FlagShipKILLER FlagShipKILLER - 1 month ago 13
Python Question

Python: Unhashable error, lists

This one is different... My code works around user inputted information and doing various things with that information such as storing it, doing mutiplication and addition to it, and storing it as a variable. At the end of the code I want a receipt to be printed out of what the user has inputted in, translated to its other name in a dict. Phew, Here is my code:

print("Hi There! Welcome to sSpecialists!")
print("To start shopping, note down what you want to buy and how much of it")
print("Here are the purchasable items")
print("~~~~~")
print("12345670 is a hammer (£4.50)")
print("87654325 is a screw driver (£4.20)")
print("96385272 is a pack of 5 iron screws (£1.20)")
print("74185290 is pack of 20 100mm bolts (£1.99)")
print("85296374 is a pack of 6 walkers crisps (£1)")
print("85274198 is haribo pack (£1)")
print("78945616 is milk (£0.88)")
print("13246570 is a bottle of evian water (£0.99)")
print("31264570 is kitkat original (£0.50)")
print("91537843 is a cadbury bar (£1)")
print("~~~~~")
items = {12345670 : 'hammer',
87654325 : 'screwDriver',
96385272 : 'packOf5IronnScrews',
74185290 : 'packOf200mmBolts',
85296374 : 'packOf6WalkersCrisps',
85274198 : 'hariboPack',
78945616 : 'milk',
13246570 : 'bottleOfEvianWater',
31264570 : 'kitkatOriginal',
91537843 : 'cadburyBar'}
print("Alright, now start typing what you want to order")
print(" ")
subtotal = 0
full_list = " "
chos_items = []
while full_list != "":
print(" ")
full_list = input("Type: ")
if full_list == 'end':
break
amount = int(input("Amount: "))
item = int(full_list)
if item in items:
print("That would be {} {}(s)".format(amount, items[item]))
if full_list == '12345670':
price = (4.50 * amount)
print("Added Hammer(s)")
print("Added "+str(price))
subtotal = subtotal + price
if full_list == '87654325':
price = (4.20 * amount)
subtotal = subtotal + price
print("Added Screw Driver(s)")
print("Added "+str(price))
if full_list == '96385272':
price = (1.20 * amount)
subtotal = subtotal + price
print("Added Pack of 5 iron
print("Added "+str(price))
if full_list == '74185290':
price = (1.99 * amount)
subtotal = subtotal + price
print("Added Pack of 20 100mm bolts")
print("Added "+str(price))
if full_list == '85296374':
price = (1.00 * amount)
subtotal = subtotal + price
print("Added Pack of 6 Walkers crisps")
print("Added "+str(price))
if full_list == '85274198':
price = (1.00 * amount)
subtotal = subtotal + price
print("Added Haribo pack(s)")
print("Added "+str(price))
if full_list == '78945616':
price = (0.88 * amount)
subtotal = subtotal + price
print("Added bottle(s) of milk")
print("Added "+str(price))
if full_list == '13246570':
price = (0.99 * amount)
subtotal = subtotal + price
print("Added bottle(s) Evian water")
print("Added "+str(price))
if full_list == '31264570':
price = (0.50 * amount)
subtotal = subtotal + price
print("Added bar(s) of Kitkat original")
print("Added "+str(price))
if full_list == '91537843':
price = (0.50 * amount)
print("Added Cadbury bar(s)")
print("Added "+str(price))
if full_list != "":
chos_items.append(full_list)
total = round(subtotal)
print("Your subtotal is " +str(total))
print(" ")
print("That would be, []".format(items[full_list]))
print(" ")
print("Your recipt is")
print(" ")


My code IS a bunch of similar things but there is method behind the madness. I believe the problem occurs at
print("That would be, []".format(items[chos_items]))
. When I run this, this is what gets outputted

print("That would be, []".format(items[chos_items]))
TypeError: unhashable type: 'list'


I've tried changing the list into a trouple but that didn't help. I for the life of me have no idea how to fix it. Please help, thanks >_<

Answer

Two major issues:

1) You are storing the results in chos_items, then not doing anything with them. full_items, when you exit the while loop, contains "end" or ""

print("That would be, {}".format(' '.join([items[int(item)] for item in chos_items])))

Will give you a list of all the items chosen, but it won't give how many, as you don't store that value.

2) You aren't leveraging the python dicts for full effect:

if item in items:

You check whether the item is within items as a dictionary, but then don't leverage the dictionary.

items = {'12345670' : {'name' : 'Hammer', 'price' : 4.50},
         '87654325' : {'name' : 'screwDriver', 'price' : 4.20}}

If this is your dictionary, you can then do the below:

for item in items:
    print("{} is a {} (£{:0.2f})".format(item, items[item]['name'], items[item]['price']))

which will print out the list of items and their prices for you:

87654325 is a screwDriver (£4.20)
12345670 is a Hammer (£4.50)

as item is the number, item['name'] is the name, and item['price'] is the price. You can then consolidate your if/if/if/if block into a single lookup: if item in items:

This will greatly simplify your logic, as the dict does most of the work.