Модуль:Statistical/Test

«Википеди» ирĕклĕ энциклопединчи материал

Для документации этого модуля может быть создана страница Модуль:Statistical/Test/doc

local p = {}

local ABCmain = mw.loadData("Модуль:Statistical/Test/ABC0")

local function First_less_Second(a, b)  
    local LenA = mw.ustring.len(a)
    local LenB = mw.ustring.len(b)
    for i = 1, (LenA < LenB) and LenA or LenB do
        if mw.ustring.codepoint(a, i, i) ~= mw.ustring.codepoint(b, i, i) then
            return mw.ustring.codepoint(a, i, i) < mw.ustring.codepoint(b, i, i) 
        end
    end
    return LenA < LenB
end  

local function internalFormatNumber(a_number, a_decimalMark, a_groupMark, a_groupMinLength, a_groupOnlyIntegerPart)
    -- find the decimal point
    local decimalPosition = mw.ustring.find(a_number, ".", 1, true);
    local needsGrouping = false;
    local DIGIT_GROUPING_SIZE = 3
    if (not decimalPosition) then
        -- no decimal point - integer number
		decimalPosition = mw.ustring.len(a_number) + 1;
		if (decimalPosition > a_groupMinLength) then
			needsGrouping = true;
		end
	else
		-- decimal point present
		if ((decimalPosition > a_groupMinLength) or (((mw.ustring.len(a_number) - decimalPosition) > DIGIT_GROUPING_SIZE) and (not a_groupOnlyIntegerPart))) then
			needsGrouping = true;
		end
		-- replace the decimal point
		a_number = mw.ustring.sub(a_number, 1, decimalPosition - 1) .. a_decimalMark .. mw.ustring.sub(a_number, decimalPosition + 1);
	end
	if (needsGrouping and (decimalPosition > DIGIT_GROUPING_SIZE + 1)) then
		-- grouping of integer part necessary
		local i = decimalPosition - DIGIT_GROUPING_SIZE;
		while (i > 1) do
			-- group the integer part
			a_number = mw.ustring.sub(a_number, 1, i - 1) .. a_groupMark .. mw.ustring.sub(a_number, i);
			decimalPosition = decimalPosition + mw.ustring.len(a_groupMark);
			i = i - DIGIT_GROUPING_SIZE;
		end
	end
	-- skip to the end of the new decimal mark (in case it is more than one char)
	decimalPosition = decimalPosition + mw.ustring.len(a_decimalMark) - 1;
	if (a_groupOnlyIntegerPart) then
		needsGrouping = false;
	end
	if (needsGrouping and ((mw.ustring.len(a_number) - decimalPosition) > DIGIT_GROUPING_SIZE)) then
		-- grouping of fractional part necessary
		-- using negative numbers (index from the end of the string)
		local i = decimalPosition - mw.ustring.len(a_number) + DIGIT_GROUPING_SIZE;
		while (i <= -1) do
			-- group the fractional part
			a_number = mw.ustring.sub(a_number, 1, i - 1) .. a_groupMark .. mw.ustring.sub(a_number, i);
			i = i + DIGIT_GROUPING_SIZE;
		end
	end
	return a_number;
end

-- from de:Modul:FormatNum
function formatNum(number)    
	if (number) then
        number = tostring(number)
		format = {decimalMark = ",", groupMark = " ", groupMinLength = 5, groupOnlyIntegerPart = true}
		-- lua can parse the number (first check passed) and format entry found
		local sign = mw.ustring.sub(number, 1, 1);
		if ((sign == "+") or (sign == "-")) then
			-- remove sign from number, add it later again
			number = mw.ustring.sub(number, 2);
		else
			-- was not a sign
			sign = "";
		end
		if (mw.ustring.sub(number, 1, 1) == ".") then
			-- number begins with "." -> add a 0 to the beginning
			number = "0" .. number;
		else
			if (mw.ustring.sub(number, -1) == ".") then
				-- number ends with "." -> remove it
				number = mw.ustring.sub(number, 1, -2);
			end
		end
		if ((number == mw.ustring.match(number, "^%d+$")) or (number == mw.ustring.match(number, "^%d+%.%d+$"))) then
			-- number has valid format (only digits or digits.digits) -> format it and add sign (if any) again
			number = sign .. internalFormatNumber(number, format.decimalMark, format.groupMark, format.groupMinLength, format.groupOnlyIntegerPart);
		else
			-- number has no valid format -> undo all modifications
			number = a_frame.args["number"];
		end
	end	   
	return number;
