Как учиться

Условия и ветвления

«Если норматив выполнен — зачёт. Если нет, но результат не хуже, чем на минуту медленнее, — повторная попытка в четверг. Если и так не выходит, тогда задание по теории». Такое правило можно услышать в любой школе, и у него есть одно свойство: оно уже почти программа. Три фразы, у двух из них есть «если», и каждое «если» проверяет что-то, на что можно ответить «да» или «нет». Остаётся пересказать то же самое языком, который понимает компьютер.

Пример у нас учебный, и числа в нём условные: пять минут на дистанцию для зачёта, шесть для повторной попытки. Настоящие нормативы в вашей школе свои, и менять мы их не будем, нас интересует форма правила. Двигаться будем так, как это обычно происходит у школьника на занятии: одно условие, потом второе, потом «иначе», потом то, на чём все спотыкаются.

Сначала правило записывается словами

Первое, что я прошу сделать ученика, — не открывать редактор. Взять листок и записать правило обычными словами, с «если», «иначе», с числами и с вопросом на каждую границу. Для нашего норматива: время вводится в минутах; если время не больше пяти — «зачёт»; иначе, если не больше шести — «повторная попытка»; иначе — «задание по теории».

Полезно сразу задать себе вопрос про границу: ровно пять минут — это зачёт или нет? Слова «не больше» означают, что да. Слова «меньше» означали бы, что нет. В жизни различие кажется мелочью, а в программе это разница между знаком < и знаком <=, и из-за неё чаще всего ошибаются не в логике, а в одной чёрточке. Если границу не решить на бумаге, её решит случай в коде.

Как записывают такие правила схемой, разобрано в статье про алгоритмы и блок-схемы, а место этой темы среди остальных показано в обзоре школьной информатики.

Одно условие

Переводим в код первую строку правила. Время приходит с клавиатуры, и сначала его надо превратить в число (почему, разобрано в статье про переменные и типы данных): t = float(input()). Дальше сама проверка: if t <= 5: print("зачёт").

В обычной записи то, что выполняется при истинном условии, пишут на следующей строке со сдвигом в четыре пробела, и этот сдвиг — часть языка: по нему Python понимает, где кончается ветка. Здесь для краткости всё записано в одну строку после двоеточия, что тоже допустимо, но при работе в редакторе привыкайте к сдвигу, на нём держится всё остальное.

Сама проверка в скобках после if — это вопрос, у которого два возможных ответа. Попробуйте вывести его отдельно: print(t <= 5) покажет True или False, то есть ровно тот самый булевый тип из статьи про типы данных. Условие в if — всего лишь такое значение, и ничего таинственного в нём нет.

Если пропустить float() и сравнить прочитанный текст с числом пять, Python тоже остановится, с ошибкой TypeError: строку с числом сравнивать нельзя. А вот две строки сравнить можно, причём по символам, как слова в словаре, отчего «10» оказывается меньше «9». Поэтому преобразование при вводе нужно делать всегда, даже если программа вроде бы работает на ваших первых примерах.

Знаков сравнения шесть: <, <=, >, >=, == и !=. Последние два означают «равно» и «не равно», причём равенство записывается двумя знаками. Одиночный знак равенства — это присваивание, о котором шла речь в статье про переменные. Если написать if t = 5, Python остановится с синтаксической ошибкой — и это хороший случай, потому что остановится.

Второе условие и порядок проверок

Теперь добавляем вторую строку правила. Хочется написать так:

  • if t <= 6: print("повторная попытка")
  • elif t <= 5: print("зачёт")

Слово elif означает «а если не так, то проверим вот это». Код выглядит правильно, и работает он плохо: спортсмен с результатом 4,5 минуты получит «повторную попытку», потому что первая проверка (не больше шести) для него истинна, и до второй программа не дойдёт. Цепочка проверяется сверху вниз, и срабатывает первая подошедшая.

Правило для порядка из этого простое: сначала самое узкое условие, потом более широкое. В нашем случае пятёрка стоит раньше шестёрки. Верный вариант выглядит так:

  • if t <= 5: print("зачёт")
  • elif t <= 6: print("повторная попытка")

Замечу, что из-за порядка программа здесь выглядит короче, чем правило на словах: во второй проверке мы не пишем «больше пяти и не больше шести», потому что «больше пяти» уже подразумевается, раз до неё дошли. Это удобно и опасно одновременно: стоит поменять строки местами или вставить сверху ещё одну проверку, и скрытое условие исчезнет.

И «иначе»

Остаётся последняя строка: во всех остальных случаях — задание по теории. Для этого есть else, которому условие не нужно: else: print("задание по теории"). Эта ветка срабатывает, когда не подошла ни одна из предыдущих, и относится ко всей цепочке сразу, включая все elif выше. Без неё программа для времени в семь минут промолчала бы: ни ошибки, ни ответа.

