Skip to main content
edited tags
Link
Alexey Popkov
  • 62.3k
  • 7
  • 154
  • 375
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

Let's say I'm debugging a program step by step and want to Print some expressions (using ShowItusing ShowIt, for example).

Is there a way to output the result of Print on top of already printed expressions instead of at the bottom?

Let's say I'm debugging a program step by step and want to Print some expressions (using ShowIt, for example).

Is there a way to output the result of Print on top of already printed expressions instead of at the bottom?

Let's say I'm debugging a program step by step and want to Print some expressions (using ShowIt, for example).

Is there a way to output the result of Print on top of already printed expressions instead of at the bottom?

deleted 4454 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131

EDIT

For the record, this version of ShowIt is particularly useful, it can be used in conjunction with ReapTags defined here http://stackoverflow.com/a/6245166/884752. To see the list of keys defined in the debugSymbol containing the results extracted from a program you can use the function Keys defined in http://mathematica.stackexchange.com/a/999/66. I've also incorporated the answer of Szabolcs into ShowIt, the answer of Mr. Wizard to the question Delete contexts from a string representation of a symbol and the answer to this question How to Print to the Console.

  • The Print output using \$ShowIt = True allows to use it in the front end if you change its style to Input.
  • \$ReverseIt = True allows to Print the result of Print in a reverse order as asked in this question.
  • The Message if you switch it on using On[Debug::ShowIt] prints a Mathematica message and would stop the code if you used a message breakpoint in Mathematica or Wolfram Workbench.
  • \$SowIt = True allows to store what would be printed with Print in a symbol.
  • $ConsoleIt = True allows to output what would be output with Print but in the Messages console accessible in the menu Window>Messages.
  • The System` context of ShowIt and ShowItList allows to use them in the Private` context of other packages without having to define the package in which these functions are defined (in BeginPackage, see here for more info on the organisation of packages).

All in all ShowIt and the functions around it show a lot of different aspects of advanced evaluation in Mathematica that could be interesting to a lot of people.

