code: def assert_categorical_single_grouper(
      education_df,
      as_index,
      observed,
      expected_index,
      normalize,
      name,
      expected_data,
  ):
      # Test single categorical grouper when non-groupers are also categorical
      education_df = education_df.copy().astype("category")
  
      # Add non-observed grouping categories
      education_df["country"] = education_df[
          "country"
      ].cat.add_categories(["ASIA"])
  
      gp = education_df.groupby(
          "country", as_index=as_index, observed=observed
      )
      result = gp.value_counts(normalize=normalize)
  
      expected_series = Series(
          data=expected_data,
          index=MultiIndex.from_tuples(
              expected_index,
              names=["country", "gender", "education"],
          ),
          name=name,
      )
      for i in range(3):
          index_level = CategoricalIndex(
              expected_series.index.levels[i]
          )
          if i == 0:
              index_level = index_level.set_categories(
                  education_df["country"].cat.categories
              )
          expected_series.index = expected_series.index.set_levels(
              index_level, level=i
          )
  
      if as_index:
          tm.assert_series_equal(result, expected_series)
      else:
          expected = expected_series.reset_index(name=name)
          tm.assert_frame_equal(result, expected)
  
imports: import numpy
  import pytest
  import pandas.util._test_decorators
  from pandas import Categorical, CategoricalIndex, DataFrame, Grouper, Index, MultiIndex, Series, date_range, to_datetime
  import pandas._testing
  from pandas.util.version import Version
label_desc: Use image node_id 20 for calling a global function with example usage: assert_categorical_single_grouper(education_df, as_index, observed, expected_index, normalize, name, expected_data) without return types