DuongTrongChi commited on
Commit
b13359f
·
verified ·
1 Parent(s): 4c4fdb7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -103
app.py CHANGED
@@ -3,7 +3,6 @@ import gradio as gr
3
  import pandas as pd
4
  from math import isnan
5
 
6
- # ===== DATA của bạn (có 3 task + Final Result) =====
7
  ROWS = [
8
  {"Team_name":"Nguyen Quang Thao","vi-law-nli (4-shot)":0.5816,"vi-law-qa (4 shot)":0.8217,"vilaw-syllo scale":0.38,"Final Result":0.5944333333},
9
  {"Team_name":"NHK","vi-law-nli (4-shot)":0.9333,"vi-law-qa (4 shot)":0.8683,"vilaw-syllo scale":0.3275,"Final Result":0.7097},
@@ -20,36 +19,22 @@ BASE_DF = pd.DataFrame(ROWS)
20
 
21
  NUM_COLS = ["vi-law-nli (4-shot)", "vi-law-qa (4 shot)", "vilaw-syllo scale", "Final Result"]
22
 
23
- # ====== Helpers ======
24
  def _prep_df(df: pd.DataFrame) -> pd.DataFrame:
25
  out = df.copy()
26
- # đảm bảo float, làm gọn:
27
  for c in NUM_COLS:
28
- out[c] = pd.to_numeric(out[c], errors="coerce").astype(float)
29
- out[c] = out[c].round(6)
30
- # sort mặc định theo Final Result desc
31
  out = out.sort_values("Final Result", ascending=False, kind="mergesort").reset_index(drop=True)
32
- # thêm Rank
33
- out.insert(0, "Rank", range(1, len(out) + 1))
34
  return out
35
 
36
  def _bar_html(v: float) -> str:
37
  if v is None or (isinstance(v, float) and isnan(v)):
38
  return "-"
39
  pct = max(0.0, min(1.0, float(v))) * 100
40
- # thanh progress tối giản, số bên phải
41
- return f"""
42
- <div class="cell">
43
- <div class="bar" style="width:{pct:.2f}%"></div>
44
- <span class="val">{v:.4f}</span>
45
- </div>
46
- """
47
 
48
  def _render_table(df: pd.DataFrame) -> str:
49
- # cột hiển thị theo thứ tự
50
- cols = ["Rank", "Team_name"] + NUM_COLS
51
- df = df[cols].copy()
52
- # build HTML
53
  header = "".join([f"<th>{c}</th>" for c in cols])
54
  rows_html = []
55
  for _, row in df.iterrows():
@@ -62,115 +47,58 @@ def _render_table(df: pd.DataFrame) -> str:
62
  f"<td>{_bar_html(row['Final Result'])}</td>",
63
  ]
64
  rows_html.append(f"<tr>{''.join(tds)}</tr>")
65
- table = f"""
66
- <table class="lb-table">
67
- <thead><tr>{header}</tr></thead>
68
- <tbody>{"".join(rows_html)}</tbody>
69
- </table>
70
- """
71
- return table
72
 
73
- def _filter_and_sort(
74
- search: str,
75
- min_nli: float,
76
- min_qa: float,
77
- min_syllo: float,
78
- quick: str
79
- ) -> pd.DataFrame:
80
  df = BASE_DF.copy()
81
-
82
- # search theo team (case-insensitive, hỗ trợ nhiều từ cách nhau bởi ;)
83
  if search:
84
  terms = [t.strip() for t in search.split(";") if t.strip()]
85
  for t in terms:
86
  df = df[df["Team_name"].str.contains(t, case=False, na=False)]
87
-
88
- # bộ lọc điểm
89
- if min_nli is not None:
90
- df = df[df["vi-law-nli (4-shot)"] >= float(min_nli)]
91
- if min_qa is not None:
92
- df = df[df["vi-law-qa (4 shot)"] >= float(min_qa)]
93
- if min_syllo is not None:
94
- df = df[df["vilaw-syllo scale"] >= float(min_syllo)]
95
-
96
- # quick filter theo Final Result
97
  if quick == "Top 3":
98
- df = df.sort_values("Final Result", ascending=False, kind="mergesort").head(3)
99
  elif quick == "Top 5":
100
- df = df.sort_values("Final Result", ascending=False, kind="mergesort").head(5)
101
  else:
102
- df = df.sort_values("Final Result", ascending=False, kind="mergesort")
103
-
104
  return _prep_df(df)
105
 
106
- def _controller(search, min_nli, min_qa, min_syllo, quick):
107
- df = _filter_and_sort(search, min_nli, min_qa, min_syllo, quick)
108
- html = _render_table(df)
109
- return html, df # trả cả CSV để user tải
110
 
