The request

From Megan Collins, Head of Sales
Your goal
Fix the code so result is a dictionary mapping each channel to its average order total (the channel's total divided by the number of orders in that channel), rounded to 2 decimals.
- Store a dict in
resultnot done yet
Your code
Loading the editor…
Reference solution
Mote checks your result
Press Run. Each row that matches the goal becomes a firefly in your lantern.
What Megan gets, and why
The lesson
An average is a total over a count of the same group
To average per group by hand you keep two dictionaries side by side: a running total and a running count for every key. One pass over the orders fills both:
for channel, total in orders:
totals[channel] = totals.get(channel, 0) + total
counts[channel] = counts.get(channel, 0) + 1
# totals: web 344.45, app 226.48, marketplace 273.25
# counts: web 4, app 4, marketplace 2
The average for a channel is its total divided by its own count. Web is 344.45 / 4 = 86.11.
Dividing by len(orders), which is 10, mixes two groups: web’s money with everyone’s orders. That
gives 34.45, a number that doesn’t describe anything real. The three wrong “averages” even add up to
the overall average of all orders ($84.42), which is a hint that the denominator is shared.
Sense-check every average
You don’t need to read the code to know the starter is broken. An average always sits between the smallest and the largest value in its group. The smallest web order this morning was $57.80, so an average web basket of $34.45 is impossible. The same test works for every channel:
- app orders run from $38.40 to $95.10, so the app average must be in that range ($56.62 is);
- marketplace has two orders, $61.25 and $212.00, so its average is halfway between, $136.62.
Running this kind of check before you send numbers takes seconds and saves embarrassing corrections.
Why the counts were “right” but unused
Bugs like this are common when code is edited over time. Someone added the counts dictionary
correctly, but the division line was written earlier and kept len(orders). Nothing fails, there’s
no error, and the output has the right shape: one number per channel. Only the values are wrong,
which is why it’s worth looking at the numbers and not just at whether the script runs.
Common mistakes
- Dividing by the total number of rows instead of the group’s count.
- Rounding the totals before dividing, which can move the last cent.
- Resetting
totals = {}inside the loop, so only the last order survives. Keep the empty dictionaries above the loop.
Lantern lit!
Practised: debuggingdictionariesaveragesaccumulator
- Solved
- No hints
- First run
