class_docstr: A node in an expression tree.
  
  ExprNode always holds an operator. Leaves are strings.
code: def __str__(self):
      left_str = str(self.left)
      right_str = str(self.right)
      left_use_parens = (
          isinstance(self.left, ExprNode)
          and self.left.op.precedence < self.op.precedence
      )
      right_use_parens = (
          isinstance(self.right, ExprNode)
          and self.right.op.precedence <= self.op.precedence
          and not (self.op.associative and self.right.op == self.op)
      )
      left_final = "(" + left_str + ")" if left_use_parens else left_str
      right_final = (
          "(" + right_str + ")" if right_use_parens else right_str
      )
      return left_final + str(self.op) + right_final
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from collections import namedtuple
  import random
  import six
  from six.moves import range
  import sympy
label_desc: Use image node_id 2 for calling the ExprNode obj's underlying member method code with example usage: obj.__str__() and returns: unknown