Lilli98 commited on
Commit
8f7f025
·
verified ·
1 Parent(s): 38135f4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -25
app.py CHANGED
@@ -449,7 +449,7 @@ def plot_results(df: pd.DataFrame, title: str, human_role: str):
449
  plt.tight_layout(rect=[0, 0, 1, 0.96]); return fig
450
 
451
 
452
- # =============== NEW: Leaderboard Functions ===============
453
  @st.cache_data(ttl=60)
454
  def load_leaderboard_data():
455
  if not hf_api or not HF_REPO_ID: return {}
@@ -474,38 +474,57 @@ def save_leaderboard_data(data):
474
  except Exception as e:
475
  st.sidebar.error(f"Failed to upload leaderboard: {e}")
476
 
 
477
  def display_rankings(df, top_n=10):
478
  if df.empty:
479
  st.info("No completed games for this category yet. Be the first!")
480
  return
481
- df['total_cost'] = pd.to_numeric(df['total_cost'], errors='coerce')
482
- df['order_std_dev'] = pd.to_numeric(df['order_std_dev'], errors='coerce')
483
- df = df.dropna(subset=['total_cost', 'order_std_dev'])
484
- if df.empty:
485
- st.info("No valid completed games for this category yet.")
486
- return
487
  c1, c2, c3 = st.columns(3)
 
 
488
  with c1:
489
  st.subheader("🏆 Supply Chain Champions")
490
- st.caption(f"Top {top_n} - Lowest Total Cost")
491
- champs_df = df.sort_values('total_cost', ascending=True).head(top_n).copy()
492
- champs_df['total_cost'] = champs_df['total_cost'].map('${:,.2f}'.format)
493
- champs_df.rename(columns={'id': 'Participant', 'total_cost': 'Total Cost'}, inplace=True)
494
- st.dataframe(champs_df[['Participant', 'Total Cost']], use_container_width=True, hide_index=True)
 
 
 
 
 
 
495
  with c2:
496
- st.subheader("👑 Bullwhip Kings")
497
- st.caption(f"Top {top_n} - Highest Total Cost")
498
- kings_df = df.sort_values('total_cost', ascending=False).head(top_n).copy()
499
- kings_df['total_cost'] = kings_df['total_cost'].map('${:,.2f}'.format)
500
- kings_df.rename(columns={'id': 'Participant', 'total_cost': 'Total Cost'}, inplace=True)
501
- st.dataframe(kings_df[['Participant', 'Total Cost']], use_container_width=True, hide_index=True)
 
 
 
 
 
 
502
  with c3:
503
  st.subheader("🧘 Mr. Smooth")
504
  st.caption(f"Top {top_n} - Lowest Order Variation (Std. Dev.)")
505
- smooth_df = df.sort_values('order_std_dev', ascending=True).head(top_n).copy()
506
- smooth_df['order_std_dev'] = smooth_df['order_std_dev'].map('{:,.2f}'.format)
507
- smooth_df.rename(columns={'id': 'Participant', 'order_std_dev': 'Order Std. Dev.'}, inplace=True)
508
- st.dataframe(smooth_df[['Participant', 'Order Std. Dev.']], use_container_width=True, hide_index=True)
 
 
 
 
509
 
510
  def show_leaderboard_ui():
511
  st.markdown("---")
@@ -518,9 +537,12 @@ def show_leaderboard_ui():
518
  try:
519
  df = pd.DataFrame(leaderboard_data.values())
520
  if 'id' not in df.columns and not df.empty: df['id'] = list(leaderboard_data.keys())
 
 
521
  if 'total_cost' not in df.columns or 'order_std_dev' not in df.columns or 'setting' not in df.columns:
522
  st.error("Leaderboard data is corrupted or incomplete.")
523
  return
 
524
  groups = sorted(df.setting.unique())
525
  tabs = st.tabs(["**Overall**"] + groups)
526
  with tabs[0]: display_rankings(df)
