aimodelshare 0.3.94__py3-none-any.whl → 0.4.71__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aimodelshare/moral_compass/apps/model_building_app_ca.py +221 -76
- aimodelshare/moral_compass/apps/model_building_app_en.py +496 -373
- aimodelshare/moral_compass/apps/model_building_app_es.py +117 -106
- {aimodelshare-0.3.94.dist-info → aimodelshare-0.4.71.dist-info}/METADATA +1 -1
- {aimodelshare-0.3.94.dist-info → aimodelshare-0.4.71.dist-info}/RECORD +8 -8
- {aimodelshare-0.3.94.dist-info → aimodelshare-0.4.71.dist-info}/WHEEL +0 -0
- {aimodelshare-0.3.94.dist-info → aimodelshare-0.4.71.dist-info}/licenses/LICENSE +0 -0
- {aimodelshare-0.3.94.dist-info → aimodelshare-0.4.71.dist-info}/top_level.txt +0 -0
|
@@ -404,7 +404,7 @@ def _build_attempts_tracker_html(current_count, limit=10):
|
|
|
404
404
|
border_color = "#bae6fd"
|
|
405
405
|
text_color = "#0369a1"
|
|
406
406
|
icon = "🛑"
|
|
407
|
-
label = f"Última oportunitat (
|
|
407
|
+
label = f"Última oportunitat (per ara) per pujar la teva puntuació!: {current_count}/{limit}"
|
|
408
408
|
else:
|
|
409
409
|
# Normal - blue styling
|
|
410
410
|
bg_color = "#f0f9ff"
|
|
@@ -784,7 +784,7 @@ def _background_initializer():
|
|
|
784
784
|
INIT_FLAGS["competition"] = True
|
|
785
785
|
except Exception as e:
|
|
786
786
|
with INIT_LOCK:
|
|
787
|
-
INIT_FLAGS["errors"].append(f"
|
|
787
|
+
INIT_FLAGS["errors"].append(f"La connexió amb la competició ha fallat: {str(e)}")
|
|
788
788
|
|
|
789
789
|
try:
|
|
790
790
|
# Step 2: Load dataset core (train/test split)
|
|
@@ -793,7 +793,7 @@ def _background_initializer():
|
|
|
793
793
|
INIT_FLAGS["dataset_core"] = True
|
|
794
794
|
except Exception as e:
|
|
795
795
|
with INIT_LOCK:
|
|
796
|
-
INIT_FLAGS["errors"].append(f"
|
|
796
|
+
INIT_FLAGS["errors"].append(f"La càrrega del conjunt de dades ha fallat: {str(e)}")
|
|
797
797
|
return # Cannot proceed without data
|
|
798
798
|
|
|
799
799
|
try:
|
|
@@ -803,7 +803,7 @@ def _background_initializer():
|
|
|
803
803
|
INIT_FLAGS["warm_mini"] = True
|
|
804
804
|
except Exception as e:
|
|
805
805
|
with INIT_LOCK:
|
|
806
|
-
INIT_FLAGS["errors"].append(f"
|
|
806
|
+
INIT_FLAGS["errors"].append(f"El dataset mini de preescalfament ha fallat: {str(e)}")
|
|
807
807
|
|
|
808
808
|
# Progressive sampling - samples are already created in load_and_prep_data
|
|
809
809
|
# Just mark them as ready sequentially with delays to simulate progressive loading
|
|
@@ -815,7 +815,7 @@ def _background_initializer():
|
|
|
815
815
|
INIT_FLAGS["pre_samples_small"] = True
|
|
816
816
|
except Exception as e:
|
|
817
817
|
with INIT_LOCK:
|
|
818
|
-
INIT_FLAGS["errors"].append(f"
|
|
818
|
+
INIT_FLAGS["errors"].append(f"La mostra petita ha fallat: {str(e)}")
|
|
819
819
|
|
|
820
820
|
try:
|
|
821
821
|
# Step 4b: Medium sample (60%)
|
|
@@ -824,7 +824,7 @@ def _background_initializer():
|
|
|
824
824
|
INIT_FLAGS["pre_samples_medium"] = True
|
|
825
825
|
except Exception as e:
|
|
826
826
|
with INIT_LOCK:
|
|
827
|
-
INIT_FLAGS["errors"].append(f"
|
|
827
|
+
INIT_FLAGS["errors"].append(f"La mostra mitjana ha fallat: {str(e)}")
|
|
828
828
|
|
|
829
829
|
try:
|
|
830
830
|
# Step 4c: Large sample (80%)
|
|
@@ -833,7 +833,7 @@ def _background_initializer():
|
|
|
833
833
|
INIT_FLAGS["pre_samples_large"] = True
|
|
834
834
|
except Exception as e:
|
|
835
835
|
with INIT_LOCK:
|
|
836
|
-
INIT_FLAGS["errors"].append(f"
|
|
836
|
+
INIT_FLAGS["errors"].append(f"La mostra gran ha fallat: {str(e)}")
|
|
837
837
|
print(f"✗ Large sample failed: {e}")
|
|
838
838
|
|
|
839
839
|
try:
|
|
@@ -844,7 +844,7 @@ def _background_initializer():
|
|
|
844
844
|
INIT_FLAGS["pre_samples_full"] = True
|
|
845
845
|
except Exception as e:
|
|
846
846
|
with INIT_LOCK:
|
|
847
|
-
INIT_FLAGS["errors"].append(f"
|
|
847
|
+
INIT_FLAGS["errors"].append(f"La mostra completa ha fallat: {str(e)}")
|
|
848
848
|
|
|
849
849
|
try:
|
|
850
850
|
# Step 5: Leaderboard prefetch (best-effort, unauthenticated)
|
|
@@ -856,7 +856,7 @@ def _background_initializer():
|
|
|
856
856
|
INIT_FLAGS["leaderboard"] = True
|
|
857
857
|
except Exception as e:
|
|
858
858
|
with INIT_LOCK:
|
|
859
|
-
INIT_FLAGS["errors"].append(f"
|
|
859
|
+
INIT_FLAGS["errors"].append(f"La pre-obtenció de la classificació ha fallat: {str(e)}")
|
|
860
860
|
|
|
861
861
|
try:
|
|
862
862
|
# Step 6: Default preprocessor on small sample
|
|
@@ -865,7 +865,7 @@ def _background_initializer():
|
|
|
865
865
|
INIT_FLAGS["default_preprocessor"] = True
|
|
866
866
|
except Exception as e:
|
|
867
867
|
with INIT_LOCK:
|
|
868
|
-
INIT_FLAGS["errors"].append(f"
|
|
868
|
+
INIT_FLAGS["errors"].append(f"El preprocessador per defecte ha fallat: {str(e)}")
|
|
869
869
|
print(f"✗ Default preprocessor failed: {e}")
|
|
870
870
|
|
|
871
871
|
|
|
@@ -1291,7 +1291,7 @@ def _build_kpi_card_html(new_score, last_score, new_rank, last_rank, submission_
|
|
|
1291
1291
|
|
|
1292
1292
|
# Handle pending state - show processing message with provisional diff
|
|
1293
1293
|
if is_pending:
|
|
1294
|
-
title = "⏳
|
|
1294
|
+
title = "⏳ Processant l'enviament"
|
|
1295
1295
|
acc_color = "#3b82f6" # Blue
|
|
1296
1296
|
acc_text = f"{(local_test_accuracy * 100):.2f}%" if local_test_accuracy is not None else "N/A"
|
|
1297
1297
|
|
|
@@ -1299,60 +1299,60 @@ def _build_kpi_card_html(new_score, last_score, new_rank, last_rank, submission_
|
|
|
1299
1299
|
if local_test_accuracy is not None and last_score is not None and last_score > 0:
|
|
1300
1300
|
score_diff = local_test_accuracy - last_score
|
|
1301
1301
|
if abs(score_diff) < 0.0001:
|
|
1302
|
-
acc_diff_html = "<p style='font-size: 1.5rem; font-weight: 600; color: #6b7280; margin:0;'>
|
|
1302
|
+
acc_diff_html = "<p style='font-size: 1.5rem; font-weight: 600; color: #6b7280; margin:0;'>Sense canvis (↔) <span style='font-size: 0.9rem; color: #9ca3af;'>(Provisional)</span></p><p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0; padding-top: 8px;'>Actualització de la classificació pendent...</p>"
|
|
1303
1303
|
elif score_diff > 0:
|
|
1304
|
-
acc_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: #16a34a; margin:0;'>+{(score_diff * 100):.2f} (⬆️) <span style='font-size: 0.9rem; color: #9ca3af;'>(Provisional)</span></p><p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0; padding-top: 8px;'>
|
|
1304
|
+
acc_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: #16a34a; margin:0;'>+{(score_diff * 100):.2f} (⬆️) <span style='font-size: 0.9rem; color: #9ca3af;'>(Provisional)</span></p><p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0; padding-top: 8px;'>Actualització de la classificació pendent...</p>"
|
|
1305
1305
|
else:
|
|
1306
|
-
acc_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: #ef4444; margin:0;'>{(score_diff * 100):.2f} (⬇️) <span style='font-size: 0.9rem; color: #9ca3af;'>(Provisional)</span></p><p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0; padding-top: 8px;'>
|
|
1306
|
+
acc_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: #ef4444; margin:0;'>{(score_diff * 100):.2f} (⬇️) <span style='font-size: 0.9rem; color: #9ca3af;'>(Provisional)</span></p><p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0; padding-top: 8px;'>Actualització de la classificació pendent...</p>"
|
|
1307
1307
|
else:
|
|
1308
1308
|
# No last score available - just show pending message
|
|
1309
1309
|
acc_diff_html = "<p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0; padding-top: 8px;'>Pending leaderboard update...</p>"
|
|
1310
1310
|
|
|
1311
1311
|
border_color = acc_color
|
|
1312
1312
|
rank_color = "#6b7280" # Gray
|
|
1313
|
-
rank_text = "
|
|
1314
|
-
rank_diff_html = "<p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0;'>
|
|
1313
|
+
rank_text = "Pendent"
|
|
1314
|
+
rank_diff_html = "<p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0;'>Calculant la posició...</p>"
|
|
1315
1315
|
|
|
1316
1316
|
# Handle preview mode - Styled to match "success" card
|
|
1317
1317
|
elif is_preview:
|
|
1318
|
-
title = "🔬
|
|
1318
|
+
title = "🔬 Prova de vista prèvia finalitzada!"
|
|
1319
1319
|
acc_color = "#16a34a" # Green (like success)
|
|
1320
1320
|
acc_text = f"{(new_score * 100):.2f}%" if new_score > 0 else "N/A"
|
|
1321
|
-
acc_diff_html = "<p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0; padding-top: 8px;'>(
|
|
1321
|
+
acc_diff_html = "<p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0; padding-top: 8px;'>(Només vista prèvia - no s'ha enviat)</p>" # Neutral color
|
|
1322
1322
|
border_color = acc_color # Green border
|
|
1323
1323
|
rank_color = "#3b82f6" # Blue (like rank)
|
|
1324
1324
|
rank_text = "N/A" # Placeholder
|
|
1325
|
-
rank_diff_html = "<p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0;'>
|
|
1325
|
+
rank_diff_html = "<p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0;'>Sense posició (vista prèvia)</p>" # Neutral color
|
|
1326
1326
|
|
|
1327
1327
|
# 1. Handle First Submission
|
|
1328
1328
|
elif submission_count == 0:
|
|
1329
|
-
title = "🎉
|
|
1329
|
+
title = "🎉 Primer model enviat!"
|
|
1330
1330
|
acc_color = "#16a34a" # green
|
|
1331
1331
|
acc_text = f"{(new_score * 100):.2f}%"
|
|
1332
|
-
acc_diff_html = "<p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0; padding-top: 8px;'>(
|
|
1332
|
+
acc_diff_html = "<p style='font-size: 1.2rem; font-weight: 500; color: #6b7280; margin:0; padding-top: 8px;'>(La teva primera puntuació!)</p>"
|
|
1333
1333
|
|
|
1334
1334
|
rank_color = "#3b82f6" # blue
|
|
1335
1335
|
rank_text = f"#{new_rank}"
|
|
1336
|
-
rank_diff_html = "<p style='font-size: 1.5rem; font-weight: 600; color: #3b82f6; margin:0;'
|
|
1336
|
+
rank_diff_html = "<p style='font-size: 1.5rem; font-weight: 600; color: #3b82f6; margin:0;'>¡Ja ets a la taula!</p>"
|
|
1337
1337
|
border_color = acc_color
|
|
1338
1338
|
|
|
1339
1339
|
else:
|
|
1340
1340
|
# 2. Handle Score Changes
|
|
1341
1341
|
score_diff = new_score - last_score
|
|
1342
1342
|
if abs(score_diff) < 0.0001:
|
|
1343
|
-
title = "✅
|
|
1343
|
+
title = "✅ Enviament completat!"
|
|
1344
1344
|
acc_color = "#6b7280" # gray
|
|
1345
1345
|
acc_text = f"{(new_score * 100):.2f}%"
|
|
1346
|
-
acc_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: {acc_color}; margin:0;'>
|
|
1346
|
+
acc_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: {acc_color}; margin:0;'>Sense canvis (↔)</p>"
|
|
1347
1347
|
border_color = acc_color
|
|
1348
1348
|
elif score_diff > 0:
|
|
1349
|
-
title = "✅
|
|
1349
|
+
title = "✅ Enviament completat!"
|
|
1350
1350
|
acc_color = "#16a34a" # green
|
|
1351
1351
|
acc_text = f"{(new_score * 100):.2f}%"
|
|
1352
1352
|
acc_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: {acc_color}; margin:0;'>+{(score_diff * 100):.2f} (⬆️)</p>"
|
|
1353
1353
|
border_color = acc_color
|
|
1354
1354
|
else:
|
|
1355
|
-
title = "📉
|
|
1355
|
+
title = "📉 La puntuació ha baixat"
|
|
1356
1356
|
acc_color = "#ef4444" # red
|
|
1357
1357
|
acc_text = f"{(new_score * 100):.2f}%"
|
|
1358
1358
|
acc_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: {acc_color}; margin:0;'>{(score_diff * 100):.2f} (⬇️)</p>"
|
|
@@ -1363,25 +1363,25 @@ def _build_kpi_card_html(new_score, last_score, new_rank, last_rank, submission_
|
|
|
1363
1363
|
rank_color = "#3b82f6" # blue
|
|
1364
1364
|
rank_text = f"#{new_rank}"
|
|
1365
1365
|
if last_rank == 0: # Handle first rank
|
|
1366
|
-
rank_diff_html = "<p style='font-size: 1.5rem; font-weight: 600; color: #3b82f6; margin:0;'
|
|
1366
|
+
rank_diff_html = "<p style='font-size: 1.5rem; font-weight: 600; color: #3b82f6; margin:0;'>¡Ja ets a la taula!</p>"
|
|
1367
1367
|
elif rank_diff > 0:
|
|
1368
|
-
rank_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: #16a34a; margin:0;'>🚀
|
|
1368
|
+
rank_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: #16a34a; margin:0;'>🚀 ¡Has pujat {rank_diff} posició/ons!</p>"
|
|
1369
1369
|
elif rank_diff < 0:
|
|
1370
|
-
rank_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: #ef4444; margin:0;'>🔻
|
|
1370
|
+
rank_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: #ef4444; margin:0;'>🔻 Has baixat {abs(rank_diff)} posició/ons!</p>"
|
|
1371
1371
|
else:
|
|
1372
|
-
rank_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: {rank_color}; margin:0;'>
|
|
1372
|
+
rank_diff_html = f"<p style='font-size: 1.5rem; font-weight: 600; color: {rank_color}; margin:0;'>Mantens la teva posició (↔)</p>"
|
|
1373
1373
|
|
|
1374
1374
|
return f"""
|
|
1375
1375
|
<div class='kpi-card' style='border-color: {border_color};'>
|
|
1376
1376
|
<h2 style='color: #111827; margin-top:0;'>{title}</h2>
|
|
1377
1377
|
<div class='kpi-card-body'>
|
|
1378
1378
|
<div class='kpi-metric-box'>
|
|
1379
|
-
<p class='kpi-label'>
|
|
1379
|
+
<p class='kpi-label'>Nova precisió</p>
|
|
1380
1380
|
<p class='kpi-score' style='color: {acc_color};'>{acc_text}</p>
|
|
1381
1381
|
{acc_diff_html}
|
|
1382
1382
|
</div>
|
|
1383
1383
|
<div class='kpi-metric-box'>
|
|
1384
|
-
<p class='kpi-label'>
|
|
1384
|
+
<p class='kpi-label'>La teva posició</p>
|
|
1385
1385
|
<p class='kpi-score' style='color: {rank_color};'>{rank_text}</p>
|
|
1386
1386
|
{rank_diff_html}
|
|
1387
1387
|
</div>
|
|
@@ -1400,7 +1400,7 @@ def _build_team_html(team_summary_df, team_name):
|
|
|
1400
1400
|
use the unmodified English team names from the DataFrame.
|
|
1401
1401
|
"""
|
|
1402
1402
|
if team_summary_df is None or team_summary_df.empty:
|
|
1403
|
-
return "<p style='text-align:center; color:#6b7280; padding-top:20px;'>
|
|
1403
|
+
return "<p style='text-align:center; color:#6b7280; padding-top:20px;'>Encara no hi ha enviaments per equips.</p>"
|
|
1404
1404
|
|
|
1405
1405
|
# Normalize the current user's team name for comparison (using English names)
|
|
1406
1406
|
normalized_user_team = _normalize_team_name(team_name).lower()
|
|
@@ -1409,11 +1409,11 @@ def _build_team_html(team_summary_df, team_name):
|
|
|
1409
1409
|
<table class='leaderboard-html-table'>
|
|
1410
1410
|
<thead>
|
|
1411
1411
|
<tr>
|
|
1412
|
-
<th>
|
|
1413
|
-
<th>
|
|
1414
|
-
<th>
|
|
1415
|
-
<th>
|
|
1416
|
-
<th>
|
|
1412
|
+
<th>Posició</th>
|
|
1413
|
+
<th>Equip</th>
|
|
1414
|
+
<th>Millor Puntuació</th>
|
|
1415
|
+
<th>Mitjana</th>
|
|
1416
|
+
<th>Enviaments</th>
|
|
1417
1417
|
</tr>
|
|
1418
1418
|
</thead>
|
|
1419
1419
|
<tbody>
|
|
@@ -1445,16 +1445,16 @@ def _build_team_html(team_summary_df, team_name):
|
|
|
1445
1445
|
def _build_individual_html(individual_summary_df, username):
|
|
1446
1446
|
"""Generates the HTML for the individual leaderboard."""
|
|
1447
1447
|
if individual_summary_df is None or individual_summary_df.empty:
|
|
1448
|
-
return "<p style='text-align:center; color:#6b7280; padding-top:20px;'>
|
|
1448
|
+
return "<p style='text-align:center; color:#6b7280; padding-top:20px;'>Encara no hi ha enviaments individuals.</p>"
|
|
1449
1449
|
|
|
1450
1450
|
header = """
|
|
1451
1451
|
<table class='leaderboard-html-table'>
|
|
1452
1452
|
<thead>
|
|
1453
1453
|
<tr>
|
|
1454
|
-
<th>
|
|
1455
|
-
<th>
|
|
1456
|
-
<th>
|
|
1457
|
-
<th>
|
|
1454
|
+
<th>Posició</th>
|
|
1455
|
+
<th>Enginyer/a</th>
|
|
1456
|
+
<th>Millor Puntuació</th>
|
|
1457
|
+
<th>Enviaments</th>
|
|
1458
1458
|
</tr>
|
|
1459
1459
|
</thead>
|
|
1460
1460
|
<tbody>
|
|
@@ -1496,8 +1496,8 @@ def generate_competitive_summary(leaderboard_df, team_name, username, last_submi
|
|
|
1496
1496
|
|
|
1497
1497
|
if leaderboard_df is None or leaderboard_df.empty or "accuracy" not in leaderboard_df.columns:
|
|
1498
1498
|
return (
|
|
1499
|
-
"<p style='text-align:center; color:#6b7280; padding-top:20px;'>
|
|
1500
|
-
"<p style='text-align:center; color:#6b7280; padding-top:20px;'>
|
|
1499
|
+
"<p style='text-align:center; color:#6b7280; padding-top:20px;'>La classificació està buida.</p>",
|
|
1500
|
+
"<p style='text-align:center; color:#6b7280; padding-top:20px;'>La classificació està buida.</p>",
|
|
1501
1501
|
_build_kpi_card_html(0, 0, 0, 0, 0, is_preview=False, is_pending=False, local_test_accuracy=None),
|
|
1502
1502
|
0.0, 0, 0.0
|
|
1503
1503
|
)
|
|
@@ -1867,9 +1867,9 @@ def perform_inline_login(username_input, password_input):
|
|
|
1867
1867
|
|
|
1868
1868
|
# Build success message based on whether team is new or existing
|
|
1869
1869
|
if is_new_team:
|
|
1870
|
-
team_message = f"
|
|
1870
|
+
team_message = f"T'hem assignat a un nou equip: <b>{display_team_name}</b> 🎉"
|
|
1871
1871
|
else:
|
|
1872
|
-
team_message = f"
|
|
1872
|
+
team_message = f"Hola de nou! Continues a l'equip: <b>{display_team_name}</b> ✅"
|
|
1873
1873
|
|
|
1874
1874
|
# Success: hide login form, show success message with team info, enable submit button
|
|
1875
1875
|
success_html = f"""
|
|
@@ -2010,11 +2010,11 @@ def run_experiment(
|
|
|
2010
2010
|
"""
|
|
2011
2011
|
|
|
2012
2012
|
# --- Stage 1: Lock UI and give initial feedback ---
|
|
2013
|
-
progress(0.1, desc="
|
|
2013
|
+
progress(0.1, desc="Iniciant l'experiment...")
|
|
2014
2014
|
initial_updates = {
|
|
2015
|
-
submit_button: gr.update(value="⏳ Experiment
|
|
2016
|
-
submission_feedback_display: gr.update(value=get_status_html(1, "
|
|
2017
|
-
login_error: gr.update(visible=False),
|
|
2015
|
+
submit_button: gr.update(value="⏳ Experiment en curs...", interactive=False),
|
|
2016
|
+
submission_feedback_display: gr.update(value=get_status_html(1, "Iniciant", "Preparant les variables de dades..."), visible=True), # Make sure it's visible
|
|
2017
|
+
login_error: gr.update(visible=False), # Hide login success/error message
|
|
2018
2018
|
attempts_tracker_display: gr.update(value=_build_attempts_tracker_html(submission_count))
|
|
2019
2019
|
}
|
|
2020
2020
|
yield initial_updates
|
|
@@ -2028,10 +2028,155 @@ def run_experiment(
|
|
|
2028
2028
|
log_output = f"▶ New Experiment\nModel: {model_name_key}\n..."
|
|
2029
2029
|
|
|
2030
2030
|
# Check readiness
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2031
|
+
with INIT_LOCK:
|
|
2032
|
+
flags = INIT_FLAGS.copy()
|
|
2033
|
+
|
|
2034
|
+
# Normalize variable name for consistency
|
|
2035
|
+
ready_for_submission = ready
|
|
2036
|
+
|
|
2037
|
+
# If not ready but warm mini available, run preview
|
|
2038
|
+
if not ready_for_submission and flags["warm_mini"] and X_TRAIN_WARM is not None:
|
|
2039
|
+
_log("Running warm mini preview (not ready yet)")
|
|
2040
|
+
progress(0.5, desc="Executant la vista prèvia...")
|
|
2041
|
+
yield {
|
|
2042
|
+
submission_feedback_display: gr.update(value=get_status_html("Vista prèvia", "Prova d'escalfament", "Provant amb un conjunt de dades reduït..."), visible=True),
|
|
2043
|
+
login_error: gr.update(visible=False)
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
try:
|
|
2047
|
+
# Run preview on warm mini dataset
|
|
2048
|
+
numeric_cols = [f for f in feature_set if f in ALL_NUMERIC_COLS]
|
|
2049
|
+
categorical_cols = [f for f in feature_set if f in ALL_CATEGORICAL_COLS]
|
|
2050
|
+
|
|
2051
|
+
if not numeric_cols and not categorical_cols:
|
|
2052
|
+
raise ValueError("No features selected for modeling.")
|
|
2053
|
+
|
|
2054
|
+
# Quick preprocessing and training on warm mini (uses memoized preprocessor)
|
|
2055
|
+
preprocessor, selected_cols = build_preprocessor(numeric_cols, categorical_cols)
|
|
2056
|
+
|
|
2057
|
+
X_warm_processed = preprocessor.fit_transform(X_TRAIN_WARM[selected_cols])
|
|
2058
|
+
X_test_processed = preprocessor.transform(X_TEST_RAW[selected_cols])
|
|
2059
|
+
|
|
2060
|
+
base_model = MODEL_TYPES[model_name_key]["model_builder"]()
|
|
2061
|
+
tuned_model = tune_model_complexity(base_model, complexity_level)
|
|
2062
|
+
|
|
2063
|
+
# Handle sparse arrays for models that require dense input
|
|
2064
|
+
if isinstance(tuned_model, (DecisionTreeClassifier, RandomForestClassifier)):
|
|
2065
|
+
X_warm_for_fit = _ensure_dense(X_warm_processed)
|
|
2066
|
+
X_test_for_predict = _ensure_dense(X_test_processed)
|
|
2067
|
+
else:
|
|
2068
|
+
X_warm_for_fit = X_warm_processed
|
|
2069
|
+
X_test_for_predict = X_test_processed
|
|
2070
|
+
|
|
2071
|
+
tuned_model.fit(X_warm_for_fit, Y_TRAIN_WARM)
|
|
2072
|
+
|
|
2073
|
+
# Get preview score
|
|
2074
|
+
from sklearn.metrics import accuracy_score
|
|
2075
|
+
predictions = tuned_model.predict(X_test_for_predict)
|
|
2076
|
+
preview_score = accuracy_score(Y_TEST, predictions)
|
|
2077
|
+
|
|
2078
|
+
# Update metadata state
|
|
2079
|
+
new_kpi_meta = {
|
|
2080
|
+
"was_preview": True,
|
|
2081
|
+
"preview_score": preview_score,
|
|
2082
|
+
"ready_at_run_start": False,
|
|
2083
|
+
"poll_iterations": 0,
|
|
2084
|
+
"local_test_accuracy": preview_score,
|
|
2085
|
+
"this_submission_score": None,
|
|
2086
|
+
"new_best_accuracy": None,
|
|
2087
|
+
"rank": None
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
# Show preview card
|
|
2091
|
+
preview_html = _build_kpi_card_html(
|
|
2092
|
+
preview_score, 0, 0, 0, -1,
|
|
2093
|
+
is_preview=True, is_pending=False, local_test_accuracy=None
|
|
2094
|
+
)
|
|
2095
|
+
|
|
2096
|
+
settings = compute_rank_settings(
|
|
2097
|
+
submission_count, model_name_key, complexity_level, feature_set, data_size_str
|
|
2098
|
+
)
|
|
2099
|
+
|
|
2100
|
+
final_updates = {
|
|
2101
|
+
submission_feedback_display: gr.update(value=preview_html, visible=True),
|
|
2102
|
+
team_leaderboard_display: _build_skeleton_leaderboard(rows=6, is_team=True),
|
|
2103
|
+
individual_leaderboard_display: _build_skeleton_leaderboard(rows=6, is_team=False),
|
|
2104
|
+
last_submission_score_state: last_submission_score,
|
|
2105
|
+
last_rank_state: last_rank,
|
|
2106
|
+
best_score_state: best_score,
|
|
2107
|
+
submission_count_state: submission_count,
|
|
2108
|
+
first_submission_score_state: first_submission_score,
|
|
2109
|
+
rank_message_display: settings["rank_message"],
|
|
2110
|
+
model_type_radio: gr.update(choices=settings["model_choices"], value=settings["model_value"], interactive=settings["model_interactive"]),
|
|
2111
|
+
complexity_slider: gr.update(minimum=1, maximum=settings["complexity_max"], value=settings["complexity_value"]),
|
|
2112
|
+
feature_set_checkbox: gr.update(choices=settings["feature_set_choices"], value=settings["feature_set_value"], interactive=settings["feature_set_interactive"]),
|
|
2113
|
+
data_size_radio: gr.update(choices=settings["data_size_choices"], value=settings["data_size_value"], interactive=settings["data_size_interactive"]),
|
|
2114
|
+
submit_button: gr.update(value="🔬 Build & Submit Model", interactive=True),
|
|
2115
|
+
login_username: gr.update(visible=False),
|
|
2116
|
+
login_password: gr.update(visible=False),
|
|
2117
|
+
login_submit: gr.update(visible=False),
|
|
2118
|
+
login_error: gr.update(visible=False),
|
|
2119
|
+
attempts_tracker_display: gr.update(value=_build_attempts_tracker_html(submission_count)),
|
|
2120
|
+
was_preview_state: True,
|
|
2121
|
+
kpi_meta_state: new_kpi_meta,
|
|
2122
|
+
last_seen_ts_state: None # No timestamp for preview
|
|
2123
|
+
}
|
|
2124
|
+
yield final_updates
|
|
2125
|
+
return
|
|
2126
|
+
|
|
2127
|
+
except Exception as e:
|
|
2128
|
+
_log(f"Preview failed: {e}")
|
|
2129
|
+
# Fall through to error handling
|
|
2130
|
+
|
|
2131
|
+
if playground is None or not ready_for_submission:
|
|
2132
|
+
settings = compute_rank_settings(
|
|
2133
|
+
submission_count, model_name_key, complexity_level, feature_set, data_size_str
|
|
2134
|
+
)
|
|
2135
|
+
|
|
2136
|
+
error_msg = "<p style='text-align:center; color:red; padding:20px 0;'>"
|
|
2137
|
+
if playground is None:
|
|
2138
|
+
error_msg += "Playground not connected. Please try again later."
|
|
2139
|
+
else:
|
|
2140
|
+
error_msg += "Data still initializing. Please wait a moment and try again."
|
|
2141
|
+
error_msg += "</p>"
|
|
2142
|
+
|
|
2143
|
+
error_kpi_meta = {
|
|
2144
|
+
"was_preview": False,
|
|
2145
|
+
"preview_score": None,
|
|
2146
|
+
"ready_at_run_start": False,
|
|
2147
|
+
"poll_iterations": 0,
|
|
2148
|
+
"local_test_accuracy": None,
|
|
2149
|
+
"this_submission_score": None,
|
|
2150
|
+
"new_best_accuracy": None,
|
|
2151
|
+
"rank": None
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2154
|
+
error_updates = {
|
|
2155
|
+
submission_feedback_display: gr.update(value=error_msg, visible=True),
|
|
2156
|
+
submit_button: gr.update(value="🔬 Build & Submit Model", interactive=True),
|
|
2157
|
+
team_leaderboard_display: _build_skeleton_leaderboard(rows=6, is_team=True),
|
|
2158
|
+
individual_leaderboard_display: _build_skeleton_leaderboard(rows=6, is_team=False),
|
|
2159
|
+
last_submission_score_state: last_submission_score,
|
|
2160
|
+
last_rank_state: last_rank,
|
|
2161
|
+
best_score_state: best_score,
|
|
2162
|
+
submission_count_state: submission_count,
|
|
2163
|
+
first_submission_score_state: first_submission_score,
|
|
2164
|
+
rank_message_display: settings["rank_message"],
|
|
2165
|
+
model_type_radio: gr.update(choices=settings["model_choices"], value=settings["model_value"], interactive=settings["model_interactive"]),
|
|
2166
|
+
complexity_slider: gr.update(minimum=1, maximum=settings["complexity_max"], value=settings["complexity_value"]),
|
|
2167
|
+
feature_set_checkbox: gr.update(choices=settings["feature_set_choices"], value=settings["feature_set_value"], interactive=settings["feature_set_interactive"]),
|
|
2168
|
+
data_size_radio: gr.update(choices=settings["data_size_choices"], value=settings["data_size_value"], interactive=settings["data_size_interactive"]),
|
|
2169
|
+
login_username: gr.update(visible=False),
|
|
2170
|
+
login_password: gr.update(visible=False),
|
|
2171
|
+
login_submit: gr.update(visible=False),
|
|
2172
|
+
login_error: gr.update(visible=False),
|
|
2173
|
+
attempts_tracker_display: gr.update(value=_build_attempts_tracker_html(submission_count)),
|
|
2174
|
+
was_preview_state: False,
|
|
2175
|
+
kpi_meta_state: error_kpi_meta,
|
|
2176
|
+
last_seen_ts_state: None
|
|
2177
|
+
}
|
|
2178
|
+
yield error_updates
|
|
2179
|
+
return
|
|
2035
2180
|
|
|
2036
2181
|
try:
|
|
2037
2182
|
# --- Stage 2: Smart Build (Cache vs Train) ---
|
|
@@ -2160,7 +2305,7 @@ def run_experiment(
|
|
|
2160
2305
|
if submission_count >= ATTEMPT_LIMIT:
|
|
2161
2306
|
limit_warning_html = f"""
|
|
2162
2307
|
<div class='kpi-card' style='border-color: #ef4444;'>
|
|
2163
|
-
<h2 style='color: #111827; margin-top:0;'>🛑
|
|
2308
|
+
<h2 style='color: #111827; margin-top:0;'>🛑 Límit d'enviaments assolit</h2>
|
|
2164
2309
|
<div class='kpi-card-body'>
|
|
2165
2310
|
<div class='kpi-metric-box'>
|
|
2166
2311
|
<p class='kpi-label'>Attempts Used</p>
|
|
@@ -2174,10 +2319,10 @@ def run_experiment(
|
|
|
2174
2319
|
settings = compute_rank_settings(submission_count, model_name_key, complexity_level, feature_set, data_size_str)
|
|
2175
2320
|
limit_reached_updates = {
|
|
2176
2321
|
submission_feedback_display: gr.update(value=limit_warning_html, visible=True),
|
|
2177
|
-
submit_button: gr.update(value="🛑
|
|
2322
|
+
submit_button: gr.update(value="🛑 Límit d'enviaments assolit", interactive=False),
|
|
2178
2323
|
model_type_radio: gr.update(interactive=False), complexity_slider: gr.update(interactive=False),
|
|
2179
2324
|
feature_set_checkbox: gr.update(interactive=False), data_size_radio: gr.update(interactive=False),
|
|
2180
|
-
attempts_tracker_display: gr.update(value=f"<div style='text-align:center; padding:8px; margin:8px 0; background:#fef2f2; border-radius:8px; border:1px solid #ef4444;'><p style='margin:0; color:#991b1b; font-weight:600;'>🛑
|
|
2325
|
+
attempts_tracker_display: gr.update(value=f"<div style='text-align:center; padding:8px; margin:8px 0; background:#fef2f2; border-radius:8px; border:1px solid #ef4444;'><p style='margin:0; color:#991b1b; font-weight:600;'>🛑 Intents utilitzats: {ATTEMPT_LIMIT}/{ATTEMPT_LIMIT}</p></div>"),
|
|
2181
2326
|
team_leaderboard_display: team_leaderboard_display, individual_leaderboard_display: individual_leaderboard_display,
|
|
2182
2327
|
last_submission_score_state: last_submission_score, last_rank_state: last_rank,
|
|
2183
2328
|
best_score_state: best_score, submission_count_state: submission_count,
|
|
@@ -2189,9 +2334,9 @@ def run_experiment(
|
|
|
2189
2334
|
yield limit_reached_updates
|
|
2190
2335
|
return
|
|
2191
2336
|
|
|
2192
|
-
progress(0.5, desc="
|
|
2337
|
+
progress(0.5, desc="S'està enviant al núvol...")
|
|
2193
2338
|
yield {
|
|
2194
|
-
submission_feedback_display: gr.update(value=get_status_html(3, "
|
|
2339
|
+
submission_feedback_display: gr.update(value=get_status_html(3, "Enviament en curs", "S'està enviant el model al servidor de la competició..."), visible=True),
|
|
2195
2340
|
login_error: gr.update(visible=False)
|
|
2196
2341
|
}
|
|
2197
2342
|
|
|
@@ -2312,24 +2457,24 @@ def run_experiment(
|
|
|
2312
2457
|
# 1. Append the Limit Warning HTML *below* the Result Card
|
|
2313
2458
|
limit_html = f"""
|
|
2314
2459
|
<div style='margin-top: 16px; border: 2px solid #ef4444; background:#fef2f2; padding:16px; border-radius:12px; text-align:left;'>
|
|
2315
|
-
<h3 style='margin:0 0 8px 0; color:#991b1b;'>🛑
|
|
2460
|
+
<h3 style='margin:0 0 8px 0; color:#991b1b;'>🛑 Límit d'enviaments assolit ({ATTEMPT_LIMIT}/{ATTEMPT_LIMIT})</h3>
|
|
2316
2461
|
<p style='margin:0; color:#7f1d1d; line-height:1.4;'>
|
|
2317
2462
|
<b>You have used all your attempts for this session.</b><br>
|
|
2318
|
-
|
|
2463
|
+
Revisa els teus resultats finals a dalt i després baixa fins a "Finalitzar i reflexionar" per continuar.
|
|
2319
2464
|
</p>
|
|
2320
2465
|
</div>
|
|
2321
2466
|
"""
|
|
2322
2467
|
final_html_display = kpi_card_html + limit_html
|
|
2323
2468
|
|
|
2324
2469
|
# 2. Disable all controls
|
|
2325
|
-
button_update = gr.update(value="🛑
|
|
2470
|
+
button_update = gr.update(value="🛑 Límit assolit", interactive=False)
|
|
2326
2471
|
interactive_state = False
|
|
2327
|
-
tracker_html = f"<div style='text-align:center; padding:8px; margin:8px 0; background:#fef2f2; border-radius:8px; border:1px solid #ef4444;'><p style='margin:0; color:#991b1b; font-weight:600;'>🛑
|
|
2472
|
+
tracker_html = f"<div style='text-align:center; padding:8px; margin:8px 0; background:#fef2f2; border-radius:8px; border:1px solid #ef4444;'><p style='margin:0; color:#991b1b; font-weight:600;'>🛑 Intents utilitzats: {ATTEMPT_LIMIT}/{ATTEMPT_LIMIT} (Max)</p></div>"
|
|
2328
2473
|
|
|
2329
2474
|
else:
|
|
2330
2475
|
# Normal State: Show just the result card and keep controls active
|
|
2331
2476
|
final_html_display = kpi_card_html
|
|
2332
|
-
button_update = gr.update(value="🔬
|
|
2477
|
+
button_update = gr.update(value="🔬 Construir i enviar model", interactive=True)
|
|
2333
2478
|
interactive_state = True
|
|
2334
2479
|
tracker_html = _build_attempts_tracker_html(new_submission_count)
|
|
2335
2480
|
|
|
@@ -2427,14 +2572,14 @@ def on_initial_load(username, token=None, team_name=""):
|
|
|
2427
2572
|
welcome_html = f"""
|
|
2428
2573
|
<div style='text-align:center; padding: 30px 20px;'>
|
|
2429
2574
|
<div style='font-size: 3rem; margin-bottom: 10px;'>👋</div>
|
|
2430
|
-
<h3 style='margin: 0 0 8px 0; color: #111827; font-size: 1.5rem;'>
|
|
2575
|
+
<h3 style='margin: 0 0 8px 0; color: #111827; font-size: 1.5rem;'>Ja formes part de l'equip: <b>{display_team}</b>!</h3>
|
|
2431
2576
|
<p style='font-size: 1.1rem; color: #4b5563; margin: 0 0 20px 0;'>
|
|
2432
|
-
El teu equip
|
|
2577
|
+
El teu equip necessita la teva ajuda per millorar la IA.
|
|
2433
2578
|
</p>
|
|
2434
2579
|
|
|
2435
2580
|
<div style='background:#eff6ff; padding:16px; border-radius:12px; border:2px solid #bfdbfe; display:inline-block;'>
|
|
2436
2581
|
<p style='margin:0; color:#1e40af; font-weight:bold; font-size:1.1rem;'>
|
|
2437
|
-
👈 Fes clic a
|
|
2582
|
+
👈 Fes clic a 'Construir i enviar model' per començar a jugar!
|
|
2438
2583
|
</p>
|
|
2439
2584
|
</div>
|
|
2440
2585
|
</div>
|
|
@@ -2469,7 +2614,7 @@ def on_initial_load(username, token=None, team_name=""):
|
|
|
2469
2614
|
# CASE 1: New User (or first time loading session) -> FORCE WELCOME
|
|
2470
2615
|
# regardless of whether the leaderboard has other people's data.
|
|
2471
2616
|
team_html = welcome_html
|
|
2472
|
-
individual_html = "<p style='text-align:center; color:#6b7280; padding-top:40px;'>
|
|
2617
|
+
individual_html = "<p style='text-align:center; color:#6b7280; padding-top:40px;'>Envia el teu model per veure la teva posició a la classificació!</p>"
|
|
2473
2618
|
|
|
2474
2619
|
elif full_leaderboard_df is None or full_leaderboard_df.empty:
|
|
2475
2620
|
# CASE 2: Returning user, but data fetch failed -> Show Skeleton
|
|
@@ -2487,8 +2632,8 @@ def on_initial_load(username, token=None, team_name=""):
|
|
|
2487
2632
|
)
|
|
2488
2633
|
except Exception as e:
|
|
2489
2634
|
print(f"Error generating summary HTML: {e}")
|
|
2490
|
-
team_html = "<p style='text-align:center; color:red; padding-top:20px;'>
|
|
2491
|
-
individual_html = "<p style='text-align:center; color:red; padding-top:20px;'>
|
|
2635
|
+
team_html = "<p style='text-align:center; color:red; padding-top:20px;'>S'ha produït un error en carregar la classificació.</p>"
|
|
2636
|
+
individual_html = "<p style='text-align:center; color:red; padding-top:20px;'>S'ha produït un error en mostrar la classificació.</p>"
|
|
2492
2637
|
|
|
2493
2638
|
return (
|
|
2494
2639
|
get_model_card(DEFAULT_MODEL),
|
|
@@ -2511,7 +2656,7 @@ def build_final_conclusion_html(best_score, submissions, rank, first_score, feat
|
|
|
2511
2656
|
Colors are handled via CSS classes so that light/dark mode work correctly.
|
|
2512
2657
|
"""
|
|
2513
2658
|
unlocked_tiers = min(3, max(0, submissions - 1)) # 0..3
|
|
2514
|
-
tier_names = ["
|
|
2659
|
+
tier_names = ["En pràctiques", "Júnior", "Sènior", "Principal"]
|
|
2515
2660
|
reached = tier_names[: unlocked_tiers + 1]
|
|
2516
2661
|
tier_line = " → ".join([f"{t}{' ✅' if t in reached else ''}" for t in tier_names])
|
|
2517
2662
|
|
|
@@ -2520,8 +2665,8 @@ def build_final_conclusion_html(best_score, submissions, rank, first_score, feat
|
|
|
2520
2665
|
strong_used = [f for f in feature_set if f in strong_predictors]
|
|
2521
2666
|
|
|
2522
2667
|
ethical_note = (
|
|
2523
|
-
"
|
|
2524
|
-
"
|
|
2668
|
+
"Has desbloquejat predictors molt potents. Reflexiona: eliminant els camps demogràfics canviaria la justícia del model?"
|
|
2669
|
+
"En la següent secció començarem a investigar aquesta qüestió a fons."
|
|
2525
2670
|
)
|
|
2526
2671
|
|
|
2527
2672
|
# Tailor message for very few submissions
|
|
@@ -2529,7 +2674,7 @@ def build_final_conclusion_html(best_score, submissions, rank, first_score, feat
|
|
|
2529
2674
|
if submissions < 2:
|
|
2530
2675
|
tip_html = """
|
|
2531
2676
|
<div class="final-conclusion-tip">
|
|
2532
|
-
<b>Tip:</b>
|
|
2677
|
+
<b>Tip:</b> Prova de fer almenys 2 o 3 enviaments canviant NOMÉS un paràmetre cada vegada per veure clarament la relació causa-efecte.
|
|
2533
2678
|
</div>
|
|
2534
2679
|
"""
|
|
2535
2680
|
|
|
@@ -3438,7 +3583,7 @@ def create_model_building_game_ca_app(theme_primary_hue: str = "indigo") -> "gr.
|
|
|
3438
3583
|
gr.Markdown(
|
|
3439
3584
|
"""
|
|
3440
3585
|
<div style='text-align:center; padding:100px 0;'>
|
|
3441
|
-
<h2 style='font-size:2rem; color:#6b7280;'>⏳
|
|
3586
|
+
<h2 style='font-size:2rem; color:#6b7280;'>⏳ Carregant...</h2>
|
|
3442
3587
|
</div>
|
|
3443
3588
|
"""
|
|
3444
3589
|
)
|