Workshop: Error Handling and Debugging (Optional, Self-Study)¶
View workshop code on GitHub Get the Video Course
From the lesson
Workshop problems for Section 09 Concepts. Build each yourself first, then expand the solution to check.
Four optional workshop problems, one per concept step, in a car-rental scenario. You build one function, cost_per_day, and make it safer step by step (the same shape as the lesson's calculate_books_per_student). The numbers line up with the steps. Self-study: check python-workshop/solutions.
Step-01: try / except Basics¶
Concepts: try / except Exception as a catch-all.
Write a function cost_per_day that takes a total cost and a number of days, turns both into whole numbers, and returns the cost for each day. Wrap the risky lines in a try/except so a bad value returns Something went wrong with the rental. instead of crashing. Call it with "300" and "3", then "abc" and "3", then "300" and "0", printing each result.
Need a hint?
Wrap both int() conversions and the / division in one try; a single except Exception returning the message catches both the bad-value and zero-days cases.
Show the solution
# Problem-1 Task-1: define cost_per_day with try/except
def cost_per_day(total_cost, days):
try:
cost = int(total_cost)
count = int(days)
return cost / count
except Exception:
return "Something went wrong with the rental."
# Problem-1 Task-2: print result for valid rental
print(cost_per_day("300", "3"))
# Problem-1 Task-3: print result for bad cost
print(cost_per_day("abc", "3"))
# Problem-1 Task-4: print result for zero days
print(cost_per_day("300", "0"))
Pages for this step: Concept | Practice | Workshop
Python Files for this step: Concept | Practice | Practice Solutions | Workshop | Workshop Solutions
Step-02: Catching Specific Errors¶
Concepts: catching a SPECIFIC error; except ValueError and except ZeroDivisionError side by side.
Reuse cost_per_day, but catch the two problems separately: if the values are not whole numbers catch the ValueError and return Cost and days must be whole numbers.; if there are zero days catch the ZeroDivisionError and return There must be at least one day. Call it with "300" and "3", "abc" and "3", then "300" and "0", printing each result.
Need a hint?
Use two handlers in order: except ValueError for non-whole values, then except ZeroDivisionError for zero days, each with its own return message.
Show the solution
# Problem-1 Task-1: cost_per_day catching ValueError and ZeroDivisionError separately
def cost_per_day(total_cost, days):
try:
cost = int(total_cost)
count = int(days)
return cost / count
except ValueError:
return "Cost and days must be whole numbers."
except ZeroDivisionError:
return "There must be at least one day."
# Problem-1 Task-2: print result for valid rental
print(cost_per_day("300", "3"))
# Problem-1 Task-3: print result for bad cost
print(cost_per_day("abc", "3"))
# Problem-1 Task-4: print result for zero days
print(cost_per_day("300", "0"))
Pages for this step: Concept | Practice | Workshop
Python Files for this step: Concept | Practice | Practice Solutions | Workshop | Workshop Solutions
Step-03: finally - Cleanup That Always Runs¶
Concepts: finally always runs; catching two errors in one except (A, B).
Reuse cost_per_day with a combined except that returns Please enter valid numbers., and add a finally block that always prints Rental closed. Call it with "300" and "3", then with "300" and "0", printing each result.
finally runs even when you return
A finally block runs no matter what, even when the try block already hit a return. That is why Rental closed. prints before the returned value is printed by the caller.
Need a hint?
A finally block always runs, even after a return, which is why Rental closed. prints before the returned value reaches the caller.
Show the solution
# Problem-1 Task-1: cost_per_day with a finally that always runs
def cost_per_day(total_cost, days):
try:
cost = int(total_cost)
count = int(days)
return cost / count
except (ValueError, ZeroDivisionError):
return "Please enter valid numbers."
finally:
print("Rental closed.")
# Problem-1 Task-2: print result for valid rental
print(cost_per_day("300", "3"))
# Problem-1 Task-3: print result for zero days
print(cost_per_day("300", "0"))
Pages for this step: Concept | Practice | Workshop
Python Files for this step: Concept | Practice | Practice Solutions | Workshop | Workshop Solutions
Step-04: raise - Signal Bad Input on Purpose¶
Concepts: raise, except ... as err.
Reuse cost_per_day, turning both inputs into whole numbers, then enforce two rules before dividing: if the total cost is negative, raise a ValueError with cost cannot be negative; if there is less than one day, raise a ValueError with there must be at least one day. Otherwise return the cost for each day. Print the result of calling it with "300" and "3". Then call it with "300" and "0" inside a try/except that catches the error as err, and print Caught: followed by the error. Finally print Still running..
Need a hint?
You raise ValueError(...) before dividing, then catch it at the call site with except ValueError as err and print err to show the message.
Show the solution
# Problem-1 Task-1: cost_per_day that raises ValueError on bad rules
def cost_per_day(total_cost, days):
cost = int(total_cost)
count = int(days)
if cost < 0:
raise ValueError("cost cannot be negative")
if count < 1:
raise ValueError("there must be at least one day")
return cost / count
# Problem-1 Task-2: print result for valid rental
print(cost_per_day("300", "3"))
# Problem-1 Task-3: call with zero days and catch the error
try:
cost_per_day("300", "0")
except ValueError as err:
print("Caught:", err)
# Problem-1 Task-4: show the program keeps running
print("Still running.")
Pages for this step: Concept | Practice | Workshop
Python Files for this step: Concept | Practice | Practice Solutions | Workshop | Workshop Solutions
Finished this section?
Check your work against the solutions above, then head back to the Section 09 lesson, or try the Section 09 practice for more reps.
Prefer to learn by watching?
The full video course teaches every concept on screen and builds the projects with you, step by step.
Workshop: Type Hints Next: Workshop: Files JSON and Paths