def METHOD_NAME(
        df, train_split_ratio=0.99, speaker_in_all_splits=False, rand_seed=0
) -> Tuple[Dict[str, str], List[str]]:
    np.random.seed(rand_seed)
    dev_split_ratio = (1. - train_split_ratio) / 3
    grouped = list(df.groupby("client_id"))
    id_to_split = {}
    for _, cur_df in tqdm(grouped):
        cur_n_examples = len(cur_df)
        if speaker_in_all_splits and cur_n_examples < 3:
            continue
        cur_n_train = int(cur_n_examples * train_split_ratio)
        cur_n_dev = int(cur_n_examples * dev_split_ratio)
        cur_n_test = cur_n_examples - cur_n_dev - cur_n_train
        if speaker_in_all_splits and cur_n_dev * cur_n_test == 0:
            cur_n_dev, cur_n_test = 1, 1
            cur_n_train = cur_n_examples - cur_n_dev - cur_n_test
        cur_indices = cur_df.index.tolist()
        cur_shuffled_indices = np.random.permutation(cur_n_examples)
        cur_shuffled_indices = [cur_indices[i] for i in cur_shuffled_indices]
        cur_indices_by_split = {
            "train": cur_shuffled_indices[:cur_n_train],
            "dev": cur_shuffled_indices[cur_n_train: cur_n_train + cur_n_dev],
            "test": cur_shuffled_indices[cur_n_train + cur_n_dev:]
        }
        for split in SPLITS:
            for i in cur_indices_by_split[split]:
                id_ = df["id"].loc[i]
                id_to_split[id_] = split
    return id_to_split, sorted(df["client_id"].unique())