refactor(quickadapter): consolidate LabelTransformer scaler tail and direction core (#179)
* refactor(quickadapter): consolidate LabelTransformer scaler tail and direction core
Extract the shared scaler tail of `_standardize`/`_normalize` into a static
`_apply_registered_scaler(method, registry, type_names, kind, ...)` helper
(registry lookup, ValueError on unknown method, RuntimeError on unfitted
scaler, `_apply_scaler` dispatch). Method-specific preambles (`mmad`,
`sigmoid`, `none`) and the two registries stay separate.
Fold `transform`/`inverse_transform` onto a shared direction-parametrized
`_apply_columns` core; the public wrappers keep their exact signatures
(including the unused `outlier_check` and `**kwargs`).
Behavior-preserving: no registry merge, no `_fit_*` change, no `Utils`
import (avoids the import cycle); error messages built locally and kept
byte-identical. Outputs verified bit-for-bit unchanged across all
standardization x normalization x gamma combinations, 1D/2D inputs,
multi-column, and every error path.
Closes #175
* refactor(quickadapter): tidy LabelTransformer scaler-family descriptor and naming
Address review nits on the #175 consolidation, behavior-preserving:
- Bundle the co-varying `(registry, type_names, kind)` triple into a frozen
`_ScalerFamily` descriptor with two per-family class constants
(`_STANDARDIZATION_FAMILY`, `_NORMALIZATION_FAMILY`); `_apply_registered_scaler`
now takes one `family` argument instead of three. The two registries stay
separate. Matches the file's dataclass idiom (`_ColumnState`).
- Type the error noun as `Literal["standardization", "normalization"]` instead
of `str`, consistent with the module's enum typing.
- Rename orchestrator `_apply_columns` to `_transform_columns` to pair with
`_transform_column` and reserve the `_apply_*` prefix for the static kernels.
Error strings kept byte-identical; outputs verified bit-for-bit unchanged
(container SHA-256 across all standardization x normalization x gamma combos,
1D/2D, multi-column, and every error path). No `_fit_*` change, no `Utils`
import, no instance/state field renames.
* refactor(quickadapter): harden _ScalerFamily immutability and hashing
Re-review follow-up on the #175 consolidation, behavior-preserving:
- Set `_ScalerFamily` to `eq=False` so the frozen dataclass no longer
synthesizes a `__hash__` over its mutable `registry` mapping (which would
raise `TypeError` on hash despite advertising hashability); identity
semantics are correct for the two class-level singletons.
- Type `registry` as `Mapping[str, str]` to signal read-only intent.
- Mark `_STANDARDIZATION_SCALERS`/`_NORMALIZATION_SCALERS` as `Final`, matching
the `Final` family constants that wrap them.
The two registries stay separate; no `_fit_*` change, no `Utils` import, no
instance/state field renames. Outputs verified bit-for-bit identical to the
pre-refactor baseline (container SHA-256, full method x gamma x shape x
error-path matrix).
Document why the frozen `_ScalerFamily` descriptor sets `eq=False`: the
default `eq=True` would synthesize a `__hash__` over the fields and raise
`TypeError` on the unhashable `registry` mapping. Comment only; no behavior
change (outputs verified bit-for-bit identical to the pre-refactor baseline).
The previous comment implied the synthesized __hash__ itself raises; in fact
eq=True synthesizes a __hash__ that raises TypeError only when called (the
``registry`` mapping is unhashable). Reword to state this precisely and that
eq=False keeps identity hashing. Comment only; no behavior change (outputs
verified bit-for-bit identical to the pre-refactor baseline).
* docs(quickadapter): trim _ScalerFamily eq=False comment to the invariant
The prior comment described a __hash__ TypeError that never occurs: no _ScalerFamily instance is ever hashed (only constructed as two constants and passed by value). Reduce it to the actual invariant behind eq=False (registry is an unhashable Mapping).