Initial commit: SejeteralO water tarification platform
Full-stack app for participatory water pricing using Bezier curves. - Backend: FastAPI + SQLAlchemy + SQLite with JWT auth - Frontend: Nuxt 4 + TypeScript with interactive SVG editor - Math engine: cubic Bezier tarification with Cardano solver - Admin: commune management, household import, vote monitoring, CMS - Citizen: interactive curve editor, vote submission - Docker-compose deployment ready Includes fixes for: - Impact table snake_case/camelCase property mismatch - CMS content backend API + frontend editor (was stub) - Admin route protection middleware - Public content display on commune page - Vote confirmation page link fix Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
48
backend/app/engine/median.py
Normal file
48
backend/app/engine/median.py
Normal file
@@ -0,0 +1,48 @@
|
||||
"""
|
||||
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)),
|
||||
)
|
||||
Reference in New Issue
Block a user