Is there a way to make a calculator that uses numbers such as -35 +25 to get -5 without having a section which determines the operation?
without doing this:
print("Please select operation -\n" \
"1. Add\n" \
"2. Subtract\n" \
"3. Multiply\n" \
"4. Divide\n")
>Solution :
A simple example:
def calc(s):
for op in '-+/*':
if op in s:
x, *xs = s.split(op)
if op == '*':
return calc(x) * calc(op.join(xs))
if op == '/':
return calc(x) / calc(op.join(xs))
if op == '+':
return calc(x) + calc(op.join(xs))
if op == '-':
return calc(x) - calc(op.join(xs))
else:
return float(s)
while True:
expr = input('Enter an expression with +, -, * or / ("stop" to exit): ')
if expr == 'stop':
break
print(calc(expr.replace(' ', '')))
For example, if you enter "2*3 + 15/5 – 2", the following happens:
- there’s a
-there, socalc('2*3+15/5') - calc('2')gets called- there’s a
+in'2*3+15/5', socalc('2*3') + calc('15/5')gets called- there’s a
*in'2*3', socalc('2') * calc('3')gets called- there are no operations in
'2', so it returns2.0 - there are no operations in
'3', so it returns3.0
- there are no operations in
- the results get multiplied, and
6.0is returned
etc.
- there’s a
- there’s a
The result is 7.0. The operations get executed in the correct order because the for loop looks for - first, then +, etc.
You could of course use eval() but that’s generally a bad idea. Consider this:
import shutil
expr = input('Enter something: ') # user enters 'shutil.rmtree("c:/windows")'
eval(expr)
I hope it’s clear that you should not try this, especially if your user accounts has admin rights and can actually delete your Windows folder (running on Windows, clearly).
The answer linked by user @amalk (Evaluating a mathematical expression in a string) goes a bit deeper into the use of eval(), but doing that safely is hardly easier than the above, if all you need is a simple calculator. Of course, if you want to use the full power of Python, you could just import math and use eval() to have access to all of it, including the use of parentheses, etc.