code:
def rpn():
list = []
while 1:
x = raw_input(" ")
if x in ["+","-","*","/","%"]:
y=str(eval(list[-2]+x+list[-1]))
list[-2:]=[y]
elif x == "":
break
elif x == "=":
print y
else:
list.append(x)

How can i modify my rpn calculator in order to:

1)accept random number

x = random number

e.g

x x x x x x

2)accept a stack variable
and pop each time a number:
e.g

1
2
3
+
stack
+
stack
=


3)accept comments

e.g

#comment
1 #comment
2 #comment
+
=

4) accept as input :

2
+
=


5) accept exponential

e.g

1 1 ^ 1 =


Please help me! Thank you!

Recommended Answers

All 25 Replies

for Python on Daniweb:
Please use the [code=python] and [/code] tag pair to enclose your python code.

Python code uses proper indentation as part of its code. Presenting unindented Python code forces the person that may want to help you to do this and discourages many.

[Sorry for not including the code tags in my previous post]

Well thats my rpn calculator up to now
but i still want to add extra features such as

a)to insert a variable, for instance "x", while im doing some calculations in order to re-add the two previous numbers every time that im typing x :
1
2
3
x
+
x
=

b) to be able to inputs such as:
1
+


c) to handle zeroDivisionError

d)to be able to handle exponential functions, in the same line not as my current version of rpn works i.e:

2 2 ^ 2 ^ =

e) to be able to accept comments in the same manner as the above works i.e:

#accept a comment
1 1 + #accept a comment


f) to be able to accept random numbers


Thanks in advance and i'm awaiting tensely for replies ! ! !

import random
import math

def rpn_calculator():
    list = []
    ls = []
  
    while 1:
        
        x = raw_input("> ")
        ls.append(x)


            
        #BASIC THINGS
        
        if x in ["+","-","*","/","%"]:
            y=str(eval(list[-2]+x+list[-1]))
            list[-2:]=[y]

     
            #add comments
        
        elif x in ["+","#"]:
                for i in range(len(ls)):
                    if list["#":] + '\n':
                        pass

                elif x in ['\n', list["#":]]:
                        ls.remove(x)
                        pass

                elif x not in list["#":]:
                        y = str(eval(list[-2] + x + list[-1]))
                        list[-2:] = [y]
                        
            
        elif x == "":
            break
        elif x == "=":
            print y

        else:
            list.append(x)

Sorry, but could you please be more specific with what your program does? I have no idea what a 'rpn' calculator does, neither what it is. If you could explain what your calculator is supposed to do, I believe I can be of some help =]

One quick hint, do not use list as a variable name it is a function in Python. Use something like mylist.

I did it but i cant find out how will this help me ?

Have you ever gotten your code to do anything? The way it is now it will not work, even in its simplest form.

Yeah it works with the simple things except from those i posted previously.

def rpn_calculator():
    mylist = []
    ls = []
    
    while 1:

        x = raw_input("> ")
        ls.append(x)

        
            #basic things
                    
        if x in ["+","-","*","/","%"]:
            y=str(eval(mylist[-2]+x+mylist[-1]))
            mylist[-2:]=[y]

            #comments

        elif x in ["+","#"]:
            for i in range(len(ls)):
                if mylist["#":]+ '\n':
                    pass
                elif x in ['\n', mylist["#":]]:
                    ls.remove(x)
                    pass
                elif x not in mylist["#":]:
                    y = str(eval(mylist[-2] + x + mylist[-1]))
                    mylist[-2:] = [y]
                        
        elif x == "":
            break
        elif x == "=":
            print y
        else:
            mylist.append(x)

hint: use a stack. number => push onto stack ; operator => pop 2 off stack, operate, push back result.

Neither can i understood the modification of list to mylist..

hint: use a stack. number => push onto stack ; operator => pop 2 off stack, operate, push back result.

But thats how the calculator works
The problem is that i dunno how to add the extra features i posted previously

Thanks in advance !

Sorry, I thought I said I could help, but this is out of my league, and I can't think of how to do it xD

Sorry, I thought I said I could help, but this is out of my league, and I can't think of how to do it xD

