Ветвления и сложные условия. Цикл с условием.
10 класс, углублённый уровень — занятие четвёртое.
До сих пор наши программы шли сверху вниз и делали одно и то же. Сегодня они научатся выбирать, что делать, и повторять столько раз, сколько потребуется — а сколько, заранее неизвестно.
if x > 100:
print("больше ста")
elif x > 10:
print("больше десяти")
else:
print("маленькое")
Условия проверяются сверху вниз. Выполняется первое подошедшее, остальные не вычисляются вовсе.
if x > 10:
print("больше десяти")
elif x > 100:
print("больше ста")
При x = 500 напечатается «больше десяти».
if x > 100:
print("больше ста")
elif x > 10:
print("больше десяти")
Сначала узкое условие, потом широкое.
Всё, что больше 100, больше и 10. Вторая ветка слева не сработает никогда, ни при каком x — и Python об этом не предупредит: написано синтаксически верно.
n = 12
if n % 2 == 0:
print("чётное")
elif n % 3 == 0:
print("кратно трём")
чётное
n = 12
if n % 2 == 0:
print("чётное")
if n % 3 == 0:
print("кратно трём")
чётное
кратно трём
if — это несколько независимых вопросов, и
ответить «да» может каждый.
| Операция | Истинна, когда | Приоритет |
|---|---|---|
not A | A ложно | 1 — раньше всех |
A and B | истинны обе | 2 |
A or B | истинна хотя бы одна | 3 — позже всех |
x > 0 or x < -5 and x % 2 == 0
# читается как:
x > 0 or (x < -5 and x % 2 == 0)
Сравнения (>, ==, %) считаются
раньше логических операций, поэтому скобок вокруг них не нужно. А вот
скобки для ясности ставить не стыдно — их ставят и опытные.
150 <= h <= 200 — это h >= 150 and h <= 200.
В C++ такая запись означала бы совсем другое.
if x == 1 or 2:
print("подходит")
Ошибки нет. Программа запускается.
if (x == 1) or (2):
print("подходит")
Число 2 истинно всегда, значит и условие истинно всегда.
print(5 == 1 or 2) 2 # не True и не False!
or возвращает не «да/нет», а первый истинный операнд.
Правильно — сравнение с каждым значением по отдельности:
if x == 1 or x == 2:.
if x = 5: там Python сразу скажет SyntaxError, и
ошибка найдётся за секунду. Опаснее та, на которую он молчит.
x = 0
print(x != 0 and 10 // x > 1) False
Деления на ноль не произошло. and вычислил левую часть, увидел
False — и правую часть не стал считать вовсе: результат уже
известен.
То же у or: если левая часть истинна, правая не вычисляется.
| Написано | То же самое |
|---|---|
not (A and B) | not A or not B |
not (A or B) | not A and not B |
Словами: «неверно, что оба» — значит «хотя бы один нет».
«Неверно, что хоть один» — значит «ни один».
# «не годен», если рост или вес вне нормы
if not (150 <= h <= 200 and 40 <= w <= 120):
print("не годен")
# то же самое, без отрицания целиком
if h < 150 or h > 200 or w < 40 or w > 120:
print("не годен")
Пригодится и на ЕГЭ: в задании 15 логические выражения преобразуют именно так.
Когда заранее неизвестно, сколько раз повторять.
for d in range(1, n + 1):
if n % d == 0:
print(d)
«Перебрать все числа от 1 до n».
years = 0
while total < goal:
total += total // 10
years += 1
«Пока не накопили нужное».
for счётчик двигается сам, а в
while переменную двигаете вы. Забыли — цикл не
кончится.
total = 20000
goal = 19999
years = 0
while total < goal: # 20000 < 19999 — ложь с самого начала
total += total // 10
years += 1
print(years) 0
Тело не выполнилось ни разу — и это правильный ответ: копить не надо, цель уже достигнута.
while True:
total += total // 10
years += 1
if total >= goal:
break
Здесь проверка в конце, поэтому хотя бы один проход будет всегда. Ровно эта ошибка ждёт вас сегодня в третьем задании.
i = 1
while i < 10:
print(i)
i не меняется — условие истинно всегда.
n = 100
while n != 1:
n = n - 3
«Ровно 1» не наступит: 100, 97, … 4, 1 — повезло. А при 101 — мимо.
Остановить зависшую программу в IDLE: Ctrl + C.
while n > 1 закончится при любом старте.
| Приём | Как выглядит | Пример задачи |
|---|---|---|
| счётчик | k = k + 1 | сколько шагов до цели |
| накопитель | s = s + n % 10 | сумма цифр числа |
| перебор цифр | while n > 0: … n = n // 10 | задание 25 ЕГЭ |
| максимум | if d > m: m = d | наибольшая цифра |
n = 4728
s = 0
while n > 0:
s = s + n % 10 # взять последнюю цифру
n = n // 10 # отрезать её
print(s) 21
Здесь встретились обе сегодняшние темы и прошлая: цикл с условием, ветвление внутри и деление с остатком, которым мы доставали цифры в прошлый раз.
break — выйти совсемd = 2
while d * d <= n:
if n % d == 0:
break
d = d + 1
Нашли делитель — дальше искать незачем.
continue — пропустить шагwhile i < 10:
i = i + 1
if i % 3 == 0:
continue
s = s + i
Кратные трём в сумму не попадут.
i увеличивается до continue. Иначе
программа зависла бы на первом же кратном трём: переход к проверке
условия есть, а движения вперёд нет.
A. Прибавь 1 — увеличивает число на экране на единицу.
B. Поменяй местами — меняет местами цифры двух младших разрядов. Применяется только к числу, у которого цифра десятков меньше цифры единиц.
# команды A, B, A — на экране 13
13 --A--> 14 --B--> 41 --A--> 42
Ряд промежуточных чисел называется траекторией. На экзамене спрашивают, сколько существует программ, переводящих одно число в другое; сегодня мы учимся выполнять одну программу — сначала руками, потом машиной.
n % 10 — единицы,
n // 10 % 10 — десятки. «Применима ли команда» — это
обычное ветвление внутри цикла.
| № | Программа | Ради чего |
|---|---|---|
| 1 | Календарь: сколько дней в месяце и високосный ли год | лестница elif, сложное условие, вложенное ветвление |
| 2 | Исполнитель: выполнить программу из команд A и B (команды вводятся по одной) | цикл с условием и ветвление внутри него; задание 13 ЕГЭ |
| 3 | Накопления: через сколько лет вклад дорастёт до цели | while со счётчиком, условие выхода |
zadanie1.py, zadanie2.py, zadanie3.py.Проверка.bat → «Найти мои файлы» → «Проверить всё».input() быть не должно: input(), а не
input("Введите год: "). Вывод читает машина.
Отметка: три задания — «5», два — «4», одно — «3». Попыток сколько угодно, оболочка каждый раз показывает, на каких данных программа ошиблась.
Сначала тренажёр, потом три программы.
Домашнее задание — на странице «Домашнее задание»: шесть типов задач на чтение кода, Python дома не нужен. В начале следующей пары — проверочная по этим же типам.