, it’s simple to make an impression along with your knowledge science and analytics abilities.
Even when knowledge high quality stays a problem more often than not, you could find alternatives to unravel issues by offering insights to operational groups.
Operations Supervisor: “What number of short-term staff ought to I recruit subsequent to fulfill our workforce demand on the lowest price?
Once I was a Provide Chain Answer Supervisor in a logistics firm, I discovered knowledge science by making use of mathematical rules to unravel operational issues in our warehouses.
It was very archaic.
I used to be operating Python scripts or Jupyter notebooks on my machine and sharing the outcomes with my colleagues.
Till I found Streamlit, which let me effortlessly package deal my fashions into net purposes that I might simply deploy.

That is essential for any provide chain course of engineer or knowledge scientist to discover ways to productise analytics instruments.
How you can rework Python code into actionable insights?
On this article, I’ll present you easy methods to rework a simulation mannequin inbuilt Jupyter Pocket book into a completely functioning net utility.
This train was a part of a tutorial sequence on my YouTube Channel, wherein we use Python to be taught Stock Administration in Provide Chain.
You’ll find out how I took a core module written in Python scripts to construct an interactive utility with which you’ll:
- Simulate a number of stock administration guidelines
- Check a number of eventualities with totally different supply lead instances (LD in days), demand variability (sigma in items) and cycle time (T in days)
If you’re not accustomed to these ideas, you’ll be able to nonetheless observe this tutorial, as I’ll briefly introduce them within the first part.
Or you’ll be able to instantly leap into the second part that focuses solely on the creation and deployment of the app.
Stock Administration Simulation with Python
What’s stock administration?
Most retailers I’ve labored with in Asia and Europe handle retailer orders with rule-based strategies constructed into their ERPs.
When do you have to replenish your shops to keep away from stock-outs?
These guidelines are often applied in an Enterprise Useful resource Planning (ERP) software program that sends orders to a Warehouse Administration System (WMS).

The purpose is to develop a coverage that minimises ordering, holding and lack prices.
- Ordering Prices: fastened price to position an order
- Holding Prices: variable prices required to maintain your stock (storage and capital prices)
- Scarcity Prices: the prices of not having sufficient stock to fulfill the client demand (Misplaced Gross sales, Penalty)
We’ll act as knowledge scientists in a retail firm and assess the effectivity of the stock group’s guidelines.
Logistics Director: “Samir, we’d like your help to know why some shops face stockouts whereas different have an excessive amount of stock.”
For that, we’d like a software to simulate a number of eventualities and visualise the impression of key parameters on prices and inventory availability.

Within the chart above, you could have an instance of a rule with:
- A uniform demand distribution (i.e σ = 0)
Day by day, your retailer will promote the identical variety of gadgets. - A periodic evaluation coverage with T = 10 days
You replenish the shops each 10 days. - A supply lead time of LD = 1 day.
For those who order at present, you’ll obtain the products tomorrow.
As you’ll be able to see within the inexperienced chart, your stock on-hand (IOH) is all the time optimistic (i.e. you don’t expertise stock-outs).
- What if in case you have a 3-day lead time?
- What could be the impression of variability within the demand (σ > 0)?
- Can we cut back the typical stock available?
To reply these questions, I developed a simulation mannequin utilizing Jupyter Pocket book to generate visuals in a complete tutorial.

