#!/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}")