The request

From Catherine Hale, Chief Executive Officer
Your goal
Step 1 of 3. Set result to a dict for 2025 with three ints: "buyers" (distinct customers with a booked order in 2025), "new_customers" (of those, customers whose first booked order ever is in 2025) and "returning_customers" (the rest).
- Use the
ordersDataFramenot done yet - Use the
order_itemsDataFramenot done yet - Store a dict in
resultnot done yet
Step 2 of 3. Set result to a dict for 2025, each value rounded to 2: "aov" (net revenue / booked orders), "orders_per_buyer" (booked orders / distinct buyers) and "revenue_per_buyer" (net revenue / distinct buyers).
- Use the
ordersDataFramenot done yet - Use the
order_itemsDataFramenot done yet - Store a dict in
resultnot done yet
Step 3 of 3. Over all booked orders (2023–2025), set result to a DataFrame with one row per customer segment and the columns segment, customers (customers with a booked order), orders_per_customer (rounded to 2), ltv (net revenue per customer, rounded to 2) and revenue_share_pct (the segment's share of all net revenue × 100, rounded to 2). Sort by ltv, highest first.
- Use the
order_itemsDataFramenot done yet - Use the
returnsDataFramenot done yet - Show exactly
segmentcustomersorders_per_customerltvrevenue_share_pctnot done yet
Step 1 · your code
Loading the editor…
Reference solution
| order_id | customer_id | order_date | status | channel |
|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace |
Mote checks your result
Press Run. Each row that matches the goal becomes a firefly in your lantern.
Step 2 · your code
Loading the editor…
Reference solution
| order_id | customer_id | order_date | status | channel |
|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace |
Mote checks your result
Press Run. Each row that matches the goal becomes a firefly in your lantern.
Step 3 · your code
Loading the editor…
Reference solution
| order_item_id | order_id | product_id | quantity | unit_price |
|---|---|---|---|---|
| 1 | 1001 | 121 | 9 | 31.99 |
| 2 | 1001 | 154 | 3 | 11.99 |
| 3 | 1002 | 154 | 4 | 11.99 |
| 4 | 1002 | 194 | 1 | 149.00 |
Mote checks your result
Press Run. Each row that matches the goal becomes a firefly in your lantern.
What Catherine gets, and why
DataFrames
Loaded for you as pandas DataFrames, plus pd and np.
orders12,000 rows · 7 columns
order_idintegercustomer_idintegerorder_datetimestampstatusvarcharchannelvarcharshipping_feedecimalcoupon_codevarchar
| order_id | customer_id | order_date | status | channel | shipping_fee | coupon_code |
|---|---|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web | 0.00 | NaN |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web | 0.00 | NaN |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace | 4.99 | WELCOME10 |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace | 4.99 | WELCOME10 |
| 1005 | 82 | 2023-01-02 11:43:36 | completed | web | 0.00 | WELCOME10 |
order_items30,338 rows · 6 columns
order_item_idintegerorder_idintegerproduct_idintegerquantityintegerunit_pricedecimaldiscount_pctdecimal
| order_item_id | order_id | product_id | quantity | unit_price | discount_pct |
|---|---|---|---|---|---|
| 1 | 1001 | 121 | 9 | 31.99 | 0.00 |
| 2 | 1001 | 154 | 3 | 11.99 | 0.00 |
| 3 | 1002 | 154 | 4 | 11.99 | 0.00 |
| 4 | 1002 | 194 | 1 | 149.00 | 0.00 |
| 5 | 1002 | 193 | 2 | 19.99 | 0.00 |
returns1,673 rows · 5 columns
return_idintegerorder_item_idintegerreturned_ondatereasonvarcharrefund_amountdecimal
| return_id | order_item_id | returned_on | reason | refund_amount |
|---|---|---|---|---|
| 1 | 14 | 2023-01-10 | damaged | 83.69 |
| 2 | 42 | 2023-01-10 | wrong_item | 19.99 |
| 3 | 105 | 2023-01-14 | wrong_item | 10.99 |
| 4 | 24 | 2023-01-16 | changed_mind | 26.99 |
| 5 | 126 | 2023-01-16 | late | 20.99 |
customers2,018 rows · 9 columns
customer_idintegerfirst_namevarcharlast_namevarcharemailvarcharcityvarcharstatevarcharsignup_datedatesegmentvarcharreferral_sourcevarchar
| customer_id | first_name | last_name | city | state | signup_date | segment | referral_source | |
|---|---|---|---|---|---|---|---|---|
| 1 | Owen | Hudson | owen.hudson@icloud.com | San Francisco | CA | 2022-06-02 | consumer | search |
| 2 | Douglas | Mendoza | dmendoza69@gmail.com | Atlanta | GA | 2022-06-02 | consumer | NaN |
| 3 | Henry | Brooks | hbrooks@lakesidecafe.com | Los Angeles | CA | 2022-06-04 | business | NaN |
| 4 | Brian | Graham | bgraham@bluecedarhomes.com | Seattle | WA | 2022-06-06 | business | |
| 5 | Kyle | Jimenez | kjimenez27@yahoo.com | Indianapolis | IN | 2022-06-07 | consumer | NaN |
products120 rows · 8 columns
product_idintegernamevarcharcategoryvarcharsubcategoryvarcharunit_pricedecimalunit_costdecimallaunched_ondateis_activeboolean
| product_id | name | category | subcategory | unit_price | unit_cost | launched_on | is_active |
|---|---|---|---|---|---|---|---|
| 101 | Vale Velvet Loveseat | Furniture | Sofas | 1659.00 | NaN | 2023-09-11 | true |
| 102 | Alder Oak Coffee Table | Furniture | Tables | 919.00 | 503.50 | 2024-05-16 | true |
| 103 | Orchard Rattan Dining Chair | Furniture | Chairs | 789.00 | 429.87 | 2023-05-27 | true |
| 104 | Upland Oak Bookcase | Furniture | Storage | 429.00 | 214.70 | 2022-12-20 | true |
| 105 | Avery Leather Bed Frame | Furniture | Beds | 449.00 | 232.70 | 2021-08-31 | true |
employees60 rows · 8 columns
employee_idintegerfirst_namevarcharlast_namevarchardepartmentvarchartitlevarcharmanager_idintegerhire_datedatesalaryinteger
| employee_id | first_name | last_name | department | title | manager_id | hire_date | salary |
|---|---|---|---|---|---|---|---|
| 1 | Catherine | Hale | Executive | Chief Executive Officer | NaN | 2016-03-01 | 285000 |
| 2 | Robert | Kim | Executive | Chief Operating Officer | 1 | 2017-01-09 | 235000 |
| 3 | Megan | Collins | Sales | Head of Sales | 1 | 2018-04-16 | 172000 |
| 4 | Chloe | Gutierrez | Sales | Account Executive | 3 | 2020-01-21 | 72000 |
| 5 | Frank | Bell | Sales | Account Executive | 3 | 2023-05-21 | 73000 |
web_sessions40,000 rows · 7 columns
session_idintegercustomer_idintegerstarted_attimestampdevicevarcharsourcevarcharpages_viewedintegerconvertedboolean
| session_id | customer_id | started_at | device | source | pages_viewed | converted |
|---|---|---|---|---|---|---|
| 1 | NaN | 2023-01-01 23:02:24 | mobile | paid | 1 | false |
| 2 | 18 | 2023-01-01 15:07:49 | desktop | paid | 1 | false |
| 3 | NaN | 2023-01-01 16:55:46 | desktop | direct | 7 | false |
| 4 | NaN | 2023-01-01 12:43:28 | mobile | organic | 3 | false |
| 5 | NaN | 2023-01-01 13:06:21 | mobile | social | 2 | false |
marketing_spend3,276 rows · 3 columns
spend_datedatechannelvarcharamountdecimal
| spend_date | channel | amount |
|---|---|---|
| 2023-01-01 | paid | 492.99 |
| 2023-01-01 | 37.38 | |
| 2023-01-01 | social | 200.53 |
| 2023-01-02 | paid | 709.13 |
| 2023-01-02 | 64.13 |
The lesson
What goes on a customer one-pager
A leadership team asks the same three questions about customers every planning cycle: how many did we serve and how many were new, what is a customer worth in a year, and which customers carry the business. Each block in this level answers one of them, and each needs the definitions from this chapter: booked orders only, net revenue after discounts and refunds, a customer is new in the year of their first booked order.
Block 1: the base
Buyers in 2025 are distinct customers with a booked order that year. Splitting them into new and returning needs each customer’s first booked order over all years, not within 2025, otherwise every 2025 buyer looks new. Report the counts, not only the share: 641 new customers is a number a marketing plan can be built on.
Block 2: value per buyer
Three totals give three ratios: AOV (revenue per order), orders per buyer and revenue per buyer. The third is the product of the first two, which is a useful cross-check: if your revenue per buyer does not equal AOV times frequency, one of the denominators is wrong. Revenue per buyer in a year is also the building block of the predictive LTV from level 4.
Block 3: segments
Segment comparisons are customer metrics, so collapse orders to one row per customer before grouping by segment. Grouping orders directly by segment gives revenue per order, a different question. Put the revenue share next to the per-customer value: a segment can be worth six times more per customer and still be a minority of revenue, or, as here, be 15% of customers and more than half of revenue.
Common mistakes
- Mixing windows. Blocks 1 and 2 are 2025; block 3 is 2023–2025. Say so on the slide.
- Calling all buyers “customers acquired”. Returning buyers were acquired in earlier years and belong to those cohorts.
- Averages without counts. A per-customer value means little until the reader knows how many customers it covers.
Interview note
Case interviews often end with “what would you put in front of the CEO?”. Three blocks, each with a number, its definition and one sentence of meaning, is a strong structure. Add the caveat that matters most: here, that a few business accounts carry the revenue, so losing one is a real risk.
Lantern lit!
Practised: new customersaovpurchase frequencyltvsegmentreporting
- Solved
- No hints
- First run
