34 lines
1.4 KiB
Python
34 lines
1.4 KiB
Python
"""Panel-Primitive (creator2-Lektionen 15-24): 2 = Konsens-Minimum, Merge nur
|
|
einstimmig, Ausfall = keine Stimme = kein Entscheid, Ersatz-Richter bei genau
|
|
einem Ausfall."""
|
|
from typing import Awaitable, Callable
|
|
|
|
|
|
def einstimmig(stimmen: list, n: int, urteil: Callable) -> bool:
|
|
"""True nur bei vollzähligem Panel UND allen Stimmen True.
|
|
urteil(s) → True/False/None; None (Ausfall/Parse) = keine Stimme."""
|
|
urteile = [urteil(s) for s in stimmen if s is not None]
|
|
urteile = [u for u in urteile if u is not None]
|
|
return len(urteile) >= n and all(urteile)
|
|
|
|
|
|
async def panel(ruf: Callable[[int], Awaitable], groesse: int) -> list:
|
|
"""groesse unabhängige Calls; fällt GENAU eine Stimme aus, läuft ein
|
|
Ersatz-Richter (Index -1). None-Stimmen bleiben in der Liste."""
|
|
import asyncio
|
|
stimmen = list(await asyncio.gather(*(ruf(i) for i in range(groesse))))
|
|
gueltig = [s for s in stimmen if s is not None]
|
|
if groesse >= 2 and len(gueltig) == groesse - 1:
|
|
stimmen.append(await ruf(-1))
|
|
return stimmen
|
|
|
|
|
|
def mehrheit(stimmen: list, urteil: Callable) -> bool | None:
|
|
"""Mehrheitsentscheid (Klärung, 3er): None wenn keine Mehrheit möglich."""
|
|
urteile = [urteil(s) for s in stimmen if s is not None]
|
|
urteile = [u for u in urteile if u is not None]
|
|
if not urteile:
|
|
return None
|
|
ja = sum(1 for u in urteile if u)
|
|
return ja * 2 > len(urteile)
|