fix: коэффициенты времени суток по методичке ПСО «Экстремум» (§12.3.3, §12.3.5)
Сверка с методикой ПСР ред. 12.17 (Евдокимов, Лейтес): - ночь: 0.5 → 0.0 — методичка §12.3.5 прямо даёт «ночь = 0 км»: без фонаря в лесу ночью пострадавший не перемещается. Ранее 0.5 ЗАВЫШАЛО радиус ночного поиска. - сумерки/вечер: 0.7 → 0.5 — «за час до заката скорость 50% от обычной». B5 переносил 0.7 из старого фронта вопреки методичке. - get_base_speed: документирована семантика «скорость смещения» (не асфальтовая НормС из §12.3.2) — оператору не нужно вводить асфальтовую скорость, она уже свёрнута; СП = поправка конкретной местности поверх базового среднего леса. Тесты обновлены под методичку, добавлен тест ночи = 0. 201 passed, 0 failed.
This commit is contained in:
@@ -85,8 +85,9 @@ class TestCalculateMaxDistance:
|
||||
|
||||
distance = calculate_max_distance(case_data)
|
||||
|
||||
# 3 * 1.5 * 0.2 * 0.85 * 0.5 * 0.7 = 0.27 km
|
||||
assert distance == pytest.approx(0.27, rel=0.01)
|
||||
# 3 * 1.5 * 0.2 * 0.85 * 0.0(ночь) * 0.7 = 0.0 км —
|
||||
# методичка §12.3.5: без фонаря ночью движение = 0
|
||||
assert distance == pytest.approx(0.0, rel=0.01)
|
||||
|
||||
def test_adult_heavy_rain_field(self):
|
||||
"""Test for adult in heavy rain on field."""
|
||||
@@ -193,12 +194,13 @@ class TestTimeOfDayCoefficient:
|
||||
assert get_time_of_day_coefficient('день') == 1.0
|
||||
|
||||
def test_night(self):
|
||||
assert get_time_of_day_coefficient('ночь') == 0.5
|
||||
# Методичка §12.3.5: ночь = 0 (без фонаря движение прекращается)
|
||||
assert get_time_of_day_coefficient('ночь') == 0.0
|
||||
|
||||
def test_twilight(self):
|
||||
# B5: сумерки/вечер = 0.7 (было 0.5 — канон фронта)
|
||||
assert get_time_of_day_coefficient('сумерки') == 0.7
|
||||
assert get_time_of_day_coefficient('вечер') == 0.7
|
||||
# Методичка §12.3.3: за час до заката скорость 50% от обычной
|
||||
assert get_time_of_day_coefficient('сумерки') == 0.5
|
||||
assert get_time_of_day_coefficient('вечер') == 0.5
|
||||
|
||||
|
||||
class TestWeatherCoefficient:
|
||||
|
||||
@@ -82,15 +82,25 @@ def get_base_speed(age: int) -> float:
|
||||
"""
|
||||
Get base movement speed by age (НормС).
|
||||
|
||||
ВАЖНО (семантика): в ВЕКТОРе это НЕ «нормальная скорость по асфальту»
|
||||
из методички ПСО (§12.3.2, стандарт 5 км/ч), а уже готовая скорость
|
||||
СМЕЩЕНИЯ потерявшегося по лесу: НормС_асфальт × СП, усреднённое
|
||||
с учётом кружения/остановок/испуга. Канон перенесён из фронтового
|
||||
расчёта (B5, 3e2692f) и согласован с априорами ПСО «Экстремум»:
|
||||
400 случаев 2015 г., 94% найдены в пределах 3 км.
|
||||
|
||||
Следствие: в формуле ВЕКТОРА коэффициент СП применяется ПОВЕРХ этих
|
||||
значений как поправка конкретной местности (густой лес < простой лес),
|
||||
поэтому СП = 1.0 соответствует «среднему лесу», а не асфальту.
|
||||
Оператору НЕ нужно вводить асфальтовую скорость — она уже свёрнута.
|
||||
|
||||
Args:
|
||||
age: Age in years
|
||||
|
||||
Returns:
|
||||
Base speed in km/h
|
||||
Base displacement speed in km/h
|
||||
"""
|
||||
# Скорость смещения потерявшегося ребёнка (не скорость ходьбы)
|
||||
# ПСО ЭКСТРЕМУМ: 94% найдены в пределах 3 км
|
||||
# Скорость смещения потерявшегося ребёнка (не скорость ходьбы).
|
||||
# Скорость смещения потерявшегося (не скорость ходьбы).
|
||||
# Реальное смещение: испуг, кружение, остановки. Основа — ПСО ЭКСТРЕМУМ
|
||||
# (400 случаев, 94% найдены в пределах 3 км). Значения перенесены из
|
||||
# фронтендового расчёта как каноничные (согласовано с методологией).
|
||||
@@ -203,10 +213,16 @@ def get_transport_coefficient(has_transport) -> float:
|
||||
|
||||
def get_time_of_day_coefficient(time_of_day: str) -> float:
|
||||
"""
|
||||
Get time of day movement coefficient (ВВС).
|
||||
ВВС — влияние времени суток (методичка ПСО «Экстремум» §12.3.3).
|
||||
|
||||
- день: 1.0
|
||||
- сумерки/вечер: 0.5 («за час до заката скорость 50% от обычной»)
|
||||
- ночь: 0.0 — в примере §12.3.5 этап «ночь» даёт 0 км движения:
|
||||
без фонаря в лесу ночью пострадавший не перемещается.
|
||||
(Свет/фонарь/Луна — редкий случай, учитывается оператором вручную.)
|
||||
|
||||
Args:
|
||||
time_of_day: Time of day
|
||||
time_of_day: 'день' | 'сумерки' | 'вечер' | 'ночь'
|
||||
|
||||
Returns:
|
||||
Time coefficient (0.0 - 1.0)
|
||||
@@ -216,9 +232,9 @@ def get_time_of_day_coefficient(time_of_day: str) -> float:
|
||||
time_lower = time_of_day.lower()
|
||||
|
||||
if 'ночь' in time_lower:
|
||||
return 0.5
|
||||
return 0.0
|
||||
elif 'сумерки' in time_lower or 'вечер' in time_lower:
|
||||
return 0.7
|
||||
return 0.5
|
||||
else: # день
|
||||
return 1.0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user