code: def split_train_dev(all_data, num_dev, outfile):
      """Group all paths listed in `datalist` according to their name prefix,
      and split all groups into train and dev subsets.
  
      Each subset has distinct groups.
  
      This is designed for splitting same-size groups into train and dev subsets.
      That is, all groups must have exactly the same number of paths.
  
      Args:
          all_data (Dict[group_name: List[str]]): all paths grouped by their category
          num_dev (int or Fraction): number/percentage of the samples for the dev set
          outfile (str): template path to the ourput file
      """  # noqa: H405
  
      # all groups must have the same number of paths
      group_id0 = next(iter(all_data.keys()))
      group_length = len(all_data[group_id0])
      for k, v in all_data.items():
          assert len(v) == group_length, (k, len(v), group_length)
      total_num = group_length * len(all_data)
  
      # determine number of groups for dev subset
      if isinstance(num_dev, int):
          assert num_dev % group_length == 0, (num_dev, group_length)
          num_dev_groups = num_dev // group_length
      elif isinstance(num_dev, Fraction):
          num_dev_groups = num_dev * total_num / group_length
          if num_dev_groups.denominator == 1:
              num_dev_groups = num_dev_groups.numerator
          else:
              num_dev_groups = round(num_dev_groups)
              print(
                  "Warning: num_dev_groups is rounded to the nearest integer "
                  f"{num_dev_groups}."
              )
      else:
          raise TypeError("Unsupported data type: %s" % type(num_dev))
  
      groups = list(all_data.keys())
      random.shuffle(groups)
      dev_groups = groups[:num_dev_groups]
      train_groups = groups[num_dev_groups:]
  
      outdir = Path(outfile).expanduser().resolve().parent
      outdir.mkdir(parents=True, exist_ok=True)
      assert "{}" in outfile, outfile
      with Path(outfile.format("dev")).open("w") as out:
          for room in dev_groups:
              for wav in all_data[room]:
                  out.write(wav)
      with Path(outfile.format("train")).open("w") as out:
          for room in train_groups:
              for wav in all_data[room]:
                  out.write(wav)
  
file_path: espnet/egs2/aishell4/enh1/local/split_train_dev.py
imports: import math
  import random
  from collections import Counter, defaultdict
  from fractions import Fraction
  from pathlib import Path
  from typing import List, Tuple
label_desc: Use image node_id 2 for calling a global function with example usage: split_train_dev(all_data, num_dev, outfile) without return types