code: def _ndcg(
      gain_key: str,
      top_k_list: Optional[List[int]] = None,
      name: str = NDCG_NAME,
      eval_config: Optional[config_pb2.EvalConfig] = None,
      model_names: Optional[List[str]] = None,
      output_names: Optional[List[str]] = None,
      sub_keys: Optional[List[metric_types.SubKey]] = None,
      example_weighted: bool = False,
      query_key: str = "",
  ) -> metric_types.MetricComputations:
      """Returns metric computations for NDCG."""
      if not query_key:
          raise ValueError("a query_key is required to use NDCG metric")
      sub_keys = [k for k in sub_keys if k is not None]
      if top_k_list:
          if sub_keys is None:
              sub_keys = []
          for k in top_k_list:
              if not any([sub_key.top_k == k for sub_key in sub_keys]):
                  sub_keys.append(metric_types.SubKey(top_k=k))
      if not sub_keys or any(
          [sub_key.top_k is None for sub_key in sub_keys]
      ):
          raise ValueError(
              "top_k values are required to use NDCG metric: {}".format(
                  sub_keys
              )
          )
      computations = []
      for model_name in model_names if model_names else [""]:
          for output_name in output_names if output_names else [""]:
              keys = []
              for sub_key in sub_keys:
                  keys.append(
                      metric_types.MetricKey(
                          name,
                          model_name=model_name,
                          output_name=output_name,
                          sub_key=sub_key,
                          example_weighted=example_weighted,
                      )
                  )
              computations.append(
                  metric_types.MetricComputation(
                      keys=keys,
                      preprocessors=[
                          metric_types.CombinedFeaturePreprocessor(
                              feature_keys=[query_key, gain_key]
                          )
                      ],
                      combiner=_NDCGCombiner(
                          metric_keys=keys,
                          eval_config=eval_config,
                          model_name=model_name,
                          output_name=output_name,
                          example_weighted=example_weighted,
                          query_key=query_key,
                          gain_key=gain_key,
                      ),
                  )
              )
      return computations
  
imports: from typing import Dict, Iterable, List, Optional, Tuple, Union
  import apache_beam
  import numpy
  from tensorflow_model_analysis.metrics import metric_types
  from tensorflow_model_analysis.metrics import metric_util
  from tensorflow_model_analysis.proto import config_pb2
  from tensorflow_model_analysis.utils import util
label_desc: Use image node_id 1 for calling a global function with example usage: _ndcg(gain_key, top_k_list, name, eval_config, model_names, output_names, sub_keys, example_weighted, query_key) and returns: computations