Edge Rewrite
Jump to content

Module:Sports attendance/sandbox

From Wikipedia, the free encyclopedia
-- Module to build tables for attendance in Sports
-- See documentation for details

require('strict')

local p = {}

-- Main function
function p.main(frame)
	-- Declare locals
    local getArgs = require('Module:Arguments').getArgs
	local Args = getArgs(frame, {parentFirst = true})
	local team_list = {['League total'] = {name = 'League total', attendance = {}}}
	local sorted_teams = {}
	local t = {}
	local lang = mw.language.getContentLanguage()
    
    -- Load modules
	local yesno = require('Module:Yesno')
	local mm = require('Module:Math')
	    
    -- Form list of teams, stored under key of string following 'team_'
    for arg, value in pairs(Args) do
    	local tname = string.match(arg, '^team_(.+)')
       	if yesno(tname, true) then
			-- Initialise team in team_list
			team_list[tname] = {}
			table.insert(sorted_teams, tname)
			
        	-- Set team's name, with link stripped
        	local stripped_brackets = mw.ustring.gsub(value, '[%[%]]', '')
        	team_list[tname]['name'] = mw.ustring.gsub(stripped_brackets, '.-|', '') -- strip original page name
           
        	-- Transform team's match attendances into numbers
        	local attendance = mw.text.split(Args['attendance_' .. tname] or '', '%s*[;,]%s*')
        	for i, att in ipairs(attendance) do
				if i == 1 then team_list[tname]['attendance'] = {} end -- Initialise team's attendance array
				
            	local att_num = tonumber(att)
            	team_list[tname]['attendance'][i] = att_num
            	table.insert(team_list['League total']['attendance'], att_num)
        	end
           
        	-- Compute team's average attendance for ranking
        	team_list[tname]['average'] = mm._round(mm._average(unpack(attendance)), 0)
        end
    end
    
    -- Compute league total average
    team_list['League total']['average'] = mm._round(mm._average(unpack(team_list['League total'].attendance)), 0)
    
    -- Rank teams by average attendance
	table.sort(sorted_teams, function(a, b)
    	-- Compare names if both teams do not have any attendance, or if their averages are identical
        if (not yesno(#team_list[a].attendance) and not yesno(#team_list[b].attendance)) or team_list[a].average == team_list[b].average then return a > b end
        
        -- The team with no attendance is placed lower
        if not yesno(#team_list[a].attendance) then return false end
        if not yesno(#team_list[b].attendance) then return true end
        
        -- Compare average attendance
        return team_list[a].average > team_list[b].average
    end)
	-- Add 'League total' to end of sorted_teams
	table.insert(sorted_teams, 'League total')
    
    -- Create table header
    table.insert(t, '{| class="wikitable sortable" style="text-align:right;"\n')
    table.insert(t, '!width=25|Pos\n')
    table.insert(t, '!width=185|Team\n')
    table.insert(t, '!width=25|<abbr title="Home matches played">Matches</abbr>\n')
    table.insert(t, '!width=65|<abbr title="Total season attendance">Total</abbr>\n')
    table.insert(t, '!width=55|<abbr title="Highest season attendance">High</abbr>\n')
    table.insert(t, '!width=55|<abbr title="Lowest season attendance">Low</abbr>\n')
    table.insert(t, '!width=55|<abbr title="Median season attendance">Median</abbr>\n')
    table.insert(t, '!width=55|<abbr title="Average season attendance">Average</abbr>\n')
    table.insert(t, '!width=55|<abbr title="Change in average attendance in comparison with the previous season">Change</abbr>\n')
    
    -- Create data rows
    for pos, tname in ipairs(sorted_teams) do
        local any = yesno(#team_list[tname].attendance, true) -- Check if any attendance data is available for the team
        local total = tname == 'League total'
        if total then
            -- Total row formatting
            table.insert(t, '|-class="sortbottom" style="background-color:#d8edf3; font-weight:bold;"\n')
        else
            -- Team row formatting
            table.insert(t, '|-\n')
        end
        table.insert(t, '| style="text-align:center;" |'..(any and not total and pos or '')..'\n')
        table.insert(t, '| style="text-align:left;" |'..(Args['team_'..tname] or 'League total')..'\n')
        table.insert(t, '| style="text-align:center;" |'..(any and #team_list[tname].attendance or '')..'\n')
        table.insert(t, '| '..(any and lang:formatNum(mm._sum(unpack(team_list[tname].attendance))) or '')..'\n')
        table.insert(t, '| '..(any and lang:formatNum(mm._max(unpack(team_list[tname].attendance))) or '')..'\n')
        table.insert(t, '| '..(any and lang:formatNum(mm._min(unpack(team_list[tname].attendance))) or '')..'\n')
        table.insert(t, '| '..(any and lang:formatNum(mm._median(unpack(team_list[tname].attendance))) or '')..'\n')
        table.insert(t, '| style="font-weight:bold" | '..(any and lang:formatNum(team_list[tname].average) or '')..'\n')
        if yesno(Args['previous_'..tname], true) then
        	table.insert(t, '| '..(any and frame:expandTemplate{title='change', args={Args['previous_'..tname], team_list[tname].average, dec=1}}..'\n'))
        else
        	table.insert(t, '| style="text-align:center" | n/a\n')
        end
        if yesno(Args['note_'..tname], true) then
            table.insert(t, '<sup>'..Args['note_'..tname]..'</sup>|<span style="visibility:hidden;color: transparent"><sup>†</sup></span>')
        end
    end

	-- Close table
	table.insert(t, '|}')
    
    -- Create footer
    if yesno(Args['updated'] or 'no') then
        table.insert(t, 'Updated to games played on '..Args['updated']..'<br />\n')
    end
    if yesno(Args['source'] or 'no') then
        table.insert(t, 'Source: '..Args['source']..'\n')
    end

	return table.concat(t)
end

return p