amendolajine commited on
Commit
3f0b75e
·
verified ·
1 Parent(s): 363ee67

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -11
app.py CHANGED
@@ -13,8 +13,8 @@ def load_excel(file):
13
  """
14
  Reads the Excel file and normalizes header names.
15
  Expected headers (row 1): "Player", "Role 1", "Role 2", "Role 3", "xB90".
16
- Returns six Dropdown components: three for the selected roles and three for the corresponding preferred proposal roles,
17
- populated with the union of roles from all three role columns (with a blank option prepended).
18
  """
19
  global df
20
  logging.debug("load_excel: Received file %s", file.name)
@@ -39,7 +39,7 @@ def load_excel(file):
39
  df["role2"] = df["role2"].astype(str).str.strip()
40
  df["role3"] = df["role3"].astype(str).str.strip()
41
  df["xb90"] = pd.to_numeric(df["xb90"], errors="coerce")
42
- # Get union of roles from all three columns.
43
  roles = pd.concat([df["role1"], df["role2"], df["role3"]]).dropna().unique().tolist()
44
  roles = sorted(roles)
45
  roles = [""] + roles # Prepend blank.
@@ -73,10 +73,18 @@ def update_players(selected_role):
73
  logging.debug("Players for role %s: %s", selected_role, players)
74
  return gr.Dropdown(choices=players, interactive=True)
75
 
 
 
 
 
 
 
 
 
 
76
  def get_xb90_value(role, player):
77
  """
78
- Returns the xB90 value (as a string) for the given player and selected role.
79
- Searches rows where the player's name matches and the role appears in any column.
80
  """
81
  global df
82
  logging.debug("get_xb90_value: role=%s, player=%s", role, player)
