I am quite new to programming. This is in relation to python. So the idea is to take an expression such as 3/5 or, at most, 3/5*2(at most two operators, note that the operat
Use the shlex
and StringIO
Python module. In Python 2.3+:
>>> from StringIO import StringIO
>>> import shlex
>>> input = StringIO('3/4+5')
>>> list(shlex.shlex(input))
['3', '/', '4', '+', '5']
If I wasn't going to rely on external libraries, I'd do it something like this:
def parse(x):
operators = set('+-*/')
op_out = [] #This holds the operators that are found in the string (left to right)
num_out = [] #this holds the non-operators that are found in the string (left to right)
buff = []
for c in x: #examine 1 character at a time
if c in operators:
#found an operator. Everything we've accumulated in `buff` is
#a single "number". Join it together and put it in `num_out`.
num_out.append(''.join(buff))
buff = []
op_out.append(c)
else:
#not an operator. Just accumulate this character in buff.
buff.append(c)
num_out.append(''.join(buff))
return num_out,op_out
print parse('3/2*15')
It's not the most elegant, but it gets you the pieces in a reasonable data structure (as far as I'm concerned anyway)
Now code to actually parse and evaluate the numbers -- This will do everything in floating point, but would be easy enough to change ...
import operator
def my_eval(nums,ops):
nums = list(nums)
ops = list(ops)
operator_order = ('*/','+-') #precedence from left to right. operators at same index have same precendece.
#map operators to functions.
op_dict = {'*':operator.mul,
'/':operator.div,
'+':operator.add,
'-':operator.sub}
Value = None
for op in operator_order: #Loop over precedence levels
while any(o in ops for o in op): #Operator with this precedence level exists
idx,oo = next((i,o) for i,o in enumerate(ops) if o in op) #Next operator with this precedence
ops.pop(idx) #remove this operator from the operator list
values = map(float,nums[idx:idx+2]) #here I just assume float for everything
value = op_dict[oo](*values)
nums[idx:idx+2] = [value] #clear out those indices
return nums[0]
print my_eval(*parse('3/2*15'))
That's not really the way to parse an expression, you should look more into lexers and parsers, something like PLY or pyparsing. However, if you just want to evaluate the expression you could use eval(expr)
. Note that eval will execute any code you feed it, so it's not really safe.
Edit There's an example here for using pyparsing, that should get you started:
pyparsing example