code: def _prepare_to_calculate(
      self, X: pd.DataFrame, y: pd.Series
  ) -> Tuple[pd.DataFrame, np.ndarray, dict]:
      X, y, params = super()._prepare_to_calculate(X, y)
      if self.cat_features is not None:
          num_features = [
              col for col in X.columns if col not in self.cat_features
          ]
          X[num_features] = X[num_features].fillna(-999)
          X = fill_na_cat_features(X, self.cat_features)
          # TODO use one-hot encoding if cardinality is less 50
          for feature in self.cat_features:
              X[feature] = X[feature].astype("category").cat.codes
      if not is_numeric_dtype(y):
          y = correct_string_target(y)
      return X, y, params
  
imports: import logging
  from copy import deepcopy
  from typing import Any, Callable, Dict, List, Optional, Tuple, Union
  import numpy
  import pandas
  from catboost import CatBoostClassifier, CatBoostRegressor
  from lightgbm import LGBMClassifier, LGBMRegressor
  from numpy import log1p
  from pandas.api.types import is_numeric_dtype
  from sklearn.metrics import check_scoring, get_scorer, make_scorer, roc_auc_score
  from upgini.utils.sklearn_ext import cross_validate
  from sklearn.metrics._regression import _check_reg_targets, check_consistent_length, mean_squared_error
  from sklearn.model_selection import BaseCrossValidator
  from upgini.errors import ValidationError
  from upgini.metadata import ModelTaskType
  from upgini.resource_bundle import bundle
  from upgini.utils.target_utils import correct_string_target
label_desc: Use image node_id 3 for calling the OtherEstimatorWrapper obj's underlying member method code with example usage: obj._prepare_to_calculate(X, y) and returns: X,  y,  params