Files
loogle-scripts/services/telegram-bot/test_previsione7_interpretation.py
T

120 lines
4.3 KiB
Python

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