CS50 taqueria task – input of eof halts program

Question:

I am trying to solve the taqueria task for the Harvard CS50 python course. It generally works, but check50 spits out the following:

🙁 input of EOF halts program
Cause
expected exit code 0, not 1

This is my code:

menu = {
    "Baja Taco": 4.00,
    "Burrito": 7.50,
    "Bowl": 8.50,
    "Nachos": 11.00,
    "Quesadilla": 8.50,
    "Super Burrito": 8.50,
    "Super Quesadilla": 9.50,
    "Taco": 3.00,
    "Tortilla Salad": 8.00
}

def main():
    item = get_dish("Item: ")
    total = 0
    try:
        while True:
            try:
                total += menu[item.title()]
                print("$" + str(round(total, 3)))
                item = get_dish("Item: ")
            except KeyError:
                item = get_dish("Item: ")
                pass
    except EOFError:
        pass

def get_dish(prompt):
    dish = input(prompt)
    while dish.lower() in menu == False:
        dish = input(prompt)
    else:
        return dish

main()

I cannot end input to induce an EOFError in VS Code on GitHub myself by pressing ctrl + z or ctrl + d. Therefore, I cannot handle it myself in the try… except block. It might be a problem with the VS Code itself. Maybe there are other ways to end input, induce an EORError and handle it in the code.

Asked By: Mikołaj Przygoda

||

Answers:

Method 1: provide an empty input file

You can reproduce an EOFError in your code by giving it an empty input file.

In the VSCode terminal using bash, or at a bash prompt:

$ python script_name.py < /dev/null
Item: Traceback (most recent call last):
  File "C:Usersmesandboxesscratchscript_name.py", line 35, in <module>
    main()
  File "C:Usersmesandboxesscratchscript_name.py", line 14, in main
    item = get_dish("Item: ")
  File "C:Usersmesandboxesscratchscript_name.py", line 29, in get_dish
    dish = input(prompt)
EOFError: EOF when reading a line

Or if you’re using the Windows cmd prompt, in a VSCode terminal or otherwise:

> python script_name.py < NUL
Item: Traceback (most recent call last):
  File "C:Usersmesandboxesscratchscript_name.py", line 35, in <module>
    main()
  File "C:Usersmesandboxesscratchscript_name.py", line 14, in main
    item = get_dish("Item: ")
  File "C:Usersmesandboxesscratchscript_name.py", line 29, in get_dish
    dish = input(prompt)
EOFError

In both cases above, you could also create a file to use as input, and have it empty when that’s what you want to test, but /dev/null / NUL is the bash/cmd name for the special system empty file you can always use instead of creating one.

And as you see in these traces, the problem is that your first call to get_dish() is not in a try/except block.

Method 2: interactively end the input stream

In cmd, just type ^Z+Enter and that’ll trigger the EOF and reproduce the same error.

To my surprise, in bash the equivalent ^D doesn’t automatically do the same thing. I expected it would, as is typical, but instead when you type ^D+Enter you get "x04" as the string returned by input(). So I guess if your program wants to accept ^D+Enter to mean end of file, it would have to explicitly do so with a piece of logic like if dish == "x04": raise EOFError in get_dish(), but I understand you’re just trying to debug your code and reproduce the error check50 gives you, so this is not too helpful.

So… if you’re working in a bash terminal, use method 1 above.

When you’ve got things working, you’ll probably want to add something to get_dish() for the user to signify they’re done, like accepting q to mean done, because as it is, your user won’t be able to exit the program cleanly, at least not from a bash terminal.

Answered By: joanis

I think the issue is that when EOFError is raised, your code is not exiting gracefully – it is just catching the error and then continuing. To fix this:

Remove the bare except EOFError: – This catches the error but doesn’t handle it.

In your while loop, check for EOFError specifically and break out of the loop:

```
while True:
  try:
    item = get_dish("Item: ")
    
    total += menu[item.title()]
    print("$" + str(round(total, 2))
  
  except EOFError:
    break  # Exit loop
  
  except KeyError:
    item = get_dish("Item: ")
    pass
```

After the loop, print out the total:

```print(f"Total: ${total:.2f}")```

This way, when EOFError is caught, it will break out of the loop, and then your code will print the total and exit cleanly with exit code 0.

The key points:

  • Catch EOFError specifically in the loop
  • Break out of the loop to handle EOF
  • Print total after loop instead of bare except
  • This will allow the program to exit properly on EOF

I hope this helps!

Answered By: Thabhelo
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.