Ilayr222 commited on
Commit
4def061
Β·
verified Β·
1 Parent(s): 38d7b65

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +14 -59
app.py CHANGED
@@ -105,14 +105,6 @@ def dataset_nations():
105
  vals = [n for n in DF["Nation"].dropna().unique().tolist() if str(n).strip()]
106
  return sorted(set(vals))
107
 
108
- def all_countries_minus_excluded():
109
- vals = []
110
- for c in pycountry.countries:
111
- nm = c.name
112
- if re.sub(r"\s+"," ", nm).upper() not in EXCLUDED_NATIONS:
113
- vals.append(nm)
114
- return sorted(set(vals))
115
-
116
  def clubs_list():
117
  if "Club" not in DF.columns: return []
118
  vals = [c for c in DF["Club"].dropna().unique().tolist() if str(c).strip()]
@@ -151,39 +143,31 @@ def to_csv_bytes(df):
151
  return buf.getvalue().encode("utf-8")
152
 
153
  # =======================
154
- # UI (bubble layout + equalized heights)
155
  # =======================
156
  THEME = gr.themes.Soft(primary_hue="blue")
157
  CSS = """
158
  #title { text-align:center; }
159
- .bubble { background:#fff; border-radius:16px; padding:12px; box-shadow:0 2px 10px rgba(0,0,0,.06); display:flex; flex-direction:column; justify-content:space-between; min-height:110px; }
160
  .bubble.tall { min-height: 220px; }
161
  .grid { gap:12px; }
162
  .stat { font-weight:600; font-size:14px; }
163
  .banner { background:#f6f7ff; border:1px solid #e3e6ff; padding:10px 12px; border-radius:12px; }
 
 
164
  """
165
 
166
  with gr.Blocks(theme=THEME, css=CSS) as demo:
167
- # Data banner shows linkage state (how many players + which columns)
168
  if DF.empty:
169
- gr.Markdown("<div class='banner'><b>Dataset not found or empty.</b> Upload <code>players.dataset.xlsx</code> to the root.</div>")
170
  else:
171
- cols = ", ".join(DF.columns.tolist())
172
- gr.Markdown(f"<div class='banner'>Loaded <b>{len(DF)}</b> players β€’ Columns: <code>{cols}</code></div>")
173
 
174
  gr.Markdown("<h1 id='title'>ProScout β€” Player Finder</h1>")
175
 
176
- # Toggle for nation list source (dataset vs all countries)
177
- with gr.Row():
178
- with gr.Column(scale=3):
179
- pass
180
- with gr.Column(scale=1):
181
- with gr.Group(elem_classes="bubble"):
182
- show_all_countries = gr.Checkbox(label="Show all countries", value=False, info="Default: only nations present in your dataset")
183
-
184
- # Filters + results
185
  with gr.Row():
186
- # Column 1 β€” categorical + search
187
  with gr.Column(scale=1, elem_classes="grid"):
188
  with gr.Group(elem_classes="bubble tall"):
189
  pos = gr.CheckboxGroup(positions_list(), label="Positions", value=[], info="Pick one or more")
@@ -218,28 +202,16 @@ with gr.Blocks(theme=THEME, css=CSS) as demo:
218
  with gr.Group(elem_classes="bubble"):
219
  max_wage = gr.Number(value=np.nan, label="Max Wage (EUR)")
220
 
221
- # Results panel (wide)
222
  with gr.Column(scale=2):
223
  with gr.Group(elem_classes="bubble tall"):
 
224
  results = gr.Dataframe(row_count=(12,"dynamic"), wrap=True, interactive=False, label="Results")
225
- with gr.Row():
226
- count_box = gr.Markdown("", elem_classes="stat")
227
- avg_ovr_box = gr.Markdown("", elem_classes="stat")
228
- avg_age_box = gr.Markdown("", elem_classes="stat")
229
- dl = gr.DownloadButton("Download CSV")
230
-
231
- # Full-width Search button
232
- with gr.Row():
233
- with gr.Column(scale=3):
234
- with gr.Group(elem_classes="bubble"):
235
  btn = gr.Button("Search", variant="primary")
236
 
237
- # Dynamic: switch nations list source
238
- def update_nations_list(show_all):
239
- return gr.update(choices=all_countries_minus_excluded() if show_all else dataset_nations(), value=[])
240
-
241
- show_all_countries.change(update_nations_list, inputs=show_all_countries, outputs=nat)
242
-
243
  # Main callback
244
  def _run(positions, nations, clubs, min_overall, min_potential,
245
  max_age, min_h, max_h, min_w, max_w, max_val, max_wage, query):
@@ -247,21 +219,4 @@ with gr.Blocks(theme=THEME, css=CSS) as demo:
247
  max_age, min_h, max_h, min_w, max_w, max_val, max_wage, query)
248
  count = len(df)
