Чему научитесь
- Писать программу, которая выбирает: одно действие в одном случае, другое — в другом
- Составлять цепочки случаев через elif и не путать порядок проверок
- Находить наибольшее и наименьшее сравнениями, а не готовой функцией
- Не терять границы: понимать разницу между «до 18» и «до 18 включительно»
Как устроено занятие
Сначала разбор с примерами и короткими проверками понимания — они нужны, чтобы поймать непонятое сразу, а не через три темы.
Дальше 15 задач лестницей: разминка, основа, со звёздочкой. Занятие засчитывается, когда решено 10 — остальные не пропадают и учитываются отдельно.
После занятия — вторая часть, ещё 15 задач на те же приёмы в новых сюжетах.
Сколько это займёт
Примерно час-полтора вместе с задачами. Сроков нет: можно закрыть вкладку и вернуться когда удобно — прогресс сохранится.
Программа, которая выбирает
До сих пор все ваши программы делали одно и то же в одном и том же порядке: прочитали, посчитали, напечатали. Такая программа называется линейной, и на ней далеко не уедешь.
Попробуйте решить старым способом: «дано число, выведите его модуль». Формулы нет — ответ зависит от того, какое число пришло. Для −7 нужно напечатать 7, а для 7 — тоже 7, но ничего не меняя.
Значит, программе нужна развилка: в одном случае делать одно, в другом другое. В Python это if:
n = int(input())
if n < 0:
print(-n)
else:
print(n)
Читается почти как по-русски: «если n меньше нуля — напечатать минус n, иначе — напечатать n».
Обратите внимание на две вещи, без которых Python откажется работать: двоеточие в конце строки с условием и отступ у строк внутри. Отступ здесь не украшение — именно он показывает, что относится к развилке, а что нет.
Сравнения
Условие в if — это вопрос, на который есть ответ «да» или «нет». Задаётся он сравнением:
| запись | вопрос |
|---|---|
a > b |
больше? |
a < b |
меньше? |
a >= b |
больше или равно? |
a <= b |
меньше или равно? |
a == b |
равно? |
a != b |
не равно? |
Отдельно запомните: равенство проверяется двумя знаками ==, а один знак = — это присваивание, то самое «положить в переменную». Перепутать легко, и Python в этом месте выдаёт ошибку, а не молча делает не то, — за это ему спасибо.
Сравнивать можно не только переменные, но и любые выражения: a * b > 100, n % 2 == 0, x + y <= z. Сначала вычисляется всё, что слева и справа, потом сравнивается.
Проверка: равенство
Как проверить, что переменная n равна десяти?
Когда случаев больше двух: elif
Развилка не обязана быть на два исхода. Знак числа — это уже три случая: положительное, отрицательное, ноль.
Можно написать вложенно, но получится громоздко. Для цепочки случаев есть elif — сокращение от «else if»:
n = int(input())
if n > 0:
print(1)
elif n < 0:
print(-1)
else:
print(0)
Работает это так: проверки идут сверху вниз, и как только одна сработала, остальные пропускаются. Поэтому в elif n < 0 уже не нужно писать «и при этом n не больше нуля» — если бы было больше, мы бы сюда не дошли.
Это свойство очень удобно для порогов. Оценка по баллам пишется так:
if n >= 85:
print(5)
elif n >= 70:
print(4)
elif n >= 50:
print(3)
else:
print(2)
Обратите внимание: во второй строке достаточно n >= 70. Проверять, что число меньше 85, не нужно — до этой строки дошли только те, кто не прошёл первую проверку. Порядок сверху вниз здесь и делает всю работу.
Ветка else необязательна: если ни одно условие не сработало и else нет, программа просто пойдёт дальше. Но в задачах, где ответ нужен всегда, else лучше писать — иначе на каком-то входе программа не напечатает ничего.
Проверка: порядок веток
Что напечатает программа if n >= 50: print(3) / elif n >= 85: print(5) при n = 90?
Условие внутри условия
Иногда после первой проверки нужно задать второй вопрос. Тогда одну развилку вкладывают в другую:
x, y = map(int, input().split())
if x > 0:
if y > 0:
print(1) # обе положительны
else:
print(4) # x положителен, y нет
else:
print("слева")
Вложенность обозначается отступом: строки с двумя отступами относятся к внутренней развилке, с одним — к внешней. Здесь Python строже других языков, и это к лучшему: код нельзя написать так, чтобы он выглядел иначе, чем работает.
Такая запись пригодится, когда нужно проверить два условия сразу: сначала первое, внутри него второе. Для этого есть и более короткий способ — and, — но он на следующем занятии. Пока вкладывайте: заодно станет видно, почему короткая запись потом покажется удобной.
Границы — главное место ошибок
Почти все неудачные посылки на этой теме — не про логику, а про границы. Разница между < и <= кажется мелочью ровно до первого теста.
Смотрите: «билет детский, если возраст до 18 лет». Восемнадцатилетний — уже взрослый или ещё нет? В условии написано «до 18», значит age < 18. А если бы было «до 18 включительно», то age <= 18.
Правило простое: каждое граничное значение из условия обязано попасть в ваши тесты. Если написано «от 0 до 100 включительно» — проверьте −1, 0, 100 и 101. Четыре числа, полминуты работы, и целый класс ошибок закрыт.
Вторая ловушка — потерянный случай равенства. В задаче «какое число больше» есть третий вариант: они равны. Если про него забыть, программа напечатает что-то наугад или не напечатает ничего.
Третья — порядок проверок в цепочке. Если поставить elif n >= 50 раньше if n >= 85, все отличники получат тройки: первая подходящая ветка срабатывает и останавливает цепочку.
Проверка: граница
Скидка даётся при сумме покупки от 1000 рублей. Какая наименьшая сумма даёт скидку? Введите целое число.
Проверка: цепочка случаев
Каким словом в Python записывают следующую ветку в цепочке проверок — между if и else? Напишите одно слово.
Практика: пятнадцать задач
Лестница прежняя: пять разминочных, семь основных, три со звёздочкой. Зачёт при десяти решённых.
Перед отправкой каждой задачи задайте себе один вопрос: какие значения на границах? Выпишите их из условия и проверьте программу именно на них — это самая быстрая проверка на этом занятии.
В части задач ответ — слово (YES, NO, ICE). Регистр и написание заданы в условии: Yes вместо YES не засчитается.
Найдите ошибку на границе
Задача: «билет стоит 0 рублей для детей младше 7 лет, 150 рублей с 7 до 17 лет включительно и 400 рублей с 18 лет».
Ученик написал:
age = int(input())
if age < 7:
print(0)
elif age < 17:
print(150)
else:
print(400)
На большинстве тестов решение работает, но не принято. Найдите ошибку, назовите возраст, на котором она видна, и объясните, как исправить.