Подтвердить что ты не робот

Как оценить ноутбук из командной строки?

Как мы можем вычислить ноутбук Mathematica из командной строки (т.е. при запуске ядра в режиме командной строки)?

Предположим, что мы работаем на удаленной машине. Я знаю, что можно преобразовать ноутбук в m файл и оценить его, но мне любопытно, можно ли это сделать непосредственно с помощью ноутбука.


Это то, что у меня есть до сих пор:

Во-первых, нам нужно запустить безголовый X-сервер на удаленной машине Linux, поэтому перед ним можно запустить интерфейс (и откройте ноутбук). Пропустите этот шаг, если вы работаете на локальной машине.

Xvfb :1 &
export DISPLAY=:1

После этого я запустил ядро ​​Mathematica (math) и сделал следующее.

Необходимо использовать UsingFrontEnd, потому что для открытия ноутбука требуется передний конец. test.nb имеет единственную ячейку ввода, содержащую a=1.

In[1]:= [email protected]["test.nb"]

Out[1]= -NotebookObject-

Попытавшись оценить ноутбук, видимо, я получаю dialog, и мне нужно использовать Return[] для возврата. Я не уверен, почему строка ввода начинает отсчет с 1 снова (новое ядро ​​запускалось передним концом?). Обратите внимание, что a не получило значения.

In[2]:= [email protected][nb]

 In[1]:= a

 Out[1]= a

 In[2]:= Return[]

Out[2]= a

После возвращения из диалога a все еще не имеет значения.

In[3]:= a

Out[3]= a
4b9b3361

Ответ 1

Это в Windows, используя хорошую работу Arnouds и просто добавляя простой старый MathLink (довольно медленно btw...):

link = LinkCreate["8000", LinkProtocol -> "TCPIP"];
UsingFrontEnd[
NotebookPauseForEvaluation[nb_] := Module[{},
 While[ NotebookEvaluatingQ[nb], Pause[.25] ] ];
NotebookEvaluatingQ[nb_]:=Module[{},
 SelectionMove[nb,All,Notebook];
 [email protected]@Map["Evaluating"/.#&,Developer`CellInformation[nb]]
];
nb = NotebookOpen["G:\\mma\\test.nb"];
SelectionMove[nb, Before, Notebook];
NotebookWrite[nb, Cell["Link = LinkConnect[\"8000\", LinkProtocol -> \"TCPIP\"]", "Input"]];
SelectionMove[nb, After, Notebook];
NotebookWrite[nb, Cell["LinkWrite[Link, a]", "Input"]];
SelectionMove[nb, All, Notebook];
SelectionEvaluate[nb];
a = LinkRead[link];
Print["a = ",a];
]

Ответ 2

Это частичный ответ на ваш вопрос. Следующий код открывает ноутбук, назначает ему Ядро "Тест", оценивает ноутбук в этом ядре, ждет завершения оценки и сохраняет оцененный ноутбук. Это не приводит к определению a в локальном ядре командной строки.

Ожидается, что оценки ядра будут завершены в записной книжке:

NotebookPauseForEvaluation[nb_] := Module[{},
 While[ NotebookEvaluatingQ[nb], Pause[.25] ] ]

Это проверяет, находится ли какая-либо ячейка в записной книжке по-прежнему:

NotebookEvaluatingQ[nb_]:=Module[{},
 SelectionMove[nb,All,Notebook];
 [email protected]@Map["Evaluating"/.#&,Developer`CellInformation[nb]]
]

Это просто диагностическое сообщение, когда вы пытаетесь переопределить ядро ​​как "Тест":

AddTestEvaluator::exists = "Evaluator `1` is already defined, but has a definition that is `2` and not the expected `3`.";

Это код для добавления оценщика, такого как "Тест" к интерфейсу:

AddTestEvaluator[evaluator_String] := Module[
 {evaluatornames, testevaluator},
 evaluatornames = EvaluatorNames /. Options[$FrontEnd, EvaluatorNames];
 testevaluator = evaluator -> {"AutoStartOnLaunch" -> False};
 Which[
  MemberQ[evaluatornames, evaluator -> {"AutoStartOnLaunch" -> False}],
  Null,
  MemberQ[evaluatornames, evaluator -> _],
  Message[AddTestEvaluator::exists,
  evaluator,
  evaluator /. (EvaluatorNames /. Options[$FrontEnd, EvaluatorNames]),
  {"AutoStartOnLaunch" -> False}
 ],
 True,
 AppendTo[evaluatornames, testevaluator];
 SetOptions[$FrontEnd, EvaluatorNames -> evaluatornames]
 ]
]

Наконец, это код для оценки ноутбука под ядром "Тест" и сохранения оцененного ядра:

 UsingFrontEnd[     
  AddTestEvaluator["Test"];
  nb = NotebookOpen["test.nb"];
  SetOptions[nb,Evaluator->"Test"];
  SelectionMove[nb,All,Notebook];
  SelectionEvaluate[nb];
  NotebookPauseForEvaluation[nb];
  NotebookSave[nb]
 ]

Я все еще ищу решение для вашей полной проблемы (имея a, определенный в локальной команде линейное ядро).