Okay thanks anyway...

Does anyone else know how to help me ???
:(

Neither can i understood the modification of list to mylist..

You don't want to use a Python builtin function as a variable name. Here is an example, first the normal use of the list() function ...

print list('abcde')
"""
my output -->
['a', 'b', 'c', 'd', 'e']
"""

Now make list is a variable name, this will give you an error when you want to use it as a function later ...

list = []
# lots 
# of your
# code here
# finally comes the moment you want to use list as a function 
print list('abcde')
"""
my output -->
TypeError: 'list' object is not callable
"""

Actually the problem that i want to solve is to find a way the input of my program to accept apart from vertical, horizontal inputs
in other words the current form accepts
1
2
+
=
but i want to modify it in order to accept:
1 2 +


Thanks

http://en.wikipedia.org/wiki/Reverse_Polish_notation

Its a calculator that takes input of this form:

a b + = result

Thanks in advance !

Write your initial program to do just that. Once you got that working, expand gradually with more operators.

But my program is supposed to do both of them
To accept things either vertical or horizontal
:-/

I assume this is what you mean with horizontal ...

# the user enters data in reverse polish notation eg.
mystr = '11 77 +'

# put it into a list
mylist = mystr.split()
# test it
print mylist  # ['11', '77', '+']

# convert it to '11+77' so you can calculate it
# you can do that with list indexing
calcstr = str(mylist[0]) + str(mylist[2]) + str(mylist[1])

# now evaluate the string
print mystr, '=', eval(calcstr)
print 'or ...'
print calcstr, '=', eval(calcstr)
"""
my output -->
11 77 + = 88
or ...
11+77 = 88
"""

It's still not be what I want!:(
I want my current code in a way to be modified in order to accept the horizontal inputs
:( :-/

Thanks in advance

import random


def rpn():
     mylist = []
     while 1:
                 x = raw_input("> ")
               
                 if x in ["+","-","*","/","%"]:
                         y = str(eval(mylist[-2]+x+mylist[-1]))
                         mylist[-2:]=[y]
                 elif x == "":
                         continue
                 elif x == "=":
                         if int(y) >= 2147483647:    # max value
                             print 2147483647
                         elif int(y) <= -2147483648: # min value
                             print -2147483648
                         #elif ZeroDivisionError:
                          #   print "Devision by 0"
                         else:
                             print y
                 elif x == "r":
                     random_numb()
                 elif x == "d":
                         for x in mylist[:]:
                             print x
                 elif x[0] == "#":  # accept comment
                         continue
                 else:
                         mylist.append(x)
      


def random_numb():
     mylistrand = (1,2,3,4)
     
     rando = random.choice(mylistrand)
     print rando


rpn()

But my program is supposed to do both of them
To accept things either vertical or horizontal
:-/

untested, but should work w/ small mods:

stack = [ ]
for line in sys.stdin.readlines():
for item in line.split():
try:
x = int(item)
stack.append(x)
except ValueError:
# XXX: add error check for len(stack) < 2
op1, op2 = stack.pop(), stack.pop()
# XXX: check that 'item' is a valid operator
rslt = eval("%d %s %d" % (op1, item, op2))
stack.append(rslt)
# final result
print stack[0]

sorry forgot to enclose code..

stack = [ ]
for line in sys.stdin.readlines():
  for item in line.split():
    try:
      x = int(item)
      stack.append(x)
    except ValueError:
      # XXX: add error check for len(stack) < 2
      op1, op2 = stack.pop(), stack.pop()
      # XXX: check that 'item' is a valid operator
      rslt = eval("%d %s %d" % (op1, item, op2))
      stack.append(rslt)
# final result
print stack[0]

Thanks for your help but actually your program takes input only in horizontal form is that what im missing in my program and i have to add it
Is there any way via the sys module to accept input in both form [vertical and horizontal] ??

Thanks in advance

Im almost done
One of the last things i need to add is an exception for ZeroDivisionError but when im setting it:
except ZeroDivisonError:
print "Zero."

I get an invalid syntax error
By the way im wrote it before the last else of the code.

If anyone have any idea of how this error can be solved let me know

Thanks in advance!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.