def categorical_excess_cardinality_flagger_and_reducer(df, useful_cols,
    cardinality_fraction_threshold=0.1,
    cardinality_max_categories_threshold=50, **kwargs):
    """
    Function inspects categorical features in the input dataframe where there is excess cardinality (too many unique     values), and returns a list of features which exceed these thresholds, as well as Series detailing the cardinality     (in absolute terms as well as as a fraction of the total number of samples).
    
    Parameters
    ----------
    df : pandas.DataFrame
        The input dataframe
    useful_cols : pandas.DataFrame
        Look-up dataframe, which contains information about the dtypes of desired features, and how to deal with
        missing values for each feature
    cardinality_fraction_threshold : int or None
        Cardinality fraction is the ratio of unique values for a given feature to the total number of samples in the dataset
        - If None, no threshold applied
        - If int, this is the threshold beyond which a feature is deemed to have excessive cardinality
    cardinality_max_categories_threshold : int or None
        Cardinality max categories is the absolute number of unique values for a given feature
        - If None, no threshold applied
        - If int, this is the threshold beyond which a feature is deemed to have excessive cardinality
        
    Returns
    -------
    df_cardinality : pandas.Series
        Cardinality (number of unique elements) of the categorical features in the input dataset
    df_cardinality_fraction : pandas.Series
        Cardinality fractions of the categorical features in the input dataset
    excess_cardinality : list
        List of features which exceed one or more of the thresholds
    
    """
    categorical_features = list(useful_cols.loc[useful_cols.dtype ==
        'nominal', 'feature'])
    categorical_data = df[categorical_features]
    m_samples = categorical_data.shape[0]
    df_cardinality = categorical_data.nunique()
    df_cardinality_fraction = df_cardinality / m_samples
    excess_cardinality_fraction = set(df_cardinality_fraction[
        df_cardinality_fraction > cardinality_fraction_threshold].index)
    print(
        f'Following features exceed cardiality fraction threshold of {cardinality_fraction_threshold}: {excess_cardinality_fraction}'
        )
    excess_cardinality_absolute = set(df_cardinality[df_cardinality >
        cardinality_max_categories_threshold].index)
    print(
        f'Following features exceed cardiality absolute number threshold of {cardinality_max_categories_threshold}: {excess_cardinality_absolute}'
        )
    excess_cardinality = list(set.union(excess_cardinality_fraction,
        excess_cardinality_absolute))
    if kwargs['reducer'] == True:
        n_max_categories = kwargs['reducer_max_categories']
        for feature in excess_cardinality:
            value_counts = df[feature].value_counts()
            small_categories = list(value_counts[n_max_categories:].index)
            df.loc[df[feature].isin(small_categories), feature
                ] = 'SMALL_CATEGORY'
        print(
            f'Features {excess_cardinality} exceeded thresholds and have each been reduced down to a maximum {n_max_categories} categories per feature'
            )
    return df_cardinality, df_cardinality_fraction, excess_cardinality
