def expand(exprTree): if not expr.isTree(exprTree): return exprTree left = expand(exprTree.node1) right = expand(exprTree.node2) if exprTree.oper == "+": return expand(left) + expand(right) if exprTree.oper == "*": if expr.isTree(left): if left.oper == "+": return expand(leftFoil(right, left)) if expr.isTree(right): if right.oper == "+": return expand(leftFoil(left, right)) if exprTree.oper == "^": if expr.isInt(right): right = int(expr.numeric(right)) return expand(left * left**(right - 1)) return exprTree
def numeric(obj): if not expr.isTree(obj): try: return obj.numeric() except (AttributeError, NotImplementedError): return obj return expr.refresh(obj, numeric)
def evaluate(obj, var, repl): if expr.isTree(obj): return expr.refresh(obj, lambda x: evaluate(x, var, repl)) try: if obj in var: return repl[var.index(obj)] else: return obj except TypeError: if obj == var: return repl else: return obj
def pow(base, exp): if exp == 0: return 1 if base == 0: return 0 if exp == 1: return base if base == 1: return 1 if expr.isTree(base): if base.oper == "^": return expr.ExprTree(base.node1, "^", (base.node2 * exp)) return expr.ExprTree(base, "^", exp)
def deriv(self, wrt): if expr.isConstWrt(self, wrt): return 0 if expr.isTree(self): if self.oper == "+": return add(self, wrt) if self.oper == "*": return mul(self, wrt) if self.oper == "^": return pow(self, wrt) try: # When it's a function return self.deriv(wrt) * deriv(self.arg, wrt) except AttributeError: # When it's a variable return self.deriv(wrt)