piano: il codice sta nel repo, non anche nel piano
This commit is contained in:
@@ -10,3 +10,6 @@ assets-src/
|
|||||||
|
|
||||||
# Artefatti di lavoro dei subagenti (ledger, brief, review package)
|
# Artefatti di lavoro dei subagenti (ledger, brief, review package)
|
||||||
.superpowers/
|
.superpowers/
|
||||||
|
|
||||||
|
# Cache di Python generata rieseguendo l'oracolo
|
||||||
|
__pycache__/
|
||||||
|
|||||||
@@ -69,141 +69,27 @@ Prima di portare una sola curva, serve il metro di paragone.
|
|||||||
|
|
||||||
- [ ] **Step 1: Scrivi il generatore**
|
- [ ] **Step 1: Scrivi il generatore**
|
||||||
|
|
||||||
```python
|
⚠️ **Questo passo è già stato eseguito.** La griglia definitiva vive in
|
||||||
#!/usr/bin/env python3
|
`tests/longevity/riferimento/genera-riferimento.py`, committata e verificata: rieseguirla
|
||||||
"""
|
riproduce `riferimento.json` byte per byte (4018 casi, 25 funzioni, nessuna eccezione).
|
||||||
Esegue il motore del cliente su una griglia fitta di ingressi e scrive i risultati
|
|
||||||
in riferimento.json. È il metro contro cui si misura il porting in TypeScript:
|
|
||||||
non serve a provare che l'oracolo è giusto, ma che il nostro porting gli è fedele.
|
|
||||||
|
|
||||||
Uso: python3 tests/longevity/riferimento/genera-riferimento.py
|
Qui **non** ne teniamo una seconda copia, e la ragione è un incidente vero: quando il piano
|
||||||
"""
|
conteneva anche il codice, piano e script sono divergiti — il file di riferimento è rimasto
|
||||||
import json
|
per un momento non riproducibile dal proprio generatore, che per un oracolo è il difetto
|
||||||
import pathlib
|
peggiore possibile. Due copie della stessa cosa si separano sempre; il codice sta nel repo,
|
||||||
import sys
|
il piano dice cosa deve fare e perché.
|
||||||
|
|
||||||
QUI = pathlib.Path(__file__).parent
|
**Cosa la griglia copre**, che è ciò che va verificato se un domani si tocca:
|
||||||
sys.path.insert(0, str(QUI))
|
|
||||||
|
|
||||||
import isl_scoring_engine as m
|
- le curve del questionario su **tutto** il dominio, non su un campione, comprese le due
|
||||||
|
coppie di parametri di `score_decreasing` — quella normale e quella dell'alcol (7→14);
|
||||||
casi = []
|
- `score_increasing_plateau` con `worst` **diverso da zero**: zero è il caso degenere in
|
||||||
|
cui un errore sull'offset resterebbe invisibile;
|
||||||
|
- `vo2max_from_2km_walk` variando **un parametro alla volta** dal caso base, così una
|
||||||
def prova(fn_nome, *args):
|
divergenza dice anche quale dei cinque coefficienti è sbagliato;
|
||||||
"""Esegue una funzione dell'oracolo e registra ingressi e uscita."""
|
- i confini di banda **esatti** delle funzioni a bande (composizione, pressione, plank,
|
||||||
fn = getattr(m, fn_nome)
|
flamingo, SpO2), che una griglia a passo regolare salterebbe;
|
||||||
casi.append({"fn": fn_nome, "args": list(args), "atteso": fn(*args)})
|
- le tre tabelle dei sollevamenti sul rapporto col peso corporeo, per entrambi i sessi.
|
||||||
|
|
||||||
|
|
||||||
def griglia(inizio, fine, passo):
|
|
||||||
"""Valori da inizio a fine compreso, con arrotondamento pulito."""
|
|
||||||
n, v = [], inizio
|
|
||||||
while v <= fine + 1e-9:
|
|
||||||
n.append(round(v, 4))
|
|
||||||
v += passo
|
|
||||||
return n
|
|
||||||
|
|
||||||
|
|
||||||
# --- curve generiche del questionario: tutto il dominio, non un campione ---
|
|
||||||
for v in griglia(0, 14, 0.5):
|
|
||||||
prova("score_bell_curve", v, 4, 7, 9, 12) # q_ore_sonno
|
|
||||||
prova("score_decreasing", v, 0, 7) # q_caffeina e gemelle
|
|
||||||
prova("score_decreasing", v, 7, 14) # q_alcol_life: la soglia voluta
|
|
||||||
for v in griglia(0, 10, 0.5):
|
|
||||||
prova("score_direct_x10", v)
|
|
||||||
for v in griglia(0, 7, 0.5):
|
|
||||||
prova("score_increasing_plateau", v, 0, 4)
|
|
||||||
|
|
||||||
# --- le tre aggiunte che chiudono i buchi di copertura ---
|
|
||||||
# ⚠️ `worst` va variato: con `worst` sempre a 0 un errore sull'offset resta invisibile
|
|
||||||
for v in griglia(0, 7, 0.5):
|
|
||||||
prova("score_increasing_plateau", v, 2, 6)
|
|
||||||
|
|
||||||
# ⚠️ formula a cinque coefficienti: un parametro alla volta, per sapere QUALE diverge
|
|
||||||
for t in (10, 15.5, 20, 25):
|
|
||||||
prova("vo2max_from_2km_walk", t, 130, 40, 24)
|
|
||||||
for hr in (100, 115, 130, 145, 160):
|
|
||||||
prova("vo2max_from_2km_walk", 15.5, hr, 40, 24)
|
|
||||||
for eta in (20, 40, 60, 75):
|
|
||||||
prova("vo2max_from_2km_walk", 15.5, 130, eta, 24)
|
|
||||||
for bmi in (18, 22, 26, 32):
|
|
||||||
prova("vo2max_from_2km_walk", 15.5, 130, 40, bmi)
|
|
||||||
|
|
||||||
# i confini di banda esatti del plank: la curva è continua, ma costano nulla
|
|
||||||
for sesso, confini in (("M", (79, 97, 122, 157, 201)), ("F", (35, 63, 84, 108, 142))):
|
|
||||||
for v in confini:
|
|
||||||
prova("score_plank", v, sesso)
|
|
||||||
|
|
||||||
# --- composizione corporea: attorno ai confini delle bande ---
|
|
||||||
for sesso in ("M", "F"):
|
|
||||||
for v in griglia(0, 45, 0.5):
|
|
||||||
prova("score_fat_percent", v, sesso)
|
|
||||||
for v in griglia(20, 60, 0.5):
|
|
||||||
prova("score_muscle_percent", v, sesso)
|
|
||||||
for v in griglia(0.5, 1.3, 0.01):
|
|
||||||
prova("score_whr", v, sesso)
|
|
||||||
|
|
||||||
# --- cardio ---
|
|
||||||
for v in griglia(85, 100, 1):
|
|
||||||
prova("score_spo2", v)
|
|
||||||
for sbp in griglia(90, 200, 5):
|
|
||||||
for dbp in griglia(50, 120, 5):
|
|
||||||
prova("score_blood_pressure", sbp, dbp)
|
|
||||||
for v in griglia(0, 40, 1):
|
|
||||||
prova("score_hrr", v)
|
|
||||||
for sesso in ("M", "F"):
|
|
||||||
for eta in griglia(20, 75, 5):
|
|
||||||
for v in griglia(15, 70, 2.5):
|
|
||||||
prova("score_vo2max", v, eta, sesso)
|
|
||||||
for v in griglia(120, 200, 5):
|
|
||||||
prova("vo2max_from_step_test", v, "M")
|
|
||||||
prova("vo2max_from_step_test", v, "F")
|
|
||||||
for v in griglia(100, 300, 10):
|
|
||||||
prova("vo2max_from_mutt", v)
|
|
||||||
for w in griglia(50, 200, 10):
|
|
||||||
prova("vo2max_from_milfit", w, 75)
|
|
||||||
prova("vo2max_from_2km_walk", 15.5, 130, 40, 24)
|
|
||||||
|
|
||||||
# --- forza ---
|
|
||||||
for sesso in ("M", "F"):
|
|
||||||
for eta in griglia(25, 75, 5):
|
|
||||||
for v in griglia(10, 70, 2.5):
|
|
||||||
prova("score_handgrip", v, eta, sesso)
|
|
||||||
for v in griglia(0, 60, 2):
|
|
||||||
prova("score_pushup", v, eta, sesso)
|
|
||||||
for v in griglia(0, 250, 5):
|
|
||||||
prova("score_plank", v, sesso)
|
|
||||||
for v in griglia(0, 120, 5):
|
|
||||||
prova("score_flexed_arm_hang", v, sesso)
|
|
||||||
for v in griglia(0, 60, 2):
|
|
||||||
prova("score_sit_to_stand_1min", v, 40, sesso)
|
|
||||||
for v in griglia(-30, 30, 1):
|
|
||||||
prova("score_sit_and_reach", v, sesso)
|
|
||||||
for eta in griglia(25, 75, 5):
|
|
||||||
for v in griglia(-30, 20, 2):
|
|
||||||
prova("score_back_scratch", v, eta, sesso)
|
|
||||||
|
|
||||||
# --- sollevamenti sui rapporti col peso corporeo ---
|
|
||||||
for sesso in ("M", "F"):
|
|
||||||
for carico in griglia(20, 200, 10):
|
|
||||||
prova("score_bw_ratio_lift", carico, 80, 5, m.TIERS_BENCH_M, m.TIERS_BENCH_F, sesso)
|
|
||||||
prova("score_bw_ratio_lift", carico, 80, 5, m.TIERS_SQUAT_M, m.TIERS_SQUAT_F, sesso)
|
|
||||||
prova("score_bw_ratio_lift", carico, 80, 5, m.TIERS_ROW_M, m.TIERS_ROW_F, sesso)
|
|
||||||
|
|
||||||
# --- stabilità ---
|
|
||||||
for v in griglia(0, 30, 1):
|
|
||||||
prova("score_flamingo", v)
|
|
||||||
for a in griglia(0, 180, 10):
|
|
||||||
prova("score_shoulder_mobility_wt", a, a)
|
|
||||||
|
|
||||||
uscita = QUI / "riferimento.json"
|
|
||||||
uscita.write_text(json.dumps(
|
|
||||||
{"generato_da": "isl_scoring_engine.py", "casi": casi},
|
|
||||||
indent=1, ensure_ascii=False,
|
|
||||||
))
|
|
||||||
print(f"{len(casi)} casi scritti in {uscita}")
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 2: Eseguilo e guarda l'esito**
|
- [ ] **Step 2: Eseguilo e guarda l'esito**
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user