Вы здесь

11. Отладка и трассировка программ

 

Отладка и трассировка программ

 

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

Но даже такой пользователь нуждается в специальных средствах диагностики и контроля программ. Чем их больше, тем совершеннее система программирования. При этом пользователь-программист должен заботиться и о том, чтобы такие средства входили в программные модули, которые создает он сам.

Некоторые правила культурного программирования

Выше мы описали множество методов программирования на языке системы Mathematica. Попробуем сформулировать некоторые общие правила так называемого культурного программирования с учетом специфики систем Mathematica, позволяющие создавать надежные и эффективные программные средства:

  • Тщательно продумайте алгоритм решения задачи. Порой выбор лучшего алгоритма позволяет кардинально повысить скорость вычислений и упростить программу (впрочем, одновременно это достигается далеко не всегда).
  • Используйте прежде всего возможности функционального программирования — из него родились основы языка программирования систем Mathematica.
  • Разделяйте задачу на малые части и оформляйте их в виде законченных программных модулей — прежде всего функций.
  • Pie скупитесь на программные комментарии — чем их больше, тем понятнее программа и тем больше шансов, что она заинтересует пользователей и будет долго жить. Учтите, что ясность программы в большинстве случаев важнее скорости ее работы.
  • Тщательно готовьте сообщения об ошибках и диагностические сообщения, а также наименования программных модулей и описания их назначения.
  • Тщательно производите диагностику программных модулей, в том числе с самыми безумными значениями и типами параметров — хорошо спроектированный модуль должен диагностировать любые виды ошибочных ситуаций и реагировать на них адекватным образом.
  • Используйте имена переменных и констант в стиле, принятом в Mathematica, и обязательно с использованием понятных по смыслу обозначений. По мере возможности не используйте в именах зарегистрированные идентификаторы команд и функций.
  • Заменяйте циклы функциями обработки списков, например функциями суммирования и произведения. Применяйте эффективные варианты упрощенных операторов и функций.
  • В максимальной степени используйте функции ядра системы. Обращайтесь к пакетам расширений только в том случае, когда это действительно необходимо.
  • Проводите тщательное тестирование своих модулей, в том числе с выполнением их трассировки. Помните, что нет программы, которую нельзя хоть чуть-чуть, но улучшить и сократить. Однако при этом цените затраченное на это время!
  • По мере возможности используйте готовые апробированные программные модули — изобретать велосипед и делать то, что уже сделано, неразумно.
  • Обращайте особое внимание на реализацию механизма контекстов, позволяющего избежать грубых ошибок при модернизации различных объектов программ, прежде всего наборов функций.
  • Не слишком оригинальничайте! Не применяйте программные трюки и недокументированные приемы программирования. Такие программы в момент создания могут выглядеть удивительно эффектными и потрясающе оригинальными, но вполне возможно, что в следующей версии системы они перестанут работать вообще, поскольку разработчики обычно стараются исключить любые недокументированные трюки в своих программах.

Применение этих рекомендаций на практике позволит вам создавать программы, которые нужны не только вам, но и многим пользователям системы Mathematica. Только такие программы могут быть размещены в Интернете и, вполне возможно, войти в пакеты расширения и электронные книги системы Mathematica.

Трассировка программных модулей

В практике подготовки и отладки программ важное значение имеет наличие специальных средств отладки программ по шагам — средств трассировки. Mathematica имеет ряд функций для осуществления трассировки своих программных конструкций.

Функция Trace [ехрг] позволяет выполнить трассировку выражения ехрг. Возьмем простой пример — вычисление выражения 2 (3 + 4) 2 /5:


Trace[2 (3 + 4)^2 / 5]

{{{{3+4, 7 },7^2,49}, {1/5,1/5}, 49/5, 49/5}, 249/5, 98/5}

Результат трассировки представлен вложенными списками, имеющими два элемента — вычисляемое выражение и результат вычислений. В частности, для приведенного примера отчетливо видно, что вначале вычисляется выражение в круглых скобках (3 + 4) и получается результат 7, который затем возводится в квадрат — получается число 49. Затем вызывается явно не записанная единица для деления на 5, потом 49 умножается на 1/5 и, наконец, 49/5 умножается на 2 и получается конечный результат. Отсюда ясно, что даже равноценные операции умножения и деления Mathematica разделяет по приоритету — деление выполняется перед умножением! Символьные операции также могут трассироваться:


Trace[а*а/(b*b)]

{{ {{bb,b^2}, 1/b^2, 1/b^2}, aa/b^2, a^2/b^2}

Можно выполнить и трассировку рекуррентных вычислений. Ниже представлен пример трассировки вычисления чисел Фибоначчи:


fib[n_] := fib[n - 1] + fib[n - 2]

fib[0] = fib[l] = 1

1

Trace[fib[5], fib[n_] -> n]

{5, {4, {3, {2, {!}, {0}}, {!}}, {2, {1}, {0}}},

{3, {2, {!}, {0}}, {!}}}

Trace[fib[3]]

{fib[3], fib[3-l] + fib[3-2] ,

{{3- 1, 2}, fib[2] , fib[2-l] + fib[2- 2] , {{2-1, 1}, fibtl], 11, {{2-2, 0}, fib[0] , 1}, 1+1, 2},

{{3-2, 1}, fib[l], 1}, 2+1, 3}

Функция TracePrint [expr] дает распечатку последовательности действий при вычислении выражения ехрг:


TracePrint[a*b/c]

ab/c

Times а b _1 с

Power

1/c

ab/с

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

 

Что нового мы узнали?

В этом уроке мы научились:

  • Работать с образцами.
  • Создавать функции.
  • Использовать функции FixedPoint и Catch.
  • Реализовывать рекурсивные и рекуррентные алгоритмы.
  • Использовать процедуры.
  • Создавать циклы различного типа.
  • Использовать условные выражения и безусловные переходы.
  • Работать с контекстами.
  • Готовить пакеты расширений системы Mathematica.
  • Создавать простейшие средства визуального программирования.
  • Использовать средства отладки и трассировки программ.

 


Top.Mail.Ru