On this article, I’ll briefly introduce the core features I constructed on this tutorial and present how we are going to reuse them in our Streamlit app.
Observe: I’ll maintain explanations high-level to give attention to the Streamlit app. For particulars, you’ll be able to watch the complete video later.
Your Stock Simulation Device in a Jupyter Pocket book
The outcomes of this tutorial will function the core basis of our Stock Simulation Streamlit App.
The undertaking construction is primary with two Python information (.py) and a Jupyter Pocket book.
tuto_inventory /
├─ Stock Administration.ipynb
└─ stock/
├─ init.py
├─ inventory_analysis.py
└─ inventory_models.py
In inventory_models.py, you could find a Pydantic class that incorporates all of the enter parameters for our simulation.
from typing import Non-compulsory, Literal
from pydantic import BaseModel, Area
class InventoryParams(BaseModel):
"""Base financial & demand parameters (deterministic day by day demand)."""
D: float = Area(2000, gt=0, description="Annual demand (items/12 months)")
T_total: int = Area(365, ge=1, description="Days in horizon (often 365)")
LD: int = Area(0, ge=0, description="Lead time (days)")
T: int = Area(10, ge=1, description="Cycle time (days)")
Q: float = Area(0, ge=0, description="Order amount (items)")
initial_ioh: float = Area(0, description="Preliminary stock available")
sigma: float = Area(0, ge=0, description="Normal deviation of day by day demand (items/day)")
These operational parameters cowl
- Demand Distribution: the entire demand
D(pcs), our simulation horizonT_total(pcs) and the variability σ (pcs) - Logistics Operations: with the supply lead time
LD(in days) - Stock rule parameters: together with the cycle time
T, order amountQand the preliminary stock availableinitial_ioh
Based mostly on these parameters, we need to simulate the impression on our distribution chain:
- Demand distribution: what number of items did we promote?
- Stock On-Hand in inexperienced: what number of items do now we have within the retailer?
- Replenishment orders in blue: when and the way a lot have we ordered?

Within the instance above, you see a simulation of a periodic evaluation coverage with a 10-day cycle time.
How did I generate these visuals?
These features are simulated utilizing the category InventorySimulation created in inventory_analysis.py.
class InventorySimulation:
def __init__(self,
params: InventoryParams):
self.kind = kind
self.D = params.D
self.T_total = params.T_total
self.LD = params.LD
self.T = params.T
self.Q = params.Q
self.initial_ioh = params.initial_ioh
self.sigma = params.sigma
# # Demand per day (unit/day)
self.D_day = self.D / self.T_total
# Simulation dataframe
self.sim = pd.DataFrame({'time': np.array(vary(1, self.T_total+1))})
We begin by initialising the enter parameters for the features:
order()which represents a periodic ordering coverage (you order Q items each T days)simulation_1()that calculates the impression of the demand (gross sales) and the ordering coverage on the stock available every day
class InventorySimulation:
''' [Beginning of the class] '''
def order(self, t, T, Q, start_day=1):
"""Order Q beginning at `start_day`, then each T days."""
return Q if (t > start_day and ((t-start_day) % T) == 0) else 0
def simulation_1(self):
"""Mounted-cycle ordering; lead time NOT compensated."""
sim_1 = self.sim.copy()
sim_1['demand'] = np.random.regular(self.D_day, self.sigma, self.T_total)
T = int(self.T)
Q = float(self.Q)
sim_1['order'] = sim_1['time'].apply(lambda t: self.order(t, T, Q))
LD = int(self.LD)
sim_1['receipt'] = sim_1['order'].shift(LD, fill_value=0.0)
# Stock: iterative replace to respect lead time
ioh = [self.initial_ioh]
for t in vary(1, len(sim_1)):
new_ioh = ioh[-1] - sim_1.loc[t, 'demand']
new_ioh += sim_1.loc[t, 'receipt']
ioh.append(new_ioh)
sim_1['ioh'] = ioh
for col in ['order', 'ioh', 'receipt']:
sim_1[col] = np.rint(sim_1[col]).astype(int)
return sim_1
The perform simulation_1() features a mechanism that updates stock on-hand based mostly on retailer demand (gross sales) and provide (replenishment orders).
My purpose for this tutorial was to begin with two primary guidelines to clarify what occurs once you introduce a lead time, as proven under.

Shops expertise stock-outs, as proven within the inexperienced chart.
Their on-hand stock turns into unfavorable because of late deliveries.
What can we do? Perhaps growing the order amount Q?
That is what I attempted within the tutorial; we found that this resolution doesn’t work.

