from operator import itemgetter
def calculVoteUnique(votes, scrutin):
nbVotes = len(votes)
resultats = {}
for c in scrutin["Candidats"]:
resultats[c] = 0
resultats[u"Vote Blanc"] = 0
for k, v in votes.iteritems():
resultats[v["choix"]] = resultats[v["choix"]] + 1
aPourvoir = int(scrutin["Parametres Scrutin"]["Sieges a pourvoir"])
paires = sorted(resultats.iteritems(), key=itemgetter(1), reverse=True)
elus = paires [0:aPourvoir]
elus = [el[0] for el in elus]
details =u""
for candidat, score in resultats.iteritems():
pourcentage = float(score)*100.0 / float(nbVotes)
details = details + u"<font color=green>" + unicode(candidat)\
+ u"</font> : <font color=blue>" + unicode("%.2f" % pourcentage)\
+ u"%</font> - <font color=orange>" + unicode(score) +" votes</font><br>\n"
return {"Elus" : elus,\
"Details" : details\
}
def comptePremiersVotes(votesPonderes, candidats):
result = {}
for c in candidats:
result[c] = 0
for k,v in votesPonderes.iteritems():
if v[0] == []:
aDistribuer = v[1]/len(candidats)
for c in candidats:
result[c] += aDistribuer
else:
print u"DEBUG Candidat 1 : "+repr(v[0][0])
result[v[0][0]] += v[1]
return result
def vireGagnants(votesPonderes, gagnants, seuil):
for k,v in votesPonderes.iteritems():
for gagnant, score in gagnants.iteritems():
if gagnant in v[0]:
if gagnant == v[0][0]:
votesPonderes[k][1] *= float((score - seuil))/float(score)
votesPonderes[k][0].remove(gagnant)
else:
votesPonderes[k][0].remove(gagnant)
return votesPonderes
def virePerdant(votesPonderes, perdant):
print "DEBUG vire Perdant"
for k,v in votesPonderes.iteritems():
if perdant in v[0]:
votesPonderes[k][0].remove(perdant)
return votesPonderes
def calculVoteUniqueTransferable(votes, scrutin):
detail = u""
elus=[]
votesPonderes = {}
candidatsRestants = scrutin["Candidats"]
num = 0
for idVote,vote in votes.iteritems():
num += 1
paires = sorted(vote.iteritems(), key=itemgetter(1), reverse=False)
v = [p[0] for p in paires]
votesPonderes[num] = [v, float(1.0)]
seuil = (len(votesPonderes) / (scrutin["Parametres Scrutin"]["Sieges a pourvoir"] +1)) + 1
detail += u"------------------------------------------<br>\n"\
+ u"Seuil de votes nécessaire pour être élu : nombre de votes ("+unicode(len(votesPonderes))\
+ u") divisé par le nombre de sièges ("+unicode(scrutin["Parametres Scrutin"]["Sieges a pourvoir"])\
+ u") +1, auquel on ajoute 1<br><font color=blue>Seuil = " + unicode(seuil)\
+ u" votes pour obtenir un siège</font><br>" + u"------------------------------------------<br>\n"
candidatsElus=0
while candidatsElus < scrutin["Parametres Scrutin"]["Sieges a pourvoir"]:
score = comptePremiersVotes(votesPonderes, candidatsRestants)
gagnants = {}
for cand, sc in score.iteritems():
if sc >= seuil:
gagnants[cand] = sc
candidatsElus += 1
detail += u"Le candidat <font color=green>"+unicode(cand)+"</font> passe le seuil avec "+unicode(sc)+" voix<br>\n"
candidatsRestants.remove(cand)
else:
detail += u"Le candidat <font color=orange>"+unicode(cand)+"</font> ne passe pas avec "+unicode(sc)+" voix<br>\n"
if len(gagnants) > 0:
paires = sorted(gagnants.iteritems(), key=itemgetter(1), reverse=True)
elus.extend([p[0] for p in paires])
votesPonderes = vireGagnants(votesPonderes, gagnants, seuil)
else:
scoreMin = min([sc for c,sc in score.iteritems()])
aVirer = [c for c, sc in score.iteritems() if sc == scoreMin]
if len(aVirer) > 1:
detail += u"<font color=red>Attention : plusieurs candidats sont éliminables avec un score égal :<br>\n"
for av in aVirer:
detail += unicode(av) + "<br>\n"
detail += u"----> " + unicode(aVirer[0]) + u" éliminé !</font><br>\n" TODO
elif len(aVirer) < 1:
detail += u"<font color=red>BUG : pas de candidat à éliminer alors qu'il n'y a pas de gagnant !</font><br>\n"
return {"Elus" : elus, "Details":detail}
else:
detail += u"Pas d'élu ! Le candidat <font color=red>" + unicode(aVirer[0]) + u"</font> est éliminé (score le plus faible)<br>\n"
votesPonderes = virePerdant(votesPonderes, aVirer[0])
candidatsRestants.remove(aVirer[0])
detail += u"<br>"
return {"Elus" : elus, "Details":u"<font size=10>"+detail+"</font>\n"}
def calculVoteAssentiment(votes, scrutin):
methode = scrutin["Parametres Scrutin"]["Methode de calcul"]
nbVotes = len(votes)
resultats={}
noteFinale = {}
if methode == u"Note Moyenne":
for c in scrutin["Candidats"]:
noteFinale[c] = float(0.0)
for k, v in votes.iteritems():
for candidat, note in v.iteritems():
noteFinale[candidat] = noteFinale[candidat] + float(note)/float(nbVotes)
elif methode == u"Note Médiane":
for c in scrutin["Candidats"]:
resultats[c] = {}
for note in xrange(scrutin["Parametres Scrutin"]["Note minimale"], scrutin["Parametres Scrutin"]["Note maximale"] + 1):
resultats[c][note] = 0
for k,v in votes.iteritems():
for candidat, note in v.iteritems():
if not(resultats[candidat].has_key(note)):
print u"BUG : un électeur a rentré une note invalide pour le candidat "+repr(candidat)
else:
resultats[candidat][note] += 1
positionMediane = float(nbVotes)/2.0
for candidat, notes in resultats.iteritems():
cumulVotes = 0
clefs = notes.keys()
clefs.sort()
for k in clefs:
if cumulVotes + notes[k] >= positionMediane:
p = float(positionMediane - cumulVotes)/float(notes[k])
mini = float(k)-0.5
maxi = float(k)+0.5
noteFinale[candidat] = p*maxi + (1.0-p)*mini
break
cumulVotes = cumulVotes + notes[k]
else:
return {}
aPourvoir = int(scrutin["Parametres Scrutin"]["Sieges a pourvoir"])
paires = sorted(noteFinale.iteritems(), key=itemgetter(1), reverse=True)
elus = paires [0:aPourvoir]
elus = [el[0] for el in elus]
details =u""
for candidat, score in noteFinale.iteritems():
details = details + u"<font color=green>" + unicode(candidat)\
+ u"</font> - note <font color=blue>" + unicode(score)\
+ u"</font><br>\n"
if methode == u"Note Médiane":
details = details + "<font color=orange>"
for k in clefs:
details = details + u"---> Note " + unicode(k) + ": "+ unicode(resultats[candidat][k])+" votes<br>\n"
details = details + "</font>\n"
return {"Elus" : elus,\
"Details" : details\
}
def getAllMethods():
return {"Vote unique" : calculVoteUnique,\
"Vote unique transferable" : calculVoteUniqueTransferable,\
"Vote par assentiment" : calculVoteAssentiment\
}