PLACE |
spec |
solutions |
Python |
This implementation is a stack-based one. It repeatedly calls the raw_input()
built-in function to read a line from the standard input, then transforms that line into a list of tokens. The latter is done by the split()
method of the module string
. The resulting list is fed to the for
loop so that the individual tokens become the successive values of tk
. An empty input line produces an empty list, for which the for
loop does nothing.
All intermediate results in the course of evaluating an expression are stored in st
– a list of numbers used as a stack.
If tk
is one of '+'
, '-'
, '*'
, or '/'
, then finding it in the ops
dictionary is successful. The two topmost numbers are popped off st
, the arithmetic function corresponding to tk
is obtained from ops
and applied to them. If tk
is not an operator, it is expected to contain a number. Whatever the case, a numeric result z
is eventually produced and pushed onto the stack.
Nominally, the program is an endless loop with all its actual content placed within a try
block. Upon encountering end of input, raw_input()
raises the EOFError
exception, which is handled by breaking the loop and eventually terminating the program.
Other exceptions may take place due to erroneous input. For example, if tk
is neither an operator nor a number, the call of float
, instead of producing a number, fails by raising ValueError
. Calling pop
raises IndexError
if st
is empty, showing an insufficient number of arguments for a particular arithmetic operator. Also, the assert
statement raises AssertionError
when the stated condition does not hold, indicating the presence of too few operators in an expression. For all these exceptions there is one universal handler which prints an error message and (implicitly) resumes the main loop.
import string, operator ops = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.div} while True: try: st = [] for tk in string.split(raw_input()): if tk in ops: y,x = st.pop(),st.pop() z = ops[tk](x,y) else: z = float(tk) st.append(z) assert len(st)<=1 if len(st)==1: print(st.pop()) except EOFError: break except: print('error')
The above program is written in the so called Python 2 dialect of the language. A major revision of the language, Python 3, is partially incompatible with the said dialect. With the following changes, the RPN calculator adapts to Python 3.
The div
function from the operator
module is renamed to truediv
.
The raw_input
function is renamed to input
.
The split
function in Python 3 does not belong to the string
module.
Along with many other former members of string
, it is now a method of a built-in string class, supplying frequently needed operations on textual data.
The string
module is not needed and is not imported in the Python 3 version of the calculator.
import operator ops = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.truediv} while True: try: st = [] for tk in input().split(): if tk in ops: y,x = st.pop(),st.pop() z = ops[tk](x,y) else: z = float(tk) st.append(z) assert len(st)<=1 if len(st)==1: print(st.pop()) except EOFError: break except: print('error')
boykobbatgmaildotcom