Module:Election box US auto
Appearance
| This module is rated as beta. It is considered ready for widespread use, but as it is still relatively new, it should be applied with some caution to ensure results are as expected. |
This is used by {{Election box US auto}}.
Usage
{{#invoke:Election box US auto|function_name}}
local p = {}
local mRedirect = require('Module:Redirect')
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