Проверить программы онлайн · файлы остаются в браузере

Инвариант цикла и документирование — практикум

10 класс, углублённый уровень. Занятие седьмое: как написать цикл, чтобы он был верным, и как записать, что он делает.

План на пару. Сначала тренажёр: шесть коротких задач на чтение циклов — таблица витков, фраза, которая верна на каждом витке, строка, которая её ломает, комментарий, который врёт, пример в шапке программы. Потом три своих программы, каждая — по заранее данной фразе. Проверяет их оболочка Проверка.bat из общей папки: она запускает программу на девяти наборах данных, а если в программе есть шапка с примером — запускает и пример. Интернет не нужен.

Часть 1. Тренажёр: читаем циклы

Шесть типов задач, по одной на каждый. Считать в уме или на бумаге: главный инструмент сегодня — таблица витков, где одна строка — одна проверка условия цикла. Где ответ — номер фразы или строки, пиши только число.

0 верно из 6

Часть 2. Фраза, верная на каждом витке

Таблица витков

фрагмент программы — набери его сам
проверка условияnss + сумма цифр n
до цикла537200 + 17 = 17
после 1-го витка53722 + 15 = 17
после 2-го5399 + 8 = 17
после 3-го51212 + 5 = 17
на выходе01717 + 0 = 17

Переменные меняются на каждом витке, а последний столбец — нет. Фразу «s плюс сумма цифр n равно сумме цифр исходного числа» называют инвариантом цикла: она верна перед каждой проверкой условия — до первого витка, после каждого и на выходе. Строк в таблице на одну больше, чем витков.

Выход + фраза = ответ

На выходе известны две вещи: условие ложно (n == 0) и фраза верна (s + сумма цифр n = 17). Подставляем n = 0 — получаем s = 17. Программу не надо гонять виток за витком, чтобы понять, что она считает: хватает фразы и условия выхода.

Строим цикл по фразе

Фраза диктует все три места цикла:

Три места, где фраза ломается

фрагмент программы — набери его сам

Проверять фразу надо на границе: до первого витка, на выходе и там, где условие срабатывает впритык — N точная степень двойки, два равных максимума, самое маленькое допустимое число.

Часть 3. Документирование

Что писать в комментарии

фрагмент программы — набери его сам

Полезный комментарий говорит, что верно, а не что делает строка. Самая ценная строка документации цикла — его инвариант, одной строкой перед while.

Шапка программы — договор

фрагмент программы — набери его сам

Что подать, что получить и пример. Карточка задания в этом практикуме устроена ровно так же. Пример ценнее слов: его можно проверить запуском. Оболочка так и делает — берёт вход из примера, запускает программу и сверяет с обещанным выводом. Документация обязана быть правдой.

Документация для пользователя и чужая документация

Приглашение input("Введите число: ") — документация для человека, который сидит за программой. Когда вывод читает машина (оболочка, ЕГЭ), текста в input() быть не должно. Чужую документацию читают через help(): в IDLE наберите help(abs) или help(round) — это шапки, которые написали авторы Python.

Часть 4. Три программы

Задание 1 Степень двойки

Программа читает натуральное число код (от 1 до 1000000000) и печатает наибольшую степень двойки, не больше код: показатель код и само число код.

Фраза цикла: код и код.

Вход

20

Вывод

Степень: 4
Число: 16

Проверяется: начальные значения из фразы, условие выхода на границе — код против код.

Если застрял

Начало: при каких код и код фраза верна для любого код? Шаг: удвоить код и прибавить единицу к код — фраза «p = 2 ** k» сохранится. Выход: удваивать можно, пока удвоенное ещё не больше код.

Ловушки, ради которых это задание. Оболочка подаст 1 (ни одного витка, ответ 0 и 1), 1024 (точная степень: с код вместо код ответ на шаг меньше) и 1023. Условие код даст лишний виток: на выходе код больше код — фраза сломалась.

Задание 2 Наименьшее и наибольшее

Программа читает количество чисел код (от 1 до 20), затем код целых чисел от −1000 до 1000, каждое со своей строки. Печатает наименьшее, наибольшее и номер первого из наибольших (нумерация с 1). Списков не нужно: числа читаются и сравниваются по одному.