These two eventualities highlighted the necessity for an improved ordering coverage that compensates for lead instances.
That’s what we constructed within the second a part of the tutorial with these two further features.
class InventorySimulation:
''' [Beginning of the class] '''
def order_leadtime(self, t, T, Q, LD, start_day=1):
return Q if (t > start_day and ((t-start_day + (LD-1)) % T) == 0) else 0
def simulation_2(self, technique: Non-compulsory[str] = "order_leadtime"):
"""Mounted-cycle ordering; lead time NOT compensated."""
sim_1 = self.sim.copy()
LD = int(self.LD)
sim_1['demand'] = np.most(np.random.regular(self.D_day, self.sigma, self.T_total), 0)
T = int(self.T)
Q = float(self.Q)
if technique == "order_leadtime":
sim_1['order'] = sim_1['time'].apply(lambda t: self.order_leadtime(t, T, Q, LD))
else:
sim_1['order'] = sim_1['time'].apply(lambda t: self.order(t, T, Q))
sim_1['receipt'] = sim_1['order'].shift(LD, fill_value=0.0)
# Stock: iterative replace to respect lead time
ioh = [self.initial_ioh]
for t in vary(1, len(sim_1)):
new_ioh = ioh[-1] - sim_1.loc[t, 'demand']
new_ioh += sim_1.loc[t, 'receipt']
ioh.append(new_ioh)
sim_1['ioh'] = ioh
for col in ['order', 'ioh', 'receipt']:
sim_1[col] = np.rint(sim_1[col]).astype(int)
return sim_1
The thought is sort of easy.
In apply, which means stock planners should create replenishment orders at day = T – LD to compensate for the lead time.

This ensures shops obtain their items on day = T as proven within the chart above.
On the finish of this tutorial, we had an entire simulation software that allows you to take a look at any state of affairs to turn into accustomed to stock administration guidelines.
For those who want extra clarification, you could find detailed explanations in this step-by-step YouTube tutorial:
Nonetheless, I used to be not glad with the end result.
Why do we have to package deal this in an online utility?
Productising This Simulation Device
As you’ll be able to see within the video, I manually modified the parameters within the Jupyter pocket book to check totally different eventualities.

That is considerably regular for knowledge scientists like us.
However, would you think about our Logistics Director opening a Jupyter Pocket book in VS Code to check the totally different eventualities?
We have to productise this software so anybody can entry it with out requiring programming or knowledge science abilities.
Excellent news, 70% of the job is finished as now we have the core modules.
Within the subsequent part, I’ll clarify how we will package deal this in a user-friendly analytics product.
Create your Stock Simulation App utilizing Streamlit
On this part, we are going to create a single-page Streamlit App based mostly on the core module from the primary tutorial.
You can begin by cloning this repository that incorporates the core simulation, together with inventory_models.py and inventory_analysis.py.

With this repository in your native machine, you’ll be able to observe the tutorial and find yourself with a deployed app like this one:

Let’s begin!
Undertaking Setup
Step one is to create a neighborhood Python setting for the undertaking.
For that, I counsel you to make use of the package deal supervisor uv:
# Create a digital setting and activate it
uv init
uv venv
supply .venv/bin/activate
# Set up
uv pip set up -r necessities.txt
It is going to set up the libraries listed within the necessities file:
streamlit>=1.37
pandas>=2.0
numpy>=1.24
matplotlib>=3.7
pydantic>=2.0
We embrace Streamlit, Pydantic, and libraries for knowledge manipulation (numpy, pandas) and for producing visuals (matplotlib).
Now you might be able to construct your app.
Create your Streamlit Web page
Create a Python file that you just name: app.py
import numpy as np
import matplotlib.pyplot as plt
import streamlit as st
from stock.inventory_models import InventoryParams
from stock.inventory_analysis import InventorySimulation
seed = 1991
np.random.seed(seed)
st.set_page_config(page_title="Stock Simulation – Streamlit", structure="broad")
On this file, we begin by:
- Importing the libraries put in and the evaluation module with its Pydantic class for the enter parameters
- Defining a seed for random distribution era that might be used to generate a variable demand
Then we begin to create the web page with st.set_page_config(), wherein we embrace as parameters:
page_title: the title of the net web page of your appstructure: an choice to set the structure of the web page

By setting the parameter structure to “broad”, we make sure the web page is broad by default.
You’ll be able to run your app now,
streamlit run app.py
After operating this command, your app will be opened utilizing the native URL shared in your terminal:

After loading, what you could have is that this clean web page:

