code: def universal_fairness_check(
      self,
      epsilon,
      verbose,
      num_for_not_fair,
      num_for_no_decision,
      metrics,
  ):
      if epsilon is None:
          epsilon = self.epsilon
      else:
          epsilon = checks.check_epsilon(epsilon)
  
      metric_ratios = self.result
  
      subgroups = np.unique(self.protected)
      subgroups_without_privileged = subgroups[
          subgroups != self.privileged
      ]
      metric_ratios = metric_ratios.loc[
          subgroups_without_privileged, metrics
      ]
  
      metrics_exceeded = (
          (metric_ratios > 1 / epsilon) | (epsilon > metric_ratios)
      ).apply(sum, 0)
  
      names_of_exceeded_metrics = list(
          metrics_exceeded.index[metrics_exceeded != 0]
      )
      if len(names_of_exceeded_metrics) >= num_for_not_fair:
          print(
              f'Bias detected in {len(names_of_exceeded_metrics)} metrics: {", ".join(names_of_exceeded_metrics)}'
          )
      elif len(names_of_exceeded_metrics) == num_for_no_decision:
          print(
              f"Bias detected in {len(names_of_exceeded_metrics)} metric: {names_of_exceeded_metrics[0]}"
          )
      else:
          print("No bias was detected!")
  
      # arbitrary decision
      if len(names_of_exceeded_metrics) >= num_for_not_fair:
          conclusion = "is not fair because 2 or more criteria exceeded acceptable limits set by epsilon"
      elif len(names_of_exceeded_metrics) == num_for_no_decision:
          conclusion = (
              "cannot be called fair because 1 criterion exceeded acceptable limits set by epsilon.\n"
              "It does not mean that your model is unfair "
              "but it cannot be automatically approved based on these metrics"
          )
      else:
          conclusion = "is fair in terms of checked fairness criteria"
  
      print(f"\nConclusion: your model {conclusion}.")
  
      print(
          f"\nRatios of metrics, based on '{self.privileged}'. Parameter 'epsilon' was set to {epsilon}"
          f" and therefore metrics should be within ({epsilon}, {round(1 / epsilon, 3)})"
      )
      print(metric_ratios.to_string())
      if pd.isna(metric_ratios).sum().sum() > 0:
          helper.verbose_cat(
              "\nWarning!\nTake into consideration that NaN's are present, consider checking 'metric_scores' "
              "plot to see the difference",
              verbose=verbose,
          )
  
imports: from copy import deepcopy
  import numpy
  import pandas
  from .None import checks
  from ...None import _global_checks
  from ..._explainer import helper
  from ...model_explanations._model_performance import utils
label_desc: Use image node_id 9 for calling a global function with example usage: universal_fairness_check(epsilon, verbose, num_for_not_fair, num_for_no_decision, metrics) without return types