commit 4a20a70bfa0c27532cf2f53436cd588757339a9b Author: philippe lhardy Date: Sat Jun 14 12:15:38 2025 +0200 premiere implementation en python - il n'y a pas de departage des candidats ayant obtenu la même mention - aucune certitude que l'algorithme est bien respecté. diff --git a/samples/1.json b/samples/1.json new file mode 100644 index 0000000..0e8e12a --- /dev/null +++ b/samples/1.json @@ -0,0 +1,80 @@ +{ +"candidats":{ + "A":"albert", + "B":"Beatrice", + "C":"Chloé", + "D":"Deborah", + "E":"Eric", + "F":"Francçois", + "G":"Gisèle", + "H":"Hugo" +}, +"votants":{ + "decompte":10 +}, +"mentions":[ + "Très Bien", + "Bien", + "Assez Bien", + "Passable", + "Insuffisant", + "A rejeter" +], +"votation": + { + "date":"14 juin 2025", + "lieu":"liffré", + "votes":[ + { + "A":1, + "C":2, + "D":3 + }, + { + "A":1, + "C":2, + "D":3 + }, + { + "A":1, + "C":2, + "D":3 + }, + { + "A":1, + "C":2, + "D":3, + }, + { + "A":1, + "C":2, + "D":3 + }, + { + "A":1, + "C":2, + "D":3 + }, + { + "A":1, + "C":2, + "D":3 + }, + { + "A":1, + "C":2, + "D":3 + }, + { + "A":1, + "C":2, + "D":3 + }, + { + "A":1, + "C":2, + "D":3 + } + ] + } +} diff --git a/samples/2.json b/samples/2.json new file mode 100644 index 0000000..5244914 --- /dev/null +++ b/samples/2.json @@ -0,0 +1,77 @@ +{ +"candidats":{ + "A":"albert", + "B":"Beatrice", + "C":"Chloé", + "D":"Deborah", + "E":"Eric", + "F":"Francçois", + "G":"Gisèle", + "H":"Hugo" +}, +"votants":{ + "decompte":10 +}, +"mentions":[ + "Très Bien", + "Bien", + "Assez Bien", + "Passable", + "Insuffisant", + "A rejeter" +], +"votation": + { + "date":"14 juin 2025", + "lieu":"liffré", + "votes":[ + { + "A":1, + "C":2, + "D":3 + }, + { + "B":1, + "C":2, + "E":3 + }, + { + "A":1, + "C":2, + "F":3 + }, + { + "G":1, + "C":2, + "D":3, + }, + { + "A":1, + "G":2, + "E":3 + }, + { + "E":1, + "C":2, + "D":3 + }, + { + "E":1, + "C":2, + "D":3 + }, + { + "A":1, + "D":2, + }, + { + "A":5, + "C":2, + "D":3 + }, + { + "A":4, + } + ] + } +} diff --git a/samples/check.sh b/samples/check.sh new file mode 100755 index 0000000..24b7d51 --- /dev/null +++ b/samples/check.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +if [[ $# > 0 ]] +then + vote=$1 +fi + +if [[ -z $vote ]] +then + echo "[ERROR] numéro de vote manquant ( ex 1 pour 1.json )" + exit 1 +fi + +json=~/clients/artlog/artisanlogiciel.code/artlog_jsontools/build/json + +json_file=$vote.json +json_indent_file=$vote.indent.json +echo "generating $json_indent_file" + +$json indent=spaces:2 -- $json_file > $json_indent_file + +python3 parse_sample.py $json_indent_file diff --git a/samples/parse_sample.py b/samples/parse_sample.py new file mode 100644 index 0000000..351ffd5 --- /dev/null +++ b/samples/parse_sample.py @@ -0,0 +1,105 @@ +import json +import sys + +if len(sys.argv) > 1: + poll_file=sys.argv[1] +else: + print('missing file argument') + exit(1) + +verbose=False + +with open(poll_file,'r') as poll_fd: + poll = json.load(poll_fd) + +if verbose: + print(poll) + +votants=poll['votants']['decompte'] +candidats=poll['candidats'] +nombre_candidats=len(candidats) + +# l'ordre des mentions est de la meilleure à la pire (reject) +mentions=poll['mentions'] +default_mention=len(mentions)-1 + +votes=poll["votation"]["votes"] +if verbose: + print('candidats:' + str(candidats)) + print(votes) + +default_vote={} +for candidat in candidats: + default_vote[candidat]=default_mention + +collect={} +for vote in votes: + + # missing candidat in vote is the worts one + for candidat in candidats: + if not candidat in vote: + vote[candidat]=default_mention + + for candidat,mention in vote.items(): + if candidat in collect: + if mention in collect[candidat]: + collect[candidat][mention]=collect[candidat][mention]+1 + else: + collect[candidat][mention]=1 + else: + collect[candidat]={mention:1} + +if verbose: + print(collect) + +votant_median_check= votants / 2 if votants % 2 == 0 else ((votants-1) / 2) +1 + +votant_median=votants // 2 + votants % 2 + +if votant_median_check != votant_median: + print('[ERROR] le nombre median de votants semble erroné. contactez le developpeur de ce code.' + str(votant_median_check)) + +merite={} +mention_mediane={} + +# cumul : du meilleur au pire +# range_mentions = range(len(mentions)) +# cumul du pire au meilleur +range_mentions = range(len(mentions)-1,-1,-1) + +for candidat in candidats: + vote=collect[candidat] + cumul=0 + m=[0 for i in range(len(mentions))] + mention_m=None + for mention in range_mentions: + if mention in vote: + cumul=cumul+vote[mention] + if cumul >= votant_median and mention_m is None: + mention_m=mention + m[mention]=cumul + if cumul < votants: + print('[ERROR] le cumul des votes doit correspondre au nombre de votants. contactez le developpeur de ce code.') + mention_mediane[candidat]=mention_m + merite[candidat]=m + +if verbose: + print(merite) + print(mention_mediane) + +# les gagnants sont ceux qui ont la mention minimale ( la meilleure ) +found=[] +for mention in range(0,len(mentions)): + for candidat,merite_median in mention_mediane.items(): + if merite_median == mention: + found.append({candidat:candidats[candidat]}) + if len(found) > 0: + break + +if verbose: + print(found) + print(mentions[mention]) + +result = {'resultat':{'mention':mentions[mention],'candidats':found},'merite':merite} + +print(json.dumps(result))