Exception Handling — Practice Questions
50 questions. Try each one yourself before checking the answer.
Write a try/except that attempts 10 / 0 and prints "Cannot divide by zero" when it fails.
Ask the user for a number using input() and int(). Catch the ValueError that happens if they type non-numeric text, printing "That's not a valid number".
Catch a ZeroDivisionError and print the actual error message using as e.
Write a try/except around 5 + 5 (which never fails) and print the result, showing that the except block simply never runs.
Given numbers = [1, 2, 3], write separate except blocks that catch IndexError (accessing numbers[10]) and ZeroDivisionError (dividing by numbers[0] - 1) as two independent examples.
Write a try/except Exception that catches ANY error type and prints a generic message plus the error text.
Given fruits = ["apple", "banana"], try to access fruits[5] and catch the IndexError, printing "Index out of range".
Given person = {"name": "Bob"}, try to access person["age"] and catch the KeyError, printing "Key not found".
Try to add a string and an integer together ("5" + 5) and catch the resulting TypeError.
Write a function check_age(age) that manually raises a ValueError if age is negative, and call it inside a try/except to catch it.
Write a try/except/else block around a division that succeeds, showing that else runs ONLY when no exception occurred.
Write a try/except/finally block where the division fails, showing that finally runs regardless.
Write ONE except block that catches both ValueError and ZeroDivisionError using a tuple, when converting and dividing user input.
Use a while True loop with try/except to keep asking for a number until the user enters a valid one, then break.
Write a nested try/except: the outer block catches a general error, the inner block specifically catches ZeroDivisionError before it can escape to the outer one.
Catch a ValueError from int("abc") and print both the error's type() and its message using str(e).
Try to open a file called "missing_file.txt" that doesn't exist, catching FileNotFoundError instead of checking beforehand.
Write a function safe_get(items, index) that returns the item at index, or None if the index is out of range, using try/except.
Write a function safe_int(value) that returns the integer conversion of value, or 0 if the conversion fails.
Combine all four blocks (try, except, else, finally) in one example dividing two numbers, and label which block ran using print statements.
Build a "Safe Division Calculator". Ask for two numbers and print their quotient, handling both invalid (non-numeric) input and division by zero.
Build an age input validator: ask for age repeatedly (using a loop) until a valid, non-negative integer is entered.
Build a simple ATM withdrawal check. Given balance = 1000, ask for a withdrawal amount and raise/catch a ValueError if it exceeds the balance.
Write a robust file reader: try to read "config.txt", and if it doesn't exist, create it with default content instead of crashing.
Write a function safe_divide(a, b) returning the division result, or the string "undefined" if b is zero.
Build a robust calculator menu (add/subtract/multiply/divide) that catches an invalid operator choice using a custom raise ValueError, and also handles bad numeric input.
Try to parse an invalid JSON string, catching json.JSONDecodeError and printing a friendly message.
Build a "retry loop" that gives the user up to 3 attempts to enter a valid number, printing how many attempts remain after each failure.
The following code is meant to catch a missing dictionary key but never does. Find and fix the bug.
person = {"name": "Bob"}
try:
print(person["age"])
except ValueError:
print("Key not found")Write a try/except that formats a division result to 2 decimal places on success, or prints a formatted error box on failure.
Write a function withdraw(balance, amount) that manually raises a ValueError with a descriptive message if amount exceeds balance, and demonstrate catching it.
Define a custom exception class InsufficientFundsError(Exception) and raise it from a withdraw() function instead of a generic ValueError.
Define a custom exception NegativeAgeError(Exception) that stores the invalid age as an attribute, and print that attribute when caught.
Demonstrate that except order matters: catching a general Exception BEFORE a specific ValueError means the specific branch never runs. Show the bug and the fix.
Write a function where try has a return statement AND a finally block also runs. Demonstrate that finally executes even though the function is already returning.
Build a small banking system with TWO custom exceptions, InsufficientFundsError and InvalidAmountError, and a withdraw() function that raises the appropriate one.
Use an assert statement to guarantee a function's precondition (n must be non-negative), and catch the resulting AssertionError.
Catch an exception, print a log message, and then raise it again (re-raise) so it still propagates upward.
Catch a low-level ValueError and re-raise it as a more meaningful custom exception using raise ... from ..., preserving the original cause.
The following code is supposed to validate a percentage (0-100) but the custom exception message never shows the actual invalid value. Find and fix the bug.
class InvalidPercentageError(Exception):
pass
def set_percentage(value):
if not (0 <= value <= 100):
raise InvalidPercentageError("Invalid percentage")
return value
try:
set_percentage(150)
except InvalidPercentageError as e:
print(e)Build a "Robust Calculator" with a menu loop that handles invalid operators, non-numeric input, and division by zero, without ever crashing.
Build an "ATM System" with a custom InsufficientFundsError, supporting deposit and withdraw operations in a loop until the user exits.
Build a "Config Loader" that tries to load settings from "app_config.json", falling back to hardcoded defaults if the file is missing or malformed.
Build an "Input Validation Library" with custom exceptions InvalidAgeError and InvalidEmailError, and functions validate_age(age) / validate_email(email) that raise them appropriately.
Build a "Bank Transfer System" with custom exceptions AccountNotFoundError and InsufficientFundsError, transferring money between two accounts stored in a dict.
Explain Python's "Easier to Ask Forgiveness than Permission" (EAFP) philosophy versus "Look Before You Leap" (LBYL), demonstrating both styles for safely accessing a dictionary key.
Design a small custom exception hierarchy: a base AppError(Exception) with two subclasses, ValidationError and NotFoundError, and demonstrate catching the BASE class to handle both at once.
Explain why a bare except: (with no exception type) is considered bad practice, demonstrating how it can silently swallow bugs like a typo'd variable name.
Explain the difference between else and finally on a try block — when each runs — with a single example showing both together and their distinct purposes.
Build an "Exception Handling Mastery Report" — the most complete demonstration in this module. Create a custom exception hierarchy (AppError -> ValidationError, InsufficientFundsError), a process_order(amount, balance) function using try/except/else/finally, raise, and re-raising, then demonstrate it with both a successful and a failing call.
Still stuck on something?
Book a free 1-on-1 session and we'll work through it together.
Book a Free Session