code: def test_summarize_grid_search_results(pipeline_results):
      """Tests summarize_grid_search_results"""
      # Tests EvaluationMetricEnum `score_func`, `cv_report_metrics=CV_REPORT_METRICS_ALL`
      grid_search = pipeline_results["1"].grid_search
      metric = EvaluationMetricEnum.MeanAbsolutePercentError
      cv_result = summarize_grid_search_results(
          grid_search=grid_search,
          only_changing_params=True,
          combine_splits=True,
          score_func=metric.name,
          score_func_greater_is_better=metric.get_metric_greater_is_better(),
      )
      assert cv_result.shape == (4, 60)
      # The proper scores are extracted
      short_name = metric.get_metric_name()
      expected = grid_search.cv_results_[f"mean_test_{short_name}"]
      assert_equal(
          np.array(cv_result[f"mean_test_{short_name}"]), expected
      )
      # Rank direction is correct
      assert (
          cv_result[f"rank_test_{short_name}"].idxmin()
          == cv_result[f"mean_test_{short_name}"].idxmin()
      )
      assert all(cv_result[f"mean_test_{short_name}"] > 0)
      assert [
          "rank_test_MAE",
          "rank_test_MSE",
          "rank_test_MedAPE",
          "rank_test_MAPE",
          "mean_test_MAE",
          "mean_test_MSE",
          "mean_test_MedAPE",
          "mean_test_MAPE",
          "split_test_MAPE",
          "split_test_MSE",
          "split_test_MAE",
          "split_test_MedAPE",
          "mean_train_MAE",
          "mean_train_MSE",
          "mean_train_MedAPE",
          "mean_train_MAPE",
          "params",
          "param_estimator__strategy",
          "param_estimator__quantile",
          "param_estimator__constant",
          "split_train_MAPE",
          "split_train_MSE",
          "split_train_MAE",
          "split_train_MedAPE",
          "mean_fit_time",
          "std_fit_time",
          "mean_score_time",
          "std_score_time",
          "split0_test_MAE",
          "split1_test_MAE",
          "split2_test_MAE",
          "std_test_MAE",
          "split0_train_MAE",
          "split1_train_MAE",
          "split2_train_MAE",
          "std_train_MAE",
          "split0_test_MSE",
          "split1_test_MSE",
          "split2_test_MSE",
          "std_test_MSE",
          "split0_train_MSE",
          "split1_train_MSE",
          "split2_train_MSE",
          "std_train_MSE",
          "split0_test_MedAPE",
          "split1_test_MedAPE",
          "split2_test_MedAPE",
          "std_test_MedAPE",
          "split0_train_MedAPE",
          "split1_train_MedAPE",
          "split2_train_MedAPE",
          "std_train_MedAPE",
          "split0_test_MAPE",
          "split1_test_MAPE",
          "split2_test_MAPE",
          "std_test_MAPE",
          "split0_train_MAPE",
          "split1_train_MAPE",
          "split2_train_MAPE",
          "std_train_MAPE",
      ] == list(cv_result.columns)
  
      # `combine_splits=False`
      cv_result = summarize_grid_search_results(
          grid_search=grid_search,
          only_changing_params=True,
          combine_splits=False,
          score_func=metric.name,
          score_func_greater_is_better=metric.get_metric_greater_is_better(),
          cv_report_metrics=CV_REPORT_METRICS_ALL,
      )
      assert cv_result.shape == (
          4,
          52,
      )  # no train/test split summary for 4 metrics
      assert "split_test_MedAPE" not in cv_result.columns
  
      # cv_report_metrics=list, different column_order
      cv_result = summarize_grid_search_results(
          grid_search=grid_search,
          only_changing_params=True,
          combine_splits=False,
          score_func=metric.name,
          score_func_greater_is_better=metric.get_metric_greater_is_better(),
          cv_report_metrics=[
              EvaluationMetricEnum.MeanSquaredError.name
          ],
          column_order=["mean", "time", ".*"],
      )
      assert cv_result.shape == (
          4,
          30,
      )  # only two metrics in the summary
      assert [
          "mean_fit_time",
          "mean_score_time",
          "mean_test_MSE",
          "mean_train_MSE",
          "mean_test_MAPE",
          "mean_train_MAPE",
          "std_fit_time",
          "std_score_time",
          "param_estimator__strategy",
          "param_estimator__quantile",
          "param_estimator__constant",
          "params",
          "split0_test_MSE",
          "split1_test_MSE",
          "split2_test_MSE",
          "std_test_MSE",
          "rank_test_MSE",
          "split0_train_MSE",
          "split1_train_MSE",
          "split2_train_MSE",
          "std_train_MSE",
          "split0_test_MAPE",
          "split1_test_MAPE",
          "split2_test_MAPE",
          "std_test_MAPE",
          "rank_test_MAPE",
          "split0_train_MAPE",
          "split1_train_MAPE",
          "split2_train_MAPE",
          "std_train_MAPE",
      ] == list(cv_result.columns)
      # These metrics are computed but not requested in summary
      assert "rank_test_MedAPE" not in cv_result.columns
      assert "mean_test_MAE" not in cv_result.columns
  
      # cv_report_metrics=None, different column order
      cv_result = summarize_grid_search_results(
          grid_search=grid_search,
          only_changing_params=True,
          combine_splits=False,
          score_func=metric.name,
          score_func_greater_is_better=metric.get_metric_greater_is_better(),
          cv_report_metrics=None,
          column_order=["split", "rank", "mean", "params"],
      )
      assert cv_result.shape == (
          4,
          12,
      )  # only one metric in the summary
      assert [
          "split0_test_MAPE",
          "split1_test_MAPE",
          "split2_test_MAPE",
          "split0_train_MAPE",
          "split1_train_MAPE",
          "split2_train_MAPE",
          "rank_test_MAPE",
          "mean_fit_time",
          "mean_score_time",
          "mean_test_MAPE",
          "mean_train_MAPE",
          "params",
      ] == list(cv_result.columns)
      assert "rank_test_MSE" not in cv_result.columns
  
      # Tests FRACTION_OUTSIDE_TOLERANCE `score_func`
      grid_search = pipeline_results["2"].grid_search
      cv_result = summarize_grid_search_results(
          grid_search=grid_search,
          only_changing_params=True,
          score_func=FRACTION_OUTSIDE_TOLERANCE,
          score_func_greater_is_better=False,
      )
      assert cv_result.shape == (4, 242)
      # The proper scores are extracted
      short_name = FRACTION_OUTSIDE_TOLERANCE_NAME
      expected = grid_search.cv_results_[f"mean_test_{short_name}"]
      assert_equal(
          np.array(cv_result[f"mean_test_{short_name}"]), expected
      )
      # Rank direction is correct
      assert (
          cv_result[f"rank_test_{short_name}"].idxmin()
          == cv_result[f"mean_test_{short_name}"].idxmin()
      )
      assert all(cv_result[f"mean_test_{short_name}"] > 0)
  
      # Tests callable `score_func`, greater_is_better=True, split scores
      grid_search = pipeline_results["3"].grid_search
      cv_max_splits = 2
      cv_result = summarize_grid_search_results(
          grid_search=grid_search,
          only_changing_params=True,
          score_func=mean_absolute_error,
          score_func_greater_is_better=True,
      )
      assert cv_result.shape == (4, 20)
      # the proper scores are extracted
      short_name = CUSTOM_SCORE_FUNC_NAME
      expected = grid_search.cv_results_[f"mean_test_{short_name}"]
      assert_equal(
          np.array(cv_result[f"mean_test_{short_name}"]), expected
      )
      # Rank direction is correct
      assert (
          cv_result[f"rank_test_{short_name}"].idxmin()
          == cv_result[f"mean_test_{short_name}"].idxmax()
      )  # NB: max
      assert all(cv_result[f"mean_test_{short_name}"] > 0)
      assert (
          len(cv_result["params"][0]) == 2
      )  # two params have multiple options in the grid
      assert (
          len(cv_result[f"split_test_{short_name}"][0]) == cv_max_splits
      )
      # no rounding is applied
      assert cv_result[f"mean_test_{short_name}"][1] == pytest.approx(
          2.430402, rel=1e-5
      )
      assert cv_result[f"mean_train_{short_name}"][1] == pytest.approx(
          1.839883, rel=1e-5
      )
      assert cv_result[f"std_test_{short_name}"][1] == pytest.approx(
          0.16548, rel=1e-5
      )
      assert cv_result[f"split_test_{short_name}"][1][
          0
      ] == pytest.approx(2.26492, rel=1e-5)
      assert cv_result[f"split_train_{short_name}"][1][
          0
      ] == pytest.approx(1.84082, rel=1e-5)
      expected = grid_search.cv_results_
      for k, v in cv_result.items():
          if k in expected and k not in (
              "params",
              f"rank_test_{short_name}",
          ):
              assert_equal(pd.Series(expected[k], name=k), v)
  
      # decimals=2, and only_changing_params=False
      cv_result = summarize_grid_search_results(
          grid_search=grid_search,
          only_changing_params=False,
          decimals=2,
          score_func=mean_absolute_error,
          score_func_greater_is_better=False,
      )
      assert cv_result.shape == (4, 20)
      # only_changing_params=False, so all params in hyperparameter_grid are included
      assert len(cv_result["params"][0]) == 4
      # rounding is applied
      assert cv_result[f"mean_test_{short_name}"][1] == 2.43
      assert cv_result[f"mean_train_{short_name}"][1] == 1.84
      assert cv_result[f"std_test_{short_name}"][1] == 0.17
      assert cv_result[f"split_test_{short_name}"][1][0] == 2.26
      assert cv_result[f"split_train_{short_name}"][1][0] == 1.84
  
imports: import warnings
  import numpy
  import pandas
  import pytest
  from sklearn.metrics import mean_absolute_error
  from sklearn.pipeline import Pipeline
  from greykite.common.constants import FRACTION_OUTSIDE_TOLERANCE
  from greykite.common.evaluation import EvaluationMetricEnum
  from greykite.common.python_utils import assert_equal
  from greykite.common.testing_utils import generate_df_for_tests
  from greykite.framework.constants import CUSTOM_SCORE_FUNC_NAME
  from greykite.framework.constants import CV_REPORT_METRICS_ALL
  from greykite.framework.constants import FRACTION_OUTSIDE_TOLERANCE_NAME
  from greykite.framework.pipeline.pipeline import forecast_pipeline
  from greykite.framework.utils.result_summary import get_ranks_and_splits
  from greykite.framework.utils.result_summary import summarize_grid_search_results
  from greykite.sklearn.estimator.null_model import DummyEstimator
  from greykite.sklearn.estimator.silverkite_estimator import SilverkiteEstimator
label_desc: Use image node_id 2 for calling a global function with example usage: test_summarize_grid_search_results(pipeline_results) without return types