#!/usr/bin/env python3 """Regression checks for Meteo7 interpretation (weathercode mode, ice gates, hours, trend max/min).""" import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) from previsione7 import ( _merge_weathercode, _format_event_hours, analyze_daily_events, analyze_temperature_trend, format_detailed_trend_explanation, get_precip_type, ) def test_weathercode_mode_not_median(): # 61 (rain) + 71 (snow) → mediana numerica sarebbe 66 (FZRA); moda deve evitare 66 assert _merge_weathercode([61, 71], preferred=61) == 61 assert _merge_weathercode([61, 71], preferred=71) == 71 assert _merge_weathercode([61, 61, 71]) == 61 assert _merge_weathercode([66, 66, 61]) == 66 print("OK weathercode mode") def test_get_precip_type_temp_gate(): assert "Congelantesi" not in get_precip_type(67, temp=28.0) assert "Pioggia" in get_precip_type(67, temp=28.0) assert "Congelantesi" in get_precip_type(67, temp=0.5) assert "Neve" not in get_precip_type(71, temp=20.0) assert "Neve" in get_precip_type(71, temp=-1.0) print("OK precip type temp gate") def test_gelicidio_hot_air_no_event(): times = [f"2026-07-21T{h:02d}:00" for h in range(24)] codes = [0] * 24 codes[20] = 67 # FZRA spurio precip = [0.0] * 24 precip[20] = 1.2 temps = [28.0] * 24 dewpoints = [18.0] * 24 winds = [5.0] * 24 events = analyze_daily_events( times, codes, None, precip, winds, temps, dewpoints, snowfalls=[0.0] * 24, rains=precip[:], soil_temps=[25.0] * 24, cloud_covers=[50.0] * 24, wind_speeds=winds, ) ice_like = [e for e in events if "GELICIDIO" in e or "BRINA" in e or "Gelata" in e or "Black Ice" in e] assert not ice_like, f"unexpected ice events in heat: {ice_like}" rain_like = [e for e in events if "Pioggia" in e or "Congelantesi" in e] assert rain_like, "expected rain event" assert all("Congelantesi" not in e for e in rain_like) print("OK no gelicidio at 28°C") def test_single_hour_event_range(): times = [f"2026-07-21T{h:02d}:00" for h in range(24)] assert _format_event_hours(times, 20, 20) == "20:00-21:00" assert _format_event_hours(times, 20, 21) == "20:00-22:00" # last hour of day assert _format_event_hours(times, 23, 23) == "23:00-00:00" codes = [0] * 24 precip = [0.0] * 24 precip[20] = 2.0 temps = [22.0] * 24 events = analyze_daily_events( times, codes, None, precip, [5.0] * 24, temps, [12.0] * 24, snowfalls=[0.0] * 24, rains=precip[:], ) rain_ev = [e for e in events if "🕒" in e] assert rain_ev, events assert "20:00-21:00" in rain_ev[0] assert "20:00-20:00" not in rain_ev[0] print("OK single-hour 20:00-21:00") def test_trend_max_min_not_media(): # Heatwave: max stay high, slight drop → calo_termico not fronte_freddo tmax = [34, 35, 36, 33, 30, 29, 28, 27, 26, 25] tmin = [22, 23, 24, 21, 20, 19, 18, 17, 16, 15] trend = analyze_temperature_trend(tmax, tmin, days=10) assert trend is not None assert "first_max" in trend and "first_min" in trend assert trend["type"] == "calo_termico" text = format_detailed_trend_explanation(trend, daily_time_list=[f"2026-07-{21+i:02d}" for i in range(10)]) assert "media" not in text.lower() assert "Massime:" in text and "Minime:" in text assert "Fronte Freddo" not in text print("OK trend max/min calo_termico") def test_real_gelicidio_cold(): times = [f"2026-01-10T{h:02d}:00" for h in range(24)] codes = [0] * 24 codes[8] = 67 precip = [0.0] * 24 precip[8] = 0.5 temps = [5.0] * 24 temps[8] = -0.5 events = analyze_daily_events( times, codes, None, precip, [3.0] * 24, temps, [-1.0] * 24, snowfalls=[0.0] * 24, rains=precip[:], soil_temps=[-1.0] * 24, cloud_covers=[80.0] * 24, wind_speeds=[3.0] * 24, ) assert any("GELICIDIO" in e for e in events), events print("OK real gelicidio at subzero") if __name__ == "__main__": test_weathercode_mode_not_median() test_get_precip_type_temp_gate() test_gelicidio_hot_air_no_event() test_single_hour_event_range() test_trend_max_min_not_media() test_real_gelicidio_cold() print("\nAll interpretation regression checks passed.")