code: def get_condition_train_test_relative_degradation_less_than(
      threshold: float,
  ) -> t.Callable[[pd.DataFrame], ConditionResult]:
      """Add condition - test performance is not degraded by more than given percentage in train.
  
      Parameters
      ----------
      threshold : float
          maximum degradation ratio allowed (value between 0 and 1)
  
      Returns
      -------
      Callable
          the condition function
      """
  
      def _ratio_of_change_calc(score_1, score_2):
          if score_1 == 0:
              if score_2 == 0:
                  return 0
              return 1
          return (score_1 - score_2) / abs(score_1)
  
      def condition(check_result: pd.DataFrame) -> ConditionResult:
          test_scores = check_result.loc[
              check_result["Dataset"] == "Test"
          ]
          train_scores = check_result.loc[
              check_result["Dataset"] == "Train"
          ]
          max_degradation = ("", -np.inf)
          num_failures = 0
  
          def update_max_degradation(diffs, class_name):
              nonlocal max_degradation
              max_scorer, max_diff = get_dict_entry_by_value(diffs)
              if max_diff > max_degradation[1]:
                  max_degradation_details = f"Found max degradation of {format_percent(max_diff)} for metric {max_scorer}"
                  if class_name is not None:
                      max_degradation_details += (
                          f" and class {class_name}."
                      )
                  max_degradation = max_degradation_details, max_diff
  
          if (
              "Class" in check_result.columns
              and not pd.isnull(check_result["Class"]).all()
          ):
              if (
                  "Class Name" in check_result.columns
                  and not pd.isnull(check_result["Class Name"]).all()
              ):
                  class_column = "Class Name"
              else:
                  class_column = "Class"
              classes = check_result[class_column].unique()
          else:
              classes = None
  
          if classes is not None:
              for class_name in classes:
                  test_scores_class = test_scores.loc[
                      test_scores[class_column] == class_name
                  ]
                  train_scores_class = train_scores.loc[
                      train_scores[class_column] == class_name
                  ]
                  test_scores_dict = dict(
                      zip(
                          test_scores_class["Metric"],
                          test_scores_class["Value"],
                      )
                  )
                  train_scores_dict = dict(
                      zip(
                          train_scores_class["Metric"],
                          train_scores_class["Value"],
                      )
                  )
                  if (
                      len(test_scores_dict) == 0
                      or len(train_scores_dict) == 0
                  ):
                      continue
                  # Calculate percentage of change from train to test
                  diff = {
                      score_name: _ratio_of_change_calc(
                          score, test_scores_dict[score_name]
                      )
                      for score_name, score in train_scores_dict.items()
                  }
                  update_max_degradation(diff, class_name)
                  num_failures += len(
                      [v for v in diff.values() if v >= threshold]
                  )
          else:
              test_scores_dict = dict(
                  zip(test_scores["Metric"], test_scores["Value"])
              )
              train_scores_dict = dict(
                  zip(train_scores["Metric"], train_scores["Value"])
              )
              if not (
                  len(test_scores_dict) == 0
                  or len(train_scores_dict) == 0
              ):
                  # Calculate percentage of change from train to test
                  diff = {
                      score_name: _ratio_of_change_calc(
                          score, test_scores_dict[score_name]
                      )
                      for score_name, score in train_scores_dict.items()
                  }
                  update_max_degradation(diff, None)
                  num_failures += len(
                      [v for v in diff.values() if v >= threshold]
                  )
          if num_failures > 0:
              message = (
                  f"{num_failures} scores failed. " + max_degradation[0]
              )
              return ConditionResult(ConditionCategory.FAIL, message)
          else:
              message = max_degradation[0]
              return ConditionResult(ConditionCategory.PASS, message)
  
      return condition
  
file_path: deepchecks/deepchecks/core/check_utils/class_performance_utils.py
imports: import typing
  import numpy
  import pandas
  from deepchecks.core import ConditionResult
  from deepchecks.core.condition import ConditionCategory
  from deepchecks.core.errors import DeepchecksValueError
  from deepchecks.utils.dict_funcs import get_dict_entry_by_value
  from deepchecks.utils.strings import format_number, format_percent
label_desc: Use image node_id 2 for calling a global function with example usage: get_condition_train_test_relative_degradation_less_than(threshold) and returns: condition, unknown, int, ConditionResult, ConditionResult, int