Concepts / Program Flow Control with Conditionals

Program Flow Control with Conditionals

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.

  • 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.

Key point

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

Filenameuser inputopen(filename)try blockFile openedcontinue after try/exceptError messagerecovery codeOpening errorexcept blocksupplies filenamesucceedsfailsjumps to
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

Code walkthrough
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)
  1. 1
    The input statement obtains a filename from the user.
  2. 2
    The try block contains the risky open operation.
  3. 3
    If open succeeds, fhand is assigned and Python skips the except block.
  4. 4
    If open fails, Python jumps to the except block.
  5. 5
    The except block prints a helpful message and calls exit().
  6. 6
    When the file is available, the later statements count lines that start with "Subject:" and print the 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

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

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.

  1. 1
    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.

  2. 2
    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().

  3. 3
    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.

Result

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

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

Recovery or Termination

Recovery codefor example, print amessageContinueonly if safeexit()inside exceptProgram endsimmediatelyhandles problemterminates
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

  • Common mistake

    Putting the risky file operation outside the try block.

    What it looks like
    fhand = open(filename)
    try:
        print("File opened")
    Why it fails

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

    Do this instead

    Place the open operation inside the try block.

  • Common mistake

    Assuming the except block runs after every try block.

    What it looks like

    The file opens successfully, but the program still expects the except block to run.

    Why it fails

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

    Do this instead

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

  • Common mistake

    Calling exit() without explaining the failure.

    What it looks like
    except:
        exit()
    Why it fails

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

    Do this instead

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

  • Common mistake

    Continuing to use the file after opening failed.

    What it looks like
    except:
        print("Could not open file")
    print(fhand)
    Why it fails

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

    Do this instead

    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. 1
    Use try around a risky operation such as opening a file.
  2. 2
    If the try block succeeds, Python skips except and continues after the structure.
  3. 3
    If the try block fails, Python immediately jumps to except.
  4. 4
    Use the except block to provide a helpful error message and decide whether the program can continue.
  5. 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.

Related concepts

More concepts starting with P