Search code examples
pythonfunctiondictionaryfor-loopnested

Nested dictionary for loop with def (INDENTENTION PROBLEM)


I am learning Python with the 2°Ed. Automate the boring stuff with python, and I came across with a indentention problem.

Can someone explain what I am doing wrong?

I am trying to add a indentention after the for loop to insert the num_brought value, but it keeps getting an error: TypeError: unsupported operand type(s) for +: 'int' and 'str'.

Book code:

allGuests = {'Alice': {'apples': 5, 'pretzels': 12},
             'Bob': {'ham sandwiches': 3, 'apples': 2},
             'Carol': {'cups': 3, 'apple pies': 1}}

def totalBrought(guests, item):
    numBrought = 0
    for k, v in guests.items():
        numBrought = numBrought + v.get(item, 0)
    return numBrought
    
print('Number of things being brought:')
print(' - Apples         ' + str(totalBrought(allGuests, 'apples')))
print(' - Cups           ' + str(totalBrought(allGuests, 'cups')))
print(' - Cakes          ' + str(totalBrought(allGuests, 'cakes')))
print(' - Ham Sandwiches ' + str(totalBrought(allGuests, 'ham sandwiches')))
print(' - Apple Pies     ' + str(totalBrought(allGuests, 'apple pies')))

My code:

all_guests = {
    'Alice': {'apple': 1, 'ham': 2},
    'Joe': {'potato': 7, 'beer': 7},
    'Carl': {'apple': 3, 'beer': 'none'}}

def total_brought(guest, item):
    num_brought = 0
    for k, v in guest.items():
        num_brought = num_brought + v.get(item, 0)
    return num_brought

print('Total brought: ')
print('Apples: ' + str(total_brought(all_guests, 'apple')))
print('Beer: ' + str(total_brought(all_guests, 'beer')))
print('Ham: ' + str(total_brought(all_guests, 'ham')))
print('Potato: ' + str(total_brought(all_guests, 'potato')))

Solution

  • The issue is your data, not your indentation. On this line

    num_brought = num_brought + v.get(item, 0)
    

    you add num_brought (a number) to a value of one of the dictionaries in allGuests. In the book, all of those values are numbers too, but in your data, one of them is the string 'none' (allGuests['Carl']['beer']).

    The solution is to just change that data to 0, as the number zero means having nothing, or "none":

    all_guests = {
        'Alice': {'apple': 1, 'ham': 2},
        'Joe': {'potato': 7, 'beer': 7},
        'Carl': {'apple': 3, 'beer': 0}}
    
    def total_brought(guest, item):
        num_brought = 0
        for k, v in guest.items():
            num_brought = num_brought + v.get(item, 0)
        return num_brought
    
    print('Total brought: ')
    print('Apples: ' + str(total_brought(all_guests, 'apple')))
    print('Beer: ' + str(total_brought(all_guests, 'beer')))
    print('Ham: ' + str(total_brought(all_guests, 'ham')))
    print('Potato: ' + str(total_brought(all_guests, 'potato')))
    

    Alternatively, you can check for the value 'none' and change it to zero in your function:

    all_guests = {
        'Alice': {'apple': 1, 'ham': 2},
        'Joe': {'potato': 7, 'beer': 7},
        'Carl': {'apple': 3, 'beer': 'none'}}
    
    def total_brought(guest, item):
        num_brought = 0
        for k, v in guest.items():
            val = v.get(item, 0)
            if val == 'none':
                val = 0
    
            num_brought = num_brought + val
        return num_brought
    
    print('Total brought: ')
    print('Apples: ' + str(total_brought(all_guests, 'apple')))
    print('Beer: ' + str(total_brought(all_guests, 'beer')))
    print('Ham: ' + str(total_brought(all_guests, 'ham')))
    print('Potato: ' + str(total_brought(all_guests, 'potato')))