Math operations from string

Question:

Let’s say I have a standard Python string (such as one obtained from raw_input()), maybe "2 + 2" for simplicity’s sake.

I’d like to convert this string to standard math operations in Python, such that "2 + 2" would return 4.

Is there an easy way to do this, or would I have to split on the spaces and parse each number/symbol manually, then do the math based on what I find?

Do I want Regex?

Asked By: Elliot Bonneville

||

Answers:

Warning: this way is not a safe way, but is very easy to use. Use it wisely.

Use the eval function.

print eval('2 + 4')

Output:

6

You can even use variables or regular python code.

a = 5
print eval('a + 4')

Output:

9

You also can get return values:

d = eval('4 + 5')
print d

Output:

9

Or call functions:

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

a = 20
b = 10    
print eval('add(a, b)')
print eval('subtract(a, b)')

Output:

30
10

In case you want to write a parser, maybe instead you can built a python code generator if that is easier and use eval to run the code. With eval you can execute any Python evalution.

Why eval is unsafe?

Since you can put literally anything in the eval, e.g. if the input argument is:

os.system(‘rm -rf /’)

It will remove all files on your system (at least on Linux/Unix).
So only use eval when you trust the input.

Answered By: Michel Keijzers

The easiest way is to use eval as in:

 >>> eval("2   +    2")
 4

Pay attention to the fact I included spaces in the string. eval will execute a string as if it was a Python code, so if you want the input to be in a syntax other than Python, you should parse the string yourself and calculate, for example eval("2x7") would not give you 14 because Python uses * for multiplication operator rather than x.

Answered By: zenpoy

Regex won’t help much. First of all, you will want to take into account the operators precedence, and second, you need to work with parentheses which is impossible with regex.

Depending on what exactly kind of expression you need to parse, you may try either Python AST or (more likely) pyparsing.
But, first of all, I’d recommend to read something about syntax analysis in general and the Shunting yard algorithm in particular.

And fight the temptation of using eval, that’s not safe.

Answered By: bereal

A simple way but dangerous way to do this would be to use eval(). eval() executes the string passed to it as code. The dangerous thing about this is that if this string is gained from user input, they could maliciously execute code that could break the computer. I would get the input, check it with a regex, and then execute it if you determine if it’s OK. If it’s only going to be in the format “number operation number”, then you could use a simple regex:

import re
s = raw_input('What is your math problem? ')
if re.findall('d+? *?+ *?d+?', s):
  print eval(s)
else:
  print "Try entering a math problem"

Otherwise, you would have to come up with something a bit stricter than this. You could also do it conversely, using a regex to find if certain things are not in it, such as numbers and operations. Also you could check to see if the input contains certain commands.

Answered By: CoffeeRain

The asker commented:

I figure that if I understand a problem well enough to write a program that can figure it out, I don’t need to do the work manually.

If he’s writing a math expression solver as a learning exercise, using eval() isn’t going to help. Plus it’s terrible design.

You might consider making a calculator using Reverse Polish Notation instead of standard math notation. It simplifies the parsing considerably. It would still be a good exercise

Answered By: japreiss

If you want to do it safely, you may want to use http://docs.python.org/library/ast.html#ast.literal_eval

from this answer:
Python "safe" eval (string to bool/int/float/None/string)

It might not do math, but you could parse the math operators and then operate on safely evaluated terms.

Answered By: Garrett Berg

The best way would be to do:

print eval("2 + 2")

If you wanted to you could use a variable:

addition = eval("2 + 2")
print addition

If you really wanted to, you could use a function:

def add(num1, num2):
eval("num1 + num2")

Answered By: typemaster

You could use this function which is doing the same as the eval() function, but in a simple manner, using a function.

def numeric(equation):
    if '+' in equation:
        y = equation.split('+')
        x = int(y[0])+int(y[1])
    elif '-' in equation:
        y = equation.split('-')
        x = int(y[0])-int(y[1])
    return x
Answered By: MOHAMMAD WASEEM
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.