Including an if statement for a merged dictionary causes 'TypeError: 'int' object is not callable

Viewed 37

First time poster here and Python newbie.

To get to grips with the basics of Python I've started by reading Automate The Boring Stuff by Al Sweigart, and there was one mini project that I thought I'd try my hand in, which was the "Fantasy Inventory" project. I managed to figure out how it works with some trial and error (and a lot of Googling), but here's the final code:

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

def displayInventory(inventory):
    total_items = 0
    for item, quantity in inventory.items():
        print(str(quantity) + ' ' + item)
        total_items += quantity
    print("Total number of items: " + str(total_items))

displayInventory(stuff)

I decided to try and include a "precious minerals" dictionary so that it would add a little extra flavour to the text, including an if and elif statement if the preciousMineral total was 0 or more than 0. The code now looks like this:

stuff = {'arrows': 41, 'sword': 1, 'dagger': 2, 'torch': 1}
preciousMinerals = {'rubies': 0, 'emeralds': 0, 'sapphires': 0}
stuffAndMinerals = stuff|preciousMinerals

def displayInventory(inventory):
    total_items = 0
    for item, quantity in inventory.items():
        print(str(quantity) + ' ' + item)
        total_items += quantity
    print('You have a total of ' + str(total_items) + ' items in your bag.')
    if str(quantity(preciousMinerals)) == 0:
        print('You have no precious minerals.')
    elif str(quantity(preciousMinerals)) > 0:
        print('You have some precious minerals in your bag.')
        print('You have: ' + str(quantity(preciousMinerals[0]) + ', ' +
                             str(quantity(preciousMinerals[1]) + ', ' +
                             str(quantity(preciousMinerals[2]) + '.'))))
displayInventory(stuffAndMinerals)

Before adding the precious minerals, the code ran smoothly with no errors. However, I now get a 'TypeError: 'int' object is not callable' error on line:

if str(quantity(preciousMinerals)) == 0:

Any help would be greatly appreciated! Thank you very much.

3 Answers

You are trying to call quantity which is an int with preciousMinerals here:

if str(quantity(preciousMinerals)) == 0: I'd advice you to keep track of what types you are using in your code. Every type has its own capabilities and some can't do things and some can.

This will work just fine for you:

stuff = {'arrows': 41, 'sword': 1, 'dagger': 2, 'torch': 1}
precious_minerals = {'rubies': 1, 'emeralds': 0, 'sapphires': 0}
stuff_and_minerals = stuff|precious_minerals

def display_inventory(inventory):
    total_items = 0
    for item, quantity in inventory.items():
        print(f"You have {quantity} {item}")
        total_items += quantity

    print(f"You have a total of {total_items} items in your bag.")

    if sum(precious_minerals.values()) == 0:
        print('You have no precious minerals.')
    elif sum(precious_minerals.values()) > 0:
        print('You have some precious minerals in your bag.')
        for item, quantity in precious_minerals.items():
            print(f"You have {quantity} {item}")

display_inventory(stuff_and_minerals)

Here's the code that seems to work, I hope it's what you've asked for:

#!/usr/bin/env python3

stuff = {'arrows': 41, 'sword': 1, 'dagger': 2, 'torch': 1}
preciousMinerals = {'rubies': 0, 'emeralds': 2, 'sapphires': 1}
stuffAndMinerals = stuff|preciousMinerals

def displayInventory(inventory):
    total_items = 0
    for item, quantity in inventory.items():
        print(str(quantity) + ' ' + item)
        total_items += quantity
    print('You have a total of ' + str(total_items) + ' items in your bag.')

    if sum(preciousMinerals.values()) == 0: # get the content of preciousMinerals, will look like dict_values[0, 2, 1] in this case
                                            # won't tell anything about dict_valuesm see more here (recommended): https://stackoverflow.com/questions/33674033/python-how-to-convert-a-dictionary-into-a-subscriptable-array
        print('You have no precious minerals.')
    elif sum(preciousMinerals.values()) > 0:
        print('You have some precious minerals in your bag.')
        nrOfAllPreciousMinerals = list(preciousMinerals.values()) # remember: list(dict_values[0, 2, 1]) => removes the dict_values, see the link above

        # count the number of minerals greater than 0
        nrOfYourPreciousMinerals = 0
        for mineral in nrOfAllPreciousMinerals:
            if mineral > 0:
                nrOfYourPreciousMinerals += 1


        print("You have: ", end="") # end="" removes the newline
        i = 0
        for item in preciousMinerals:
            if preciousMinerals[item] != 0:
                print(item, end="")
                if nrOfYourPreciousMinerals > i+1: # +1 because enumerate() starts counting at zero
                    print(",", end=" ") # end=SomeString defines what shall be printed if the whole print() is done - in this case it's a space
                else:
                    print(".")

                i += 1





displayInventory(stuffAndMinerals)

The comments might clarify what I did. I don't know what you were trying to do and why you did that.

If you've got a question, please comment.

Before anything, I think that you age mixing your inventory variable that is passed into your function, with the variable preciousMinerals that is declared outside your function.

Also, you are trying to use quantity outside of its scope (which is the for loop), and call it like if it was a function, while it is a number instead.

Let me try to help you with a reference implementation, so hopefully things will become more clear:

# keep a list of known items and their categories
catalog = {
  'boring items': {'arrows', 'sword', 'dagger', 'torch'},
  'precious minerals': {'rubies', 'emeralds', 'sapphires'}
}

def displayInventory(inventory):
  if not any(inventory.values()):
    print('You do not have anything, get out!')
    return
  remaining = set(inventory.keys())
  for category, cat_items in catalog.items():
    matching = {itm: inventory[itm] for itm in (remaining & cat_items)}
    if not any(matching.values()):
      print(f'You have no {category}.')
      continue
    print(f'These are all the {category} you have:')
    print(*(f'  {k} {v}' for k, v in matching.items()), sep=',\n')
    print(f'  You have a total of {sum(matching.values())} {category} in your bag.')
    remaining.difference_update(cat_items)
  if any(remaining):
    matching = {itm: inventory[itm] for itm in remaining}
    print('You have some unknown items:')
    print(*(f'  {k} {v}' for k, v in matching.items()), sep=',\n')


displayInventory({'arrows': 41, 'sword': 1, 'dagger': 2, 'torch': 1})
displayInventory({'rubies': 0, 'emeralds': 0, 'sapphires': 0})
displayInventory({'rubies': 4, 'torch': 7, 'dagger': 0, 'cheese': 4})
Related