Concepts / Program Flow Control with Conditionals

Program Flow Control with Conditionals

The try/except structure catches errors in risky code (like opening files) and runs recovery code in the except block instead of crashing.

  • Programming

When File Opening Fails

A program that opens a file makes an assumption: the filename supplied by the user refers to a file that exists and can be read. That assumption may be wrong. A user might enter a filename that does not exist or type text such as "na na boo boo" instead of a real filename. Without protection, the program crashes and the user sees a confusing traceback. The try/except structure lets the program anticipate this failure and respond with a helpful message.

The try block contains code that might fail. The except block contains recovery code that runs only when something goes wrong in the try block.

The Two Control-Flow Paths

supplies filenamesucceedsfailsjumps toFilenameuser inputopen(filename)try blockFile openedcontinue after try/exceptError messagerecovery codeOpening errorexcept block
What happens next when the file-opening operation succeeds versus when it raises an error?

Python chooses one of two paths. If the try block succeeds, Python skips the except block entirely and execution continues after the try/except structure. If the try block fails, Python immediately jumps to the except block. The statements after the structure run only if the program continues past it; they do not run if the except block calls exit().

A Protected File Operation

filename = input("Enter a filename: ") try: fhand = open(filename) except: print("Unable to open the file. Please check the filename.") exit() count = 0 for line in fhand: if line.startswith("Subject:"): count = count + 1 print("Subject lines:", count)

This example follows the file-opening scenario described in the source. The rest of the program depends on fhand being a valid file object. If opening the file fails, continuing would not make sense, so the recovery code reports the problem and terminates the program instead of allowing a later operation to fail.

Tracing Success and Failure

failsjumps to exceptcalls exit()File operationinside tryOpening errortry failsHelpful messageinside exceptProgram endsexit()
How does control move from the risky file operation to recovery code instead of allowing the program to crash?

Two runs of the file-opening program

Trace what happens when the user enters a valid filename and when the user enters an invalid filename.

Valid filename: With a filename such as "mbox.txt", the open call succeeds. fhand is assigned, the except block is skipped, and the program counts and prints the subject lines.

Invalid filename: With a filename such as "na na boo boo", the open call fails. Python immediately jumps to the except block, which prints the helpful error message and calls exit().

Statements after the structure: The counting loop and print statement run on the successful path. They never run after the invalid filename because exit() terminates the program immediately.

The valid run continues to the file-processing code. The invalid run reports the problem and exits without showing a traceback.

succeedsthenfailsthenopen(filename)tryCount subjectssuccess pathPrint countsuccess pathError messagefailure pathexit()failure path
Which statements run on the success path, which run on the failure path, and where does execution end?

Recovery or Termination

handles problemterminatesRecovery codefor example, print amessageContinueonly if safeexit()inside exceptProgram endsimmediately
What is the difference between running recovery code and calling exit() to stop the program?

Entering the except block is not the same as ending the program. The except block is recovery code: it can print a message and, when appropriate, allow a program to continue. Calling exit() is a separate decision. It terminates the program immediately. In the file example, termination is appropriate because the later processing depends on fhand being a valid file object.

Mistakes with try/except

  • Putting the risky file operation outside the try block.

    The operation that may fail is not protected by try, so the except block cannot handle its failure.

    Fix: Place the open operation inside the try block.

  • Assuming the except block runs after every try block.

    When the try block succeeds, Python skips the except block entirely.

    Fix: Put success-path statements after the try/except structure.

  • Calling exit() without explaining the failure.

    The program ends, but the user is not told what went wrong.

    Fix: Print a helpful error message in the except block before calling exit().

  • Continuing to use the file after opening failed.

    The rest of the program depends on fhand being a valid file object.

    Fix: Call exit() when the failed file operation makes it impossible to proceed.

Practice the Paths

What do you think happens?

Suppose the user enters an invalid filename. Which part of the program runs next?

  • The file-processing loop
  • The except block
  • The statements after the except block
  • Nothing, without any message
Reveal answer

Answer: The except block

When the open operation in the try block fails, Python immediately jumps to the except block. If that block calls exit(), the later loop and print statement do not run.

MEDIUM

Trace both paths in the file-opening example. For a valid filename, identify which statements run after the try/except structure. For an invalid filename, identify the message that should be shown and explain why the counting loop does not run.

Hints
  • A successful try block skips except.
  • A failed try block transfers control immediately to except.
  • exit() stops the program immediately.

Graceful Failure

  1. Use try around a risky operation such as opening a file.
  2. If the try block succeeds, Python skips except and continues after the structure.
  3. If the try block fails, Python immediately jumps to except.
  4. Use the except block to provide a helpful error message and decide whether the program can continue.
  5. Use exit() when the failure makes it impossible to proceed safely; it terminates the program immediately.

Key Takeaways

  • try/except gives a program separate success and failure paths for risky operations.
  • A successful try block skips except, while a failed try block immediately enters except.
  • The except block should explain the problem clearly to the user.
  • exit() terminates the program and is appropriate when later code cannot safely continue.
  • Handling predictable file failures this way prevents confusing tracebacks and makes programs more user-friendly.