# Simple RPN calculator from math import * from random import random ops = {'+': [2, lambda x, y : x + y], '-': [2, lambda x, y : x - y], '*': [2, lambda x, y : x * y], '/': [2, lambda x, y : x / y], 'inv': [1, lambda x : 1 / x], 'pow': [2, lambda x, y : pow(x, y)], '!': [1, lambda x : fact(int(round(x)))], 'deg': [1, lambda x : degrees(x)], 'rad': [1, lambda x : radians(x)], 'log': [1, lambda x : log(x)], 'log10': [1, lambda x : log10(x)], 'sqrt': [1, lambda x : sqrt(x)], 'sin': [1, lambda x : sin(x)], 'cos': [1, lambda x : cos(x)], 'tan': [1, lambda x : tan(x)], 'asin': [1, lambda x : asin(x)], 'acos': [1, lambda x : acos(x)], 'atan': [1, lambda x : atan(x)], 'chs': [1, lambda x : -x] } def evaluate(tokens, stack): for t in tokens: if t == 'pi': stack.append(pi) elif t == 'e': stack.append(e) elif t == 'rnd': stack.append(random()) elif t == 'swap': try: a = stack.pop() except: return [] try: b = stack.pop() except: return [a] stack.append(a) stack.append(b) elif t == 'roll': try: stack.insert(0, stack.pop()) except: return [] elif t == 'drop': try: stack.pop() except: return [] elif t == 'ent': try: stack.append(stack[-1]) except: return [] elif t in ops: op = ops[t][1] if ops[t][0] == 1 and len(stack) >= 1: a = stack.pop() try: stack.append(op(a)) except: print("Error"); stack.append(a) elif ops[t][0] == 2 and len(stack) >= 2: a = stack.pop() b = stack.pop() try: stack.append(op(b,a)) except: print("Error"); stack.append(b); stack.append(a) elif set(t).issubset(set("0123456789.-")): stack.append(float(t)) else: print("Unknown token %s" % t) return stack def fact(n): f = 1 while n > 0: f *= n; n -= 1 return f stack = [] while True: expression = input('> ') if expression is 'q': break elif expression is 'clr': stack = [] elif expression is '?': print('Help:', end=' ') w = 0 for o in sorted(list(ops.keys()) + ['rnd', '?', 'q', 'clr', 'pi', 'e', 'swap', 'roll', 'drop']): print(o, end=' ') w += 1 if w > 5: print(); w = 0 if w != 0: print() continue else: if len(expression) == 0: expression = "ent" stack = evaluate(expression.split(), stack) print(stack)