Привет, Хабр! Меня зовут Дмитрий, я аналитик данных и программный эксперт на курсе Python для анализа данных в Яндекс Практикуме. Решил поделиться тем, как реализованы условные операторы в Python: статья поможет вам составить впечатление о Python и улучшит ваше понимание условных операторов, при этом изложенные ниже принципы могут помочь и в других языках программирования и в формулах Excel или гугл-таблиц.

Условные операторы являются ключевым элементом любого языка программирования, так как позволяют выполнять определённые участки кода в зависимости от заданных условий, будь то простые или сложные.

В этой статье мы подробно рассмотрим концепцию условного оператора на примере языка Python. Сначала обсудим основные понятия и термины, такие как условия, функции и объекты. Затем углубимся в изучение условного оператора в Python, его синтаксиса и особенностей применения.

Мы также проанализируем примеры сложных условий и продемонстрируем, как можно упростить код с помощью инверсии. Это сделает ваш код более читаемым и эффективным.

Эта статья будет полезна начинающим программистам, стремящимся улучшить свои навыки работы с условными операторами. Она поможет вам глубже понять эту важную концепцию и научиться применять её на практике.

Простые и сложные условия

Условие может зависеть от переменных и быть сложным. Вот пример: «Чтобы прокатиться на зиплайне через Москву-реку, нужно быть 7 лет или старше, весить меньше 110 килограммов и прийти на аттракцион в светлое время суток». На самом деле условия сложнее, но если эти не выполняются, то на аттракционе делать нечего. Мы можем записать это условие так же, как оно произносится:

(user_age == 7 or user_age > 7) and user_weight < 110 and not night.

Условия в скобках проверяются в первую очередь. Если хотя бы одно условие из стоящих слева и справа от оператора or истинно, то результатом выражения будет истина (True). Так как в Python присвоение значения переменной делается одинарным знаком равно (например, age = 18 поместит в переменную age число 18), то для проверки равенства используется двойное равно ==. Для сравнений «строго больше и строго меньше» используются знаки больше и меньше.

Мы сразу можем упростить выражение в скобках, использовав вместо «строго больше» условие «больше или равно», тогда получится (user_age >= 7) and (user_weight < 110) and (not night). Чтобы оператор and вернул истину, оба выражения и справа, и слева от него должны быть истинны, иначе вернётся ложь (False). Оператор not меняет истину на ложь и наоборот. Если внутри переменной night сейчас хранится False, то not night вернёт True.

Скобки добавлены для того, чтобы выражение было легче читать. Без них порядок действий был бы такой: сначала выполняются все сравнения, потом оператор «не» (not), далее слева направо «и» (and) и только затем «или» (or).

Функции и объекты

Условие может быть настолько сложным, что его нужно проверять отдельной функцией. Функция — это кусочек кода, который выполняется с определёнными вводными (аргументами) и выдаёт результат. В Python функции определяются при помощи ключевого слова def, а вызываются указанием имени функции и аргументов в скобках.

Предположим, что у нас определена функция с именем is_tech_worker, которая возвращает True или False в зависимости от того, считается ли пользователь (user) сотрудником, отвечающим за техническое обслуживание аттракциона:

def is_tech_worker(user):
    ...
    return result 

В блоке пропущенного кода (…) могут быть любые операции и сравнения, но внутри функции результат её работы нужно поместить в переменную result, которая и будет возвращена функцией при её вызове. После выполнения оператора return код, расположенный ниже внутри функции, уже не выполняется.

Вызывается функция следующим образом: user_tech_worker = is_tech_worker(user). Тут в функцию передаётся объект user. В Python всё считается объектами, в этом случае это пользовательский тип данных со своими атрибутами.

Ранее мы проверяли вес и рост пользователя, уже сохранённые в отдельные переменные, но, скорее всего, мы также могли использовать атрибуты объекта, в которых хранится возраст и вес: user.age и user.weight. Если в атрибуте объекта хранится либо ложь, либо истина, то мы можем использовать этот атрибут в качестве условия — вместо вызова функции с объектом пользователя в качестве аргумента обращаться к user.tech_worker. Довольно предисловий, теперь мы можем перейти к тому, что такое условный оператор.

Условный оператор в Python

В Python условный оператор — это if. Он позволяет совершить какие-то действия только если условие истинно.

if condition:
    do_this()

В Python после if не нужно писать then, вместо этого используются отступы. Мы можем дополнять if последующими elif и else.

if condition:
    do_this()
elif second_condition:
    do_that()
elif other_condition:
    become_busy()
else:
    do_nothing()

С отступом после каждого условия даётся своя ветка кода. Выше каждая из них состоит только из вызова одной функции, но каждая ветка может содержать сколько угодно строк.

Во всей конструкции if-elif-else может быть выполнена только одна ветка: если расположенное выше условие истинно, то оставшиеся не проверяются. Для экономии вр��мени выполнения кода условия, которые чаще оказываются истинными, стоит располагать выше. Если мы делаем проверку внутри функции, то полным аналогом кода выше будет такой код:

def check_conditions():
    if condition:
        return start()
    if second_condition:
        return do_this()
    if other_condition:
        return do_that()
    
    return do_nothing()

Мы тут не используем elif и else, так как после return оставшиеся ветки кода выполнены не будут.

Инверсия

Вернёмся к примеру с аттракционом. Если посетитель 14 лет или младше, то поездка на зиплайне проходит с инструктором. Проверяется наличие билета для всех, кроме технических работников. Получается очень много условий. Мы можем разбить их на группы в зависимости от исхода — платная поездка с инструктором, платная поездка без инструктора, бесплатная поездка и поездка не состоялась. Для каждого исхода в одном условном операторе у нас будет своя ветка кода:

if (  user.age >= 7 
      and user.age <= 14 
      and user.weight < 110 
      and user.ticket 
      and not user.tech_worker):
        call_instructor()
        validate_ticket(user)
        start()
elif (user.age > 14 
      and user.weight < 110 
      and user.ticket 
      and not user.tech_worker):
        validate_ticket(user)
        start()
elif user.tech_worker:
        start()
else:
        print('Поездка не состоялась')

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

Есть способ сделать код понятнее. В самом конце, если никакие другие ветки кода не выполнены, вступает в действие ветка кода внутри else. В ней мы вызываем функцию print, распечатывающую текст о том, что поездка не состоялась.

Поскольку ветки независимы, у нас много условий дублируется в первой и второй ветке. Для облегчения кода инвертируем условия: если возраст меньше 7 или вес больше либо равен 110, а также нет билета — сразу завершим все проверки. Конечно, только в случае, если это не технический сотрудник, с ними разберёмся в первую очередь.

if user.tech_worker:
    start()
elif user.age < 7 or user.weight > 110 or not user.ticket:
    print('Поездка не состоялась')
else:
    if user.age <= 14:
        call_instructor()
    validate_ticket(user)
    start()

Кода стало сильно меньше! Теперь мы знаем, что если программа попала в ветку else, то значит, уже выполняется масса условий. Чтобы не дублировать код для проверки билета и старта поездки, мы создали вложенную ветку if. Она проверяет, что посетителю 14 лет или меньше, и в этом случае призывает инструктора.

На время прощаюсь. Мы рассмотрели базовые аспекты условных операторов на примере гипотетической системы, с которой вряд ли будут работать аналитики, однако их можно применять и для работы с таблицами в pandas. Пожалуйста, оставляйте свои вопросы, комментарии и отзывы — интересно узнать, хотите ли вы увидеть примеры использования условных операторов для анализа и обработки данных в pandas.