end

function p.GetStat(frame)

--    local args = frame:getParent().args
    local args = frame.args
    
    if args == nil then return "Введите название объекта АТД" end
    local PlaceName = args[1]

    if PlaceName == nil then return "Введите название объекта АТД" end
    PlaceName = mw.text.trim(PlaceName)
    
    local NumABC = nil
    -- ё = е , так как по соглашению их не различают при сортировке
    local PlaceEEE = mw.ustring.gsub (PlaceName, "ё", "е")
	PlaceEEE = mw.ustring.gsub (PlaceEEE, "Ё", "Е")
	PlaceEEE = mw.ustring.gsub (PlaceEEE, "-", "")
	
--	do return  First_less_Second("Сельское поселение «Село Ильинское» (Малоярославецкий район)", "Сельское поселение Званновский сельсовет"), "Сельское поселение «Село Ильинское» (Малоярославецкий район)"< "Сельское поселение Званновский сельсовет" end
--	do return  First_less_Second("Сельское поселение ", "Сельское посе-ление"), "Сельское поселение "< "Сельское посе-ление" end
--	do return  First_less_Second("Сельское поселение ", "Сёльс"), "Сельское поселение "< "Сёльс" end
		
    for k, v in pairs(ABCmain) do 
    	-- mw.ustring.lower для регистроНЕзависимого сравнения
        if First_less_Second(mw.ustring.lower(PlaceEEE), mw.ustring.lower(v)) then break else NumABC = k end
    end    
    
    if NumABC == nil then return "[[Категория:Википедия:Статьи с неправильными параметрами шаблона Население]]" end

local ABCPage = mw.loadData("Модуль:Statistical/Test/ABC"..NumABC)

    if ABCPage[PlaceName] == nil then return "#Н/Д"..frame:callParserFunction{name = '#tag:ref', args = {PlaceName .." > Данные не обнаружены. Возможно страница переименовывалась. Проверьте справочник[[Категория:Википедия:Статьи с неправильными параметрами шаблона Население]]"}} end
    local RegionData = mw.loadData("Модуль:Statistical/Test/"..ABCPage[PlaceName][1])
    local PlaceData = RegionData[ABCPage[PlaceName][2]]
    if PlaceData == nil then return "#Н/Д"..frame:callParserFunction{name = '#tag:ref', args = {PlaceName .." > Данные не обнаружены. Возможно страница переименовывалась. Проверьте справочник[[Категория:Википедия:Статьи с неправильными параметрами шаблона Население]]"}} end
    local Format = mw.text.trim ( (args[2] or "Таблица"))
    
    local LastRecord = 0
    for k in pairs(PlaceData) do LastRecord = LastRecord + 1 end
    local NumRecord = LastRecord
    
local function FormatY()    
    return PlaceData[NumRecord][1]
end

local function FormatN()    
    return PlaceData[NumRecord][2]
end

local function FormatS(SourceType)  
    if PlaceData[NumRecord][3] == "" then
        return ""
    else
        local Source1
        local Source2 
        if string.find(PlaceData[NumRecord][3],"%d%d%d%d")==1 then
            Source1 = RegionData['Источники'][PlaceData[NumRecord][3]][1]
            Source2 = PlaceData[NumRecord][3]
        else
            Source1 = PlaceData[NumRecord][3]
            Source2 = ""
        end
        if string.find(Source1, "http://")==1 then
            Source1 = '['..Source1..']'
        end
		if SourceType == "и" then
			return Source1
		end
        if Source2 == "" then
            return frame:callParserFunction{name = '#tag:ref', args = {Source1}}
        else
            return frame:callParserFunction{name = '#tag:ref', args = {Source1, name = Source2}}
        end
    end
