Пуштросэз вылэ выжоно

Модуль:DemographyStatistical

Мегавики-ысь

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

--- модуль генерации текста для раздела Демографии населенных пунктов

local p = {}

function p.getAgeDistributionText(frame)
    local entityId = mw.wikibase.getEntityIdForCurrentPage() or frame.args[1] -- Идентификатор элемента Wikidata
    local headers = {
        ['P42'] = '5 арес тырмымтэос', 
        ['P43'] = '5-ысен 9 аресозь', 
        ['P44'] = '10-ысен 14 аресозь', 
        ['P45'] = '15-ысен 19 аресозь',
        ['P46'] = '20-ысен 24 аресозь', 
        ['P48'] = '25-ысен 29 аресозь', 
        ['P49'] = '30-ысен 34 аресозь', 
        ['P52'] = '35-ысен 39 аресозь',
        ['P55'] = '40-ысен 44 аресозь', 
        ['P56'] = '45-ысен 49 аресозь', 
        ['P60'] = '50-ысен 54 аресозь', 
        ['P62'] = '55-ысен 59 аресозь',
        ['P63'] = '60-ысен 64 аресозь', 
        ['P64'] = '65-ысен 69 аресозь', 
        ['P67'] = '70-ысен 74 аресозь', 
        ['P68'] = '75-ысен 79 аресозь',
        ['P70'] = '80-ысен 84 аресозь'
    }
    local data = {}
    local populationText = ""

    -- Получение утверждений по свойству P1082 (население по возрастным группам)
    local statements1082 = mw.wikibase.getBestStatements(entityId, 'P1082')

    -- Если данных о населении по возрастным группам нет или они отсутствуют, вернуть сообщение об ошибке
    if not statements1082 or not next(statements1082) then
        return "" -- возрат пустой строки, если нет данных
    end

    -- Получение последнего доступного года с данными
    local latestYearWithData = p.getLatestYear(statements1082)

    -- Если год с данными найден
    if latestYearWithData > 0 then
        -- Получение данных о населении по возрастным группам для последнего года
        local yearData = {}
        for _, statement in ipairs(statements1082) do
            if statement.qualifiers and statement.qualifiers.P585 then
                local timeValue = statement.qualifiers.P585[1].datavalue.value
                if timeValue.time then
                    local year = tonumber(string.match(timeValue.time, '^%+(%d%d%d%d)'))
                    if year == latestYearWithData then
                        for propId, header in pairs(headers) do
                            local percent = 0
                            if statement.qualifiers[propId] then
                                percent = tonumber(statement.qualifiers[propId][1].datavalue.value.amount) or 0
                            end
                            table.insert(yearData, {header, percent})
                        end
                    end
                end
            end
        end
        data[latestYearWithData] = yearData
    end

	-- Формирование текста о распределении населения по возрастным группам
	if latestYearWithData > 0 then
	    populationText = "Арлыдзыя, улӥсьёс " .. latestYearWithData .. " арын ортчытэм лыдъян-чотан тодэтъёсъя тазьы люкиськизы: "
	    local ageRanges = {}
	    for _, entry in ipairs(data[latestYearWithData]) do
	        -- Проверка, является ли второй элемент числом
	        if tonumber(entry[2]) then
	            -- Преобразование второго элемента в число
	            local percentage = tonumber(entry[2])
	            if percentage > 0 then
	                -- Форматирование процентов с заменой точки на запятую и добавлением знака процента
	                local formattedPercentage = string.format("%.1f%%", percentage):gsub("%.", ",")
	                table.insert(ageRanges, entry[1] .. " — " .. formattedPercentage)
	            end
	        end
	    end
	    -- Используем запятую с пробелом в качестве разделителя
	    populationText = populationText .. table.concat(ageRanges, ", ") .. "."
	end

    -- Получение среднего возраста для последнего года с данными
	local averageAge = nil
	for _, statement in ipairs(statements1082) do
	    if statement.qualifiers and statement.qualifiers.P585 then
	        local timeValue = statement.qualifiers.P585[1].datavalue.value
	        if timeValue.time then
	            local year = tonumber(string.match(timeValue.time, '^%+(%d%d%d%d)'))
	            if year == latestYearWithData and statement.qualifiers.P4442 then
	                averageAge = tonumber(statement.qualifiers.P4442[1].datavalue.value.amount)
	                break
	            end
	        end
	    end
	end


    -- Добавление информации о среднем возрасте, если он доступен
    if averageAge then
    --populationText = populationText .. "\nУлӥсьёслэн шорлыко арлыдзы " .. string.format("%.1f%%", averageAge):gsub("%.", ",") .. " " .. p.getAgeWord(averageAge) .. "."
    populationText = populationText .. "\nУлӥсьёслэн шорлыко арлыдзы " .. averageAge .. " " .. p.getAgeWord(averageAge) .. "."

