#!/usr/bin/env python # coding: utf-8 # # Advanced Expression Manipulation Solutions # In[ ]: from sympy import * x, y, z = symbols('x y z') init_printing() from IPython.display import display # For each exercise, fill in the function according to its docstring. # ## Creating expressions from classes # Create the following objects without using any mathematical operators like `+`, `-`, `*`, `/`, or `**` by explicitly using the classes `Add`, `Mul`, and `Pow`. You may use `x` instead of `Symbol('x')` and `4` instead of `Integer(4)`. # # $$x^2 + 4xyz$$ # $$x^{(x^y)}$$ # $$x - \frac{y}{z}$$ # # In[ ]: def explicit_classes1(): """ Returns the expression x**2 + 4*x*y*z, built using SymPy classes explicitly. >>> explicit_classes1() x**2 + 4*x*y*z """ return Add(Pow(x, 2), Mul(4, x, y, z)) # In[ ]: explicit_classes1() # In[ ]: def explicit_classes2(): """ Returns the expression x**(x**y), built using SymPy classes explicitly. >>> explicit_classes2() x**(x**y) """ return Pow(x, Pow(x, y)) # In[ ]: explicit_classes2() # In[ ]: def explicit_classes3(): """ Returns the expression x - y/z, built using SymPy classes explicitly. >>> explicit_classes3() x - y/z """ return Add(x, Mul(-1, Mul(y, Pow(z, -1)))) # In[ ]: explicit_classes3() # ## Nested args # In[ ]: expr = x**2 - y*(2**(x + 3) + z) # Use nested `.args` calls to get the 3 in expr. # In[ ]: def nested_args(): """ Get the 3 in the above expression. >>> nested_args() 3 """ expr = x**2 - y*(2**(x + 3) + z) return expr.args[0].args[2].args[1].args[1].args[0] # In[ ]: nested_args() # ## Traversal # Write a post-order traversal function that prints each node. # In[ ]: def post(expr): """ Post-order traversal >>> expr = x**2 - y*(2**(x + 3) + z) >>> post(expr) -1 y 2 3 x x + 3 2**(x + 3) z 2**(x + 3) + z -y*(2**(x + 3) + z) x 2 x**2 x**2 - y*(2**(x + 3) + z) """ for arg in expr.args: post(arg) display(expr) # In[ ]: expr = x**2 - y*(2**(x + 3) + z) # In[ ]: post(expr)