Фраза цикла: код и код — наименьшее и наибольшее из уже прочитанных, код — номер первого наибольшего.

Вход

5
4
9
1
9
2

Вывод

Наименьшее: 1
Наибольшее: 9
Номер наибольшего: 2

Проверяется: старт накопителя, который делает фразу верной с самого начала; строгое сравнение для первого максимума.

Если застрял

До цикла прочитай первое число: из одного прочитанного оно само и наименьшее, и наибольшее, и его номер 1 — фраза верна. Дальше код — читаем очередное число и сравниваем.

Ловушки, ради которых это задание. Старт код врёт, когда все числа положительные, код — когда все отрицательные: оболочка подаст и то и другое. И подаст два равных наибольших: сравнение код перезапишет номер, а нужен номер первого.

Задание 3 НОД вычитанием — с документацией

Программа читает два натуральных числа код и код (от 1 до 1000), каждое со своей строки. Пока числа не равны, из большего вычитает меньшее. Печатает наибольший общий делитель (он получится, когда числа сравняются) и сколько было вычитаний.

Фраза цикла: НОД(a, b) не меняется — он всё время равен НОД исходных чисел.

Вход

12
18

Вывод

НОД: 6
Вычитаний: 2

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

фрагмент программы — набери его сам

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

Проверяется: цикл с условием, счётчик шагов — и документация, которая проверяется запуском.

Если застрял

Цикл код, внутри ветвление: если код, то код, иначе код. Счётчик вычитаний стартует с нуля. На выходе код, а фраза говорит, что НОД(a, b) тот же, что у исходных, — и НОД двух равных чисел равен им самим. Это и есть ответ.

Ловушки, ради которых это задание. Равные числа на входе: ни одного вычитания. Остаток от деления (код) даёт тот же НОД быстрее, но число шагов другое — задание именно про вычитание. И пример в шапке: посчитай его таблицей по виткам, прежде чем писать.

Часть 5. Сдача

  1. Файлы zadanie1.py … zadanie3.py лежат в твоей папке, отладочные print из них убраны.
  2. В общей папке двойной щелчок по Проверка.bat.
  3. «Найти мои файлы» → «Проверить всё».
  4. Покажи учителю два экрана: тренажёр наверху этой страницы и итог оболочки.
Если вместо окна открылся текст программы — файл открылся в IDLE как код. Нажми F5, окно появится.

Оболочка показывает, на каких данных программа ошиблась и что должна была вывести, а если соврала шапка — что она обещала и что вышло на деле. Исправляй и проверяй снова, попыток сколько угодно.

Подсказка: инвариант цикла и документирование

Таблица витков

Одна строка — одна проверка условия цикла: до цикла, после каждого витка и на выходе. Строк на одну больше, чем витков. В последней строке условие ложно.

Инвариант

Фраза о переменных, верная в каждой строке таблицы. Сумма цифр: s + сумма цифр n = сумма цифр исходного. Степень двойки: p = 2 ** k и p ≤ N. НОД вычитанием: НОД(a, b) не меняется. На выходе фраза верна, а условие ложно — вместе они дают ответ без запуска.

Цикл по фразе

Начало — значения, при которых фраза верна до первого витка (s = 0, p = 1 и k = 0, mn = первое прочитанное). Шаг — сдвиг к цели, после которого фраза снова верна. Выход — условие, при котором фраза превращается в ответ.

Где фраза ломается

Старт накопителя чужим числом (m = 0). Граница выхода: < против <=, на выходе проверить, что фраза ещё верна. Равный максимум: >= перезаписывает номер первого. Проверять на границе: самый маленький вход, точная степень, два равных числа.

Комментарий

Говорит, что верно, а не пересказывает строку. Главный комментарий цикла — инвариант одной строкой перед while.

Шапка программы

# Ввод: что подаётся; # Вывод: что печатается; # Пример: вход -> вывод. Пример проверяется запуском: не сошлось — врёт программа или шапка. Приглашение в input() — для человека, машине оно мешает. Чужая документация — help(abs), help(round).

Материалы подготовлены с использованием технологий искусственного интеллекта.