end

    return populationText
end

-- Получение последнего доступного года с данными
function p.getLatestYear(statements1082) 
    local latestYearWithData = 0
    for _, statement in ipairs(statements1082) do
        if statement.qualifiers and statement.qualifiers.P585 then
            local timeValue = statement.qualifiers.P585[1].datavalue.value
            if timeValue.time then
                local year = tonumber(string.match(timeValue.time, '^%+(%d%d%d%d)'))
                latestYearWithData = math.max(latestYearWithData, year)
            end
        end
    end
    
    return latestYearWithData
end

-- текст дохода
function p.getIncomeStatistics(frame)
    local entityId = mw.wikibase.getEntityIdForCurrentPage() or frame.args[1] -- Идентификатор элемента Wikidata

    -- Получение утверждений по свойству P1082 (доходы)
    local statements1082 = mw.wikibase.getBestStatements(entityId, 'P1082')

    -- Формирование строки с данными о доходах
    local incomeStatistics = "" -- возрат пустой строки, если нет данных

    if not statements1082 or not next(statements1082) then
        return ""
    end

    local avgHouseholdIncome = p.getPropertyValue(statements1082, 'P120', p.getLatestYear(statements1082))
    local avgFamilyIncome = p.getPropertyValue(statements1082, 'P99', p.getLatestYear(statements1082))
    local avgMaleIncome = p.getPropertyValue(statements1082, 'P100', p.getLatestYear(statements1082))
    local avgFemaleIncome = p.getPropertyValue(statements1082, 'P104', p.getLatestYear(statements1082))
    local avgIncomePerCapita = p.getPropertyValue(statements1082, 'P10622', p.getLatestYear(statements1082))
    local povertyIndex = p.getPropertyValue(statements1082, 'P107', p.getLatestYear(statements1082))
    if avgHouseholdIncome and avgFamilyIncome and avgMaleIncome and avgFemaleIncome and avgIncomePerCapita and povertyIndex then
        incomeStatistics = incomeStatistics ..
                            "Одӥг юртъер понна табышлэн шорлыдыз " .. mw.language.new('udm'):formatNum(avgHouseholdIncome) .. " " .. frame:preprocess("[[USD|США доллар ]],") .. " " ..
                            "нош одӥг семья понна табышлэн шорлыдыз — " .. mw.language.new('udm'):formatNum(avgFamilyIncome) .. " " .. p.getDollarsWord(avgFemaleIncome) ..". " ..
                            "Воргоронъёслэн табышсы араз шорлыдын " .. mw.language.new('udm'):formatNum(avgMaleIncome) .. " " .. p.getDollarsWord(avgMaleIncome) .. ", " .. mw.language.new('udm'):formatNum(avgFemaleIncome) .. " ".. p.getDollarsWord(avgFemaleIncome) .. " нылкышноослэн арскын поттэм шорлыко табышсылы пумит. " ..
                            frame:preprocess("[[Одӥг мурт понна поттэм табышлэн арскын шорлыдыз]]") .. " " .. mw.language.new('udm'):formatNum(avgIncomePerCapita) .. " ".. p.getDollarsWord(avgIncomePerCapita) .. " . " ..
                            "Татысь вань семьяослэн табышсы куанерлыко вадесгожлэсь вылынгес вал. " .. mw.language.new('udm'):formatNum(povertyIndex) .. " %-эз улӥсь калык лыдъян-чотан ортчытон дыръя ёрмыса улӥз. "
    end


    return incomeStatistics ~= "" and incomeStatistics or "" -- возрат пустой строки, если нет данных
end

