3

In MMA 9 I use the following code to load multiple nb's and close them after they are evaluated. In MMA 10 this code is broken. It appears that MMA 10 takes far longer to evaluate the code than the function takes to run, and the NotebookClose closes them before they are completely evaluated in 10. Eliminating the NotebookClose lets the code load properly, but then the user has all of these nb's to close before using the GUI. The point of this code was to have only the nb with the GUI open for the user.

nbs = {"ImportFunctions.nb", "StandardData.nb","DataConditioning.nb", "Functions_1.nb", "Functions_2.nb", "Functions_3.nb", "PaperDifference.nb", "PlotFunctions.nb"};

For[i = 1, i <=  Length[nbs], i++, 
  Block[{nb = NotebookOpen[NotebookDirectory[] <> nbs[[i]]]},
      FrontEndTokenExecute[nb, "EvaluateNotebook"];
      NotebookClose[nb];
  ]
] 

Is there a better way to accomplish this in MMA 10?


A modification of procedure1[] from the answer by Kuba that does something recognizable when evaluated in version 9, but not in version 10.4.1:

procedure0[] := Module[{nbs},
  nbs = Table[With[{i = i},
     NotebookPut @ Notebook[{Cell[BoxData@MakeBoxes[Speak[ToString@i]], "Input"]}]], {i, 4}];
  For[i = 1, i <= Length[nbs], i++, 
   FrontEndTokenExecute[nbs[[i]], "EvaluateNotebook"];
   NotebookClose[nbs[[i]]];];
  Print["is this really finished?"];]

procedure0[]

A simpler single notebook example

With[{nb = NotebookPut @ Notebook[{Cell[BoxData@MakeBoxes[Speak["Hi"]], "Input"]}]}, 
 FrontEndTokenExecute[nb, "EvaluateNotebook"]; NotebookClose[nb];]
Nothingtoseehere
  • 4,518
  • 2
  • 30
  • 58
  • 1
    Have you looked at http://reference.wolfram.com/language/ref/NotebookEvaluate.html ? – Gustavo Delfino Jul 26 '16 at 13:20
  • Which MMA 10 version are you using. Does evaluating the code given in your question within a normal notebook work in version 9, or does it only work using the GUI? – Karsten7 Jul 27 '16 at 09:16
  • @Karsten7. I'm using version 10.4.1.0 and in that version the code runs but will not evaluate the functions in the nb's unless I remove the NotebookClose then it runs but leaves all the nb's open. Version 9 works as expected. The code runs and NB's close leaving all functions loaded in the kernel. This list is evaluated then the GUI is loaded and the program is ready to run. – Nothingtoseehere Jul 27 '16 at 16:38
  • I think this behavior changed in version 10.4 or 10.4.1. – Karsten7 Jul 27 '16 at 17:43
  • @Kuba I added a modification of your procedure1, that works in version 9, but not in version 10.4.1, to the question. – Karsten7 Jul 27 '16 at 17:52
  • @Karsten7. I will come later and check, I'm quite confused atm about what and where fails. – Kuba Jul 27 '16 at 17:59
  • 2
    Does adding NotebookClose[] to the end of the individual notebooks together with removing NotebookClose[nb] from the given code work? – Karsten7 Jul 27 '16 at 18:40
  • 1
    @Karsten7. That was a very good solution! Solved the problem...Thank you! – Nothingtoseehere Jul 27 '16 at 19:48

1 Answers1

5

FrontEndTokenExecute[nb, "EvaluateNotebook"] does not return anything, it won't wait for a nb to finish evaluating. If it worked I think it was a coincidence. Compare those examples:

The first one is analogous to your approach.

