Coverage for src/arcade_collection/input/group_template_conditions.py: 100%
50 statements
« prev ^ index » next coverage.py v7.1.0, created at 2024-12-09 19:07 +0000
« prev ^ index » next coverage.py v7.1.0, created at 2024-12-09 19:07 +0000
1from itertools import groupby
4def group_template_conditions(conditions: list[dict], max_seeds: int) -> list[dict]:
5 """
6 Create conditions groups obeying specified max seeds for each group.
8 Parameters
9 ----------
10 conditions
11 List of conditions, containing a unique "key" and "seed".
12 max_seeds
13 Maximum number of total seeds in each group.
15 Returns
16 -------
17 :
18 List of condition groups.
19 """
21 grouped_conditions = group_seed_ranges(conditions, max_seeds)
22 condition_sets = group_condition_sets(grouped_conditions, max_seeds)
23 return [{"conditions": condition_set} for condition_set in condition_sets]
26def group_seed_ranges(conditions: list[dict], max_seeds: int) -> list[dict]:
27 """
28 Group conditions by continuous seed ranges.
30 Parameters
31 ----------
32 conditions
33 List of conditions, containing a unique "key" and "seed".
34 max_seeds
35 Maximum number of seeds in a single range.
37 Returns
38 -------
39 :
40 List of conditions updated with "start_seed" and "end_seed" ranges.
41 """
43 conditions.sort(key=lambda x: (x["key"], x["seed"]))
44 grouped_conditions = []
46 for _, condition_group in groupby(conditions, lambda x: x["key"]):
47 key_seeds = []
48 key_conditions = {}
50 for condition in condition_group:
51 key_seeds.append(condition["seed"])
52 key_conditions.update(condition)
54 key_conditions.pop("seed")
55 seed_ranges = find_seed_ranges(key_seeds, max_seeds)
57 for range_start, range_end in seed_ranges:
58 group_condition = key_conditions.copy()
59 group_condition["start_seed"] = range_start
60 group_condition["end_seed"] = range_end
61 grouped_conditions.append(group_condition)
63 return grouped_conditions
66def find_seed_ranges(seeds: list[int], max_seeds: int) -> list[tuple[int, int]]:
67 """
68 Find continuous seed ranges, with range no larger than specified max seeds.
70 Parameters
71 ----------
72 seeds
73 List of seeds.
74 max_seeds
75 Maximum number of seeds in a single range.
77 Returns
78 -------
79 :
80 List of seeds grouped into ranges.
81 """
83 seeds.sort()
84 ranges = []
86 for _, group in groupby(enumerate(seeds), lambda x: x[0] - x[1]):
87 group_list = list(group)
88 subset = True
89 range_start = group_list[0][1]
90 range_end = group_list[-1][1]
92 while subset:
93 ranges.append((range_start, min(range_end, range_start + max_seeds - 1)))
94 range_start = range_start + max_seeds
95 if range_start > range_end:
96 subset = False
98 return ranges
101def group_condition_sets(conditions: list[dict], max_seeds: int) -> list[list[dict]]:
102 """
103 Group conditions, with total seeds no larger than specified max seeds.
105 Parameters
106 ----------
107 conditions
108 List of conditions, containing a unique "key" with "start_seed" and
109 "end_seed" ranges.
110 max_seeds
111 Maximum number of seeds in a single group.
113 Returns
114 -------
115 :
116 List of groups of conditions.
117 """
119 seed_count = 0
120 condition_set = []
121 condition_sets = []
123 for condition in conditions:
124 num_seeds = condition["end_seed"] - condition["start_seed"] + 1
126 if seed_count + num_seeds <= max_seeds:
127 condition_set.append(condition)
128 seed_count = seed_count + num_seeds
129 else:
130 condition_sets.append(condition_set)
131 seed_count = num_seeds
132 condition_set = [condition]
134 condition_sets.append(condition_set)
136 return condition_sets