13

Sin[] does not exist in Python and while I can do FortranForm and similar things, I do not know of any PythonForm, is there anything built-in to convert an expression to Python?

Of course I can make rules like Sin[a_]->math.sin(a) but is going to be tedious and maybe somebody (at Wolfram) did this already?

I think the question is sufficiently different from this one 85445/convert-mathematica-math-expression-form-to-python-math-expression

Answer that I take from @masterxilo and I will keep updating as more known functions appear under my radar

PythonForm~SetAttributes~HoldAll
PythonForm[Sin[x_]] := StringTemplate["math.sin(``)"]@PythonForm@x
PythonForm[Cos[x_]] := StringTemplate["math.cos(``)"]@PythonForm@x
PythonForm[Log[x_]] := StringTemplate["math.log(``)"]@PythonForm@x
PythonForm[Rational[a_, b_]] := 
StringTemplate["(``/``)"][PythonForm@a, PythonForm@b]
PythonForm[Pi] := ToString["math.pi"]
PythonForm[Times[a_, b_]] := 
StringTemplate["(`` * ``)"][PythonForm@a, PythonForm@b]
PythonForm[Power[a_, b_]] := 
StringTemplate["(``**``)"][PythonForm@a, PythonForm@b]
PythonForm[Plus[a_, b_]] := 
StringTemplate["(``+``)"][PythonForm@a, PythonForm@b]
PythonForm[x_] := ToString@x;
PythonForm[f_Symbol[args___]] := 
StringTemplate["``(``)"][ToString@f, PythonForm@args]
PythonForm[args___] := (PythonForm /@ {args})~StringRiffle~", ";
Rho Phi
  • 1,420
  • 11
  • 21
  • 1
    you actually cant do ->math.sin() because mathematica will take it as a dot product. You can do something like ->mathdotsin() and fix it later with a string replace. Quite a hack though. – george2079 Aug 10 '16 at 16:44
  • yes, Dot[] might stand in your way. For now I am doing an InputForm of everything and then replacing in the python editor . ->.,^ ->**, [ -> ( and ]->) .. awful but works, I was hoping in something more classy ... – Rho Phi Aug 10 '16 at 16:57
  • Also related: http://mathematica.stackexchange.com/questions/85817/prepare-mathematica-output-to-be-parsed-in-python – Michael E2 Aug 19 '16 at 13:46

2 Answers2

6

If I where to do this manually, I would start with

PythonForm~SetAttributes~HoldAll
(*known symbols*)
PythonForm[Sin[x_]] := StringTemplate["math.sin(``)"]@PythonForm@x
PythonForm[Times[a_, b_]] := 
 StringTemplate["(`` * ``)"][PythonForm@a, PythonForm@b]
(*fallback*)
PythonForm[x_] := ToString@x; 
PythonForm[f_Symbol[args___]] := 
 StringTemplate["``(``)"][ToString@f, PythonForm@args]
PythonForm[args___] := (PythonForm /@ {args})~StringRiffle~", ";

PythonForm[Sin[2 * Sin[x] * 4 * f[x, y]]]

"math.sin((2 * (math.sin(x) * (4 * f(x, y)))))"

masterxilo
  • 5,739
  • 17
  • 39
  • 1
    You can probably leverage ToString@FortranForm to do some of the work. – masterxilo Aug 19 '16 at 13:42
  • I am editing my question to add the list of (known symbols) I have added so far. It should be noticed that this function cannot evaluate things like % because of the HoldAll I presume. – Rho Phi Aug 31 '16 at 15:01
3

Have a look at my solution to this problem, at: https://mathematica.stackexchange.com/a/144200/48312. I also prepared a Mathematica package for handling this at https://github.com/gwiederhecker/ToPython.