procedure1[] := Module[{nb},
  nb = NotebookPut @ Notebook[
     Table[
       Cell[BoxData@MakeBoxes[Print[#]; Pause[1];], "Input"] & @ i, 
       {i, 4}
     ]
  ];
  FrontEndTokenExecute[nb, "EvaluateNotebook"];
  Print["is this really finished?"];
  NotebookClose[nb]
]  

The second works as expected:

procedure2[] := Module[{nb},
  nb = NotebookPut @ Notebook[
     Table[
       Cell[BoxData@MakeBoxes[Print[#]; Pause[1];], "Input"] & @ i, 
       {i, 4}
     ]
  ];
  NotebookEvaluate[nb];              (* <-- the only change*)
  Print["is this really finished?"];
  NotebookClose[nb]
]

Prints from nb are not evaluated because they are not fast enough and NotebookClose fires. Without NotebookClose you'd see 1,2,3,4 in a Message window.

As noted in comments you can use NotebookEvaluate or SelectionMove[nb,All, Notebook] + SelectionEvaluate[nb] instead of your FronEndTokenExecute.

For differences between those two functions take a look at Global context seems to be shared between kernels

Kuba
  • 136,707
  • 13
  • 279
  • 740
  • So to understand this code, replacing "Input" with {"ImportFunctions.nb", "StandardData.nb","DataConditioning.nb", "Functions_1.nb", "Functions_2.nb", "Functions_3.nb", "PaperDifference.nb", "PlotFunctions.nb"} should load all of these nb's? – Nothingtoseehere Jul 26 '16 at 13:47
  • @RHall No, this code is only an example of the sequence of events. Just use NotebookEvaluate in your code instead of tokens and it should work. – Kuba Jul 26 '16 at 13:49
  • Sorry I can't easily recognize the connection between your proposed solution and my code. Can you show a working example? – Nothingtoseehere Jul 26 '16 at 14:18
  • @RHall was my edit helpful with linking to your code? – Kuba Jul 27 '16 at 05:31
  • thanks for the change in your code, but neither example calls a list of nb's to evaluate. So my struggle is in figuring out how to make either example do just that. Where can that change be made? – Nothingtoseehere Jul 27 '16 at 16:25
  • There is a misunderstanding here. procedure1[] doesn't do anything recognizable in version 9 too. – Karsten7 Jul 27 '16 at 17:41
  • @Karsten7. what do you mean by "doesn't do anything recognizable"? Is FrontEndTokenExecute waiting for a result or something? I can't test on 9. – Kuba Jul 27 '16 at 19:45
  • When you evaluate With[{nb = NotebookPut@ Notebook[{Cell[BoxData@MakeBoxes[Pause[3]], "Input"], Cell[BoxData@MakeBoxes[Speak["Hi"]], "Input"], Cell[BoxData@MakeBoxes[Pause[3]], "Input"]}]}, FrontEndTokenExecute[nb, "EvaluateNotebook"]; NotebookClose[nb];] in version 10.4.1 you only see a notebook flashing up quickly and don't hear any output from Speak. When you evaluate the same code in version 9, you also only see the notebook flashing up (meaning it gets closed immediately). However, after 3 seconds you can hear the output from Speak. – Karsten7 Jul 27 '16 at 20:03
  • @Karsten7. Thanks for the feedback. Somthing with how cells evaluation is queued was changed then. I will rephrase my post tomorrow in order to not confuse readers. – Kuba Jul 27 '16 at 20:06
  • The point is: For your example there is no recognizable difference between version 9 and 10, as in both versions one can not observe the output of Print. Nevertheless the Print comments are evaluated in version 9, but not in version 10. The notebook becomes invisible immediately in both versions. – Karsten7 Jul 27 '16 at 20:07
  • Maybe part of the misunderstanding was also on my side. You are mentioning the Message window. Looks like your CurrentValue[$FrontEnd, PrintAction] setting is "PrintToConsole", while I have it set to "PrintToNotebook", which is the same as CurrentValue[$DefaultFrontEnd, PrintAction]. Changing this setting procedure1[] does print to the Message window in version 9, but not in version 10. – Karsten7 Jul 27 '16 at 20:26