3
$\begingroup$

I want to use input() in Python code which runs in the Wolfram Notebook.

So I create an external evaluation cell by typing ">" and choosing Python. Then I define this function:

def func():
    x = input()
    print(x)

Then I try to call it:

func()

which makes Mathematica run forever and not evaluate.

Can I call Python's input() from within the notebook?

2020-09-04 updt. "input() reads from standard input. There is no standard input when using a notebook."

yes, but Jupyter does support it though

$\endgroup$
8
  • 3
    $\begingroup$ Simple answer: No. $\endgroup$ – Szabolcs Aug 27 '20 at 16:06
  • $\begingroup$ huh, that's a bit sad $\endgroup$ – iav Aug 27 '20 at 19:39
  • 2
    $\begingroup$ input() reads from standard input. There is no standard input when using a notebook. Maybe what you actually want is to read user input when running Python from Mathematica. But that is not what you asked. You asked specifically to use input(). $\endgroup$ – Szabolcs Aug 28 '20 at 10:45
  • 2
    $\begingroup$ I don't have an easy answer for you (and unfortunately I don't have time to look for one), but I would investigate along the following lines: (1) Notebooks are a GUI environment. Find a way to put up a graphical input box from Python to get the input. It would work in practice, although it would be completely independent from notebooks or from Mathematica (2) Find out how to call back to Mathematica from Python. I don't know if this is possible, but I would hope that it is. Then you can invoke Mathematica's own Input (or some other, better way). $\endgroup$ – Szabolcs Aug 28 '20 at 14:02
  • 1
    $\begingroup$ If I wanted something practical, I'd probably go with (1), but I am curious if (2) is possible so I asked a question: mathematica.stackexchange.com/q/229164/12 $\endgroup$ – Szabolcs Aug 28 '20 at 14:12
3
$\begingroup$

I found a trick using TemplateExpression <* *> and SetDelayed in Mathematica.

As an example, I try to define a python function like this, which duplicates the input string:

def func():
    return input()*2

the Mathematica code is:

pysession = StartExternalSession["Python"];
wlfunc[] := ExternalEvaluate[pysession, "<* InputString[] *> *2"]
ExternalEvaluate[pysession, "func = <* wlfunc *>"]

(Note that python function input is equivalent to Mathematica function InputString)

Now, the function func defined in the python session can get input from the FrontEnd of Mathematica:

ExternalEvaluate[pysession, "[func() for i in range(3)]"]

I should mention that this trick is quite limited, for example,

ExternalEvaluate[pysession, "func() + func()"]

will return a Failure, because the function is effectively defined in Mathematica rather than python. To avoid this, use

ExternalEvaluate[pysession, "<* wlfunc[] *> + <* wlfunc[] *>"]
$\endgroup$
1
  • $\begingroup$ This works great! $\endgroup$ – Jason B. Sep 4 '20 at 17:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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