Reading and running a mathematical expression in Python
Asked Answered
G

6

5

Using Python, how would I go about reading in (be from a string, file or url) a mathematical expression (1 + 1 is a good start) and executing it?

Aside from grabbing a string, file or url I have no idea of where to start with this.

Gabbi answered 30/12, 2008 at 11:22 Comment(0)
E
7

Because python supports some algebraic forms, you could do:

eval("1 + 1")

But this allows the input to execute about anything defined in your env:

eval("__import__('sys').exit(1)")

Also, if you want to support something python doesn't support, the approach fails:

x³ + y² + c
----------- = 0
     z

Instead of doing this, you can implement a tokenizer and a parser with ply. Evaluating a thing like '1 + 1' ought not take more than ten lines or so.

You could also implement the tokenizer and the parser by hand. Read about LL and LR parsers. Before attempting this it's also better to learn using parser generators first.

Emmanuelemmeline answered 30/12, 2008 at 11:43 Comment(7)
Before starting to implement your own parser It is worth to take a look at the existing ways to do it in Python e.g., sympy, scipy. For a complete CAS you could go with SAGE. vnoel.wordpress.com/2008/05/03/…Coenosarc
The "eval can crash your application" advice is at the fringes of schizophrenic. It's Python. Everyone have the source. Why mess around with subverting eval() when you have the source for the entire app?Proust
@S.Lott: The application may be gathering remote input.Diffident
@nosklo: Quite an assumption given the nature of the question. For web apps ONLY would it be an issue and that's not stated.Proust
@S.Lott: The point was not to show that you can exit from the routine with the 'eval'. The asker did neither mention he wouldn't write a web app.Emmanuelemmeline
S.O. isn't a private message service: these questions will be found by other people looking for similar information. Eval can be dangerous, and it's never bad to reinforce that message. Even if Teifion is using it in an inherently safe way, others who read this answer may not be.Asseveration
@J.F. Sebastian I have seen SymPy methods, but what is the math parser in Scipy? I've looked very hard, and I haven't found anything in Numpy or Scipy, only numexpr and asteval.Astute
S
2

If you are receiving an expression as a string you'll need to parse it into its operators and operands and then process the resulting tree. This isn't a python problem per se. but a general issue of how to deal with mathematical expressions delivered as strings.

A quick google reveals a bunch of lexical parsers for python.

Seve answered 30/12, 2008 at 11:28 Comment(0)
R
2

Don't writing your own parser unless you want to learn how to write a parser. As already mentioned in the comments by @J.F. Sebastian, I would suggest a full-on computer algebra system (CAS) like SAGE. It will handle mathematical statements much more complicated than 1+1 :)

Rijeka answered 31/12, 2008 at 15:45 Comment(0)
V
1

Perhaps eval is what you're after?

>>> eval('1+1')
2
Voiced answered 30/12, 2008 at 11:28 Comment(1)
This is more dangerous than using input()Thalassa
P
1

Read about the input function.

Proust answered 30/12, 2008 at 11:32 Comment(1)
Input just calls eval() on the user's input. Calling eval on user input is almost universally a horrible idea.Forelady
B
0

You can take advantage of Python's own evaluation capabilities. However, blind use of eval() is a very dangerous, since somebody can trick your program into:

eval( (__import__("os").system("rm important_file") or 1) + 1)

The correct way to use eval is with the following receipe, which will make sure nothing dangerous is contained in the expression that you are evaluating:

http://code.activestate.com/recipes/496746-restricted-safe-eval/

Bicipital answered 25/2, 2011 at 9:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.