Edit:
it looks like there is a lot of debates regarding eval() insecure to use which should be mentioned before someone use it
see this thread:
Why is using 'eval' a bad practice?
Use the builtin method eval()
.
def translate(x, function):
return eval(function)
result = translate(10, "x**2")
print(result)
Output: 100
Edit2: another way without eval
def translate(s):
symbols = ['+', '-', '*', '/']
buff = ''
num = []
operations = []
for i, c in enumerate(s):
if c in symbols: # check for operators
# check for double operators like **
if s[i + 1] in symbols: # i.e. checking the first '*' in '**'
operations.append(2 * c)
continue
elif s[i - 1] in symbols: # i.e. checking the second '*' in '**'
num.append(float(buff))
buff = ''
continue
operations.append(c)
num.append(float(buff))
buff = ''
continue
else:
buff += c
num.append(float(buff))
print('input string:', s)
print('numbers:', num)
print('operations', operations)
# "power calculations" to be done first
for i, x in enumerate(operations):
if x == '**':
num[i] = perform[operations[i]](num[i], num[i + 1])
num.pop(i + 1)
operations.pop(i)
# multiply/division
for i, x in enumerate(operations):
if x in ['*', '/']:
num[i] = perform[operations[i]](num[i], num[i + 1])
num.pop(i + 1)
operations.pop(i)
# last addition/subtraction
for i, op in enumerate(operations):
if op == '-':
num[i + 1] = -num[i + 1]
return sum(num)
# define all operations you need, no need to add + or -
perform = {'*': lambda x, y: x * y, '/': lambda x, y: x / y, '**': lambda x, y: x ** y }
result = translate('5+3+10**2+210-30/2')
print('result =', result)
Output:
input string: 5+3+10**2+210-30/2
numbers: [5.0, 3.0, 10.0, 2.0, 210.0, 30.0, 2.0]
operations ['+', '+', '**', '+', '-', '/']
result = 303.0
Edit3:
shorter one with regex
import re
def translate(s):
num = re.findall(r'\d+', s) # '\d' means digits only
operations = re.findall(r'\D+', s) # '\D' means anything but digits
print('input string:', s)
print('numbers:', num)
print('operations', operations)
# "power calculations" to be done first
for i, x in enumerate(operations):
if x == '**':
num[i] = perform[operations[i]](num[i], num[i + 1])
num.pop(i + 1)
operations.pop(i)
# multiply/division
for i, x in enumerate(operations):
if x in ['*', '/']:
num[i] = perform[operations[i]](num[i], num[i + 1])
num.pop(i + 1)
operations.pop(i)
# last addition/subtraction
for i, op in enumerate(operations):
if op == '-':
num[i + 1] = -num[i + 1]
return sum(num)
# define all operations you need, no need to add + or -
perform = {'*': lambda x, y: x * y, '/': lambda x, y: x / y, '**': lambda x, y: x ** y }
result = translate('5+3+10**2+210-30/2')
print('result =', result)