Alright, those who know me well are bound to ask, 19 credit hours and you are bored? Answer: Yes. It is still the first week and we don’t seem to have gotten beyond the “introduce your loser self to the other non-interested members of the class” and since I have only 1 programming intensive course this semester, I should have lots of time to kill.
Well, my first script this semester is an RPN calculator. Totally useless for the vast majority of people out there but they know what to expect from someone who likes theoretical computer science.
So, I first began with a stack – in this case an array. I then keep populating it with numbers and every time the state of the stack changes, it prints out the current state.
If an operation is entered (only +, -, * and /), it performs the operation, replaces the appropriate positions in the stack and then prints out the current state.
Here is the code, Its been a while since I wrote any OOP stuff in Python and the “self” especially feels weird after an entire semester of Java…
#Author: Shriphani Palakodety
#Mail: shriphani@shriphani.com
#RPN Calculator
class Machine:
def __init__(self, stack=[]):
self.stack = []
def modifyStack(self, element):
”‘add to stack if input is float else run operation or complain’”
if self.isOperator(element):
self.operate(element)
self.printStack()
elif self.isFloat(element):
self.stack.append(element)
self.printStack()
else:
print "Only numbers and operators"
def isFloat(self, char):
”‘Checks whether the last item entered in the stack is a float or not’”
try:
float(char)
except ValueError:
return False
return True
def isOperator(self, char):
”‘Checks whether the last item entered in the stack is an operator or not’”
if char == ‘+’ or char == ‘-’ or char == ‘*’ or char == ‘/’:
return True
else:
return False
def operate(self, operator):
”‘Perform the stated operation on the last two elements in the stack’”
operand1 = float(self.stack[-1])
operand2 = float(self.stack[-2])
self.stack.pop(-1)
self.stack.pop(-1)
if operator==‘+’:
self.stack.append(operand1+operand2)
elif operator==‘-’:
self.stack.append(operand2-operand1)
elif operator==‘*’:
self.stack.append(operand1*operand2)
elif operator==‘/’:
self.stack.append(float(operand2)/float(operand1))
else:
print "God only knows what operation you have typed in"
self.stack += [operand2, operand1]
self.printStack()
def printStack(self):
print self.stack
def kickOff():
calc = Machine()
while True:
a = raw_input(‘Input: ‘)
if a != ”:
calc.modifyStack(a)
else:
calc.printStack()
raise SystemExit
print"Press Enter to Quit\n"
kickOff()
The calculator in action:
pal-179-083:~ shriphani$ python rpn.py Press Enter to Quit Input: 1 ['1'] Input: 2 ['1', '2'] Input: 3 ['1', '2', '3'] Input: 4 ['1', '2', '3', '4'] Input: 5 ['1', '2', '3', '4', '5'] Input: + ['1', '2', '3', 9.0] Input: h Only numbers and operators Input: - ['1', '2', -6.0] Input: ['1', '2', -6.0]
In other news, I am really pissed with Picasa since I can’t see how many people have viewed my pics (http://picasaweb.google.com/shriphanip in case you are interested), I have begun filling my playlists with songs played at apple keynotes and in apple ads. Friends say this is an obsession with everything with the Apple stamp on it. I basically don’t care.
There has always been this one question bugging me since last semester. In Java:
When I run this:
pal-179-083:~ shriphani$ java Test 5349 pal-179-083:~ shriphani$
What is happening here?
Anyway, looking forward to this semester. Hope my GPA stays at 4.0

octal
For the Java question: By starting the literal with a zero you’ve designated it to be in octal, or base 8. In Python try “print oct(5349)”.
The same thing happens in Python. The leading 0 on your integer makes it an octal number.
That is octal format: “012345″
A leading zero specifies an octal constant. Similarly, a leading 0x specifies a hex constant.
You are specifying an octal value (leading ‘zero’ flags value as an octal to the compiler) and println is outputting decimal.
In response to your question:
12345 in octal is 5349 in decimal so perhaps Java takes a “0″ prefix to mean the number is in octal.
This is just a guess as my Java experience ended when I started to learn Python (3+ years ago).
> int a = 012345;
That would be octal. From http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html:
“”"
The prefix 0 indicates octal, whereas 0x indicates hexadecimal.
…
int octVal = 032; // The number 26, in octal
“”"
Oh, I know, Octal! ;-)
I won’t mention the word “octal” since nine people before me have already done so. ;-)
A couple of suggestions for the Python code: the de facto standard indentation, also blessed by the official style guide (PEP 8) is 4 spaces per level, not 8.
You can express the operator check more concisely as
return char in ['+', '-', '*', '/']
Also, ‘char’ is not a particularly good name since it may well be a multi-character string containing a floating point number.
list.pop() defaults to popping the last item, so passing -1 is redundant.
You’ve already converted both operands to floats when you extracted them from the stack (personally, I’d convert them when inserting into the stack, but whatever), so there’s no need for a repeated conversion where you’re implementing division. On the other hand, this may be a place where explicit is better than implicit.
Machine.__init__ ignores the stack argument. Also beware of using mutable types such as lists for default argument values, you can easily end up sharing objects without intending to do so.
I’d also use ‘return’ in place of ‘raise SystemExit’.
Small clarification: it was supposed to be “PEP 8″ (http://www.python.org/dev/peps/pep-0008/) followed by a closing parenthesis, and not a smiley at all.
Octal octal, octal octal octal. Octal octal octal; octal.
Oc tal octaaaaaaaaaaaallllllll!
Marius:
Thanks for your comments. Will keep them in mind.
Everyone Else
Thanks for answering my question.
Someone suggested that the leading 0 will produce octal content in Python. While this used to be true, it has been fixed in more recent versions (I tested in Python 2.5.2). To interpret a string as an octal value in Python you now are expected to pass the base to int, thus:
>>> int(’012345′)
12345
but
>>> int(’012345′, 8)
5349
“Explicit is better than implicit” strikes again
If you’re going to have folks talking about code, turning off automatic smiley’s would be a good step. The second example above should have ended with an eight (8) followed by a closing parenthesis.
May I suggest adding this to __init__:
self.operations = {'+':lambda o1, o2:o1+o2, '-':lambda o1, o2:o1-o2, '*':lambda o1, o2:o1*o2, '/':lambda o1, o2:o1/o2, '^':lambda o1, o2:o1**o2} The isOperator becomes: def isOperator(self, char): """Checks whether the last item entered in the stack is an operator or not""" if char in self.operations.keys(): return True else: return False and Operate() becomes: def operate(self, operator): """"Perform the stated operation on the last two elements in the stack""" operand1 = float(self.stack[-1]) operand2 = float(self.stack[-2]) self.stack.pop() self.stack.pop() self.stack.append(self.operations[operator](operand1, operand2))And adding operators becomes quite easy.
I’ve disabled automatic smileys. That shouldn’t be a problem anymore.
Dethe Elza:
Thanks a lot for mentioning that.
rcriii:
That looks cool. Thanks for posting your version.