Module:Final results table

From Wiki - Scioly.org
Jump to: navigation, search

Documentation for this module may be created at Module:Final results table/doc

local p = {};
local medals = 6;
local event_num = 1;
local drop_num = 0;
local using_states = false;
local using_numbers = false;
local trial_nums = {};
local getArgs = require('Module:Arguments').getArgs

function p.trim(str)
    -- trim string function
    return (string.gsub(str, "^%s*(.-)%s*$", "%1"))
end

function p.split(inputstr, sep)
    -- split string function
    t = {}
    for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
        str = p.trim(str)
        table.insert(t, str)
    end
    return t
end

function p.sum(scores)
    sum = 0
    for k, v in pairs(scores) do
        trial = false
        for _, v in pairs(trial_nums) do
            if v == k then
                trial = true
            end
        end
        if trial == false then
            sum = sum + tonumber(v)
        end
    end
    return sum
end

function event_sort(a, b)
    return a['num'] < b['num']
end

function score_sort(a, b)
    return a['sum'] < b['sum']
end

function p.get_score_row(num)
    colors = {
        "#FFF386",
        "#D6E6ED",
        "#C9A977",
        "#FFF5CA",
        "#C9FFBF",
        "#E4C6FF",
        "#FFDEB7",
        "#CCF6FF",
        "#FFC9DD",
        "#EA9BB3",
        "#E3FAFF",
        "#E3FAFF",
        "#E3FAFF",
        "#E3FAFF",
        "#E3FAFF",
        "#E3FAFF",
        "#E3FAFF",
        "#E3FAFF",
        "#E3FAFF",
        "#E3FAFF",
    };
    if num <= medals then
        return "|style='background-color: " .. colors[num] .. ";'|" .. tostring(num) .. "\n"
    else
        return "|" .. tostring(num) .. "\n"
    end
end

function p.main(frame)
    local args = getArgs(frame)
    -- get medals
    if args['medals'] ~= nil then
        medals = tonumber(args['medals'])
    end
    if args['drop'] ~= nil then
        drop_num = tonumber(args['drop'])
    end
    -- start table
    res = "{| class='wikitable sortable'\n|-\n"
    -- make header
    header = "! class='unsortable' style='line-height: 1;'| "
    if args['name'] ~= nil then
        header = header .. "<span style='font-size: 24px;'><b>" .. args['name'] .. "</b></span>"
        if args['div'] ~= nil or args['date'] ~= nil then
            header = header .. "<span style='font-size: 14px; font-weight: normal;'>"
        end
        if args['div'] ~= nil then
            header = header .. frame:preprocess("{{break}}") .. "<b>Division " .. args['div'] .. "</b>"
        end
        if args['date'] ~= nil then
            header = header .. frame:preprocess("{{break}}") .. args['date']
        end
        if args['div'] ~= nil or args['date'] ~= nil then
            header = header .. "</span>"
        end
    end
    res = res .. header .. "\n"
    -- make event columns
    eventNames = {}
    for k, v in pairs(args) do
        if string.find(k, "event_") ~= nil and string.find(k, "trial") == nil then
            num = tonumber(string.match(k, '%d+'))
            if args['event_' .. num .. '_trial'] ~= nil then
                table.insert(eventNames, {name=v, trial=true, num=num}) 
                table.insert(trial_nums, num)
            else
                table.insert(eventNames, {name=v, trial=false, num=num})
            end
        end
    end
    event_num = #eventNames
    table.sort(eventNames, event_sort)
    -- get the number of rows to make
    maxRow = 1
    for k, v in pairs(args) do
        num = tonumber(string.match(k, '%d+'))
        if num ~= nil and num > maxRow and string.find(k, "team") ~= nil then
            maxRow = num
        end
    end
    -- get score data for each row 
    tableData = {}
    for i = 1, maxRow do
        scores = p.split(args['team_' .. tostring(i) .. '_scores'], ",")
        unsortedScores = {}
        for k, v in pairs(scores) do
            unsortedScores[k] = v
        end
        scoreSum = p.sum(scores)
        droppedScore = 0
        if drop_num > 0 then
            -- if scores need to be dropped
            for k, v in pairs(scores) do
                -- convert scores to numbers
                scores[k] = tonumber(v)
            end
            table.sort(scores)
            for l, u in pairs(scores) do
                if (l > event_num - drop_num) then
                    -- drop the last drop_num events
                    droppedScore = droppedScore + u
                end
            end
        end
        state = ""
        if args['team_' .. tostring(i) .. '_state'] ~= nil then
            using_states = true
            state = args['team_' .. tostring(i) .. '_state']
        end
        team_number = ""
        if args['team_' .. tostring(i) .. '_number'] ~= nil then
            using_numbers = true
            team_number = args['team_' .. tostring(i) .. '_number']
        end
        scoreSum = scoreSum - droppedScore
        table.insert(tableData, {name=args['team_' .. tostring(i) .. '_name'], scores=unsortedScores, sum=scoreSum, drop=droppedScore, state=state, number=team_number})
    end
    if using_states == true then
        res = res .. frame:preprocess("! {{vertical header|State|stp=1}}\n") 
    end
    if using_numbers == true then
        res = res .. frame:preprocess("! {{vertical header|Team Number|stp=1}}\n") 
    end
    for k, v in pairs(eventNames) do
        if v['trial'] == true then
            res = res .. frame:preprocess("! {{vertical header|" .. v['name'] .. " (Trial)|stp=1|cellstyle=background-color: #C0D1E9}}\n")
        else
            res = res .. frame:preprocess("! {{vertical header|" .. v['name'] .. "|stp=1}}\n")
        end
    end
    if drop_num > 0 then
        res = res .. frame:preprocess("! {{vertical header|Dropped Points|stp=1}}\n") 
    end
    res = res .. frame:preprocess("! {{vertical header|Points|stp=1}}\n")
    res = res .. frame:preprocess("! {{vertical header|Final Place|stp=1}}\n")
    -- make table
    table.sort(tableData, score_sort)
    for k, v in pairs(tableData) do
        -- for each row in the sorted data
        tableRow = ""
        -- add row styling
        tableRow = tableRow .. "|- style='text-align: center;'\n"
        tableRow = tableRow .. "|style='text-align: left; width: 20%;'|" .. v['name'] .. "\n"
        -- add team numbers/states
        if using_states == true then
            tableRow = tableRow .. "|" .. v['state'] .. "\n"
        end
        if using_numbers == true then
            tableRow = tableRow .. "|style='background-color: #E3E3E3;'| " .. v['number'] .. "\n"
        end
        -- add scores
        for l, u in pairs(v['scores']) do
            tableRow = tableRow .. p.get_score_row(tonumber(u))
        end
        -- add sum
        if drop_num > 0 then
            -- if scores need to be dropped
            tableRow = tableRow .. "|style='background-color: #EABFBF;'|" .. v['drop'] .. "\n"
        end
        tableRow = tableRow .. "|style='background-color: #E3E3E3;'|" .. v['sum'] .. "\n"
        tableRow = tableRow .. "|style='background-color: #CCCCCC;'|" .. k .. "\n"
        res = res .. tableRow
    end
    res = res .. '|}'
    return res
end

return p;