code: def _compute_ylimits_for_featureset(
      df: pd.DataFrame, metrics: List[str]
  ) -> Dict[str, Tuple[float, float]]:
      """
      Compute the y-limits for learning curve score plots.
  
      Parameters
      ----------
      df : pd.DataFrame
          A data_frame with relevant metric information for
          train and test.
      metrics : List[str]
          A list of metrics for learning curve plots.
  
      Returns
      -------
      ylimits : Dict[str, Tuple[float, float]]
          A dictionary, with metric names as keys
          and a tuple of (lower_limit, upper_limit) as values.
      """
      # set the y-limits of the curves depending on what kind
      # of values the metric produces
      ylimits = {}
      for metric in metrics:
          # get the real min and max for the values that will be plotted
          df_train = df[
              (df["variable"] == "train_score_mean")
              & (df["metric"] == metric)
          ]
          df_test = df[
              (df["variable"] == "test_score_mean")
              & (df["metric"] == metric)
          ]
          train_values_lower = (
              df_train["value"].values
              - df_train["train_score_std"].values
          )
          test_values_lower = (
              df_test["value"].values - df_test["test_score_std"].values
          )
          min_score = np.min(
              np.concatenate([train_values_lower, test_values_lower])
          )
          train_values_upper = (
              df_train["value"].values
              + df_train["train_score_std"].values
          )
          test_values_upper = (
              df_test["value"].values + df_test["test_score_std"].values
          )
          max_score = np.max(
              np.concatenate([train_values_upper, test_values_upper])
          )
  
          # squeeze the limits to hide unnecessary parts of the graph
          # set the limits with a little buffer on either side but not too much
          if min_score < 0:
              lower_limit = max(
                  min_score - 0.1, math.floor(min_score) - 0.05
              )
          else:
              lower_limit = 0
  
          if max_score > 0:
              upper_limit = min(
                  max_score + 0.1, math.ceil(max_score) + 0.05
              )
          else:
              upper_limit = 0
  
          ylimits[metric] = (lower_limit, upper_limit)
  
      return ylimits
  
imports: from __future__ import annotations
  import csv
  import json
  import math
  import sys
  from collections import defaultdict
  from pathlib import Path
  from typing import IO, Any, Dict, List, Tuple
  import matplotlib
  import matplotlib.pyplot
  import numpy
  import pandas
  import seaborn
  from ruamel.yaml import YAML
  from skll.types import FoldMapping, PathOrStr
  from skll.utils.logging import get_skll_logger
label_desc: Use image node_id 1 for calling a global function with example usage: _compute_ylimits_for_featureset(df, metrics) and returns: ylimits