class_docstr: An `Adapter`, guided by the `AdapterSpec`, takes a `Scenario` and produces
  a `ScenarioState`. It has additional logic surrounding in-context examples.
docstr: Sample a random set of train instances to use as examples by following the steps below:
  1. Sort the class labels (i.e., correct References) by the number of Instances that belong to the
     class so more common labels are included in the in-context examples. Break ties by shuffling.
  2. Keep sampling one train Instance from each class in the order established in step 1, until
     there are k examples.
  3. If we run out of examples to sample, sample the rest from the Instances that do not have
     class labels.
  
  Example:
  
      If we had to sample 2 instances from these train instances:
          Instance("say no", references=[Reference("no", tags=[CORRECT_TAG])]),
          Instance("say yes", references=[Reference("yes", tags=[CORRECT_TAG])]),
          Instance("say yes", references=[Reference("yes", tags=[CORRECT_TAG])]),
  
      The following instances would be selected:
  
          Instance("say yes", references=[Reference("yes", tags=[CORRECT_TAG])])
          Instance("say no", references=[Reference("no", tags=[CORRECT_TAG])])
  
  Returns a new list of randomly sampled train instances.
docstr_tok: ["Sample","a","random","set","of","train","instances","to","use","as","examples","by","following","the","steps","below",":","1",".","Sort","the","class","labels","(","i.e.",",","correct","References",")","by","the","number","of","Instances","that","belong","to","the","class","so","more","common","labels","are","included","in","the","in-context","examples",".","Break","ties","by","shuffling",".","2",".","Keep","sampling","one","train","Instance","from","each","class","in","the","order","established","in","step","1",",","until","there","are","k","examples",".","3",".","If","we","run","out","of","examples","to","sample",",","sample","the","rest","from","the","Instances","that","do","not","have","class","labels",".","Example",":","If","we","had","to","sample","2","instances","from","these","train","instances",":","Instance","(","``","say","no","''",",","references=","[","Reference","(","``","no","''",",","tags=","[","CORRECT_TAG","]",")","]",")",",","Instance","(","``","say","yes","''",",","references=","[","Reference","(","``","yes","''",",","tags=","[","CORRECT_TAG","]",")","]",")",",","Instance","(","``","say","yes","''",",","references=","[","Reference","(","``","yes","''",",","tags=","[","CORRECT_TAG","]",")","]",")",",","The","following","instances","would","be","selected",":","Instance","(","``","say","yes","''",",","references=","[","Reference","(","``","yes","''",",","tags=","[","CORRECT_TAG","]",")","]",")","Instance","(","``","say","no","''",",","references=","[","Reference","(","``","no","''",",","tags=","[","CORRECT_TAG","]",")","]",")","Returns","a","new","list","of","randomly","sampled","train","instances","."]
code: def sample_examples(
      self,
      all_train_instances: List[Instance],
      seed: int,
      sample_train: bool = True,
  ) -> List[Instance]:
      """
      Sample a random set of train instances to use as examples by following the steps below:
      1. Sort the class labels (i.e., correct References) by the number of Instances that belong to the
         class so more common labels are included in the in-context examples. Break ties by shuffling.
      2. Keep sampling one train Instance from each class in the order established in step 1, until
         there are k examples.
      3. If we run out of examples to sample, sample the rest from the Instances that do not have
         class labels.
  
      Example:
  
          If we had to sample 2 instances from these train instances:
              Instance("say no", references=[Reference("no", tags=[CORRECT_TAG])]),
              Instance("say yes", references=[Reference("yes", tags=[CORRECT_TAG])]),
              Instance("say yes", references=[Reference("yes", tags=[CORRECT_TAG])]),
  
          The following instances would be selected:
  
              Instance("say yes", references=[Reference("yes", tags=[CORRECT_TAG])])
              Instance("say no", references=[Reference("no", tags=[CORRECT_TAG])])
  
      Returns a new list of randomly sampled train instances.
      """
      # Fix the random seed for reproducibility
      random.seed(seed)
      num_instances_to_sample: int = min(
          len(all_train_instances),
          self.adapter_spec.max_train_instances,
      )
  
      examples: List[Instance] = []
      if not sample_train:
          # Select sequentially from the train set
          examples = all_train_instances[
              num_instances_to_sample
              * seed : num_instances_to_sample
              * (seed + 1)
          ]
          return examples
  
      unlabeled_instances: List[Instance] = []
      label_to_instances: Dict[str, List[Instance]] = defaultdict(list)
      for instance in all_train_instances:
          if instance.first_correct_reference:
              label_to_instances[
                  instance.first_correct_reference.output.text
              ].append(instance)
          else:
              unlabeled_instances.append(instance)
  
      # Build Instance counts to labels
      instances: List[Instance]
      counts_to_labels: Dict[int, List[str]] = defaultdict(list)
      for label, instances in sorted(label_to_instances.items()):
          counts_to_labels[len(instances)].append(label)
  
      sorted_labels: List[str] = []
      # Sort the labels by the number of Instances that belong to them
      for count in sorted(counts_to_labels, reverse=True):
          labels: List[str] = counts_to_labels[count]
          # Break ties by randomly shuffling labels that have the same number of Instances
          random.shuffle(labels)
          sorted_labels.extend(labels)
  
      labels_iterable = cycle(sorted_labels)
      while num_instances_to_sample > 0:
          next_label: Optional[str] = next(labels_iterable, None)
          if not next_label:
              break
  
          instances = label_to_instances[next_label]
          # If there are no Instances to sample for this particular label, skip it.
          if len(instances) == 0:
              continue
  
          # Randomly sample without replacement
          examples.append(
              instances.pop(random.randrange(len(instances)))
          )
          num_instances_to_sample -= 1
  
      # If we ran out of Instances with correct References, sample the rest from
      # the pool of Instances without any References
      examples += random.sample(
          unlabeled_instances, num_instances_to_sample
      )
      return examples
  
imports: import random
  from abc import ABC
  from collections import defaultdict
  from dataclasses import replace
  from itertools import cycle
  from typing import List, Dict, Optional
  from helm.benchmark.adaptation.prompt import Prompt
  from helm.benchmark.adaptation.request_state import RequestState
  from helm.benchmark.adaptation.scenario_state import ScenarioState
  from helm.benchmark.scenarios.scenario import Instance, TRAIN_SPLIT, EVAL_SPLITS, Reference
  from helm.common.general import parallel_map
  from helm.common.hierarchical_logger import hlog, htrack, htrack_block
  from .adapter import Adapter
label_desc: Use image node_id 3 for calling the InContextLearningAdapter obj's underlying member method code with example usage: obj.sample_examples(all_train_instances, seed, sample_train) and returns: examples, examples