Case Study: Simplifying the Menu
Revenue isn't profit.
The head of operations wants a shorter menu. Fewer products mean less waste, faster service, and simpler training. Everybody agrees on that. But which ones should go? The obvious answer is to cut whatever sells the least. Is that the right call?

- A shorter menu
- Less waste, faster service
- Cut what sells least?
Step one: look beyond revenue
We calculate revenue, margin, and share of profit for each product. Run it. Look at sandwiches. They're the second biggest seller by revenue, at a million dollars. But their margin is only fifty percent, the lowest on the menu, so they're fourth for profit. Now look at tea. It's near the bottom for revenue, yet it has the highest margin of all, at eighty four percent. If you'd ranked by revenue, you might have cut tea, and that would have been a mistake.
import pandas as pd
s = pd.read_csv("sales.csv")
t = s.groupby("product").agg(revenue=("revenue", "sum"), profit=("profit", "sum"), units=("units", "sum"))
t["margin"] = (t["profit"] / t["revenue"]).round(2)
t["share"] = (t["profit"] / t["profit"].sum()).round(3)
print(t.sort_values("profit", ascending=False)[["revenue", "margin", "share"]].round(2).to_string())revenue margin share product Latte 1803083.40 0.69 0.30 Flat White 922106.34 0.67 0.15 Espresso 738690.30 0.73 0.13 Sandwich 1000441.00 0.50 0.12 Mocha 771012.50 0.62 0.11 Muffin 592162.90 0.57 0.08 Tea 393887.04 0.84 0.08 Cookie 231740.25 0.64 0.04
Step two: how concentrated is it?
The Pareto idea says that a few items usually make most of the profit. Let's check. We sort them, and add up as we go. Run it. It takes five of the eight products to reach eighty percent of the profit. So this menu isn't very concentrated, and that's interesting in itself. Cutting the bottom product, cookies, only touches about three and a half percent of profit. So it's a small risk, but there's only a small gain as well.
import pandas as pd
s = pd.read_csv("sales.csv")
t = s.groupby("product")["profit"].sum().sort_values(ascending=False)
c = (t.cumsum() / t.sum()).round(3)
print(c.to_string())
print("Products for 80% of profit:", int((c < .8).sum()) + 1, "of", len(t))product Latte 0.295 Flat White 0.443 Espresso 0.572 Sandwich 0.692 Mocha 0.805 Muffin 0.886 Tea 0.965 Cookie 1.000 Products for 80% of profit: 5 of 8
Step three: which way are they heading?
Finally, is anything growing or shrinking? We compare units year on year. Run it. Everything's growing, from fourteen to seventeen percent. Mocha's growing fastest. There's no dying product here. So simplifying the menu won't be about removing failures, as there aren't any. It's a question of cost and complexity. And that's the kind of honest finding that stops a costly mistake.
import pandas as pd
s = pd.read_csv("sales.csv", parse_dates=["date"])
s["y"] = s["date"].dt.year
t = s.pivot_table(index="product", columns="y", values="units", aggfunc="sum")
t["growth"] = (t[2025] / t[2024] - 1).round(3)
print(t.sort_values("growth")[["growth"]].iloc[[0, 1, -2, -1]].to_string())y growth product Espresso 0.144 Flat White 0.144 Muffin 0.160 Mocha 0.173
What you recommend
Recommendation, keep tea, and don't cut anything on profit grounds alone. Test removing cookies in two cafes, as it's the smallest contributor. Look at the cost of sandwiches, as raising their margin by five points is worth far more than any cut. And remember what's missing. People may come for a coffee, and stay for a sandwich. Product data alone can't tell you that, so you'd need receipt data.
Summary
Rank by profit, not revenue, and look for what the data can't see. Next, who are our most valuable customers?
Key takeaways- Margin changes the ranking
- Check the concentration
- Look for missing data