You've been computing ARPU throughout the track. What happens when a customer dict has a missing 'seats' key or a string where you expect a number?
After rank_plans_by_mrr my data is clean. But in real exports — messy Stripe CSV, Zapier webhook — the seats field sometimes has "N/A" or is completely absent. mrr / seats would crash.
try/except is exactly the IFERROR of Python. Wrap the risky computation in try:, list the exception types you expect in except (KeyError, ValueError, ZeroDivisionError):, and return a safe default:
try:
arpu = customer["mrr"] / customer["seats"]
except (KeyError, ValueError, ZeroDivisionError):
arpu = 0.0Can I just catch Exception to cover everything? Why list specific types?
You can, but you shouldn't. Catching Exception masks bugs you didn't intend to handle — like a TypeError from passing the wrong argument type. List only what you expect: KeyError for missing keys, ValueError for float("N/A"), ZeroDivisionError for mrr / 0. Here's the full function:
def safe_compute_arpu(customer: dict) -> float:
try:
mrr = float(customer["mrr"])
seats = int(customer["seats"])
arpu = mrr / seats
print(f"ARPU: {arpu:.2f}")
return round(arpu, 2)
except (KeyError, ValueError, ZeroDivisionError):
print("ARPU computation failed, returning 0.0")
return 0.0So instead of crashing on messy data, the function returns 0.0 and keeps running. My whole investor update pipeline stays alive even with bad rows.
Your investor update will survive contact with real-world data. That's what separates a script that runs once from a tool you run every Monday.
I wrapped the riskiest computation in the track in error handling. The investor update is now fault-tolerant.
except only catches exceptions that were raised in the try block. Code after an exception in try is skipped. The except block runs, then execution continues after the whole try/except structure.
Wrap risky code in try: and handle specific errors in except:.
try:
result = risky_computation()
except SpecificError:
result = safe_default| Exception | Cause |
|---|---|
KeyError | Missing dict key |
ValueError | Bad type conversion (float('N/A')) |
ZeroDivisionError | Division by zero |
TypeError | Wrong argument type |
except Exception catches everything — including bugs you didn't intend to silence. Always list specific exception types.
You've been computing ARPU throughout the track. What happens when a customer dict has a missing 'seats' key or a string where you expect a number?
After rank_plans_by_mrr my data is clean. But in real exports — messy Stripe CSV, Zapier webhook — the seats field sometimes has "N/A" or is completely absent. mrr / seats would crash.
try/except is exactly the IFERROR of Python. Wrap the risky computation in try:, list the exception types you expect in except (KeyError, ValueError, ZeroDivisionError):, and return a safe default:
try:
arpu = customer["mrr"] / customer["seats"]
except (KeyError, ValueError, ZeroDivisionError):
arpu = 0.0Can I just catch Exception to cover everything? Why list specific types?
You can, but you shouldn't. Catching Exception masks bugs you didn't intend to handle — like a TypeError from passing the wrong argument type. List only what you expect: KeyError for missing keys, ValueError for float("N/A"), ZeroDivisionError for mrr / 0. Here's the full function:
def safe_compute_arpu(customer: dict) -> float:
try:
mrr = float(customer["mrr"])
seats = int(customer["seats"])
arpu = mrr / seats
print(f"ARPU: {arpu:.2f}")
return round(arpu, 2)
except (KeyError, ValueError, ZeroDivisionError):
print("ARPU computation failed, returning 0.0")
return 0.0So instead of crashing on messy data, the function returns 0.0 and keeps running. My whole investor update pipeline stays alive even with bad rows.
Your investor update will survive contact with real-world data. That's what separates a script that runs once from a tool you run every Monday.
I wrapped the riskiest computation in the track in error handling. The investor update is now fault-tolerant.
except only catches exceptions that were raised in the try block. Code after an exception in try is skipped. The except block runs, then execution continues after the whole try/except structure.
Wrap risky code in try: and handle specific errors in except:.
try:
result = risky_computation()
except SpecificError:
result = safe_default| Exception | Cause |
|---|---|
KeyError | Missing dict key |
ValueError | Bad type conversion (float('N/A')) |
ZeroDivisionError | Division by zero |
TypeError | Wrong argument type |
except Exception catches everything — including bugs you didn't intend to silence. Always list specific exception types.
Your Stripe exports occasionally have missing seats fields or 'N/A' strings in numeric columns. Write `safe_compute_arpu(customer)` that computes mrr / seats from the customer dict inside a try/except, returning 0.0 on any KeyError, ValueError, or ZeroDivisionError.
Tap each step for scaffolded hints.
No blank-editor panic.