code: def _score_decorator(perfect_score, zero_score):
      """
      Decorate metric with evaluation results for perfect and zero score.
  
      Parameters
      ----------
      perfect_score : float or tuple
      zero_score : float or tuple
  
      Returns
      -------
      metric
          Decorated metric.
  
      """
  
      def wrap(metric):
          """Metric to decorate"""
  
          @wraps(metric)
          def score(detections, annotations, *args, **kwargs):
              """
              Return perfect/zero score if neither/either detections and
              annotations are given, respectively.
  
              """
              # neither detections nor annotations are given, perfect score
              if len(detections) == 0 and len(annotations) == 0:
                  return perfect_score
              # either beat detections or annotations are empty, score 0
              elif (len(detections) == 0) != (len(annotations) == 0):
                  return zero_score
              # normal scoring
              return metric(detections, annotations, *args, **kwargs)
  
          return score
  
      return wrap
  
imports: from __future__ import absolute_import, division, print_function
  import warnings
  from functools import wraps
  import numpy
  from .None import MeanEvaluation, calc_absolute_errors, calc_errors, evaluation_io, find_closest_matches
  from .onsets import OnsetEvaluation
label_desc: Use image node_id 2 for calling a global function with example usage: _score_decorator(perfect_score, zero_score) and returns: wrap, score, metric, perfect_score, zero_score