class_docstr: Class to compile results from static turn annotations.
  
  Change PROBLEM_BUCKETS in task_config/annotations_config.json to be the buckets that
  you are asking crowdsource workers to annotate with.
  
  NOTE this script directly accesses Mephisto files rather than using the DataBrowser.
  This makes it fragile and not a great example for extension. It is a good candidate
  for refactor.
class_docstr_tok: ["Class","to","compile","results","from","static","turn","annotations",".","Change","PROBLEM_BUCKETS","in","task_config\/annotations_config.json","to","be","the","buckets","that","you","are","asking","crowdsource","workers","to","annotate","with",".","NOTE","this","script","directly","accesses","Mephisto","files","rather","than","using","the","DataBrowser",".","This","makes","it","fragile","and","not","a","great","example","for","extension",".","It","is","a","good","candidate","for","refactor","."]
docstr: Validate a conversation subtask within the HIT.
  
  :return: tuple (is_valid, reason)
docstr_tok: ["Validate","a","conversation","subtask","within","the","HIT",".",":","return",":","tuple","(","is_valid",",","reason",")"]
code: def _validate_subtask(
      self, subtask_data
  ) -> Tuple[bool, Optional[str]]:
      """
      Validate a conversation subtask within the HIT.
  
      :return: tuple (is_valid, reason)
      """
      # Check that the conversation consists of pairs of comments between
      # agents 0 and 1, with 0 speaking first
      try:
          assert all(
              [
                  utterance_data["agent_idx"] == turn_idx % 2
                  for turn_idx, utterance_data in enumerate(
                      subtask_data
                  )
              ]
          )
          messages_0 = [
              utt for utt in subtask_data if utt["agent_idx"] == 0
          ]
          messages_1 = [
              utt for utt in subtask_data if utt["agent_idx"] == 1
          ]
          assert len(messages_0) + len(messages_1) == len(subtask_data)
      except Exception:
          return (
              False,
              f"Data not in form expected. Length is: {len(subtask_data)}",
          )
  
      for utterance_data in subtask_data:
          if (
              utterance_data["agent_idx"] == 1
              and self.problem_buckets[0] not in utterance_data
          ):
              return (
                  False,
                  f"Bot utterance was malformed and had no problem annotation fields (Failed to find key: {self.problem_buckets[0]}).",
              )
  
      return True, None
  
imports: import copy
  import json
  import os
  from datetime import datetime
  from typing import Any, Dict, Optional, Tuple
  import numpy
  import pandas
  from parlai.crowdsourcing.utils.analysis import AbstractTurnAnnotationResultsCompiler
label_desc: Use image node_id 7 for calling the TurnAnnotationsStaticResultsCompiler obj's underlying member method code with example usage: obj._validate_subtask(subtask_data) and returns: True,  None, False,  str, len, False,  str, self, str