@@ -532,6 +554,7 @@ def show_leaderboard_ui():
532
  st.error(f"Error displaying leaderboard: {e}")
533
  st.dataframe(leaderboard_data)
534
 
 
535
  def save_logs_and_upload(state: dict):
536
  if not state.get('logs'):
537
  st.warning("No log data to save.")
@@ -559,17 +582,34 @@ def save_logs_and_upload(state: dict):
559
  st.subheader("Updating Leaderboard...")
560
  try:
561
  human_role = state['human_role']
562
- total_cost = logs_df[f'{human_role}.total_cost'].iloc[-1]
 
 
 
 
 
 
 
 
 
 
563
  order_std_dev = logs_df[f'{human_role}.order_placed'].std()
 
564
  setting_name = f"{state['llm_personality']} / {state['info_sharing']}"
 
 
565
  new_entry = {
566
- 'id': participant_id, 'setting': setting_name,
567
- 'total_cost': float(total_cost),
 
 
568
  'order_std_dev': float(order_std_dev) if pd.notna(order_std_dev) else 0.0
569
  }
 
570
  leaderboard_data = load_leaderboard_data()
571
  leaderboard_data[participant_id] = new_entry
572
  save_leaderboard_data(leaderboard_data)
 
573
  except Exception as e_board:
574
  st.error(f"Error calculating or saving leaderboard score: {e_board}")
575
  # ==============================================================================
 
449
  plt.tight_layout(rect=[0, 0, 1, 0.96]); return fig
450
 
451
 
452
+ # =============== NEW: Leaderboard Functions (MODIFIED) ===============
453
  @st.cache_data(ttl=60)
454
  def load_leaderboard_data():
455
  if not hf_api or not HF_REPO_ID: return {}
 
474
  except Exception as e:
475
  st.sidebar.error(f"Failed to upload leaderboard: {e}")
476
 
477
+ # ---------- MODIFIED FUNCTION (v2) ----------
478
  def display_rankings(df, top_n=10):
479
  if df.empty:
480
  st.info("No completed games for this category yet. Be the first!")
481
  return
482
+
483
+ # 为新旧数据列进行数值转换
484
+ df['distributor_cost'] = pd.to_numeric(df.get('total_cost'), errors='coerce') # 'total_cost' 是旧的 distributor_cost
485
+ df['total_chain_cost'] = pd.to_numeric(df.get('total_chain_cost'), errors='coerce')
486
+ df['order_std_dev'] = pd.to_numeric(df.get('order_std_dev'), errors='coerce')
487
+
488
  c1, c2, c3 = st.columns(3)
489
+
490
+ # 排行榜 1: 总供应链成本 (新)
491
  with c1:
492
  st.subheader("🏆 Supply Chain Champions")
493
+ st.caption(f"Top {top_n} - Lowest **Total Chain** Cost")
494
+ # .dropna() 确保只对有该数据的条目进行排序 (兼容旧数据)
495
+ champs_df = df.dropna(subset=['total_chain_cost']).sort_values('total_chain_cost', ascending=True).head(top_n).copy()
496
+ if champs_df.empty:
497
+ st.info("No data for this category yet.")
498
+ else:
499
+ champs_df['total_chain_cost'] = champs_df['total_chain_cost'].map('${:,.2f}'.format)
500
+ champs_df.rename(columns={'id': 'Participant', 'total_chain_cost': 'Total Chain Cost'}, inplace=True)
501
+ st.dataframe(champs_df[['Participant', 'Total Chain Cost']], use_container_width=True, hide_index=True)
502
+
503
+ # 排行榜 2: 你的 (Distributor) 成本 (修改)
504
  with c2:
