Skip to Content
Course content

139: Exceptions and the Try/Except Block

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've noticed a lot of developers coming from C++ or Java carry a habit into Python that I call "defensive hoarding." They spend half their function writing checks to make sure nothing goes wrong before they actually perform the operation. In the industry, we call this LBYL: Look Before You Leap. It seems intuitive, but in Python, it often leads to brittle code that misses edge cases.

The "Look Before You Leap" Trap

Let's say you're writing a piece of code that takes a user's input—maybe a character's level for a game—and converts it to an integer. A naive approach looks like this:

def set_character_level(user_input):
    if user_input.isdigit():
        level = int(user_input)
        print(f"Level set to {level}")
    else:
        print("That's not a valid number!")

At first glance, this looks safe. You checked if it was a digit, so int() won't crash, right? Not exactly. What happens if the user enters "-5"? isdigit() returns False because the minus sign isn't a digit, even though int("-5") is perfectly valid Python. Or what if there's a trailing space? You end up writing a mountain of if/elif statements just to validate a single piece of data. You're trying to predict every possible way the input could be "wrong," which is a losing battle.

Embracing the Crash with Try/Except

The Pythonic way is to embrace a philosophy called EAFP: Easier to Ask Forgiveness than Permission. Instead of trying to predict the failure, we just try the operation and handle the fallout if it blows up. This is where the try/except block comes in.

def set_character_level(user_input):
    try:
        level = int(user_input)
        print(f"Level set to {level}")
    except ValueError:
        print("That's not a valid number!")

Notice how much cleaner this is. I'm not guessing if the string is "digit-like." I'm telling Python: "Try to make this an integer. If it's impossible, Python will throw a ValueError. When that happens, stop panicking and run this recovery code instead." By catching the specific ValueError, we handle the failure exactly when and where it happens, without worrying about minus signs or weird whitespace.

The Trade-off: Precision vs. Prediction

You might wonder if this is "sloppy" because we're letting an error happen. In reality, it's more precise. When you use isdigit(), you're creating your own arbitrary rule for what a "number" is. When you use try/except, you're relying on the language's own internal logic for what constitutes a valid integer.

One word of warning, though: never use a "bare" except. I've seen juniors do this:

try:
    do_something()
except:
    print("Something went wrong")

This is a nightmare to debug. A bare except catches everything, including KeyboardInterrupt (when you try to hit Ctrl+C to stop the program) or MemoryError. You'll find yourself staring at a "Something went wrong" message while your program is actually crashing because of a typo in a variable name (a NameError) that you accidentally suppressed. Always name the specific exception you expect—like ValueError, TypeError, or FileNotFoundError—so you don't accidentally hide bugs that you actually need to see.




📋 Practical Task

Sanitizing the Corrupted High Score File

You've been handed a text file called scores.txt that contains a list of high scores, one per line. However, the file is corrupted; some lines contain actual numbers, while others contain random text fragments or empty lines.

Write a script that does the following:

  • Reads each line of the file scores.txt.
  • Attempts to convert the line to an integer.
  • If successful, adds the score to a list called valid_scores.
  • If a ValueError occurs, prints a message saying "Skipping invalid entry: [the value]" and continues to the next line without crashing.
  • Finally, prints the sum of all valid_scores.

Setup: Before running your code, create a file named scores.txt with the following content:

100
250
corrupted_data
500
 
broken_score
1000
Rating
0 0

There are no comments for now.

to be the first to leave a comment.