appending to a list inside dictionary deletes previous values - python

so I want a function where I read through a file, and creates an instance with every 'recipe'. I also want to create a dictionary, that contains another diciotnary, that points to a list. This is the format I am aiming for:
{cuisine:{course:[recipe_instance...]...}...}
But when I run the version below, I only get one item in every list, although there are more than one item in every list. I'm assuming that I am overwriting a previous value, but I am appending to the list, so i'm not sure if thats correct. Any help helps!
def read_file(filename):
with open(filename,"r", encoding='utf-8') as filein:
filein.readline()
reader = csv.reader(filein)
dic = {}
for line in reader:
srno = line[0]
recipe_name = line[1]
translated_recipe_name = line[2]
ingredients = line[3]
translated_ingredients = line[4]
prep_time = line[5]
cook_time = line[6]
total_time = line[7]
servings = line[8]
cuisine = line[9]
course = line[10]
diet = line[11]
translated_instructions = line[13]
url = line[14]
every_recipe = r.Recipe(srno, translated_recipe_name, translated_ingredients, prep_time,
cook_time, total_time, servings, cuisine, course, diet, translated_instructions, url)
if cuisine not in dic:
dic[cuisine] = {course:[every_recipe]}
elif cuisine in dic:
if course not in cuisine:
dic[cuisine][course] = [every_recipe]
elif course in cuisine:
course.append(every_recipe)
return dic

Related

How to remember something from a loop after the loop is done?

I am trying to read a file and then have it print specific integers (Retail Prices) that I put into a dictionary from that file. This part I got. But when I try and print the Retail Prices outside of the loop, it cannot find them. If I include it within the loop, the file only reads one line! Help!!
while line != '':
line = fh.readline()
line = line.replace(',', '')
line = line.replace('"', '')
line = line.replace(';', ',')
linesplit = line.split(',')
linesplit = line.split(',')
dictionary = dict(zip(headerItems, linesplit))
RetailPrice = dictionary.get('retailprice')
print(RetailPrice)
RetailPrice = Retail_Prices
z = z + 1
if z == 4:
price = 'goodbye'
price = input('Enter a valid Retail Price to find all products below that price, or type anything else to exit: ')
print(Retail_Prices)
You can have the keyword dictionary outside the while loop set to None or empty dict and then over-ride it in the while loop.

Trying to call a variable from a function to another function

def editselection():
#this converts the text in the files into a list in a list
with open("stocks", "r") as stocks:
for line in stocks:
stripped_line = line.strip()
line_list = stripped_line.split()
list_of_items.append(line_list)
itemselection = input('Choice: ')
if itemselection.isalpha() == True:
ManageStock()
elif itemselection == '':
ManageStock()
itemselection = int(itemselection)
os.system('clear')
#the square brackets are the indexes so for example if they select 0, the first item turned into a list would be known as specific item
specificitem = list_of_items[itemselection]
changeitem(specificitem)
return specificitem
I'm trying to call the variable 'specificitem' to the function AddItem()
def AddToCart(specificitem):
os.system('clear')
number = 0
os.system('clear')
print ("""Here is the current stock
--------------------------
Name, Price, Quantity
--------------------------
""")
with open ('stocks', 'r') as stocks:
for i in stocks:
number = str(number)
print (number+'.' , i)
number = int(number)
number = number + 1
#this converts the text in the files into a list in a list
with open("stocks", "r") as stocks:
for line in stocks:
stripped_line = line.strip()
line_list = stripped_line.split()
list_of_items.append(line_list)
itemselection = input('Choice: ')
if itemselection.isalpha() == True:
AddToCart()
if itemselection == '':
MakeASale()
itemselection = int(itemselection)
#the square brackets are the indexes so for example if they select 0, the first item turned into a list would be known as specific item
quantity = input('How many would you like? ')
chosenitem2 = list_of_items[itemselection]
with open ('cart' , 'a') as cart:
chosenitem2 = str(chosenitem2)
cart.write(chosenitem2 + '\n')
with open("cart", "r") as cart:
for line in cart:
stripped_line = line.strip()
line_list = stripped_line.split()
list_of_cart.append(line_list)
with open ("cart" , "r+") as cart:
data = cart.read()
data = data.replace(chosenitem2[2], quantity)
cart.close
cart = open('cart' , 'wt')
cart.write(data)
cart.close()
with open ("stocks" , "r+") as stocks:
data = stocks.read()
data = data.replace(specificitem[2], chosenitem2[2])
stocks.close
stocks = open('stocks' , 'wt')
stocks.write(data)
stocks.close()
print(chosenitem2)
though it comes up with AddToCart() missing 1 required positional argument: 'specificitem'
I'm trying to use the variable from editselection to edit the quantity for example when the user enters a value it adds it to the file cart and 'subtracts' if you will from the file stocks, the use of global is unavailable due to the fact that I'll just get marked down. I've been stuck on this for 2 days now
In the first function write (function name)editselection.(variable name)specificitem=(value)list_of_items[itemselection]
And on the second function call the variable for example like this:
print(editselection.specificitem)
And this will print the value of the variable.
This is called a function variable (or something like this)

