12
$\begingroup$

Please imagine a simple loop:

For[i=1,i<=100,i++,
  Print[i];
];

We can ask Print[] to output $(1,2,3,4,...)$ to a different notebook (in the context of the same kernel)?

$\endgroup$
5
  • 2
    $\begingroup$ You could look up NotebookWrite. $\endgroup$
    – Yves Klett
    Sep 23, 2013 at 9:27
  • $\begingroup$ @YvesKlett Sorry, should have found that. $\endgroup$
    – RM1618
    Sep 23, 2013 at 9:28
  • $\begingroup$ Not to worry - perhaps someone can help with Print as well. $\endgroup$
    – Yves Klett
    Sep 23, 2013 at 9:29
  • 4
    $\begingroup$ Possible duplicates / related: (1041), (5040), (7081), (10456), (22584), (29235) $\endgroup$
    – Mr.Wizard
    Sep 23, 2013 at 9:52
  • 1
    $\begingroup$ Also this: mathematica.stackexchange.com/q/5734/5 (just change MessagesNotebook[] to your desired notebook. $\endgroup$
    – rm -rf
    Sep 23, 2013 at 13:58

3 Answers 3

13
$\begingroup$

As Yves already mentioned, you can easily create and edit notebooks through Mathematica commands. A start would be this tutorial, which you can find in the Documentation Center under tutorial/ManipulatingNotebooksFromTheKernel

Here is a short example printing the i values into a new notebook:

nb = CreateDocument[];

For[i = 1, i <= 10, i++,
 SelectionMove[nb, Next, Cell];
 NotebookWrite[nb, 
  Cell[BoxData@RowBox[{"i is now ", ToString[i]}], "Output"]];
]

If you want to know how to construct cell expressions, you could just go over any cell in a notebook and hit Ctrl+Shift+E to see the underlying structure.

$\endgroup$
2
$\begingroup$

Although the question has been answered, no reason for this question was given. One possible motivation is to be able to discard a lot of diagnostic output, e.g. from an iterative process, by trashing the newly created notebook.

In such a case an alternative could be Dynamic[.], e.g.

ClearAll[iter];
Dynamic[iter]
For[i = 1, i <= 10, i++,
    Pause[1.0];
    iter = "i is now " <> ToString[i]
]
$\endgroup$
1
  • $\begingroup$ Thanks for your answer - my reason for asking was that I was interested in printing multiple plots or outputs at different speeds while running a computation. It became cumbersome to have everything moving around in the same notebook. $\endgroup$
    – RM1618
    Sep 23, 2013 at 23:44
2
$\begingroup$

Here's what I have been using.

Any improvements / comments are welcome.

(* this opens a notebook file and if notebook exists it CLEARS the contents as well  *)
OpenNB[fname_] := Module[{dir, fns, nb},
   dir = NotebookDirectory[];
   fns = FileNames[FileNameJoin[{dir, fname}]];
   If[fns === {}, (
     nb = CreateNotebook[];
     NotebookSave[nb, FileNameJoin[{dir, fname}]];
     ), (
     nb = NotebookOpen[fns[[1]]];
     SelectionMove[nb, All, Notebook];
     NotebookDelete[nb];
     )
    ];
   Return[nb];
   ];

PrintNB[style_String: "Print", nb_NotebookObject: EvaluationNotebook[], args__] := NotebookWrite[nb, Cell[BoxData@ToBoxes[SequenceForm[args]], style]];

Here is example usage

logNB = OpenNB["log.nb"];
PrintNB[logNB, "Execution Log for: ", NotebookFileName[]];
PrintNB[logNB, "Started at: ", DateString[]];

f[r] = r^\[Gamma]*Exp[-\[Kappa] r];
PrintNB[logNB, "f(r) = ", f[r]]; 
PrintNB["PageBreak", logNB, " "];
PrintNB[logNB, "Hello"];

Here is the output

output notebook

$\endgroup$
6
  • 1
    $\begingroup$ Why would you only have your NotebookWrite write out "Output" cells...? If you allow your code to pass the style of cell to print (defaulting to "Output") you also won't need to fake the "Subsection" or whatever style with PrintHeader... $\endgroup$
    – b3m2a1
    May 30, 2019 at 19:58
  • $\begingroup$ @b3m2a1 I wrote the code so that it behaves like Print[], which is what the question asked for. PrintHeader is just a helper function. $\endgroup$
    – RFS
    May 30, 2019 at 20:07
  • 1
    $\begingroup$ Well yes, but I'm saying there's a better approach. Also if you want to directly emulate Print you should use "Print" as the cell style instead of `"Output". $\endgroup$
    – b3m2a1
    May 30, 2019 at 20:14
  • 1
    $\begingroup$ looks like Print does this: Cell[BoxData@ToBoxes[SequenceForm[args]], "Print", CellLabel -> "During evaluation of In["<>ToString[$Line]<>"]:="] $\endgroup$
    – b3m2a1
    May 30, 2019 at 20:21
  • 1
    $\begingroup$ @b3m2a1 I implemented your suggestions. It works well from my testing of it. Could you give a like? $\endgroup$
    – RFS
    May 31, 2019 at 0:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.