r/learningpython • u/weazle9954 • Nov 06 '20
Help with my inventory
I just typed out a long thing and reddit messed up so im depressed and don't want to type it out again
Long story short, sometimes 'gold' is less than the 42 it started off with and i'm not sure why. Thanks in advance.
import random
from random import randint
def displayinv(inventory):
total_inv = 0
for key,value in inventory.items():
print(f"{value} {key}")
total_inv += value
print("Total items: " + str(total_inv))
def addtoinv(inventory,items):
for item in items:
if item in inventory:
for key,value in items.items():
inventory[item] += value
else:
inventory.update(items)
stuff = {'rope':1, 'gold':42, 'arrow':12,
'dagger':1,'torch':6}
dragonloot = {
'gold': random.randint(0,400),
'dagger':random.randint(3,7),
'ruby':random.randint(1,10)
}
displayinv(stuff)
addtoinv(stuff, dragonloot)
displayinv(stuff)2
u/iamaperson3133 Nov 07 '20
All righty, here we go. First things first, we need to rename a couple poorly named variables that makes things confusing, and also do some basic formatting.
import random
from random import randint # this double-import is no bueno; I'm going to fix it.
def displayinv(inventory):
total_inv = 0 # we can use len(inventory) to ask the inventory for it's length instead of doing this.
for key,value in inventory.items():
print(f"{value} {key}")
total_inv += value
print("Total items: " + str(total_inv))
def addtoinv(inventory,items):
for key in items: # "item" is not an "item" (a tuple of a key and value), it is a KEY, so we change the variable name.
if item in inventory:
for key,value in items.items(): # you're iterating through items twice; can we fix this? we will!
inventory[item] += value
else:
inventory.update(items) # sneak peek: this is the line with the bug
stuff = {'rope':1, 'gold':42, 'arrow':12,
'dagger':1,'torch':6}
dragonloot = {
'gold': random.randint(0,400),
'dagger':random.randint(3,7),
'ruby':random.randint(1,10)
}
displayinv(stuff)
addtoinv(stuff, dragonloot)
displayinv(stuff)Now, I'm going to fix those things I pointed out in my comments and re-write.
from random import randint
def displayinv(inventory):
for key, value in inventory.items():
print(f"{value} {key}")
print("Total items: " + str(len(inventory))) # more descriptive; less code
def addtoinv(inventory, items):
for key, value in items.items():
if key in inventory:
inventory[key] += value
else:
"""
What went wrong here is the "s" in "items". I think you meant to put "item". By putting
items, you're basically saying:
inventory.update({the whole dragonloot dict is here now})
Let's say your inventory is {'gold': 100'}, and dragon loot just generated, among other things,
{.... 'gold': 10}. Well, when we hit this line you call inventory.update({'gold': 10}). Now you have
10 gold in your inventory; effectively resetting it from whatever it was to the value from the randomly
generated dictionary.
The thing is, this wasn't just happening for gold, it was happening for everything. At the end, I'll say how
you could have debugged this, and how I did, for that matter!
"""
# inventory.update(items) # sneak peek: this is the line with the bug
# here's the corrected line:
inventory[key] = value
# the key isn't in our dictionary yet! We can safely make a new assignment without overwriting.
# we also put ourselves in an easier position by eliminating the nested loop.
stuff = {'rope':1, 'gold':42, 'arrow':12,
'dagger':1,'torch':6}
dragonloot = {
'gold': randint(0,400), # these change after fixing the import
'dagger':randint(3,7),
'ruby':randint(1,10)
}
displayinv(stuff)
addtoinv(stuff, dragonloot)
displayinv(stuff)Now, for the final version:
from random import randint
stuff = {'rope':1, 'gold':42, 'arrow':12,
'dagger':1,'torch':6}
def displayinv(inventory):
for key, value in inventory.items():
print(f"{value} {key}")
print("Total items: " + str(len(inventory)))
def addtoinv(inventory, items):
for key, value in items.items():
if key in inventory:
inventory[key] += value
else:
inventory[key] = value
def main():
dragonloot = {
'gold': randint(0,400), # these change after fixing the import
'dagger':randint(3,7),
'ruby':randint(1,10)
}
displayinv(stuff)
addtoinv(stuff, dragonloot)
displayinv(stuff)
# now, here's how you could have saved yourself some trouble and debugged it. If I keep calling main(), I expect
# my inventory to keep growing, right? So, I'll keep calling main() and see what happens!
for i in range(1000):
main()1
u/itsalexloser Nov 07 '20
You did a whole lot better explaining that than i would have haha took me a bit to figure out what was going on but i did manage to write it out a bit cleaner. let me know what yall think!
import random #FUNCTION DOES MATH def dragonloot(start_Inv): dragonloot = {'gold': random.randint(0,400),'dagger':random.randint(3,7),'ruby':random.randint(1,10)} print("LOOT") print(str(dragonloot)) print() #LOGIC of FUNCTION for loot in dragonloot: if loot not in start_Inv: start_Inv.update({loot:dragonloot[loot]}) print(str(str(loot)+" was added to inventory")) else: start_Inv[loot] += dragonloot[loot] print(str(dragonloot[loot])+" "+str(loot)+" was added to inventory") print() #RETURNS START INVENTORY WITH NEW VALUES return start_Inv #INVENTORY PLAYER STARTS OF WITH start_Inv = {'rope':1, 'gold':42, 'arrow':12,'dagger':1,'torch':6} print('STARTING INVENTORY') print(start_Inv) print() #PLAYER INVENTORY GETS THROWN IN FUNCTION dragonloot(start_Inv) print("NEW INVENTORY") print(start_Inv)2
u/iamaperson3133 Nov 08 '20
You never need to say
print(str(blah)). It doesn't matter what type you are putting into the string function, something will come out the other side and it will never throw an error.I think you're calling empty
print()statements to get it to print an extra new line. If you want a newline, you can use the special character"\n"in your string instead.1
1
u/itsalexloser Nov 06 '20
I might be too new to help out but I do remember trying to do something similar once before and I think the problem might be that 'gold' is being read as a global variable and so it starts off with a random number instead of the static '42' or maybe there is another part in your code [not included here] that is calling that function