Module:Election box US auto
Appearance
![]() | This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
This is used by {{Election box US auto}}
.
Usage
{{#invoke:Election box US auto|function_name}}
local p = {}
local mError = require('Module:Error')
function percent( part, total )
if total >= 1000000 then
-- if > 1 million votes, then round to 2 decimals
round_to = 2
else
round_to = 1
end
local ret = mw.ext.ParserFunctions.expr( "" .. 100 * part / total .. " round " .. round_to )
if not string.find( ret, ".", 1, true ) then
-- add the decimals that expr doesn't
ret = ret .. "." .. string.rep("0", round_to)
end
return ret
end
function p.make( frame )
return frame:preprocess( make( frame:getParent() ) )
end
function make( frame )
local state = frame.args[1]
if not state then
return mError.error({message="State is missing"})
end
local year = frame.args[2]
if not year then
return mError.error({message="Year is missing"})
end
local contest = frame.args[3]
if not contest then
return mError.error({message="Contest is missing"})
end
local type = "General"
if frame.args.type then
if frame.args.type == "Primary" then
type = "Primary"
else
return mError.error({message="Invalid value for |type="})
end
end
local tab_name = state .. " Elections/" .. year .. "/" .. type .. "/Candidates.tab"
local tabular = mw.ext.data.get(tab_name)
if not tabular then
return mError.error({message="Unable to find tabular data: " .. tab_name})
end
local data = tabular.data
local candidates = {}
for k,v in pairs(data) do
if v[1] == contest then
table.insert(candidates, v)
end
end
local total_votes = 0
local winner = {}
winner[5] = 0
for k,v in pairs(candidates) do
total_votes = total_votes + v[5]
if v[5] > winner[5] then
winner = v
end
end
if mw.ustring.find(contest, "United States Representative", 1, true) then
title = "[[United States House of Representatives elections, " .. year .. "]]"
elseif contest == "President" then
title = "U.S. presidential election in " .. state .. ", " .. year
else
title = "...????"
end
local ret = "{{Election box begin no change| title=" .. title .. '<ref name="' .. tab_name .. '">' .. tabular.sources .. "</ref>}}"
function sort_candidates(a,b)
return a[5] > b[5]
end
table.sort(candidates, sort_candidates)
local linked_write_in = false
for k,v in pairs(candidates) do
local temp = "{{"
if v[2] == winner[2] then
temp = temp .. "Election box winning candidate"
else
temp = temp .. "Election box candidate"
end
local n_party = normalize_parties( v[3] )
if n_party then
temp = temp .. " with party link no change|party=" .. n_party
else
temp = temp .. " no party link no change"
end
link = frame.args[v[2] .. " link"]
if link then
link = mw.title.new(link)
else
-- bypass redirects, which is mostly important for display names
link = mw.title.new(v[2])
if link.isRedirect then
link = link.redirectTarget
end
end
-- Strip disambiguators since we can't use the pipe trick
display_name, ignore = mw.ustring.gsub(link.prefixedText, "%b()", "")
if frame.args.redlinks or link.exists then
full_link = "[[" .. link.prefixedText .. "|" .. display_name .. "]]"
else
full_link = display_name
end
temp = temp .. "|candidate=" .. full_link
if v[4] then
-- incumbent
temp = temp .. " ([[incumbent]])"
end
if v[6] then
-- write in
if linked_write_in then
temp = temp .. " (write-in)"
else
temp = temp .. " ([[Write-in candidate|write-in]])"
linked_write_in = true -- only link it once
end
end
temp = temp .. "|votes={{formatnum:" .. v[5] .. "}}"
temp = temp .. "|percentage=" .. percent(v[5], total_votes) .. "%"
temp = temp .. "}}"
ret = ret .. temp
end
ret = ret .. "{{Election box total no change|votes= {{formatnum:" .. total_votes .. "}}|percentage = " .. percent(total_votes, total_votes) .. "%}}"
local hold = frame.args.hold
local gain = false
if hold == "held" or winner[4] then
ret = ret .. "{{Election box hold with party link without swing|winner=" .. normalize_parties(winner[3]) .. "}}"
elseif hold == "flip" then
-- shorthand for D->R/R->D
win_party = winner[3]
if win_party == "Democratic" then
lose_party = normalize_parties("Republican")
else
lose_party = normalize_parties("Democratic")
end
win_party = normalize_parties(win_party)
gain = true
elseif frame.args.gain then
win_party = normalize_parties(frame.args.gain)
lose_party = normalize_parties(frame.args.loser)
gain = true
end
if gain then
ret = ret .. "{{Election box gain with party link without swing|winner=" .. win_party .. "|loser=" .. lose_party .. "}}"
end
ret = ret .. "{{Election box end}}"
return ret
end
function normalize_parties( party )
-- Drop all parties after the first one?
party = mw.text.split( party, ",", true )[1]
local parties = {
Democratic = "Democratic Party (United States)",
Republican = "Republican Party (United States)",
Blank = "Independent (politician)",
Independent = "Independent (politician)",
Libertarian = "Libertarian Party (United States)",
Green = "Green Party (United States)",
}
parties["Peace and Freedom"] = "Peace and Freedom Party"
parties["No Party Preference"] = "Independent (politician)"
for k, v in pairs(parties) do
if k == party then
return v
end
end
-- not found, return false
return false
end
return p