Questa pagina è protetta dallo spostamento
Questa pagina è protetta

Modulo:Sommastat

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca

Modulo in Lua per gestire le funzioni del template {{Sommastat}}


local p = {}

local reply = {}
local debug = {}

local sort_code = {
    ['-?'] = ' data-sort-value="-0.4"',
    ['-0+'] = ' data-sort-value="-0.3"',
    ['-'] = ' data-sort-value="-0.2"',
    ['-0'] = ' data-sort-value="-0.1"',
    ['?'] = ' data-sort-value="0.1"',
    ['0+]'] = ' data-sort-value="0.2"'
}

local function dump(t, ...)
    local args = {...}
    for _, s in ipairs(args) do
        table.insert(t, s)
    end
end

local function cell_color_toggle(cell_color)
    return (cell_color == '' and 'bgcolor=#F2F2F2') or ''
end

local function sumstring(value)
    -- Riceve una stringa contenente una somma della forma:
    -- a1+a2+a3...+an  dove ogni ai è numero opzionalmente preceduto da "-"
    -- e ne ritorna la somma
    local addendums = mw.text.split(value, '+', true)
    local sum = 0
    for _, addendum in ipairs(addendums) do
        _, _, a = string.find(addendum, '^(-?%d+)')
        if a then sum = sum + tonumber(a) end
    end
    return sum
end

-- =================================================================
-- Classe per accumulare le somme
-- =================================================================
local Sum = {}
Sum.__index = Sum

function Sum.new(is_reti, sum)
    return setmetatable({
        N = 0,
        n_interrogativi = 0,
        n_trattini = 0,
        is_reti = is_reti or false,
        n_interrogativi_minus = 0,
        n_zero_minus = 0,
        n_zero_plus = 0,
        n_zero_plus_minus = 0,
        do_sum = (sum == nil) or false,
        sum = sum or 0,
        end_plus = ''
     }, Sum)
end

function Sum:status()
    local sum_result
    if self.do_sum then
        sum_result = tonumber(self.sum)
    else
        sum_result = self.sum
    end
    return table.concat({
        'N: ' .. tostring(self.N),
        'n_interrogativi: ' .. tostring(self.n_interrogativi),
        'n_trattini: ' .. tostring(self.n_trattini),
        'is_reti: ' .. tostring(self.is_reti),
        'n_interrogativi_minus: ' .. tostring(self.n_interrogativi_minus),
        'n_zero_minus: ' .. tostring(self.n_zero_minus),
        'n_zero_plus:' .. tostring(self.n_zero_plus),
        'n_zero_plus_minus: ' .. tostring(self.n_zero_plus_minus),
        'do_sum: ' .. tostring(self.do_sum),
        'sum: ' .. sum_result,
        'end_plus: ' .. tostring(self.end_plus)
        }, '<br />')
end

function Sum.__tostring(self)
    if self.n_trattini == self.N then
        return '-' .. self.end_plus
    elseif self.n_interrogativi == self.N then
        return '?' .. self.end_plus
    elseif self.n_interrogativi_minus == self.N then
        return '-?' .. self.end_plus
    elseif self.n_trattini + self.n_zero_minus == self.N then
        return '-0' .. self.end_plus
    elseif (self.n_trattini + self.n_zero_minus + self.n_zero_plus + self.n_interrogativi_minus) == self.N then
        return '-0+'
    elseif self.do_sum then
        if self.n_interrogativi > 0 or self.n_interrogativi_minus > 0 then self.end_plus = '+' end
        return tostring(self.sum) .. self.end_plus
    else
        return self.sum
    end
end

function Sum:add(value)
    self.N = self.N + 1
    if string.match(value, "%+$") then self.end_plus = '+' end
    if self.is_reti then
        if value == '?' then
            self.n_interrogativi = self.n_interrogativi +1
            return
        elseif value == '-?' then
             self.n_interrogativi_minus =  self.n_interrogativi_minus + 1
        elseif value == '-' then
            self.n_trattini = self.n_trattini + 1
            return
        elseif value == '-0' then
            self.n_zero_minus = self.n_zero_minus + 1
            return
        elseif value == '-0+' then
            self.n_zero_plus = self.n_zero_plus + 1
            return
        end
    elseif value == '-' then
        self.n_trattini = self.n_trattini + 1
        return
    elseif value == '?' then
        self.n_interrogativi = self.n_interrogativi + 1
        return
    end
    if self.do_sum then
        self.sum = self.sum + (tonumber(value) or sumstring(value))
    end
end

setmetatable(Sum, { __call = function(_, ...) return Sum.new(...) end })
-- =================================================================
-- fine dichiarazione classe per somma
-- =================================================================

function p.sommastat(frame)
    -- Se chiamata mediante  #invoke, usa gli argomenti passati al template invocante.
    -- Altrimenti a scopo di test assume che gli argomenti siano passati direttamente
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame.args
    end

    local function nil_if_blank(s)
        if s and s == '' then return nil end
        return s
    end

    local skip_amm_esp = (origArgs.C == 'no') or false
    local data_cols = (skip_amm_esp and 2) or 4
    local pres = nil_if_blank(origArgs.pres)
    local reti = nil_if_blank(origArgs.reti)
    local amm = nil_if_blank(origArgs.amm)
    local esp = nil_if_blank(origArgs.esp)
    local cell_color = cell_color_toggle('')
    dump(reply, '')
    local sums = { Sum(false, pres), Sum(true, reti), Sum(false, amm), Sum(false, esp)}
    local i= 0
    local end_loop = false
    while not end_loop do
        if i > 3 then break end
        for j = 1, data_cols do
            local cell_value = origArgs[i*4+j]
            if cell_value == nil then
                -- se le colonne esaminate non sono una serie completa di 2 o 4 colonne aggiungi colonne vuote
                -- per mantenere l'allineamento dei dati della tabella
                end_loop= true
                cell_color = cell_color_toggle(cell_color)
                if j == 1 then break end
                for k = j, data_cols do
                    dump(reply, '<td ', cell_color, '>&nbsp;</td>')
                end
                break
            else
                cell_value = mw.text.trim(cell_value)
                dump(reply, '<td ', cell_color, (sort_code[cell_value] or ''), '>', cell_value, '</td>')
                sums[j]:add(cell_value)
            end
        end
        cell_color = cell_color_toggle(cell_color)
        i = i + 1
    end
    if sums[1].N > 1 then
        for j = 1, data_cols do
            local cell_value = tostring(sums[j])
            dump(reply, '<td ', cell_color, (sort_code[cell_value] or ''),  '>',  "'''", cell_value,  "'''</td>")
            -- output di debug
            --dump(reply, '<td ', cell_color, (sort_code[cell_value] or ''),  '>',  "'''", cell_value,  "'''" .. '<br />' .. sums[j]:status() .. '</td>')
        end
    end
    return table.concat(reply)
end

return p