505
+ st.subheader("👤 Distributor Champions")
506
+ st.caption(f"Top {top_n} - Lowest **Your** (Distributor) Cost")
507
+ dist_df = df.dropna(subset=['distributor_cost']).sort_values('distributor_cost', ascending=True).head(top_n).copy()
508
+
509
+ if dist_df.empty:
510
+ st.info("No data for this category yet.")
511
+ else:
512
+ dist_df['distributor_cost'] = dist_df['distributor_cost'].map('${:,.2f}'.format)
513
+ dist_df.rename(columns={'id': 'Participant', 'distributor_cost': 'Your Cost'}, inplace=True)
514
+ st.dataframe(dist_df[['Participant', 'Your Cost']], use_container_width=True, hide_index=True)
515
+
516
+ # 排行榜 3: 订单平滑度 (不变)
517
  with c3:
518
  st.subheader("🧘 Mr. Smooth")
519
  st.caption(f"Top {top_n} - Lowest Order Variation (Std. Dev.)")
520
+ smooth_df = df.dropna(subset=['order_std_dev']).sort_values('order_std_dev', ascending=True).head(top_n).copy()
521
+
522
+ if smooth_df.empty:
523
+ st.info("No data for this category yet.")
524
+ else:
525
+ smooth_df['order_std_dev'] = smooth_df['order_std_dev'].map('{:,.2f}'.format)
526
+ smooth_df.rename(columns={'id': 'Participant', 'order_std_dev': 'Order Std. Dev.'}, inplace=True)
527
+ st.dataframe(smooth_df[['Participant', 'Order Std. Dev.']], use_container_width=True, hide_index=True)
528
 
529
  def show_leaderboard_ui():
530
  st.markdown("---")
 
537
  try:
538
  df = pd.DataFrame(leaderboard_data.values())
539
  if 'id' not in df.columns and not df.empty: df['id'] = list(leaderboard_data.keys())
540
+
541
+ # 检查旧列是否存在即可
542
  if 'total_cost' not in df.columns or 'order_std_dev' not in df.columns or 'setting' not in df.columns:
543
  st.error("Leaderboard data is corrupted or incomplete.")
544
  return
545
+
546
  groups = sorted(df.setting.unique())
547
  tabs = st.tabs(["**Overall**"] + groups)
548
  with tabs[0]: display_rankings(df)
 
554
  st.error(f"Error displaying leaderboard: {e}")
555
  st.dataframe(leaderboard_data)
556
 
557
+ # ---------- MODIFIED FUNCTION (v2) ----------
558
  def save_logs_and_upload(state: dict):
559
  if not state.get('logs'):
560
  st.warning("No log data to save.")
 
582
  st.subheader("Updating Leaderboard...")
583
  try:
584
  human_role = state['human_role']
585
+
586
+ # 1. 计算你的 (Distributor) 成本
587
+ distributor_cost = logs_df[f'{human_role}.total_cost'].iloc[-1]
588
+
589
+ # 2. 计算总供应链成本
590
+ r_cost = logs_df['Retailer.total_cost'].iloc[-1]
591
+ w_cost = logs_df['Wholesaler.total_cost'].iloc[-1]
592
+ f_cost = logs_df['Factory.total_cost'].iloc[-1]
593
+ total_chain_cost = r_cost + w_cost + distributor_cost + f_cost
594
+
595
+ # 3. 计算订单标准差
596
  order_std_dev = logs_df[f'{human_role}.order_placed'].std()
597
+
598
  setting_name = f"{state['llm_personality']} / {state['info_sharing']}"
599
+
600
+ # 4. 创建新的条目
601
  new_entry = {
602
+ 'id': participant_id,
603
+ 'setting': setting_name,
604
+ 'total_cost': float(distributor_cost), # 'total_cost' 现在明确是 distributor_cost
605
+ 'total_chain_cost': float(total_chain_cost), # 新增: 总成本
606
  'order_std_dev': float(order_std_dev) if pd.notna(order_std_dev) else 0.0
607
  }
608
+
609
  leaderboard_data = load_leaderboard_data()
610
  leaderboard_data[participant_id] = new_entry
611
  save_leaderboard_data(leaderboard_data)
612
+
613
  except Exception as e_board:
614
  st.error(f"Error calculating or saving leaderboard score: {e_board}")
615
  # ==============================================================================