Congratulations, you could have run your app!
For those who face any points at this stage, please examine that:
- The native Python setting is about up correctly
- You could have put in all of the libraries inside the necessities file
Now we will begin constructing our Stock Administration App.
A Sidebar with Stock Administration Parameters
Do you bear in mind the Pydantic class now we have outlined in inventory_models.py?
They’ll function our enter parameters for the app, and we are going to show them in a Streamlit sidebar.
with st.sidebar:
st.markdown("**Stock Parameters**")
D = st.number_input("Annual demand D (items/12 months)", min_value=1, worth=2000, step=50)
T_total = st.number_input("Horizon T_total (days)", min_value=1, worth=365, step=1)
LD = st.number_input("Lead time LD (days)", min_value=0, worth=0, step=1)
T = st.number_input("Cycle time T (days)", min_value=1, worth=10, step=1)
Q = st.number_input("Order amount Q (items)", min_value=0.0, worth=55.0, step=10.0, format="%.2f")
initial_ioh = st.number_input("Preliminary stock available", min_value=0.0, worth=55.0, step=1.0, format="%.2f")
sigma = st.number_input("Day by day demand std. dev. σ (items/day)", min_value=0.0, worth=0.0, step=0.5, format="%.2f")
technique = st.radio(
"Ordering technique",
choices=["Simple Ordering", "Lead-time Ordering"],
index=0
)
method_key = "order_leadtime" if technique.startswith("Lead-time") else "order"
run = st.button("Run simulation", kind="main")
if run:
st.session_state.has_run = True
On this sidebar, we embrace:
- A title utilizing
st.markdown() - Quantity Enter fields for all of the parameters with their minimal, default, and incremental step values
- A radio button to pick the ordering technique (contemplating or not lead time)
- A button to begin the primary simulation

Earlier than this block, we should always add a session state variable:
if "has_run" not in st.session_state:
st.session_state.has_run = False
This boolean signifies whether or not the consumer has already clicked the simulation button.
If that’s the case, the app will mechanically rerun all calculations at any time when the consumer modifications a parameter.
Nice, now you app.py ought to seem like this:
import numpy as np
import matplotlib.pyplot as plt
import streamlit as st
from stock.inventory_models import InventoryParams
from stock.inventory_analysis import InventorySimulation
seed = 1991
np.random.seed(seed)
st.set_page_config(page_title="Stock Simulation – Streamlit", structure="broad")
if "has_run" not in st.session_state:
st.session_state.has_run = False
with st.sidebar:
st.markdown("**Stock Parameters**")
D = st.number_input("Annual demand D (items/12 months)", min_value=1, worth=2000, step=50)
T_total = st.number_input("Horizon T_total (days)", min_value=1, worth=365, step=1)
LD = st.number_input("Lead time LD (days)", min_value=0, worth=0, step=1)
T = st.number_input("Cycle time T (days)", min_value=1, worth=10, step=1)
Q = st.number_input("Order amount Q (items)", min_value=0.0, worth=55.0, step=10.0, format="%.2f")
initial_ioh = st.number_input("Preliminary stock available", min_value=0.0, worth=55.0, step=1.0, format="%.2f")
sigma = st.number_input("Day by day demand std. dev. σ (items/day)", min_value=0.0, worth=0.0, step=0.5, format="%.2f")
technique = st.radio(
"Ordering technique",
choices=["Simple Ordering", "Lead-time Ordering"],
index=0
)
method_key = "order_leadtime" if technique.startswith("Lead-time") else "order"
run = st.button("Run simulation", kind="main")
if run:
st.session_state.has_run = True
You’ll be able to take a look at your app, usually the window ought to seem like this after a refresh:

On the left, you could have your sidebar that we simply created.

Then, for aesthetics and consumer expertise, I need to add a title and a reminder of the parameters used.
Why do I need to remind the parameters used?
On the top-left aspect of the window, you could have a button to cover the aspect panel, as proven under.

