ThatNinja ThatNinja - 6 months ago 9
Python Question

What is "trace" parameter to evaluate function?

So we started learning python in one of my classes, and now we are messing around with postfix/prefix notations. I looked around the web for some examples, and found this code, but i don't fully understand it. My question is regarding evaluate and parse functions. What is the deal with "trace" Why is it there, what does it do(if trace blocks)?

import operator
import string
import operator
import string

class EvaluationError(Exception):
pass

class InvalidParse(Exception):
pass

class InvalidNumber(Exception):
pass


class InvalidOperator(Exception):
pass


class UnbalancedParens(Exception):
pass


def cast(value):

if isinstance(value, (int, float)):
return value

try:
return int(value)
except ValueError:
pass
try:
return float(value)
except ValueError:
pass

raise InvalidNumber(value)


class Operator(object):
def __init__(self, op, precedence):
self._op = op
self._prec = precedence

def __call__(self, *args):
return self._op(*args)

def __lt__(self, op):
return self._prec < op._prec

def __gt__(self, op):
return self._prec > op._prec

def __eq__(self, op):
return self._prec == op._prec

def __repr__(self):
return repr(self._op)

def __str__(self):
return str(self._op)


class Calculator(object):
operators = {
'+' : Operator(operator.add, 1),
'-' : Operator(operator.sub, 1),
'*' : Operator(operator.mul, 2),
'/' : Operator(operator.div, 2),
'^' : Operator(operator.pow, 3),
}

def __init__(self):
pass

def calculate(self, expr):

tokens = self.parse(expr)
result = self.evaluate(tokens)
return result

def evaluate(self, tokens, trace=False):

stack = []
for item in tokens:
if isinstance(item, Operator):
if trace:
print stack

b, a = cast(stack.pop()), cast(stack.pop())
result = item(a, b)
stack.append(result)

if trace:
print stack
else:
if item.endswith('.'):
raise InvalidNumber(item)
stack.append(item)

if len(stack) > 1:
raise EvaluationError(str(stack))

return stack[0]

def parse(self, expr, trace=False):

tokens = []
op_stack = []

last = None

for c in expr:
if c in string.whitespace:
last = c
elif c in string.digits:
value = str(c)
if last and last in string.digits:
value = tokens.pop() + value

last = c
tokens.append(value)
elif c == '.':
if last and last in string.digits:
tokens.append(tokens.pop() + ".")
else:
raise InvalidParse()
elif c == '(':
op_stack.append('(')
elif c == ')':
if not op_stack:
raise UnbalancedParens(c)


while op_stack:
curr = op_stack.pop()
if curr is '(':
break
else:
tokens.append(curr)
else:
op = self.operators.get(c, None)
if op is None:
raise InvalidOperator(c)

while op_stack:
curr = op_stack[-1]

if curr is '(':
break
elif curr < op:
break
tokens.append(op_stack.pop())

op_stack.append(op)
last = c

if trace:
print "----"
print tokens
print op_stack
print "----"

while op_stack:
op = op_stack.pop()
if op is '(':
raise UnbalancedParens()
tokens.append(op)

if trace:
print "----"
print tokens
print op_stack
print "----"

return tokens

if __name__ == '__main__':
import sys

calc = Calculator()




print calc.calculate("12^2.5-10")

Answer

Literally what it says in the code. If trace is set to True, you'll get the stack printed out at various point of execution. This seems to exist for debugging / presentation purposes.

Comments