This is the List to Dictionary Function for Fantasy Game Inventory project in Chapter 5.
The project is as follows:
Write a function named addToInventory(inventory, addedItems), where the inventory parameter is a dictionary representing the player’s inventory (like in the previous project) and the addedItems parameter is a list like dragonLoot. The addToInventory() function should return a dictionary that represents the updated inventory. Note that the addedItems list can contain multiples of the same item.
I believe I've filled the requirements but I wondered if I was doing something inefficiently.
My code:
def display_inventory(inventory):
total_items = 0
print ("Inventory:")
for item in inventory.keys():
print(str(inventory[item]) + ' ' + item)
total_items += inventory[item]
print("Total number of items: " + str(total_items))
def addToInventory(inventory, addedItems):
for item in addedItems:
if item in inventory:
inventory[item] += 1
else:
inventory.setdefault(item, 1)
inv = {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}
dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby', 'torch']
addToInventory(inv, dragonLoot)
display_inventory(inv)
1 Answer 1
Put all code in functions. Even the usage-demo code. This is one of many bug-avoidance and testability-supporting habits that experienced programmers adopt.
Should the function return a new inventory or modify the current one? The
text says we should "return a dictionary", but the suggested function name
implies that we should modify/update the current inventory. This distinction is
crucial in software engineering, and it's unfortunate that the book is so
confused on this topic. Your code updates the current inventory (and returns
None
). Absent a compelling reason to do otherwise, one should prefer
functions that return new data rather than functions that modify data they are
given. There are many reasons for no-mutation as the default approach when
writing functions, and I would encourage you to learn more about them.
If you need to count things, consider using a Counter. Python includes a dict-like data structure designed explicitly for counting things.
Displaying an inventory: take better advantage dict, print, and sum.
Your code to display an inventory is overly complex. The print()
function
automatically converts its arguments to str
, so you don't need to
bother with that. It seems handier to iterate over both keys and values.
And there's no need to add up the values yourself: let sum()
do the work.
Pick a naming convention. Some of your code doesThis
and some of it
does_this
. I see the latter more often in Python. Here's the code I ended
up with.
import sys
from collections import Counter
def main():
inv_initial = {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}
dragon_loot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby', 'torch']
inv_new = updated_inventory(inv_initial, dragon_loot)
display_inventory(inv_initial, 'initial')
display_inventory(inv_new, 'new')
def updated_inventory(inventory, added):
c = Counter(inventory)
c.update(added)
return dict(c)
def display_inventory(inventory, label = ''):
total = sum(inventory.values())
print(f'Inventory: {label} (total: {total})')
for item, n in inventory.items():
print(f' {item}: {n}')
if __name__ == '__main__':
main()
inv
anddragonLoot
made this much more readable, thanks \$\endgroup\$