Dictionary value "not defined" Python - python

I'm working on a simple grocery list for class. In the first step we create an empty dictionary and list to be filled by input from a user. All grocery items go into a dictionary (grocery_item{}) and all of the dictionaries are to be added to the list (grocery_history).
My script currently looks like this:
grocery_item = {}
grocery_history = []
stop = 'go'
while stop == 'go' or stop == 'c':
item_name = input("Item name: \n" )
quantitiy = int(input("Quantitiy purchased:\n" ))
cost = float(input("Price per item:\n" ))
grocery_item.update({'name' : item_name, 'number' : quantitiy, 'price' :
cost})
grocery_history.append(grocery_item)
stop = input("Would you like to enter another item?\n Type 'c' for continue
or 'q' to quite:\n")
If I print grocery_history at this point, it will print the list of dictionaries exactly as I intended. In the next step of the grocery list, we are trying to find the grand total of the items. However, whenever I try to find each items individual value, using for loops to get to each dictionary in the list, I receive an error claiming that keys are not defined, even though it just printed the dictionary entry for that grocery item, and all of the keys had values.
My script for this section looks like this:
grand_total = 0
for item in grocery_history:
I = 0
for price in item:
item_total = number * price
grand_total += item_total
print(number + name + '#' + '$' + price + 'ea' + '$' + round(item_total,2))
item_total = 0
I += 1
print('$' + round(grand_total,2))
The error is for the line in which I am trying to find the item_total, because it is the first line I try to use one of the keys. I have tried to rewrite the keys as grocery_item(numbers)/grocery_item(price), and receive the same error message.
I appreciate any help, and thanks in advance!

Try something like this:
grocery_history = []
stop = 'go'
while stop == 'go' or stop == 'c':
grocery_item = {}
grocery_item['name'] = input("Item name: \n" )
grocery_item['number'] = int(input("Quantitiy purchased:\n" ))
grocery_item['price'] = float(input("Price per item:\n" ))
grocery_history.append(grocery_item)
stop = input("Would you like to enter another item?\n Type 'c' for continue or 'q' to quit:\n")
grand_total = 0
for item in grocery_history:
item_total = 0
item_total = item['number'] * item['price']
grand_total += item_total
print(item['number'], item['name'], '#', '$', item['price'], 'ea', '$', round(item_total,2))
print('$', round(grand_total,2))
If you want to use a for loop on a dictionary you will need to loop over the keys of the dictionary. You can do that by using .keys() or .items() functions of a dict. But as you see above, there is no need to loop over the dict keys in your code.

grocery_item = {}
grocery_history = []
stop = 'go'
while stop == 'go' or stop == 'c':
item_name = input("Item name: \n" )
quantitiy = int(input("Quantitiy purchased:\n" ))
cost = float(input("Price per item:\n" ))
grocery_item.update({'name' : item_name, 'number' : quantitiy, 'price' :
cost})
grocery_history.append(grocery_item)
stop = input("Would you like to enter another item?\n Type 'c' for continue or 'q' to quit:\n")
grand_total = 0
for item in grocery_history:
item_total = item['number'] * item['price']
grand_total += float(item_total)
print(str(item['number']) + " " + str(item['name']) + ' # ' + '$' + str(item['price']) + 'ea' + "\n" + '$' + str(round(item_total,2)))
item_total = 0
print("\n" + '$' + str(round(grand_total,2)) + " is the grand total.")

Related

Existing dictionaries in list all being updated to new dictionary entry?

I am trying to create a simple program that contains a list of dictionaries. The grocery_history is the list of dictionaries, and the dictionary is grocery_item. Here is the code:
'''
The task is broken down into three sections.
Section 1 - User Input
Section 2 - loop through the grocery list
Section 3 - provide output to the console
'''
grocery_item = {}
grocery_history = []
stop = 'go'
while stop != 'q':
item_name = input("Item name:\n")
quantity = int(input("Quantity purchased:\n"))
cost = float(input("Price per item:\n"))
grocery_item['name'] = item_name
grocery_item['number'] = quantity
grocery_item['price'] = cost
grocery_history.append(grocery_item)
stop = input("Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n")
print(grocery_history)
grand_total = 0
for grocery_item in range(0, len(grocery_history)):
item_total = grocery_history[grocery_item]['number'] * grocery_history[grocery_item]['price']
grand_total += item_total
print(str(grocery_history[grocery_item]['number']) + " " + grocery_history[grocery_item]['name'] + " # $%.2f" % grocery_history[grocery_item]['price'] + " ea \t$%.2f" % item_total)
item_total = 0.0
print("Grand total: $%.2f" % grand_total)
print(grocery_history)
In case you're wondering, the prompt for this assignment told me to use the variable grocery_item in my for loop. I normally would have chosen a different name since it becomes confusing. I also added a couple of print statements to print out the contents of grocery_history to see what's going wrong, and I confirmed it's when the dictionary is being added to the grocery_history list, that's when it for some reason updates existing dictionary items to match the new one being added. I can't figure out what I'm doing wrong. Any help would be greatly appreciated!
You need to define a new dictionary object each time in loop or else you end up using the same dictionary object so in effect replaces the already added one.
while stop != 'q':
grocery_item = {}
# ...
sample code should work
grocery_history = []
stop = 'go'
while stop != 'q':
item_name = input("Item name:\n")
quantity = int(input("Quantity purchased:\n"))
cost = float(input("Price per item:\n"))
grocery_item = {}
grocery_item['name'] = item_name
grocery_item['number'] = quantity
grocery_item['price'] = cost
grocery_history.append(grocery_item)
stop = input("Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n")
print(grocery_history)
grand_total = 0
for grocery_item in range(0, len(grocery_history)):
item_total = grocery_history[grocery_item]['number'] * grocery_history[grocery_item]['price']
grand_total += item_total
print(str(grocery_history[grocery_item]['number']) + " " + grocery_history[grocery_item]['name'] + " # $%.2f" % grocery_history[grocery_item]['price'] + " ea \t$%.2f" % item_total)
item_total = 0.0
print("Grand total: $%.2f" % grand_total)
print(grocery_history)
the problem happened because you are repeating using same dict, although it adds to list each time, what you actually doing is keep updating the same reference so all content in the list becomes the same value
move dict inside solve the problem
This is because your loop does not create a new grocery_item object each time; it just updates the same grocery_item object over and over.
grocery_history ends up containing multiple references to this single object, in its latest state.
To fix this issue, move the line grocery_item = {} to be the first item underneath the while stop != 'q': loop. This will create a new object each time through the loop.
You can use map and sum to get grand_total
grocery_history = []
stop = 'go'
while stop != 'q':
grocery_item = {}
grocery_item['name'] = input("Item name:\n")
grocery_item['number'] = int(input("Quantity purchased:\n"))
grocery_item['price'] = float(input("Price per item:\n"))
grocery_history.append(grocery_item)
stop = input("Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n")
grand_total = sum(map(lambda item: item['number'] * item['price'], grocery_history))
print("Grand total: $%.2f" % grand_total)
print(grocery_history)
Input:
Item name:
item
Quantity purchased:
2
Price per item:
1.2
Would you like to enter another item?
Type 'c' for continue or 'q' to quit:
q
Output:
Grand total: $2.40
[{'name': 'item', 'number': 2, 'price': 1.2}]

Difficulties with funtions and syntax in python

I have written a program for a homework assignment, that should function as a mock grocery list that will calculate how much the items should cost as well.
grocery_item = {}
grocery_history=[{'name': 'milk', 'number': int(1), 'price': float(2.99)},
{'name': 'eggs', 'number': 2, 'price': 3.99},
{'name': 'onions', 'number': 4, 'price': 0.79}]
stop = 'go'
item_name = "Item name"
quantity = "Quantity purchased"
cost = "Price per item"
print ("Item name:")
print ("Quantity purchased:")
print ("Price per item:")
cont = 'c'
while cont != 'q':
item_name = "milk"
quantity = "Quantity purchased"
quantity = 2
cost = "Price per item"
cost = 2.99
grocery_history.append(item_name)
grocery_history.append(quantity)
grocery_history.append(cost)
grocery_item['name'] = item_name
grocery_item['number'] = quantity
grocery_item['price'] = cost
print("Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n")
cont = 'c'
item_name = "eggs"
quantity = "Quantity purchased"
quantity = 1
cost = "Price per item"
cost = 3.99
grocery_history.append(item_name)
grocery_history.append(quantity)
grocery_history.append(cost)
grocery_item['name'] = item_name
grocery_item['number'] = quantity
grocery_item['price'] = cost
"Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n"
cont = 'c'
item_name = "onions"
quantity = "Quantity purchased"
quantity = 4
cost = "Price per item"
cost = 0.79
"Would you like to enter another item?\nType 'c' for continue or 'q' to quit:\n"
cont = 'q'
grand_total = []
number = grocery_item['number']
price = grocery_item['price']
for grocery_history in grocery_item:
item_total = number*price
grand_total.append(item_total)
print (grocery_item['number'] + ['name'] + "#" + ['price'] + "ea" + ['item_total'])
item_total = 0
print (grand_total)
This is the error I get:
print (grocery_item['number'] + ['name'] + "#" + ['price'] + "ea" + ['item_total'])
TypeError: unsupported operand type(s) for +: 'int' and 'list'
There are multiple problems with this code.
I am supposed to use the %.2f to get the price in dollar form, but I have no idea how, and the things I've tried haven't worked.
There are syntax errors in my print(grocery_item) statement.
The code doesn't run through the list grocery_history, and just repeats with the same input over and over.
To get a formatted print with the fields from the dict you can use .format() like:
print('{number} {name} # {price:.2f} ea'.format(**grocery_item))
You have an error because you are adding string to floats. Python does not know how to do that.
As #Stephen Rauch showed, you can do it in one line with a very pythonic structure. If you want you can use the syntax
'%s\t%s\t...'%(my_variable1, my_variable2)
Which works great as well.
I assume you wanted to add items to already existing grocery_history and then calculate the grand total of all your groceries (using Stephen Rauch's printing answer).
grocery_history=[{'name': 'milk', 'number': int(1), 'price': float(2.99)},
{'name': 'eggs', 'number': 2, 'price': 3.99},
{'name': 'onions', 'number': 4, 'price': 0.79}]
cont = 'c'
grand_total = 0
while cont != 'q':
num = input("How many bottles of milk do you want to buy? ")
grocery_history[0]['number'] += num
num = input("How many eggs do you want to buy? ")
grocery_history[1]['number'] += num
num = input("How many onions do you want to buy? ")
grocery_history[2]['number'] += num
cont = raw_input("Enter c to continue or q to quit: ")
while cont not in ['c', 'q']:
cont = raw_input("Wrong choice, enter your choice again: ")
for grocery_item in grocery_history:
item_total = grocery_item['number'] * grocery_item['price']
grand_total += item_total
print('${:.2f} for {number} {name} # {price:.2f} ea'.format(item_total, **grocery_item))
print ("Grand total is ${:.2f}".format(grand_total))
Some of what went wrong:
You weren't actually asking the user to enter c or q, so you just went once over the list and exited in the end because of cont = 'q'.
You were constantly overwriting your variables, for example:
quantity = "Quantity purchased"
quantity = 2
First line assigns string and the second - integer. You can operate directly on dict values, provided you know how to access them.
This part:
number = grocery_item['number']
price = grocery_item['price']
assigned the last actually updated grocery_item (eggs) and you did all your calculations in for loop with these two values.
Here:
grocery_history.append(item_name)
grocery_history.append(quantity)
grocery_history.append(cost)
you were appending strings and numbers to a list of dictionaries.

overlapping variable doesn't change variable

I can't even explain. Here is my code
foods = {12345670 : 'orange(s)',
87654325 : 'pineapple(s)'}
loop = 10
while loop == 10:
full_list = input("Type: ")
if full_list == 'end':
break
amount = int(input("Amount: "))
subtotal = 0
item = int(full_list)
if item in foods:
print("That would be {} {}".format(amount, foods[item]))
if full_list == '12345670':
price = (0.50 * amount)
print("Added Orange(s)")
print("Added "+str(price))
subtotal = subtotal + price
if full_list == '87654325':
price = (1.00 * amount)
subtotal = subtotal + price
print("Added Pineapple(s)")
print("Added "+str(price))
print("Your subtotal is " +str(subtotal))
I'm trying to get my subtotal to change accordingly to what the user purchases, I haven't finished making my list of purchasable items and so I don't want to change the name of the variable every time. What is the problem here? Why doesn't the variable subtotal change?
foods = {12345670 : 'orange(s)',
87654325 : 'pineapple(s)'}
loop = 10
subtotal = 0 # <------ moved it outside of the while loop
while loop == 10:
full_list = input("Type: ")
if full_list == 'end':
break
amount = int(input("Amount: "))
item = int(full_list)
if item in foods:
print("That would be {} {}".format(amount, foods[item]))
if full_list == '12345670':
price = (0.50 * amount)
print("Added Orange(s)")
print("Added "+str(price))
subtotal = subtotal + price
if full_list == '87654325': #should be an elif not an if
price = (1.00 * amount)
subtotal = subtotal + price
print("Added Pineapple(s)")
print("Added "+str(price))
print("Your subtotal is " +str(subtotal))
Every time you looped you restarted the total cost to 0 and it only kept the latest price. Move it outside of the while loop where I commented and you should be fine. Also use elif if you want to chain similar if statements together.
You have the following
if full_list == '12345670'
But it will never enter this if statement because your input type is an integer not a string. Do this without the single quotes instead:
if full_list == 12345670

How to Return a Shopping Cart Total

I've been at this for hours and I just can't seem to figure out how to return a total. All I know is that I need to start with total = 0. I have tried 'for i in x' loops and I wish I had them to post here but I've been doing trial and error for so long that I can't exactly recall what I've done. I'm using Python 2.7.10 and I'm a complete beginner. Please help? Even if just a hint?
f_list = []
print 'Enter a fruit name (or done):',
f = raw_input()
while f != 'done':
print 'Enter a fruit name (or done):',
f_list.append(f)
f = raw_input()
print ""
p_list = []
for i in f_list:
print 'Enter the price for ' + i + ':',
p = float(raw_input())
p_list.append(p)
print ""
print 'Your fruit list is: ' + str(f_list)
print 'Your price list is: ' + str(p_list)
print ""
n = len(f_list)
r = range(0,n)
q_list = []
for i in r:
print str(f_list[i]) + '(' + '$' + str(p_list[i]) + ')',
print 'Quantity:',
q = raw_input()
total = 0
You have forgotten to create the list of quantities, which isn't going to help.
Then just iterate over your f_list and add them up.
f_list = []
print 'Enter a fruit name (or done):',
f = raw_input()
while f != 'done':
print 'Enter a fruit name (or done):',
f_list.append(f)
f = raw_input()
print ""
p_list = []
for i in f_list:
print 'Enter the price for ' + i + ':',
p = float(raw_input())
p_list.append(p)
print ""
print 'Your fruit list is: ' + str(f_list)
print 'Your price list is: ' + str(p_list)
print ""
q_list = []
for i in range(len(f_list)):
print str(f_list[i]) + '(' + '$' + str(p_list[i]) + ')',
print 'Quantity:',
q = raw_input()
q_list.append(q)
total = 0
for i in range(len(f_list)):
total += float(p_list[i]) * int(q_list[i])
print "Basket value : ${:.2f}".format(total)
There are definitely other answers on this site that should help you, but you want to convert your q to a float and append q to q_list just like for p. To get your grand total all you need to do is total = sum(q_list) and display your answer.

Dictionary values are not showing up in a later section of code when they are printed

Ignore all of this cod except the spots that I point out, I will say ##Look Here## at the spots:
ans = raw_input('Enter Amount of Players: ').lower()
if ans == '2':
a = raw_input('What is Player 1 named: ')
b = raw_input('What is Player 2 named: ')
cf={a:{}, b:{}}
cf[a] = a
cf[b] = b
p1 = raw_input(a + ", what is your city named: ")
p2 = raw_input(b + ", what is your city named: ")
cf={a:{p1:50}, b:{p2:50}}
##Look here, print cf ##
print cf
for key, cf in cf.items():
print(key)
for attribute, value in cf.items():
print('{} : {}'.format(attribute, value))
answer = raw_input ("Hit 'Enter' to continue")
def cva(x):
y = cf[ques][city]
y = float(y)
return x + y
while True:
one = raw_input("Type 'view' to view civil form, type 'change' to change civil order, or 'add' to add a city: ")
if one == 'change':
ques = raw_input('Enter Name of Player That Will Change His/Her Civil Form: ').lower()
city = raw_input(ques + ' Enter Name Of City That Will Change Civil Form: ').lower()
inc = raw_input(ques + ' Enter Amount of change for ' + city + ": ").lower()
##Look here, print cf##
print cf
cf[ques][city]=cva(float(inc))
for key, cf in cf.items():
print(key)
for attribute, value in cf.items():
print('{} : {}'.format(attribute, value))
elif one == 'view':
for key, cf in cf.items():
print(key)
for attribute, value in cf.items():
print('{} : {}'.format(attribute, value))
elif one == 'add':
ch1 = raw_input('Enter the Name of Player That Will Add a City: ')
ch2 = raw_input(ch1 + ', Enter The Name of Your New City: ')
cf[ch1][ch2] = '50'
elif one == 'over': break
elif one == 'game over': break
elif one == 'quit': break
The 2 parts of the code that I told you to look at basically print the dictionary. When I input the name 'Andrew' and 'Matt', and the cities 'Po' and 'Lo' the first print looks like this:{'Matt': {'Lo': 50}, 'Andrew': {'Po': 50}}
The second print looks like this for Matt: {'Po': 50}
The second print looks like this for Andrew: {'Lo': 50}
Why does the name of the player not show up in the second print like it did in the first print. Is it because the name got deleted? If so, can you tell me how to fix this problem?
The problem is your loop
for key, cf in cf.items():
for attribute, value in cf.items():
print('{} : {}'.format(attribute, value))
Since you name one of the iteration variables to the same thing as the dictionary you are iterating over, you have problems.
cf will, after this loop, contain the value of the last item.
Rename the iteration variable cf to something else, like
for key, dict_val in cf.items():
for attribute, value in dict_val.items():
print('{} : {}'.format(attribute, value))
and things should be fine.

Categories