Module:Country population table

From IxWiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Country population table/doc

local p = {}

local lang = mw.language.getContentLanguage()

local function getPopulations(qid)
	-- Return table of all population or nil if none found.
	-- Each entry is a table { POP, TIMESTAMP } where POP is a number.
	local populations = {}
	local props = mw.wikibase.getAllStatements(qid, 'P1082')
	if not props then return nil end
	for _, v in pairs(props) do
		if v.qualifiers and v.qualifiers["P585"] then
			local timestamp = v.qualifiers["P585"][1].datavalue.value.time
			timestamp = timestamp:gsub("%-00%-00T", "-01-01T")
			if string.sub(timestamp, 1, 1) ~= '-' then
				populations[#populations + 1] = {
					tonumber(v.mainsnak.datavalue.value.amount),  -- number or nil
					tonumber(lang:formatDate('U',timestamp))  -- timestamp
				}
			end
		end
	end
	if next(populations) then  -- if table is not empty
		return populations
	end
	return nil
end

local function getPopEst(qid)
	local populations = getPopulations(qid)
	if not populations then return -1 end
	-- get the two most recent population counts
	local popCurrent, popPrevious, timeCurrent, timePrevious = -1, -1, -1, -1
	for i, v in ipairs(populations) do
		if v[2] > timeCurrent then
			popPrevious = popCurrent
			timePrevious = timeCurrent
			popCurrent = v[1]
			timeCurrent = v[2]
		elseif v[2] > timePrevious then
			popPrevious = v[1]
			timePrevious = v[2]
		end
	end
	if (timeCurrent > 0) and (timePrevious > 0) then
		local timeNow = lang:formatDate( 'U', nil, true )
		return math.floor(popCurrent + (popCurrent - popPrevious)/(timeCurrent - timePrevious)*(timeNow - timeCurrent) + 0.5)
	else
		return -1
	end
end

function p.row(frame)
    local function formatnum(num)
        return frame:callParserFunction{ name = 'formatnum', args = num }
    end
    local function flag(str)
    	return frame:expandTemplate{ title = 'flag', args = { str } }
    end
   	local args = frame.args
   	local res = ''
   	
    local argnums = {}
    for k, v in pairs( args ) do
		if type( k ) == 'number' and v ~= '' then
			argnums[#argnums + 1] = k
		end
	end
	table.sort(argnums)
	
	local wpop = getPopEst('Q2')
	
	for j = 1,#argnums do
		local country = args[argnums[j]]

		local qid = nil
		if country == nil or country == "" then 
			qid = mw.wikibase.getEntityIdForCurrentPage()
		else
			qid = mw.wikibase.getEntityIdForTitle(country)
		end
	
		local cpop = getPopEst(qid)

		if (cpop > 0) and (wpop > 0) then
			local pct = math.floor(1000*cpop / wpop + 0.5) / 10
			cpop = formatnum(cpop)
			res = res .. '|-\n|' .. flag(country) .. '||' .. cpop .. ' || ' .. lang:formatDate( 'd F Y', nil, true ) .. ' || ' .. pct .. '%\n'
		else
			res = res .. 'Error: Country = ' .. country .. ' Country population estimate = ' .. cpop .. ' World population estimate = ' .. wpop
		end
	end
	return res
end

return p