-- текст процентности населения
function p.getPopulationText(frame)
    local entityId = mw.wikibase.getEntityIdForCurrentPage() or frame.args[1] -- Идентификатор элемента Wikidata
   
    -- Получение последнего доступного года с данными
	local latestYearWithData = 0
	local population = 0
	local sourceUrl = nil
	local statements1082 = mw.wikibase.getBestStatements(entityId, 'P1082')
	for _, statement in ipairs(statements1082) do
	    if statement.qualifiers and statement.qualifiers.P585 then
	        local timeValue = statement.qualifiers.P585[1].datavalue.value
	        if timeValue.time then
	            local year = tonumber(string.match(timeValue.time, '^%+(%d%d%d%d)'))
	            if year > latestYearWithData then
	                latestYearWithData = year
	                population = tonumber(statement.mainsnak.datavalue.value.amount)
	                local sources = statement.references
	                if sources then
	                    for _, source in ipairs(sources) do
	                        local sourceData = source.snaks.P854
	                        if sourceData and sourceData[1] and sourceData[1].datavalue.value then
	                            sourceUrl = mw.text.decode(sourceData[1].datavalue.value)
	                            break
	                        end
	                    end
	                end
	            end
	        end
	    end
	end

    -- Если год с данными найден
    if latestYearWithData > 0 then
        -- Создаем текст для вывода
        -- если есть источник, добавляем cite web через ref тэг
        local reference = ""
		if sourceUrl then
		    reference = '{{cite web |url='..sourceUrl..' |title='..sourceUrl..' |website= |access-date= | lang=}}'
		end
		local populationText = "Лыдъян-чотан тодэтъёсъя " .. latestYearWithData .. " арын" .. frame:extensionTag('ref', reference) .. " татын улӥз "

        -- Выводим данные о населении
        if population then
            populationText = populationText .. p.formatNumber(population) .. " " .. p.getPeopleWord(population) .. ", "
        end

        -- Получаем данные о количестве семей
        local families = p.getPropertyValue(statements1082, 'P3', latestYearWithData)
        if families then
            populationText = populationText .. p.formatNumber(families) .. " "..p.getFamilyWord(families) .. ", "
        end

        -- Получаем данные о количестве домашних хозяйств
        local households = p.getPropertyValue(statements1082, 'P1538', latestYearWithData)
        if households then
            populationText = populationText .. " лыдъяськиз ".. p.formatNumber(households) .. " " .. p.getHouseholdsWord(households) .. " но "
        end

        -- Получаем данные о количестве жилых домов
        local residentialBuildings = p.getPropertyValue(statements1082, 'P10814', latestYearWithData)
        if residentialBuildings then
            populationText = populationText .. p.formatNumber(residentialBuildings) .. " улоно ".. p.getResidentialBuildingsWord(residentialBuildings) .. ". "
        end

        -- Получаем данные о расовом составе населения
        populationText = populationText .. "Лыдъян-чотан тодэтъёсъя та улон интыысь расовый составез тазьы висъяськиз: "
        populationText = populationText .. p.getRaceComposition(entityId, latestYearWithData, frame)

        return populationText
    else
        return "" -- возрат пустой строки, если нет данных
    end
end

-- получение данных с утверждения по году
function p.getPropertyValue(statements, propertyId, year)
    for _, statement in ipairs(statements) do
        if statement.qualifiers and statement.qualifiers.P585 then
            local timeValue = statement.qualifiers.P585[1].datavalue.value.time
            local statementYear = tonumber(string.match(timeValue, '^%+(%d%d%d%d)'))
            if statementYear == year then
                if statement.qualifiers[propertyId] then
                    return tonumber(statement.qualifiers[propertyId][1].datavalue.value.amount)
                end
            end
        end
    end
    return nil
end


