code: def _get_codes_for_values(values, categories):
      
      from pandas.core.algorithms import _get_data_algo, _hashtables
      dtype_equal = is_dtype_equal(values.dtype, categories.dtype)
  
      if dtype_equal:
          # To prevent erroneous dtype coercion in _get_data_algo, retrieve
          # the underlying numpy array. gh-22702
          values = getattr(values, '_ndarray_values', values)
          categories = getattr(categories, '_ndarray_values', categories)
      elif (is_extension_array_dtype(categories.dtype) and
            is_object_dtype(values)):
          # Support inferring the correct extension dtype from an array of
          # scalar objects. e.g.
          # Categorical(array[Period, Period], categories=PeriodIndex(...))
          try:
              values = (
                  categories.dtype.construct_array_type()._from_sequence(values)
              )
          except Exception:
              # but that may fail for any reason, so fall back to object
              values = ensure_object(values)
              categories = ensure_object(categories)
      else:
          values = ensure_object(values)
          categories = ensure_object(categories)
  
      (hash_klass, vec_klass), vals = _get_data_algo(values, _hashtables)
      (_, _), cats = _get_data_algo(categories, _hashtables)
      t = hash_klass(len(cats))
      t.map_locations(cats)
      return coerce_indexer_dtype(t.lookup(vals), cats)
docs: utility routine to turn values into codes given the specified categories