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

Среда и отладка — практикум

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

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

Часть 1. Что происходит с программой до того, как она заработает

Процессор не понимает ни print, ни while. Он понимает только машинный код — числа. Значит, между вашим текстом и процессором обязательно кто-то стоит. Кто именно — зависит от языка.

КомпиляторИнтерпретатор
Когда переводитвсю программу заранее, до запуска по ходу дела, строку за строкой
Что получаетсяготовый файл (.exe) ничего не остаётся, результат сразу
Скорость работывышениже
Когда видно ошибкудо запуска, все сразу когда до неё дошло выполнение
ЯзыкиC, C++, PascalPython, JavaScript

У Python дорога чуть длиннее и хитрее. Текст программы переводится не в команды процессора, а в промежуточный байт-код — и уже его выполняет виртуальная машина. Байт-код Python складывает в папку __pycache__ рядом с программой, чтобы в следующий раз не переводить заново.

Зачем это нужно. Байт-код одинаков везде, а виртуальные машины написаны под каждую систему. Поэтому программа на Python переезжает с Windows на Linux и на телефон без единой правки. Так же устроены Java (JVM) и C# (.NET). Плата за это — скорость: между вашей программой и процессором стоит лишний слой.

Среда разработки

IDLE, в которой вы работаете, — это интегрированная среда разработки (IDE). «Интегрированная» значит, что всё нужное собрано в одном окне:

Взрослые среды (PyCharm, VS Code, Visual Studio) устроены так же, только у них ещё есть подсказки по коду, работа с git и профилировщик — инструмент, который меряет, на что программа тратит время.

Часть 2. Тренажёр: исполни программу как процессор

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

Четыре задачи, при каждом открытии новые. Считать на бумаге или в уме: запустив программу, вы узнаете ответ, но не научитесь. Задачу можно поправить и отправить снова сколько угодно раз; если тип дался не с первого захода, кнопка «Добавить задачи» даст по нему ещё одну — с другими числами.

0 верно из 4

Часть 3. Три инструмента, когда программа врёт

Ошибки бывают двух разных видов, и лечатся они по-разному.

ВидКак выглядитЧем ловится
Программа не запускается красный текст, SyntaxError, ValueError читать последнюю строку сообщения — там сказано что и где
Программа работает, но врёт ошибок нет, ответ неправильный трассировка, отладочный вывод, отладчик

1. Трассировочная таблица — на бумаге

Самый дешёвый инструмент, и часто самый быстрый. Берёте лист, выписываете переменные в столбцы и проходите цикл руками. Если программа не помещается в голову — она не поместится и в таблицу; значит, надо разбивать на куски.

2. Отладочный вывод — временный print

Вставьте print туда, где хотите увидеть, что происходит:

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

Правило одно: такие строки убирают перед сдачей. Оболочка сравнивает вывод с эталонным, и забытая отладочная строка — это уже другой ответ.

3. Отладчик IDLE — когда непонятно вообще

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

  1. Перейди в главное окно IDLE (то, где >>>).
  2. Debug → Debugger. Появится окошко Debug Control, в Shell — [DEBUG ON].
  3. Поставь галочки Locals и Globals — иначе значений не увидишь.
  4. Вернись в окно программы, F5. Программа встанет на первой строке.
  5. Кнопки: Step — шаг, Over — шаг не заходя в функцию, Out — выйти из функции, Go — до точки останова, Quit — прервать.
  6. Закончил — выключи отладчик тем же пунктом меню. Пока он включён, любой запуск идёт по шагам.
Точка останова. Щёлкни по строке правой кнопкой → Set Breakpoint, строка станет жёлтой. Теперь Go домчит программу до неё и остановится перед этой строкой. Незаменимо в цикле: не нужно жать Step по сто раз.
Как ловить зависшую программу

Программа работает и не заканчивается — значит, цикл не может выйти. Порядок такой:

  1. Останови её: Ctrl+C в окне Shell. Python напечатает KeyboardInterrupt и покажет строку, на которой её прервали, — это строка внутри вечного цикла.
  2. Посмотри на условие цикла и найди переменную, от которой оно зависит.
  3. Проверь глазами: меняется ли эта переменная внутри цикла? Если нет — условие останется истинным навсегда.

То же самое покажет и отладчик: точка останова на первой строке тела, потом Go несколько раз подряд — и видно, что в Locals ничего не движется.

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

В общей папке лежат broken1.py, broken2.py, broken3.py. В каждой описано, что программа должна делать, и в каждой ровно одна ошибка. Открой в IDLE, найди, почини.

Сохраняй в свою папку под именами zadanie1.py, zadanie2.py, zadanie3.py — File → Save As…. Файлы в общей папке править нельзя: они нужны всему классу.
Читаешь дома? Тексты трёх заготовок здесь

Общей папки дома нет, поэтому вот сами программы. Скопируй нужную в IDLE (File → New File), сохрани под именем zadanieN.py и чини. Проверить починку оболочкой получится только в кабинете — дома сверяйся с примерами из условий ниже и трассировочной таблицей.

broken1.py

# Задание 1. Пробег за смену.
#
# Что программа ДОЛЖНА делать:
#   читает число n — сколько поездок было за смену,
#   потом n чисел — километры каждой поездки,
#   печатает: Всего: <сумма> км
#
# Пример:  вход 3, 12, 5, 20  ->  Всего: 37 км
#
# Программа работает, но считает неправильно. Найди ошибку и исправь.
# Сохрани исправленную программу в свою папку как zadanie1.py

