# Buggy code
def fit_summary(self, verbosity=3):
    """
    Output summary of information about models produced during `fit()`.
    May create various generated summary plots and store them in folder: `Predictor.output_directory`.

    Parameters
    ----------
    verbosity : int, default = 3
        Controls how detailed of a summary to ouput.
        Set <= 0 for no output printing, 1 to print just high-level summary,
        2 to print summary and create plots, >= 3 to print all information produced during fit().

    Returns
    -------
    Dict containing various detailed information. We do not recommend directly printing this dict as it may be very large.
    """
    hpo_used = len(self._trainer.hpo_results) > 0
    model_typenames = {
        key: self._trainer.model_types[key].__name__
        for key in self._trainer.model_types
    }
    model_innertypenames = {
        key: self._trainer.model_types_inner[key].__name__
        for key in self._trainer.model_types
        if key in self._trainer.model_types_inner
    }
    MODEL_STR = "Model"
    ENSEMBLE_STR = "Ensemble"
    for model in model_typenames:
        if (
            (model in model_innertypenames)
            and (ENSEMBLE_STR not in model_innertypenames[model])
            and (ENSEMBLE_STR in model_typenames[model])
        ):
            new_model_typename = (
                model_typenames[model] + "_" + model_innertypenames[model]
            )
            if new_model_typename.endswith(MODEL_STR):
                new_model_typename = new_model_typename[: -len(MODEL_STR)]
            model_typenames[model] = new_model_typename

    unique_model_types = set(model_typenames.values())  # no more class info
    # all fit() information that is returned:
    results = {
        "model_types": model_typenames,  # dict with key = model-name, value = type of model (class-name)
        "model_performance": self._trainer.get_model_attributes_dict(
            "val_score"
        ),  # dict with key = model-name, value = validation performance
        "model_best": self._trainer.model_best,  # the name of the best model (on validation data)
        "model_paths": self._trainer.model_paths,  # dict with key = model-name, value = path to model file
        "model_fit_times": self._trainer.get_model_attributes_dict("fit_time"),
        "model_pred_times": self._trainer.get_model_attributes_dict("predict_time"),
        "num_bagging_folds": self._trainer.kfolds,
        "stack_ensemble_levels": self._trainer.stack_ensemble_levels,
        "feature_prune": self._trainer.feature_prune,
        "hyperparameter_tune": hpo_used,
        "hyperparameters_userspecified": self._trainer.hyperparameters,
    }
    if self.problem_type != REGRESSION:
        results["num_classes"] = self._trainer.num_classes
    if hpo_used:
        results["hpo_results"] = self._trainer.hpo_results
    # get dict mapping model name to final hyperparameter values for each model:
    model_hyperparams = {}
    for model_name in self._trainer.get_model_names_all():
        model_obj = self._trainer.load_model(model_name)
        model_hyperparams[model_name] = model_obj.params
    results["model_hyperparams"] = model_hyperparams

    if verbosity > 0:  # print stuff
        print("*** Summary of fit() ***")
        print("Estimated performance of each model:")
        results["leaderboard"] = self._learner.leaderboard(silent=False)
        # self._summarize('model_performance', 'Validation performance of individual models', results)
        #  self._summarize('model_best', 'Best model (based on validation performance)', results)
        # self._summarize('hyperparameter_tune', 'Hyperparameter-tuning used', results)
        print("Number of models trained: %s" % len(results["model_performance"]))
        print("Types of models trained:")
        print(unique_model_types)
        num_fold_str = ""
        bagging_used = results["num_bagging_folds"] > 0
        if bagging_used:
            num_fold_str = f" (with {results['num_bagging_folds']} folds)"
        print("Bagging used: %s %s" % (bagging_used, num_fold_str))
        num_stack_str = ""
        stacking_used = results["stack_ensemble_levels"] > 0
        if stacking_used:
            num_stack_str = f" (with {results['stack_ensemble_levels']} levels)"
        print("Stack-ensembling used: %s %s" % (stacking_used, num_stack_str))
        hpo_str = ""
        if hpo_used and verbosity <= 2:
            hpo_str = (
                " (call fit_summary() with verbosity >= 3 to see detailed HPO info)"
            )
        print("Hyperparameter-tuning used: %s %s" % (hpo_used, hpo_str))
        # TODO: uncomment once feature_prune is functional:  self._summarize('feature_prune', 'feature-selection used', results)
        print("User-specified hyperparameters:")
        print(results["hyperparameters_userspecified"])
    if verbosity > 1:  # create plots
        plot_tabular_models(
            results,
            output_directory=self.output_directory,
            save_file="SummaryOfModels.html",
            plot_title="Models produced during fit()",
        )
        if hpo_used:
            for model_type in results["hpo_results"]:
                if "trial_info" in results["hpo_results"][model_type]:
                    plot_summary_of_models(
                        results["hpo_results"][model_type],
                        output_directory=self.output_directory,
                        save_file=model_type + "_HPOmodelsummary.html",
                        plot_title=f"Models produced during {model_type} HPO",
                    )
                    plot_performance_vs_trials(
                        results["hpo_results"][model_type],
                        output_directory=self.output_directory,
                        save_file=model_type + "_HPOperformanceVStrials.png",
                        plot_title=f"HPO trials for {model_type} models",
                    )
    if verbosity > 2:  # print detailed information
        if hpo_used:
            hpo_results = results["hpo_results"]
            print("*** Details of Hyperparameter optimization ***")
            for model_type in hpo_results:
                hpo_model = hpo_results[model_type]
                print(
                    "HPO for %s model:  Num. configurations tried = %s, Time spent = %s, Search strategy = %s"
                    % (
                        model_type,
                        len(hpo_model["trial_info"]),
                        hpo_model["total_time"],
                        hpo_model["search_strategy"],
                    )
                )
                print(
                    "Best hyperparameter-configuration (validation-performance: %s = %s):"
                    % (self.eval_metric, hpo_model["validation_performance"])
                )
                print(hpo_model["best_config"])
        """
            if bagging_used:
                pass # TODO: print detailed bagging info
            if stacking_used:
                pass # TODO: print detailed stacking info, like how much it improves validation performance
            if results['feature_prune']:
                pass # TODO: print detailed feature-selection info once feature-selection is functional.
            """
    if verbosity > 0:
        print("*** End of fit() summary ***")
    return results


