- PVSM.RU - https://www.pvsm.ru -

Python: Мышление программиста

Небольшая статья о том, как можно решить одну и ту же задачу несколькими способами. Предназначена для новичков в Python и программировании.

В качестве примера взят простой случай — реализация диалога подтверждения какой-либо операции. Программа задает пользователю вопрос Вы уверены? [Д/н (Y/n)]:, на который требуется ответить, введя одно из восьми допустимых значений (Д, д, Н, н, Y, y, N, n).

Способ №1

Первое, что приходит на ум, это реализовать проверку совпадения каждого из условий следующим образом:

    def are_you_sure1():
        while True:
            print("Вы уверены? [Д/н (Y/n)]: ")
            response = input()

            if response == "Д" or response == "д":
                print("Положительный ответ: {}".format(response))
            elif response == "Y" or response == "y":
                print("Положительный ответ: {}".format(response))
            elif response == "Н" or response == "н":
                print("Отрицательный ответ: {}".format(response))
            elif response == "N" or response == "n":
                print("Отрицательный ответ: {}".format(response))
            else:
                print("Введено некорректное значение: {}".format(response)

    are_you_sure1()  

Можно было расписать все 8 блоков if/elif, но для краткости используется логический оператор or (ИЛИ) для каждой из пар возможных значений.

В этом решении нет ничего плохого и оно является правильным, хорошо характеризуя принцип «Чем проще, тем лучше». Именно к такому решению приходит большинство начинающих питонистов.

Однако, это противоречит принципу «Не повторяйся», так как любой программист стремится к уменьшению числа вводимых символов.

Способ №2

Второй способ заключается в отсечении лишних сущностей (Бритва Оккама [1]). Не имеет значения в каком именно регистре будет введен символ в ответ на вопрос программы. Поэтому воспользуемся методом строки upper() или lower() для приведения символов к верхнему или нижнему регистру:

    def are_you_sure2():
        while True:
            print("Вы уверены? [Д/н (Y/n)]: ")
            # Принимает значение, введенное пользователем и
            # переводит его в верхний регистр
            response = input().upper()  

            if response == "Д" or response == "Y":
                print("Положительный ответ: {}".format(response))
            elif response == "Н" or response == "N":
                print("Отрицательный ответ: {}".format(response))
            else:
                print("Введено некорректное значение: {}".format(response))

    are_you_sure2()

Введенное пользователем значение сразу же приводится к одному регистру, а далее уже происходит его проверка. Как итог — сокращение количества вводимых символов и повторяющихся блоков кода.

Способ №3

Еще один способ — проверить входит ли введенное значение в список допустимых.

    def are_you_sure3():
        while True:
            print("Вы уверены? [Д/н (Y/n)]: ")
            response = input()

            if response in ["Д", "д", "Y", "y"]:
                print("Положительный ответ: {}".format(response))
            elif response in ["Н", "н", "N", "n"]:
                print("Отрицательный ответ: {}".format(response))
            else:
                print("Введено некорректное значение: {}".format(response))

    are_you_sure3()

Проверка осуществляется с помощью оператора вхождения in. Пример альтернативного мышления [2].

Способ №4

Еще один пример альтернативного мышления [2], заключающийся в использовании регулярных выражений. Для этого воспользуемся стандартным модулем для работы с регулярными выражениями re и методом re.match().

    import re    # Импорт модуля для работы с регулярными выражениями

    def are_you_sure4():
        while True:
            print("Вы уверены? [Д/н (Y/n)]: ")
            response = input()

            if re.match("[yYдД]", response):
                print("Положительный ответ: {}".format(response))
            elif re.match("[nNнН]", response):
                print("Отрицательный ответ: {}".format(response))
            else:
                print("Введено некорректное значение: {}".format(response))

    def are_you_sure4()

Метод re.match(шаблон, строка) ищет по заданному шаблону в начале строки. В качестве шаблона используется регулярное выражение [yYдД] и [nNнН] (квадратные скобки группируют символы). Более подробно тема регулярных выражений раскрывается в статьях, ссылки на которые приведены в конце. Также рекомендую книгу «Освой самостоятельно регулярные выражения. 10 минут на урок» Бена Форты [3].

В этом способе тоже можно использовать принцип отсечения лишнего и сократить регулярные выражения до вида [YД] и [NН] с помощью метода upper().

Также стоит отметить, что в данном случае корректными будут считаться любые значения, начинающиеся с разрешенных символов, например, да, Yum и т.д., так как re.match() ищет совпадения только с начала строки. В отличии от других способов, где должно быть точное соответствие и любые лишние символы вызовут сообщение о некорректности. Можно считать это преимуществом, но ничего не мешает исправить такое поведение.

Последний способ излишен для такого простого примера, но хорош своей универсальностью и расширяемостью, так как регулярные выражения позволяют осуществлять более сложную проверку (например, проверку e-mail [4]).

Ссылки

Автор: OneManRevolution

Источник [14]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/python/121269

Ссылки в тексте:

[1] Бритва Оккама: https://ru.wikipedia.org/wiki/Бритва_Оккама

[2] мышления: http://www.braintools.ru

[3] «Освой самостоятельно регулярные выражения. 10 минут на урок» Бена Форты: http://www.ozon.ru/context/detail/id/2142281/

[4] проверку e-mail: https://habrahabr.ru/post/175375/

[5] «Чем хуже, тем лучше»: https://ru.wikipedia.org/wiki/%D0%A7%D0%B5%D0%BC_%D1%85%D1%83%D0%B6%D0%B5,_%D1%82%D0%B5%D0%BC_%D0%BB%D1%83%D1%87%D1%88%D0%B5

[6] «Не повторяйся»: https://ru.wikipedia.org/wiki/Don%E2%80%99t_repeat_yourself

[7] Бритва Оккама: https://ru.wikipedia.org/wiki/%D0%91%D1%80%D0%B8%D1%82%D0%B2%D0%B0_%D0%9E%D0%BA%D0%BA%D0%B0%D0%BC%D0%B0

[8] Pythonicway: Операторы в Python: http://pythonicway.com/python-operators

[9] Pythonz.net: Метод str.upper: https://pythonz.net/references/named/str.upper/

[10] Бен Форта «Освой самостоятельно регулярные выражения. 10 минут на урок»: http://www.ozon.ru/context/detail/id/2142281

[11] Типичный программист: Использование регулярных выражений в Python для новичков: https://tproger.ru/translations/regular-expression-python/

[12] Регулярные выражения в Python: изучение и оптимизация: http://blog.dzinko.org/2011/03/python.html

[13] Хабрахабр: Регулярные выражения, пособие для новичков: https://habrahabr.ru/post/115825/

[14] Источник: https://habrahabr.ru/post/301344/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best