Nat G February 2016

Identifying elements in a list from sys.argv to do Reverse Polish Notation

I am having issues parsing arguments entered on command line that become part of a list. The following code correctly identifies whether an argument is either an operand or number, and thus makes the calculations correctly:

import operator
ops = { '+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.div }
import sys
print str(sys.argv)
array = sys.argv
total = 0
for i in range(1,len(array)):
    if array[i] == '+' or array[i] == '-' or array[i] == '*' or array[i] == '/':
        answer = ops[array[i]](float(array[i - 2]),float(array[i - 1]))
        total += answer
print total

So $ 1 1 + 1 0 - outputs 3

However the above logic is incorrect for Reverse Polish Notation. The below logic is better (forgive any indentation errors), but for some reason now the code doesn't identify whether the arguments are operands or numbers:

import operator
ops = { '+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.div }
import sys
print str(sys.argv)
array = sys.argv
i = 1
my_stack = []
while i < len(array):
#    if array[i] == float(array[i]) or array[i] == int(array[i]):

     if array[i] != '+' or array[i] != '-' or array[i] != '*' or array[i] != '/':
        my_stack.insert(0, array[i])
     else:
        answer = ops[array[i]](float(my_stack[1]),float(my_stack[0]))
        my_stack.pop(1)
        my_stack.pop(0)        
        my_stack.insert(0, answer)
     i = i + 1
print my_stack[0]

I've tried positively identifying if elements are numbers (floats or integers), and negatively identifying if elements are not operands, but neither approach is working. Either the command line doesn't recognize that element is not an operand, or doesn't recognize that element is float or integer. Any thoughts on how to identify if elements of list are numbers or operands?

Answers


Jeff Y February 2016

You have not followed DeMorgan's Law correctly. The second example must use "and" between the "!=" parts.

 if array[i] != '+' and array[i] != '-' and array[i] != '*' and array[i] != '/':


mhawke February 2016

You can determine whether a value is an operator by checking whether it exists as a key in your ops dictionary:

import operator

ops = { '+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.div }

if array[i] in ops:
    # it's an operator
else:
    # it's an operand... maybe

This has the advantage that you can easily support new operators just by adding them to your ops dictionary, e.g. modulo:

ops = { '%': operator.mod, '+': operator.add, '-': operator.sub, ...}

Post Status

Asked in February 2016
Viewed 1,180 times
Voted 8
Answered 2 times

Search




Leave an answer