def fac(n): return 1 if n==0 else n * fac(n-1) def choose(n,k): return fac(n) / fac(k) / fac(n-k) def prob(n,k,p): return choose(n,k) * p ** k * (1-p) ** (n-k) def prob_lt(n,k,p): return sum([prob(n,i,p) for i in range(p)]) SIGS = 30 ACTUALSIGS = 10 POWRETURN = 0.03 POSRETURN = 0.01 # Expected number of signatures on a block def ev(pos): return SIGS * pos # Chance you have at least k sigs def at_least_k(pos, k): return sum([prob(SIGS, i, pos) for i in range(k, SIGS + 1)]) # Expected number of signatures on a block filtering all