EduBrick
классная работа

Составные условия и вложенность

Программирование на Python: от нуля до олимпиад

0/19решено 0 из 19до зачёта осталось 10

Чему научитесь

  • Записывать требование из нескольких условий через 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, если число xx лежит в диапазоне от 10 до 20 включительно».

Ученик написал:

x = int(input())
if x >= 10 or x <= 20:
    print("YES")
else:
    print("NO")

Программа печатает YES вообще всегда, на любом входе. Объясните, почему так выходит, приведите число, на котором ошибка очевидна, и скажите, как исправить.

Войдите, чтобы ответить.