1. Lighthouse

Level 7 · A weekly summary with built-ins

The request

From Megan Collins, Head of Sales

“Before Monday's call: total units this week, how many products are on the list, our best seller and our slowest seller by units, and the top three by revenue, numbered.”

Your goal

Set result to a dictionary with keys 'total_units' (sum of units, int), 'n_products' (number of products, int), 'best_seller' (name with the most units), 'slowest' (name with the fewest units), and 'top3' (a list of three strings like "1. Fern Rattan Desk Lamp": the products with the highest units * price, highest first, numbered 1 to 3).

  • 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

    The built-ins that do the counting

    Python ships with a handful of functions you will use in almost every script, no import needed:

    units = [row[1] for row in week]
    sum(units)      # 271
    len(week)       # 6
    max(units)      # 102
    min(units)      # 9
    sorted(units)   # [9, 15, 41, 46, 58, 102]  a new list, smallest first

    sum also takes a generator directly, sum(row[1] for row in week), so you don’t need the extra list. sorted returns a new list and leaves the original alone, unlike .sort(), which reorders the list in place.

    lambda: a tiny function for a key

    max(units) tells you the biggest number, but not which product sold it. To get the product, give max the whole rows and a key: a function that says what to compare. A lambda writes that function inline, in one expression:

    max(week, key=lambda row: row[1])   # ('Hazel Linen Throw Pillow', 102, 20.99)
    min(week, key=lambda row: row[1])   # ('Tidewater Concrete String Lights', 9, 379.0)

    lambda row: row[1] means “take a row, return its units”. It is the same as a def with one return line, without a name. The key can compute too, which is how you rank by revenue:

    sorted(week, key=lambda row: row[1] * row[2], reverse=True)

    The desk lamp sells only 15 units but at $379 it brings in $5,685, the most this week. The pillow, the best seller by units, is fifth by revenue ($2,140.98). Which “best” you report depends on the question, so name the measure.

    range for numbering

    range(start, stop) produces whole numbers from start up to, but not including, stop. range(1, 4) is 1, 2, 3, which is exactly the ranks of a top three:

    [f"{i}. {by_revenue[i - 1][0]}" for i in range(1, 4)]

    Ranks start at 1 but list positions start at 0, hence i - 1. range also takes a step: range(0, 14, 7) gives 0 and 7, the first day of each week in a two-week window. And range(len(week)) walks the positions 0 to 5, which you’ll see in older code that loops by index. Looping over the rows directly, as above, is usually clearer.

    Common mistakes

    • Calling max(week) with no key. Tuples compare by their first item, the name, so you get “Tidewater Concrete String Lights” because T comes last in the alphabet.
    • Forgetting reverse=True, which puts the smallest revenue first.
    • range(1, 3) for a top three. The stop value is excluded.

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