end        

local function FormatF()    
    return formatNum(PlaceData[NumRecord][2])    
end

local function FormatT()    
    if NumRecord > 1 then
        if PlaceData[NumRecord][2] > PlaceData[NumRecord - 1][2] then
            return "<span style='color: #0c0; font-weight:bold; font-size: larger;'>↗</span>" 
        elseif PlaceData[NumRecord][2] < PlaceData[NumRecord - 1][2] then
            return "<span style='color: red; font-weight:bold; font-size: larger;'>↘</span>"  
        else
            return "<span style='color:#0AF;'>→</span>"  
        end
    else
        return ""
    end            
end

    if Format == 'Год' or Format == 'г' then
        return FormatY()    
    elseif Format == 'Безформат' or Format == 'Число' or Format == 'ч'  then
        return FormatN()    
    elseif Format == 'Ссылка' or Format == 'с'  then
        return FormatS("с")    
    elseif Format == 'Источник' or Format == 'и'  then
        return FormatS("и")    
    elseif Format == 'Формат' or Format == 'ф'  then
        return FormatF()    
    elseif Format == 'Формат' or Format == 'фс'  then
        return FormatF()..FormatS()    
    elseif Format == 'ФорматСсылкаГод' or Format == 'фсг'  then
        return FormatF()..FormatS().." ("..FormatY()..")"
    elseif Format == 'Тренд' or Format == 'т'  then
        return FormatT()..FormatF()    
    elseif Format == 'Значение' or Format == 'ТрендСсылка' or Format == 'тс'  then
        return FormatT()..FormatF()..FormatS()
    else
        -- Формироание HTML-таблицы
        local HtmlBuilder = require('Модуль:HtmlBuilder')    
        local HTML = HtmlBuilder.create('table')
    
        local MaxData
        if args['Столбцов'] then
            Column = tonumber(args['Столбцов'])
        else
            MaxData = (PlaceData[1][2] > PlaceData[LastRecord][2]) and PlaceData[1][2] or PlaceData[LastRecord][2]
            if MaxData < PlaceData[math.floor((LastRecord + 1) / 2)][2] then MaxData = PlaceData[math.floor((LastRecord + 1) / 2)][2] end
            if MaxData < 10 then Column = 15 
            elseif MaxData < 100 then Column = 12 
            elseif MaxData < 1000 then Column = 12
            elseif MaxData < 10000 then Column = 12
            elseif MaxData < 100000 then Column = 10
            elseif MaxData < 1000000 then Column = 10
            elseif MaxData < 10000000 then Column = 8
            elseif MaxData < 100000000 then Column = 8
            else Column = 7 end
            if Column > LastRecord then Column = LastRecord end
        end

        if args['Оформление'] ~= nil then
            HTML.attr('class', args['Оформление'])
        else
            if Column > 7 then HTML.attr('class', 'wide') else HTML.attr('class', 'standard') end
        end

        local TempRow
        local NumRow = 0
        TempRow = HTML.tag('th').attr('colspan', Column).wikitext(args['Заголовок'] or 'Численность населения')
        for i = 1, math.ceil(LastRecord / Column) do
            TempRow = HTML.tag('tr').addClass("bright")
            for j = 1, Column do
				NumRecord = (i - 1) * Column + j
                if PlaceData[NumRecord] == nil then
                    TempRow.tag('th').wikitext("")
                else
                    TempRow.tag('th').wikitext(FormatY()..FormatS("с"))
                end
            end
        
            TempRow = HTML.tag('tr').attr('align', 'center')
            for j = 1, Column do
				NumRecord = (i - 1) * Column + j
                if PlaceData[NumRecord] == nil then
                    TempRow.tag('td').wikitext("")
                else
                    TempRow.tag('td').wikitext(FormatT()..FormatF())
                end
            end
        end            
        return tostring(HTML)
    end
    return 1, Format
end

return p