Generates code samples.

  Args:
    max_length: int.  max literal length.
    max_nest: int. max nesting level.
    ops: CodeOp. set of allowable operations.

  Returns:
    1. (str) output value.
    2. (str) Code operation.

def generate_code(max_length, max_nest, ops):
  """Generates code samples.

  Args:
    max_length: int.  max literal length.
    max_nest: int. max nesting level.
    ops: CodeOp. set of allowable operations.

  Returns:
    1. (str) output value.
    2. (str) Code operation.
  """
  stack = []
  def fetch_one():
    # Always use an existing nested value for one of the operands.
    if stack:
      return stack.pop()
    else:
      # Produce a numeral of max_length-digits.
      value = random.randint(10 ** (max_length - 1), 10 ** max_length - 1)
      code = str(value)
      return value, code

  def fetch(num_operands):
    values, codes = zip(*[fetch_one() for _ in six.moves.range(num_operands)])
    return values, codes

  for _ in six.moves.range(max_nest):
    op = random.choice(ops)
    values, codes = fetch(op.num_operands)
    new_value = op.eval(values)
    new_code = op.get_code(codes)
    stack.append((new_value, "(" + new_code + ")"))
  final_value, final_code = stack.pop()
  final_code = final_code[1:-1]
  final_code.strip("()")
  if not op.is_memory:
    final_value = int(final_value) % 10 ** (max_length+1)
  return str(final_value), final_code