class_docstr: Generates a controllable_gen version of a ParlAI task, i.e., for tasks with multi-
  turn dialogues (episodes), this will generate a task with single example episodes,
  in which we append to the context a special classification token.
class_docstr_tok: ["Generates","a","controllable_gen","version","of","a","ParlAI","task",",","i.e.",",","for","tasks","with","multi-","turn","dialogues","(","episodes",")",",","this","will","generate","a","task","with","single","example","episodes",",","in","which","we","append","to","the","context","a","special","classification","token","."]
docstr: Flatten and classify the normal task data.
  
  Save/load where applicable.
  
  :param opt:
      options dict.
docstr_tok: ["Flatten","and","classify","the","normal","task","data",".","Save\/load","where","applicable",".",":","param","opt",":","options","dict","."]
code: def _setup_data(self, opt: Opt) -> List[List[Message]]:
      """
      Flatten and classify the normal task data.
  
      Save/load where applicable.
  
      :param opt:
          options dict.
      """
      # create save directory, if it does not already exist
      self.original_task_name = ":".join(opt["task"].split(":")[2:])
      self.save_dir = self._get_save_path(
          opt["datapath"], str(datetime.datetime.today())
      )
      os.makedirs(self.save_dir, exist_ok=True)
  
      fname = f"{opt['datatype'].split(':')[0]}.json"
      self.save_path = os.path.join(self.save_dir, fname)
  
      data = self.load_data(opt, fname)
      if data is not None:
          # successfully load data
          return data
  
      # build the original teacher
      original_task_module = get_original_task_module(opt)
      teacher_opt = deepcopy(opt)
      teacher_opt["task"] = self.original_task_name
      teacher = original_task_module(teacher_opt)
  
      total_exs = teacher.num_examples()
      if self.opt["max_examples"] > 0:
          total_exs = min(self.opt["max_examples"], total_exs)
  
      progress_bar = tqdm(
          total=total_exs,
          unit="ex",
          unit_scale=True,
          desc="Building flattened data",
      )
  
      all_episodes = []
      num_exs = 0
      while num_exs < total_exs:
          current_episode = []
          episode_done = False
  
          while not episode_done:
              action = Message(teacher.act())
              current_episode.append(action)
              episode_done = action.get("episode_done", False)
              num_exs += 1
  
          # flatten the episode into 1-example episodes with context
          flattened_ep = flatten_and_classify(
              current_episode,
              opt["flatten_max_context_length"],
              include_labels=opt["flatten_include_labels"],
              delimiter=opt["flatten_delimiter"],
              word_lists=self.word_lists,
          )
          all_episodes += flattened_ep
  
          progress_bar.update(len(flattened_ep))
  
      # save data for future use
      self.save_data(all_episodes)
  
      return all_episodes
  
imports: from parlai.core.params import ParlaiParser
  from parlai.core.message import Message
  from parlai.core.opt import Opt
  from parlai.core.teachers import FixedDialogTeacher
  from parlai.utils.io import PathManager
  import parlai.utils.logging
  from parlai.utils.typing import TShared
  from parlai.tasks.genderation_bias.build import build
  from parlai.tasks.genderation_bias.utils import flatten_and_classify, get_original_task_module
  from copy import deepcopy
  import datetime
  import glob
  import json
  import os
  from tqdm import tqdm
  from typing import List, Optional, Tuple
label_desc: Use image node_id 7 for calling the ControllableTaskTeacher obj's underlying member method code with example usage: obj._setup_data(opt) and returns: all_episodes, data