next up previous contents
Далее: Определения функций Наверх: Курс языка Python для начинающих Назад: Выбор   Содержание

В этой главе

Отладка программ

Что такое отладка?

Как только мы начали программировать, к нашему удивлению, мы обнаружили, что оказалось не так просто писать правильные программы, как мы думали. Я помню точный момент, когда я понял, что значительная часть моей жизни, начиная с этого мгновения, будет потрачена на отыскивание ошибок в моих собственных программах.

- Морис Вилкс открывает для себя отладку программ, 1949г.

К этому времени, если вы пытались программировать самостоятельно, вероятно, вы обнаружили, что иногда программа делает не то, что вы ожидали. Это вполне обычное явление. Отладка – это процесс понимания, что делает компьютер и затем принуждения его делать то, что хотите вы. Это может быть достаточно сложно. Однажды я потратил почти целую неделю, чтобы найти и устранить ошибку, которая произошла из-за того, что кто-то написал x вместо y.

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

Что должна делать программа?

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

ширина длина периметр
3 4 14
2 3 10
4 4 16
2 2 8
5 1 12

Я запускаю программу для всех начальных данных и проверяю, делает ли программа то, что я от нее ожидаю. Если нет, то необходимо понять, что же делает компьютер.

Чаще всего, для каких-то данных программа будет работать, а для каких-то – нет. В этом случае вы должны разобраться, что общего между теми начальными данными, для которых программа работает правильно. Например, вот результат работы программы для вычисления периметра (программа будет приведена ниже):

Height: 3
Width: 4
perimeter =  15
Height: 2
Width: 3
perimeter =  11
Height: 4
Width: 4
perimeter =  16
Height: 2
Width: 2
perimeter =  8
Height: 5
Width: 1
perimeter =  8

Заметьте, что программа не работает для первых двух наборов данных, работает для следующих двух и не работает для последнего. Попробуйте понять, что общего между третьим и четвертым случаем. Если вы поймете, в чем проблема, становится легче найти причину. Для ваших программ попробуйте дополнительные данные, если вам это необходимо.

Что делает программа?

Далее необходимо взглянуть на программу. Одна из самых важных вещей в программировании – умение читать программы. Основной способ для этого – просчет программы вручную.

Этот процесс начинается с первой строки и продолжается до конца программы. Циклы while и команды if означают, что некоторые команды, возможно, не выполнятся, а некоторые выполнятся много раз. Для каждой команды выясните, что сделал Python.

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

height = input("Height: ")
width = input("Width: ")
print "perimeter = ",width+height+width+width

Вопрос: Какую команду Python выполняет первой?

Ответ: Первая строка всегда выполняется первой. В данном случае это: height = input("Height: ")

Вопрос: Что делает эта команда?

Ответ: Выводит Height: , ждет, пока пользователь напечатает число и сохраняет его в переменной height.

Вопрос: Какую команду Python выполняет следующей?

Ответ: Обычно, это следующая строка, которая в данном случае: width = input("Width: ")

Вопрос: Что делает эта команда?

Ответ: Выводит Width: , ждет, пока пользователь напечатает число и сохраняет его в переменной width.

Вопрос: Какую команду Python выполняет следующей?

Ответ: Если следующая строка начинается с той же позиции, что и предыдущая, то выполняется она. В нашем случае: print "perimeter = ", width+height+width+width (возможно, в этой строке произойдет вызов функции, но это мы рассмотрим в последующих главах).

Вопрос: Что делает эта команда?

Ответ: Сначала она выводит perimeter =, затем величину width+height+width+width.

Вопрос: А правильно ли вычисляет периметр выражение width+height+width+width?

Ответ: Периметр прямоугольника равен его нижняя сторона (width) плюс левая сторона (height) плюс верхняя сторона (width) плюс правая сторона (width, вот оно!). Последнее слагаемое должно быть height, а не width.

Вопрос: Понимаете, почему иногда периметр вычислялся правильно?

Ответ: Он вычислялся правильно, если длина и ширина были равны.

Следующая программа, которую мы будем просчитывать вручную, должна выводить пять точек на экран. Однако выводит она следующее:

. . . .

А вот и программа:

number = 5
while number > 1:
    print ".",
    number = number - 1
print

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

Вопрос: Какая команда выполнится первой?

Ответ: Первая строка файла: number = 5.

Вопрос: Что делает эта команда?

Ответ: Записывает число 5 в переменную number.

Вопрос: Какая команда выполнится следующей?

Ответ: Следующая команда while number > 1:

Вопрос: Что делает эта команда?

Ответ: Команда while проверяет выражение, содержащееся в ней, и, если оно истинно, выполняет следующую команду в выделенном блоке, в противном случае пропускает весь следующий блок.

Вопрос: Итак, что же делает эта команда сейчас?

Ответ: Если выражение number > 1 истинно, то будут выполнены следующие две команды.

Вопрос: А number > 1 истинно?