This helps customers to have more room to point out the visible.
Nonetheless, the enter parameters might be hidden.
Subsequently, we have to add a reminder on the prime.
st.title("Stock Simulation Internet Software")
# Chosen Enter Parameters
D_day = D / T_total
st.markdown("""
""", unsafe_allow_html=True)
def quick_card(label, worth, unit=""):
unit_html = f'{unit}
' if unit else ""
st.markdown(f'{label}
{worth}
{unit_html}', unsafe_allow_html=True)
Within the piece of code above, I’ve launched :
- CSS styling embedded in Streamlit to create playing cards
- The perform quick_card will create a card for every parameter utilizing its
label,worthanditems

Then we will generate these playing cards in the identical row utilizing the streamlit object st.columns().
c1, c2, c3, c4, c5, c6 = st.columns(6)
with c1:
quick_card("Common day by day demand", f"{D_day:,.2f}", "items/day")
with c2:
quick_card("Lead time", f"{LD}", "days")
with c3:
quick_card("Cycle time", f"{T}", "days")
with c4:
quick_card("Order amount Q", f"{Q:,.0f}", "items")
with c5:
quick_card("Preliminary IOH", f"{initial_ioh:,.0f}", "items")
with c6:
quick_card("Demand σ", f"{sigma:.2f}", "items/day")
The primary line defines the six columns wherein we place the playing cards utilizing the quick_card perform.

We are able to transfer on to the fascinating half: integrating the simulation software into the app.
Any query or blocking at this step? You should use the remark part of the video, I’ll strive my greatest to reply promptly.
Integrating the stock simulation module within the Streamlit App
We are able to now begin engaged on the primary web page.
Allow us to think about that our Logistics Director arrives on the web page, selects the totally different parameters and clicks on “Run Simulation”.
This could set off the simulation module:
if st.session_state.has_run:
params = InventoryParams(
D=float(D),
T_total=int(T_total),
LD=int(LD),
T=int(T),
Q=float(Q),
initial_ioh=float(initial_ioh),
sigma=float(sigma)
)
sim_engine = InventorySimulation(params)
On this quick piece of code, we do many issues:
- We construct the enter parameter object utilizing the Pydantic class from
inventory_models.py
This ensures each worth (demand, lead time, evaluation interval, sigma…) has the proper knowledge kind earlier than operating the simulation. - We create the simulation engine
InventorySimulationclass frominventory_analysis.py
This class incorporates all of the stock logic I developed within the first tutorial.
Nothing will change on the consumer interface.
We are able to now begin to outline the computation half.
if st.session_state.has_run:
''' [Previous block introduced above]'''
if method_key == "order_leadtime":
df = sim_engine.simulation_2(technique="order_leadtime")
elif method_key == "order":
df = sim_engine.simulation_2(technique="order")
else:
df = sim_engine.simulation_1()
# Calculate key parameters that might be proven under the visible
stockouts = (df["ioh"] < 0).sum()
min_ioh = df["ioh"].min()
avg_ioh = df["ioh"].imply()
First, we choose the proper ordering technique.
Relying on the ordering rule chosen within the radio button of the sidebar, we name the suitable simulation technique:
- technique=”order”: is the preliminary technique that I confirmed you, which didn’t maintain a secure stock once I added a lead time
- technique=”order_leadtime”: is the improved technique that orders at day = T – LD

The outcomes, saved within the pandas dataframe, df are used to compute key indicators such because the variety of stockouts and the minimal and most stock ranges.
Now that now we have simulation outcomes accessible, let’s create our visuals.
Create Stock Simulation Visuals on Streamlit
For those who adopted the video model of this tutorial, you in all probability seen that I copied and pasted the code from the pocket book created within the first tutorial.
if st.session_state.has_run:
'''[Previous Blocks introduced above]'''
# Plot
fig, axes = plt.subplots(3, 1, figsize=(9, 4), sharex=True) # ↓ from (12, 8) to (9, 5)
# Demand
df.plot(x='time', y='demand', ax=axes[0], coloration='r', legend=False, grid=True)
axes[0].set_ylabel("Demand", fontsize=8)
# Orders
df.plot.scatter(x='time', y='order', ax=axes[1], coloration='b')
axes[1].set_ylabel("Orders", fontsize=8); axes[1].grid(True)
# IOH
df.plot(x='time', y='ioh', ax=axes[2], coloration='g', legend=False, grid=True)
axes[2].set_ylabel("IOH", fontsize=8); axes[2].set_xlabel("Time (day)", fontsize=8)
# Widespread x formatting
axes[2].set_xlim(0, int(df["time"].max()))
for ax in axes:
ax.tick_params(axis='x', rotation=90, labelsize=6)
ax.tick_params(axis='y', labelsize=6)
plt.tight_layout()
Certainly, the identical visible code that you just use to prototype in your Notebooks will work in your app.
The one distinction is that as an alternative of utilizing plt.present(), you conclude the part with:
st.pyplot(fig, clear_figure=True, use_container_width=True)
Streamlit must explicitly management of the rendering utilizing
figwhich is the Matplotlib determine you created earlier.clear_figure=Truewhich is a parameter to clear the determine from reminiscence after rendering to keep away from duplicated plots when parameters are up to date.use_container_width=Trueto make the chart mechanically resize to the width of the Streamlit web page
At this stage, usually you could have this in your app:

For those who attempt to change any parameter, for instance, change the ordering technique, you will notice the visible mechanically up to date.
What’s remaining?
As a bonus, I added a bit that can assist you uncover further functionalities of streamlit.
if st.session_state.has_run:
'''[Previous Blocks introduced above]'''
# Key parameters offered under the visible
kpi_cols = st.columns(3)
kpi_cols[0].metric("Stockout days", f"{stockouts}")
kpi_cols[1].metric("Min IOH (items)", f"{min_ioh:,.0f}")
kpi_cols[2].metric("Avg IOH (items)", f"{avg_ioh:,.0f}")
# Message of data
st.success("Simulation accomplished.")
Along with the columns that we already outlined within the earlier part, now we have:
metric()that generates a clear and built-in Streamlit card
In contrast to my customized card, you don’t want CSS right here.st.success()to show a inexperienced success banner to inform the consumer that the outcomes have been up to date.

That is the cherry on the cake that we wanted to conclude this app.
You now have an entire app that mechanically generates visuals and simply assessments eventualities, working in your machine.
What about our Logistics Director? How he can use it?
Let me present you easy methods to deploy it totally free on Streamlit Neighborhood Cloud simply.
Deploy your App on Streamlit Neighborhood
You first must push your code to your GitHub, as I did right here: GitHub Repository.
Then you definately go to the highest proper of your app, and also you click on on Deploy.

Then click on Deploy now, and observe the steps to offer entry to your GitHub account (Streamlit will mechanically detect that you’ve got pushed your code to GitHub).

You’ll be able to create a customized URL: mine is supplyscience.
After clicking on Deploy, Streamlit will redirect you to your deployed app!
Congratulations, you could have deployed your first Provide Chain Analytics Streamlit App!
Any query? Be at liberty to check the complete tutorial.
Be at liberty to make use of the remark to ask your questions or share what you deployed on Streamlit.
Conclusion
I designed this tutorial for the model of myself from 2018.
Again then, I knew sufficient Python and analytics to construct optimisation and simulation instruments for my colleagues, however I didn’t but know easy methods to flip them into actual merchandise.
This tutorial is step one in your journey towards industrialising analytics options.
What you constructed right here might be not production-ready, however it’s a purposeful app you could share with our Logistics Director.
Do you want inspiration for different purposes?
How you can Full this App?
Now that you’ve got the playbook for deploying Provide Chain Analytics apps, you in all probability need to enhance the app by including extra fashions.
I’ve a suggestion for you.
You’ll be able to observe this step-by-step tutorial to implement Product Segmentation with Pareto Analysis and ABC Chart.
You’ll discover ways to deploy strategic visuals just like the ABC XYZ that assist retail corporations handle their stock.

This may be simply applied on the second web page of the app that you just simply deployed.
If wanted, I can work on one other article specializing in this resolution!
Uninterested in stock administration?
Yow will discover 80+ case research of AI & analytics merchandise to help Provide Chain Optimisation, Enterprise Profitability and Course of Automation in this cheat sheet.

For many of the case research, revealed in In the direction of Information Science, you could find the supply code that may be applied in a Streamlit app.
About Me
Let’s join on Linkedin and Twitter. I’m a Provide Chain Engineer who makes use of knowledge analytics to enhance logistics operations and cut back prices.
For consulting or recommendation on analytics and sustainable provide chain transformation, be happy to contact me through Logigreen Consulting.
If you’re desirous about Information Analytics and Provide Chain, take a look at my web site.

