code: def test_get_feature_sets_terms():
      """Tests get_feature_sets_terms"""
      silverkite = SimpleSilverkiteForecast()
      daily_seas_interaction_order = 4
      weekly_seas_interaction_order = 3
      growth_term = "ct2"
      changepoint_cols = [
          f"{CHANGEPOINT_COL_PREFIX}0",
          f"{CHANGEPOINT_COL_PREFIX}1",
      ]
      num_trend_terms = 1 + len(
          changepoint_cols
      )  # growth plus changepoints
      holidays = (
          silverkite._SimpleSilverkiteForecast__get_silverkite_holidays(
              holiday_lookup_countries="auto",
              holidays_to_model_separately="auto",
              start_year=2017,
              end_year=2025,
              pre_num=2,
              post_num=2,
          )
      )
      feature_sets_terms = silverkite._SimpleSilverkiteForecast__get_feature_sets_terms(
          daily_event_df_dict=holidays,
          daily_seas_interaction_order=daily_seas_interaction_order,
          weekly_seas_interaction_order=weekly_seas_interaction_order,
          growth_term=growth_term,
          changepoint_cols=changepoint_cols,
      )
      num_interaction_holidays = len(
          [
              k
              for k in holidays.keys()
              if k in SilverkiteHoliday.HOLIDAYS_TO_INTERACT
          ]
      )
  
      expected = {
          # number of terms, substring of first term
          SilverkiteColumn.COLS_HOUR_OF_WEEK: (
              1,
              "C(Q('dow_hr'), levels=['1_00',",
          ),
          SilverkiteColumn.COLS_WEEKEND_SEAS: (
              2 * daily_seas_interaction_order,
              "is_weekend:sin1_tod_daily",
          ),
          SilverkiteColumn.COLS_DAY_OF_WEEK_SEAS: (
              2 * daily_seas_interaction_order,
              "C(Q('str_dow'), levels=['1-Mon",
          ),
          SilverkiteColumn.COLS_TREND_DAILY_SEAS: (
              2 * daily_seas_interaction_order * num_trend_terms,
              f"is_weekend:{growth_term}:sin1_tod_daily",
          ),
          SilverkiteColumn.COLS_EVENT_SEAS: (
              2
              * daily_seas_interaction_order
              * num_interaction_holidays,
              "C(Q('events_Christmas Day'), l",
          ),
          SilverkiteColumn.COLS_EVENT_WEEKEND_SEAS: (
              2
              * daily_seas_interaction_order
              * num_interaction_holidays,
              "is_weekend:C(Q('events_Christm",
          ),
          SilverkiteColumn.COLS_DAY_OF_WEEK: (
              1,
              "C(Q('str_dow'), levels=['1-Mon",
          ),
          SilverkiteColumn.COLS_TREND_WEEKEND: (
              num_trend_terms,
              f"is_weekend:{growth_term}",
          ),
          SilverkiteColumn.COLS_TREND_DAY_OF_WEEK: (
              num_trend_terms,
              "C(Q('str_dow'), levels=['1-Mon",
          ),
          SilverkiteColumn.COLS_TREND_WEEKLY_SEAS: (
              2 * weekly_seas_interaction_order * num_trend_terms,
              "ct2:sin1_tow_weekly",
          ),
      }
      assert sorted(list(feature_sets_terms.keys())) == sorted(
          list(expected.keys())
      )
      for feature_set, (
          expected_len,
          expected_term,
      ) in expected.items():
          assert len(feature_sets_terms[feature_set]) == expected_len
          if expected_len > 0:
              assert (
                  feature_sets_terms[feature_set][0][:30]
                  == expected_term
              )
  
      # if there are events and seasonality but no growth
      feature_sets_terms = silverkite._SimpleSilverkiteForecast__get_feature_sets_terms(
          daily_event_df_dict=holidays,
          daily_seas_interaction_order=daily_seas_interaction_order,
          weekly_seas_interaction_order=weekly_seas_interaction_order,
          growth_term=None,
          changepoint_cols=None,
      )
      expected = {
          # number of terms, substring of first term
          SilverkiteColumn.COLS_HOUR_OF_WEEK: (
              1,
              "C(Q('dow_hr'), levels=['1_00',",
          ),
          SilverkiteColumn.COLS_WEEKEND_SEAS: (
              2 * daily_seas_interaction_order,
              "is_weekend:sin1_tod_daily",
          ),
          SilverkiteColumn.COLS_DAY_OF_WEEK_SEAS: (
              2 * daily_seas_interaction_order,
              "C(Q('str_dow'), levels=['1-Mon",
          ),
          SilverkiteColumn.COLS_TREND_DAILY_SEAS: (0, None),
          SilverkiteColumn.COLS_EVENT_SEAS: (
              2
              * daily_seas_interaction_order
              * num_interaction_holidays,
              "C(Q('events_Christmas Day'), l",
          ),
          SilverkiteColumn.COLS_EVENT_WEEKEND_SEAS: (
              2
              * daily_seas_interaction_order
              * num_interaction_holidays,
              "is_weekend:C(Q('events_Christm",
          ),
          SilverkiteColumn.COLS_DAY_OF_WEEK: (
              1,
              "C(Q('str_dow'), levels=['1-Mon",
          ),
          SilverkiteColumn.COLS_TREND_WEEKEND: (0, None),
          SilverkiteColumn.COLS_TREND_DAY_OF_WEEK: (0, None),
          SilverkiteColumn.COLS_TREND_WEEKLY_SEAS: (0, None),
      }
      assert sorted(list(feature_sets_terms.keys())) == sorted(
          list(expected.keys())
      )
      for feature_set, (
          expected_len,
          expected_term,
      ) in expected.items():
          assert len(feature_sets_terms[feature_set]) == expected_len
          if expected_len > 0:
              assert (
                  feature_sets_terms[feature_set][0][:30]
                  == expected_term
              )
  
      # if there are no events, seasonality, or growth
      feature_sets_terms = (
          silverkite._SimpleSilverkiteForecast__get_feature_sets_terms(
              daily_event_df_dict=None,
              daily_seas_interaction_order=0,
              weekly_seas_interaction_order=0,
              growth_term=None,
              changepoint_cols=None,
          )
      )
      expected = {
          # number of terms, substring of first term
          SilverkiteColumn.COLS_HOUR_OF_WEEK: (
              1,
              "C(Q('dow_hr'), levels=['1_00',",
          ),
          SilverkiteColumn.COLS_WEEKEND_SEAS: (0, None),
          SilverkiteColumn.COLS_DAY_OF_WEEK_SEAS: (0, None),
          SilverkiteColumn.COLS_TREND_DAILY_SEAS: (0, None),
          SilverkiteColumn.COLS_EVENT_SEAS: (0, None),
          SilverkiteColumn.COLS_EVENT_WEEKEND_SEAS: (0, None),
          SilverkiteColumn.COLS_DAY_OF_WEEK: (
              1,
              "C(Q('str_dow'), levels=['1-Mon",
          ),
          SilverkiteColumn.COLS_TREND_WEEKEND: (0, None),
          SilverkiteColumn.COLS_TREND_DAY_OF_WEEK: (0, None),
          SilverkiteColumn.COLS_TREND_WEEKLY_SEAS: (0, None),
      }
      assert sorted(list(feature_sets_terms.keys())) == sorted(
          list(expected.keys())
      )
      for feature_set, (
          expected_len,
          expected_term,
      ) in expected.items():
          assert len(feature_sets_terms[feature_set]) == expected_len
          if expected_len > 0:
              assert (
                  feature_sets_terms[feature_set][0][:30]
                  == expected_term
              )
  