Creating new dictionary from old dictionary

I'm trying to create a new dictionary from an old one to get only the values I'll new in a df in the future. But the function I created is returning always the same key+values.
def load_data():
with open('./data/awards.json', 'r') as file:
json_file = json.load(file)
events_dict = {}
for data_raw in json_file:
events_dict['event'] = (data_raw['Event'])
#form categories_list
categories_list = []
for all_data in data_raw['Data']:
for awards_data in all_data['nomineesWidgetModel']['eventEditionSummary']['awards']:
#check if it's a premium category
if categories_data['isPremiumCategory'] == True:
for categories_data in awards_data['categories']:
categories = {}
categories['category_name'] = (categories_data['categoryName'])
#form nomination_list
nomination_list = []
for nominations_data in categories_data['nominations']:
primary_nominees = nominations_data['primaryNominees']
if len(primary_nominees)>0:
nominee1 = primary_nominees[0]['name']
secondary_nominees = nominations_data['secondaryNominees']
if len(secondary_nominees)>0:
nominee2 = secondary_nominees[0]['name']
nomination_list.append([nominee1, nominee2, nominations_data['isWinner']])
categories['nominations'] = nomination_list
categories_list.append(categories)
events_dict['categories'] = categories_list
return events_dict
My intention is to get for each award the category, nominations an if it is a winner or not. What I'm getting now is 11 times the same event.
I've tried changing the indentation, append the dict to a list first but nothing helped... I'm sure it's something pretty basic, but I'm new to Python and not seeing my error.
json file
Is it possible to do something like this?
Your logic was a bit off. You want to initialise your events_dict = {} in your loop, then you can append that into a list, which I named results.
def load_data():
with open('C:/test/awards.json', 'r') as file:
json_file = json.load(file)
results = [] #<---- initialize result list
for data_raw in json_file:
events_dict = {} #<--- here initialize your dictionary then build it
events_dict['event'] = data_raw['Event']
#form categories_list
categories_list = []
for all_data in data_raw['Data']:
for awards_data in all_data['nomineesWidgetModel']['eventEditionSummary']['awards']:
#check if it's a premium category
for categories_data in awards_data['categories']: #<---- Need to switch this line
if categories_data['isPremiumCategory'] == True: #<---This needs to follow your loop
categories = {}
categories['category_name'] = (categories_data['categoryName'])
#form nomination_list
nomination_list = []
for nominations_data in categories_data['nominations']:
primary_nominees = nominations_data['primaryNominees']
if len(primary_nominees)>0:
nominee1 = primary_nominees[0]['name']
else:
nominee1 = ''
secondary_nominees = nominations_data['secondaryNominees']
if len(secondary_nominees)>0:
nominee2 = secondary_nominees[0]['name']
else:
nominee2 = ''
nomination_list.append([nominee1, nominee2, nominations_data['isWinner']])
categories['nominations'] = nomination_list
categories_list.append(categories)
events_dict['categories'] = categories_list
results.append(events_dict) #<---- once that dictionary is filled, you can append it into that result list, then move on to make a new events_dict with the next iteration
return results

Text File to Dictionary with multiple columns