n = int(input())
for i in range(n):
    total = 0
    km = int(input())
    total = total + km
print(f"Всего: {total} км")

broken2.py

# Задание 2. Самый короткий заказ.
#
# Что программа ДОЛЖНА делать:
#   читает число n — сколько было заказов,
#   потом n чисел — расстояние каждого заказа в километрах,
#   печатает: Минимум: <самое маленькое из них> км
#
# Пример:  вход 3, 12, 5, 20  ->  Минимум: 5 км
#
# Программа запускается и что-то печатает, но ответ всегда один и тот же.
# Найди ошибку и исправь.
# Сохрани исправленную программу в свою папку как zadanie2.py

n = int(input())
mn = 0
for i in range(n):
    km = int(input())
    if km < mn:
        mn = km
print(f"Минимум: {mn} км")

broken3.py

# Задание 3. Сколько заказов увезёт курьер.
#
# Что программа ДОЛЖНА делать:
#   читает вес одного заказа в килограммах,
#   потом грузоподъёмность машины в килограммах,
#   печатает: Заказов: <сколько таких заказов влезет в машину>
#
# Пример:  вход 7, 30  ->  Заказов: 4   (четыре по 7 кг это 28, пятый не влезет)
#
# ВНИМАНИЕ: эта программа зависает — работает и не заканчивается.
# Останови её (Ctrl+C в окне IDLE), найди причину и исправь.
# Сохрани исправленную программу в свою папку как zadanie3.py

weight = int(input())
limit = int(input())
count = 0
free = limit
while free >= weight:
    count = count + 1
print(f"Заказов: {count}")

Задание 1 Пробег за смену

Программа читает число поездок, потом расстояние каждой поездки, и печатает суммарный пробег.

Вход

3
12
5
20

Вывод

Всего: 37 км

Симптом: ответ меньше правды. Похоже на последнюю введённую поездку.

Если застрял

Заполни трассировочную таблицу на трёх поездках: столбцы код, код, код. На каждом шаге смотри, чему равен код в начале шага.

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

Задание 2 Самый короткий заказ

Программа читает число заказов, потом расстояние до каждого, и печатает наименьшее.

Вход

3
12
5
20

Вывод

Минимум: 5 км

Симптом: ответ всегда один и тот же, какие числа ни вводи.

Если застрял

Условие код сравнивает прочитанное расстояние с тем, что уже лежит в код. Посмотри в отладчике, чему равно код перед первым сравнением, и спроси себя: может ли расстояние оказаться меньше?

И сразу про ловушку. Взять вместо нуля «заведомо большое» число (100, 1000) — не решение, а такая же ошибка: заказ может оказаться дальше. Начинать надо с первого прочитанного расстояния — тогда выдумывать ничего не приходится.

Задание 3 Сколько заказов увезёт курьер

Программа читает вес одного заказа и грузоподъёмность машины и печатает, сколько целых заказов помещается.

Вход

7
30

Вывод

Заказов: 4

Симптом: программа зависает. Останови её Ctrl+C в окне Shell.

Если застрял

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

Когда починишь, проверь ещё одну вещь: что будет, если груз влезает ровно впритык — скажем, вес 5 и грузоподъёмность 20. Ответ должен быть 4, а не 3. Отсюда видно, код в условии или код.

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

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

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

Подсказка: как работает Python и как искать ошибку

Кто стоит между программой и процессором

компиляторинтерпретатор
когда переводитвсю заранее, до запуска по ходу, строка за строкой
что остаётсяготовый файл (.exe) ничего, результат сразу
когда видно ошибкудо запуска, все сразу когда до неё дошло выполнение
языкиC, C++, PascalPython, JavaScript

У Python дорога длиннее: текст переводится в байт-код (папка код), а выполняет его виртуальная машина. Байт-код одинаков везде, машины написаны под каждую систему — поэтому программа переезжает с Windows на Linux без единой правки. Плата — скорость. Так же устроены Java (JVM) и C# (.NET).

Две разные беды, и лечатся по-разному

не запускаетсякрасный текст, SyntaxError, ValueError — читать последнюю строку сообщения: там что и где
работает, но врётошибок нет, ответ неправильный — трассировка, отладочный вывод, отладчик

Три инструмента

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

Отладчик IDLE за шесть шагов

  1. перейти в главное окно IDLE — то, где код;
  2. Debug → Debugger, в Shell появится [DEBUG ON];
  3. поставить галочки Locals и Globals — иначе значений не увидишь;
  4. вернуться в окно программы, F5 — встанет на первой строке;
  5. Step — шаг, Over — не заходя в функцию, Out — выйти из функции, Go — до точки останова, Quit — прервать;
  6. закончил — выключить тем же пунктом меню.

Точка останова: правой кнопкой по строке → Set Breakpoint, строка станет жёлтой. Go домчит до неё и остановится. В цикле незаменима — не нужно жать Step по сто раз.

Программа зависла

Ctrl+C в окне Shell: Python напечатает KeyboardInterrupt и покажет строку, на которой прервали, — она внутри вечного цикла. Дальше смотреть переменную из условия цикла: меняется ли она внутри? Не меняется — условие останется истинным навсегда.

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