from math import comb
from random import Random
rng = Random(34)
probabilities = {'uniform': [0.8] * 20, 'split': [0.99] * 10 + [0.55] * 10}
counts = {}
for name, probs in probabilities.items():
    counts[name] = []
    for task, probability in enumerate(probs):
        successes = 0
        for trial in range(10):
            booking = {'id': task, 'status': 'pending'}
            if rng.random() < probability:
                booking['status'] = 'confirmed'
            successes += booking['status'] == 'confirmed'
        counts[name].append(successes)

def score(cs, k, all_success=True):
    assert 1 <= k <= 10
    terms = [comb(c if all_success else 10-c, k) / comb(10, k) for c in cs]
    return sum(terms) / len(terms) if all_success else 1 - sum(terms) / len(terms)

def interval(cs, k):
    boot_rng = Random(340 + k)
    values = sorted(score([boot_rng.choice(cs) for _ in cs], k) for _ in range(500))
    return values[12], values[487]

for name, cs in counts.items():
    print(name, 'successes_per_task', cs)
    for k in (1, 2, 5):
        lo, hi = interval(cs, k)
        print(f'k={k} pass^k={score(cs,k):.3f} pass@k={score(cs,k,False):.3f}',
              f'task_bootstrap_95pct=[{lo:.3f},{hi:.3f}]')
assert abs(score([8], 2) - 28/45) < 1e-12
