Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

// request.cf · coarse context

A page that knows where it met you.

Only coarse request metadata is shown. This demo does not display or persist visitor IP addresses.

Country
US
Cloudflare location
CMH
Connection
HTTP/2
Language
Not provided

Ray ID: a44fa7507efda376

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'] = {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
			team_list[tname]['sort_name'] = Args['data_sort_value_name_'..tname] or team_list[tname].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 attendance stats for ranking
        	team_list[tname]['average'] = mm._average(unpack(attendance))
			team_list[tname]['median'] = mm._median(unpack(attendance))
			team_list[tname]['sum'] = mm._sum(unpack(attendance))
			team_list[tname]['max'] = mm._max(unpack(attendance))
			team_list[tname]['min'] = mm._min(unpack(attendance))
			team_list[tname]['range'] = (team_list[tname]['max'] or 0) - (team_list[tname]['min'] or 0)
        end
    end
    
    -- Compute league overall stats
    team_list['league']['average'] = mm._average(unpack(team_list['league'].attendance))
	team_list['league']['median'] = mm._median(unpack(team_list['league'].attendance))
	team_list['league']['sum'] = mm._sum(unpack(team_list['league'].attendance))
	team_list['league']['max'] = mm._max(unpack(team_list['league'].attendance))
	team_list['league']['min'] = mm._min(unpack(team_list['league'].attendance))
    
    -- Rank teams by average attendance
	table.sort(sorted_teams, function(a, b)
		-- If both teams do not have any attendance, sort alphabetically by sort_name
        if (not yesno(#team_list[a].attendance, true) and not yesno(#team_list[b].attendance, true)) then		return team_list[a].sort_name < team_list[b].sort_name
		end

		-- 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

		-- Sort by average if not identical
		if team_list[a].average ~= team_list[b].average then
			return team_list[a].average > team_list[b].average
		end

		-- Sort by median if not identical
		if team_list[a].median ~= team_list[b].median then
			return team_list[a].median > team_list[b].median
		end

		-- Sort by sum if not identical, to favour teams that have played more matches
		if team_list[a].sum ~= team_list[b].sum then
			return team_list[a].sum > team_list[b].sum
		end
			
		-- Sort by smaller range if not identical, to favour teams with more consistent attendance
		if team_list[a].range ~= team_list[b].range then
			return team_list[a].range < team_list[b].range
		end
        
        -- Otherwise, sort alphabetically by sort_name
        return team_list[a].sort_name < team_list[b].sort_name
    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(team_list[tname].sum) or '')..'\n')
        table.insert(t, '| '..(any and lang:formatNum(team_list[tname].max) or '')..'\n')
        table.insert(t, '| '..(any and lang:formatNum(team_list[tname].min) or '')..'\n')
        table.insert(t, '| '..(any and lang:formatNum(team_list[tname].median) or '')..'\n')
		table.insert(t, '| style="font-weight:bold" | '..(any and lang:formatNum(mm._round(team_list[tname].average, 0)) 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 match(es) 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