При регистрации в различных сервисах пользователи вводят большое количество информации. Правильное заполнение полей — важная часть работы программы, поэтому формы снабжают системами валидации данных.
Напишите функцию name_validation
, которая принимает один позиционный аргумент — фамилию или имя.
Если параметр не является строкой, то вызовите исключение TypeError
.
А также разработайте собственные ошибки:
CyrillicError
— вызывается, если значение не состоит только из кириллических букв;CapitalError
— вызывается, если значение не начинается с заглавной буквы или найдена заглавная буква не в начале значения.
Обработка ошибок должна происходить в порядке, указанном в задании.
В случае успешного выполнения, функция должна вернуть переданный параметр без изменений.
Примечание
В решении не должно быть вызовов требуемых функций.
Пример
Ввод
print(name_validation("user"))
Вывод
Вызвано исключение CyrillicError
Ввод
print(name_validation("иванов"))
Вывод
Вызвано исключение CapitalError
Решение
Довольно простая задача.
Проверяем является ли переданный параметр строкой с помощью type() или isinstance(). Если это не так, вызываем исключение TypeError.
Проверяем все ли буквы являются кириллицей. Это можно сделать несколькими способами: с помощью диапазонов кодов русских букв или с помощью заранее заданного алфавита. Можно проверить буквы с помощью all() или any(), а можно посчитать количество букв не являющихся кириллицей. Если хоть одна буква не является кириллицей вызываем исключение CyrillicError.
Проверяем является ли первая буква заглавной, а остальные прописными. Самый простой способ – преобразовать строку с помощью метода .istitle(). Если они не равны, то вызвать исключение CapitalError.
Посмотреть код
Решение
class CyrillicError(Exception):
pass
class CapitalError(Exception):
pass
def name_validation(name) -> str:
valid_cyrillic_chars = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя'
if not isinstance(name, str):
raise TypeError
if not all([char.lower() in valid_cyrillic_chars for char in name]):
raise CyrillicError
if not name.istitle():
raise CapitalError
return name
Сергей, здравствуйте.
Простите за, возможно, глупый вопрос. Но я вдруг поняла, что запуталась.
Скажите, пожалуйста, в каких случаях действует правило о том, что в одном блоке может быть только один if и один else, а elif может быть сколько угодно?
А в каких мы можем указывать более одного if (как в Вашем решении)?
Говорить об этих случаях как о правиле не очень корректно.
Конструкция с многими if более универсальна, но не отлавливает случай, когда ни один из if не сработал. Кроме того, по сравнению с if/elif/else она менее производительна, так как каждый if срабатывает каждый раз.
Возьмем, к примеру такой код:
вне зависимости от того чему будет равно a будет проведено три сравнения.
В свою очередь if/elif/else отсекает варианты:
В идеальном случае (a = 1) будет проведено всего одно сравнение. В худшем случае, a = 3 будет три сравнения. Зато в случае если нет совпадений, получаем возможность легко это отследить.
Но, к примеру, если мы поместим конструкцию из первого примера в функцию, которая будет сразу из тела if возвращать результат, преимущество второго способа над первым пропадает:
Про правило, которое, как выясняется, не совсем правило, всё поняла. Большое спасибо, что объяснили. Просто про это много говорится в разных уроках именно как про правило. Теперь понимаю, что дело не в правиле как таковом, а в производительности.
А кроме того, все эти объяснения ведутся на стадии разбора темы условного оператора (когда функции еще не освоены). И да, теперь понятно, что если речь идет именно о функции, которая из тела if возвращает результат, то преимущество if-elif над несколькими if отсутствует. То есть в такой функции можно применить как if-elif, так и многие if – результат будет тот же (на производительности это не скажется).
Надеюсь, а правильно всё поняла.
Огромное спасибо!