Files
InsanityLab-web/tests/longevity/riferimento/genera-riferimento.py
T

128 lines
4.7 KiB
Python

#!/usr/bin/env python3
"""
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
"""
import json
import pathlib
import sys
QUI = pathlib.Path(__file__).parent
sys.path.insert(0, str(QUI))
import isl_scoring_engine as m
casi = []
def prova(fn_nome, *args):
"""Esegue una funzione dell'oracolo e registra ingressi e uscita."""
fn = getattr(m, fn_nome)
casi.append({"fn": fn_nome, "args": list(args), "atteso": fn(*args)})
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)
prova("score_increasing_plateau", v, 2, 6) # worst != 0: l'offset e' l'unico parametro a rischio refuso
# --- 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)
# caso base + variazione di un parametro alla volta: un punto solo non separa i 5 coefficienti
BASE_2KM = (15.5, 130, 40, 24) # tempo_min, hr, eta, bmi
prova("vo2max_from_2km_walk", *BASE_2KM)
for tempo in griglia(10, 25, 2.5):
prova("vo2max_from_2km_walk", tempo, BASE_2KM[1], BASE_2KM[2], BASE_2KM[3])
for hr in griglia(100, 160, 10):
prova("vo2max_from_2km_walk", BASE_2KM[0], hr, BASE_2KM[2], BASE_2KM[3])
for eta in griglia(20, 75, 5):
prova("vo2max_from_2km_walk", BASE_2KM[0], BASE_2KM[1], eta, BASE_2KM[3])
for bmi in griglia(18, 32, 2):
prova("vo2max_from_2km_walk", BASE_2KM[0], BASE_2KM[1], BASE_2KM[2], bmi)
# --- 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)
confini_plank = [79, 97, 122, 157, 201] if sesso == "M" else [35, 63, 84, 108, 142]
for v in confini_plank: # confini esatti delle bande: costano zero, tolgono ogni dubbio
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}")