Files
YvvandClaude Opus 5.5 67ddee28b2 v3 : socle Rust (moteur pur, accès trustinWallet, serveur) ; maquette Nuxt rangée dans maquette/
- crates/ld-engine : formule inertielle (parité avec la maquette, garde C),
  coquille / changement de fond, assistant d'édition à règles, composition
  d'un document sous vote permanent (adoptions, aperçus, rivales).
- crates/trustin-access : qui voit, qui ouvre, qui gère les accès.
- crates/ld-server : API axum + SQLite, connexion Ğ1 (client OAuth2 de
  connect.monnaie-libre.fr), invitations, entrée en vigueur automatique,
  signalements de contradiction, traductions éditoriales, publication git,
  taille de la toile lue sur la chaîne.
- seeds/acte-engagement-certification.json : 33 articles, fr + en + es ;
  en vigueur : préambule, E1, E2 (seed a minima).
- maquette/ : frontend, backend et docker v2 déplacés tels quels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 02:04:42 +02:00

96 lines
2.5 KiB
Python

"""Six-level nuanced vote evaluation.
Levels:
0 - CONTRE
1 - PAS DU TOUT
2 - PAS D'ACCORD
3 - NEUTRE
4 - D'ACCORD
5 - TOUT A FAIT
Adoption rule:
The sum of votes at levels 3 + 4 + 5 must be >= threshold_pct% of total votes.
A minimum number of participants is also required.
"""
from __future__ import annotations
LEVEL_LABELS: dict[int, str] = {
0: "CONTRE",
1: "PAS DU TOUT",
2: "PAS D'ACCORD",
3: "NEUTRE",
4: "D'ACCORD",
5: "TOUT A FAIT",
}
NUM_LEVELS = 6
def evaluate_nuanced(
votes: list[int],
threshold_pct: int = 80,
min_participants: int = 59,
) -> dict:
"""Evaluate a nuanced vote from a list of individual vote levels.
Parameters
----------
votes:
List of vote levels (each 0-5). One entry per voter.
threshold_pct:
Minimum percentage of positive votes (levels 3-5) out of total
for adoption.
min_participants:
Minimum number of participants required for validity.
Returns
-------
dict
{
"total": int,
"per_level_counts": {0: int, 1: int, ..., 5: int},
"positive_count": int, # levels 3 + 4 + 5
"positive_pct": float, # 0.0 - 100.0
"threshold_met": bool,
"min_participants_met": bool,
"adopted": bool,
}
Raises
------
ValueError
If any vote value is outside the 0-5 range.
"""
# Validate vote levels
for v in votes:
if v < 0 or v > 5:
raise ValueError(
f"Niveau de vote invalide : {v}. Les niveaux valides sont 0-5."
)
total = len(votes)
per_level_counts: dict[int, int] = {level: 0 for level in range(NUM_LEVELS)}
for v in votes:
per_level_counts[v] += 1
# Positive = levels 3 (NEUTRE), 4 (D'ACCORD), 5 (TOUT A FAIT)
positive_count = per_level_counts[3] + per_level_counts[4] + per_level_counts[5]
positive_pct = (positive_count / total * 100.0) if total > 0 else 0.0
threshold_met = positive_pct >= threshold_pct
min_participants_met = total >= min_participants
adopted = threshold_met and min_participants_met
return {
"total": total,
"per_level_counts": per_level_counts,
"positive_count": positive_count,
"positive_pct": round(positive_pct, 2),
"threshold_met": threshold_met,
"min_participants_met": min_participants_met,
"adopted": adopted,
}