code: def diff(y, x):
      
      if y == x: return ONE
      elif not y.args: return ZERO
      else:
          u, op, v = y.args[0], y.op, y.args[-1]
          if op == '+': return diff(u, x) + diff(v, x)
          elif op == '-' and len(args) == 1: return -diff(u, x)
          elif op == '-': return diff(u, x) - diff(v, x)
          elif op == '*': return u * diff(v, x) + v * diff(u, x)
          elif op == '/': return (v*diff(u, x) - u*diff(v, x)) / (v * v)
          elif op == '**' and isnumber(x.op):
              return (v * u ** (v - 1) * diff(u, x))
          elif op == '**': return (v * u ** (v - 1) * diff(u, x)
                                   + u ** v * Expr('log')(u) * diff(v, x))
          elif op == 'log': return diff(u, x) / u
          else: raise ValueError("Unknown op: %s in diff(%s, %s)" % (op, y, x))
docs: Return the symbolic derivative, dy/dx, as an Expr.
      However, you probably want to simplify the results with simp.
      >>> diff(x * x, x)
      ((x * 1) + (x * 1))
      >>> simp(diff(x * x, x))
      (2 * x)