Бесплатный курс по Python. Зарегистрируйтесь для отслеживания прогресса →

Python: Логические операторы

Мы уже умеем писать функции, которые проверяют одиночные условия. Теперь научимся строить составные условия.

Хороший пример: проверка пароля. Предположим, что некий сайт при регистрации требует, чтобы пароль был длиннее восьми символов и короче двадцати символов. Да, ограничение выглядит странно, но бывает и такое.

В математике мы бы написали 8 < x < 20, но во многих языках программирования так сделать нельзя. К счастью, Python такие составные условия писать позволяет. И всё же на минутку мы забудем о такой возможности. Попробуем сделать два отдельных логических выражения и соединить их специальным оператором «И»:

Пароль длиннее 8 символов И пароль короче 20 символов.

Вот функция, которая принимает пароль и говорит, соответствует ли он условиям (True) или не соответствует (False):

def is_correct_password(password):
    length = len(password)
    return length > 8 and length < 20

print(is_correct_password('qwerty'))                   # => False
print(is_correct_password('qwerty1234'))               # => True
print(is_correct_password('zxcvbnmasdfghjkqwertyui'))  # => False

and — означает «И» (в математической логике это называют конъюнкцией). Всё выражение считается истинным, только если истинен каждый операнд — каждое из составных выражений. Иными словами, and означает «и то, и другое».

Приоритет этого оператора ниже, чем приоритет операторов сравнения, поэтому выражение length > 8 and length < 20 отрабатывает правильно без скобок.

Кроме and часто используется оператор or — «ИЛИ» (дизъюнкция). Он означает «или то, или другое, или оба». То есть выражение a or b считается истинным, если хотя бы один из операндов (a или b или одновременно все операнды) является истинным. Иначе выражение ложное.

Операторы можно комбинировать в любом количестве и любой последовательности, но когда одновременно встречаются and и or, то приоритет лучше задавать скобками. Ниже пример расширенной функции определения корректности пароля:

def has_special_chars(str):
    # проверяет содержание специальных символов в строке


def is_strong_password(password):
    length = len(password)
    # Скобки задают приоритет. Понятно что к чему относится.
    return (length > 8 and length < 20) or has_special_chars(password)

Другой пример. Мы хотим купить квартиру, которая удовлетворяет условиям: площадь от 100 кв. метров и больше на любой улице ИЛИ площадь от 80 кв. метров и больше, но на центральной улице Main Street.

Напишем функцию, проверяющую квартиру. Она принимает два аргумента: площадь (число) и название улицы (строку):

def is_good_apartment(area, street):
    return area >= 100 or (area >= 80 and street == 'Main Street')

print(is_good_apartment(91, 'Queens Street'))  # => False
print(is_good_apartment(78, 'Queens Street'))  # => False
print(is_good_apartment(70, 'Main Street'))    # => False

print(is_good_apartment(120, 'Queens Street')) # => True
print(is_good_apartment(120, 'Main Street'))   # => True
print(is_good_apartment(80, 'Main Street'))    # => True

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

И and

A B A and B
True True True
True False False
False True False
False False False

ИЛИ or

A B A or B
True True True
True False True
False True True
False False False

Задание

Реализуйте метод is_leap_year(), который определяет является ли год високосным или нет. Год будет високосным, если он кратен (то есть делится без остатка) 400 или он одновременно кратен 4 и не кратен 100. Как видите, в определении уже заложена вся необходимая логика, осталось только переложить её на код:

is_leap_year(2018) # false
is_leap_year(2017) # false
is_leap_year(2016) # true

Кратность можно проверять так:

# % - возвращает остаток от деления левого операнда на правый
# Проверяем что number кратен 10
number % 10 == 0

# Проверяем что number не кратен 10
number % 10 != 0
Упражнение не проходит проверку — что делать? 😶

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

  • Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨

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

Мой код отличается от решения учителя 🤔

Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно 🙄

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.

Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.

Полезное

Определения

  • Логические операторы - операторы «И» (and), ИЛИ (or), позволяющие создавать составные логические условия.


Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном сообществе