The request

From Megan Collins, Head of Sales
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
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
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.
Lantern lit!
Practised: built in functionslambdasortedmax min keyrange
- Solved
- No hints
- First run
