Chapter 5 Exercises: Loops and Iteration
Python for Business for Beginners — Chapter 5
These exercises are organized into five tiers of difficulty. Work through them in order. Tiers 1 and 2 are essential practice; Tier 5 problems are genuinely challenging and will stretch you.
All exercises use Python 3.10+. No external libraries are required.
Tier 1 — Foundations (Exercises 1–4)
Goal: Get comfortable with basic loop syntax and the accumulator pattern.
Exercise 1: Sum a Sales List
You have a list of daily sales figures for the past two weeks:
daily_sales = [
4_200, 3_800, 5_100, 4_600, 6_300,
2_900, 0, 4_700, 5_500, 4_100,
6_800, 5_200, 3_300, 4_900
]
Tasks:
a) Use a for loop to calculate the total sales for the two-week period.
b) Use a for loop to count how many days had sales above $5,000.
c) Use a for loop to find the highest single-day figure.
d) Print each result with a clear label. Your output should look like:
Two-week total: $65,400
Days above $5,000: 4
Best single day: $6,800
Hint: Use three separate accumulator variables. Initialize each before the loop.
Exercise 2: Print a Multiplication Table
Use nested for loops and range() to print a 5×5 multiplication table formatted like this:
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
Each number should be right-aligned in a field of 5 characters. Use an f-string with a width specifier: f"{value:>5}".
Exercise 3: FizzBuzz for Accountants
Iterate over the numbers 1 through 30 using range(). For each number:
- If the number is divisible by 3, print
"Quarter end" - If the number is divisible by 5, print
"Payment due" - If the number is divisible by both 3 and 5, print
"Quarter end + Payment due" - Otherwise, print the number itself
Check the divisible-by-both case first, or your logic will produce the wrong result.
Exercise 4: Invoice Status Checker
You have a list of invoice amounts and a matching list of payment statuses:
invoice_amounts = [8_500, 12_200, 3_400, 27_000, 9_100, 15_300, 6_600]
payment_statuses = [True, False, True, False, True, False, True]
# True = paid, False = outstanding
Use zip() to combine the two lists and print each invoice with its status. Then calculate and print the total outstanding balance.
Expected output format:
Invoice 1: $8,500 — PAID
Invoice 2: $12,200 — OUTSTANDING
...
Total outstanding: $54,500
Tier 2 — Core Skills (Exercises 5–8)
Goal: Apply loops to realistic business data and work with dictionaries.
Exercise 5: Regional Report with enumerate
Given this data:
regions = ["Northeast", "Southeast", "Midwest", "West Coast", "International"]
q3_sales = [187_400, 143_200, 162_800, 224_500, 98_700]
q3_targets = [180_000, 150_000, 160_000, 220_000, 100_000]
Use enumerate() (starting at 1) and zip() together to print a ranked performance table:
Rank Region Q3 Sales Target vs. Target
-----------------------------------------------------------
1. Northeast $187,400 $180,000 +$7,400
2. Southeast $143,200 $150,000 -$6,800
...
After the table, print which regions exceeded their target and which missed.
Exercise 6: Sales Rep Commission Calculator
sales_reps = [
{"name": "Ana Lima", "sales": 142_000, "tier": "senior"},
{"name": "Tom Park", "sales": 87_500, "tier": "junior"},
{"name": "Jess Wong", "sales": 203_000, "tier": "senior"},
{"name": "Dan Reyes", "sales": 65_200, "tier": "junior"},
{"name": "Cara Bell", "sales": 178_400, "tier": "senior"},
{"name": "Luis Mora", "sales": 112_300, "tier": "junior"},
]
COMMISSION_RATES = {
"junior": 0.05, # 5%
"senior": 0.08, # 8%
}
Write a loop that calculates each rep's commission and prints a table. Also calculate and print: - Total commission paid out - Highest individual commission (and who earned it) - Average commission across all reps
Exercise 7: Expense Category Totals
Maya has a list of expense entries for the month:
expenses = [
{"category": "Travel", "amount": 342.50},
{"category": "Software", "amount": 89.00},
{"category": "Travel", "amount": 215.00},
{"category": "Meals", "amount": 67.40},
{"category": "Software", "amount": 149.00},
{"category": "Office", "amount": 34.20},
{"category": "Meals", "amount": 112.80},
{"category": "Travel", "amount": 480.00},
{"category": "Office", "amount": 78.50},
{"category": "Software", "amount": 299.00},
]
a) Use a for loop to build a dictionary that totals expenses by category.
b) Print the category totals sorted from highest to lowest.
c) Calculate the total of all expenses and express each category as a percentage of the total.
d) Use a list comprehension to get a list of only the categories where spending exceeded $300.
Exercise 8: while Loop — Loan Payoff Simulator
Sandra is evaluating whether to take a short-term loan for inventory. Write a while loop that simulates paying off a loan:
principal = 25_000.00
annual_interest_rate = 0.065 # 6.5% annual
monthly_payment = 2_200.00
Each month:
1. Calculate monthly interest: balance * (annual_interest_rate / 12)
2. Add interest to the balance
3. Subtract the monthly payment from the balance
4. Print the month number, interest charged, payment made, and remaining balance
Stop when the balance reaches zero (or goes below zero — handle the final partial payment correctly).
At the end, print the total number of months and total interest paid.
Tier 3 — Applying Patterns (Exercises 9–12)
Goal: Combine multiple loop techniques to solve multi-step problems.
Exercise 9: Five-Week Trend Analysis
Using the data from Case Study 1 (or your own similar dataset), write a script that:
a) Calculates total sales for each week and prints them in order.
b) Calculates the week-over-week change for each week (Week 2 minus Week 1, etc.) and labels each as "Up", "Down", or "Flat" (within $1,000 of previous).
c) Identifies the single best and worst week across all regions combined.
d) Uses a nested loop to find the best-performing region in each individual week.
e) Prints a clean, formatted summary of all findings.
Exercise 10: Customer Tier Classification
customers = [
{"name": "Brightway Inc.", "annual_spend": 145_000},
{"name": "Oakwood Supplies", "annual_spend": 38_200},
{"name": "Prism Retail", "annual_spend": 287_500},
{"name": "Clearstone LLC", "annual_spend": 12_400},
{"name": "Summit Partners", "annual_spend": 198_700},
{"name": "Delta Logistics", "annual_spend": 67_800},
{"name": "Horizon Group", "annual_spend": 324_100},
{"name": "Crestview Corp", "annual_spend": 8_900},
]
TIERS = {
"Platinum": 300_000, # >= $300k
"Gold": 150_000, # >= $150k
"Silver": 50_000, # >= $50k
"Bronze": 0, # < $50k
}
a) Write a function that takes a customer's annual spend and returns their tier name. (You will learn formal functions in Chapter 6; for now, write the logic inline or as a simple lookup.)
b) Use a loop to assign each customer their tier and build a new list of dictionaries that includes the tier.
c) Use a list comprehension to extract just the names of Platinum customers.
d) Group customers by tier into a dictionary: {"Platinum": [...], "Gold": [...], ...}.
e) Print a summary showing how many customers are in each tier and each tier's combined spend.
Exercise 11: break and continue — Data Validation
Priya is importing a batch of sales figures from a legacy system. The data sometimes contains errors:
raw_sales_data = [
12_400, 8_700, -500, 34_200, None, 15_600,
9_800, "N/A", 22_100, 0, 44_700, -100,
18_300, None, 27_900
]
ANOMALY_THRESHOLD = 40_000 # Flag anything above this for review
Write a loop that:
- Uses continue to skip any entry that is None, a string, or negative
- Uses break to stop processing if it encounters a value above ANOMALY_THRESHOLD (flag it for manual review)
- Accumulates a running total and count of valid entries processed
- Prints a summary at the end: valid entries processed, entries skipped, whether processing was halted early and why
Exercise 12: list comprehension — Inventory Filter
inventory = [
{"sku": "BND-001", "product": "3-Ring Binders", "units": 450, "reorder_point": 100, "cost": 2.50},
{"sku": "PEN-012", "product": "Blue Ballpoint", "units": 80, "reorder_point": 200, "cost": 0.25},
{"sku": "PPR-005", "product": "Copy Paper (ream)", "units": 320, "reorder_point": 150, "cost": 5.99},
{"sku": "STK-003", "product": "Sticky Notes", "units": 25, "reorder_point": 100, "cost": 1.75},
{"sku": "FLD-008", "product": "Manila Folders", "units": 600, "reorder_point": 200, "cost": 0.45},
{"sku": "MRK-002", "product": "Highlighters", "units": 55, "reorder_point": 150, "cost": 0.99},
{"sku": "CLI-011", "product": "Binder Clips", "units": 1200, "reorder_point": 300, "cost": 0.05},
{"sku": "SCI-007", "product": "Scissors", "units": 18, "reorder_point": 50, "cost": 3.25},
]
Write the following using list comprehensions:
a) A list of SKUs that need reordering (units below reorder_point).
b) A list of (product_name, reorder_quantity) tuples, where reorder_quantity = reorder_point * 2 - units_on_hand (only for items that need reordering).
c) A list of all product names in uppercase.
d) The total current inventory value (units × cost for each item). Use a generator expression with sum().
Tier 4 — Integration Challenges (Exercises 13–16)
Goal: Build complete, multi-step programs that process real-looking datasets.
Exercise 13: Full Invoice Aging Report
Build on the invoice_processor.py from the chapter. Given the same invoice data, generate an aging report that groups invoices into buckets:
- Current (not yet due)
- 1–30 days overdue
- 31–60 days overdue
- 61–90 days overdue
- 90+ days overdue
For each bucket, calculate the total number of invoices and total outstanding balance. Print a formatted aging table. At the bottom, show what percentage of outstanding dollars falls into each bucket.
Exercise 14: Weekly Payroll Calculator
employees = [
{"name": "Sandra Chen", "role": "VP Sales", "hourly_rate": None, "salary": 120_000},
{"name": "Marcus Webb", "role": "IT Manager", "hourly_rate": None, "salary": 95_000},
{"name": "Priya Okonkwo","role": "Analyst", "hourly_rate": 35.00,"salary": None},
{"name": "Ana Lima", "role": "Sales Rep", "hourly_rate": 28.50,"salary": None},
{"name": "Tom Park", "role": "Sales Rep", "hourly_rate": 28.50,"salary": None},
]
hours_worked_this_week = {
"Priya Okonkwo": 42.5, # Overtime possible
"Ana Lima": 38.0,
"Tom Park": 45.0,
}
OVERTIME_THRESHOLD = 40.0
OVERTIME_MULTIPLIER = 1.5
WEEKS_PER_YEAR = 52
Write a script that:
a) Calculates weekly gross pay for salaried employees (annual / 52) and hourly employees (with overtime at 1.5× for hours above 40).
b) Prints a weekly payroll summary table showing each employee, their type (salaried/hourly), regular pay, overtime pay (if any), and gross weekly pay.
c) Calculates and prints the total weekly payroll cost.
d) Uses continue to skip salaried employees when processing overtime.
Exercise 15: Sales Leaderboard Generator
Using this data (or your own invented equivalent):
sales_data = [
{"rep": "Ana Lima", "region": "Northeast", "month": "January", "amount": 42_100},
{"rep": "Tom Park", "region": "Southeast", "month": "January", "amount": 28_700},
{"rep": "Jess Wong", "region": "Midwest", "month": "January", "amount": 51_300},
{"rep": "Ana Lima", "region": "Northeast", "month": "February", "amount": 47_800},
{"rep": "Tom Park", "region": "Southeast", "month": "February", "amount": 33_400},
{"rep": "Jess Wong", "region": "Midwest", "month": "February", "amount": 48_600},
{"rep": "Dan Reyes", "region": "West Coast","month": "January", "amount": 61_200},
{"rep": "Dan Reyes", "region": "West Coast","month": "February", "amount": 58_900},
{"rep": "Cara Bell", "region": "Northeast", "month": "January", "amount": 38_400},
{"rep": "Cara Bell", "region": "Northeast", "month": "February", "amount": 44_700},
]
Build a complete leaderboard script that:
a) Groups total sales by rep using a dictionary accumulator.
b) Sorts the leaderboard from highest to lowest using sorted() with a key.
c) Uses enumerate() to print ranked positions.
d) Calculates each rep's share of total sales as a percentage.
e) Groups and totals sales by region.
f) Finds the single best month-rep combination.
Exercise 16: Inventory Reorder Email Generator
Acme Corp's inventory system needs to generate a plain-text reorder email whenever items fall below their reorder points. Using the inventory data from Exercise 12 (or an extended version of it):
Write a script that:
a) Identifies all items below reorder point.
b) Calculates the reorder quantity for each item (bring inventory up to 2× the reorder point).
c) Calculates the estimated cost of each reorder.
d) Generates a plain-text email body (as a string) that Marcus could copy-paste into Outlook. The email should: - Have a professional greeting and closing - Include a formatted table of items to reorder - Include the total estimated reorder cost - Be built using string concatenation or an f-string inside a loop
Print the final email to the console.
Tier 5 — Stretch Problems (Exercises 17–20)
Goal: Solve open-ended problems that require designing your own approach. There is no single right answer.
Exercise 17: Cash Flow Projection
Write a while loop simulation of Acme Corp's cash position over time:
starting_cash = 250_000
monthly_revenue = 180_000
monthly_expenses = 165_000
monthly_loan_payment = 8_500
minimum_cash_reserve = 50_000
The simulation should run month by month. Each month:
- Add revenue
- Subtract expenses and loan payment
- If cash falls below minimum_cash_reserve, the simulation stops and reports a cash crisis
Additionally: increase monthly expenses by 0.5% each month (cost creep). Does this change when the cash crisis hits?
Print the monthly cash position for each month and the final status.
Exercise 18: Sales Commission Dispute Resolver
Two spreadsheets have been merged, and some sales entries appear to be duplicates. Write a script that:
sales_log = [
{"id": "S-101", "rep": "Ana Lima", "amount": 12_400, "date": "2024-11-01"},
{"id": "S-102", "rep": "Tom Park", "amount": 8_700, "date": "2024-11-01"},
{"id": "S-101", "rep": "Ana Lima", "amount": 12_400, "date": "2024-11-01"}, # duplicate
{"id": "S-103", "rep": "Jess Wong", "amount": 22_100, "date": "2024-11-02"},
{"id": "S-104", "rep": "Ana Lima", "amount": 9_800, "date": "2024-11-03"},
{"id": "S-102", "rep": "Tom Park", "amount": 8_700, "date": "2024-11-01"}, # duplicate
{"id": "S-105", "rep": "Dan Reyes", "amount": 34_500, "date": "2024-11-03"},
{"id": "S-103", "rep": "Jess Wong", "amount": 22_100, "date": "2024-11-02"}, # duplicate
]
a) Identify all duplicate entries (same id).
b) De-duplicate the list, keeping only the first occurrence of each ID.
c) Calculate commission (8%) on the de-duplicated totals per rep.
d) Calculate how much commission would have been overpaid if the duplicates had not been caught.
e) Print a clean report of findings.
Exercise 19: Compound Interest Comparison
Maya is deciding between two savings accounts for her business emergency fund. Write a program that uses loops to calculate and compare the growth of $20,000 over 5 years under both options:
- Account A: 4.5% annual interest, compounded monthly
- Account B: 4.2% annual interest, compounded daily
For each account, print the balance at the end of each year. At the end, print which account performs better and by how much.
Formula for compound interest per period:
balance = balance * (1 + rate / periods_per_year)
Apply this in a loop for each period (month or day) over 5 years.
Exercise 20: Text-Based Report Builder
Design a reusable "report building" system using only loops and string operations. Your system should accept:
report_title = "Q4 Performance Summary"
report_date = "2024-12-31"
sections = [
{
"heading": "Revenue",
"rows": [
("Northeast", 187_400),
("Southeast", 143_200),
("Midwest", 162_800),
("West Coast", 224_500),
],
"row_format": "currency", # Format as $X,XXX
},
{
"heading": "Headcount",
"rows": [
("Northeast", 52),
("Southeast", 41),
("Midwest", 48),
("West Coast", 59),
],
"row_format": "integer",
},
]
Build a loop-driven system that generates a complete formatted text report from any such data structure — calculating section totals automatically, applying the right number format, and producing consistent headers and separators throughout. The report should look professional enough to paste into an email.
Notes on Working Through These Exercises
On getting stuck: If a Tier 3 or 4 exercise seems overwhelming, break it into pieces. Write a comment describing what each part needs to do, then fill in the code under each comment. Solve one comment at a time.
On checking your work: Run your code and verify the output makes business sense. If a sales total looks wrong, trace through the loop manually with a small subset of the data.
On style: Use descriptive variable names. Write a one-line comment above any section that is not immediately obvious. Your future self will thank you.
On asking for help: If you are stuck after 20 minutes, look at the relevant section of Chapter 5, then try again. If you are stuck after 40 minutes, that is the right time to look up a hint or ask someone.