Три кусочка вместе уже составляют готовую программу. Написать её стоит самостоятельно и ввести пять значений: 4.9, 5, 5.1, 6 и 6.1. Числа выбраны по правилу: каждая граница, 5 и 6, и по значению рядом с ней — меньше пяти, между пятью и шестью, больше шести. Если на всех пяти ответ совпал с тем, что вы ожидали от правила, программа верна. Если хотя бы один расходится, виновата почти всегда граница: перепутаны < и <=.

Родителям пригодится ещё одно наблюдение. Когда ребёнок показывает готовую программу, вопрос «работает?» ничего не выясняет: на тех значениях, которые автор ввёл, она работает почти всегда. Спросите другое: на каких числах проверял и вводил ли он границу. Если ответ «на двух-трёх обычных», самое время попросить добавить ещё два значения — одно ровно на границе, второе на ней же с другой стороны.

Порог по значению: «и», «или» и ловушка

Другая типичная задача — порог. Освобождение от итоговой работы, например, дают, если средний балл не меньше 4.5 (число опять условное), причём пропусков без уважительной причины нет. Здесь два условия сразу, и для связи их в Python есть слова and («и») и or («или»): if score >= 4.5 and absences == 0: print("освобождён").

Проверьте себя на задаче с несколькими уровнями: по числу баллов вывести «отлично», «хорошо», «удовлетворительно» или «неудовлетворительно», пороги для примера 18, 14 и 9. Четыре исхода требуют трёх проверок и else, а порядок проверок снова решает всё: начинать нужно с самого высокого порога, иначе «удовлетворительно» получит каждый, кто набрал хотя бы девять, даже если у него все восемнадцать.

С or связана ловушка: запись if grade == 4 or 5 Python принимает без единого замечания и считает её всегда истинной: 5 как условие сама по себе означает «да», и программа пропустит любую оценку, хоть двойку. Верная запись требует повторить сравнение: if grade == 4 or grade == 5, или короче, if grade in (4, 5).

В сложных выражениях скобки лучше не экономить; порядок, в котором Python выполняет and, or и not, и таблицы истинности разобраны в статье про логику и таблицы истинности.

Вложенность или цепочка

Условие можно положить внутрь другого условия: сначала проверить, есть ли справка, и только потом сравнивать время. Иногда это нужно: когда второй вопрос вообще не имеет смысла без ответа на первый. Но если проверки просто идут друг за другом, как в нашем нормативе, цепочка elif читается легче, чем лестница из сдвигов, и ошибиться в ней сложнее. Некоторые преподаватели любят вложенные условия за наглядность, но в работах учеников вложенность чаще всего возникает от того, что цепочку не придумали, задача этого не требует, и лестница из четырёх сдвигов — как раз такой случай.

Куда это ведёт

Условия повторяются в программах постоянно, а чаще всего внутри цикла: «для каждого результата проверить, прошёл ли он норматив» — это уже тема циклов. На экзамене ветвление встречается внутри задач на чтение и написание программ; кроме того, в первой части есть задания на логические выражения, и по смыслу они про те же и, или, не (какие именно задания, смотрите в карте первой части и в демоверсии своего года). Общее устройство экзамена изложено в статье о структуре ЕГЭ по информатике.

Начать поиск:

Вопросы и ответы

Чем отличаются = и ==? Одинарный знак кладёт значение в переменную, двойной сравнивает. Если перепутать внутри if, Python остановится с ошибкой.

Когда нужен elif, а когда достаточно нескольких if? Цепочка из if и elif подходит, когда варианты исключают друг друга: оценка не может быть одновременно «зачёт» и «повторная попытка», и сработать должна одна ветка. Отдельные if нужны для независимых проверок: например, к оценке добавляются надбавки за пропуски и за олимпиаду, и могут сработать обе. Если поставить отдельные if там, где нужна цепочка, программа может напечатать два ответа вместо одного, и это легко заметить; если наоборот, вторая надбавка молча пропадёт.

Программа выдаёт верный ответ на моих примерах, а проверка говорит «неверно». Что смотреть? Границы. Свои примеры обычно берутся из середины диапазона, а ошибка живёт на стыке, то есть на самом числе 5. Проверьте значения ровно на границе и рядом с ней, а также ввод, которого вы не ждали: пустую строку, запятую вместо точки, отрицательное число. Если разобраться не выходит, репетитору стоит отправить файл с программой и список значений, на которых она ошибается: запустить её он может у себя.

Нужен ли школьнику match? В Python начиная с версии 3.10 есть конструкция match, похожая на выбор по образцу. Для школьного курса она не нужна: цепочка if и elif покрывает всё, что встретится.

Оставить заявку

Ещё в рубрике «Как учиться»