1. Lighthouse

Level 7 · Boss: the monthly KPI sheet

The request

From Catherine Hale, Chief Executive Officer

“From January, leadership reviews one KPI sheet a month. Build 2025 as the first edition: the revenue block, the customer and traffic block, growth against last year, and a guardrail check that tells me which months broke the 7% return-rate limit, without counting months whose returns are not in yet.”

Your goal

Step 1 of 4. Revenue block. Set result to a DataFrame with one row per month of 2025 (sorted) and columns month, orders (distinct booked orders), net_sales, refunds, net_revenue (net_sales − refunds), aov (net_sales / orders) and return_rate_pct (refunds × 100 / net_sales), money and rates rounded to 2.

  • Use the order_items DataFramenot done yet
  • Use the returns DataFramenot done yet
  • Show exactly month orders net_sales refunds net_revenue aov return_rate_pctnot done yet

Step 1 · your code

Python

Loading the editor…

    ResultPreview of order_items · press Run to see yours
    Preview of order_items
    order_item_idorder_idproduct_idquantityunit_price
    11001121931.99
    21001154311.99
    31002154411.99
    410021941149.00

    Mote checks your result

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

    Step 2 · your code

    Python

    Loading the editor…

      ResultPreview of orders · press Run to see yours
      Preview of orders
      order_idcustomer_idorder_datestatuschannel
      10011252023-01-01 20:51:19completedweb
      10021562023-01-02 07:58:46completedweb
      1003222023-01-02 10:25:27completedmarketplace
      1004482023-01-02 11:21:51completedmarketplace

      Mote checks your result

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

      Step 3 · your code

      Python

      Loading the editor…

        ResultPreview of orders · press Run to see yours
        Preview of orders
        order_idcustomer_idorder_datestatuschannel
        10011252023-01-01 20:51:19completedweb
        10021562023-01-02 07:58:46completedweb
        1003222023-01-02 10:25:27completedmarketplace
        1004482023-01-02 11:21:51completedmarketplace

        Mote checks your result

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

        Step 4 · your code

        Python

        Loading the editor…

          ResultPreview of orders · press Run to see yours
          Preview of orders
          order_idcustomer_idorder_datestatuschannel
          10011252023-01-01 20:51:19completedweb
          10021562023-01-02 07:58:46completedweb
          1003222023-01-02 10:25:27completedmarketplace
          1004482023-01-02 11:21:51completedmarketplace

          Mote checks your result

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

          DataFrames

          Loaded for you as pandas DataFrames, plus pd and np.

          order_items30,338 rows · 6 columns
          • order_item_idinteger
          • order_idinteger
          • product_idinteger
          • quantityinteger
          • unit_pricedecimal
          • discount_pctdecimal
          First 5 rows of order_items
          order_item_idorder_idproduct_idquantityunit_pricediscount_pct
          11001121931.990.00
          21001154311.990.00
          31002154411.990.00
          410021941149.000.00
          51002193219.990.00
          returns1,673 rows · 5 columns
          • return_idinteger
          • order_item_idinteger
          • returned_ondate
          • reasonvarchar
          • refund_amountdecimal
          First 5 rows of returns
          return_idorder_item_idreturned_onreasonrefund_amount
          1142023-01-10damaged83.69
          2422023-01-10wrong_item19.99
          31052023-01-14wrong_item10.99
          4242023-01-16changed_mind26.99
          51262023-01-16late20.99
          orders12,000 rows · 7 columns
          • order_idinteger
          • customer_idinteger
          • order_datetimestamp
          • statusvarchar
          • channelvarchar
          • shipping_feedecimal
          • coupon_codevarchar
          First 5 rows of orders
          order_idcustomer_idorder_datestatuschannelshipping_feecoupon_code
          10011252023-01-01 20:51:19completedweb0.00NaN
          10021562023-01-02 07:58:46completedweb0.00NaN
          1003222023-01-02 10:25:27completedmarketplace4.99WELCOME10
          1004482023-01-02 11:21:51completedmarketplace4.99WELCOME10
          1005822023-01-02 11:43:36completedweb0.00WELCOME10
          web_sessions40,000 rows · 7 columns
          • session_idinteger
          • customer_idinteger
          • started_attimestamp
          • devicevarchar
          • sourcevarchar
          • pages_viewedinteger
          • convertedboolean
          First 5 rows of web_sessions
          session_idcustomer_idstarted_atdevicesourcepages_viewedconverted
          1NaN2023-01-01 23:02:24mobilepaid1false
          2182023-01-01 15:07:49desktoppaid1false
          3NaN2023-01-01 16:55:46desktopdirect7false
          4NaN2023-01-01 12:43:28mobileorganic3false
          5NaN2023-01-01 13:06:21mobilesocial2false
          customers2,018 rows · 9 columns
          • customer_idinteger
          • first_namevarchar
          • last_namevarchar
          • emailvarchar
          • cityvarchar
          • statevarchar
          • signup_datedate
          • segmentvarchar
          • referral_sourcevarchar
          First 5 rows of customers
          customer_idfirst_namelast_nameemailcitystatesignup_datesegmentreferral_source
          1OwenHudsonowen.hudson@icloud.comSan FranciscoCA2022-06-02consumersearch
          2DouglasMendozadmendoza69@gmail.comAtlantaGA2022-06-02consumerNaN
          3HenryBrookshbrooks@lakesidecafe.comLos AngelesCA2022-06-04businessNaN
          4BrianGrahambgraham@bluecedarhomes.comSeattleWA2022-06-06businesspinterest
          5KyleJimenezkjimenez27@yahoo.comIndianapolisIN2022-06-07consumerNaN
          products120 rows · 8 columns
          • product_idinteger
          • namevarchar
          • categoryvarchar
          • subcategoryvarchar
          • unit_pricedecimal
          • unit_costdecimal
          • launched_ondate
          • is_activeboolean
          First 5 rows of products
          product_idnamecategorysubcategoryunit_priceunit_costlaunched_onis_active
          101Vale Velvet LoveseatFurnitureSofas1659.00NaN2023-09-11true
          102Alder Oak Coffee TableFurnitureTables919.00503.502024-05-16true
          103Orchard Rattan Dining ChairFurnitureChairs789.00429.872023-05-27true
          104Upland Oak BookcaseFurnitureStorage429.00214.702022-12-20true
          105Avery Leather Bed FrameFurnitureBeds449.00232.702021-08-31true
          employees60 rows · 8 columns
          • employee_idinteger
          • first_namevarchar
          • last_namevarchar
          • departmentvarchar
          • titlevarchar
          • manager_idinteger
          • hire_datedate
          • salaryinteger
          First 5 rows of employees
          employee_idfirst_namelast_namedepartmenttitlemanager_idhire_datesalary
          1CatherineHaleExecutiveChief Executive OfficerNaN2016-03-01285000
          2RobertKimExecutiveChief Operating Officer12017-01-09235000
          3MeganCollinsSalesHead of Sales12018-04-16172000
          4ChloeGutierrezSalesAccount Executive32020-01-2172000
          5FrankBellSalesAccount Executive32023-05-2173000
          marketing_spend3,276 rows · 3 columns
          • spend_datedate
          • channelvarchar
          • amountdecimal
          First 5 rows of marketing_spend
          spend_datechannelamount
          2023-01-01paid492.99
          2023-01-01email37.38
          2023-01-01social200.53
          2023-01-02paid709.13
          2023-01-02email64.13

          The lesson

          A KPI sheet is a page, not a dashboard

          A KPI sheet is the one page a leadership team reads every month. It is short on purpose: the north star, the few numbers that drive it, growth against the same period last year, and the guardrails with a status. Everything on it has a written definition, and the definitions do not change between editions.

          Harbor & Pine’s sheet has four blocks, and you build one per step.

          Block 1: revenue

          Orders, net sales, refunds, net revenue (the north star), AOV and the return rate, one row per month. All of it comes from one table of booked, valid lines with the refund attached, so the numbers add up across columns: net revenue is net sales minus refunds, and AOV × orders gives net sales back.

          Block 2: customers and traffic

          Sessions, conversions, conversion rate and new customers. These are the drivers: revenue grows because more people visit, more of them buy, or more of them are new. The conversion rate is conversions over sessions in the same month, computed from the totals.

          Block 3: growth against last year

          Harbor & Pine is seasonal, so the growth column is year over year, not month over month. Put orders growth next to revenue growth: when orders grow and revenue does not, orders got smaller, and that deserves a sentence on the sheet.

          Block 4: guardrails with a maturity rule

          The return-rate guardrail is 7% of net sales. A month can only breach it once its returns are in, which takes up to 40 days after the month ends. Months younger than that are listed as not final instead of being judged early, so the newest months cannot look better than they are.

          Common mistakes

          • Averaging monthly rates for the year. Recompute annual rates from summed totals.
          • Month-over-month growth in a seasonal business. It measures the calendar.
          • Judging young months. Delayed metrics need a “final from” date.
          • Changing a definition between editions. If it must change, restate the history with it.

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