Coverage for little_loops / stats.py: 0%
13 statements
« prev ^ index » next coverage.py v7.12.0, created at 2026-06-26 17:38 -0500
« prev ^ index » next coverage.py v7.12.0, created at 2026-06-26 17:38 -0500
1"""Statistical utilities for loop evaluation reporting.
3Provides Wilson 95% binomial confidence intervals for honest uncertainty
4reporting at small sample sizes where naive ±√(p(1-p)/n) estimates are
5unreliable near 0 or 1.
6"""
8from __future__ import annotations
10import math
13def wilson_ci(k: int, n: int, z: float = 1.96) -> tuple[float, float]:
14 """Compute Wilson binomial confidence interval.
16 Formula: (p + z²/2n ± z√(p(1-p)/n + z²/4n²)) / (1 + z²/n)
18 Args:
19 k: Number of successes (0 <= k <= n).
20 n: Total trials (n > 0).
21 z: Z-score for confidence level (default 1.96 for 95% CI).
23 Returns:
24 (lower, upper) bounds as floats clamped to [0, 1].
26 Raises:
27 ValueError: If n <= 0, k < 0, or k > n.
28 """
29 if n <= 0:
30 raise ValueError(f"n must be positive, got {n}")
31 if k < 0 or k > n:
32 raise ValueError(f"k must be in [0, n], got k={k}, n={n}")
34 p = k / n
35 z2 = z * z
36 denominator = 1.0 + z2 / n
37 center = (p + z2 / (2.0 * n)) / denominator
38 margin = (z * math.sqrt(p * (1.0 - p) / n + z2 / (4.0 * n * n))) / denominator
39 return max(0.0, center - margin), min(1.0, center + margin)