Чему научитесь
- Записывать требование из нескольких условий через and, or и not
- Проверять попадание в диапазон одной строкой и не путать «и» с «или»
- Ставить скобки там, где and и or встречаются вместе
- Упрощать громоздкую проверку: формулировать наоборот или считать вместо перебора случаев
Как устроено занятие
Сначала разбор с примерами и короткими проверками понимания — они нужны, чтобы поймать непонятое сразу, а не через три темы.
Дальше 15 задач лестницей: разминка, основа, со звёздочкой. Занятие засчитывается, когда решено 10 — остальные не пропадают и учитываются отдельно.
После занятия — вторая часть, ещё 15 задач на те же приёмы в новых сюжетах.
Сколько это займёт
Примерно час-полтора вместе с задачами. Сроков нет: можно закрыть вкладку и вернуться когда удобно — прогресс сохранится.
Когда условий несколько
На прошлом занятии условие всегда было одно: «больше нуля», «равно десяти», «чётное». Но требования из жизни редко бывают такими простыми.
Автомат продаёт напиток, если банки есть и денег хватает. Билет детский, если возраст от 7 и до 17. Год високосный, если делится на 4 и не делится на 100, или делится на 400.
Вчера вы бы записали это вложенными развилками — и получилось бы верно, но громоздко:
if n > 0:
if m >= p:
print("YES")
else:
print("NO")
else:
print("NO")
Шесть строк, слово NO написано дважды, и стоит добавить третье требование — станет вдвое хуже. Сегодня научимся записывать такие условия одной строкой.
and, or, not
В Python есть три слова, соединяющие условия.
| слово | когда верно | по-русски |
|---|---|---|
A and B |
верны оба | «и то, и другое» |
A or B |
верно хотя бы одно | «или то, или другое» |
not A |
A неверно | «неверно, что» |
Тот же автомат теперь занимает три строки вместо шести:
if n > 0 and m >= p:
print("YES")
else:
print("NO")
Важная тонкость про or: в обычной речи «или» часто означает «одно из двух, но не оба» — «чай или кофе». В программировании or верно и когда выполняется всё сразу. «Есть отрицательное среди двух чисел» — верно и тогда, когда отрицательны оба.
И про not: чаще всего он нужен, чтобы перевернуть готовое условие. «Точка вне отрезка» — это not (a <= x <= b). Писать так можно, но иногда понятнее сформулировать условие сразу в положительной форме — об этом в конце занятия.
Проверка: смысл or
Числа 3 и 5. Что вернёт условие a < 0 or b < 0?
Диапазоны и цепочки сравнений
Самое частое составное условие — попадание в диапазон. «От 13 до 19 включительно» — это два требования сразу:
if age >= 13 and age <= 19:
В Python это можно записать короче — так, как пишут в математике:
if 13 <= age <= 19:
Цепочка работает ровно так, как выглядит, и читается легче. Это редкий случай, когда красивая запись ещё и правильнее: в ней невозможно случайно сравнить не ту переменную.
Обратите внимание на частую ошибку. Запись 13 <= age <= 19 верна, а вот age >= 13 or age <= 19 — бессмыслица: этому условию удовлетворяет любое число. Проверьте на числе 100: оно больше 13, значит первая часть верна, значит и всё условие верно. Диапазон — это всегда and.
Обратное тоже верно: «вне диапазона» — это or. Число вне отрезка, если оно меньше левой границы или больше правой.
Проверка: диапазон
Как правильно проверить, что число x лежит в диапазоне от 10 до 20 включительно?
Скобки и порядок
Когда в условии есть и and, и or, порядок начинает значить. У and приоритет выше: он «связывает крепче», как умножение по сравнению со сложением.
Значит запись
a > 0 and b > 0 or c > 0
понимается как (a > 0 and b > 0) or c > 0. Возможно, вы имели в виду именно это. А возможно — нет.
Правило простое и того же рода, что со скобками в арифметике: если в условии встретились и and, и or — ставьте скобки. Даже там, где Python понял бы вас правильно. Читать такое условие будете вы сами через неделю.
Классический пример — високосный год:
if (y % 4 == 0 and y % 100 != 0) or y % 400 == 0:
Скобки здесь обязательны по смыслу: «делится на 4 и не делится на 100» — это одно цельное требование, и уже оно соединяется с «делится на 400» через or.
Как упростить громоздкую проверку
Условие из пяти сравнений — признак того, что задачу можно посмотреть иначе. Три приёма, которые обычно помогают.
Первый: сформулируйте наоборот. Задача «пересекаются ли отрезки» перебором взаимных расположений разваливается на пять случаев. А вопрос «когда они точно не пересекаются» имеет ровно два ответа: первый целиком левее второго или целиком правее. Отсюда всё условие — две проверки вместо пяти.
Второй: посчитайте вместо проверки. Цвет шахматной клетки можно выяснять четырьмя условиями по чётности каждой координаты, а можно заметить, что всё решает чётность суммы: (x + y) % 2.
Третий: отсеките невозможное сразу. В задаче про дату сначала проверьте, что месяц вообще существует, и только потом выясняйте число дней. Иначе придётся отвечать, сколько дней в тринадцатом месяце.
Осторожно с длинными цепочками
Условие, которое не помещается в строку, почти наверняка можно разбить: вычислить части в переменные с понятными именами и соединить их.
fits_as_is = a <= c and b <= d
fits_rotated = a <= d and b <= c
if fits_as_is or fits_rotated:
print("YES")
Так видно замысел, а не нагромождение знаков. И отлаживать проще: можно напечатать каждую часть отдельно.
Проверка: соединение условий
Каким словом соединяют два условия, если требуется, чтобы выполнились оба? Напишите одно слово.
Практика: пятнадцать задач
Лестница прежняя: пять разминочных, семь основных, три со звёздочкой. Зачёт при десяти решённых.
Совет на это занятие: прежде чем писать условие, проговорите его словами полностью. «Коробка проходит, если она помещается как есть или помещается повёрнутой» — и только потом переводите в код. Половина ошибок здесь — от того, что условие переводили по кускам.
И проверяйте случаи, где выполняется только одна часть условия: именно там and и or ведут себя по-разному.
Почему условие всегда верно
Задача: «выведите YES, если число лежит в диапазоне от 10 до 20 включительно».
Ученик написал:
x = int(input())
if x >= 10 or x <= 20:
print("YES")
else:
print("NO")
Программа печатает YES вообще всегда, на любом входе. Объясните, почему так выходит, приведите число, на котором ошибка очевидна, и скажите, как исправить.