# Fantasy game inventory — Ch. 5 Automate the Boring Stuff

Here is a practice exercise — Fantasy Game Inventory $$\-\$$

You are creating a fantasy video game. The data structure to model the player’s inventory will be a dictionary where the keys are string values describing the item in the inventory and the value is an integer value detailing how many of that item the player has. For example, the dictionary value {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12} means the player has 1 rope, 6 torches, 42 gold coins, and so on.

Write a function named display_inventory() that would take any possible “inventory” and display it like the following -

Inventory:
12 arrows
42 gold coins
1 rope
6 torches
1 dagger
Total number of items: 62


Hint - You can use a for loop to loop through all the keys in a dictionary.

I have written the following code. Any feedback is highly appreciated.

stuff = {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}

def display_inventory(inventory):
total_items = 0
print ("Inventory:")
for item in inventory:
print(str(inventory[item]) + ' ' + item)
total_items += inventory[item]
print("Total number of items: " + str(total_items))

if __name__ == '__main__':
display_inventory(stuff)

• The interesting part of this task is to generate the correct plural forms from the singulars. You completely missed this one. – Roland Illig Jun 15 '19 at 14:38
• @RolandIllig - Please check my answer below which covers your suggestion. Thank you for pointing this out. – Justin Jun 16 '19 at 4:13

I am suggesting to use fstrings and the dictionary items() method.

The

print(f'{value} {key}')


print(str(inventory[item]) + ' ' + item)


is more neatly:

def display_inventory(inventory):
total_items = 0
print ("Inventory:")

for key, value in inventory.items():
print(f'{value} {key}')
total_items += value

print(f'Total number of items: {total_items}')


Also, you can just calculate the total number in the needed place by the sum() function and the dictionary values() method. Then, you are not needing the total_items variable.

def display_inventory(inventory):
print ("Inventory:")

for key, value in inventory.items():
print(f'{value} {key}')

print(f'Total number of items: {sum(inventory.values())}')


As mentioned in a comment by Roland Illig, I missed the interesting part of generating the correct plural forms from the singulars.

Here's a module which supports Python 3 - Inflect.

# Initialization
import inflect
p = inflect.engine()


Examples -

word = "torch"
print(f"The plural of '{word}' is '{p.plural(word)}'.")

>>> The plural of 'torch' is 'torches'.


word = "torches"
print(f"The singular of '{word}' is '{p.singular_noun(word)}'.")

>>> The singular of 'torches' is 'torch'.


My updated code, expanding on MiniMax's answer, is:

import inflect
p = inflect.engine()

stuff = {'rope': 0, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}

def display_inventory(inventory):

print ("Inventory:")
for key, value in inventory.items():

if value != 1:
key = p.plural(key)

print(f'{value} {key}')
print(f'Total number of items: {sum(inventory.values())}')

if __name__ == '__main__':
display_inventory(stuff)


This will give the following output -

Inventory:
0 ropes
6 torches
42 gold coins
1 dagger
12 arrows
Total number of items: 61


OR

In cases like this -

stuff = {'ropes': 1, 'torches': 1, 'gold coin': 42, 'daggers': 1, 'arrow': 0}


where -

{'ropes': 1, 'torches': 1, 'daggers': 1}


you will need to generate the correct singular forms from the plurals.

Therefore, expanding more on the previous code, I get -

import inflect
p = inflect.engine()

stuff = stuff = {'ropes': 1, 'torches': 1, 'gold coin': 42, 'daggers': 1, 'arrow': 0}

def display_inventory(inventory):
print ("Inventory:")
for key, value in inventory.items():

if value != 1:
key = p.plural(key)
else:
key = p.singular_noun(key)

print(f'{value} {key}')
print(f'Total number of items: {sum(inventory.values())}')

if __name__ == '__main__':
display_inventory(stuff)


This will give the following output:

Inventory:
1 rope
1 torch
42 gold coins
1 dagger
0 arrows
Total number of items: 45


• Yes, that works. An easier way would probably be using a ternary: key = p.plural(key) if value > 1 else p.singular_noun(key) – Graipher Jun 16 '19 at 9:42
• @Graipher The documentation of the inflict package suggests p.plural(key, value). – Roland Illig Jun 16 '19 at 11:07
• @RolandIllig Might be, I don't know the packet. I just used the commands as they are in the post. – Graipher Jun 16 '19 at 11:16

I got stuck in this asnwer and decided to convert the dictionary into a list, resulting in the following code:

stuff = {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}

keys = list(stuff.keys())
values = list(stuff.values())

def displayInventory(q):
print("Inventory:")
item_total = 0
for a in range(len(keys)):
item_total = int(item_total) + int(values[a])
print (str(values[a]) +' '+ str(keys[a]))
a = a + 1
print("Total number of items: " + str(item_total))

displayInventory(stuff)


After reviewing comments this is the new code i got:

stuff = {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}

def displayInventory(inventory):
print("Inventory:")
for key, value in inventory.items():
print(value, key)
print('Total number of items: ' +  str((sum(inventory.values()))))

displayInventory(stuff)

• You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) so that the author and other readers can learn from your thought process. Please read Why are alternative solutions not welcome? – Sᴀᴍ Onᴇᴌᴀ Oct 10 '19 at 20:12