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