docs: def make_ttv(dataset, ttv_ratio=DEFAULT_TTV_RATIO, deterministic=False, limit_per_set=None):
      """
      Return a dict of test,train,validation sets with information regarding the split (lists of paths to data).
  
      Currently only separates by subjectID.
  
      Prioitises having a diverse set than a well fitting set. This means that the
      'knapsacking' is done by subjects with the least videos first, so that each set can have
      as many different subjects in as possible. If shuffle is set to true, the set is shuffled, which means this property does not hold
  
      returns {
          'subjects': list of subjectIDs in the set
          'number_of_files': number of files the set has
          'expected_size' : (ttv_ratio * number_of_resources) or the limit_per_set (if not None),
          'paths': list of paths to the files
      }
      """
      sizes_and_ids = [(len(dataset[key]), key) for key in dataset]
      number_of_resources = sum([x[0] for x in sizes_and_ids])
  
  
      # Get the smallest first
      sizes_and_ids.sort()
      if not deterministic:
          random.shuffle(sizes_and_ids)
  
      # normalise ttv_ratio
      ttv_ratio = [float(x) / sum(ttv_ratio) for x in ttv_ratio]
  
      data_sets = {}
  
      for key, ratio in zip(['test', 'train', 'validation'], ttv_ratio):
          expected_size = min(limit_per_set * ratio, (ratio * number_of_resources)) \
              if limit_per_set is not None else (ratio * number_of_resources)
  
          data_sets[key] = {
              'subjects': [],
              'number_of_files': 0,
              'expected_size': expected_size
          }
  
  
      set_names = list(data_sets.keys())
      i = 0
      while len(sizes_and_ids) > 0:
          if limit_per_set is not None:
              # if all the sets have more than the limit
              if all(map(lambda x: x['number_of_files'] >= x['expected_size'], data_sets.values())):
                  break
          i += 1
          s = data_sets[set_names[i % len(set_names)]]
          if s['number_of_files'] < s['expected_size']:
              size, subjectID = sizes_and_ids.pop(0)
              s['subjects'].append(subjectID)
              s['number_of_files'] += size
  
      def get_filenames(subjects):
          return sum(list(map(lambda x: dataset[x], subjects)), [])
  
      # turn subjectIDs into paths to files
      for data_set in data_sets:
          s = data_sets[data_set]
          s['paths'] = get_filenames(s['subjects'])
  
      return data_sets