Search code examples
pythonfor-loopwhile-loopglobal-variableslocal-variables

Python global and local variable: How does the code work?


I came across a code that allows users to enter a fruit name. Based on the input, it will be searched for from the basket list and show its quantity if the fruit is on the list.

If the fruit is not found, users can enter the quantity for that fruit and add it to the list.

basket = [
    {'fruit': 'apple', 'qty': 20},
    {'fruit': 'banana', 'qty': 30},
    {'fruit': 'orange', 'qty': 10}
]

fruit = input('Enter a fruit:')

index = 0
found_it = False

while index < len(basket):
    item = basket[index]
    # check the fruit name
    if item['fruit'] == fruit:
        found_it = True
        print(f"Basket has {item['qty']} {item['fruit']}(s)")
        break

    index += 1

if not found_it:
    qty = int(input(f'Enter the qty for {fruit}:'))
    basket.append({'fruit': fruit, 'qty': qty})
    print(basket)

But I don't understand the logic of the outer if condition. Which found_it is it referring to? The one defined before (global) the while statement or the one in it (local)? How does the outer if work?


Solution

  • This is not really an answer, but shows you how to sidestep the issue of using a mutable value at all to make decisions about what to do next.


    Note that Python has a while-else construct that makes the found_it variable unnecessary.

    basket = [
        {'fruit': 'apple', 'qty': 20},
        {'fruit': 'banana', 'qty': 30},
        {'fruit': 'orange', 'qty': 10}
    ]
    
    fruit = input('Enter a fruit:')
    
    index = 0
    
    while index < len(basket):
        item = basket[index]
        # check the fruit name
        if item['fruit'] == fruit:
            print(f"Basket has {item['qty']} {item['fruit']}(s)")
            break
    
        index += 1
    else:
        qty = int(input(f'Enter the qty for {fruit}:'))
        basket.append({'fruit': fruit, 'qty': qty})
        print(basket)
    

    The else clause of the loop only executes if break wasn't used to exit the loop, i.e., when you would have changed the value of found_it.


    Somewhat unrelated, you can iterate over the elements of basket directly, without bothering with an index.

    basket = [
        {'fruit': 'apple', 'qty': 20},
        {'fruit': 'banana', 'qty': 30},
        {'fruit': 'orange', 'qty': 10}
    ]
    
    fruit = input('Enter a fruit:')
    
    for item in basket:
        # check the fruit name
        if item['fruit'] == fruit:
            print(f"Basket has {item['qty']} {item['fruit']}(s)")
            break
    else:
        qty = int(input(f'Enter the qty for {fruit}:'))
        basket.append({'fruit': fruit, 'qty': qty})
        print(basket)
    

    else behaves the same way with for as with while: it only executes if the loop exits "naturally", in this case by exhausting the iterator rather than when the loop condition becomes false.