You have three months of totals: [100.0, 120.0, 80.0]. You want the average. What's the Python formula?
Sum them and divide by the count. sum(totals) / len(totals).
Exactly. sum() and len() are built-in — sum() does the same accumulator loop you wrote on Day 12, in one call. len() returns the count:
sum(totals) / len(totals)For three months totaling 300.0, that's 100.0.
What happens if the list is empty? len([]) is zero, and dividing by zero crashes.
Right — ZeroDivisionError. You guard against the zero count before you divide. The idiomatic empty-check is the same falsy-collection shortcut the champion pattern used:
if not monthly_totals:
return 0.0
return sum(monthly_totals) / len(monthly_totals)Guard first, compute second. The order matters — you have to check before you touch the thing that would fail.
And why return 0.0 instead of None when the list is empty?
Convention, plus consistency. The function returns a float on the happy path, so returning a float on the edge path keeps the type stable. A caller doing arithmetic with the result doesn't have to suddenly handle a None — the contract is "always a float, always safe to add."
Guard empty, then sum/len. Two lines, no crashes, consistent return type. Very clean.
This is the shape for every division you'll write in this track. Check the denominator before you divide — it's a cheap, early habit worth locking in right now.
sum() / len() with an empty-list guardTL;DR: guard the empty list first, then compute the mean.
sum(xs) — same as an accumulator loop, one calllen(xs) — element countif not xs: return 0.0 — prevents ZeroDivisionError| Order | Behavior |
|---|---|
| Guard first, compute second | Safe — never divides by zero |
| Compute first, then guard | Too late — crash already happened |
The denominator check always comes before the division. Same habit applies to any / operator where the divisor could be zero.
You have three months of totals: [100.0, 120.0, 80.0]. You want the average. What's the Python formula?
Sum them and divide by the count. sum(totals) / len(totals).
Exactly. sum() and len() are built-in — sum() does the same accumulator loop you wrote on Day 12, in one call. len() returns the count:
sum(totals) / len(totals)For three months totaling 300.0, that's 100.0.
What happens if the list is empty? len([]) is zero, and dividing by zero crashes.
Right — ZeroDivisionError. You guard against the zero count before you divide. The idiomatic empty-check is the same falsy-collection shortcut the champion pattern used:
if not monthly_totals:
return 0.0
return sum(monthly_totals) / len(monthly_totals)Guard first, compute second. The order matters — you have to check before you touch the thing that would fail.
And why return 0.0 instead of None when the list is empty?
Convention, plus consistency. The function returns a float on the happy path, so returning a float on the edge path keeps the type stable. A caller doing arithmetic with the result doesn't have to suddenly handle a None — the contract is "always a float, always safe to add."
Guard empty, then sum/len. Two lines, no crashes, consistent return type. Very clean.
This is the shape for every division you'll write in this track. Check the denominator before you divide — it's a cheap, early habit worth locking in right now.
sum() / len() with an empty-list guardTL;DR: guard the empty list first, then compute the mean.
sum(xs) — same as an accumulator loop, one calllen(xs) — element countif not xs: return 0.0 — prevents ZeroDivisionError| Order | Behavior |
|---|---|
| Guard first, compute second | Safe — never divides by zero |
| Compute first, then guard | Too late — crash already happened |
The denominator check always comes before the division. Same habit applies to any / operator where the divisor could be zero.
Write `monthly_average(monthly_totals)` that returns the mean of a list of floats. Empty list returns 0.0.
Tap each step for scaffolded hints.
No blank-editor panic.