@@ -111,22 +119,27 @@ def compute_exchange(role1, player1, pref1, role2, player2, pref2, role3, player
111
  Computes exchange proposals:
112
  - Actual value: sum of selected players’ xB90.
113
  - Target: actual * multiplier.
114
- - For each selected player, gather candidate replacements from rows where:
115
  (a) the candidate has the selected role (in any column), and
116
  (b) if a preferred proposal role is provided, candidate must have it.
117
- If no candidate meets the preference, relax the constraint.
118
  - Excludes any candidate that is among the selected players.
119
  - Generates candidate combinations and selects up to three proposals ensuring no candidate
120
  is repeated across proposals.
121
- - Also enforces that if the selected role is "Por", then the preferred must be "Por".
 
122
  """
123
  global df
124
  logging.debug("compute_exchange: Starting computation")
125
  selected = []
126
  for i, (r, p, pref) in enumerate([(role1, player1, pref1), (role2, player2, pref2), (role3, player3, pref3)], start=1):
127
  if r and p:
128
- if r == "Por": # enforce rule: if role is Por, then preferred must be Por.
129
- logging.debug("For player %d with role 'Por', forcing preferred to 'Por'", i)
 
 
 
 
130
  pref = "Por"
131
  xb90_val = get_xb90_value(r, p)
132
  if xb90_val == "":
@@ -289,13 +302,17 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
289
  xb90_3 = gr.Textbox(label="xB90 per Giocatore 3", interactive=False)
290
  pref3 = gr.Dropdown(label="Ruolo Preferito per Proposta (3)", choices=[], interactive=True)
291
 
292
- # Add slider for configurable multiplier.
293
  multiplier_slider = gr.Slider(minimum=0.5, maximum=1.5, value=1.05, step=0.01, label="Moltiplicatore di Scambio", interactive=True)
294
 
295
  file_input.change(fn=load_excel, inputs=file_input, outputs=[role1, role2, role3, pref1, pref2, pref3])
296
  role1.change(fn=update_players, inputs=role1, outputs=player1)
297
  role2.change(fn=update_players, inputs=role2, outputs=player2)
298
  role3.change(fn=update_players, inputs=role3, outputs=player3)
 
 
 
 
 
299
  player1.change(fn=get_xb90_value, inputs=[role1, player1], outputs=xb90_1)
300
  player2.change(fn=get_xb90_value, inputs=[role2, player2], outputs=xb90_2)
301
  player3.change(fn=get_xb90_value, inputs=[role3, player3], outputs=xb90_3)
 
13
  """
14
  Reads the Excel file and normalizes header names.
15
  Expected headers (row 1): "Player", "Role 1", "Role 2", "Role 3", "xB90".
16
+ Returns six Dropdown components: three for selected roles and three for preferred proposal roles,
17
+ populated with the union of roles from all three columns (with a blank option prepended).
18
  """
19
  global df
20
  logging.debug("load_excel: Received file %s", file.name)
 
39
  df["role2"] = df["role2"].astype(str).str.strip()
40
  df["role3"] = df["role3"].astype(str).str.strip()
41
  df["xb90"] = pd.to_numeric(df["xb90"], errors="coerce")
42
+ # Get union of roles.
43
  roles = pd.concat([df["role1"], df["role2"], df["role3"]]).dropna().unique().tolist()
44
  roles = sorted(roles)
45
  roles = [""] + roles # Prepend blank.
 
73
  logging.debug("Players for role %s: %s", selected_role, players)
74
  return gr.Dropdown(choices=players, interactive=True)
75
 
76
+ def sync_pref(selected_role):
77
+ """
78
+ If the selected role is "Por", returns "Por" to automatically set the preferred proposal role.
79
+ Otherwise, returns an empty string.
80
+ """
81
+ if selected_role == "Por":
82
+ return "Por"
83
+ return ""
84
+
85
  def get_xb90_value(role, player):
86
  """
87
+ Returns the xB90 value (as a string) for the given player where the selected role appears in any role column.
 
88
  """
89
  global df
90
  logging.debug("get_xb90_value: role=%s, player=%s", role, player)
 
119
  Computes exchange proposals:
120
  - Actual value: sum of selected players’ xB90.
121
  - Target: actual * multiplier.
122
+ - For each selected player, gathers candidate replacements from rows where:
123
  (a) the candidate has the selected role (in any column), and
124
  (b) if a preferred proposal role is provided, candidate must have it.
125
+ If no candidate meets the preferred criterion, the preference constraint is relaxed.
126
  - Excludes any candidate that is among the selected players.
127
  - Generates candidate combinations and selects up to three proposals ensuring no candidate
128
  is repeated across proposals.
129
+ - Enforces that if a player's role is "Por", then the preferred must be "Por".
130
+ - If a user somehow sets a different preferred value for a "Por" player, an error is returned.
131
  """
132
  global df
133
  logging.debug("compute_exchange: Starting computation")
134
  selected = []
135
  for i, (r, p, pref) in enumerate([(role1, player1, pref1), (role2, player2, pref2), (role3, player3, pref3)], start=1):
136
  if r and p:
137
+ if r == "Por":
138
+ if pref != "Por":
139
+ msg = f"Puoi scambiare un portiere solo per un altro portiere. (Giocatore {i})"
140
+ logging.error(msg)
141
+ return msg
142
+ # Automatically force preferred to Por.
143
  pref = "Por"
144
  xb90_val = get_xb90_value(r, p)
145
  if xb90_val == "":
 
302
  xb90_3 = gr.Textbox(label="xB90 per Giocatore 3", interactive=False)
303
  pref3 = gr.Dropdown(label="Ruolo Preferito per Proposta (3)", choices=[], interactive=True)
304
 
 
305
  multiplier_slider = gr.Slider(minimum=0.5, maximum=1.5, value=1.05, step=0.01, label="Moltiplicatore di Scambio", interactive=True)
306
 
307
  file_input.change(fn=load_excel, inputs=file_input, outputs=[role1, role2, role3, pref1, pref2, pref3])
308
  role1.change(fn=update_players, inputs=role1, outputs=player1)
309
  role2.change(fn=update_players, inputs=role2, outputs=player2)
310
  role3.change(fn=update_players, inputs=role3, outputs=player3)
311
+ # Sync preferred role: if role is "Por", force preferred to "Por"
312
+ role1.change(fn=sync_pref, inputs=role1, outputs=pref1)
313
+ role2.change(fn=sync_pref, inputs=role2, outputs=pref2)
314
+ role3.change(fn=sync_pref, inputs=role3, outputs=pref3)
315
+
316
  player1.change(fn=get_xb90_value, inputs=[role1, player1], outputs=xb90_1)
317
  player2.change(fn=get_xb90_value, inputs=[role2, player2], outputs=xb90_2)
318
  player3.change(fn=get_xb90_value, inputs=[role3, player3], outputs=xb90_3)