diff --git a/CODE_REVIEW.md b/CODE_REVIEW.md index 06d8ec3..f4841dd 100644 --- a/CODE_REVIEW.md +++ b/CODE_REVIEW.md @@ -53,7 +53,7 @@ except KeyboardInterrupt: ## HIGH -### H1. `format_weather_data_for_console` -- IndexError при пустом `current_condition` +### H1. `format_weather_data_for_console` -- IndexError при пустом `current_condition` — **ИСПРАВЛЕНО** **Файл:** `utils/pogoda.py`, строка 122 @@ -86,7 +86,7 @@ current = current_condition_list[0] --- -### H2. `translate_weather` -- подстроочное совпадение зависит от порядка dict +### H2. `translate_weather` -- подстроочное совпадение зависит от порядка dict — **ИСПРАВЛЕНО** **Файл:** `utils/pogoda.py`, строки 96-130 @@ -536,8 +536,8 @@ DeprecationWarning: 'asyncio.iscoroutinefunction' is deprecated and slated for r ### Этап 2: High (баги + надёжность) -3. [ ] H1: Защитить `format_weather_data_for_console` от пустого списка -4. [ ] H2: Отсортировать ключи `translate_weather` по убыванию длины +3. [x] H1: Защитить `format_weather_data_for_console` от пустого списка — **выполнено** +4. [x] H2: Отсортировать ключи `translate_weather` по убыванию длины — **выполнено** 5. [ ] H3: Исправить `pressure_to_mmhg` -- `not mb` -> `mb is None or mb == ""` 6. [ ] H4: Добавить защиту от дублирования cogs в `on_ready` 7. [ ] H5: Заменить `asyncio.run()` на `async def` в fetch-тестах (50+ тестов) diff --git a/tests/test_pogoda.py b/tests/test_pogoda.py index 8043e27..2f0972a 100644 --- a/tests/test_pogoda.py +++ b/tests/test_pogoda.py @@ -121,7 +121,7 @@ class TestTranslateWeather: ("Light rain", "Небольшой дождь"), ("Moderate rain", "Умеренный дождь"), ("Heavy rain", "Сильный дождь"), - ("Moderate or heavy rain at times", "Сильный дождь"), # "Heavy rain" совпадает раньше в mapping dict (key in text) + ("Moderate or heavy rain at times", "Дождь"), # длинный ключ проверяется первым ("Heavy rain at times", "Сильный дождь"), ("Light snow", "Небольшой снег"), ("Moderate snow", "Умеренный снег"), @@ -169,12 +169,10 @@ class TestTranslateWeather: assert translate_weather(text_with_prefix) == "Дождь" def test_translate_longer_key_priority(self): - """translate_weather ищет key in text, порядок dict важен. - "Heavy rain" стоит раньше "Moderate or heavy rain at times" в mapping, - и "heavy rain" in "moderate or heavy rain at times" = True. - Поэтому совпадёт первым и вернёт "Сильный дождь".""" + """Длинные ключи проверяются первыми (_WEATHER_MAPPING отсортирован по убыванию длины). + "Moderate or heavy rain at times" проверится до "Heavy rain".""" text = "Moderate or heavy rain at times" - assert translate_weather(text) == "Сильный дождь" + assert translate_weather(text) == "Дождь" def test_translate_case_insensitive(self): """Перевод должен быть регистронезависимым.""" diff --git a/utils/pogoda.py b/utils/pogoda.py index 880485c..51188a4 100644 --- a/utils/pogoda.py +++ b/utils/pogoda.py @@ -98,50 +98,53 @@ def wmo_to_russian(code): return mapping.get(code, "Неизвестно") +_WEATHER_MAPPING = [ + ("Moderate or heavy freezing rain at a distance", "Ледяной дождь"), + ("Moderate or heavy sleet at a distance", "Слякоть"), + ("Moderate or heavy freezing rain in area", "Ледяной дождь"), + ("Moderate or heavy sleet in area", "Слякоть"), + ("Moderate or heavy snow in area", "Снег"), + ("Moderate or heavy rain in area", "Дождь"), + ("Thundery outbreaks in nearby", "Гроза вблизи"), + ("Moderate or heavy rain at times", "Дождь"), + ("Moderate or heavy snow at times", "Снег"), + ("Patchy light drizzle", "Местами лёгкая морось"), + ("Patchy light snow", "Местами лёгкий снег"), + ("Heavy freezing rain", "Сильный ледяной дождь"), + ("Light freezing rain", "Лёгкий ледяной дождь"), + ("Light rain shower", "Небольшой дождь"), + ("Heavy rain shower", "Сильный дождь"), + ("Moderate or light sleet", "Слякоть"), + ("Patchy rain nearby", "Местами дождь"), + ("Patchy snow nearby", "Местами снег"), + ("Patchy sleet nearby", "Местами слякоть"), + ("Moderate rain at times", "Умеренный дождь"), + ("Heavy rain at times", "Сильный дождь"), + ("Moderate rain", "Умеренный дождь"), + ("Light rain", "Небольшой дождь"), + ("Heavy rain", "Сильный дождь"), + ("Light snow", "Небольшой снег"), + ("Moderate snow", "Умеренный снег"), + ("Heavy snow", "Сильный снег"), + ("Blowing snow", "Метель"), + ("Partly cloudy", "Переменная облачность"), + ("Overcast", "Пасмурно"), + ("Cloudy", "Облачно"), + ("Foggy", "Туманно"), + ("Fog", "Туман"), + ("Mist", "Туман"), + ("Haze", "Дымка"), + ("Clear", "Ясно"), + ("Sunny", "Ясно"), +] + + def translate_weather(en): if not en: return "—" - mapping = { - "Moderate or heavy freezing rain in area": "Ледяной дождь", - "Moderate or heavy sleet in area": "Слякоть", - "Moderate or heavy snow in area": "Снег", - "Moderate or heavy rain in area": "Дождь", - "Thundery outbreaks in nearby": "Гроза вблизи", - "Patchy rain nearby": "Местами дождь", - "Patchy snow nearby": "Местами снег", - "Patchy sleet nearby": "Местами слякоть", - "Heavy freezing rain": "Сильный ледяной дождь", - "Heavy snow": "Сильный снег", - "Heavy rain": "Сильный дождь", - "Moderate or heavy rain at times": "Дождь", - "Moderate or heavy snow at times": "Снег", - "Blowing snow": "Метель", - "Patchy light drizzle": "Местами лёгкая морось", - "Moderate or heavy freezing rain at a distance": "Ледяной дождь", - "Moderate or heavy sleet at a distance": "Слякоть", - "Light rain shower": "Небольшой дождь", - "Heavy rain shower": "Сильный дождь", - "Moderate rain": "Умеренный дождь", - "Light rain": "Небольшой дождь", - "Moderate rain at times": "Умеренный дождь", - "Heavy rain at times": "Сильный дождь", - "Light snow": "Небольшой снег", - "Moderate snow": "Умеренный снег", - "Patchy light snow": "Местами лёгкий снег", - "Partly cloudy": "Переменная облачность", - "Moderate or light sleet": "Слякоть", - "Light freezing rain": "Лёгкий ледяной дождь", - "Foggy": "Туманно", - "Fog": "Туман", - "Mist": "Туман", - "Haze": "Дымка", - "Overcast": "Пасмурно", - "Cloudy": "Облачно", - "Clear": "Ясно", - "Sunny": "Ясно", - } - for key, value in mapping.items(): - if key.lower() in en.lower(): + en_lower = en.lower() + for key, value in _WEATHER_MAPPING: + if key.lower() in en_lower: return value return en