""" Median computation for vote parameters. Computes the element-wise median of (vinf, a, b, c, d, e) across all active votes. This parametric median is chosen over geometric median because: - It's transparent and politically explainable - The result is itself a valid set of Bézier parameters """ import numpy as np from dataclasses import dataclass @dataclass class VoteParams: """The 6 citizen-adjustable parameters.""" vinf: float a: float b: float c: float d: float e: float def compute_median(votes: list[VoteParams]) -> VoteParams | None: """ Compute element-wise median of vote parameters. Returns None if no votes provided. """ if not votes: return None vinfs = [v.vinf for v in votes] a_s = [v.a for v in votes] b_s = [v.b for v in votes] c_s = [v.c for v in votes] d_s = [v.d for v in votes] e_s = [v.e for v in votes] return VoteParams( vinf=float(np.median(vinfs)), a=float(np.median(a_s)), b=float(np.median(b_s)), c=float(np.median(c_s)), d=float(np.median(d_s)), e=float(np.median(e_s)), )