# -*- coding: utf-8 -*- """ Конвертер раскладки клавиатуры: определяет, в какой раскладке (русской или английской) набран текст, и при необходимости переключает её. Используется для исправления сообщений, набранных по ошибке не в той раскладке. """ import logging logger = logging.getLogger(__name__) def convert_layout(text: str) -> str: """ Определяет, в какой раскладке набран текст, и переключает, если нужно. Команды (начинающиеся с ! или /) и ссылки (http://) не трогает. Алгоритм: 1. Если текст начинается с http://, https://, ! или / – возвращается без изменений. 2. Составляем таблицы перевода: английские символы -> русские и наоборот. 3. Если в тексте есть и русские, и английские символы – считаем, что всё правильно (не переключаем). 4. Считаем количество гласных букв в английской и русской раскладках для исходного текста и для его переведённых вариантов. 5. Выбираем вариант с наибольшим количеством гласных (вероятная правильная раскладка). 6. Если гласных поровну или нет ни одной, возвращаем исходный текст. """ if not text: return text # Не трогаем команды и ссылки if text.startswith('http') or text.startswith(('!', '/')): return text # Таблицы соответствия символов (раскладка QWERTY / ЙЦУКЕН) en_chars = "qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?~" ru_chars = "йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,Ё" to_ru = str.maketrans(en_chars, ru_chars) # таблица для перевода английской раскладки в русскую to_en = str.maketrans(ru_chars, en_chars) # таблица для перевода русской раскладки в английскую # Проверяем, есть ли символы обеих раскладок в тексте has_russian = any('а' <= c <= 'я' or 'А' <= c <= 'Я' for c in text) has_english = any('a' <= c <= 'z' or 'A' <= c <= 'Z' for c in text) if has_russian and has_english: # Смесь – вероятно, уже правильно return text # Гласные буквы для подсчёта (в английской и русской раскладках) eng_vowels = "aeiouyAEIOUY" ru_vowels = "аеёиоуыэюяАЕЁИОУЫЭЮЯ" orig_en_vowels = sum(1 for c in text if c in eng_vowels) orig_ru_vowels = sum(1 for c in text if c in ru_vowels) # Переводим текст в другую раскладку translated_en = text.translate(to_en) # русская -> английская translated_ru = text.translate(to_ru) # английская -> русская trans_en_vowels = sum(1 for c in translated_en if c in eng_vowels) trans_ru_vowels = sum(1 for c in translated_ru if c in ru_vowels) # Если в исходном тексте нет русских символов, но при переводе в русскую раскладку # появляется больше гласных, значит, текст был набран в английской раскладке. if not has_russian and trans_ru_vowels > orig_en_vowels: return translated_ru # Если в исходном тексте нет английских символов, но при переводе в английскую раскладку # появляется больше гласных, значит, текст был набран в русской раскладке. if has_russian and trans_en_vowels > orig_ru_vowels: return translated_en return text