SetAttributes[ExtractSymbolName, HoldAll];
ExtractSymbolName[expr_] :=
Module[{T,SR = StringReplace[#, a__ ~~ "$" ~~ DigitCharacter .. :> a] &}, 
    Defer[expr] 
        /. s_Symbol :> T@MakeExpression@SR@SymbolName@Unevaluated@s 
        /. T@_@x___ :> x
];

insertBelowEvaluationCell[expr_]:=
(
    SelectionMove[EvaluationNotebook[],After,EvaluationCell];
    NotebookWrite[EvaluationNotebook[],Cell[BoxData@ToBoxes[expr],"Print"]]
);

$OldLine = -1;
SetAttributes[PrintToConsole, HoldFirst];
PrintToConsole[expr_] := 
(
    SelectionMove[MessagesNotebook[], After, Cell];
    NotebookWrite[
        MessagesNotebook[], 
        Cell[BoxData[ToBoxes[Defer@expr]], "Print", 
         CellLabel ->  "During evaluation of In[" <> ToString[$Line-1] <> "]:=", 
         ShowCellLabel -> ($OldLine =!= $Line)]
    ];
    $OldLine = $Line;
);

System`Debug::ShowIt = "`1`";
Off[Debug::ShowIt];
SetAttributes[System`ShowIt, HoldAll];
System`ShowIt[expr__] := System`ShowIt[{expr}];
System`ShowIt[expr_] :=
With[{evaluatedExpr = expr,exprWithSymbolNamesCorrected = ExtractSymbolName@expr},

    Message[Debug::ShowIt,Defer[exprWithSymbolNamesCorrected = evaluatedExpr]];

    If[TrueQ@System`$ShowIt,
    If[TrueQ@System`$ReverseIt,
            insertBelowEvaluationCell[Defer[exprWithSymbolNamesCorrected = evaluatedExpr]];
            ,
            Print[Defer[exprWithSymbolNamesCorrected = evaluatedExpr]];
        ];
    ];

    If[TrueQ@System`$ConsoleIt,
        PrintToConsole[exprWithSymbolNamesCorrected = evaluatedExpr];
    ];

    If[TrueQ@System`$SowIt,
        Sow[
            evaluatedExpr
            ,
            Function[deferedExpr, ToString@Unevaluated@deferedExpr, HoldFirst] @@ exprWithSymbolNamesCorrected
        ];
    ];

    evaluatedExpr
]; 

SetAttributes[System`ShowItList, {HoldAll,Listable}];
System`ShowItList[expr__]:=System`ShowItList[{expr}];
System`ShowItList[expr_] := System`ShowIt[expr];

SetAttributes[ReapTags,HoldFirst];
ReapTags[expr_]:=
   Module[{elements},
      Reap[expr,_,(elements[#1]=If[Length@#2==1,First@#2,#2])&];
      elements
   ];

Example

$ShowIt=True; $SowIt = True; $ReverseIt=False; $ConsoleIt = True; On[Debug::ShowIt];
debugResult = ReapTags[x={1,2};y=3;z=4;ShowIt@Mean@x;ShowIt@z;ShowItList[x,y];ShowItList@{x,y};];
debugResult["Mean[x]"]
debugResult["x"]
debugResult["y"]
debugResult["z"]

The argument of ReapTags can be any expression including the call to a function which is hard to split into simple pieces thus using Reap and Sow as underlying functions is useful in such a case.

EDIT

For the record, this version of ShowIt is particularly useful, it can be used in conjunction with ReapTags defined here http://stackoverflow.com/a/6245166/884752. To see the list of keys defined in the debugSymbol containing the results extracted from a program you can use the function Keys defined in http://mathematica.stackexchange.com/a/999/66. I've also incorporated the answer of Szabolcs into ShowIt, the answer of Mr. Wizard to the question Delete contexts from a string representation of a symbol and the answer to this question How to Print to the Console.

  • The Print output using \$ShowIt = True allows to use it in the front end if you change its style to Input.
  • \$ReverseIt = True allows to Print the result of Print in a reverse order as asked in this question.
  • The Message if you switch it on using On[Debug::ShowIt] prints a Mathematica message and would stop the code if you used a message breakpoint in Mathematica or Wolfram Workbench.
  • \$SowIt = True allows to store what would be printed with Print in a symbol.
  • $ConsoleIt = True allows to output what would be output with Print but in the Messages console accessible in the menu Window>Messages.
  • The System` context of ShowIt and ShowItList allows to use them in the Private` context of other packages without having to define the package in which these functions are defined (in BeginPackage, see here for more info on the organisation of packages).

All in all ShowIt and the functions around it show a lot of different aspects of advanced evaluation in Mathematica that could be interesting to a lot of people.

SetAttributes[ExtractSymbolName, HoldAll];
ExtractSymbolName[expr_] :=
Module[{T,SR = StringReplace[#, a__ ~~ "$" ~~ DigitCharacter .. :> a] &}, 
    Defer[expr] 
        /. s_Symbol :> T@MakeExpression@SR@SymbolName@Unevaluated@s 
        /. T@_@x___ :> x
];

insertBelowEvaluationCell[expr_]:=
(
    SelectionMove[EvaluationNotebook[],After,EvaluationCell];
    NotebookWrite[EvaluationNotebook[],Cell[BoxData@ToBoxes[expr],"Print"]]
);

$OldLine = -1;
SetAttributes[PrintToConsole, HoldFirst];
PrintToConsole[expr_] := 
(
    SelectionMove[MessagesNotebook[], After, Cell];
    NotebookWrite[
        MessagesNotebook[], 
        Cell[BoxData[ToBoxes[Defer@expr]], "Print", 
         CellLabel ->  "During evaluation of In[" <> ToString[$Line-1] <> "]:=", 
         ShowCellLabel -> ($OldLine =!= $Line)]
    ];
    $OldLine = $Line;
);

System`Debug::ShowIt = "`1`";
Off[Debug::ShowIt];
SetAttributes[System`ShowIt, HoldAll];
System`ShowIt[expr__] := System`ShowIt[{expr}];
System`ShowIt[expr_] :=
With[{evaluatedExpr = expr,exprWithSymbolNamesCorrected = ExtractSymbolName@expr},

    Message[Debug::ShowIt,Defer[exprWithSymbolNamesCorrected = evaluatedExpr]];

    If[TrueQ@System`$ShowIt,
    If[TrueQ@System`$ReverseIt,
            insertBelowEvaluationCell[Defer[exprWithSymbolNamesCorrected = evaluatedExpr]];
            ,
            Print[Defer[exprWithSymbolNamesCorrected = evaluatedExpr]];
        ];
    ];

    If[TrueQ@System`$ConsoleIt,
        PrintToConsole[exprWithSymbolNamesCorrected = evaluatedExpr];
    ];

    If[TrueQ@System`$SowIt,
        Sow[
            evaluatedExpr
            ,
            Function[deferedExpr, ToString@Unevaluated@deferedExpr, HoldFirst] @@ exprWithSymbolNamesCorrected
        ];
    ];

    evaluatedExpr
]; 

SetAttributes[System`ShowItList, {HoldAll,Listable}];
System`ShowItList[expr__]:=System`ShowItList[{expr}];
System`ShowItList[expr_] := System`ShowIt[expr];

SetAttributes[ReapTags,HoldFirst];
ReapTags[expr_]:=
   Module[{elements},
      Reap[expr,_,(elements[#1]=If[Length@#2==1,First@#2,#2])&];
      elements
   ];

Example

$ShowIt=True; $SowIt = True; $ReverseIt=False; $ConsoleIt = True; On[Debug::ShowIt];
debugResult = ReapTags[x={1,2};y=3;z=4;ShowIt@Mean@x;ShowIt@z;ShowItList[x,y];ShowItList@{x,y};];
debugResult["Mean[x]"]
debugResult["x"]
debugResult["y"]
debugResult["z"]

The argument of ReapTags can be any expression including the call to a function which is hard to split into simple pieces thus using Reap and Sow as underlying functions is useful in such a case.

added 751 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 21 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 324 characters in body; added 1 characters in body; added 2 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 2 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 2 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
Rollback to Revision 22
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
edited body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 465 characters in body; added 2 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 2 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 288 characters in body; deleted 29 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 117 characters in body; deleted 92 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 157 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
deleted 57 characters in body; added 6 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 111 characters in body; deleted 1 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 170 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
deleted 21 characters in body; Post Made Community Wiki
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 235 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 6 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
deleted 1 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
deleted 1 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 170 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 1 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading