1. Lighthouse

Level 7 · Debug: basket sizes look far too small

The request

From Megan Collins, Head of Sales

“The script says our average web basket this morning was $34.45. I looked at the orders and not one web order was under $50. Something in the maths is off, can you fix it?”

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

Python

Loading the editor…

    ResultPress Run to see yours

    Mote checks your result

    Press Run. Each row that matches the goal becomes a firefly in your lantern.

    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.

    Pick what may run on this site. You can change this any time from "Cookie settings" at the bottom of every page.