Module:majority judgement
Apparence
La documentation pour ce module peut être créée à Module:majority judgement/Documentation
local p = {}
local GRADES_LABELS = { "À Rejeter", "Insuffisant", "Passable", "Assez Bien", "Bien", "Très Bien" }
local COLORS = { "black", "red", "yellow", "yellowgreen", "ForestGreen", "DarkGreen" }
local function initVotes(nbCandidates)
local votes = {}
for i=1,nbCandidates do
votes[i] = {0, 0, 0, 0, 0, 0}
end
return votes
end
local function parseVotes(nbVoters, nbCandidates, args)
local voters = {}
local votes = initVotes(nbCandidates)
for i=0,nbVoters-1 do
table.insert(voters, mw.text.trim(args[i * (nbCandidates + 1) + 1]))
for j=1,nbCandidates do
local vote = tonumber(args[i * (nbCandidates + 1) + j + 1])
if vote == -1 then
vote = 0
end
vote = vote + 1
votes[j][vote] = votes[j][vote] + 1
end
end
return voters, votes
end
local function userLink(user)
return mw.ustring.format("[[User:%s|%s]]", user, user)
end
local function generateVotersList(nbVoters, voters)
local message = nbVoters .. " personnes ont voté : "
for i, v in ipairs(voters) do
message = message .. userLink(v) .. ((i < nbVoters) and ", " or ".\n")
end
return message
end
local function generateResultTableHeader(label)
local message = mw.ustring.format([[
{| class="wikitable" style="text-align: center
|+ Votes en %s
! Choix
! À Rejeter
! Insuffisant
! Passable
! Assez Bien
! Bien
! Très Bien
]], label)
return message
end
local function generateAbsoluteValueVotes(nbCandidates, nbVoters, votes)
local message = generateResultTableHeader("valeur absolue")
for i=1,nbCandidates do
message = message .. "|-\n|Choix " .. i
for j=1,6 do
local vote = votes[i][j]
message = message .. "||" .. vote
end
message = message .. "\n"
end
message = message .. "|}\n"
return message
end
local function formatPercentage(value)
return mw.ustring.format("%.2f%%", value)
end
local function generatePercentageVotes(nbCandidates, nbVoters, votes)
local message = generateResultTableHeader("pourcentage")
for i=1,nbCandidates do
message = message .. mw.ustring.format("|-\n|Choix %d", i)
for j=1,6 do
local vote = votes[i][j]
message = message .. "||" .. formatPercentage(vote / nbVoters * 100)
end
message = message .. "\n"
end
message = message .. "|}\n"
return message
end
local function generateHistogram(nbCandidates, nbVoters, votes)
local message = [[
{|
|+ '''Histogramme des votes'''
|-
|
|
{| cellpadding=0 width=500 border=0 cellspacing=0
|-
| width=49% |
| width=2% style=\"text-align: center\" | ↓
| width=49% | Point médian
|}
]]
for i=1,nbCandidates do
message = message .. mw.ustring.format([[
|-
| Choix %d
|
{| cellpadding=0 width=500 border=0 cellspacing=0
|-
]], i)
for j=1,6 do
if votes[i][j] ~= 0 then
message = message ..
mw.ustring.format('| bgcolor="%s" width="%s" | \n', COLORS[j], formatPercentage(votes[i][j] / nbVoters * 100))
end
end
message = message .. "|}\n"
end
message = message .. "|}\n"
return message
end
local function generateCondensedVotes(nbCandidates, nbVoters, votes)
local message = generateAbsoluteValueVotes(nbCandidates, nbVoters, votes)
message = message .. generatePercentageVotes(nbCandidates, nbVoters, votes)
message = message .. generateHistogram(nbCandidates, nbVoters, votes)
return message
end
local function computeMajorityGrades(nbCandidates, nbVoters, votes)
local median = nbVoters / 2
local grades = {}
for i = 1,nbCandidates do
local sum = 0
local grade = -1
for j, vote in ipairs(votes[i]) do
sum = sum + vote
if sum >= median then
grade = j - 1
break
end
end
table.insert(grades, grade)
end
return grades
end
local function searchWinners(grades)
local maxGrade = -1
local maxCandidates = {}
for i,mention in ipairs(grades) do
if mention > maxGrade then
maxGrade = mention
maxCandidates = {}
end
if mention == maxGrade then
table.insert(maxCandidates, i)
end
end
return maxGrade, maxCandidates
end
local function computeGroupsTable(candidates, votes, lowerGrade, higherGrade)
local message = "{| class=\"wikitable\" style=\"text-align: center\"\n"
message = message .. "|+\n"
message = message .. "!Choix !! Votes pour des<br>mentions<br>inférieures !! Votes pour des<br>mentions<br>supérieures\n"
local tmp = {}
for i, candidate in ipairs(candidates) do
local tmp2 = {0, 0}
for j=1,lowerGrade do
tmp2[1] = tmp2[1] + votes[candidate][j]
end
for j=higherGrade+2,5 do
tmp2[2] = tmp2[2] + votes[candidate][j]
end
message = message .. "|-\n"
message = message .. "| Choix " .. candidate .."||" .. tmp2[1] .. "||" .. tmp2[2] .. "\n"
tmp[candidate] = tmp2
end
return tmp, message .. "|}\n"
end
--[[
Encodage des résultats :
-1 = non répondu, considéré comme à rejeter
0 = à rejeter
1 = insuffisant
2 = passable
3 = assez bien
4 = bien
5 = très bien
]]--
function p.judge(frame)
local args = frame:getParent().args
local nbCandidates = tonumber(args['nb_candidats'])
local nbVoters = tonumber(args['nb_votants'])
local voters, votes = parseVotes(nbVoters, nbCandidates, args)
local message = "=== Affichage condensé des votes ===\n"
message = message .. generateVotersList(nbVoters, voters)
message = message .. generateCondensedVotes(nbCandidates, nbVoters, votes)
-- Calcul du meilleur choix
local grades = computeMajorityGrades(nbCandidates, nbVoters, votes)
local maxGrade, maxCandidates = searchWinners(grades)
--- Affichage des résultats
message = message .. "=== Résultats ===\n"
local nbWinners = #maxCandidates
if nbWinners == 1 then
return message .. "Le choix " .. maxCandidates[1] .. " remporte le vote en ayant obtenu la mention " .. GRADES_LABELS[maxGrade + 1] ..".\n"
elseif nbWinners > 1 then
message = message .. "Plusieurs candidats ont obtenu la même mention majoritaire (" .. GRADES_LABELS[maxGrade + 1] .. ") : "
for i,candidate in ipairs(maxCandidates) do
message = message .. candidate .. ((i < nbWinners) and ", " or ".\n")
end
else
return "ERREUR"
end
-- Départage
local groups, tabular = computeGroupsTable(maxCandidates, votes, maxGrade, maxGrade)
message = message .. tabular
local maxi = -1
for candidate, group in pairs(groups) do
local q = group[1]
if q < maxi then
maxi = q
end
local p = group[2]
end
return message
end
return p