Lilli98 commited on
Commit
799dff1
·
verified ·
1 Parent(s): ff7a527

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -36
app.py CHANGED
@@ -1,5 +1,5 @@
1
  # app.py
2
- # @title Beer Game Final Version (v4.19 - Fixed TypeError, Removed Costs, Highlighted Player)
3
 
4
  # -----------------------------------------------------------------------------
5
  # 1. Import Libraries
@@ -57,7 +57,7 @@ else:
57
 
58
 
59
  # -----------------------------------------------------------------------------
60
- # 3. Core Game Logic Functions (Using stable v4.17 logic)
61
  # -----------------------------------------------------------------------------
62
 
63
  def get_customer_demand(week: int) -> int:
@@ -87,8 +87,7 @@ def init_game_state(llm_personality: str, info_sharing: str):
87
  else: shipping_weeks = SHIPPING_DELAY
88
 
89
  st.session_state.game_state['echelons'][name] = {
90
- 'name': name,
91
- 'inventory': INITIAL_INVENTORY, 'backlog': INITIAL_BACKLOG,
92
  'incoming_shipments': deque([0] * shipping_weeks, maxlen=shipping_weeks),
93
  'incoming_order': 0, 'order_placed': 0, 'shipment_sent': 0,
94
  'weekly_cost': 0, 'total_cost': 0, 'upstream_name': upstream, 'downstream_name': downstream,
@@ -302,7 +301,7 @@ def save_logs_and_upload(state: dict):
302
  except Exception as e_save: st.error(f"Error processing or saving log data: {e_save}")
303
 
304
  # -----------------------------------------------------------------------------
305
- # 4. Streamlit UI (Removed Costs, Highlighted Player)
306
  # -----------------------------------------------------------------------------
307
  st.title("🍺 The Beer Game: A Human-AI Collaboration Challenge")
308
 
@@ -332,12 +331,37 @@ else:
332
  st.markdown(f"* **Week 10 (You):** You place an order for **50**.\n* **Week 11 (System):** Your order arrives at the Factory (**{ORDER_PASSING_DELAY}w Order Delay**). Factory AI decides to produce 50.\n* **Week 12 (System):** Factory finishes producing 50 (**{FACTORY_LEAD_TIME}w Production Delay**) & ships it.\n* **Week 13 (System):** The 50 units arrive at your warehouse (**{FACTORY_SHIPPING_DELAY}w Shipping Delay**).\n**Conclusion:** Think 3 weeks ahead! Your order in Week 10 arrives at the start of Week 13.")
333
  st.subheader("4. Understanding Inventory & Backlog")
334
  st.markdown("Managing your inventory and backlog is key to minimizing costs. Here's how they work:\n* **Effective \"Orders to Fill\":** Each week, the total demand you need to satisfy is your `Incoming Order` for the week PLUS any `Backlog` carried over from the previous week.\n* **If you DON'T have enough inventory:**\n * You ship **all** the inventory you have (after receiving any arrivals for the week).\n * The remaining unfilled \"Orders to Fill\" becomes your **new Backlog** for next week.\n * **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`.\n* **If you DO have enough inventory:**\n * You ship all the \"Orders to Fill\".\n * Your Backlog becomes 0.\n * The remaining inventory is carried over to next week (and incurs holding costs).")
335
- st.subheader("5. The Bullwhip Effect (What to Avoid)")
336
  st.markdown("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.")
 
 
337
  st.subheader("6. How Each Week Works & Understanding Your Dashboard")
338
- st.markdown(f"Your main job is simple: place one order each week based on the dashboard presented to you.\n\n**A) At the start of every week, BEFORE your turn:**\n* **(Step 1) Shipments Arrive:** Beer you ordered {ORDER_PASSING_DELAY + FACTORY_LEAD_TIME + FACTORY_SHIPPING_DELAY} weeks ago arrives.\n* **(Step 2) New Orders Arrive:** You receive a new order from the Wholesaler (their order from *last* week).\n* **(Step 3) You Ship Beer (Automatically):** The system ships beer *immediately* based on your inventory *after* Step 1 and the total demand *after* Step 2.\n\n**B) Your Dashboard (What You See for Your Turn):**\nThe dashboard shows your status **at the start of the week, BEFORE Steps 1, 2, and 3 happen**:\n* `Inventory (Opening)`: Your stock **at the beginning of the week**.\n* `Backlog (Opening)`: Unfilled orders **carried over from the end of last week**.\n* `Incoming Order (This Week)`: The specific order quantity that **will arrive** from the Wholesaler *during* this week (Step 2). Use this for your planning.\n* `Arriving Next Week`: The quantity scheduled to arrive at the start of the **next week**. Use this for your planning.\n\n**C) Your Decision (Step 4 - Two Parts):**\nNow, looking at the dashboard (showing the start-of-week state) and considering the incoming order and future arrivals, you decide how much to order:\n* **(Step 4a - Initial Order):** Submit your first estimate.\n* **(Step 4b - Final Order):** See the AI's suggestion, then submit your final decision. This order will arrive in 3 weeks.\n\nSubmitting 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.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
 
340
- # --- Game Configuration ---
341
  st.markdown("---")
342
  st.header("⚙️ Game Configuration")
343
  c1, c2 = st.columns(2)
@@ -372,7 +396,7 @@ else:
372
  # =============== UI CHANGE: Highlight Player ===============
373
  if name == human_role:
374
  # Use markdown with HTML/CSS for highlighting
375
- st.markdown(f"##### **<span style='color:#FF4B4B; border: 1px solid #FF4B4B; padding: 2px 5px; border-radius: 3px;'>{icon} {name} (You)</span>**", unsafe_allow_html=True)
376
  else:
377
  st.markdown(f"##### {icon} {name}")
378
  # ========================================================
@@ -382,41 +406,48 @@ else:
382
  st.metric("Backlog (Opening)", e['backlog'])
383
 
384
  # =============== UI CHANGE: Removed Costs ===============
385
- # if name == human_role:
386
- # st.metric("Total Cost (Cumulative)", f"${e['total_cost']:,.2f}")
387
- # last_week_cost = state['logs'][-1][f"{human_role}.weekly_cost"] if week > 1 and state['logs'] else 0
388
- # st.metric("Cost Last Week", f"${last_week_cost:,.2f}")
389
  # =======================================================
390
 
391
  # Display info about THIS week's events / NEXT week's arrivals
392
- st.write(f"Incoming Order (This Week): **{e['incoming_order']}**") # Order arriving in Step 2
 
 
 
 
 
 
 
 
 
 
393
  if name == "Factory":
394
- # Production completing NEXT week
395
  prod_completing_next = list(state['factory_production_pipeline'])[0] if state['factory_production_pipeline'] else 0
396
  st.write(f"Completing Next Week: **{prod_completing_next}**")
397
  else:
398
- # Shipment arriving NEXT week
399
  arriving_next = list(e['incoming_shipments'])[0] if e['incoming_shipments'] else 0
400
  st.write(f"Arriving Next Week: **{arriving_next}**")
401
  else: # Local Info Mode
402
  st.info("In Local Information mode, you can only see your own status dashboard.")
403
  e = echelons[human_role]
404
- # =============== UI CHANGE: Highlight Player ===============
405
  st.markdown(f"### 👤 **<span style='color:#FF4B4B;'>{human_role} (Your Dashboard - Start of Week State)</span>**", unsafe_allow_html=True) # Highlight self
406
- # ========================================================
407
 
408
  col1, col2, col3, col4 = st.columns(4)
409
  # Display OPENING state
410
  col1.metric("Inventory (Opening)", e['inventory'])
411
  col2.metric("Backlog (Opening)", e['backlog'])
 
412
  # Display info about THIS week's events / NEXT week's arrivals
413
- col3.write(f"**Incoming Order (This Week):**\n# {e['incoming_order']}")
 
 
 
 
 
414
  col4.write(f"**Shipment Arriving (Next Week):**\n# {list(e['incoming_shipments'])[0] if e['incoming_shipments'] else 0}")
415
 
416
  # =============== UI CHANGE: Removed Costs ===============
417
- # st.metric("Your Total Cumulative Cost", f"${e['total_cost']:,.2f}")
418
- # last_week_cost = state['logs'][-1][f"{human_role}.weekly_cost"] if week > 1 and state['logs'] else 0
419
- # st.metric("Cost Last Week", f"${last_week_cost:,.2f}")
420
  # =======================================================
421
 
422
 
@@ -436,13 +467,18 @@ else:
436
 
437
  # Calculate the state AFTER arrivals and incoming orders for the prompt
438
  inv_after_arrival = e_curr['inventory'] + arrived
439
- backlog_after_new_order = e_curr['backlog'] + e_curr['incoming_order']
 
 
 
 
 
 
 
440
 
441
  all_decision_point_states[name] = {
442
- 'name': name,
443
- 'inventory': inv_after_arrival, # State for decision making
444
- 'backlog': backlog_after_new_order, # State for decision making
445
- 'incoming_order': e_curr['incoming_order'], # Info for decision making
446
  'incoming_shipments': e_curr['incoming_shipments'].copy() if name != "Factory" else deque()
447
  }
448
  human_echelon_state_for_prompt = all_decision_point_states[human_role]
@@ -451,11 +487,12 @@ else:
451
  if state['decision_step'] == 'initial_order':
452
  with st.form(key="initial_order_form"):
453
  st.markdown("#### **Step 4a:** Based on the dashboard, submit your **initial** order to the Factory.")
454
- # Default initial order based on incoming order, minimum 4
455
- default_initial = max(4, echelons[human_role]['incoming_order'])
456
- initial_order = st.number_input("Your Initial Order Quantity:", min_value=0, step=1, value=default_initial)
457
  if st.form_submit_button("Submit Initial Order & See AI Suggestion", type="primary"):
458
- state['human_initial_order'] = int(initial_order)
 
459
  state['decision_step'] = 'final_order'
460
  st.rerun()
461
 
@@ -465,16 +502,23 @@ else:
465
  prompt_sugg = get_llm_prompt(human_echelon_state_for_prompt, week, state['llm_personality'], state['info_sharing'], all_decision_point_states)
466
  ai_suggestion, _ = get_llm_order_decision(prompt_sugg, f"{human_role} (Suggestion)")
467
 
468
- if 'final_order_input' not in st.session_state:
469
- st.session_state.final_order_input = ai_suggestion
 
470
 
471
  with st.form(key="final_order_form"):
472
  st.markdown(f"#### **Step 4b:** The AI suggests ordering **{ai_suggestion}** units.")
473
  st.markdown("Considering the AI's advice, submit your **final** order to end the week. (This order will arrive in 3 weeks).")
474
- st.number_input("Your Final Order Quantity:", min_value=0, step=1, key='final_order_input')
 
 
475
  if st.form_submit_button("Submit Final Order & Advance to Next Week"):
476
- final_order_value = st.session_state.final_order_input
 
 
 
477
  step_game(final_order_value, state['human_initial_order'], ai_suggestion)
 
478
  if 'final_order_input' in st.session_state: del st.session_state.final_order_input
479
  st.rerun()
480
 
@@ -505,7 +549,6 @@ else:
505
  else:
506
  display_df = history_df[final_cols_to_display].rename(columns=human_cols)
507
  if 'Weekly Cost' in display_df.columns:
508
- # Safely apply formatting, handling potential non-numeric data
509
  display_df['Weekly Cost'] = display_df['Weekly Cost'].apply(lambda x: f"${x:,.2f}" if isinstance(x, (int, float)) else "")
510
  st.dataframe(display_df.sort_values(by="Week", ascending=False), hide_index=True, use_container_width=True)
511
  except Exception as e:
 
1
  # app.py
2
+ # @title Beer Game Final Version (v4.20 - Fixed UI Incoming Order Timing & Input Defaults)
3
 
4
  # -----------------------------------------------------------------------------
5
  # 1. Import Libraries
 
57
 
58
 
59
  # -----------------------------------------------------------------------------
60
+ # 3. Core Game Logic Functions
61
  # -----------------------------------------------------------------------------
62
 
63
  def get_customer_demand(week: int) -> int:
 
87
  else: shipping_weeks = SHIPPING_DELAY
88
 
89
  st.session_state.game_state['echelons'][name] = {
90
+ 'name': name, 'inventory': INITIAL_INVENTORY, 'backlog': INITIAL_BACKLOG,
 
91
  'incoming_shipments': deque([0] * shipping_weeks, maxlen=shipping_weeks),
92
  'incoming_order': 0, 'order_placed': 0, 'shipment_sent': 0,
93
  'weekly_cost': 0, 'total_cost': 0, 'upstream_name': upstream, 'downstream_name': downstream,
 
301
  except Exception as e_save: st.error(f"Error processing or saving log data: {e_save}")
302
 
303
  # -----------------------------------------------------------------------------
304
+ # 4. Streamlit UI (Adjusted Dashboard Labels & Logic)
305
  # -----------------------------------------------------------------------------
306
  st.title("🍺 The Beer Game: A Human-AI Collaboration Challenge")
307
 
 
331
  st.markdown(f"* **Week 10 (You):** You place an order for **50**.\n* **Week 11 (System):** Your order arrives at the Factory (**{ORDER_PASSING_DELAY}w Order Delay**). Factory AI decides to produce 50.\n* **Week 12 (System):** Factory finishes producing 50 (**{FACTORY_LEAD_TIME}w Production Delay**) & ships it.\n* **Week 13 (System):** The 50 units arrive at your warehouse (**{FACTORY_SHIPPING_DELAY}w Shipping Delay**).\n**Conclusion:** Think 3 weeks ahead! Your order in Week 10 arrives at the start of Week 13.")
332
  st.subheader("4. Understanding Inventory & Backlog")
333
  st.markdown("Managing your inventory and backlog is key to minimizing costs. Here's how they work:\n* **Effective \"Orders to Fill\":** Each week, the total demand you need to satisfy is your `Incoming Order` for the week PLUS any `Backlog` carried over from the previous week.\n* **If you DON'T have enough inventory:**\n * You ship **all** the inventory you have (after receiving any arrivals for the week).\n * The remaining unfilled \"Orders to Fill\" becomes your **new Backlog** for next week.\n * **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`.\n* **If you DO have enough inventory:**\n * You ship all the \"Orders to Fill\".\n * Your Backlog becomes 0.\n * The remaining inventory is carried over to next week (and incurs holding costs).")
334
+ st.subheader("5. The Bullwhisp Effect (What to Avoid)")
335
  st.markdown("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.")
336
+
337
+ # =============== UPDATED: How Each Week Works & Dashboard Explanation ===============
338
  st.subheader("6. How Each Week Works & Understanding Your Dashboard")
339
+ st.markdown(f"""
340
+ Your main job is simple: place one order each week based on the dashboard presented to you.
341
+
342
+ **A) At the start of every week, BEFORE your turn:**
343
+ * **(Step 1) Shipments Arrive:** Beer you ordered {ORDER_PASSING_DELAY + FACTORY_LEAD_TIME + FACTORY_SHIPPING_DELAY} weeks ago arrives.
344
+ * **(Step 2) New Orders Arrive:** You receive a new order from the Wholesaler (this is their order placed *last* week, due to the {ORDER_PASSING_DELAY} week delay).
345
+ * **(Step 3) You Ship Beer (Automatically):** The system ships beer *immediately* based on your inventory *after* Step 1 and the total demand *after* Step 2.
346
+
347
+ **B) Your Dashboard (What You See for Your Turn):**
348
+ The dashboard shows your status **at the start of the week, BEFORE Steps 1, 2, and 3 happen**:
349
+ * `Inventory (Opening)`: Your stock **at the beginning of the week**.
350
+ * `Backlog (Opening)`: Unfilled orders **carried over from the end of last week**.
351
+ * `Incoming Order (This Week)`: The specific order quantity arriving from the Wholesaler *during* this week (Step 2). **This is the primary demand signal you need to react to.**
352
+ * `Arriving Next Week`: The quantity scheduled to arrive from the Factory at the start of the **next week**.
353
+ * `Your Total Cumulative Cost`: Sum of all weekly costs up to the **end of last week** (Removed from dashboard).
354
+ * `Cost Last Week`: The specific cost incurred just **last week** (Removed from dashboard).
355
+
356
+ **C) Your Decision (Step 4 - Two Parts):**
357
+ Now, looking at the dashboard (showing the start-of-week state) and considering the incoming order and future arrivals, you decide how much to order:
358
+ * **(Step 4a - Initial Order):** Submit your first estimate. Input box starts blank.
359
+ * **(Step 4b - Final Order):** See the AI's suggestion, then submit your final decision. Input box starts blank (or with AI suggestion if preferred - currently blank). This order will arrive in 3 weeks.
360
+
361
+ 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.
362
+ """)
363
+ # ==============================================================================
364
 
 
365
  st.markdown("---")
366
  st.header("⚙️ Game Configuration")
367
  c1, c2 = st.columns(2)
 
396
  # =============== UI CHANGE: Highlight Player ===============
397
  if name == human_role:
398
  # Use markdown with HTML/CSS for highlighting
399
+ st.markdown(f"##### **<span style='border: 1px solid #FF4B4B; padding: 2px 5px; border-radius: 3px;'>{icon} {name} (You)</span>**", unsafe_allow_html=True)
400
  else:
401
  st.markdown(f"##### {icon} {name}")
402
  # ========================================================
 
406
  st.metric("Backlog (Opening)", e['backlog'])
407
 
408
  # =============== UI CHANGE: Removed Costs ===============
409
+ # Costs are no longer displayed on the main dashboard
 
 
 
410
  # =======================================================
411
 
412
  # Display info about THIS week's events / NEXT week's arrivals
413
+ # Calculate the INCOMING order for THIS week
414
+ current_incoming_order = 0
415
+ if name == "Retailer":
416
+ current_incoming_order = get_customer_demand(week)
417
+ else:
418
+ downstream_name = e['downstream_name']
419
+ if downstream_name:
420
+ current_incoming_order = state['last_week_orders'].get(downstream_name, 0)
421
+ st.write(f"Incoming Order (This Week): **{current_incoming_order}**") # Display calculated order
422
+
423
+ # Display prediction for NEXT week's arrivals
424
  if name == "Factory":
 
425
  prod_completing_next = list(state['factory_production_pipeline'])[0] if state['factory_production_pipeline'] else 0
426
  st.write(f"Completing Next Week: **{prod_completing_next}**")
427
  else:
 
428
  arriving_next = list(e['incoming_shipments'])[0] if e['incoming_shipments'] else 0
429
  st.write(f"Arriving Next Week: **{arriving_next}**")
430
  else: # Local Info Mode
431
  st.info("In Local Information mode, you can only see your own status dashboard.")
432
  e = echelons[human_role]
 
433
  st.markdown(f"### 👤 **<span style='color:#FF4B4B;'>{human_role} (Your Dashboard - Start of Week State)</span>**", unsafe_allow_html=True) # Highlight self
 
434
 
435
  col1, col2, col3, col4 = st.columns(4)
436
  # Display OPENING state
437
  col1.metric("Inventory (Opening)", e['inventory'])
438
  col2.metric("Backlog (Opening)", e['backlog'])
439
+
440
  # Display info about THIS week's events / NEXT week's arrivals
441
+ # Calculate the INCOMING order for THIS week
442
+ current_incoming_order = 0
443
+ downstream_name = e['downstream_name'] # Wholesaler
444
+ if downstream_name:
445
+ current_incoming_order = state['last_week_orders'].get(downstream_name, 0)
446
+ col3.write(f"**Incoming Order (This Week):**\n# {current_incoming_order}") # Display calculated order
447
  col4.write(f"**Shipment Arriving (Next Week):**\n# {list(e['incoming_shipments'])[0] if e['incoming_shipments'] else 0}")
448
 
449
  # =============== UI CHANGE: Removed Costs ===============
450
+ # Costs are no longer displayed on the main dashboard
 
 
451
  # =======================================================
452
 
453
 
 
467
 
468
  # Calculate the state AFTER arrivals and incoming orders for the prompt
469
  inv_after_arrival = e_curr['inventory'] + arrived
470
+ # Determine incoming order for *this* week again for prompt state
471
+ inc_order_this_week = 0
472
+ if name == "Retailer": inc_order_this_week = get_customer_demand(week)
473
+ else:
474
+ ds_name = e_curr['downstream_name']
475
+ if ds_name: inc_order_this_week = state['last_week_orders'].get(ds_name, 0)
476
+
477
+ backlog_after_new_order = e_curr['backlog'] + inc_order_this_week
478
 
479
  all_decision_point_states[name] = {
480
+ 'name': name, 'inventory': inv_after_arrival, 'backlog': backlog_after_new_order,
481
+ 'incoming_order': inc_order_this_week, # Use the correctly calculated incoming order
 
 
482
  'incoming_shipments': e_curr['incoming_shipments'].copy() if name != "Factory" else deque()
483
  }
484
  human_echelon_state_for_prompt = all_decision_point_states[human_role]
 
487
  if state['decision_step'] == 'initial_order':
488
  with st.form(key="initial_order_form"):
489
  st.markdown("#### **Step 4a:** Based on the dashboard, submit your **initial** order to the Factory.")
490
+ # =============== UI CHANGE: Removed Default Value ===============
491
+ initial_order = st.number_input("Your Initial Order Quantity:", min_value=0, step=1) # No 'value' argument
492
+ # ===============================================================
493
  if st.form_submit_button("Submit Initial Order & See AI Suggestion", type="primary"):
494
+ # Handle case where user leaves it blank (input returns None)
495
+ state['human_initial_order'] = int(initial_order) if initial_order is not None else 0
496
  state['decision_step'] = 'final_order'
497
  st.rerun()
498
 
 
502
  prompt_sugg = get_llm_prompt(human_echelon_state_for_prompt, week, state['llm_personality'], state['info_sharing'], all_decision_point_states)
503
  ai_suggestion, _ = get_llm_order_decision(prompt_sugg, f"{human_role} (Suggestion)")
504
 
505
+ # We don't pre-fill the final_order_input anymore
506
+ # if 'final_order_input' not in st.session_state:
507
+ # st.session_state.final_order_input = ai_suggestion
508
 
509
  with st.form(key="final_order_form"):
510
  st.markdown(f"#### **Step 4b:** The AI suggests ordering **{ai_suggestion}** units.")
511
  st.markdown("Considering the AI's advice, submit your **final** order to end the week. (This order will arrive in 3 weeks).")
512
+ # =============== UI CHANGE: Removed Default Value ===============
513
+ st.number_input("Your Final Order Quantity:", min_value=0, step=1, key='final_order_input') # No 'value' argument
514
+ # ===============================================================
515
  if st.form_submit_button("Submit Final Order & Advance to Next Week"):
516
+ # Handle case where user leaves it blank
517
+ final_order_value = st.session_state.get('final_order_input', 0) # Use .get with default
518
+ final_order_value = int(final_order_value) if final_order_value is not None else 0
519
+
520
  step_game(final_order_value, state['human_initial_order'], ai_suggestion)
521
+ # Clean up session state for the input key
522
  if 'final_order_input' in st.session_state: del st.session_state.final_order_input
523
  st.rerun()
524
 
 
549
  else:
550
  display_df = history_df[final_cols_to_display].rename(columns=human_cols)
551
  if 'Weekly Cost' in display_df.columns:
 
552
  display_df['Weekly Cost'] = display_df['Weekly Cost'].apply(lambda x: f"${x:,.2f}" if isinstance(x, (int, float)) else "")
553
  st.dataframe(display_df.sort_values(by="Week", ascending=False), hide_index=True, use_container_width=True)
554
  except Exception as e: