def load_nursery(
    raw: bool = False, scaled: bool = True, test_set: float = 0.2, transform_social: bool = False
) -> DATASET_TYPE:
    """
    Loads the UCI Nursery dataset from `config.ART_DATA_PATH` or downloads it if necessary.

    :param raw: `True` if no preprocessing should be applied to the data. Otherwise, categorical data is one-hot
                encoded and data is scaled using sklearn's StandardScaler according to the value of `scaled`.
    :param scaled: `True` if data should be scaled.
    :param test_set: Proportion of the data to use as validation split. The value should be between 0 and 1.
    :param transform_social: If `True`, transforms the social feature to be binary for the purpose of attribute
                             inference. This is done by assigning the original value 'problematic' the new value 1, and
                             the other original values are assigned the new value 0.
    :return: Entire dataset and labels as numpy array.
    """
    import pandas as pd
    import sklearn.preprocessing

    # Download data if needed
    path = get_file(
        "nursery.data",
        path=config.ART_DATA_PATH,
        extract=False,
        url=[
            "https://www.dropbox.com/s/l24hwvkuueor6lp/nursery.data?dl=1",
        ],
    )

    # load data
    features_names = ["parents", "has_nurs", "form", "children", "housing", "finance", "social", "health", "label"]
    categorical_features = ["parents", "has_nurs", "form", "housing", "finance", "social", "health"]
    data = pd.read_csv(path, sep=",", names=features_names, engine="python")
    # remove rows with missing label or too sparse label
    data = data.dropna(subset=["label"])
    data.drop(data.loc[data["label"] == "recommend"].index, axis=0, inplace=True)

    # fill missing values
    data["children"] = data["children"].fillna(0)

    for col in ["parents", "has_nurs", "form", "housing", "finance", "social", "health"]:
        data[col] = data[col].fillna("other")

    # make categorical label
    def modify_label(value):  # 5 classes
        if value == "not_recom":
            return 0
        if value == "very_recom":
            return 1
        if value == "priority":
            return 2
        if value == "spec_prior":
            return 3
        raise Exception(f"Bad label value: {value}")

    data["label"] = data["label"].apply(modify_label)
    data["children"] = data["children"].apply(lambda x: 4 if x == "more" else x)

    if transform_social:

        def modify_social(value):
            if value == "problematic":
                return 1
            return 0

        data["social"] = data["social"].apply(modify_social)
        categorical_features.remove("social")

    if not raw:
        # one-hot-encode categorical features
        features_to_remove = []
        for feature in categorical_features:
            all_values = data.loc[:, feature]
            values = list(all_values.unique())
            data[feature] = pd.Categorical(data.loc[:, feature], categories=values, ordered=False)
            one_hot_vector = pd.get_dummies(data[feature], prefix=feature)
            data = pd.concat([data, one_hot_vector], axis=1)
            features_to_remove.append(feature)
        data = data.drop(features_to_remove, axis=1)

        # normalize data
        if scaled:
            label = data.loc[:, "label"]
            features = data.drop(["label"], axis=1)
            scaler = sklearn.preprocessing.StandardScaler()
            scaler.fit(features)
            scaled_features = pd.DataFrame(scaler.transform(features), columns=features.columns)
            data = pd.concat([label, scaled_features], axis=1, join="inner")

    features = data.drop(["label"], axis=1)
    if raw:
        numeric_features = features.drop(categorical_features, axis=1).to_numpy().astype(np.int32)
        min_, max_ = np.amin(numeric_features), np.amax(numeric_features)
    else:
        min_, max_ = np.amin(features.to_numpy().astype(np.float64)), np.amax(features.to_numpy().astype(np.float64))

    # Split training and test sets
    stratified = sklearn.model_selection.StratifiedShuffleSplit(n_splits=1, test_size=test_set, random_state=18)
    for train_set_i, test_set_i in stratified.split(data, data["label"]):
        train = data.iloc[train_set_i]
        test = data.iloc[test_set_i]
    x_train = train.drop(["label"], axis=1).to_numpy()
    y_train = train.loc[:, "label"].to_numpy()
    x_test = test.drop(["label"], axis=1).to_numpy()
    y_test = test.loc[:, "label"].to_numpy()

    if not raw and not scaled:
        x_train = x_train.astype(np.float64)
        x_test = x_test.astype(np.float64)

    return (x_train, y_train), (x_test, y_test), min_, max_

    Loads the UCI Nursery dataset from `config.ART_DATA_PATH` or downloads it if necessary.

    :param raw: `True` if no preprocessing should be applied to the data. Otherwise, categorical data is one-hot
                encoded and data is scaled using sklearn's StandardScaler according to the value of `scaled`.
    :param scaled: `True` if data should be scaled.
    :param test_set: Proportion of the data to use as validation split. The value should be between 0 and 1.
    :param transform_social: If `True`, transforms the social feature to be binary for the purpose of attribute
                             inference. This is done by assigning the original value 'problematic' the new value 1, and
                             the other original values are assigned the new value 0.
    :return: Entire dataset and labels as numpy array.
    
art/utils.py