summarize_from_feedback/utils/combos.py (58 lines of code) (raw):

from typing import Callable, Dict, Optional, Sequence, Tuple, Union BindingVar = str BindingVal = object Descriptor = Union[int, str] BindingMetadata = Dict[str, Union[Descriptor, bool]] Binding = Tuple[Optional[BindingVar], Optional[BindingVal], BindingMetadata] Experiment = Tuple[Binding, ...] ExperimentGroup = Sequence[Experiment] def combos(*xs: ExperimentGroup) -> ExperimentGroup: if xs: return [x + combo for x in xs[0] for combo in combos(*xs[1:])] else: return [()] def each(*xs: ExperimentGroup) -> ExperimentGroup: return [y for x in xs for y in x] def bind( var: Optional[BindingVar], val: Optional[BindingVal], descriptor: Descriptor = "" ) -> ExperimentGroup: extra: BindingMetadata = {} if descriptor: extra["descriptor"] = descriptor return [((var, val, extra),)] def label(descriptor: Descriptor) -> ExperimentGroup: return bind(None, None, descriptor) def labels(*descriptors: Descriptor) -> ExperimentGroup: return each(*[label(d) for d in descriptors]) def options( var: BindingVar, opts_with_descs: Sequence[Tuple[BindingVal, Descriptor]] ) -> ExperimentGroup: return each(*[bind(var, val, descriptor) for val, descriptor in opts_with_descs]) def _shortstr(v: object) -> str: if isinstance(v, float): s = f"{v:.03}" if "." in s: s = s.lstrip("0").replace(".", "x") else: s = str(v) return s def options_shortdesc(var: BindingVar, desc: str, opts: Sequence[BindingVal]) -> ExperimentGroup: return each(*[bind(var, val, desc + _shortstr(val)) for val in opts]) def options_vardesc(var: BindingVar, opts: Sequence[BindingVal]) -> ExperimentGroup: return each(*[bind(var, val, var + _shortstr(val)) for val in opts]) def repeat(n: int) -> ExperimentGroup: return each(*[label(i) for i in range(n)]) # list monad bind; passes descriptors to body def foreach(inputs: ExperimentGroup, body: Callable[..., ExperimentGroup]) -> ExperimentGroup: return [ inp + y for inp in inputs for y in body(*[extra["descriptor"] for var, val, extra in inp]) ] def bind_nested( prefix: str, binds: ExperimentGroup, descriptor: Optional[Descriptor] = None ) -> ExperimentGroup: ret: ExperimentGroup = [ tuple([(var if var is None else prefix + "." + var, val, extra) for (var, val, extra) in x]) for x in binds ] if descriptor is not None: ret = combos(ret, label(descriptor)) return combos(bind(prefix, "on"), ret)