Exercises — Chapter 6: Functions
Starred exercises (
*) have worked solutions in Appendix B.
Tier 1: Recall
1.1 What keyword is used to define a function in Python?
1.2 What is the difference between a parameter and an argument? Give an example of each.
1.3 Write a function double(n) that returns n multiplied by 2.
1.4 What does a function return if it has no return statement?
1.5 ★ What is a docstring, and where is it placed in a function?
1.6 What is a default parameter? Write a function greet(name, greeting="Hello") that uses one.
1.7 Explain what "scope" means in the context of Python functions. What is a local variable?
1.8 What is a lambda function? When would you use one instead of a def?
Tier 2: Apply
2.1 ★ Write a function calculate_order_total(subtotal, tax_rate=0.0875, shipping=0.0) that returns the final order total. Include a docstring. Test it with at least two different calls.
2.2 Write a function format_financial_summary(revenue, cogs, expenses) that:
- Calculates gross profit, gross margin, operating profit, operating margin
- Returns a formatted multi-line string (not a dict)
- Includes proper formatting with $ and % signs
2.3 ★ Write a function classify_customer(annual_spend) that returns a customer tier string based on the following thresholds:
- Platinum: $250,000+
- Gold: $100,000–$249,999
- Silver: $25,000–$99,999
- Bronze: $5,000–$24,999
- Standard: below $5,000
2.4 Write a function calculate_clv(monthly_revenue, gross_margin_rate, monthly_churn_rate) that calculates Customer Lifetime Value. Guard against division by zero. Return 0 if churn_rate is 0 or negative.
2.5 ★ Rewrite the following inline code as a function. Then call it three times with different inputs.
# Original inline code — calculate break-even units
fixed_costs = 50_000
unit_price = 125
unit_variable_cost = 78
break_even = fixed_costs / (unit_price - unit_variable_cost)
print(f"Break-even: {break_even:.0f} units")
Tier 3: Analyze
3.1 ★ Consider the following two functions:
# Version A
def calculate_margin(rev, c):
return (rev - c) / rev
# Version B
def calculate_gross_margin(revenue, cost_of_goods_sold):
"""
Calculate gross margin as a decimal.
Returns 0.0 if revenue is zero or negative.
"""
if revenue <= 0:
return 0.0
return (revenue - cost_of_goods_sold) / revenue
Both return the same value for valid inputs. What are the differences, and when does each approach fail? Which is better for production business code, and why?
3.2 What is the DRY principle? Give a concrete example of a business scenario where violating DRY (by copy-pasting code) would eventually cause a real problem.
3.3 Explain what "scope" means in the context of the following code. Predict the output:
tax_rate = 0.21 # Global
def calculate_tax(amount):
tax_rate = 0.15 # Local
return amount * tax_rate
print(calculate_tax(1000))
print(tax_rate)
3.4 The chapter distinguishes between "pure functions" and "functions with side effects." Categorize each of the following as pure or side-effect:
- calculate_gross_margin(revenue, cogs) — returns a float
- send_invoice_email(client, invoice) — sends an email
- format_currency(amount) — returns a formatted string
- save_report_to_file(data, filename) — writes to disk
- get_customer_tier(annual_spend) — looks up from a dict
3.5 Python functions can return multiple values using tuple packing. What are the advantages and risks of returning multiple values vs. returning a dictionary? When would you use each?
Tier 4: Synthesize
4.1 Build a complete payroll_calculator.py module with the following functions:
- gross_pay(hours_worked, hourly_rate, overtime_threshold=40) — regular pay + 1.5x overtime
- calculate_federal_tax(gross_pay) — simplified brackets: 10% up to $44,725, 22% above
- calculate_state_tax(gross_pay, state_rate=0.045) — flat rate
- net_pay(gross_pay, federal_tax, state_tax, benefits_deduction=0) — gross minus deductions
- format_pay_stub(employee_name, hours, rate, benefits=0) — returns formatted pay stub string
4.2 Build a maya_project_evaluator.py module that evaluates whether Maya should take on a new project:
Scoring criteria: - Project budget ≥ $10,000: +2 points - Project type == "consulting" (Maya's specialty): +1 point - Client is a referral: +1 point - Project duration > 3 months: +1 point - Industry is in Maya's preferred list: +1 point - Project requires travel > 25% of time: -2 points - Client has paid invoices within terms historically: +2 points
Return value: (score, recommendation) where recommendation is "Accept", "Review", or "Decline" based on total score.
4.3 Refactor the following flat script into well-designed functions:
# Original flat script
region_name = "Midwest"
q1 = 312450
q2 = 287890
q3 = 331200
q4 = 298760
total = q1 + q2 + q3 + q4
average = total / 4
best_q = max(q1, q2, q3, q4)
worst_q = min(q1, q2, q3, q4)
growth = (q4 - q1) / q1
print(f"{region_name}: Total ${total:,}, Avg ${average:,.0f}, Growth {growth:.1%}")
Design functions with clear single responsibilities. Include docstrings.
Tier 5: Challenge
5.1 (Open-Ended) The chapter shows how functions help with the DRY principle. But there's another tension: sometimes writing a function is premature abstraction — you create a function for logic that's only used once and that adds complexity without benefit. Research the concept of "premature abstraction" and write guidelines for when to create a function vs. when to leave logic inline. Apply your guidelines to 5 specific scenarios from business analytics work.
5.2 (Build) Create a complete financial_model.py module for a simplified income statement model. The module should:
- Accept revenue, COGS rate, growth rate, and year as inputs
- Project the income statement forward 5 years
- Calculate year-over-year growth rates
- Identify the year when cumulative operating profit exceeds a given threshold
- Format results as an aligned table
- All business logic in functions; no business logic outside functions