Ответ: Последняя величина, содержащаяся в number, была 5, 5 > 1, поэтому да.

Вопрос: Какая команда выполняется следующей?

Ответ: Поскольку while истинно, следующая команда: print ".",

Вопрос: Что делает эта команда?

Ответ: Выводит одну точку; поскольку команда заканчивается запятой (,), следующая команда print продолжит печатать на той же строке без перехода на новую.

Вопрос: Какая команда выполняется следующей?

Ответ: number = number – 1, поскольку не появились никакие новые блоки (начинающиеся с другой позиции строки).

Вопрос: Что делает эта команда?

Ответ: Она вычисляет number – 1, то есть от текущего значения number (или 5) вычитает 1 и записывает результат в number. Иными словами, она меняет значение number с 5 на 4.

Вопрос: Какая команда выполняется следующей?

Ответ: Блок закончился (следующая строка начинается с первой позиции), необходимо вернуться к команде управления. Это цикл while, который выглядит так: while number > 1:

Вопрос: Что происходит в цикле?

Ответ: Величина number, то есть 4, сравнивается с 1. Поскольку 4 > 1, цикл while продолжается.

Вопрос: Какая команда выполняется следующей?

Ответ: Поскольку условие в while было истинным, следующая команда: print ".",

Вопрос: Что делает эта команда?

Ответ: Выводит вторую точку на той же строке.

Вопрос: Какая команда выполняется следующей?

Ответ: Блок продолжается, поэтому следующая команда: number = number – 1.

Вопрос: А что она делает?

Ответ: Берет текущее значение number (4), вычитает из него 1, получая 3 и, наконец, записывает 3 как новое значение number.

Вопрос: Какая команда выполняется следующей?

Ответ: Поскольку мы снова дошли до конца блока (новая строка начинается с первой позиции), следующая команда: while number > 1:

Вопрос: Что делает эта команда?

Ответ: Сравнивает текущую величину number (3) с 1. 3 > 1, поэтому цикл while продолжается.

Вопрос: Какая команда выполняется следующей?

Ответ: Условие в цикле while было истинным, поэтому следующая команда: print ".",

Вопрос: А что она делает?

Ответ: Выводит третью точку.

Вопрос: Какая команда выполняется следующей?

Ответ: number = number – 1

Вопрос: Что она делает?

Ответ: Берет текущее значение number (3), вычитает из него 1, получая 2 и, наконец, записывает 2 как новое значение number.

Вопрос: Какая команда выполняется следующей?

Ответ: Возвращаемся назад к условию цикла: while number > 1:

Вопрос: И что происходит далее?

Ответ: Сравнивается текущая величина number (2) с 1. 2 > 1, поэтому цикл while продолжается.

Вопрос: Какая команда выполняется следующей?

Ответ: Поскольку цикл while продолжается: print ".",

Вопрос: Что делает эта команда?

Ответ: Она открывает смысл жизни. Я шучу. (Мне было необходимо убедиться, что вы еще не спите). Команда выводит четвертую точку.

Вопрос: Какая команда выполняется следующей?

Ответ: number = number – 1

Вопрос: Что делает эта команда?

Ответ: Берет текущее значение number (2), вычитает из него 1, получая 1 и, наконец, записывается 1 как новое значение number.

Вопрос: Какая команда выполняется следующей?

Ответ: Возвращаемся назад к условию цикла: while number > 1:

Вопрос: Что делает эта команда?

Ответ: Сравнивает текущую величину number (1) с 1. 1 > 1 – ложно (один не больше одного), поэтому цикл заканчивается.

Вопрос: Какая команда выполняется следующей?

Ответ: Поскольку условие цикла while ложно, пропускаем весь блок, следующая команда print

Вопрос: Что делает эта команда?

Ответ: Переводит печать на следующую строку.

Вопрос: Почему программа не печатает 5 точек?

Ответ: Цикл закончился на одну точку раньше.

Вопрос: Как это можно исправить?

Ответ: Заканчивать цикл на одну точку позже.

Вопрос: А как это сделать?

Ответ: Существует несколько способов. Один из них – изменить цикл while следующим образом: while number > 0: Другой способ изменить условие на number >= 1: Существуют и другие варианты.

Как исправить программу?

Вам нужно понять, что делает программа. Также нужно понять, что программа должна делать. Выясните, в чем разница между этим. Отладка программ – это навык, который приходит с опытом. Если вы не можете сделать это примерно за час, отвлекитесь, обсудите проблему с кем-нибудь или посмотрите на себя в зеркало. Вернитесь к проблеме через некоторое время, скорее всего, у вас появятся новые соображения или идеи. Удачи вам.


next up previous contents
Далее: Определения функций Наверх: Курс языка Python для начинающих Назад: Выбор   Содержание
Джош Коглиати jjc@honors.montana.edu Версия Wikibooks: Курс языка Python Для начинающих на Wikibooks