code: def process_values(
      human_and_scores_rows: List[List[str]], score_names: List[str]
  ) -> Dict[str, List[float]]:
      human_and_scores_column_titles = human_and_scores_rows[0]
      value_title_column_idx = {}
      value_titles = []
  
      def _question_from_column_title(t: str) -> str:
          if t.endswith("_result"):
              t = t.replace("_result", "_question")
          return human_and_scores_rows[1][
              human_and_scores_column_titles.index(t)
          ]
  
      values_by_title = defaultdict(list)
      for i, t in enumerate(human_and_scores_column_titles):
          if (
              "_result" in t
              and "0_full_commonsenseSituationClaim" not in t
          ) or t in score_names:
              value_title_column_idx[t] = i
              value_titles.append(t)
              values_by_title[t] = []
      # make sure there are no duplicates
      value_titles = list(set(value_titles))
  
      human_column_titles, _ = split_list(
          value_titles, is_human_label_column_title
      )
      stepwise_labels = [
          h for h in human_column_titles if is_label_stepwise(h)
      ]
      stepwise_label_roots = set(
          root_label_from_numbered_step_label(l)
          for l in stepwise_labels
      )
  
      label_step_numbers = step_numbers_from_step_labels(
          stepwise_labels
      )
      step_number_counts = {str(n): 0 for n in label_step_numbers}
  
      for row_idx, row in enumerate(human_and_scores_rows):
          if row_idx == 0:
              # skip column title row
              continue
          for title in value_titles:
              # for labels, 1.0 is good and 0.0 indicates a reasoning error
              value = row[value_title_column_idx[title]]
              if value == "":
                  values_by_title[title].append(math.nan)
              elif "no" not in value and "yes" not in value:
                  # this is either a likert label or metric score
                  values_by_title[title].append(float(value))
              elif any(p in title for p in POSITIVE_ANNOTATIONS):
                  if value == "no":
                      values_by_title[title].append(0.0)
                  elif value == "yes":
                      values_by_title[title].append(1.0)
                  else:
                      raise NotImplementedError(
                          f"{title} value {value} not handled."
                      )
              elif any(n in title for n in NEGATIVE_ANNOTATIONS):
                  if value == "no":
                      values_by_title[title].append(1.0)
                  elif value == "yes":
                      values_by_title[title].append(0.0)
                  else:
                      raise NotImplementedError(
                          f"{title} value {value} not handled."
                      )
              else:
                  raise NotImplementedError(
                      f'Unhandled label. Would answering the question "yes" be negative or positive?'
                      + "| {title}: {_question_from_column_title(title)}"
                  )
  
              assert (
                  len(values_by_title[title]) == row_idx
              ), f"no value was added for {title}"
  
          step_texts = {
              n: row[
                  human_and_scores_column_titles.index(f"{n}_step_text")
              ]
              for n in label_step_numbers
          }
          current_row_step_numbers = [
              n for n in label_step_numbers if step_texts[n]
          ]
          last_step_number = current_row_step_numbers[-1]
  
          # update stats
          for n in current_row_step_numbers:
              step_number_counts[str(n)] += 1
  
          # this question only applies to the last step, so remove it from all other steps
          for i in range(1, last_step_number):
              label_title = (
                  f"{i}_step_step_questions_newFinalAnswerWrong_result"
              )
              if label_title in values_by_title:
                  values_by_title[label_title][-1] = math.nan
  
          # aggregates over steps
          for root in stepwise_label_roots:
              values_by_title[f"any_{root}"].append(
                  min(
                      v
                      for v in [
                          values_by_title[f"{n}_{root}"][-1]
                          for n in label_step_numbers
                      ]
                      if not math.isnan(v)
                  )
              )
  
          # aggregate over steps and labels
          all_step_values = [
              values_by_title[f"{n}_{root}"][-1]
              for root in stepwise_label_roots
              for n in label_step_numbers
          ]
          values_by_title["any_step_any_issue"].append(
              min(v for v in all_step_values if not math.isnan(v))
          )
  
          binary_seq_lvl_questions = [
              f"0_{l}_result"
              for l in (
                  "full_missingStep",
                  "full_consistentSelf",
                  "full_consistentContext",
                  "full_newClearContradiction",
                  "full_newMissingStep",
              )
          ] + ["any_step_any_issue"]
          all_sequence_level_errors = [
              l
              for l in values_by_title.keys()
              if any(v in l for v in binary_seq_lvl_questions)
          ]
          values_by_title["ANY_ERROR"].append(
              min(
                  values_by_title[e][-1]
                  for e in all_sequence_level_errors
              )
          )
  
      assert_all_elements_same_length(
          values_by_title.values(),
          "some columns have a different number of rows",
      )
  
      print("Step number stats:")
      for k, v in step_number_counts.items():
          print(f"{k}:\t{v}")
  
      # remove columns with only NaNs
      values_by_title = remove_empty_columns(values_by_title)
  
      return values_by_title
  
imports: import argparse
  from collections import defaultdict
  import csv
  import math
  import os
  import pathlib
  from typing import Dict, Iterable, List, Optional, Set, Tuple, Union
  import pandas
  from projects.roscoe.meta_evaluation.correlations import Analyzer
  from projects.roscoe.score import ROSCOE_SA, ROSCOE_SS, ROSCOE_LI, ROSCOE_LC, SUPERVISED_SCORES, UNSUPERVISED_SCORES
  from projects.roscoe.utils import assert_all_elements_same_length, ordered_union, split_list
  from projects.roscoe.meta_evaluation.table_file_writing import ANNOTATION_COLUMN_ORDER, COLUMN_RENAMES, MODELS, ROSCOE_SECTIONS, STEP_COLUMN_RENAMES, section_rows, write_every_dataset_summary_table_tex, write_every_dataset_final_summary_table_tex, write_granular_summary_tex
label_desc: Use image node_id 33 for calling a global function with example usage: process_values(human_and_scores_rows, score_names) and returns: values_by_title, human_and_scores_rows