def generator(self, nbr_symbols, max_length, nbr_cases):
    """Generating for sorting task on sequence of symbols.

    The length of the sequence is drawn uniformly at random from [1, max_length]
    and then symbols are drawn (uniquely w/ or w/o replacement) uniformly at
    random from [0, nbr_symbols) until nbr_cases sequences have been produced.

    Args:
      nbr_symbols: number of symbols to use in each sequence.
      max_length: integer, maximum length of sequences to generate.
      nbr_cases: the number of cases to generate.

    Yields:
      A dictionary {"inputs": input-list, "targets": target-list} where
      target-list is input-list sorted.
    """
    for _ in range(nbr_cases):
      # Sample the sequence length.
      length = np.random.randint(max_length) + 1

      if self.unique:
        # Sample our inputs w/o replacement.
        inputs = np.arange(nbr_symbols)
        np.random.shuffle(inputs)

        # Truncate to the desired length.
        inputs = inputs[:length]
        inputs = list(inputs)
      else:
        inputs = list(np.random.randint(nbr_symbols, size=length))

      # Targets are simply the sorted inputs.
      targets = list(sorted(inputs))

      yield {"inputs": inputs, "targets": targets}
Generating for sorting task on sequence of symbols.

    The length of the sequence is drawn uniformly at random from [1, max_length]
    and then symbols are drawn (uniquely w/ or w/o replacement) uniformly at
    random from [0, nbr_symbols) until nbr_cases sequences have been produced.

    Args:
      nbr_symbols: number of symbols to use in each sequence.
      max_length: integer, maximum length of sequences to generate.
      nbr_cases: the number of cases to generate.

    Yields:
      A dictionary {"inputs": input-list, "targets": target-list} where
      target-list is input-list sorted.
    
tensor2tensor/data_generators/algorithmic.py