Просмотр усеченных сообщений в Mathematica

Можно ли увидеть полную версию Message, которая была усечена? IE, я вижу что-то вроде 0.105309,0.394682,<<20>>,<<20>>,<<20>>,0.394631 в окне Messages. Я предполагаю, что <<20>> представляет собой пропущенные части, как мне получить все это?

Вызывается функция FindMaximum для задачи с 50 переменными.

Обновление: Ответ Саймона, похоже, работает для общих сообщений, также я нашел подход, специфичный для захвата сообщения FindMaximum «не настоящее число».

Чтобы получить точку, которая приводит к сбою FindMaximum с сообщением «не настоящее число», вы можете сделать следующее (переопределение Message — единственный подход, который я смог найти, потому что точка не передается EvaluationMonitor или StepMonitor)

Unprotect[Message];
Message[FindMaximum::"nrnum", args___] := (captured = {args}; 
   Print["Captured FindMaximum::nrnum at ", First[{args}]]);
{badvals, badvars, badobj} = ReleaseHold[captured];

person Yaroslav Bulatov    schedule 24.11.2010    source источник
comment
Я не думаю, что он сохраняет сообщения, которые отключены (по крайней мере, те, которые используют механизм Off[]). Смотрите мои комментарии ниже.   -  person Simon    schedule 25.11.2010
comment
@Simon Недокументированная функция Internal`HandlerBlock позволяет перехватывать сообщения, которые отключены. Смотрите мой ответ ниже.   -  person Alexey Popkov    schedule 17.08.2011


Ответы (4)


Я не уверен, что вы можете восстановить длинное сообщение, которое уже было создано. Поскольку $MessageList и Message[] хранят только имена сообщений, а не переданные им аргументы.

Чтобы запретить автоматическое применение Short[] к сообщениям, вы можете Unset[$MessagePrePrint]. Значение по умолчанию — Automatic — что бы это ни влекло за собой.


Вместо того, чтобы постоянно печатать длинные сообщения, может быть лучше использовать что-то вроде

General::longmsg="A long message (`1`) was produced. The full message has been saved in `2`";
$MessagePrePrint=With[{bc=ByteCount[#]},If[bc>65536,
  With[{fn=FileNameJoin[{$HomeDirectory,StringJoin["MmaMsg",ToString/@DateList[]]}]},
    Put[#,fn];Message[General::longmsg,bc,Row[{fn}]];Short[Shallow[#],1]],
  #]]&;

Это распечатает сообщение как обычно, если только ByteCount не слишком велико (> 65536), и в этом случае будут распечатаны два сообщения: первое информирует вас о том, что было создано большое сообщение, и дает вам файл, в котором оно было сохранено. Второй — это усеченная версия полного сообщения.

person Simon    schedule 24.11.2010
comment
Я тоже собирался предложить $MessagePrePrint. Кажется, путь. - person Dr. belisarius; 24.11.2010
comment
Это здорово, даже независимо от платформы, определенно войдет в мой набор инструментов. - person Yaroslav Bulatov; 25.11.2010
comment
Кстати, кажется, MessagePrePrint вызывается даже для сообщений, которые не печатаются. В итоге я получил сотни файлов, потому что какая-то подпрограмма LinearAlgebra, вызванная из FindMaximum, вызывает MessagePrePrint с плотными матрицами 100x100 в качестве входных данных. Я предполагаю, что обычно вы их не видите, потому что это сообщение отключено. - person Yaroslav Bulatov; 25.11.2010
comment
Сообщения нельзя отключить. Вы можете проверить это, используя приведенный выше код и запустив Off[General::argx]; Message[General::argx, 1, Range[1000]], который не печатает сообщения и не создает файл. Это должно быть что-то другое. - person Simon; 25.11.2010
comment
На самом деле вы можете проверить, что если сообщение Off, то $MessagePrePrint даже не вызывается. Просто установите $MessagePrePrint = (Print["hi there"]) &; и вызовите различные сообщения On и Off. - person Simon; 25.11.2010
comment
О, я думаю, вы правы, это может быть следствием того, что я одновременно пробовал и ваш ответ, и ответ Эндрю Мойлана, и я не могу воспроизвести его снова. - person Yaroslav Bulatov; 25.11.2010

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

Block[{Message = f}, ...]

Например, вы можете использовать

f[args___] := Print[{args}];

Опять же, не перед Mathematica прямо сейчас. Пожалуйста, не стесняйтесь редактировать этот ответ в вики.

person Community    schedule 24.11.2010
comment
Кажется, это захватывает сообщения, которые обычно не выводятся в окно сообщений. - person Yaroslav Bulatov; 25.11.2010

Недокументированная функция Internal`HandlerBlock (раскрыта Максимом Рытиным) здесь применимо:

