pythonexceptioncs50eoferror

Why does my program exit after handling the EOFError instead of running the code inside the exception?


I want to print out a dictionary's contents after the user inputs ctrl-d, and while the program handles the exception for the EOFError, it doesn't carry out the code inside the exception.

my code is:

grocery_list = {}
while True:
    try:
        item = input("")
        for product in grocery_list:
            if item.strip().lower() == product:
                grocery_list[product] += 1
            else:
                grocery_list[item.strip().lower()] = 1
    except EOFError:
        for product in grocery_list:
            print(f"{grocery_list[product]} {product.upper()}")
        exit()

this is the code i particularly need executed

        for product in grocery_list:
            print(f"{grocery_list[product]} {product.upper()}")

i expected something like:

1 APPLE
2 BANANA
1 SUGAR

once the user inputs ctrl-d if the user entered apple once, banana twice, and sugar once prior.

but upon hitting ctrl-d the program just ends

strangely enough, when i just print within the exception

    except EOFError:
        print("x")
        exit()

it does carry out and prints

x

could anyone explain?


Solution

  • Your logic is incorrect for updating the dictionary. Consider the following:

    grocery_list = {}
    while True:
        for product in grocery_list:
            ...
    

    There are no items in grocery_list so the for loop is going to be a no-op. You then have this wrapped in a while True loop, which is going to run forever, doing nothing on each of its iterations.

    Another issue with this code is that you put the try/except blocks within the for loop. You use a call to exit() to escape the loop in the exception handler, but you could simply move the try/except and avoid needing to manually exit.


    What you probably want to use is a defaultdict, which will initialize values to a sane default when you access the dictionary with a key not yet assigned. defaultdict(int) will set the value for a key to 0 when accessed for a missing key, and otherwise return the stored value.

    from collections import defaultdict
    
    grocery_list = defaultdict(int)
    try:
        while True:
            item = input("")
            product = item.strip().lower()
            grocery_list[product] += 1
    except EOFError:
        for product in grocery_list:
            print(f"{grocery_list[product]} {product.upper()}")