- numpy - matplotlib

Global Operation Management - Inventory Management

Introduction Image
Pull inventory control - single (Economic order quantity EOQ) Watch Tutorial
def on_eoq(event): D = float(Element("D").element.value) S = float(Element("S").element.value) C = float(Element("C").element.value) I = float(Element("I").element.value) result = eoq(D,S,C,I) Element("out_eoq").element.innerHTML = result Element("button_EOQ").element.onclick = on_eoq
OUTPUT
Optimal Reorder Point - Instantaneous Resupply Watch Tutorial
def get_plot_string(Q_star, R_star, D, LT): plt = plot_inventory_wave(Q_star, R_star, D, LT) buf = io.BytesIO() plt.savefig(buf, format='png') plt.close() buf.seek(0) string = base64.b64encode(buf.read()).decode('utf-8') # output pic return "data:image/png;base64,"+ string def on_instant(event): try: D = float(Element("D1").element.value) S = float(Element("S1").element.value) C = float(Element("C1").element.value) I = float(Element("I1").element.value) / 100 LT = float(Element("LT1").element.value) Q_star, R_star = instant_order(D, S, C, I, LT) if Q_star is not None and R_star is not None: Element("instant_result").element.innerHTML = order(D, S, C, I, LT) img_data = get_plot_string(Q_star, R_star, D, LT) Element("out_instant").element.innerHTML = "Plot generated!" Element("plot_image").element.src = img_data Element("plot_image").element.style.display = "block" except ValueError: Element("out_instant").element.innerHTML = "Invalid input. Please enter numeric values." Element("button_instant").element.onclick = on_instant
OUTPUT
Inventory Plot
Optimal Reorder Point - NON - Instantaneous Resupply Watch Tutorial
import math import numpy as np import matplotlib.pyplot as plt def noninstant1(D, S, C, I, LT, P): try: numerator = 2 * D * S denominator = I * C Q_squared = numerator / denominator Q = math.sqrt(Q_squared) Q_up = math.ceil(Q) R_square = (D / 52) * LT R_up = math.ceil(R_square) Q_square = Q_up * math.sqrt(P / (P - D / 52)) round_Q = math.ceil(Q_square) max_inventory = (round_Q / P) * (P - D / 52) print(f"When the inventory level drops to {R_up} units, place a replenishment order for {round_Q}.") return round_Q, max_inventory, R_up except ValueError: Element("out_noninstant").element.innerHTML = "Invalid input. Please enter positive values." return None, None, None def plot_inventory_wave2(round_Q, max_inventory, R_up): # repeat 3 times repetitions = 3 time_period = 10 # Total time for one cycle t = np.linspace(0, time_period * repetitions, 1000) inventory_levels = np.zeros_like(t) # Generate the sawtooth wave for i in range(len(t)): cycle_position = t[i] % time_period # Position within the current cycle if cycle_position < time_period / 2: inventory_levels[i] = (max_inventory / (time_period / 2)) * cycle_position # Linear up else: inventory_levels[i] = max_inventory - ((max_inventory / (time_period / 2)) * (cycle_position - time_period / 2)) # Linear down # Plot plt.figure(figsize=(10, 6)) plt.plot(t, inventory_levels, label='Inventory Level', color='blue') # label line here plt.axhline(y=round_Q, color='green', linestyle='--', label=f'Q*: {round_Q}') plt.axhline(y=max_inventory, color='red', linestyle='--', label=f'Max Inventory: {max_inventory:.2f}') plt.axhline(y=R_up, color='orange', linestyle='--', label=f'Reordering Quantity: {R_up}') plt.ylim(0, max(round_Q, max_inventory) * 1.1) # Enlarged to the value of Q* plt.title('Sawtooth Wave of Inventory Levels (3 Cycles)') plt.xlabel('Time') plt.ylabel('Inventory Level') plt.xlim(0, time_period * repetitions) plt.grid() plt.legend() plt.text(0, round_Q + 0.05 * max(round_Q, max_inventory), f'Q*: {round_Q}', color='green') plt.text(0, max_inventory + 0.05 * max(round_Q, max_inventory), f'Max Inventory: {max_inventory:.2f}', color='red') plt.text(0, R_up + 0.05 * max(round_Q, max_inventory), f'Reordering Quantity: {R_up}', color='orange') return plt def get_plot_string2(round_Q, max_inventory, R_up): plt = plot_inventory_wave2(round_Q, max_inventory, R_up) buf = io.BytesIO() plt.savefig(buf, format='png') plt.close() buf.seek(0) string = base64.b64encode(buf.read()).decode('utf-8') # output pic return "data:image/png;base64,"+ string def on_noninstant(event): try: D = float(Element("D2").element.value) S = float(Element("S2").element.value) C = float(Element("C2").element.value) I = float(Element("I2").element.value) LT = float(Element("LT2").element.value) P = float(Element("P2").element.value) round_Q, max_inventory, R_up = noninstant1(D, S, C, I, LT, P) result = noninstant(D,S,C,I,LT,P) Element("non_result").element.innerHTML = result if round_Q is not None: img_data = get_plot_string2(round_Q, max_inventory, R_up) Element("out_noninstant").element.innerHTML = "Plot generated!" Element("plot_image_non").element.src = img_data Element("plot_image_non").element.style.display = "block" except ValueError: Element("out_noninstant").element.innerHTML = "Invalid input. Please enter numeric values." Element("button_noninstant").element.onclick = on_noninstant
OUTPUT
Inventory Plot