Python: Логические операторы
Мы уже умеем писать функции, которые проверяют одиночные условия. А в этом уроке научимся строить составные условия.
Предположим, что сайт при регистрации требует, чтобы пароль был длиннее восьми символов и содержал хотя бы одну заглавную букву. Попробуем написать два отдельных логических выражения и соединим их специальным оператором "И":
Пароль длиннее 8 символов И пароль содержит хотя бы одну заглавную букву
Вот функция, которая принимает пароль и говорит, соответствует ли он условиям (True) или не соответствует (False):
def has_capital_letter(text: str) -> bool:
# Проверяет наличие хотя бы одной заглавной буквы в строке
def is_correct_password(password: str) -> bool:
length = len(password)
return length > 8 and has_capital_letter(password)
print(is_correct_password('Qwerty')) # => False
print(is_correct_password('Qwerty1234')) # => True
print(is_correct_password('qwerty1234')) # => FalseОператор and означает "И". В математической логике это называют конъюнкцией. Все выражение считается истинным, если истинен каждый операнд, то есть каждое из составных выражений. Иными словами, and означает "и то, и другое". Приоритет этого оператора ниже, чем приоритет операторов сравнения. Поэтому выражение has_capital_letter(password) and length > 8 тоже правильно отрабатывает без скобок.
Кроме and часто используется оператор or, обозначающий "ИЛИ" (дизъюнкция). Он означает "или то, или другое, или оба". Выражение a or b считается истинным, если хотя бы один из операндов истинен или когда оба операнда истинны. В другом случае выражение ложное.
def has_discount(age: int, is_student: bool) -> bool:
return age < 18 or is_student
print(has_discount(15, False)) # => True (младше 18)
print(has_discount(25, True)) # => True (студент)
print(has_discount(15, True)) # => True (оба условия)
print(has_discount(25, False)) # => FalseОператоры можно комбинировать в любом количестве и в любой последовательности. Если в коде одновременно встречаются and и or, то приоритет лучше задавать скобками. Ниже пример расширенной функции, которая определяет корректность пароля:
def has_capital_letter(text: str) -> bool:
# Проверяет наличие хотя бы одной заглавной буквы в строке
def has_special_chars(text: str) -> bool:
# Проверяет содержание специальных символов в строке
def is_strong_password(password) -> bool:
length = len(password)
# Скобки задают приоритет. Понятно, что к чему относится.
return (length > 8 and has_capital_letter(password)) and has_special_chars(password)Теперь представим, что мы хотим купить квартиру, которая удовлетворяет таким условиям: площадь от 100 квадратных метров и больше на любой улице ИЛИ площадь от 80 квадратных метров и больше, но на центральной улице Main Street.
Напишем функцию, которая проверит квартиру. Она принимает два аргумента: площадь (число) и название улицы (строку):
def is_good_apartment(area: int, street: str) -> bool:
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Полезное
Python: Логические операторы
Мы уже умеем писать функции, которые проверяют одиночные условия. А в этом уроке научимся строить составные условия.
Предположим, что сайт при регистрации требует, чтобы пароль был длиннее восьми символов и содержал хотя бы одну заглавную букву. Попробуем написать два отдельных логических выражения и соединим их специальным оператором "И":
Пароль длиннее 8 символов И пароль содержит хотя бы одну заглавную букву
Вот функция, которая принимает пароль и говорит, соответствует ли он условиям (True) или не соответствует (False):
def has_capital_letter(text: str) -> bool:
# Проверяет наличие хотя бы одной заглавной буквы в строке
def is_correct_password(password: str) -> bool:
length = len(password)
return length > 8 and has_capital_letter(password)
print(is_correct_password('Qwerty')) # => False
print(is_correct_password('Qwerty1234')) # => True
print(is_correct_password('qwerty1234')) # => FalseОператор and означает "И". В математической логике это называют конъюнкцией. Все выражение считается истинным, если истинен каждый операнд, то есть каждое из составных выражений. Иными словами, and означает "и то, и другое". Приоритет этого оператора ниже, чем приоритет операторов сравнения. Поэтому выражение has_capital_letter(password) and length > 8 тоже правильно отрабатывает без скобок.
Кроме and часто используется оператор or, обозначающий "ИЛИ" (дизъюнкция). Он означает "или то, или другое, или оба". Выражение a or b считается истинным, если хотя бы один из операндов истинен или когда оба операнда истинны. В другом случае выражение ложное.
def has_discount(age: int, is_student: bool) -> bool:
return age < 18 or is_student
print(has_discount(15, False)) # => True (младше 18)
print(has_discount(25, True)) # => True (студент)
print(has_discount(15, True)) # => True (оба условия)
print(has_discount(25, False)) # => FalseОператоры можно комбинировать в любом количестве и в любой последовательности. Если в коде одновременно встречаются and и or, то приоритет лучше задавать скобками. Ниже пример расширенной функции, которая определяет корректность пароля:
def has_capital_letter(text: str) -> bool:
# Проверяет наличие хотя бы одной заглавной буквы в строке
def has_special_chars(text: str) -> bool:
# Проверяет содержание специальных символов в строке
def is_strong_password(password) -> bool:
length = len(password)
# Скобки задают приоритет. Понятно, что к чему относится.
return (length > 8 and has_capital_letter(password)) and has_special_chars(password)Теперь представим, что мы хотим купить квартиру, которая удовлетворяет таким условиям: площадь от 100 квадратных метров и больше на любой улице ИЛИ площадь от 80 квадратных метров и больше, но на центральной улице Main Street.
Напишем функцию, которая проверит квартиру. Она принимает два аргумента: площадь (число) и название улицы (строку):
def is_good_apartment(area: int, street: str) -> bool:
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Полезное
Ваше упражнение проверяется по этим тестам
import solution
def test1():
assert solution.is_leap_year(2016)
assert solution.is_leap_year(2000)
assert not solution.is_leap_year(2017)
assert not solution.is_leap_year(2018)
assert not solution.is_leap_year(1900)Решение учителя откроется через:
20:00