111
- # ====== CSS (dark style giống bản vẽ) ======
112
  CUSTOM_CSS = """
113
  :root {
114
- --bg: #0e1116;
115
- --panel: #12161f;
116
- --text: #e6e6e6;
117
- --muted: #9aa3b2;
118
- --accent: #f5c84b;
119
- --bar: #2ea043;
120
- --bar-bg: #1f2a36;
121
  }
122
- .gradio-container {background: var(--bg) !important; color: var(--text);}
123
- #title { text-align:center; padding: 16px 0 8px; }
124
- #subtitle { text-align:center; color: var(--muted); margin-bottom: 18px;}
125
- .controls .gradio-row { gap: 12px; }
126
  .lb-table { width:100%; border-collapse: collapse; }
127
- .lb-table thead th {
128
- position: sticky; top:0; background: var(--panel);
129
- padding: 10px 12px; text-align:left; font-weight:600; border-bottom: 1px solid #2a3240;
130
- }
131
- .lb-table tbody td { padding: 10px 12px; border-bottom: 1px solid #1d2430; }
132
- .lb-table tbody tr:hover { background: #101622; }
133
- .lb-table td.rank { width:64px; font-weight:700; }
134
- .lb-table td.team { min-width: 220px; }
135
- .cell { position: relative; height: 20px; background: var(--bar-bg); border-radius: 6px; overflow: hidden; }
136
- .cell .bar { position:absolute; left:0; top:0; bottom:0; background: var(--bar); }
137
- .cell .val { position:absolute; right:8px; top:0; bottom:0; display:flex; align-items:center; font-variant-numeric: tabular-nums; }
138
- .quick-btn .gr-button { background:#1a2030; border:1px solid #2b3445; }
139
- .quick-btn .gr-button:hover { filter: brightness(1.1); }
140
- .footer-note { color: var(--muted); font-size: 0.9rem; text-align:center; }
141
  """
142
 
143
- # ====== UI ======
144
- with gr.Blocks(css=CUSTOM_CSS, theme=gr.themes.Soft(primary_hue="orange")) as demo:
145
- gr.Markdown("<h1 id='title'>🏆 VI-Law Leaderboard</h1>", elem_id="title")
146
- gr.Markdown("<div id='subtitle'>So sánh kết quả theo cách <b>đơn giản & tái lập</b>. Mặc định xếp hạng theo <b>Final Result</b> (giảm dần).</div>", elem_id="subtitle")
147
-
148
- with gr.Row(elem_classes="controls"):
149
- search = gr.Textbox(placeholder='Tìm theo tên team. Hỗ trợ nhiều từ; phân tách bằng ";"', label="Search")
150
  with gr.Row():
151
- min_nli = gr.Slider(0.0, 1.0, value=None, step=0.01, label="Min vi-law-nli (4-shot)", interactive=True)
152
- min_qa = gr.Slider(0.0, 1.0, value=None, step=0.01, label="Min vi-law-qa (4 shot)", interactive=True)
153
- min_syllo = gr.Slider(0.0, 1.0, value=None, step=0.01, label="Min vilaw-syllo scale", interactive=True)
154
-
155
- with gr.Row(elem_classes="quick-btn"):
156
- quick = gr.Radio(choices=["All", "Top 3", "Top 5"], value="All", label="Quick Filters")
157
-
158
  html_table = gr.HTML(value=_render_table(_prep_df(BASE_DF)))
159
- csv_state = gr.State(_prep_df(BASE_DF)) # để Download CSV
160
- download = gr.DownloadButton("⬇️ Tải CSV hiện tại", label=None)
161
 
162
  def _download(df):
163
- path = "/tmp/vi_law_leaderboard.csv"
164
- df.to_csv(path, index=False)
165
  return path
166
-
167
  download.click(_download, inputs=[csv_state], outputs=download)
168
 
169
- # wire events
170
- for comp in [search, min_nli, min_qa, min_syllo, quick]:
171
- comp.change(_controller, [search, min_nli, min_qa, min_syllo, quick], [html_table, csv_state])
172
-
173
- gr.Markdown("<div class='footer-note'>Gợi ý: dùng Quick Filters để xem Top 3 / Top 5 theo Final Result.</div>")
174
 
175
  if __name__ == "__main__":
176
  demo.launch()
 
3
  import pandas as pd
4
  from math import isnan