I have a text file with the following content in it
last name, first name, email, some arbitrary id number, and a phone number.
Hill, Jonah, jonahhill#outlook.com, 015666, 123-456-7890
Reynolds, Ryan, rrdp#yahoo.com, 1081254, 789-456-1230
Baccarin,Morena, bmdp#yahoo.com, 1011340, 159-753-4561
...
I want to make a dictionary for each row, but have keys to name such as last name, firstname etc.
here's the code I'm trying
d = {}
with open("oldFile.txt") as f:
d = dict(x.rstrip().split(None, 1) for x in f)
print d
I get something like this with all the content in the file in one whole dictionary
{'"hil"': '"jonah" "jonahhill#outlook" "015666" "123-456-7890"'...}
The results I'm looking for is
First person:
{lastname: "hill" , firstname: "Jonah", email: "jonahhill#outlook.com...}
Second person:
{Reynolds, Ryan, rrdp#yahoo.com, 1081254, 789-456-1230}
Third person:
...
I want keys to print them out individual such as
in file1 print out first person and I get
First person:
{lastname: "hill" , firstname: "Jonah", email: "jonahhill#outlook.com...}
You need zip.
keys = ['lastname', 'firstname', 'email', 'id', 'phone']
dicts = []
with open("oldFile.txt") as f:
for line in f:
# Split each line.
line = line.strip().split()
# Create dict for each row.
d = dict(zip(keys, line))
# Print the row dict
print d
# Store for future use
dicts.append(d)
The dictionaries for each row are available in the list dicts.
Something like this should get the job done:
keys = ['lastname', 'firstname', 'email', 'id', 'phone']
file = open('oldFile.txt', 'r')
results = []
while True:
line = file.readline()
if not line:
break
else:
content = line.split(', ')
dict = {}
index = 0
for value in content:
if value != '\n':
pair = {keys[index]: value}
dict.update(pair)
index += 1
if dict != {}: # Prevent empty lines from appending to results
results.append(dict)
for dict in results:
print dict

Group and Check-mark using Python

I have several files, each of which has data like this (filename:data inside separated by newline):
Mike: Plane\nCar
Paula: Plane\nTrain\nBoat\nCar
Bill: Boat\nTrain
Scott: Car
How can I create a csv file using python that groups all the different vehicles and then puts a X on the applicable person, like:
Assuming those line numbers aren't in there (easy enough to fix if they are), and with an input file like following:
Mike: Plane
Car
Paula: Plane
Train
Boat
Car
Bill: Boat
Train
Scott: Car
Solution can be found here : https://gist.github.com/999481
import sys
from collections import defaultdict
import csv
# see http://stackoverflow.com/questions/6180609/group-and-check-mark-using-python
def main():
# files = ["group.txt"]
files = sys.argv[1:]
if len(files) < 1:
print "usage: ./python_checkmark.py file1 [file2 ... filen]"
name_map = defaultdict(set)
for f in files:
file_handle = open(f, "r")
process_file(file_handle, name_map)
file_handle.close()
print_csv(sys.stdout, name_map)
def process_file(input_file, name_map):
cur_name = ""
for line in input_file:
if ":" in line:
cur_name, item = [x.strip() for x in line.split(":")]
else:
item = line.strip()
name_map[cur_name].add(item)
def print_csv(output_file, name_map):
names = name_map.keys()
items = set([])
for item_set in name_map.values():
items = items.union(item_set)
writer = csv.writer(output_file, quoting=csv.QUOTE_MINIMAL)
writer.writerow( [""] + names )
for item in sorted(items):
row_contents = map(lambda name:"X" if item in name_map[name] else "", names)
row = [item] + row_contents
writer.writerow( row )
if __name__ == '__main__':
main()
Output:
,Mike,Bill,Scott,Paula
Boat,,X,,X
Car,X,,X,X
Plane,X,,,X
Train,,X,,X
Only thing this script doesn't do is keep the columns in order that the names are in. Could keep a separate list maintaining the order, since maps/dicts are inherently unordered.
Here is an example of how-to parse these kind of files.
Note that the dictionary is unordered here. You can use ordered dict (in case of Python 3.2 / 2.7) from standard library, find any available implmentation / backport in case if you have older Python versions or just save an order in additional list :)
data = {}
name = None
with open(file_path) as f:
for line in f:
if ':' in line: # we have a name here
name, first_vehicle = line.split(':')
data[name] = set([first_vehicle, ]) # a set of vehicles per name
else:
if name:
data[name].add(line)
# now a dictionary with names/vehicles is available
# let's convert it to simple csv-formatted string..
# a set of all available vehicles
vehicles = set(v for vlist in data.values()
for v in vlist)
for name in data:
name_vehicles = data[name]
csv_vehicles = ''
for v in vehicles:
if v in name_vehicles:
csv_vehicles += v
csv_vehicles += ','
csv_line = name + ',' + csv_vehicles
Assuming that the input looks like this:
Mike: Plane
Car
Paula: Plane
Train
Boat
Car
Bill: Boat
Train
Scott: Car
This python script, places the vehicles in a dictionary, indexed by the person:
#!/usr/bin/python
persons={}
vehicles=set()
with open('input') as fd:
for line in fd:
line = line.strip()
if ':' in line:
tmp = line.split(':')
p = tmp[0].strip()
v = tmp[1].strip()
persons[p]=[v]
vehicles.add(v)
else:
persons[p].append(line)
vehicles.add(line)
for k,v in persons.iteritems():
print k,v
print 'vehicles', vehicles
Result:
Mike ['Plane', 'Car']
Bill ['Boat', 'Train']
Scott ['Car']
Paula ['Plane', 'Train', 'Boat', 'Car']
vehicles set(['Train', 'Car', 'Plane', 'Boat'])
Now, all the data needed are placed in data-structures. The csv-part is left as an exercise for the reader :-)
The most elegant and simple way would be like so:
vehiclesToPeople = {}
people = []
for root,dirs,files in os.walk('/path/to/folder/with/files'):
for file in files:
person = file
people += [person]
path = os.path.join(root, file)
with open(path) as f:
for vehicle in f:
vehiclesToPeople.setdefault(vehicle,set()).add(person)
people.sort()
table = [ ['']+people ]
for vehicle,owners in peopleToVehicles.items():
table.append([('X' if p in vehiclesToPeople[vehicle] else '') for p in people])
csv = '\n'.join(','.join(row) for row in table)
You can do pprint.pprint(table) as well to look at it.

Categories