imports: import datetime
  import math
  import sys
  import warnings
  from datetime import timedelta
  import pandas
  import pytest
  from testfixtures import LogCapture
  import greykite.common.constants
  from greykite.algo.changepoint.adalasso.changepoint_detector import ChangepointDetector
  from greykite.algo.forecast.silverkite.constants.silverkite_column import SilverkiteColumn
  from greykite.algo.forecast.silverkite.constants.silverkite_holiday import SilverkiteHoliday
  from greykite.algo.forecast.silverkite.constants.silverkite_seasonality import SilverkiteSeasonality
  from greykite.algo.forecast.silverkite.constants.silverkite_seasonality import SilverkiteSeasonalityEnum
  from greykite.algo.forecast.silverkite.forecast_simple_silverkite import SimpleSilverkiteForecast
  from greykite.algo.forecast.silverkite.forecast_simple_silverkite_helper import generate_holiday_events
  from greykite.common.constants import CHANGEPOINT_COL_PREFIX
  from greykite.common.constants import EVENT_DF_DATE_COL
  from greykite.common.constants import EVENT_DF_LABEL_COL
  from greykite.common.constants import LOGGER_NAME
  from greykite.common.constants import TIME_COL
  from greykite.common.constants import VALUE_COL
  from greykite.common.data_loader import DataLoader
  from greykite.common.enums import SimpleTimeFrequencyEnum
  from greykite.common.enums import TimeEnum
  from greykite.common.features.timeseries_features import get_available_holidays_across_countries
  from greykite.common.features.timeseries_features import get_holidays
  from greykite.common.python_utils import assert_equal
  from greykite.common.python_utils import update_dictionary
  from greykite.common.testing_utils import generate_df_for_tests
  from greykite.common.testing_utils import generate_df_with_reg_for_tests
label_desc: Use image node_id 17 for calling a global function with example usage: test_get_feature_sets_terms() without return types