Skip to the content

EXECUTED, WITH ASSERTIONS

This program was run during verification and its results asserted.

The code

Straight from labs/course-3-python/12_exception_handling.py, unchanged.

"""Experiment 12: Demonstrate exception handling using try-except-finally.

Syllabus: Course 3, Unit 4 -- error and exception handling.
"""


# Step 1: A user-defined exception
class InvalidMarkError(Exception):
    """User-defined exception -- raised when a mark falls outside 0-100."""


# Step 2: try, except, else and finally
def divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        print(f"  ZeroDivisionError caught: cannot divide {a} by zero")
        return None
    else:
        print(f"  else block: {a} / {b} = {result}")   # runs only if no error
        return result
    finally:
        print("  finally block: always runs, error or not")


# Step 3: ZeroDivisionError
print("1. ZeroDivisionError")
divide(10, 2)
divide(10, 0)

# Step 4: ValueError
print("\n2. ValueError from a bad conversion")
for value in ("42", "abc"):
    try:
        print(f"  int({value!r}) = {int(value)}")
    except ValueError as exc:
        print(f"  ValueError caught: {exc}")

# Step 5: Several exception types
print("\n3. Catching several exception types")
for item in [[1, 2, 3], "hello", None]:
    try:
        print(f"  {item!r} -> first element {item[0]!r}")
    except TypeError as exc:
        print(f"  TypeError caught: {exc}")
    except IndexError as exc:
        print(f"  IndexError caught: {exc}")

# Step 6: FileNotFoundError
print("\n4. FileNotFoundError")
try:
    with open("does_not_exist.txt") as fh:
        fh.read()
except FileNotFoundError as exc:
    print(f"  FileNotFoundError caught: {exc.strerror}")

# Step 7: raise
print("\n5. raise -- signalling an error yourself")


def validate(mark):
    if not 0 <= mark <= 100:
        raise InvalidMarkError(f"{mark} is outside the valid range 0-100")
    return mark


for mark in (85, 150):
    try:
        print(f"  validate({mark}) = {validate(mark)}")
    except InvalidMarkError as exc:
        print(f"  InvalidMarkError caught: {exc}")

# Step 8: assert
print("\n6. assert -- a sanity check that raises AssertionError")
try:
    scores = [80, 90]
    assert len(scores) > 0, "scores must not be empty"
    print(f"  assertion passed, average = {sum(scores) / len(scores)}")
    assert all(s <= 100 for s in scores + [120]), "every score must be <= 100"
except AssertionError as exc:
    print(f"  AssertionError caught: {exc}")

Where this sits

One experiment from the Python Programming and Data Structures lab. The rest of them, and the theory behind this one, are on the lab page.