Factory method for LearnToExecute Dataset module.

  Args:
    batch_size: (int). The number of elements in a mini-batch.
    max_length: (int). Maximum character length.
    max_nesting: (int). Maximum level of statement nesting.
    token_by_char: (bool). Tokenize by character or words?
    mode: (string). Either 'train', 'test'.
    loss_threshold: (int) curriculum threshold for error below which increase
        the task difficulty.
    min_tries: (int) minimum update tries for curriculum difficulty level.
    task_type: (string) defines the task by allowable ops (see TASK_TYPE_OPS).

  Returns:
    tf.Data.Dataset for LearnToExecute sample generator with the
    LearnToExecuteState monkey patched into the `state` attribute.

  Raises:
    ValueError: in case of bad `mode`.

def LearnToExecute(   # pylint: disable=invalid-name
    batch_size, max_length=1, max_nesting=1, token_by_char=True,
    mode=Mode.TRAIN_COMBINE, loss_threshold=0.1,
    min_tries=DEFAULT_MIN_CURRICULUM_EVAL_TRIES, task_type=TaskType.ALG_CTRL):
  """Factory method for LearnToExecute Dataset module.

  Args:
    batch_size: (int). The number of elements in a mini-batch.
    max_length: (int). Maximum character length.
    max_nesting: (int). Maximum level of statement nesting.
    token_by_char: (bool). Tokenize by character or words?
    mode: (string). Either 'train', 'test'.
    loss_threshold: (int) curriculum threshold for error below which increase
        the task difficulty.
    min_tries: (int) minimum update tries for curriculum difficulty level.
    task_type: (string) defines the task by allowable ops (see TASK_TYPE_OPS).

  Returns:
    tf.Data.Dataset for LearnToExecute sample generator with the
    LearnToExecuteState monkey patched into the `state` attribute.

  Raises:
    ValueError: in case of bad `mode`.
  """
  # defaults mode to "train-combine"
  if mode == Mode.TRAIN_COMBINE:
    curriculum = CombineCurriculum(
        max_length, max_nesting, loss_threshold, min_tries=min_tries)
  elif mode == Mode.TRAIN_MIX:
    curriculum = MixCurriculum(
        max_length, max_nesting, loss_threshold, min_tries=min_tries)
  elif mode == Mode.TRAIN_NAIVE:
    curriculum = NaiveCurriculum(
        max_length, max_nesting, loss_threshold, min_tries=min_tries)
  elif mode == Mode.TEST:
    curriculum = BaselineCurriculum(
        max_length, max_nesting, loss_threshold, min_tries=0)
  else:
    raise ValueError("Invalid mode.")
  lte = LearnToExecuteState(batch_size, max_length, max_nesting,
                            curriculum, token_by_char, task_type=task_type)
  types_ = (tf.float32, tf.float32, tf.float32, tf.int64, tf.int64)
  shapes_ = (tf.TensorShape([lte.num_steps, batch_size, lte.vocab_size]),
             tf.TensorShape([lte.num_steps_out, batch_size, lte.vocab_size]),
             tf.TensorShape([lte.num_steps_out, batch_size, lte.vocab_size]),
             tf.TensorShape([batch_size,]),
             tf.TensorShape([batch_size,]))
  dataset = tf.data.Dataset.from_generator(lte.make_batch, types_, shapes_)
  dataset.state = lte
  return dataset