Другие статьи автора – http://twt.mpei.ac.ru/ochkov/work2.htm (in Russian)
http://twt.mpei.ac.ru/ochkov/work2_eng.htm (in English)
Статья написана в 2000 году. Более поздние правки выделены синим цветом.
В. Очков
«Обманки» –
это, если справиться на сайте «Кирилл и Мефодий» (www.km.ru),
минералы «прикидывающиеся» металлами:
Есть еще одна
– искусствоведческая «нагрузка» этого слова, связанная, например, с фарфоровыми
безделушками. На столе лежит, к примеру, помидор, но это вовсе не помидор, а…
масленка. Можно говорить и о программистских обманках – вольных или
невольных ошибках и опечатках, которые в одной ситуации могут позабавить
программиста, подсказать ему пути совершенствования используемых
инструментальных средств, а в другой… свести его с ума.
Каждый, кто когда-либо занимался программированием, знает, что написать программу несложно за пару минут, но искать в ней ошибку можно неделями. Сроки (минуты – недели), конечно, условные, но затронутая проблема – вполне реальная.
Все профессиональные
программные оболочки (Visual Basic,
Visual
C, Delphi и др.) оборудованы
средствами отладки, помогающими
локализовать и ликвидировать ошибки. Debugger – так эти
средства называются по-английски. Интересна история (этимология) этого слова.
Вот, как переводит слово bug компьютерный переводчик:
Рассказывают такую историю[1]. Во внутренностях одного из первых компьютеров застрял таракан (a bug), обуглился и закоротил провода. Поиск и удаление (de) этого таракана потребовало времени. Отсюда, говорят, и пошел термин debugging:
Физико-математический пакет Mathcad[2] (www.mathcad.com) сделал невозможными или, правильнее сказать, быстроустранимыми традиционные ошибки традиционного программирования. Вернее, даже не ошибки, а опечатки – «очепятки», когда в операторе, кодирующем формулу для расчета, вместо двойки записана тройка, а вместо знака умножения – знак сложения. Такие ошибки стали редкими потому, что в среде Mathcad результат расчета по формуле можно сразу отобразить числом, графиком или даже компьютерной анимацией. Такое «утяжеление» Mathcad-документов преследует чисто образовательные цели, но одновременно («фоново») служит и для контроля за правильностью формул. Если вдобавок все переменные расчета размерные (см. статью автора «Mathcad и Maple: работа с размерными величинами» http://twt.mpei.ac.ru/ochkov/Unit_MC_MP/Unit_MC_MP.htm), то это дает дополнительный контроль за формулами – не складываются метры с килограммами, грубо говоря[3].
Но Mathcad, делая невозможными «старые, традиционные» ошибки (опечатки), привнес в процесс создания научно-технического расчетного проекта, новые ошибки («глюки», «заморочки», «жучки», «bugs»), связанные особенностями этой математической компьютерной среды. Эти особенности и будут описаны в статье, второе название которой (MathcadBugHouse) можно перевести как «Сумасшедший дом Mathcad». Так, кстати, и называется один из форумов Internet-конференции по Mathcad (Collaboratory – см. статью «Mathcad и Internet или Сетевой колхоз» http://twt.mpei.ac.ru/ochkov/Collab/Collab.htm), где некоторые примеры статьи были уже опубликованы и обсуждены (см. http://collab.mathsoft.com/~mathcad2000/read?15489,11).
Итак, Mathcad-обманки!
В среде Mathcad сняты некоторые ограничения на имена пользовательских констант, переменных[4] и функций[5]. В имена Mathcad-переменных можно, например, вводить[6] пробелы. Ограничение на цифру в качестве первого[7], а тем более единственного символа имени, естественно, осталось. «Обойти» это ограничение можно, поставив первым символом имени переменной пробел. Это позволяет создавать такие «сумасшедшие» Mathcad-документы – см. рис. 1.
Переменные на рис. 1 имеют имена не 3 и 7, а пробел3 и пробел7, но пробел на то он и пробел, что его не видно ни на экране дисплея, ни на бумаге принтера. Имя переменной или функции может состоять только из пробелов (одного или нескольких). Такая переменная невидима на экране дисплея или бумаге принтера, что может быть полезно при решении специфических задач, некоторые из которых приведены в статье автора «Переменная-невидимка» – http://twt.mpei.ac.ru/ochkov/Invisible/Index.htm.
В среде Mathcad невидимой может быть не только переменная или часть переменной (часть имени переменной – см. рис. 1), но и один из встроенных операторов – оператор умножения. Если «сумасшедшая» ситуация, зафиксированная на рис. 1, довольно искусственна, то ситуация, отмеченная на рис. 2, вполне реальна[8].
Если от двух отнять единицу (а это именно числа 2 и 1, а не переменные, подобные тем, какие показаны на рис. 1), то должна получиться единица, но уж никак не двойка, да еще и с минусом. Секрет «фокуса» прост, но эта простота уж точно «хуже» воровства: между числами 2 и –1 «затесался» невидимый знак умножения.
Пробел между константами[9] может означать не только умножение, но и сложение, например. Так, видя запись 1 ч 20 мин, мы не перемножаем, а складываем эти две величины (см. центральный пробел; два боковых пробела означают умножение). Тут может фигурировать и союз «и» (1 ч и 20 мин), который опять же (в свою очередь) неоднозначен по своему математическому смыслу. Дело в том, что оператор «и» (and) нагружен функцией логического умножения (1 и 1 = 1, 1 и 0 = 0, 0 и 1 = 0, 0 и 0 = 0). Можно сказать, что союз (оператор) «и» контекстно зависим, что также может «сводить с ума» пользователей Mathcad – см. рис. 3:
В Mathcad-документе на рис. 3 пользовательская функция (оператор) и определяется, а затем переопределяется, но в Mathcad-документе могут «мирно сосуществовать» одноименные переменные и функции, что с точки зрения традиционного программирования является полным абсурдом. Об этой особенности Mathcad мы поговорим позже. А сейчас вопрос читателю! Чему равна производная функции хn? Почти все ответят nxn-1 и будут не правы, вернее, частично правы – см. рис. 4.
Символьная математика пакета Mathcad[10] дает иной ответ: производная от хn равна… xn ln x. В чем тут дело!? А вот второй вопрос. Чему равен корень уравнения ах = b? Вот какой ответ дала команда Solve – рис. 5:
Таких «сумасшедших» примеров можно привести множество. Секрет (a bug) рис. 4 и рис. 5 лежит в таком понятии как умолчание. Вернее, в некоторых условностях постановки математических задач – нами всегда умалчивается о том, что х – это переменная (неизвестное), а n, a и b – константы. Mathcad таких условностей не признает и выдает неправильный с точки зрения человека ответ, если пользователь перед отдачей команд символьной математики из группы Variable (команды, относящиеся к переменным) ошибочно укажет не ту переменную. Ошибка усугубляется еще и тем, что Mathcad в комментариях (by differentiation, yields; has solution(s) и т.д.) не отмечает переменную, по которой проводилась та или иная команда символьной математики.
В этом отношении более удобны операторы символьных преобразований, в которых нужная переменная выделена явно – см. рис. 6.
Но тут могут быть коллизии. Еще один вопрос – чему равна производная от хх? Вот что может выдать Mathcad – см. рис. 7:
«Фокус» рис. 7 в том, что выражение хх имеет две разные переменные х, а в первом операторе вдобавок дифференцирование ведется по третьей переменной x. Такое не только возможно, но и в ряде случаев и необходимо в среде Mathcad. В расчете можно, например, иметь одноименную функцию и переменную и т.д. Еще одна особенность Mathcad, отличающая этот пакет от традиционных языков программирования и могущая быть причиной неприятных ошибок, – это возможность переопределения встроенных функций и операторов. В «ручных» расчетах мы часто имеем одноименные, но разные переменные, не замечая это, не видя в этом проблемы. Mathcad такие «глюки» не пропускает – см. рис. 8.
Решение проблемы в разделении переменных – см. рис. 9:
Mathcad допускает в расчете до восьми одноименных (в Mathcad 11 , до девяти, а в Mathcad 12-14 - опять до восьми), но разных переменных. У семи из них могут совпадать даже имена стилей, что делает их совсем уж неотличимыми – см. рис. 10:
Одноименные, но разные переменные и функции – это очень мощный инструмент решения задач. Но это, как и любой другой мощный инструмент, – очень опасный инструмент, неумелое обращение с которым приводит к ошибкам, способным свести с ума пользователя Mathcad.
Вот еще два «глюка».
Пример на рис. 11 подчеркивает простое правило – если ты не работаешь с единицами измерения, то отключи их:
Иначе они (системные переменные, хранящие единицы измерения: W – ватт, например) могут тебе много крови попортить.
С другой стороны, эти же единицы могут подправить ошибки и промаши пользователя – см. рис. 12:
На рис. 12 по пользовательской функции V(h) строится график, но если пользователь захочет вызвать какое-либо значение функции V, то ничего из этого не выйдет – ошибка будет: несовместимые единицы измерения.
А вот еще одна Mathcad-обманка (рис. 13), которую автор поместил в Internet на сайте Collaboratory (http://twt.mpei.ac.ru/ochkov/Collab/Collab.htm) с такой припиской, которая остается в силе и для читателей этой статьи: «Если кто отгадает тайну рис. 13, то он получит от автора 100$. Если кто захочет узнать эту тайну, то он ее узнает. За те же 100$.». А тайна такая – локальные функции внутри другой функции в среде Mathcad создавать нельзя (до Mathcad 12). Но если нельзя, но очень хочется, то… см. рис. 13, где внутри функции Min_GR находится функция Golden_Ratio, локальность которой еще раз подчеркнута последним оператором программы.
Ну и совсем простейшая обманка (рис. 14):
Еще одна обманка, которая, тем не менее, позволяет восстановить логику традиционных записей формул:
Автор один раз переводил английский текст с помощью компьютерного переводчика. В тексте было слово Mathcad, которое машинный переводчик разделил на две половинки – Math cad. Так вот как было переведено слово cad:
Пару же слов Math cad можно перевести как… математический хулиган. Это недалеко от истинны, если учесть вышеприведенные примеры.
Еще одна (забытая - см. рис. 14)обманка (6 февраля 2009 г.): 2h это не только 2 помножить на h, но и двойка по шестнадцатеричной системе исчисления.
Автор (ochkov@twt.mpei.ac.ru) ждет от читателей новых примеров Mathcad-обманок.
[1] Computer Science уже обрастает преданиями и даже легендами.
[2] Разработка фирмы MathSoft
Engineering and Education, Inc. (www.mathsoft.com).
[3] Все, кто когда-либо публиковался в журналах или выпускал книги, знает о таком неприятном моменте: раскрывается сигнальный, пахнущий типографской краской экземпляр журнала или книги, и первое, что бросается в глаза – это… досадные опечатки. Над орфографической ошибкой можно посмеяться, но ошибка в формуле может быть причиной крупной неприятности. Будем надеяться, что такую формулу не введут в компьютер, управляющий сложным технологическим процессом. Но студент, вводящий такую формулу в свой компьютерный курсовой проект, может помучиться. Сейчас почти все книги и журнальные статьи набираются на компьютерах. Для ввода формул при этом используют разного рода научные (формульные) редакторы – Word Equation, LaTeX и т.д. Здесь лучше бы использовать математических пакетов со встроенными средствами проверки формул. Рассказывают такую историю про академика Крылова. Когда он окончил университет и пошел устраиваться в одну инженерную фирму, то ему дали на проверку прект одного моста. На следующее утро Крылов прибегает на фирму и уже с порога кричит: «Этот мост нельзя строить – он обвалится!». Правильно, – ответили ему, – Он был построен и тут же развалился. Поздравляем – вы приняты на работу».
[4] Константа – это переменная, значение которой постоянно в данной задаче. Об этом ниже.
[5] В среде Mathcad функциональные зависимости реализованы в виде функции (sin (0.5), например) и операторов (5!). Функция характеризуется именем, а оператор – символом. Есть и другие внешние отличия.
[6] Нажатие клавиши «пробел» расширяет область охвата пробелом текущую Mathcad-оператора. Глушится эта и другие спец. команды через аккорд Shift+Ctrl+k.
[7] В среде Mathcad есть переменные, которые могут начинаться только с цифры или даже числа: 1K, 28.56M и т.д. Суффиксы M, L, T, Q, K, S и C связаны с семью основными размерностями SI: масса, длина, время, электрический ток, количество вещества и сила света, соответственно.
[8]Один коллега автора из-за этой ситуации переинсталлировал Mathcad, считая, что он (Mathcad или «коллега») «сошел с ума».
[9] В среде Mathcad между сомножителями допустимо убрать даже пробел: 2K и т.д. Пользователь Mathcad вправе выбирать символы умножения, деления, взятия производной и др., подстраивая документ под оптимальное восприятие (чтение).
[10] Она взята из пакета Maple.