Moduuli:VLK

Wikipediasta
Siirry navigaatioon Siirry hakuun

Moduuli tuottaa automaattisesti päivittyvän tulosseurantataulukon tietyn vuoden välityslautakuntavaalista.

Huom. Vaikka moduulin avulla voi seurata äänestyksen etenemistä, on vaalin lopputulos syytä tarkastaa manuaalisesti sekä kunkin ehdokkaan äänimäärän että ehdokkaiden keskinäisen järjestyksen osalta.

Käyttö:

{{#invoke:VLK | tulosseuranta | vuosi = | yksiv = | selitys = | man = }}

Esimerkkejä:
{{#invoke:VLK|tulosseuranta|vuosi=2018}}
{{#invoke:VLK|tulosseuranta|vuosi=2018|selitys=ei}}
{{#invoke:VLK|tulosseuranta|vuosi=2018|selitys=kyllä}}

Kaksi ensimmäistä esimerkkiä toimivat täsmälleen samalla tavalla. Kolmannessa esimerkissä moduuli lisää tulostaulukon alapuolelle selityksen siitä, mitä taulukossa käytetyt taustavärit merkitsevät.

Apua manuaalisen tulostaulukon luomiseen saa käyttämällä parametria man, jonka arvolla vain moduuli tulostaa ainoastaan manuaalisen tulostaulukon laatimisessa tarvittavan osuuden. Jos parametria man ei käytetä lainkaan tai sille annetaan arvo ei, tällaista osuutta ei tulosteta. Toisaalta jos parametrille man annetaan mikä tahansa muu arvo kuin ei tai vain (esimerkiksi k tai kyllä), moduuli generoi sekä kokonaisen automaattisen tulostaulukon että manuaalisen taulukon päivittämisessä auttavan osuuden. Esimerkkejä:

{{#invoke:VLK|tulosseuranta|vuosi=2018|man=vain}}
{{#invoke:VLK|tulosseuranta|vuosi=2018|selitys=kyllä|man=kyllä}}
{{#invoke:VLK|tulosseuranta|vuosi=2018|selitys=ei|man=ei}}

Jos vaalissa valitaan varsinaisia jäseniä yksivuotiskausille, voi tällaisten paikkojen lukumäärän välittää moduulille parametrin yksiv avulla. Esimerkiksi seuraavat moduulikutsut olisivat toimineet vuosien 2007 ja 2010 äänestyksissä:

{{#invoke:VLK|tulosseuranta|vuosi=2007|yksiv=5|selitys=kyllä}}
{{#invoke:VLK|tulosseuranta|vuosi=2010|yksiv=1|selitys=kyllä}}


local p = {}

function p.tulosseuranta(frame)
	assert(frame.args['vuosi'], 'Vuosi tarvitaan.')
	local vuosi = mw.text.trim(frame.args['vuosi'])

	-- Haetaan äänestyssivun sisältö. 
    local title = mw.title.new('Välityslautakunta/Äänestys_' .. vuosi, 'Wikipedia')
	local aineisto = title:getContent()
	assert(title, 'Valitettavasti sivun sisällön hakeminen ei onnistunut (virhe 1)')
	assert(aineisto, 'Valitettavasti sivun sisällön hakeminen ei onnistunut (virhe 2)')

	-- Jos on annettu argumentti selitys (eikä sen arvo ole 'ei'), 
	-- lisätään mukaan värien selitykset.
	local selitykset
	if frame.args['selitys'] == nil or frame.args['selitys'] == 'ei' or 
			frame.args['selitys'] == '' then
		selitykset = false
	else
		selitykset = true
	end

	-- Jos on annettu argumentti man (eikä sen arvo ole 'ei'), 
	-- lisätään loppuun tuloste, joka auttaa manuaalisesti 
	-- päivitettävän taulukon teossa.
	local manuaali
	if frame.args['man'] == nil or frame.args['man'] == 'ei' or 
			frame.args['man'] == '' then
		manuaali = 0
	elseif frame.args['man'] == 'vain' then
		manuaali = 2
	else
		manuaali = 1
	end

	-- Jos on annettu argumentti yksiv (eikä sen arvo ole 'ei'), 
	-- otetaan huomioon yksivuotiskaudelle varsinaisiksi jäseniksi 
	-- valittavien määrä.
	local yksivuotiset
	if frame.args['yksiv'] == nil or frame.args['yksiv'] == 'ei' or 
			frame.args['yksiv'] == '' then
		yksivuotiset = 0
	else
		yksivuotiset = tonumber(mw.text.trim(frame.args['yksiv']))
	end

	local alku, loppu, i, w, tunnus, sija, rivi, edellisen_rivin_aanet, joku
	local ehdokasmaara, aanimaara 
    local result = ''
    local erikoismerkki = 'k_O_m_M_e_r@VeN_k@@@kHi'
	local aanijono = 'Äänet|'
	local tulosrivit = '\n\n\n'
    local aanestajat = ''
    local ehdokkaat = {}
    local joku_nollilla = false
    
	-- Poistetaan kaikki piilokommentit.
    aineisto = string.gsub(aineisto, '<%!%-%-.-%-%->', '' )

	-- Luokkamerkinnät seilaavat välillä äänten keskelle ja 
	-- aiheuttavat hankaluuksia, joten poistetaan ne. 
    aineisto = string.gsub(aineisto, '\n[^#]-%[%[Luokka:[^\n]-\n', '\n' )

	-- Ehdokkaiden äänestysosioiden hakeminen luonnistuu varmemmin, 
	-- kun ne erotetaan toisistaan erikoisella merkinnällä.
	aineisto = string.gsub(aineisto,'{{V[^\n]-lityslautakuntaehdokas', 
		'\n' .. erikoismerkki .. '\n{{Välityslautakuntaehdokas')
	aineisto = aineisto .. erikoismerkki .. '\n\n\n'
	-- Vältetään hylättyjen äänten laskeminen.
	aineisto = string.gsub(aineisto,'\n=[^\n]-[Hh]yl.-t[^\n]-=.-' .. erikoismerkki, erikoismerkki)

    -- Etsitään äänestyssivulla ensimmäisenä olevan ehdokkaan osiota.
    alku, loppu = string.find(aineisto, '\n{{V.-lityslautakuntaehdokas[^\n]-|%s-' 
    	.. vuosi .. '%s-|.-\n{{V.-lityslautakuntaehdokas[^\n]-|')

	if alku == nil or loppu == nil then
		return 'Äänestyssivulta ei löytynyt yhtään ehdokasta tai sivulla oli ainoastaan yksi ehdokas!'
	end

	ehdokasmaara = 0
	aanimaara = 0

	-- Haetaan ehdokkaiden tiedot tauluun. 
    for w in string.gfind(aineisto, '({{V.-lityslautakuntaehdokas.-|%s-' 
    	.. vuosi ..'%s-|.-)' .. erikoismerkki) do

		-- haetaan ehdokkaan käyttäjätunnus
		_, _, tunnus = string.find(w, '{{V.-lityslautakuntaehdokas.-|%s-' 
			.. vuosi .. '%s-|%s-([^\n]-)%s-[|}]')
	
		-- Lasketaan montako ääntä ehdokas on saanut (laskeminen tapahtuu gsubin 
		-- suorittamien korvaustoimintojen lukumäärän perusteella).
		i = select(2, string.gsub(w,'\n#[^#:][^\n]-kuuta', ''))
		aanimaara = aanimaara + i
		ehdokasmaara = ehdokasmaara + 1

	    table.insert(ehdokkaat,{tunnus,i})
	    aanijono = aanijono .. 'a' .. i .. 'b|'

		-- Lisätään aanestajat-merkkijonoon sellaiset käyttäjätunnukset, 
		-- jotka ovat käyttäneet ääntään mutta eivät ole merkkijonossa
		-- ennestään. Peruutettuja ääniä ei huomioida (ja hylätyt on  
		-- jo sivuutettu muissa vaiheissa). 
		for joku in string.gfind(w,'\n#[^#:][^\n]-%[%s-([^%[\n][^\n]-)%s-[%|%]]', '') do
			-- Huom. Jos merkkijono "joku" sisältää Luan erikoismerkkejä, 
			-- lisätään ulompaa gsubia varten %-merkki niiden eteen, jotta 
			-- erikoismerkit eivät sekoita hakua.
			i = select(2, string.gsub(aanestajat, 
				joku:gsub('([%(%)%%%.%+%-%*%[%]%?])', '%%%1') .. '#', '')) 
			if i == 0 then
				aanestajat = aanestajat .. joku .. '#'
			end
		end
    end

	-- Järjestetään ehdokkaat ensisijaisesti äänimäärän ja 
	-- toissijaisesti aakkosjärjestyksen mukaan.
	table.sort(ehdokkaat, 
		function(a,b) return (a[2] > b[2]) or ((a[2] == b[2]) and (a[1] < b[1])) end)
	--table.sort(ehdokkaat, function(a,b) return a[2] > b[2] end)

	-- Muodostetaan tulostaulukon alkuosa. 
	result = result .. '<table class="wikitable sortable" width="470px">'
	result = result .. '<tr>'
    result = result .. '<th style="background-color: #A7E9F7">Ehdokas</th>'
    result = result .. '<th style="background-color: #A7E9F7" class="unsortable">Linkit</th>'
	result = result .. '<th style="background-color: #A7E9F7">Äänet</th>'
    result = result .. '<th style="background-color: #A7E9F7" class="unsortable">Huomiot</th></tr>'

	edellisen_rivin_aanet = 0
	rivi = 0
	sija = 1

	for _, w in ipairs(ehdokkaat) do
		rivi = rivi + 1
		if w[2] ~= edellisen_rivin_aanet then
			sija = rivi
		end

		if w[2] == 0 then
			joku_nollilla = true
			result = result .. '<tr style="background-color: #CCCCCC">'
			tulosrivit = tulosrivit .. ' {{VLK-tulosrivi|' .. w[1] .. '|entinen|'
		elseif sija < 6 then
			result = result .. '<tr style="background-color: #9BFBBB">'
			tulosrivit = tulosrivit .. ' {{VLK-tulosrivi|' .. w[1] .. '|2v|'
		elseif yksivuotiset > 0 and sija < (yksivuotiset + 6) then
			result = result .. '<tr style="background-color: #D2FEE1">'
			tulosrivit = tulosrivit .. ' {{VLK-tulosrivi|' .. w[1] .. '|1v|'
		else
			result = result .. '<tr style="background-color: #EDF7F6">'
			tulosrivit = tulosrivit .. ' {{VLK-tulosrivi|' .. w[1] .. '|vara|'
		end
		tulosrivit = tulosrivit .. w[2]
		
		-- Lisätään ehdokkaaseen liittyvät linkit tulostaulukkoon.
		result = result .. '<td align="left">[[K%C3%A4ytt%C3%A4j%C3%A4:' .. w[1] .. '|' .. w[1] .. ']]</td>'
		result = result .. '<td align="center">[[Wikipedia:V%C3%A4lityslautakunta/%C3%84%C3%A4nestys_' 
		result = result .. vuosi .. '#' .. w[1] .. '|äänestys]]' .. ' / '
		result = result .. '[[Wikipedia:V%C3%A4lityslautakunta/%C3%84%C3%A4nestys_' 
		result = result .. vuosi .. '/Keskustelu_ehdokkaasta_' .. w[1] .. '|keskustelu]]</td>'
		-- Lisätään ehdokkaan keräämä äänimäärä tulostaulukkoon.
		result = result .. '<td align="center">' .. w[2] .. '</td>'

		-- Katsotaan, onko kyse tasasijasta (kunkin ehdokkaan äänimäärä 
		-- on tallessa merkkijonossa aanijono. Lasketaan äänimäärän w[2]
		-- esiintymiskertojen lkm gsubin suorittamien korvaustoimintojen
		-- lukumäärän perusteella).
		i = select(2, string.gsub(aanijono, '|a' .. w[2] .. 'b', ''))
		
		if i == nil then 
			i = 0
		end

		if i < 2 then
			result = result ..'<td align="center"></td></tr>'
			tulosrivit = tulosrivit .. '}}\n'
		else 
			result = result ..'<td align="center">Jaettu ' .. sija .. '. sija</td></tr>'
			tulosrivit = tulosrivit .. '|Jaettu ' .. sija .. '. sija}}\n'
		end

		edellisen_rivin_aanet = w[2]
	end
	
    result = result .. '</tr></table>'

	-- Lasketaan äänestäjien lukumäärä (laskeminen tapahtuu gsubin 
	-- suorittamien korvaustoimintojen lukumäärän perusteella).
	-- Merkkijonoon aanestajat eivät ole päätyneet tunnukset, jotka 
	-- ovat jättäneet ainoastaan hylättyjä tai peruttuja ääniä, ja  
	-- kunkin siinä olevan tunnuksen perässä on #-merkki.
	i = select(2, string.gsub(aanestajat,'#', ''))

	result = result .. '\nVähintään yhden ei-hylätyn äänen antaneiden '
	result = result ..  'tunnusten lukumäärä: ' .. i .. '\n'
	result = result .. '\nEhdokkaita: ' .. ehdokasmaara 
	result = result .. '. Hyväksyttyjen ei-peruttujen äänten kokonaismäärä: ' 
	result = result .. aanimaara .. '\n'

	if selitykset == true then
		result = result .. '<p></p><table class="wikitable" width="470px">'
		result = result .. '<tr>'
		result = result .. '<th style="background-color: #A7E9F7">Värien selitykset'
		result = result .. '</th></tr>'
	    result = result .. '<tr style="background-color: #9BFBBB">'
		result = result .. '<td align="center">menossa kaksivuotiskaudelle</td></tr>'
		if yksivuotiset > 0 then
			result = result .. '<tr style="background-color: #D2FEE1">'
			result = result .. '<td align="center">menossa yksivuotiskaudelle</td></tr>'
		end
		result = result .. '<tr style="background-color: #EDF7F6">'
		result = result .. '<td align="center">varajäseniksi yksivuotiskaudelle'
		if joku_nollilla == true then
			result = result .. '<tr style="background-color: #CCCCCC">'
			result = result .. '<td align="center">ei tulossa valituksi (ei ääniä)'
			result = result .. '</td></tr>'
		end
		result = result .. '</table>'
	end

	if manuaali == 1 then
		result = result .. tulosrivit
	end

	if manuaali == 2 then 
		return tulosrivit
	else
		return result
	end
end


return p