5
\$\begingroup\$

I'm really new to Python (like only a month of study) and I was testing out dictionaries, so I tried to make an 'inventory' where you can pick an item from your inventory and examine it. But I can tell that I'm not doing this in the most efficient or elegant way.

Originally I thought I could make each item its separate dictionary, kind of like this:

#define what's in your inventory using a list
inventory = ["apple", "tire"]
#create a list of items with attributes using dictionaries
apple = {
 "name":"apple",
 "type":"fruit",
 "edible":"edible",
 "color":"red",
}
tire = {
 "name":"tire",
 "type":"object",
 "edible":"not edible",
 "color":"grey"
}
#explain the program to the user
print("Choose an item to examine. Items in your inventory are:")
print(*inventory, sep = ", ")
#set the loop to true
itemsloop = True
#begin the loop
while itemsloop == True:
 #ask for user input
 x = input()

But then I got stuck at the part where it's time to take the input and match it to the name of a dictionary, because one is a string and one isn't. The following code is working, but feels... inelegant and unnecessary to type out (prefix)-name, (prefix)-type, (prefix)-edible for every entry. I feel like there must be a simpler way to accomplish this that I'm just not seeing because I don't think like a programmer yet. I don't know.

If you can explain any more efficient methods with simple terminology (again, huge newbie not just to Python but programming in general), I'd really appreciate it!

#define what's in your inventory using a list
inventory = ["apple", "tire"]
#create a list of items with attributes using a dictionary
items = {
 "apple-name":"apple",
 "apple-type":"fruit",
 "apple-edible":"edible",
 "apple-color":"red",
 "tire-name":"tire",
 "tire-type":"object",
 "tire-edible":"not edible",
 "tire-color":"grey"
}
#explain the program to the user
print("Choose an item to examine. Items in your inventory are:")
print(*inventory, sep = ", ")
#set the loop to true
itemsloop = True
#begin the loop
while itemsloop == True:
 #ask for user input
 x = input()
 if x in inventory:
 #if the input matches something you have, find the attributes of
 #the item in the inventory and print them.
 print("This is a " + items[x + "-color"] + " " + 
 items[x + "-name"] + ", a type of " + items[x + "-type"] 
 + ". It is " + items[x + "-edible"] + ".")
 elif x == "quit":
 #if the player wishes to quit, end the program.
 itemsloop == False
 break
 else:
 #if the item is not recognized, let the player know.
 print("You don't have that in your inventory.")

(The sample output would be something like, "This is a red apple, a type of fruit. It is edible.")

200_success
146k22 gold badges190 silver badges479 bronze badges
asked Nov 14, 2018 at 2:51
\$\endgroup\$
0

2 Answers 2

1
\$\begingroup\$

To expand on the answer given by @Aries_is_there in, you should indeed make your dictionary a nested dictionary with the item names as first keys and the item properties as keys of the sub dictionaries.

You should also be aware that x in inventory is \$\mathcal{O}(n)\$ if inventory is a list, but this is mitigated when making it a dictionary, because x in items is \$\mathcal{O}(1)\$ for dictionaries.

Your printing can also be simplified by using an f-string.

I would also add a if __name__ == "__main__" guard to allow importing functions form this script from another script.

And finally, Python has an official style-guide, PEP8, which is well worth a read. You are already mostly following it, except for the missing spaces after the : in your dictionaries.

items = {"apple": {"name": "apple",
 "type": "fruit",
 "edible": "edible",
 "color": "red"},
 "tire": {"name":"tire",
 "type":"object",
 "edible":"not edible",
 "color":"grey"}}
if __name__ == "__main__":
 print("Choose an item to examine. Items in your inventory are:")
 print(*items.keys(), sep = ", ")
 while True:
 x = input()
 if x in inventory:
 #if the input matches something you have, find the attributes of
 #the item in the inventory and print them.
 item = items[x]
 print(f"This is a {item['color']} {item['name']}, a type of {item['type']}. It is {item['edible']}.")
 elif x == "quit":
 #if the player wishes to quit, end the program.
 break
 else:
 #if the item is not recognized, let the player know.
 print("You don't have that in your inventory.")

You could take it one level further by making it object-oriented. In this case you would probably want an Object class for which you define the magic __str__ method, which controls what happens if you do print(x).

class Object:
 def __init__(self, name, type="object", edible=False, color=None):
 self.name = name
 self.type = type
 self.edible = edible
 self.color = color
 def __str__(self):
 s = ["This is a "]
 if self.color is not None:
 s.append(self.color + " ")
 s.extend([self.name, f", a type of {self.type}."]
 s.append(f"It is {'not ' if not self.edible else ''}edible.")
 return "".join(s)
items = {"apple": Object("apple", "fruit", edible=True, color="red"),
 "tire": Object("tire", color="grey")}
if __name__ == "__main__":
 print("Choose an item to examine. Items in your inventory are:")
 print(*items.keys(), sep = ", ")
 while True:
 x = input()
 if x in items:
 #if the input matches something you have, find the attributes of
 #the item in the inventory and print them.
 item = 
 print(items[x])
 elif x == "quit":
 #if the player wishes to quit, end the program.
 break
 else:
 #if the item is not recognized, let the player know.
 print("You don't have that in your inventory.")
answered Nov 14, 2018 at 9:01
\$\endgroup\$
1
  • \$\begingroup\$ Thank you very much for the thorough explanation. I didn't know you could nest dictionaries! I'm still new to a lot of the things included in your post, so i will be doing googling for a while, haha. Do you have any recommendations on a good newbie explanation for magic methods? I had never heard of those. \$\endgroup\$ Commented Nov 14, 2018 at 18:09
3
\$\begingroup\$

As you use item's name to search the item information, so you can design the name as the key of items hash table.

items = {
 "apple":
 {
 #type, edible,color information
 },
 ...
}
answered Nov 14, 2018 at 3:23
\$\endgroup\$
3
  • \$\begingroup\$ I didn't understand that you could use dictionaries as dictionary keys. Thank you. \$\endgroup\$ Commented Nov 14, 2018 at 17:57
  • \$\begingroup\$ haha as long as you get @Graipher answer, he did a good explain \$\endgroup\$ Commented Nov 14, 2018 at 18:22
  • 1
    \$\begingroup\$ @Red You actually can't. But you can use them as dictionary values. If you want to use them as keys you would have to convert the dictionary into a tuple of key, value tuples first, so it is hashable. This would be sensitive to the order then, though. \$\endgroup\$ Commented Nov 14, 2018 at 19:17

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.