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

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

Два урока плана за одну пару: «Инвариант цикла» и «Документирование программ». Они про одно и то же: самая ценная строка документации цикла — та фраза, которая верна на каждом его витке.

Вспомним вклад из пары 4

total = 1000
year = 0
while total < 2000:
    total = total + total * 20 // 100
    year = year + 1
print(year, total)

Инвариант — фраза, верная на каждом витке

Утверждение о переменных, которое верно перед каждой проверкой условия: до первого витка, после каждого и на выходе.

Не условие цикла

Условие на выходе становится ложным. Инвариант остаётся верным всегда.

Не «переменная, которая не меняется»

Меняется всё. Не меняется связь между переменными.

Зачем фраза, если программа и так работает?

Наибольшее из n чисел. Запускаем — проверяем.

m = 0
for i in range(n):
    x = int(input())
    if x > m:
        m = x
print(m)
вводнапечатала
3 7 27верно
5 1 88верно

Сумма цифр: фраза, которую видно в таблице

n = 5372
s = 0
while n > 0:
    s = s + n % 10
    n = n // 10
print(s)
nss + сумма цифр n
537200 + 17
53722 + 15
5399 + 8
51212 + 5
01717 + 0

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

МестоВопрос к фразеСумма цифр
Началопри каких значениях фраза верна до первого витка? ничего не оторвано: s = 0
Шагкак сдвинуться к цели, чтобы фраза снова стала верной? оторвали n % 10 — прибавили к s
Выходкогда фраза превращается в ответ? n == 0 → while n > 0

Степень двойки: фраза и граница

Наибольшая степень двойки, не больше N. Фраза: p = 2 ** k и p ≤ N.

k = 0
p = 1              # 2 ** 0 = 1 ≤ N
while p * 2 <= N:
    p = p * 2
    k = k + 1
print(k, p)

Ловушка: накопитель стартует с чужого числа

Тот же приём, что с максимумом в начале, — теперь для наименьшего, и как починить.

Так — неверно

mn = 0
for i in range(K):
    x = int(input())
    if x < mn:
        mn = x

«mn — наименьшее из прочитанных» неверна уже до цикла. На 5, 8, 3 напечатает 0.

Так — верно

mn = int(input())
for i in range(K - 1):
    x = int(input())
    if x < mn:
        mn = x

Из одного прочитанного числа оно само и наименьшее — фраза верна с начала.

НОД вычитанием: фраза, которой нет в коде

while a != b:
    if a > b:
        a = a - b
    else:
        b = b - a
print(a)
ab
1218
126
66

Документирование: что писать в комментарии

Шум

i = i + 1   # увеличиваем i
# цикл
while n > 0:

Пересказ строки: читать надо, нового ноль.

Польза

# Инвариант: s — сумма
# уже оторванных цифр
while n > 0:

То, что верно, — и чего в строках не видно.

Какой комментарий врёт?

Три комментария к одному циклу. Два — правда, один — нет. Какой?

s = 0
i = 0         # ① ещё ничего не сложено
while i < M:
    i = i + 1
    s = s + i # ② s — сумма от 1 до i
print(s)      # ③ s — сумма от 1 до M−1

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

# Ввод: натуральное число n
# Вывод: сумма цифр числа n
# Пример: 5372 -> 17
n = int(input())

Что дать, что получить и пример. Карточка задания в практикуме устроена ровно так же — это и есть документация.

Документация для людей и чужая документация

Для пользователя

input("Введите число: ") — подсказка человеку за клавиатурой.

Когда вывод читает машина (оболочка, ЕГЭ), текста в input() нет.

Чужая

>>> help(abs)
>>> help(round)

Шапки, которые написали авторы Python. Попробуйте в IDLE.

Что делаем сегодня

№ПрограммаФраза
1Степень двойки: наибольшая, не больше N p = 2 ** k и p ≤ N
2Наименьшее и наибольшее из K чисел и номер первого наибольшего mn, mx — из прочитанных; num — первый наибольший
3НОД вычитанием и число вычитаний — с шапкой НОД(a, b) не меняется

Как работаем

  1. Открываем практикум из общей папки — сначала тренажёр: шесть задач на чтение циклов, оценки за него нет.
  2. Пишем три программы в IDLE, сохраняем в свою папку как zadanie1.py, zadanie2.py, zadanie3.py.
  3. Запускаем Проверка.bat → «Найти мои файлы» → «Проверить всё».
  4. Показываем отметку с экрана.
В задании 3 обязательны строки # Ввод:, # Вывод:, # Пример: вход -> вывод и # Инвариант: ... перед циклом. Без них оболочка задание не примет, даже если программа считает верно.

Отметка: три задания — «5», два — «4», одно — «3». Попыток сколько угодно.

За работу

Сначала тренажёр, потом три программы.

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

Материалы подготовлены с использованием технологий искусственного интеллекта. Пробел раскрыть и дальше · ← → слайды