简体   繁体   中英

Automate the Boring Stuff with Python - Chapter 5, Fantasy Game Inventory

Below is the code that I was testing:

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

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

displayInventory(stuff)

##
inv = {'gold coin':42, 'rope':1}
dragonLoot = {'gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby'}
def addToInventory(inventory, addedItems):
    for i in addedItems:
        inventory.setdefault(i, 0)
        inventory[i] += 1
    return inventory
dragonLoot = {'gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby'}
inv = addToInventory(inv, dragonLoot)
displayInventory(inv)

I expected it to return

Inventory:
45 gold coin
1 rope
1 dagger
1 ruby
Total number of items: 46

But I am only getting 43 for 'gold coin' key. Why is this?

The problem is, that you're using a set :

dragonLoot = {'gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby'}
print(dragonLoot)

Output:

{'dagger', 'gold coin', 'ruby'}

A set will make sure, every item is unique, thus the duplicate "gold coins" will be discarded.

Solution: Use a list instead:

dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby']

Output:

Inventory:
45 gold coin
1 rope
1 dagger
1 ruby
Total number of items: 48

This is how i solved it:

def toDisplay(inventory):
    print('Inventory: ')
    total_items = 0
    for i, j in inventory.items():
        total_items = total_items + j
        print(str(j)+ ' ' + i)
    print('Total items are: ' + str(total_items))
    

def toAdd(main_inven, addedItems):
    for i in addedItems:
        main_inven.setdefault(i, 0)
        main_inven[i] = main_inven[i] + 1
    return main_inven

stuff = {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}
unlocked = ['arrow', 'gold coin', 'gold coin', 'arrow', 'gold coin', 'torch', 'compass', 'ancient map']
updated_inven = toAdd(stuff, unlocked)
#print(updated_inven)
toDisplay(updated_inven)
stuff={'rope':1, 'gold coin':42}
dragonloot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby']

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

def addToInventory(inventory, addedItems):
    for i in addedItems:
        inventory.setdefault(i,0)
        inventory[i] +=1
    return inventory

inv= addToInventory(stuff,dragonloot)
displayInventory(inv)

My version converts the addedItems list into a dictionary. it merges both dictionaries together into a 3rd dictionary. then adds the values of the both dictionaries together, and stores the values into the 3rd dictionary.
lastly it renames the 3rd dictionary as inventory and returns it to the displayInventory function. It's less than elegant, but still another way to solve this problem.

def displayInventory(inventory):
    print("Inventory:")
    item_total = 0

    for k,v in inventory.items():
        #FILL THIS PART IN
        print(str(v) + ' ' + k)
        item_total= item_total + v # or use item_total += v

    print("Total number of items: " + str(item_total))
#--------------------------------------------------------------
def addToInventory(inventory, addedItems):
    # your code goes here

    addedItemCount = {}                 #this turns the addedItems into a dictionary
    for item in addedItems:             #see pg 110 characterCount.py
        addedItemCount.setdefault(item, 0)
        addedItemCount[item] = addedItemCount[item] + 1

    #this merges inventory and addItemCount dictionaries into 3rd dict
    inventoryMerge = {**inventory, **addedItemCount}
    

    for item in inventory:  #add up the values of an item using get()
        for item in addedItemCount:
            inventoryMerge[item] = inventory.get(item, 0) + addedItemCount.get(item, 0)
    
    inventory = inventoryMerge  #rename the inventoryMerge dictionary
    
    return inventory

inv = {'gold coin': 42, 'rope': 1}
dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby']
inv = addToInventory(inv, dragonLoot)
displayInventory(inv)

This is how I solved it:

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

def displayInventory(inven):
    print('Inventory:')
    count=0
    for i,j in inven.items():
        print(str(j)+' '+i)
        count=count+j
    print('Total number of items: '+ str(count))

dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby']

def addToInventory(inventory, addedItems):
    
    for i in inventory.copy():
        for j in addedItems:
            if i==j:
                inventory[i]+=1
            else:
                inventory.setdefault(j,1)
                
    return inventory

inv = addToInventory(inventoryD, dragonLoot)

displayInventory(inv)

¿What if you try to add a item that's already in the inventory?

inventory={'rope':1,'torch':2,'potion':99,'phoenix down':11}
dragonLoot={'rope':1,'dragon tail':1,'gold coin':'100','phoenix down':1}
def displayInventory(inventory):
    print("Inventory: ")
    totalnumber=0
    for k,v in inventory.items():
        totalnumber+=v
        print(k.title()+": "+str(v))
print("Total items:"+str(totalnumber))

def addToInventory(inventory,newstuff):
    for item in newstuff:
        if item in inventory.keys():
            print("Already in stock: "+item)
            inventory.update([item])
        else:    
            inventory.setdefault(str(item),1)
            inventory[item]+1

addToInventory(inventory,dragonLoot)
displayInventory(inventory)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM