8
\$\begingroup\$

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)
\$\endgroup\$
2
  • 9
    \$\begingroup\$ The interesting part of this task is to generate the correct plural forms from the singulars. You completely missed this one. \$\endgroup\$ Commented Jun 15, 2019 at 14:38
  • \$\begingroup\$ @RolandIllig - Please check my answer below which covers your suggestion. Thank you for pointing this out. \$\endgroup\$
    – Justin
    Commented Jun 16, 2019 at 4:13

4 Answers 4

15
\$\begingroup\$

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

The

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

instead of

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())}')
\$\endgroup\$
8
\$\begingroup\$

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 = {'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

\$\endgroup\$
4
  • \$\begingroup\$ Yes, that works. An easier way would probably be using a ternary: key = p.plural(key) if value > 1 else p.singular_noun(key) \$\endgroup\$
    – Graipher
    Commented Jun 16, 2019 at 9:42
  • 2
    \$\begingroup\$ @Graipher The documentation of the inflict package suggests p.plural(key, value). \$\endgroup\$ Commented Jun 16, 2019 at 11:07
  • \$\begingroup\$ @RolandIllig Might be, I don't know the packet. I just used the commands as they are in the post. \$\endgroup\$
    – Graipher
    Commented Jun 16, 2019 at 11:16
  • \$\begingroup\$ I'd suggest inverting the if-else, and if not then I'd suggest using if not value == 1 over if value != 1. \$\endgroup\$
    – ades
    Commented Jan 22, 2022 at 10:01
3
\$\begingroup\$

I stuck with the book's methodology since it already provided much of the code except the block but I incorporated the default sum method in my block so I don't have to create a global variable set to a false-y value. I used the f'string so I could easily print the keys and values in the required format rather than use the pprint module.

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

def display_inventory(inv):
    print(f'Inventory:')
    for key, value in inv.items():
        total = sum(inv.values())
        print(f'{value} {key}')
    print(f'Total: {total} items')
        
display_inventory(Inventory_List)
\$\endgroup\$
0
1
\$\begingroup\$

I'm doing this in June 2022 but I don't think the problem asks for plurality for the values. In the example given, all the values are worded singularly. However if you want to go one step further to include plurality, I think that's great.

As for the problem itself, I also chose to use f'string because it's easier on the eyes. However I try to leave as much of the given code as possible.

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

def displayInventory(inventory):
    print("Inventory:")
    item_total = 0
    for k, v in inventory.items():
        print(f'{v} {k}')
        item_total = sum(inventory.values())
    print("Total number of items: " + str(item_total))

displayInventory(stuff)

I feel weird because the previous practice projects are not as straightforward, but I think this is it.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.