Как скрыть отладочный вывод в Mathematica?

1423
Anonimous

Я хочу скрыть все выходные данные, созданные командой Print, из пользовательской функции, определенной в module .m.

Точнее проблема заключается в следующем:

У меня есть модуль, который решает какую-то конкретную задачу (не обязательно знать задачу для понимания вопроса). Я использую команду Print внутри модуля для вывода процесса оценки. Это полезно для отладки, но не для использования (весь внутренний вывод должен быть скрыт, когда пользователь вызывает функцию, объявленную в модуле).

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

Например, у нас есть 3 файла в одном каталоге. Можете ли вы предложить мне простой способ, как скрыть все выходные данные по умолчанию и распечатать все выходные данные в режиме отладки?

modul.m:

f[x_]:=Module[, y=Cos[x]*Sin[x]; Print["modul.m: y=",y]; Return[y]]; 

debugging.nb:

SetDirectory[NotebookDirectory[]]; << modul.m; x=10; f[x] (* print all inner output generated while f is evaluating*) x=20; f[x](* print all inner output generated while f is evaluating*) 

application.nb:

<< modul.m y=f[10]+f[20]; (* Hide all outputs of f during evaluation. Command ; doesn't work for this issue. *)  
2

1 ответ на вопрос

4
Szabolcs

Короткий ответ на этот вопрос заключается в том, что простой Print[]не является хорошим способом отладки большого пакета. Невозможно отключить его (надежным способом) только для вашего пакета, но не в других местах (его можно отключить глобально, проще всего Print; Unprotect[Print]; Print = Null &, но это сильно раздражает ваших пользователей)

Чтобы узнать, как лучше выводить отладочные сообщения и отключать их, см. Здесь:

https://stackoverflow.com/questions/8698754/message-generation-in-mathematica

Я подытожу Бретта Чемпиона и мои собственные ответы оттуда, так как лично (и субъективно) я считаю эти решения наилучшими, но, пожалуйста, прочитайте всю ветку там.


Ответ Бретта Чемпиона:

Используйте пользовательский символ для сообщений отладки (так же, как ваши функции пакета, вы можете поместить его в отдельный контекст, чтобы избежать коллизий), например так:

... debugPrint[expr] ... 

Затем определите PrintDebugфункцию следующим образом:

Attributes[PrintDebug]=  PrintDebug[expr_] := Block[, expr] 

Любой завернутый код PrintDebugбудет печатать сообщения. Если PrintDebugобертки нет, печать сообщений отключена.

MyFunction[1,2,3] // PrintDebug 

Кроме того, вы можете установить debugPrintглобальное значение, чтобы включить печать сообщений для всего или просто сделать $Pre = PrintDebug.


Мой ответ:

Мы также можем использовать встроенную Messageфункциональность для отладки:

debugPrint::msg = "Debug message: `1`";  debugPrint[msg_] := Message[debugPrint::msg, msg] 

Используйте функцию как это:

debugPrint["hello"] 

Выключите или включите такие сообщения:

Off[debugPrint::msg]  On[debugPrint::msg] 
Большое спасибо за ответ! Я выбрал первое решение (от Бретта Чемпиона), так как оно может работать с несколькими аргументами в debugPrint `debugPrint [" modul.m: y = ", y]; debugPrint [" modul.m: y = ", y," z = " , z]; `Но идея использования Message выглядит великолепно. Я бы хотел, чтобы была возможность определить debugPrint с неизвестным числом аргументов. Anonimous 12 лет назад 0
@Anonimous Когда вы используете `Message` версию` debugPrint`, вы можете либо поместить все в список, прежде чем передать его ему, `debugPrint []`, либо мы можем сделать что-то вроде `debugPrint [args__]: = Сообщение [debugPrint :: msg, StringJoin [ToString / @ ]] `для эмуляции` Print` (в отличие от `Print`, это теряет форматирование, поэтому вы не можете использовать его, например, с` Graphics` !) или `debugPrint [args__]: = Message [debugPrint :: msg, StringJoin [Riffle [ToString / @ ,", "]]]` `иметь аргументы, разделенные запятыми. Сохранение форматирования также возможно, но оно более продвинутое, поэтому я не буду вдаваться в подробности. Szabolcs 12 лет назад 0
@ Anonimous Я только что понял, что `StringForm` является вложенным, поэтому вы можете использовать основанный на сообщениях` debugPrint`, например, так: `` `debugPrint [StringForm [" x = ``, y = `` ", x, y]] `` `(или, может быть, интегрировать` StringForm` непосредственно в функцию) Szabolcs 12 лет назад 0

Похожие вопросы