Jump to content

Module:Country population

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Jts1882 (talk | contribs) at 07:25, 10 December 2019 (create module based on my sandbox version (all my edits)). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
require('Module:No globals')
local fn = require('Module:Formatnum')
local mm = require('Module:Math')
local p ={}
local pargs ={}

p.main = function(frame) -- called from template
	pargs = frame:getParent().args
	local output 

	if output then
		return frame:preprocess(output)
	end
	
   return p.errormsg("No valid option for transclusion")
end

function p.populations(frame)
    local args = frame.args
    local page = "List of countries by population (United Nations)"
	local output = ""
	local data = {}
	local total = 0
	local totalProjected = 0
	local count = 0
	local title = mw.title.new( page) -- , ns)  -- creates object if page doesn't exist (and valid page name)
	                                            --TODO: could use mw.title.makeTitle(), but that needs ns
	if title and title.exists then 
		local content = title:getContent()

		local pattern = "<section begin=date_1[ ]*/>(.-)<section end=date_1[ ]*/>"
		for value in string.gmatch( content , pattern ) do
			data['date']=value                                    -- date of latest data 
		end
		local pattern = "<section begin=date[ ]*/>(.-)<section end=date[ ]*/>"
		for value in string.gmatch( content , pattern ) do
			data['date2']=value                                    -- date of previous data 
		   data['date2']=mw.getContentLanguage():formatDate('j F Y', value)
		end		
		data['today'] = mw.getContentLanguage():formatDate('j F Y')      -- today's date (for formatting see https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time)

        local ay =  (frame:callParserFunction{ name = '#time', args = { "U", data['today'] } }
                   - frame:callParserFunction{ name = '#time', args = { "U", data['date2'] } })
                       /60/60/24/365.2425 -- number of years since first date until today‬


		for k,v in pairs(args) do
			local country = mw.text.trim(v)
			
			-- get population data from section 
		    local section = country .. "_1"
			local pattern = "<section begin="..section.."[ ]*/>(.-)<section end="..section.."[ ]*/>"

			for value in string.gmatch( content , pattern ) do
			    if value then 
			    	count=count+1
			    	data[count] = {}
			        data[count]['country'] = country
					data[count]['populationString'] = frame:preprocess(value)
					local raw = string.gsub(data[count]['populationString'], ",", "") -- strip formatting from number string
                    data[count]['populationNumber'] = tonumber(raw)
                    total = total + data[count]['populationNumber']
                    
                    local section = country .. "_0"
		           	local pattern2 = "<section begin="..section.."[ ]*/>(.-)<section end="..section.."[ ]*/>"
		           	for value2 in  string.gmatch( content , pattern2 ) do
						data[count]['populationString2'] = frame:preprocess(value2)
						local raw = string.gsub(data[count]['populationString2'], ",", "") -- strip formatting from number string
	                    data[count]['populationNumber2'] = tonumber(raw)
	                    data[count]['populationIncrement']=data[count]['populationNumber'] - data[count]['populationNumber2']
	                    data[count]['populationGrowth'] =data[count]['populationIncrement']/data[count]['populationNumber2']
	                    data[count]['populationDouble'] = math.log( 2 ) / math.log(1 + data[count]['populationGrowth'])

	                    data[count]['populationProjected'] = math.pow(data[count]['populationNumber2'], 1 - ay ) 
	                                                       * math.pow(data[count]['populationNumber'], ay)
	                    totalProjected = totalProjected + data[count]['populationProjected'] 
	                end
				end
			end
		end
		
        local sort_function = function( a,b )
		    if (tonumber(a.populationNumber) > tonumber(b.populationNumber)) then                -- primary sort on 'population' -> a before b
		        return true
		    end
		end
		local test = "test: " 
		local number=5435.12345 
		test= 	fn.formatNum(5435.12345,"en",0)
		--test=   frame:expandTemplate{ title = "formatnum", args = { totalProjected ,"en",0 } }
		--test=frame:callParserFunction{ name = 'formatnum', args = { totalProjected, decs=2 } }
		
        table.sort(data, sort_function)
        
        local i = 1
        -- output table
        output = '{| class="wikitable sortable" style="text-align:right;" ' 
                  .. '\n!rowspan=2|#'
                  .. '\n!rowspan=2|Country'
                  .. '\n!rowspan=2|Projected population<br/>(' .. data['today'] .. ')' 
                  .. '\n!rowspan=2|Pct of total'
                  .. '\n!rowspan=2|Population<br/>(' .. data['date'] .. ')' 
                  --.. '\n!rowspan=2|Pct of total'
                  .. '\n!rowspan=2|Previous Population<br/>(' .. data['date2'] .. ')'
                  .. '\n!colspan=2|Annual growth'
                  .. '\n!rowspan=2|Doubling time<br/>(years)'
                  .. '\n|-\n!Increment'
                  .. '\n!Rate'                  
        while (data[i]) do
           output = output .. '\n|-\n|' ..  i 
           output = output .. '\n|style="text-align:left;" |' .. frame:expandTemplate{ title = "flagcountry", args = {data[i]['country'] }  }
           output = output .. '\n| ' .. mm._precision_format(data[i]['populationProjected'],0)  
           --output = output .. '\n| ' .. fn.formatNum(data[i]['populationProjected'],"en",0)  
           output = output .. '\n| ' .. mm._precision_format(data[i]['populationProjected']/totalProjected*100,2) .. "%" -- projected
           output = output .. '\n| ' .. data[i]['populationString'] 
           --output = output .. '\n| ' .. fn.formatNum(data[i]['populationNumber']/total*100,"en",2) .. "%"
           output = output .. '\n| ' .. data[i]['populationString2'] 
           output = output .. '\n| ' .. mm._precision_format(data[i]['populationIncrement'],0) 
           output = output .. '\n| ' .. mm._round(data[i]['populationGrowth']*100,2) .. "%"
           output = output .. '\n| ' .. mm._round(data[i]['populationDouble'],0)
           i=i+1
        end
                
        output = output .. '\n|-\n! !! Total' 
                        .. '\n! style="text-align:right;" |' .. fn.formatNum(mm._round(totalProjected,0),"en",0) 
                        .. '\n! style="text-align:right;" | 100% '
                        .. '\n! style="text-align:right;" |' .. fn.formatNum(total,"en",0) 
                        --.. '\n! style="text-align:right;" | 100% '
                        .. '\n! || || ||' -- ..test
        output = output .. '\n|}'
    else
    	return  '<span class="error">No page title found</span>'
	end

   
   
   
   return output
end

function p.firstToUpper(str)
    return (str:gsub("^%l", string.upper))
end
p.errormsg = function (message)
	return '<span class="error">' .. message .. '</span>' 
end	

return p