"""Deterministic seeding. WHY: "Seed everything" is a stated engineering convention, and it is not cosmetic here. With n ~ 124-169 cells, the difference between two models is often smaller than the difference between two random 5-fold partitions of the same data. Unless the partitions are reproducible, a benchmark table cannot be regenerated and a reported improvement cannot be distinguished from a lucky split. """ from __future__ import annotations import os import random DEFAULT_SEED = 42 def set_global_seed(seed: int = DEFAULT_SEED) -> int: """Seed Python's ``random``, NumPy, and hash randomisation. ``PYTHONHASHSEED`` is set for completeness but only affects interpreters started afterwards; it is recorded so that the provenance stamp is honest about what was and was not controlled. Args: seed: The seed to apply. Returns: The seed applied, for convenient logging. """ os.environ["PYTHONHASHSEED"] = str(seed) random.seed(seed) try: import numpy as np np.random.seed(seed) except ImportError: # NumPy is a hard dependency in practice; tolerated here pass # so the scaffold validates before deps are installed. return seed def seed_for_repeat(base_seeds: list[int], repeat_index: int) -> int: """Return the fixed seed for a given outer-CV repeat. WHY explicit per-repeat seeds rather than ``base + i``: the seeds are recorded in ``configs/models.yaml``, so a re-run reproduces the same ten partitions even if the number of repeats is later changed. """ if not 0 <= repeat_index < len(base_seeds): raise IndexError( f"Repeat index {repeat_index} is outside the {len(base_seeds)} configured repeat seeds." ) return base_seeds[repeat_index] if __name__ == "__main__": print(f"Global seed set to {set_global_seed()}")