-- обязательно передать год
function p.getRaceComposition(entityId, year, frame)
    local raceComposition = ""

    -- белые
    local whitePercentage = p.getPropertyValue(mw.wikibase.getBestStatements(entityId, 'P1082'), "P24", year)
    if whitePercentage then
        raceComposition = raceComposition .. " " .. string.format("%.1f%%", whitePercentage):gsub("%.", ",") .. " " .. frame:preprocess("[[Расовый состав США|тӧдьы куо муртъёс]]") .. ","
    else
        raceComposition = raceComposition .. "."
    end
    
    -- коренные
    local rootPercentage = p.getPropertyValue(mw.wikibase.getBestStatements(entityId, 'P1082'), "P28", year)
    if rootPercentage then
        raceComposition = raceComposition .. " " .. string.format("%.1f%%", rootPercentage):gsub("%.", ",") .. " " .. frame:preprocess("[[Коренные народы|коренной американецъёс]]") .. ","
    else
        raceComposition = raceComposition .. "."
    end
    
    -- другие
    local otherPercentage = p.getPropertyValue(mw.wikibase.getBestStatements(entityId, 'P1082'), "P33", year)
    if otherPercentage then
        raceComposition = raceComposition .. " " .. string.format("%.1f%%", otherPercentage):gsub("%.", ",") .. " мукет йӧскалыкъёс."
    else
        raceComposition = raceComposition .. "."
    end
    
    -- процент испаноговорящих
    local spanishSpeakingPercentage = p.getPropertyValue(mw.wikibase.getBestStatements(entityId, 'P1082'), "P12", year)
    if spanishSpeakingPercentage then
        raceComposition = raceComposition .. " Испан кылын вераськисьёслэн лыдзы " .. string.format("%.1f%%", spanishSpeakingPercentage):gsub("%.", ",") .. "."
    else
        raceComposition = raceComposition .. "."
    end

    return raceComposition
end

-- function p.formatNumber(number)
--     return tostring(math.floor(number)):reverse():gsub("%d%d%d", "%1,"):reverse():gsub("^,", "")
-- end
function p.formatNumber(number)
    return tostring(math.floor(number)):reverse():gsub("%d%d%d", "%1 "):reverse():gsub("^%s+", "")
end


-- СКЛОНЕНИЯ START
function p.getFamilyWord(number)
    local lastTwoDigits = number % 100
    local lastDigit = number % 10

    if lastTwoDigits >= 11 and lastTwoDigits <= 14 then
        return 'семья'
    elseif lastDigit == 1 then
        return 'семья'
    elseif lastDigit >= 2 and lastDigit <= 4 then
        return 'семьяос'
    else
        return 'семья'
    end
end

function p.getHouseholdsWord(number)
    local lastTwoDigits = number % 100
    local lastDigit = number % 10

    if lastTwoDigits >= 11 and lastTwoDigits <= 14 then
        return 'юртъер'
    elseif lastDigit == 1 then
        return 'юртъер'
    elseif lastDigit >= 2 and lastDigit <= 4 then
        return 'юртъер'
    else
        return 'юртъер'
    end
end

function p.getPeopleWord(number)
    local lastTwoDigits = number % 100
    local lastDigit = number % 10

    if lastTwoDigits >= 11 and lastTwoDigits <= 14 then
        return 'мурт'
    elseif lastDigit == 1 then
        return 'мурт'
    elseif lastDigit >= 2 and lastDigit <= 4 then
        return 'мурт'
    else
        return 'мурт'
    end
end

function p.getResidentialBuildingsWord(number)
    local lastTwoDigits = number % 100
    local lastDigit = number % 10

    if lastTwoDigits >= 11 and lastTwoDigits <= 14 then
        return 'юрт'
    elseif lastDigit == 1 then
        return 'юрт'
    elseif lastDigit >= 2 and lastDigit <= 4 then
        return 'юрт'
    else
        return 'юрт'
    end
end

function p.getAgeWord(number)
    local lastTwoDigits = number % 100
    local lastDigit = number % 10

    if lastTwoDigits >= 11 and lastTwoDigits <= 14 then
        return 'ар'
    elseif lastDigit == 1 then
        return 'ар'
    elseif lastDigit >= 2 and lastDigit <= 4 then
        return 'ар'
    else
        return 'ар'
    end
end

function p.getDollarsWord(number)
    local lastTwoDigits = number % 100
    local lastDigit = number % 10

    if lastTwoDigits >= 11 and lastTwoDigits <= 14 then
        return 'доллар'
    elseif lastDigit == 1 then
        return 'доллар'
    elseif lastDigit >= 2 and lastDigit <= 4 then
        return 'доллар'
    else
        return 'доллар'
    end
end

-- СКЛОНЕНИЯ END

return p