WalkingRandomly
WalkingRandomly

Reputation: 4557

Equation parsing in Python

How can I (easily) take a string such as "sin(x)*x^2" which might be entered by a user at runtime and produce a Python function that could be evaluated for any value of x?

Upvotes: 44

Views: 70874

Answers (6)

Don
Don

Reputation: 17606

EDIT parser is deprecated in Python 3.9: https://docs.python.org/3/whatsnew/3.9.html#new-parser

You can use Python parser:

import parser
from math import sin

formula = "sin(x)*x**2"
code = parser.expr(formula).compile()
x = 10
print(eval(code))

It performs better than pure eval and, of course, avoids code injection!

Upvotes: 34

cryo
cryo

Reputation: 14505

pyparsing might do what you want (http://pyparsing.wikispaces.com/) especially if the strings are from an untrusted source.

See also http://pyparsing.wikispaces.com/file/view/fourFn.py for a fairly full-featured calculator built with it.

Upvotes: 10

Andrew Dalke
Andrew Dalke

Reputation: 15305

To emphasize J.F. Sebastian's advice, 'eval' and even the 'compiler' solutions can be open to subtle security holes. How trustworthy is the input? With 'compiler' you can at least filter out things like getattr lookups from the AST, but I've found it's easier to use PLY or pyparsing for this sort of thing than it is to secure the result of letting Python help out.

Also, 'compiler' is clumsy and hard to use. It's deprecated and removed in 3.0. You should use the 'ast' module (added in 2.6, available in 2.5 as '_ast').

Upvotes: 3

S.Lott
S.Lott

Reputation: 391856

Python's own internal compiler can parse this, if you use Python notation.

If your change the notation slightly, you'll be happier.

import compiler
eq= "sin(x)*x**2"
ast= compiler.parse( eq )

You get an abstract syntax tree that you can work with.

Upvotes: 53

jfs
jfs

Reputation: 414207

 f = parser.parse('sin(x)*x^2').to_pyfunc()

Where parser could be defined using PLY, pyparsing, builtin tokenizer, parser, ast.

Don't use eval on user input.

Upvotes: 15

SilentGhost
SilentGhost

Reputation: 319591

Sage is intended as matlab replacement and in intro videos it's demonstrated how similar to yours cases are handled. They seem to be supporting a wide range of approaches. Since the code is open-source you could browse and see for yourself how the authors handle such cases.

Upvotes: 0

Related Questions