249
  avg_ovr = round(df["Overall"].mean(), 2) if "Overall" in df and not df["Overall"].isna().all() else "-"
250
- avg_age = round(df["Age"].mean(), 2) if "Age" in df and not df["Age"].isna().all() else "-"
251
- csv_bytes = to_csv_bytes(df)
252
- return df, f"**Players:** {count}", f"**Avg OVR:** {avg_ovr}", f"**Avg Age:** {avg_age}", csv_bytes
253
-
254
- # Load initial results automatically
255
- demo.load(
256
- _run,
257
- inputs=[pos,nat,clu,min_ovr,min_pot,max_age,min_h,max_h,min_w,max_w,max_val,max_wage,query],
258
- outputs=[results,count_box,avg_ovr_box,avg_age_box,dl]
259
- )
260
- btn.click(
261
- _run,
262
- inputs=[pos,nat,clu,min_ovr,min_pot,max_age,min_h,max_h,min_w,max_w,max_val,max_wage,query],
263
- outputs=[results,count_box,avg_ovr_box,avg_age_box,dl]
264
- )
265
-
266
- # Launch for Spaces
267
- demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860)))
 
105
  vals = [n for n in DF["Nation"].dropna().unique().tolist() if str(n).strip()]
106
  return sorted(set(vals))
107
 
 
 
 
 
 
 
 
 
108
  def clubs_list():
109
  if "Club" not in DF.columns: return []
110
  vals = [c for c in DF["Club"].dropna().unique().tolist() if str(c).strip()]
 
143
  return buf.getvalue().encode("utf-8")
144
 
145
  # =======================
146
+ # UI (clean aesthetic; equal bubble heights; Search in Results header)
147
  # =======================
148
  THEME = gr.themes.Soft(primary_hue="blue")
149
  CSS = """
150
  #title { text-align:center; }
151
+ .bubble { background:#fff; border-radius:16px; padding:12px; box-shadow:0 2px 10px rgba(0,0,0,.06); display:flex; flex-direction:column; justify-content:space-between; min-height:120px; }
152
  .bubble.tall { min-height: 220px; }
153
  .grid { gap:12px; }
154
  .stat { font-weight:600; font-size:14px; }
155
  .banner { background:#f6f7ff; border:1px solid #e3e6ff; padding:10px 12px; border-radius:12px; }
156
+ .header-row { display:flex; align-items:center; justify-content:space-between; gap:12px; }
157
+ .header-row .stats { display:flex; gap:16px; }
158
  """
159
 
160
  with gr.Blocks(theme=THEME, css=CSS) as demo:
161
+ # Top banner confirms linkage
162
  if DF.empty:
163
+ gr.Markdown("<div class='banner'><b>No players loaded.</b> Make sure <code>players.dataset.xlsx</code> is in the root.</div>")
164
  else:
165
+ gr.Markdown(f"<div class='banner'>Loaded <b>{len(DF)}</b> players.</div>")
 
166
 
167
  gr.Markdown("<h1 id='title'>ProScout β€” Player Finder</h1>")
168
 
 
 
 
 
 
 
 
 
 
169
  with gr.Row():
170
+ # Column 1 β€” categorical + search (each in its own bubble)
171
  with gr.Column(scale=1, elem_classes="grid"):
172
  with gr.Group(elem_classes="bubble tall"):
173
  pos = gr.CheckboxGroup(positions_list(), label="Positions", value=[], info="Pick one or more")
 
202
  with gr.Group(elem_classes="bubble"):
203
  max_wage = gr.Number(value=np.nan, label="Max Wage (EUR)")
204
 
205
+ # Results panel β€” Search button in header next to stats
206
  with gr.Column(scale=2):
207
  with gr.Group(elem_classes="bubble tall"):
208
+ header = gr.HTML("<div class='header-row'><div class='stats'><span id='stat-count'></span><span id='stat-ovr'></span><span id='stat-age'></span></div></div>")
209
  results = gr.Dataframe(row_count=(12,"dynamic"), wrap=True, interactive=False, label="Results")
210
+ count_box = gr.Markdown("", elem_id="stat-count")
211
+ avg_ovr_box = gr.Markdown("", elem_id="stat-ovr")
212
+ avg_age_box = gr.Markdown("", elem_id="stat-age")
 
 
 
 
 
 
 
213
  btn = gr.Button("Search", variant="primary")
214
 
 
 
 
 
 
 
215
  # Main callback
216
  def _run(positions, nations, clubs, min_overall, min_potential,
217
  max_age, min_h, max_h, min_w, max_w, max_val, max_wage, query):
 
219
  max_age, min_h, max_h, min_w, max_w, max_val, max_wage, query)
220
  count = len(df)
221
  avg_ovr = round(df["Overall"].mean(), 2) if "Overall" in df and not df["Overall"].isna().all() else "-"
222
+ avg_age = round(df["Age"].mean(), 2) if "Age" in df and not df["Age"].isna(_