Урок 003: строки, нормализация и поиск¶
Цель¶
Приводить пользовательский текст к предсказуемому виду, сравнивать артикулы и выполнять поиск по части названия.
Строки неизменяемы¶
Методы строки возвращают новое значение:
raw_name = " Лоток Перфорированный "
clean_name = raw_name.strip()
print(raw_name)
print(clean_name)
strip() удаляет пробельные символы по краям, но не меняет исходную строку. Результат нужно сохранить или сразу передать дальше.
Полезные методы:
| Метод | Назначение |
|---|---|
strip() |
убрать пробелы по краям |
lower() |
перевести буквы в нижний регистр |
casefold() |
подготовить Unicode-текст к регистронезависимому сравнению |
upper() |
перевести буквы в верхний регистр |
replace(old, new) |
заменить фрагмент |
split(separator) |
разбить строку на список |
separator.join(parts) |
соединить строки |
startswith(prefix) |
проверить начало строки |
Нормализация артикула¶
Пользователь может ввести один артикул как lo 100, LO100 или Lo-100. Правило нормализации должно быть явным и не уничтожать значимые символы.
def normalize_article(value):
return "".join(value.split()).upper()
print(normalize_article(" lo 100 "))
print(normalize_article("Lo-100"))
Ожидается LO100 и LO-100. split() без аргумента учитывает обычные пробелы, табуляцию и другие пробельные символы, а join соединяет оставшиеся части. Дефис сохранён, потому что без знания каталога нельзя считать его незначимым.
Сохраните функцию в string_lab.py. Последующий пример разбора строки вызывает normalize_article из этого же файла; при отдельном запуске перенесите определение функции вместе с примером.
Нормализация не доказывает существование артикула. Она лишь делает одинаковые варианты ввода сравнимыми.
Поиск по названию¶
query = "ЛОТОК".strip().casefold()
name = "Лоток перфорированный".casefold()
if query in name:
print("Совпадение найдено")
casefold() надёжнее lower() для регистронезависимого сравнения Unicode. Для русского текста оба часто дают одинаковый результат, но намерение casefold точнее.
Пустой запрос содержится в любой строке. Поэтому его нужно отклонить до поиска:
query = input("Фрагмент названия: ").strip().casefold()
if query == "":
print("Ошибка: запрос не может быть пустым")
Разбор строки¶
raw_line = "LO100;Лоток;3"
parts = raw_line.split(";")
if len(parts) == 3:
article = normalize_article(parts[0])
name = parts[1].strip()
quantity = int(parts[2])
Ручной split полезен для упражнения, но не заменяет модуль csv: кавычки, разделители внутри полей и переносы строк требуют стандартного парсера. Это будет темой следующего модуля.
Формирование вывода¶
Ожидаемый вывод: LO100 | Лоток | 3 шт.. Метод join принимает строки; число сначала нужно преобразовать или отформатировать.
Упражнение¶
Напишите normalize_article и matches_name(name, query). Проверьте артикулы с пробелами и разным регистром, названия Лоток перфорированный, Кабель силовой, Шкаф распределительный и запросы лоток, СИЛ, шкаф, пустую строку.
Самопроверка¶
- Почему
strip()не меняет исходную строку? - Какие символы нормализация артикула удаляет, а какие сохраняет?
- Почему пустой запрос нужно проверять отдельно?
- Почему
split(";")ещё не является полноценным чтением CSV?