How to Program a Calculator in Python
We’re going to write a calculator in Python (a reverse Polish calculator) that can run from the command line. This is based on a possible Python homework that we can help with.
import sys
def calc(expr):
return expr
def main(args):
print(calc(” “.join(args[1:])))
if __name__ == “__main__”:
main(sys.argv)
At the moment it just displays the arguments as passed from the command line (skipping the program which is args[0]). So we want to tokenize it, this is probably best done using regular expressions.
import sys, re
tokenize = re.compile(“\w+|-?[0-9.]+|[+-/*]”, re.IGNORECASE)
def calc(expr):
expr = tokenize.findall(expr)
return expr
Now we want to start evaluating the expression, well add a couple of functions initially to ensure the code works.
functions = {“*” : (lambda stack : stack.pop() * stack.pop()),
“+” : (lambda stack : stack.pop() + stack.pop())}
def is_value(token):
try:
if ‘.’ in token:
return float(token)
return int(token)
except:
return
def calc(expr):
stack = []
for token in tokenize.findall(expr):
value = is_value(token)
if value is None:
func = functions.get(token)
if func:
stack.append(func(stack))
else:
stack.append(value)
return stack[0]
Lets extend it so you can add functions, here is a simple example.
> def square: dup *;8 square
64
And the code to implement this.
import sys, re
tokenize = re.compile(“\w+|-?[0-9.]+|[+-/*;:]”, re.IGNORECASE)
def sub(stack):
r, l = stack.pop(), stack.pop()
return l – r
def div(stack):
r, l = stack.pop(), stack.pop()
return l / r
functions = {“*” : (lambda stack : stack.pop() * stack.pop()),
“+” : (lambda stack : stack.pop() + stack.pop()),
“/” : div,
“-” : sub,
“dup” : (lambda stack : stack[-1])
}
definitions = {}
def is_value(token):
try:
if ‘.’ in token:
return float(token)
return int(token)
except:
return
def tokens(expr):
new = False
defining = None
for token in tokenize.findall(expr):
if token in definitions:
for token in definitions[token]:
yield token
else:
if token in (“def”, “:”):
new = True
continue
if new and not defining:
defining = token
definitions[defining] = []
continue
if defining:
if token == “;”:
defining = None
new = False
else:
definitions[defining].append(token)
continue
yield token
def calc(expr):
try:
stack = []
for token in tokens(expr):
value = is_value(token)
if value is None:
func = functions.get(token)
if func:
stack.append(func(stack))
else:
raise Exception(“Invalid token ” + token)
else:
stack.append(value)
if len(stack) != 1:
print(stack)
raise Exception(“Expression unbalanced”)
return stack[0]
except Exception as e:
print(e)
def main(args):
if len(args) > 1:
print(calc(” “.join(args[1:])))
#print(calc(“def f2c: 32- 9/5*;212 f2c”))
while True:
expr = input(“> “)
if expr in (“q”, “quit”, “exit”):
break
print(calc(expr))
if __name__ == “__main__”:
main(sys.argv)
It can easily be extended with variables and saving the state between sessions, you can also add extra functions such as sin, cos, sqrt, etc. The code uses a generator to simplify the main logic in the calc function, as that is totally unaware of the user defined functions. So if you are looking for python assignment help and would be interested in using our service then we can deliver quality results.
At Programmingassignments.com we can write this type of code in a matter of hours and can write far more sophisticated code if required.