I need to run a file several times, each time with a different value for a certain variable. I use the following script to automate the process, but I have no idea how to make changes in the file after it's opened and then evaluated. Any guidance and help is highly appreciated.

  nb1 = NotebookOpen["/Users/toor/Desktop/myfile.nb"];
  SelectionMove[nb1, All, Notebook] SelectionEvaluate[nb1], {i, 1, 10}];
  • 3
    $\begingroup$ Perhaps the most natural way to do this would be to wrap the code present in that notebook in a function that takes those parameters that you need to change as arguments. Once your function definition is evaluated, then you can use e.g. Table, Map, or similar list manipulation constructs to pass it the various values of the parameters you need to run. Look at the Functions and Programs language overview, specifically the sections "Functions and Procedures" and "Repetitive Operations". $\endgroup$ – MarcoB Jun 8 '16 at 0:11
  • $\begingroup$ Check the notebook manipulation tutorial will be helpful to you. $\endgroup$ – Wjx Jun 8 '16 at 0:47
  • $\begingroup$ If have to use this method instea of @MacroB 's method, I think I can give you an answer. $\endgroup$ – Wjx Jun 8 '16 at 0:58
  • 1
    $\begingroup$ I think you don't need to change the variable in the opened Notebook. If you are in the same Kernel then just add the definition of the new value of your parameter in the Do loop before evaluating the opened Notebook. $\endgroup$ – Algohi Jun 8 '16 at 5:08
  • $\begingroup$ Seemingly yes~ Changing directly in the kernel will be far more direct. $\endgroup$ – Wjx Jun 8 '16 at 9:44

Just as an example, I created two files under the same folder, one named "run.nb" which is the file I'll want to evaluate for multiple times, another is "run1.nb" that controls the running process.

In "run.nb", I wrote:

A = 1;
AppendTo[B, A^2];

So what I'll change each time is the input value of A and What I would love to collecto is the value of B.

In "run1.nb", the following code can do this job.

B = {};
Do[nb = NotebookOpen[NotebookDirectory[] <> "run.nb"]; 
 SelectionMove[nb, Before, CellContents];
 SelectionMove[nb, Next, Word, 3];
 SelectionMove[nb, All, Word];
 NotebookWrite[nb, i];
 SelectionMove[nb, All, Notebook];
 NotebookClose[nb], {i, 3}]

The main idea is that after opening a notebook, I will move the selection to designed point using SelectionMove, in this case is that 1 in A=1. Then replace this part using NotebookDelete and NotebookWrite. Finally evaluate the program in run.nb with NotebookEvaluate and collect the result.

Hope this hope can help you~

| improve this answer | |
  • $\begingroup$ Dear Wjx, many thanks for your answer and descriptions; It seems like what I need. As my code is complex, I need to test it to see if I can do the same thing there and will reply here the result. many thanks once again. $\endgroup$ – Marilla Jun 8 '16 at 9:24
  • $\begingroup$ As algohi have said, changing directly from kernel is also a method~ $\endgroup$ – Wjx Jun 8 '16 at 9:45
  • $\begingroup$ Hi again Wjx, since the line of the code that I need to change the value of a variable is not the first line, I was thinking to use "TextLine" instead of "Word", but I don't know how to spot the relevant line number? Do you have any idea in this regard? $\endgroup$ – Marilla Jun 8 '16 at 10:18
  • $\begingroup$ Simply have a try and you can know how much line to move down~It just need a bit of patience to deternmin how much text lines you show write~ $\endgroup$ – Wjx Jun 8 '16 at 10:26
  • $\begingroup$ Dear Wjx, Many many thanks; I did it. One more thing that I encounter, is that how that's possible to clear memory after running each sample of the file? I need that because of the large amount of calculations, I run out of memory. Do you have any idea in this regard as well? $\endgroup$ – Marilla Jun 8 '16 at 14:54

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