Day 053 - Project 53 : My Inventory

If you have any questions, comments or issues with this project please post them here!

Hi all,
Why do I get this error:

Traceback (most recent call last):
  File "main.py", line 57, in <module>
    view()
  File "main.py", line 27, in view
    check = set(inventory) # list that allow only one of each type
TypeError: unhashable type: 'list'

when I use the set? Please help!

My code for the subroutine:

def view():
  time.sleep(1)
  os.system("clear")
  print ("VIEW INVENTORY")
#  check=[] 
#  for item in inventory:
 #   if item not in check:
 #     print(f"You have {inventory.count(item)} {item}.")
  #    check.append(item)

#Or use set
  check = set(inventory) # list that allow only one of each type
  for item in check:
    print(f"{item}{inventory.count(item)}")
  
  time.sleep(5)

Thank you so much!

Hi @Ching-LiLi thanks for your question. Can you share a link to the Repl please?

HI Ian,
here’s the link:
https://replit.com/@Ching-LiLi/day-53-100-my-game-inventory?v=1

Thanks!

Thanks!
I think I see what the issue is. The set command, when used with a list of strings or numbers, removes all duplicates so you can get each individual item e.g. wand. However the way the original list is set up each item is contained within its own list e.g.

[['Wand'], ['Wand'], ['Broom'], ['Wand'], ['Hat'], ['Stick'], ['Toy'], ['Wand'], ['Bananas'], ['Banana'], ['Apple']]

That is why you are seeing the error message. set only words with lists that contain string or number data types.

You can change the file so it looks like this:

['Wand', 'Wand', 'Broom', 'Wand', 'Hat', 'Stick', 'Toy', 'Wand', 'Bananas', 'Banana', 'Apple']

And then your program will display the item and the count of each item correctly, however you will also need to change line 17 of the code so that any new item isn’t added as a new list (remove the square brackets).

When I run the code now it displays this:
image

2 Likes

Thanks Ian! it is working now :slight_smile:

1 Like

Hi,

I’m not finished the code yet but I’m testing it out and I’m not getting an error but it’s not performing any of the functions. For example, if I select “1”, it doesn’t add an item. It just repeats the question. Link is here - https://replit.com/@rik300/Day53100Days?v=1

You had the if statements indented improperly so they were outside your loop. In addition, you had some other errors which I cleaned up. Here is some working code:

inventory = []

#try:
 # f = open("RPG.txt", "r")
  #RPG = eval(f.read())
  #f.close()
#except:
 # print("ERROR: No existing RPG list, using a blank list")

def Add ():
  global inventory
  added = input ("Which item would you like to add? ")
  inventory.append(added)
  print (added, "has been added to your inventory")

def printList():
  print()
  for items in inventory:
    print(items)
  print()

def View ():
  print (printList)

def Remove ():
  remove = ("Which item would you like to remove?")
  if remove in inventory:
        inventory.remove(remove)

print ("🌟RPG Inventory🌟")

while True: 
  choice = input ("1:Add 2:View 3:Remove > " )
  if choice == "1":
    Add ()
  elif choice == "2":
    View ()
  else:
    Remove ()


f = open("RPG.txt", "w")
f.write(str(inventory))
f.close()
1 Like

Thanks so much. Any reason that view is not working? When I click 2, I get <function printList at 0x7fe090035af0>

inventory = []

#try:
 # f = open("RPG.txt", "r")
  #RPG = eval(f.read())
  #f.close()
#except:
 # print("ERROR: No existing RPG list, using a blank list")

def Add ():
  global inventory
  added = input ("Which item would you like to add? ")
  inventory.append(added)
  print (added, "has been added to your inventory")

def printList():
  print()
  for items in inventory:
    print(items)
  print()

def View ():
  print (printList())

def Remove ():
  remove = ("Which item would you like to remove?")
  if remove in inventory:
        inventory.remove(remove)

I had no idea you could print a print statement. That’s good to know.

yeah it’ll just print None since it returns nothing, but idk what exactly he’s trying to do so I’m just having it call the func

Hello,
I’m facing issues with my code. All of my code works fine but I am not able to remove the items. It’s not giving an error message. I am not getting the output I expected. Please help.

Here’s a link to my repl : https://replit.com/@SUMAYDOHARE/Day53100Days

I’m facing issues with my code. Please help. I am not able to remove items. No error. I’m not getting the output expected.
Link to repl: https://replit.com/@SUMAYDOHARE/Day53100Days

you’re using upper() when adding an item but capitalize() when removing items, this results in two different strings for all inputs that are not all caps

3 Likes

For my “View” Option, I am trying to use a dictionary to count duplicate items in my list.
However, when I call this option it clears my list!
can someone please tell me why this is happening?

inventory = []
item = ""

def autoload():
  try:  
    f = open("inventory.txt","r")
    inventory = eval(f.read())
    f.close()
  except Exception as err:
    print("\n\n*** No file on record ***\n\n")
    print(err)

def autosave():
  f=open("inventory.txt","w")
  f.write(str(inventory))
  f.close()

def add():
  item = input("Which item do you want to add?\n> ").capitalize()
  inventory.append(item)
  print(f"{item} has been added.")

def view():
  dict = {}
  for thing in inventory:
    #qty = inventory.count(thing)
    dict[thing] = inventory.count(thing)
  print(dict)
    #print(f"{dict[thing]}x\t{dict[qty]}")

def remove():
  item = input("Which item do you want to remove?\n> ").capitalize()
  inventory.remove(item)
  print(f"{item} has been removed.")

while True: 
  menu = input("1: Add\n2: View\n3: Remove\n> ")
  autoload()
  if menu == "1":
    add()
  elif menu == "2":
    view()
  elif menu == "3":
    remove()
  else: 
    print("Not a valid option!")
    continue
  autosave()

I suggest you check what is actually in inventory…

well the inventory file works. I can add and remove items and it’s saved. But as soon as I call the “view” option the inventory list as well as the file gets cleared.

Sure, I meant look into what type is the inventory variable you are looping with … again I am trying to give hints instead of a solution as this helps better.

inventory is a list. I actually figured out now, that the problem was that I put autosave and autoload as functions. When I put them in the while loop the file is being loaded correctly everytime and there is no data loss. However, I dont understand the difference between calling the subroutine/function versus calling the code directly in the loop.

1 Like