code: def test_ndcg_bulk_match(demo_recs, drop_rating):
      "bulk and normal match"
      train, test, recs = demo_recs
      if drop_rating:
          test = test[["user", "item"]]
  
      rla = RecListAnalysis()
      rla.add_metric(ndcg)
      rla.add_metric(ndcg, name="ndcg_k", k=5)
      rla.add_metric(dcg)
      # metric without the bulk capabilities
      rla.add_metric(lambda *a: ndcg(*a), name="ind_ndcg")
      rla.add_metric(
          lambda *a, **k: ndcg(*a, **k), name="ind_ndcg_k", k=5
      )
      res = rla.compute(recs, test)
  
      res["ind_ideal"] = res["dcg"] / res["ind_ndcg"]
      print(res)
  
      assert res.ndcg.values == approx(res.ind_ndcg.values)
  
imports: import numpy
  import pandas
  from pytest import approx, mark
  from lenskit.metrics.topn import _dcg, dcg, ndcg, _bulk_ndcg
  from lenskit.topn import RecListAnalysis
  from lenskit.util.test import demo_recs
label_desc: Use image node_id 19 for calling a global function with example usage: test_ndcg_bulk_match(demo_recs, drop_rating) without return types