Edge Rewrite
Jump to content

Module:Sports attendance

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'] = {name = 'League total', attendance = {}}}
	local sorted_teams = {}
	local t = {}
	local lang = mw.language.getContentLanguage()

	local templatestyles = frame:extensionTag{
		name = 'templatestyles', args = { src = 'Module:Sports attendance/styles.css' }
	}
    
    -- 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']['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']['average'] = mm._round(mm._average(unpack(team_list['league'].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, true) and not yesno(#team_list[b].attendance, true)) or team_list[a].average == team_list[b].average then return team_list[a].name < team_list[b].name end -- sort by alphabetical order
        
        -- The team with no attendance is placed lower
        if not yesno(#team_list[a].attendance, true) then return false end
        if not yesno(#team_list[b].attendance, true) 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')
    
    -- Create table header
    table.insert(t, '{| class="wikitable sortable" style="text-align:right;"\n')
    table.insert(t, '!width=25|<abbr title="Position">Pos</abbr>\n')
    table.insert(t, '!width=185|Team\n')
    table.insert(t, '!width=25|<abbr title="Home matches played">Pld</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'
        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 team_list[tname].name)..'\n') -- Team name or table footer row name
        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')
		-- No newline at end of {{change}} for note to be tacked on
		if yesno(Args['previous_'..tname], true) then
			if yesno(#team_list[tname].attendance, true) then -- Checking attendance list instead of average since 0 attendance with matches is possible
	        	table.insert(t, '| '..(any and frame:expandTemplate{title='change', args={Args['previous_'..tname], team_list[tname].average, disp='out', dec=1}}))
			else
				table.insert(t, '| style="text-align:center" | ')
			end
        else
        	table.insert(t, '| style="text-align:center" | n/a')
        end
        if yesno(Args['note_'..tname], true) then
            table.insert(t, frame:expandTemplate{title='efn', args={group='lower-alpha', Args['note_'..tname]}})
		end
		table.insert(t, '\n') -- end change cell
    end

	-- Close table
	table.insert(t, '|}')
    
    -- Create footer
	local note_list = {}
    if yesno(Args['updated'], true) then
        table.insert(note_list, 'Updated to games played on '..Args['updated']..'.')
    end
	
    if yesno(Args['source'], true) then
        table.insert(note_list, 'Source: '..Args['source'])
	else
		table.insert(note_list, 'Source: '..frame:expandTemplate{title='Citation needed', args={date=lang:formatDate('F Y')}}..'\n')
    end
	local t_footer = '<div class="sports-attendance-notes">'..table.concat(note_list, ' ')..'</div>'..frame:expandTemplate{title='notelist', args={group='lower-alpha'}}

	return templatestyles..'\n'..table.concat(t)..t_footer
end

return p