<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def autoclean_cv(training_dataframe, testing_dataframe, drop_nans=False, copy=False, encoder=None, encoder_kwargs=None, ignore_update_check=False):
 """Performs a series of automated data cleaning transformations on the provided training and testing data sets Unlike `autoclean()`, this function takes cross-validation into account by learning the data transformations from only the training set, then applying those transformations to both the training and testing set. By doing so, this function will prevent information leak from the training set into the testing set. Parameters training_dataframe: pandas.DataFrame Training data set testing_dataframe: pandas.DataFrame Testing data set drop_nans: bool Drop all rows that have a NaN in any column (default: False) copy: bool Make a copy of the data set (default: False) encoder: category_encoders transformer The a valid category_encoders transformer which is passed an inferred cols list. Default (None: LabelEncoder) encoder_kwargs: category_encoders The a valid sklearn transformer to encode categorical features. Default (None) ignore_update_check: bool Do not check for the latest version of datacleaner Returns output_training_dataframe: pandas.DataFrame Cleaned training data set output_testing_dataframe: pandas.DataFrame Cleaned testing data set """

    global update_checked
    if ignore_update_check:
        update_checked = True

    if not update_checked:
        update_check('datacleaner', __version__)
        update_checked = True

    if set(training_dataframe.columns.values) != set(testing_dataframe.columns.values):
        raise ValueError('The training and testing DataFrames do not have the same columns. '
                         'Make sure that you are providing the same columns.')

    if copy:
        training_dataframe = training_dataframe.copy()
        testing_dataframe = testing_dataframe.copy()
    
    if drop_nans:
        training_dataframe.dropna(inplace=True)
        testing_dataframe.dropna(inplace=True)

    if encoder_kwargs is None:
        encoder_kwargs = {}

    for column in training_dataframe.columns.values:
        # Replace NaNs with the median or mode of the column depending on the column type
        try:
            column_median = training_dataframe[column].median()
            training_dataframe[column].fillna(column_median, inplace=True)
            testing_dataframe[column].fillna(column_median, inplace=True)
        except TypeError:
            column_mode = training_dataframe[column].mode()[0]
            training_dataframe[column].fillna(column_mode, inplace=True)
            testing_dataframe[column].fillna(column_mode, inplace=True)

        # Encode all strings with numerical equivalents
        if str(training_dataframe[column].values.dtype) == 'object':
            if encoder is not None:
                column_encoder = encoder(**encoder_kwargs).fit(training_dataframe[column].values)
            else:
                column_encoder = LabelEncoder().fit(training_dataframe[column].values)

            training_dataframe[column] = column_encoder.transform(training_dataframe[column].values)
            testing_dataframe[column] = column_encoder.transform(testing_dataframe[column].values)

    return training_dataframe, testing_dataframe