File size: 1,554 Bytes
70e8ba6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env python3
"""Every rate write is a receipt. Stdlib only."""
from __future__ import annotations

from fractions import Fraction as F


def as_exact(x):
    if isinstance(x, bool):
        raise TypeError("theta bool")
    if isinstance(x, int):
        return F(x)
    if isinstance(x, F):
        return F(x)
    raise TypeError("theta not Q: %s" % type(x).__name__)


def isolate(v, seed):
    v, seed = as_exact(v), as_exact(seed)
    if seed == 0:
        raise ValueError("theta seed 0")
    return (v, seed)


def mix(a, b):
    (v, r), (w, s) = a, b
    return (v * w, r * w + v * s)


def rate(top, bot):
    if bot[1] == 0:
        raise ValueError("theta dead isolator")
    return top[1] / bot[1]


def receipt(fn, v, seeds=(1, 2, F(1, 2), -1)):
    """One row per seed, plus gauge (all rates equal or split)."""
    if not seeds:
        raise ValueError("theta empty seeds")
    rows = []
    for s in seeds:
        x = isolate(v, s)
        y = fn(x)
        r = rate(y, x)
        rows.append({"seed": s, "value": y[0], "channel": y[1], "rate": r})
    rates = [row["rate"] for row in rows]
    gauge = all(r == rates[0] for r in rates)
    return {"at": as_exact(v), "gauge": gauge, "rate": rates[0] if gauge else None, "rows": rows, "theta": not gauge}


if __name__ == "__main__":
    sq = lambda x: mix(x, x)
    rec = receipt(sq, 3)
    print("gauge", rec["gauge"], "rate", rec["rate"])
    for row in rec["rows"]:
        print(row)
    try:
        receipt(sq, 3, seeds=())
    except ValueError as e:
        print(e)