code: def cv(row, col_name, arg, current_data_model, df, con):
      
      vocabulary = con.vocab.vocabularies
      cell_value = str(row[col_name])
      if not cell_value:
          return None
      elif cell_value == "None":
          return None
      cell_values = cell_value.split(":")
      cell_values = [c.strip() for c in cell_values]
      # get possible values for controlled vocabulary
      # exclude weird unicode
      possible_values = []
      for val in vocabulary[col_name]:
          try:
              possible_values.append(str(val).lower())
          except UnicodeEncodeError as ex:
              print(val, ex)
      for value in cell_values:
          if str(value).lower() == "nan":
              continue
          elif str(value).lower() in possible_values:
              continue
          elif value.lower() == "none":
              continue
          else:
              try:
                  if str(float(value)) in possible_values:
                      continue
              except:
                  pass
              return '"{}" is not in controlled vocabulary for {}'.format(value, arg)
      return None
docs: row[col_name] must contain only values from the appropriate controlled vocabulary