“Because running out of stock is bad… but overstocking is how you end up selling 2022 calendars in 2025.” 😬
🏢 The Business Setup¶
Meet CoffeeCo, a small but ambitious coffee retailer ☕. They sell premium beans, mugs, and caffeine-themed tote bags.
Lately, the CEO is worried:
“We either sell out too soon or end up with enough unsold mugs to build a fortress.” 🏰
Your mission, should you accept it: 📊 Use time-series forecasting to plan next quarter’s inventory.
🧰 Step 1. Gather the Data¶
The company tracked monthly sales of coffee beans for the past 3 years. Here’s what it looks like:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
months = pd.date_range(start='2021-01-01', periods=36, freq='M')
sales = 200 + 15*np.arange(36) + 50*np.sin(np.arange(36)/3) + np.random.normal(0, 30, 36)
df = pd.DataFrame({'ds': months, 'y': sales})
plt.plot(df['ds'], df['y'])
plt.title('☕ Monthly Coffee Bean Sales')
plt.xlabel('Month'); plt.ylabel('Units Sold')
plt.show()☕ The pattern? A growing trend, seasonal peaks, and occasional chaos (a.k.a. TikTok made them viral again).
🧙♂️ Step 2. Train a Forecasting Model (Prophet to the Rescue)¶
from prophet import Prophet
model = Prophet(yearly_seasonality=True)
model.fit(df)
future = model.make_future_dataframe(periods=6, freq='M')
forecast = model.predict(future)Just like that, Prophet gives you 6 months of data-driven hope.
📈 Step 3. Visualize the Forecast¶
from prophet.plot import plot_plotly, plot_components_plotly
plot_plotly(model, forecast)
plot_components_plotly(model, forecast)🎨 You’ll see:
A steady trend 📈
Predictable seasonality (every winter = caffeine spike) ❄️
Random holidays or marketing chaos (hi, “Pumpkin Spice Month”) 🎃
🧮 Step 4. Convert Forecast → Inventory Plan¶
The CEO asks:
“How much coffee should we stock for the next 6 months?”
You smile confidently (and open Excel).
future_sales = forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(6)
future_sales['inventory_plan'] = future_sales['yhat'] * 1.2 # 20% buffer
future_sales🧾 Interpretation:
yhat: Expected salesyhat_lower/yhat_upper: Uncertainty rangeinventory_plan: Add buffer so you don’t run out during sudden caffeine frenzies ☕💥
📊 Step 5. Evaluate Forecast Performance¶
Before you show your boss the results, test how good the model actually was:
from sklearn.metrics import mean_absolute_percentage_error
train = df.iloc[:-6]
test = df.iloc[-6:]
model = Prophet()
model.fit(train)
future = model.make_future_dataframe(periods=6, freq='M')
forecast = model.predict(future)
mape = mean_absolute_percentage_error(test['y'], forecast['yhat'][-6:])
print(f"MAPE: {mape*100:.2f}%")If your MAPE < 10%, celebrate with a triple espresso. If > 20%, tell your manager it’s a “data alignment issue.” 😅
💼 Step 6. Presenting to Management¶
Here’s how you sound smart in the meeting:
“Based on historical trends and seasonality, our forecast predicts a 15% growth in Q2. With a 20% safety stock buffer, we recommend ordering ~3,200 units for optimal coverage.”
Translation for business folks: ✅ No empty shelves ✅ No storage overflow ✅ You get credit for “AI-driven planning”
🧠 Step 7. Business Takeaways¶
| Lesson | Why It Matters |
|---|---|
| Forecasting reduces chaos | Turns gut-feel into data-driven strategy |
| Seasonality matters | Coffee sales spike in winter, dip in summer |
| Backtesting prevents embarrassment | Test before you tell finance |
| Buffers save your career | Always add a little extra stock |
| Visuals win meetings | Charts > 10 bullet points |
🎯 Final Result¶
Prophet says:
“Next quarter will be strong — order confidently, but not recklessly.”
The CEO says:
“Excellent. Also, make me a dashboard.”
You say:
“Coming right up… after one more coffee.” ☕💻
🧾 TL;DR¶
| Concept | Summary |
|---|---|
| Model Used | Prophet |
| Business Goal | Predict coffee bean sales for inventory |
| Key Metric | MAPE (Forecast Accuracy) |
| Best Practice | 20% buffer for uncertainty |
| Result | Predictable, scalable, caffeine-fueled success |
“Inventory planning is the fine art of predicting tomorrow’s chaos using yesterday’s confusion — preferably before finance notices.” 💼😅
# Your code here