Lilli98 commited on
Commit
7cd2ba9
·
verified ·
1 Parent(s): d429bec

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +9 -9
app.py CHANGED
@@ -1,5 +1,5 @@
1
  # app.py
2
- # @title Beer Game Final Version (v4.14 - Fixed NameError)
3
 
4
  # -----------------------------------------------------------------------------
5
  # 1. Import Libraries
@@ -368,6 +368,7 @@ def plot_results(df: pd.DataFrame, title: str, human_role: str):
368
  plot_data = []
369
  for _, row in df.iterrows():
370
  for e in echelons:
 
371
  plot_data.append({'week': row.get('week', 0), 'echelon': e,
372
  'inventory': row.get(f'{e}.inventory', 0), # Use end-of-week inventory for plots
373
  'order_placed': row.get(f'{e}.order_placed', 0),
@@ -388,12 +389,14 @@ def plot_results(df: pd.DataFrame, title: str, human_role: str):
388
  axes[1].legend()
389
  axes[1].set_ylabel('Ordered/Produced (Units)')
390
 
391
- total_costs = plot_df.loc[plot_df.groupby('echelon')['week'].idxmax()]
 
392
  total_costs = total_costs.set_index('echelon')['total_cost'].reindex(echelons, fill_value=0)
393
  total_costs.plot(kind='bar', ax=axes[2], rot=0)
394
  axes[2].set_title('Total Cumulative Cost')
395
  axes[2].set_ylabel('Cost ($)')
396
 
 
397
  human_cols = [f'{human_role}.initial_order', f'{human_role}.ai_suggestion', f'{human_role}.order_placed']
398
  human_df_cols = ['week'] + [col for col in human_cols if col in df.columns]
399
  human_df = df[human_df_cols].copy()
@@ -403,7 +406,7 @@ def plot_results(df: pd.DataFrame, title: str, human_role: str):
403
  f'{human_role}.order_placed': 'Your Final Order'
404
  }, inplace=True)
405
 
406
- if len(human_df.columns) > 1:
407
  human_df.plot(x='week', ax=axes[3], marker='o', linestyle='-')
408
  axes[3].set_title(f'Analysis of Your ({human_role}) Decisions')
409
  axes[3].set_ylabel('Order Quantity')
@@ -502,7 +505,6 @@ else:
502
  **Conclusion:** Think 3 weeks ahead! Your order in Week 10 arrives at the start of Week 13.
503
  """)
504
 
505
- # =============== NEW: Understanding Inventory & Backlog ===============
506
  st.subheader("4. Understanding Inventory & Backlog")
507
  st.markdown("""
508
  Managing your inventory and backlog is key to minimizing costs. Here's how they work:
@@ -510,20 +512,18 @@ else:
510
  * **If you DON'T have enough inventory:**
511
  * You ship **all** the inventory you have.
512
  * The remaining unfilled "Orders to Fill" becomes your **new Backlog** for next week.
513
- * **Backlog is cumulative!** If you have a backlog of 5 and get a new order for 8 but can only ship 10, your new backlog is `(5 + 8) - 10 = 3`.
514
  * **If you DO have enough inventory:**
515
  * You ship all the "Orders to Fill".
516
  * Your Backlog becomes 0.
517
  * The remaining inventory is carried over to next week (and incurs holding costs).
518
  """)
519
- # ====================================================================
520
 
521
  st.subheader("5. The Bullwhip Effect (What to Avoid)")
522
  st.markdown("""
523
  The "Bullwhip Effect" happens when small changes in customer demand cause **amplified**, chaotic swings in orders further up the supply chain (like you and the Factory). This often leads to cycles of **panic ordering** (ordering too much when out of stock) followed by **massive inventory pile-ups** (when late orders arrive). This cycle is very expensive. Try to order smoothly.
524
  """)
525
 
526
- # =============== UPDATED: How Each Week Works & Dashboard Explanation ===============
527
  st.subheader("6. How Each Week Works & Understanding Your Dashboard")
528
  st.markdown(f"""
529
  Your main job is simple: place one order each week based on the dashboard presented to you.
@@ -549,7 +549,7 @@ else:
549
 
550
  Submitting your final order ends the week. The system then calculates your `Weekly Cost` based on your inventory/backlog *after* Step 3 shipping, logs everything, and advances to the next week.