Off[FindMaximum::"nrnum"]
Internal`HandlerBlock[{"Message", Print}, 
 Message[FindMaximum::"nrnum", arg1, arg2, arg3]]
(* => Hold[Message[FindMaximum::nrnum,arg1,arg2,arg3],False]*)

Другой тип обработчика — «MessageTextFilter». «Сообщение» вызывается для каждого сгенерированного сообщения и передает один аргумент формы Hold[..., ...] в функцию-обработчик, а второй элемент имеет значение False для скрытых сообщений. «MessageTextFilter» вызывается для сообщений, которые фактически распечатываются, и вызывает функцию с тремя аргументами.

Максим Рытин


Другая возможность состоит в том, чтобы изменить $MessagePrePrint таким образом, чтобы он печатал сообщения, содержащие встроенные ячейки с усеченными аргументами, которые могут быть расширены до полных аргументов при оценке. Это можно сделать с помощью Interpretation:

truncatingRules = {lst : {x_, y__} /; 
     MatrixQ[lst, NumberQ] && Length[lst] > 3 :>
    {x /. v : {a_, b__} /; Length[v] > 3 :>
       {a, 
        Interpretation[Style[Skeleton[Length[{b}]], Gray], 
         Sequence @@ {b}]},
     Interpretation[Style[Skeleton[Length[{y}]], Gray], 
      Sequence @@ {y}]},
   lst : {x_, y__} /; VectorQ[lst, NumberQ] && Length[lst] > 3 :>
    {x, Interpretation[Style[Skeleton[Length[{y}]], Gray], 
      Sequence @@ {y}]}};

InlineCellInsideMessage[expr_] := 
 Style[DisplayForm[
   Cell[BoxData[MakeBoxes[expr, StandardForm]], "Input"]], 
  FontWeight -> Bold, FontFamily -> "Courier", Background -> Yellow, 
  FontColor -> Red, FontSize -> 12, StripOnInput -> True, 
  AutoNumberFormatting -> True, ShowStringCharacters -> True]

$MessagePrePrint = 
 Function[expr, 
  If[TrueQ[ByteCount[Unevaluated[expr]] < $OutputSizeLimit/20.], 
   InlineCellInsideMessage[expr],
   InlineCellInsideMessage[expr /. truncatingRules]
   ]]

Конечно, приведенная выше версия $MessagePrePrint — это всего лишь набросок, но он иллюстрирует основную идею.

person Alexey Popkov    schedule 17.08.2011

Цитирование этой ссылки:

«Когда вы выполняете символьные вычисления, довольно легко получить чрезвычайно сложные выражения. Часто вам даже не захочется видеть полный результат вычисления».

Вы можете управлять своим дисплеем с помощью Short.

Short[%, n] отобразит n строки вашего предыдущего результата, так что это может быть то, что вам нужно.

Подробнее здесь.

person darioo    schedule 24.11.2010
comment
Я не понимаю, как использовать это, чтобы получить информацию, которая попала в окно сообщения. - person Yaroslav Bulatov; 24.11.2010
comment
@Ярослав: хорошо, какую команду вы выполнили, чтобы получить описанный вами результат? - person darioo; 24.11.2010
comment
НайтиМаксимум. Обратите внимание, что я говорю о сообщениях, а не о выводе команды - person Yaroslav Bulatov; 24.11.2010
comment
@Ярослав: а, теперь твой вопрос понятнее. Извините, я не могу вам помочь прямо сейчас, потому что у меня не установлена ​​Mathematica... - person darioo; 24.11.2010