frozen_pair_source_t = TypeVar('frozen_pair_source_t', bound = Enum) frozen_pair_output_t = TypeVar('frozen_pair_output_t') frozen_pair_return_t = NewType('frozen_pair_return_t', Tuple[FrozenSet[frozen_pair_source_t], Mapping[frozen_pair_source_t, frozen_pair_output_t]]) frozen_pair_key_value_t = NewType('frozen_pair_key_value_t', Tuple[frozen_pair_source_t, frozen_pair_output_t]) def gen_frozen_set_dict_pair(source_enum: Type[frozen_pair_source_t], key_value_pairs: Iterable[frozen_pair_key_value_t], converge_keys: bool, converge_values: bool, finalize_value_entry: Callable[[frozen_pair_source_t, Iterable[frozen_pair_output_t]], frozen_pair_output_t] = None, finalize_key_entry: Callable[[frozen_pair_output_t, Iterable[frozen_pair_source_t]], frozen_pair_source_t] = None) -> frozen_pair_return_t: """Generate a frozen set and a frozen dictionary based on the provided input parameters. Parameters: - source_enum (Type[frozen_pair_source_t]): The type of the source enum. This defines the valid keys for the resulting dictionary. - key_value_pairs (Iterable[frozen_pair_key_value_t]): An iterable containing key-value pairs. Each pair is a tuple containing a source enum value and an output value. - converge_keys (bool): If set to True, the function will converge the keys. This means that for each key in the source enum, the function will associate/link the key itself to its associated values in the dictionary, mapping them to it. - converge_values (bool): If set to True, the function will converge the values. This means that for each value associated with a key, the function will associate the value itself to its associated keys in the dictionary, mapping them to it. - finalize_value_entry (Callable): An optional function that finalizes the value entry. It takes a key and an iterable of its associated values and returns the finalized value for that key. - finalize_key_entry (Callable): An optional function that finalizes the key entry. It takes a value and an iterable of its associated keys and returns the finalized key for that value. Logic: 1. Convert the parts iterable into a tuple. 2. Filter out valid parts from the tuple based on the source enum. 3. Initialize a dictionary to store the relationships between keys and values. 4. Populate the dictionary based on the filtered parts. 5. If converge_keys is True, converge the keys. 6. If converge_values is True, converge the values. 7. Finalize the value entries using the provided finalize_value_entry function. 8. Finalize the key entries using the provided finalize_key_entry function. 9. Return a frozen set of keys and a frozen dictionary. Returns: - frozen_pair_return_t: A tuple containing a frozen set of keys and a frozen dictionary. Usage: ```python3 class SampleEnum(Enum): A = "A" B = "B" # Use the function frozen_set, frozen_dict = gen_frozen_set_dict_pair(SampleEnum, [("A", "X"), ("B", "Y")], True, True) ``` Suggested Use Cases: - When you need to create an immutable mapping between a set of keys and values and want the flexibility to converge keys and values. - In scenarios where you want to ensure type safety and clarity in the function's expected inputs and outputs using type annotations. - When working with data that should not be modified after its creation, ensuring data integrity. """ net_of_parts: Tuple[frozen_pair_key_value_t, ...] = tuple(x_part for x_part in key_value_pairs if isinstance(x_part, tuple) and len(x_part) == 2 and x_part[0] in source_enum) build_table: Dict[frozen_pair_source_t, Deque[frozen_pair_output_t]] = defaultdict(deque) for key, value in net_of_parts: build_table[key].append(value) set_of_a_keys: Set[frozen_pair_source_t] = set(key for key, _ in net_of_parts) set_of_b_keys: Set[frozen_pair_output_t] = set(value for _, value in net_of_parts) if converge_keys: for key in set_of_a_keys: for vx in build_table[key]: build_table[vx].append(key) if converge_values: for value in set_of_b_keys: for kx in build_table[value]: build_table[kx].append(value) if finalize_value_entry is None: for key in set_of_a_keys: value_queue = build_table[key] if len(value_queue) == 1: build_table[key] = value_queue.pop() elif len(value_queue) > 1: build_table[key] = tuple(value_queue) else: del build_table[key] else: for key in set_of_a_keys: build_table[key] = finalize_value_entry(key, iter(build_table[key])) if finalize_key_entry is None: for value in set_of_b_keys: key_queue = build_table[value] if len(key_queue) == 1: build_table[value] = key_queue.pop() elif len(key_queue) > 1: build_table[value] = tuple(key_queue) else: del build_table[value] else: for value in set_of_b_keys: build_table[value] = finalize_value_entry(value, iter(build_table[value])) return frozenset(set_of_a_keys), frozendict(build_table)