docs: def check_keys_and_values_of_name_dictionary(names,
                                               specification_dict,
                                               num_alts):
      """
      Check the validity of the keys and values in the names dictionary.
  
      Parameters
      ----------
      names : OrderedDict, optional.
          Should have the same keys as `specification_dict`. For each key:
  
              - if the corresponding value in `specification_dict` is "all_same",
                then there should be a single string as the value in names.
              - if the corresponding value in `specification_dict` is "all_diff",
                then there should be a list of strings as the value in names.
                There should be one string in the value in names for each
                possible alternative.
              - if the corresponding value in `specification_dict` is a list,
                then there should be a list of strings as the value in names.
                There should be one string the value in names per item in the
                value in `specification_dict`.
      specification_dict : OrderedDict.
          Keys are a proper subset of the columns in `long_form_df`. Values are
          either a list or a single string, `"all_diff"` or `"all_same"`. If a
          list, the elements should be:
  
              - single objects that are within the alternative ID column of
                `long_form_df`
              - lists of objects that are within the alternative ID column of
                `long_form_df`. For each single object in the list, a unique
                column will be created (i.e. there will be a unique coefficient
                for that variable in the corresponding utility equation of the
                corresponding alternative). For lists within the
                `specification_dict` values, a single column will be created for
                all the alternatives within iterable (i.e. there will be one
                common coefficient for the variables in the iterable).
      num_alts : int.
          The number of alternatives in this dataset's universal choice set.
  
      Returns
      -------
      None.
      """
      if names.keys() != specification_dict.keys():
          msg = "names.keys() does not equal specification_dict.keys()"
          raise ValueError(msg)
  
      for key in names:
          specification = specification_dict[key]
          name_object = names[key]
          if isinstance(specification, list):
              try:
                  assert isinstance(name_object, list)
                  assert len(name_object) == len(specification)
                  assert all([isinstance(x, str) for x in name_object])
              except AssertionError:
                  msg = "names[{}] must be a list AND it must have the same"
                  msg_2 = " number of strings as there are elements of the"
                  msg_3 = " corresponding list in specification_dict"
                  raise ValueError(msg.format(key) + msg_2 + msg_3)
  
          else:
              if specification == "all_same":
                  if not isinstance(name_object, str):
                      msg = "names[{}] should be a string".format(key)
                      raise TypeError(msg)
  
              else:    # This means speciffication == 'all_diff'
                  try:
                      assert isinstance(name_object, list)
                      assert len(name_object) == num_alts
                  except AssertionError:
                      msg_1 = "names[{}] should be a list with {} elements,"
                      msg_2 = " 1 element for each possible alternative"
                      msg = (msg_1.format(key, num_alts) + msg_2)
                      raise ValueError(msg)
  
      return None