#!/usr/bin/env python3
"""Checked A/B arithmetic and Holm correction using only Python stdlib."""

from math import erfc, sqrt


def holm(p_values, alpha=0.05):
    """Return rejected IDs in Holm step-down order."""
    ordered = sorted(p_values.items(), key=lambda item: item[1])
    rejected = []
    total = len(ordered)
    for rank, (metric_id, p_value) in enumerate(ordered):
        threshold = alpha / (total - rank)
        if p_value > threshold:
            break
        rejected.append(metric_id)
    return rejected


success_a, n_a = 120, 400
success_b, n_b = 148, 400
p_a = success_a / n_a
p_b = success_b / n_b
risk_difference = p_b - p_a
risk_ratio = p_b / p_a

# Unpooled standard error for the Wald confidence interval.
se_ci = sqrt(p_a * (1 - p_a) / n_a + p_b * (1 - p_b) / n_b)
lower = risk_difference - 1.96 * se_ci
upper = risk_difference + 1.96 * se_ci

# Pooled standard error under H0: p_a == p_b.
pooled = (success_a + success_b) / (n_a + n_b)
se_h0 = sqrt(pooled * (1 - pooled) * (1 / n_a + 1 / n_b))
z_score = risk_difference / se_h0
p_value = erfc(abs(z_score) / sqrt(2))

minimum_relevant_effect = 0.04
holm_p_values = {
    "metric-1": 0.006,
    "metric-2": 0.012,
    "metric-3": 0.030,
    "metric-4": 0.200,
}

print(f"A-Rate: {p_a:.4f}")
print(f"B-Rate: {p_b:.4f}")
print(f"Absolute Differenz: {risk_difference:.4f}")
print(f"Risk Ratio: {risk_ratio:.4f}")
print(f"95%-Wald-KI: [{lower:.4f}, {upper:.4f}]")
print(f"z: {z_score:.4f}")
print(f"p (zweiseitig): {p_value:.4f}")
print(
    "Rollout-Kriterium KI-Untergrenze > 0.04: "
    + ("ja" if lower > minimum_relevant_effect else "nein")
)
print("Holm verworfen: " + ", ".join(holm(holm_p_values)))