# Traceback (ValueError)
File delimiter for ../input/house-prices-advanced-regression-techniques/test.csv inferred as ',' (comma). If this is incorrect, please manually load the data as a pandas DataFrame.
Loaded data from: ../input/house-prices-advanced-regression-techniques/test.csv | Columns = 80 / 80 | Rows = 1459 -> 1459
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-48-91455d7b9940> in <module>
1 test_data = task.Dataset(file_path=os.path.join(in_dir, job, 'test.csv'))
2
----> 3 preds = model.predict(test_data)

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/autogluon/task/tabular_prediction/predictor.py in predict(self, dataset, model, as_pandas, use_pred_cache, add_to_pred_cache)
130         """
131         dataset = self.__get_dataset(dataset)
--> 132         return self._learner.predict(X=dataset, model=model, as_pandas=as_pandas, use_pred_cache=use_pred_cache, add_to_pred_cache=add_to_pred_cache)
133
134     def predict_proba(self, dataset, model=None, as_pandas=False, as_multiclass=False):

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/autogluon/utils/tabular/ml/learner/abstract_learner.py in predict(self, X, model, as_pandas, use_pred_cache, add_to_pred_cache)
127
128         if len(X_cache_miss) > 0:
--> 129             y_pred_proba = self.predict_proba(X=X_cache_miss, model=model, inverse_transform=False)
130             problem_type = self.trainer_problem_type or self.problem_type
131             y_pred = get_pred_from_proba(y_pred_proba=y_pred_proba, problem_type=problem_type)

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/autogluon/utils/tabular/ml/learner/abstract_learner.py in predict_proba(self, X, model, as_pandas, as_multiclass, inverse_transform)
92     # TODO: Add pred_proba_cache functionality as in predict()
93     def predict_proba(self, X: DataFrame, model=None, as_pandas=False, as_multiclass=False, inverse_transform=True):
---> 94         X = self.transform_features(X)
95         y_pred_proba = self.load_trainer().predict_proba(X, model=model)
96         if inverse_transform:

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/autogluon/utils/tabular/ml/learner/abstract_learner.py in transform_features(self, X)
216     def transform_features(self, X):
217         for feature_generator in self.feature_generators:
--> 218             X = feature_generator.transform(X)
219         return X
220

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/autogluon/utils/tabular/utils/decorators.py in inner1(*args, **kwargs)
12         begin = time.time()
13
---> 14         output = func(*args, **kwargs)
15
16         # storing time after function execution

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/autogluon/utils/tabular/features/abstract_feature_generator.py in transform(self, X)
183             raise ValueError(f'Required columns are missing from the provided dataset. Missing columns: {missing_cols}')
184
--> 185         X = X.astype(self.features_init_types)
186         X.reset_index(drop=True, inplace=True)
187         X_features = self.generate_features(X)

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/pandas/core/generic.py in astype(self, dtype, copy, errors, **kwargs)
5863                     results.append(
5864                         col.astype(
-> 5865                             dtype=dtype[col_name], copy=copy, errors=errors, **kwargs
5866                         )
5867                     )

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/pandas/core/generic.py in astype(self, dtype, copy, errors, **kwargs)
5880             # else, only a single dtype is given
5881             new_data = self._data.astype(
-> 5882                 dtype=dtype, copy=copy, errors=errors, **kwargs
5883             )
5884             return self._constructor(new_data).__finalize__(self)

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/pandas/core/internals/managers.py in astype(self, dtype, **kwargs)
579
580     def astype(self, dtype, **kwargs):
--> 581         return self.apply("astype", dtype=dtype, **kwargs)
582
583     def convert(self, **kwargs):

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/pandas/core/internals/managers.py in apply(self, f, axes, filter, do_integrity_check, consolidate, **kwargs)
436                     kwargs[k] = obj.reindex(b_items, axis=axis, copy=align_copy)
437
--> 438             applied = getattr(b, f)(**kwargs)
439             result_blocks = _extend_blocks(applied, result_blocks)
440

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/pandas/core/internals/blocks.py in astype(self, dtype, copy, errors, values, **kwargs)
557
558     def astype(self, dtype, copy=False, errors="raise", values=None, **kwargs):
--> 559         return self._astype(dtype, copy=copy, errors=errors, values=values, **kwargs)
560
561     def _astype(self, dtype, copy=False, errors="raise", values=None, **kwargs):

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/pandas/core/internals/blocks.py in _astype(self, dtype, copy, errors, values, **kwargs)
641                     # _astype_nansafe works fine with 1-d only
642                     vals1d = values.ravel()
--> 643                     values = astype_nansafe(vals1d, dtype, copy=True, **kwargs)
644
645                 # TODO(extension)

~/miniconda3/envs/autogluon/lib/python3.7/site-packages/pandas/core/dtypes/cast.py in astype_nansafe(arr, dtype, copy, skipna)
698         if not np.isfinite(arr).all():
699             raise ValueError(
--> 700                 "Cannot convert non-finite values (NA or inf) to " "integer"
701             )
702

ValueError: Cannot convert non-finite values (NA or inf) to integer

# Fixed code
def fit_summary(self, verbosity=3):
    """
    Output summary of information about models produced during `fit()`.
    May create various generated summary plots and store them in folder: `Predictor.output_directory`.

    Parameters
    ----------
    verbosity : int, default = 3
        Controls how detailed of a summary to ouput.
        Set <= 0 for no output printing, 1 to print just high-level summary,
        2 to print summary and create plots, >= 3 to print all information produced during fit().

    Returns
    -------
    Dict containing various detailed information. We do not recommend directly printing this dict as it may be very large.
    """
    hpo_used = len(self._trainer.hpo_results) > 0
    model_typenames = {
        key: self._trainer.model_types[key].__name__
        for key in self._trainer.model_types
    }
    model_innertypenames = {
        key: self._trainer.model_types_inner[key].__name__
        for key in self._trainer.model_types
        if key in self._trainer.model_types_inner
    }
    MODEL_STR = "Model"
    ENSEMBLE_STR = "Ensemble"
    for model in model_typenames:
        if (
            (model in model_innertypenames)
            and (ENSEMBLE_STR not in model_innertypenames[model])
            and (ENSEMBLE_STR in model_typenames[model])
        ):
            new_model_typename = (
                model_typenames[model] + "_" + model_innertypenames[model]
            )
            if new_model_typename.endswith(MODEL_STR):
                new_model_typename = new_model_typename[: -len(MODEL_STR)]
            model_typenames[model] = new_model_typename

    unique_model_types = set(model_typenames.values())  # no more class info
    # all fit() information that is returned:
    results = {
        "model_types": model_typenames,  # dict with key = model-name, value = type of model (class-name)
        "model_performance": self._trainer.get_model_attributes_dict(
            "val_score"
        ),  # dict with key = model-name, value = validation performance
        "model_best": self._trainer.model_best,  # the name of the best model (on validation data)
        "model_paths": self._trainer.model_paths,  # dict with key = model-name, value = path to model file
        "model_fit_times": self._trainer.get_model_attributes_dict("fit_time"),
        "model_pred_times": self._trainer.get_model_attributes_dict("predict_time"),
        "num_bagging_folds": self._trainer.kfolds,
        "stack_ensemble_levels": self._trainer.stack_ensemble_levels,
        "feature_prune": self._trainer.feature_prune,
        "hyperparameter_tune": hpo_used,
        "hyperparameters_userspecified": self._trainer.hyperparameters,
    }
    if self.problem_type != REGRESSION:
        results["num_classes"] = self._trainer.num_classes
    if hpo_used:
        results["hpo_results"] = self._trainer.hpo_results
    # get dict mapping model name to final hyperparameter values for each model:
    model_hyperparams = {}
    for model_name in self._trainer.get_model_names_all():
        model_obj = self._trainer.load_model(model_name)
        model_hyperparams[model_name] = model_obj.params
    results["model_hyperparams"] = model_hyperparams

    if verbosity > 0:  # print stuff
        print("*** Summary of fit() ***")
        print("Estimated performance of each model:")
        results["leaderboard"] = self._learner.leaderboard(silent=False)
        # self._summarize('model_performance', 'Validation performance of individual models', results)
        #  self._summarize('model_best', 'Best model (based on validation performance)', results)
        # self._summarize('hyperparameter_tune', 'Hyperparameter-tuning used', results)
        print("Number of models trained: %s" % len(results["model_performance"]))
        print("Types of models trained:")
        print(unique_model_types)
        num_fold_str = ""
        bagging_used = results["num_bagging_folds"] > 0
        if bagging_used:
            num_fold_str = f" (with {results['num_bagging_folds']} folds)"
        print("Bagging used: %s %s" % (bagging_used, num_fold_str))
        num_stack_str = ""
        stacking_used = results["stack_ensemble_levels"] > 0
        if stacking_used:
            num_stack_str = f" (with {results['stack_ensemble_levels']} levels)"
        print("Stack-ensembling used: %s %s" % (stacking_used, num_stack_str))
        hpo_str = ""
        if hpo_used and verbosity <= 2:
            hpo_str = (
                " (call fit_summary() with verbosity >= 3 to see detailed HPO info)"
            )
        print("Hyperparameter-tuning used: %s %s" % (hpo_used, hpo_str))
        # TODO: uncomment once feature_prune is functional:  self._summarize('feature_prune', 'feature-selection used', results)
        print("User-specified hyperparameters:")
        print(results["hyperparameters_userspecified"])
        print("Feature Metadata (Processed):")
        print("(raw dtype, special dtypes):")
        print(self.feature_metadata)
    if verbosity > 1:  # create plots
        plot_tabular_models(
            results,
            output_directory=self.output_directory,
            save_file="SummaryOfModels.html",
            plot_title="Models produced during fit()",
        )
        if hpo_used:
            for model_type in results["hpo_results"]:
                if "trial_info" in results["hpo_results"][model_type]:
                    plot_summary_of_models(
                        results["hpo_results"][model_type],
                        output_directory=self.output_directory,
                        save_file=model_type + "_HPOmodelsummary.html",
                        plot_title=f"Models produced during {model_type} HPO",
                    )
                    plot_performance_vs_trials(
                        results["hpo_results"][model_type],
                        output_directory=self.output_directory,
                        save_file=model_type + "_HPOperformanceVStrials.png",
                        plot_title=f"HPO trials for {model_type} models",
                    )
    if verbosity > 2:  # print detailed information
        if hpo_used:
            hpo_results = results["hpo_results"]
            print("*** Details of Hyperparameter optimization ***")
            for model_type in hpo_results:
                hpo_model = hpo_results[model_type]
                print(
                    "HPO for %s model:  Num. configurations tried = %s, Time spent = %s, Search strategy = %s"
                    % (
                        model_type,
                        len(hpo_model["trial_info"]),
                        hpo_model["total_time"],
                        hpo_model["search_strategy"],
                    )
                )
                print(
                    "Best hyperparameter-configuration (validation-performance: %s = %s):"
                    % (self.eval_metric, hpo_model["validation_performance"])
                )
                print(hpo_model["best_config"])
        """
            if bagging_used:
                pass # TODO: print detailed bagging info
            if stacking_used:
                pass # TODO: print detailed stacking info, like how much it improves validation performance
            if results['feature_prune']:
                pass # TODO: print detailed feature-selection info once feature-selection is functional.
            """
    if verbosity > 0:
        print("*** End of fit() summary ***")
    return results