code: def clean_df(
      train_df,
      val_df=None,
      pc=[],
      lc=[],
      check_labels=True,
      return_types=False,
  ):
      train_type_dict = pd_data_types(train_df)
      for k, v in train_type_dict.items():
          if v != "string":
              continue
          train_df[k] = train_df[k].str.strip()
          if val_df is not None:
              if k not in val_df.columns:
                  raise ValueError("val_df is missing %s column" % (k))
              val_df[k] = val_df[k].str.strip()
      if (pc and not lc) or (not pc and lc):
          raise ValueError("pc and lc: both or neither must exist")
      if pc and lc:
          inp_cols = (
              train_df.columns.values
              if check_labels
              else [
                  col
                  for col in train_df.columns.values
                  if col not in lc
              ]
          )
          original_cols = pc + lc if check_labels else pc
          if set(original_cols) != set(inp_cols):
              raise ValueError(
                  "DataFrame is either missing columns or includes extra columns: \n"
                  + "expected: %s\nactual: %s"
                  % (original_cols, inp_cols)
              )
      if return_types:
          return train_type_dict
      return
  
imports: from ..None import utils
  from ..imports import *
  from ..preprocessor import Preprocessor
  from numbers import Number
  from types import SimpleNamespace
  from typing import Any, AnyStr, Callable, Collection, Dict, Hashable, Iterator, List, Mapping, NewType, Optional, Sequence, Tuple, TypeVar, Union
  from pandas.api.types import is_categorical_dtype, is_numeric_dtype
label_desc: Use image node_id 2 for calling a global function with example usage: clean_df(train_df, val_df, pc, lc, check_labels, return_types) and returns: train_type_dict