551
  """)
552
- # ==============================================================================
553
 
554
  st.markdown("---")
555
  st.header("⚙️ Game Configuration")
@@ -566,7 +566,7 @@ else:
566
  # --- Main Game Interface ---
567
  elif 'game_state' in st.session_state and st.session_state.game_state.get('game_running'):
568
  state = st.session_state.game_state
569
- week, human_role, echelons, info_sharing = state['week'], state['echelons'], state['info_sharing']
570
  # Define echelon order for display in the UI
571
  echelon_order = ["Retailer", "Wholesaler", "Distributor", "Factory"]
572
 
 
1
  # app.py
2
+ # @title Beer Game Final Version (v4.15 - Fixed Unpacking Error)
3
 
4
  # -----------------------------------------------------------------------------
5
  # 1. Import Libraries
 
368
  plot_data = []
369
  for _, row in df.iterrows():
370
  for e in echelons:
371
+ # Safely access keys, provide default if missing (e.g., first few weeks)
372
  plot_data.append({'week': row.get('week', 0), 'echelon': e,
373
  'inventory': row.get(f'{e}.inventory', 0), # Use end-of-week inventory for plots
374
  'order_placed': row.get(f'{e}.order_placed', 0),
 
389
  axes[1].legend()
390
  axes[1].set_ylabel('Ordered/Produced (Units)')
391
 
392
+ # Ensure total_cost calculation handles potential missing data gracefully
393
+ total_costs = plot_df.loc[plot_df.groupby('echelon')['week'].idxmax()] # Get row with max week for each echelon
394
  total_costs = total_costs.set_index('echelon')['total_cost'].reindex(echelons, fill_value=0)
395
  total_costs.plot(kind='bar', ax=axes[2], rot=0)
396
  axes[2].set_title('Total Cumulative Cost')
397
  axes[2].set_ylabel('Cost ($)')
398
 
399
+ # Safely access human decision columns
400
  human_cols = [f'{human_role}.initial_order', f'{human_role}.ai_suggestion', f'{human_role}.order_placed']
401
  human_df_cols = ['week'] + [col for col in human_cols if col in df.columns]
402
  human_df = df[human_df_cols].copy()
 
406
  f'{human_role}.order_placed': 'Your Final Order'
407
  }, inplace=True)
408
 
409
+ if len(human_df.columns) > 1: # Check if there's data to plot
410
  human_df.plot(x='week', ax=axes[3], marker='o', linestyle='-')
411
  axes[3].set_title(f'Analysis of Your ({human_role}) Decisions')
412
  axes[3].set_ylabel('Order Quantity')
 
505
  **Conclusion:** Think 3 weeks ahead! Your order in Week 10 arrives at the start of Week 13.
506
  """)
507
 
 
508
  st.subheader("4. Understanding Inventory & Backlog")
509
  st.markdown("""
510
  Managing your inventory and backlog is key to minimizing costs. Here's how they work:
 
512
  * **If you DON'T have enough inventory:**
513
  * You ship **all** the inventory you have.
514
  * The remaining unfilled "Orders to Fill" becomes your **new Backlog** for next week.
515
+ * **Backlog is cumulative!** If you start Week 10 with a backlog of 5, get an order for 8 (total needed = 13), receive 10 units, and ship those 10 units, your new backlog for Week 11 is `13 - 10 = 3`.
516
  * **If you DO have enough inventory:**
517
  * You ship all the "Orders to Fill".
518
  * Your Backlog becomes 0.
519
  * The remaining inventory is carried over to next week (and incurs holding costs).
520
  """)
 
521
 
522
  st.subheader("5. The Bullwhip Effect (What to Avoid)")
523
  st.markdown("""
524
  The "Bullwhip Effect" happens when small changes in customer demand cause **amplified**, chaotic swings in orders further up the supply chain (like you and the Factory). This often leads to cycles of **panic ordering** (ordering too much when out of stock) followed by **massive inventory pile-ups** (when late orders arrive). This cycle is very expensive. Try to order smoothly.
525
  """)
526
 
 
527
  st.subheader("6. How Each Week Works & Understanding Your Dashboard")
528
  st.markdown(f"""
529
  Your main job is simple: place one order each week based on the dashboard presented to you.
 
549
 
550
  Submitting your final order ends the week. The system then calculates your `Weekly Cost` based on your inventory/backlog *after* Step 3 shipping, logs everything, and advances to the next week.
551
  """)
552
+
553
 
554
  st.markdown("---")
555
  st.header("⚙️ Game Configuration")
 
566
  # --- Main Game Interface ---
567
  elif 'game_state' in st.session_state and st.session_state.game_state.get('game_running'):
568
  state = st.session_state.game_state
569
+ week, human_role, echelons, info_sharing = state['week'], state['human_role'], state['echelons'], state['info_sharing']
570
  # Define echelon order for display in the UI
571
  echelon_order = ["Retailer", "Wholesaler", "Distributor", "Factory"]
572