Running totals and counters in Python: the accumulator pattern
Year-one revenue, the number of months above target, the most profitable option: each is a single answer built up over many passes of a loop. That shape has a name.
The big idea
An accumulator is a variable initialized before a loop and updated on every pass, so it holds a combined result when the loop ends.
See it in code
Three parts, always: initialize before the loop, update inside it, use the result after it:
price = 38
units = 300
growth = 0.15
total_revenue = 0
for month in range(1, 13):
total_revenue = total_revenue + units * price
units = round(units * (1 + growth))
print(f"Year one revenue: ${total_revenue:,}")Year one revenue: $331,398
total_revenue grew a little on each of twelve passes. The update line must add to the old value; writing total_revenue = units * price would replace it and report only December.
Add 1 instead of a value and the accumulator becomes a counter. Put the update inside an if and it counts only the passes that qualify:
daily_tees = [42, 57, 38, 64, 71, 95, 88]
target = 60
strong_days = 0
for tees in daily_tees:
if tees >= target:
strong_days += 1
print(f"{strong_days} of {len(daily_tees)} days hit the target")
print(f"That's {strong_days / len(daily_tees):.0%} of the week")4 of 7 days hit the target That's 57% of the week
+= is shorthand for "add to this variable." Dividing a count by the number of trials gives a proportion, which is how a simulation turns results into a probability.
A third variant remembers the best so far. Keep the top result and what produced it, and replace both whenever a pass beats them:
price = 38
cost = 14
clearance = 10
demand = 800
best_profit = 0
best_run = 0
for made in range(500, 1501, 100):
sold = min(made, demand)
leftover = made - sold
profit = sold * price + leftover * clearance - made * cost
if profit > best_profit:
best_profit = profit
best_run = made
print(f"Best run: {best_run:,} tees for ${best_profit:,}")Best run: 800 tees for $19,200
When demand is known to be exactly 800, making exactly 800 wins: every extra tee costs $14 and clears for $10. Real demand is uncertain, which is where simulation comes in.
Totals, counts, and best-so-far cover a remarkable share of data work: summing a column, counting matching bases in a sequence, finding a portfolio's worst day.
Try it yourself
Add a second accumulator to the last program, total_leftover, and report the average unsold tees across all eleven runs. Then start best_profit at -1_000_000 and explain when that would matter.
The common mistake
Initializing inside the loop. If total_revenue = 0 sits under the for line, it resets on every pass and the "total" is just the last month. Initialize once, above the loop.
What it unlocks
Accumulators run inside for loops and while loops. Python's built-ins sum(), len(), and max() do the common cases for you, as covered in lists.