5
 
 
6
  ROWS = [
7
  {"Team_name":"Nguyen Quang Thao","vi-law-nli (4-shot)":0.5816,"vi-law-qa (4 shot)":0.8217,"vilaw-syllo scale":0.38,"Final Result":0.5944333333},
8
  {"Team_name":"NHK","vi-law-nli (4-shot)":0.9333,"vi-law-qa (4 shot)":0.8683,"vilaw-syllo scale":0.3275,"Final Result":0.7097},
 
19
 
20
  NUM_COLS = ["vi-law-nli (4-shot)", "vi-law-qa (4 shot)", "vilaw-syllo scale", "Final Result"]
21
 
 
22
  def _prep_df(df: pd.DataFrame) -> pd.DataFrame:
23
  out = df.copy()
 
24
  for c in NUM_COLS:
25
+ out[c] = pd.to_numeric(out[c], errors="coerce").astype(float).round(6)
 
 
26
  out = out.sort_values("Final Result", ascending=False, kind="mergesort").reset_index(drop=True)
27
+ out.insert(0, "Rank", range(1, len(out)+1))
 
28
  return out
29
 
30
  def _bar_html(v: float) -> str:
31
  if v is None or (isinstance(v, float) and isnan(v)):
32
  return "-"
33
  pct = max(0.0, min(1.0, float(v))) * 100
34
+ return f"<div class='cell'><div class='bar' style='width:{pct:.2f}%'></div><span class='val'>{v:.4f}</span></div>"
 
 
 
 
 
 
35
 
36
  def _render_table(df: pd.DataFrame) -> str:
37
+ cols = ["Rank","Team_name"]+NUM_COLS
 
 
 
38
  header = "".join([f"<th>{c}</th>" for c in cols])
39
  rows_html = []
40
  for _, row in df.iterrows():
 
47
  f"<td>{_bar_html(row['Final Result'])}</td>",
48
  ]
49
  rows_html.append(f"<tr>{''.join(tds)}</tr>")
50
+ return f"<table class='lb-table'><thead><tr>{header}</tr></thead><tbody>{''.join(rows_html)}</tbody></table>"
 
 
 
 
 
 
51
 
52
+ def _filter_and_sort(search: str, quick: str):
 
 
 
 
 
 
53
  df = BASE_DF.copy()
 
 
54
  if search:
55
  terms = [t.strip() for t in search.split(";") if t.strip()]
56
  for t in terms:
57
  df = df[df["Team_name"].str.contains(t, case=False, na=False)]
 
 
 
 
 
 
 
 
 
 
58
  if quick == "Top 3":
59
+ df = df.sort_values("Final Result", ascending=False).head(3)
60
  elif quick == "Top 5":
61
+ df = df.sort_values("Final Result", ascending=False).head(5)
62
  else:
63
+ df = df.sort_values("Final Result", ascending=False)
 
64
  return _prep_df(df)
65
 
66
+ def _controller(search, quick):
67
+ df = _filter_and_sort(search, quick)
68
+ return _render_table(df), df
 
69
 
 
70
  CUSTOM_CSS = """
71
  :root {
72
+ --bg: #0e1116; --panel:#12161f; --text:#e6e6e6; --muted:#9aa3b2; --bar:#2ea043; --bar-bg:#1f2a36;
 
 
 
 
 
 
73
  }
74
+ .gradio-container {background: var(--bg)!important; color: var(--text);}
 
 
 
75
  .lb-table { width:100%; border-collapse: collapse; }
76
+ .lb-table thead th { background: var(--panel); padding: 10px; text-align:left; }
77
+ .lb-table tbody td { padding: 10px; border-bottom: 1px solid #1d2430; }
78
+ .lb-table td.rank { width:60px; font-weight:700; }
79
+ .lb-table td.team { min-width:200px; }
80
+ .cell { position:relative; height:20px; background: var(--bar-bg); border-radius:6px; }
81
+ .cell .bar { position:absolute; left:0; top:0; bottom:0; background: var(--bar);}
82
+ .cell .val { position:absolute; right:8px; top:0; bottom:0; display:flex; align-items:center; }
 
 
 
 
 
 
 
83
  """
84
 
85
+ with gr.Blocks(css=CUSTOM_CSS) as demo:
86
+ gr.Markdown("# 🏆 VI-Law Leaderboard")
 
 
 
 
 
87
  with gr.Row():
88
+ search = gr.Textbox(placeholder="Tìm team...", label="Search")
89
+ quick = gr.Radio(choices=["All","Top 3","Top 5"], value="All", label="Quick Filter")
 
 
 
 
 
90
  html_table = gr.HTML(value=_render_table(_prep_df(BASE_DF)))
91
+ csv_state = gr.State(_prep_df(BASE_DF))
92
+ download = gr.DownloadButton("⬇️ Tải CSV")
93
 
94
  def _download(df):
95
+ path = "/tmp/leaderboard.csv"
96
+ df.to_csv(path,index=False)
97
  return path
 
98
  download.click(_download, inputs=[csv_state], outputs=download)
99
 
100
+ for comp in [search, quick]:
101
+ comp.change(_controller, [search, quick], [html_table, csv_state])
 
 
 
102
 
103
  if __name__ == "__main__":
104
  demo.launch()