"""第 3 章：教学设定的报警系统与离散等待时间分布。"""

from math import sqrt
from random import Random


WAIT_TIMES = [0, 10, 30]
PROBABILITIES = [0.5, 0.3, 0.2]


def posterior(prior=0.01, sensitivity=0.9, false_alarm=0.05):
    alarm = prior * sensitivity + (1 - prior) * false_alarm
    if alarm == 0:
        raise ValueError("报警事件概率为 0，不能以它为条件")
    return prior * sensitivity / alarm


def moments(values, probabilities):
    mean = sum(x * p for x, p in zip(values, probabilities))
    variance = sum(p * (x - mean) ** 2 for x, p in zip(values, probabilities))
    return mean, variance


def sample_waits(count, seed=2026):
    return Random(seed).choices(WAIT_TIMES, weights=PROBABILITIES, k=count)


def main():
    print(f"故障率 1% 时，报警后的故障概率：{posterior():.2%}")
    print(f"故障率 10% 时，报警后的故障概率：{posterior(0.1):.2%}")
    mean, variance = moments(WAIT_TIMES, PROBABILITIES)
    print(f"等待时间期望：{mean:.2f} 秒")
    print(f"方差：{variance:.2f} 秒²，标准差：{sqrt(variance):.2f} 秒")
    # 各样本量使用同一长序列的前缀，便于观察样本均值。
    samples = sample_waits(10000)
    for count in [10, 100, 10000]:
        print(f"{count} 次采样的平均等待：{sum(samples[:count]) / count:.3f} 秒")
    counts = [samples.count(value) for value in WAIT_TIMES]
    print("10000 次采样的各类频数：", counts)


if __name__ == "__main__":
    main()
