<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ASandbox%2FAjuanca%2FGraphIt</id>
	<title>Module:Sandbox/Ajuanca/GraphIt - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ASandbox%2FAjuanca%2FGraphIt"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Sandbox/Ajuanca/GraphIt&amp;action=history"/>
	<updated>2026-05-01T00:39:08Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Sandbox/Ajuanca/GraphIt&amp;diff=145092&amp;oldid=prev</id>
		<title>imported&gt;Ajuanca: fix bug: skip arithmetic for nil val</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Sandbox/Ajuanca/GraphIt&amp;diff=145092&amp;oldid=prev"/>
		<updated>2020-10-11T21:13:18Z</updated>

		<summary type="html">&lt;p&gt;fix bug: skip arithmetic for nil val&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[&lt;br /&gt;
		------------------&lt;br /&gt;
	---| EPIDEMICS MODULE |---&lt;br /&gt;
		------------------&lt;br /&gt;
	~~ A specialized module to work with epidemics data. ~~&lt;br /&gt;
	&lt;br /&gt;
	In order to use it:&lt;br /&gt;
	- Data should be stored in Wikimedia Commons, as a Tabular file.&lt;br /&gt;
	  ie: &amp;quot;COVID-19 cases in Asturias.tab&amp;quot;&lt;br /&gt;
	- The module is added to any wiki with: &lt;br /&gt;
	  {{#invoke:Module:Sandbox/Ajuanca/GraphIt|param1|param2|...}}&lt;br /&gt;
	- All the functions that don&amp;#039;t begin with an underscore are thought &lt;br /&gt;
	  to be invoked. The remaining functions are &amp;quot;internal&amp;quot; functions.&lt;br /&gt;
	  In case you face some problems with the functions, ask me on my talk&lt;br /&gt;
	  page (User_talk:Ajuanca)&lt;br /&gt;
	- Make sure you give the correct params. All functions include an &lt;br /&gt;
	  explication. If a graph is requested, all available parameters at &lt;br /&gt;
	  Module:Graph can be passed.&lt;br /&gt;
	  &lt;br /&gt;
	Feel free to leave any comment, suggestion or complaint on my &lt;br /&gt;
	discussion page (User_talk:Ajuanca).&lt;br /&gt;
&lt;br /&gt;
	ToDo list:&lt;br /&gt;
	[ ] Generate wikitable&lt;br /&gt;
	[ ] Add positive rate&lt;br /&gt;
&lt;br /&gt;
	Some ideas that maybe are implemented:&lt;br /&gt;
	* Divide functions (graph, wikitable) instead of booleans?? &lt;br /&gt;
	* Join functions (get_avg_incidence + get_all_incidence = get_incidences)&lt;br /&gt;
	* Get rid of internal join_tables function.&lt;br /&gt;
]]--&lt;br /&gt;
local p = {}&lt;br /&gt;
mgraph = require(&amp;quot;Module:Graph&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- Join two tables.&lt;br /&gt;
-- Number index are added over the first table.&lt;br /&gt;
-- Other type of keys are added &amp;quot;as they are&amp;quot;.&lt;br /&gt;
function p.join_tables(_table1, _table2)&lt;br /&gt;
	for k, arg in pairs(_table2) do&lt;br /&gt;
		if not tonumber(k) then&lt;br /&gt;
			_table1[k] = arg&lt;br /&gt;
		else&lt;br /&gt;
			table.insert(_table1, arg)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return _table1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Converts table data type to String.&lt;br /&gt;
-- Keys should be int numbers.&lt;br /&gt;
-- Values are concatenated with &amp;quot;, &amp;quot;&lt;br /&gt;
function p.table2string(_table)&lt;br /&gt;
	original_table = _table&lt;br /&gt;
	wrapped = &amp;quot;&amp;quot;&lt;br /&gt;
	for i=1, #original_table do&lt;br /&gt;
		wrapped = wrapped .. original_table[i] .. &amp;quot;, &amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return wrapped:sub(0, -3)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Graph the given data.&lt;br /&gt;
-- All Moduule:Graph parameters are given.&lt;br /&gt;
function p._graph(args)&lt;br /&gt;
	local ret =  mgraph.chart {args=args}&lt;br /&gt;
	local graph = mw.getCurrentFrame():extensionTag(&amp;#039;graph&amp;#039;, ret)&lt;br /&gt;
	return graph&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._get_avg_incidence(args)&lt;br /&gt;
	local incidences = args.incidences or args[1]&lt;br /&gt;
	local dates = args.dates or args[2]&lt;br /&gt;
	local avg_period = args.period or 3&lt;br /&gt;
	local periods_avg = {}&lt;br /&gt;
	local periods_dates = {}&lt;br /&gt;
	local period_cases = {}&lt;br /&gt;
	for i, sincidence in ipairs(incidences) do&lt;br /&gt;
		if period_cases == nil then&lt;br /&gt;
			&lt;br /&gt;
		else&lt;br /&gt;
			table.insert(period_cases, sincidence)&lt;br /&gt;
			if #period_cases == avg_period then&lt;br /&gt;
				local total = 0&lt;br /&gt;
		    	for i = 1, #period_cases do&lt;br /&gt;
		        	total = total + tonumber(period_cases[i])&lt;br /&gt;
		    	end&lt;br /&gt;
		    	table.insert(periods_avg, total/#period_cases)&lt;br /&gt;
		    	period_cases = {}&lt;br /&gt;
		    end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for i, sdate in ipairs(dates) do&lt;br /&gt;
		if i%avg_period == 0 then&lt;br /&gt;
			table.insert(periods_dates, sdate)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return {periods_avg, periods_dates}&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
-- Get an average for the incidence proportion of a specific event.&lt;br /&gt;
-- ie. The week average of the daily confirmed cases of flu.&lt;br /&gt;
-- The given parameters are:&lt;br /&gt;
-- [1] or src: The tabular data, ie: &amp;quot;example.tab&amp;quot;&lt;br /&gt;
-- [2] or column_name: The name of the column.&lt;br /&gt;
-- [3] or date_name: The name of the date column.&lt;br /&gt;
-- [4] or inhabitants: The population size of the given region.&lt;br /&gt;
-- [5] or nth: The power of 10 in which the result is given.&lt;br /&gt;
-- column_title: The column title of the data to work with.&lt;br /&gt;
-- date_title: The column title of the date.&lt;br /&gt;
-- period: The number of values to perform the average with. &lt;br /&gt;
-- 		   Default is 3 (ie: 3 days).&lt;br /&gt;
function p.get_avg_incidence(frame)&lt;br /&gt;
	return_graph = frame.args.graph == &amp;quot;true&amp;quot;&lt;br /&gt;
	return_table = frame.args.ltable == &amp;quot;true&amp;quot;&lt;br /&gt;
	return_wikitable = frame.args.wtable == &amp;quot;true&amp;quot;&lt;br /&gt;
	all_incidence = p.join_tables(p._get_all_incidence(frame.args), frame.args)&lt;br /&gt;
	avg_incidence = p._get_avg_incidence(all_incidence)&lt;br /&gt;
	to_return = {}&lt;br /&gt;
	if return_table then&lt;br /&gt;
		table.insert(to_return, avg_incidence)&lt;br /&gt;
	end&lt;br /&gt;
	avg_incidence = p.join_tables(avg_incidence, frame.args)&lt;br /&gt;
	if return_graph then&lt;br /&gt;
		avg_incidence.x = p.table2string(table.remove(avg_incidence, 2))&lt;br /&gt;
		avg_incidence.y = p.table2string(table.remove(avg_incidence, 1))&lt;br /&gt;
		table.insert(to_return, p._graph(avg_incidence))&lt;br /&gt;
	end&lt;br /&gt;
	if return_wikitable then&lt;br /&gt;
		mw.log(&amp;quot;in progress&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	if #to_return == 1 then&lt;br /&gt;
		to_return = to_return[1]&lt;br /&gt;
	end&lt;br /&gt;
	return to_return&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._get_all_incidence(args)&lt;br /&gt;
	local data_page = args.src or args[1]&lt;br /&gt;
	local data = mw.ext.data.get(data_page)&lt;br /&gt;
	local column_name = args.column_name or args[2]&lt;br /&gt;
	local date_name = args.date_name or args[3]&lt;br /&gt;
	local total_residents = tonumber(args.inhabitants) or tonumber(args[4])&lt;br /&gt;
	local n = tonumber(args.nth) or tonumber(args[5])&lt;br /&gt;
	local column_title = args.column_title or nil&lt;br /&gt;
	local date_title = args.date_title or nil&lt;br /&gt;
	local ci = nil&lt;br /&gt;
	local di = nil&lt;br /&gt;
	local column_values = {}&lt;br /&gt;
	local date_values = {}&lt;br /&gt;
	for j, field in ipairs(data.schema.fields) do&lt;br /&gt;
		if field.name == column_name or field.title == column_title then&lt;br /&gt;
			ci = j&lt;br /&gt;
		elseif field.name == date_name or field.title == date_title then&lt;br /&gt;
			di = j&lt;br /&gt;
		end&lt;br /&gt;
		if ci and di then&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for j, record in ipairs(data.data) do&lt;br /&gt;
		value = tonumber(record[ci])&lt;br /&gt;
		if value == nil then&lt;br /&gt;
			row_value = nil&lt;br /&gt;
		else&lt;br /&gt;
			row_value = (value*10^tonumber(n))/tonumber(total_residents)&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(column_values, row_value)&lt;br /&gt;
		table.insert(date_values, record[di])&lt;br /&gt;
	end&lt;br /&gt;
	return {column_values, date_values}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the incidence proportion of a specific event for all the available dates.&lt;br /&gt;
-- Def: &amp;quot;Number of new cases of disease during specified time interval&amp;quot;&lt;br /&gt;
-- ie. The daily confirmed cases of flu per 10.000 inhabitants.&lt;br /&gt;
-- The given parameters are:&lt;br /&gt;
-- [1] or src: The tabular data, ie: &amp;quot;example.tab&amp;quot;&lt;br /&gt;
-- [2] or column_name: The name of the column.&lt;br /&gt;
-- [3] or date_name: The name of the date column.&lt;br /&gt;
-- [4] or inhabitants: The population size of the given region.&lt;br /&gt;
-- [5] or nth: The power of 10 in which the result is given.&lt;br /&gt;
-- column_title: The column title of the data to work with.&lt;br /&gt;
-- date_title: The column title of the date.&lt;br /&gt;
function p.get_all_incidence(frame)&lt;br /&gt;
	all_incidence = p._get_all_incidence(frame.args)&lt;br /&gt;
	return_graph = frame.args.graph == &amp;quot;true&amp;quot;&lt;br /&gt;
	return_table = frame.args.ltable == &amp;quot;true&amp;quot;&lt;br /&gt;
	return_wikitable = frame.args.wtable == &amp;quot;true&amp;quot;&lt;br /&gt;
	to_return = {}&lt;br /&gt;
	if return_table then&lt;br /&gt;
		table.insert(to_return, all_incidence)&lt;br /&gt;
	end&lt;br /&gt;
	all_incidence = p.join_tables(all_incidence, frame.args)&lt;br /&gt;
	if return_graph then&lt;br /&gt;
		all_incidence.x = p.table2string(table.remove(all_incidence, 2))&lt;br /&gt;
		all_incidence.y = p.table2string(table.remove(all_incidence, 1))&lt;br /&gt;
		table.insert(to_return, p._graph(all_incidence))&lt;br /&gt;
	end&lt;br /&gt;
	if return_wikitable then&lt;br /&gt;
		mw.log(&amp;quot;in progress&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	if #to_return == 1 then&lt;br /&gt;
		to_return = to_return[1]&lt;br /&gt;
	end&lt;br /&gt;
	return to_return&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.string2table(_string)&lt;br /&gt;
	stable = {}&lt;br /&gt;
	for value in _string:gmatch(&amp;quot;[^,]+&amp;quot;) do &lt;br /&gt;
		table.insert(stable, value) &lt;br /&gt;
	end&lt;br /&gt;
	return stable&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get the incidence proportion of a specific event for the specific intervals.&lt;br /&gt;
-- Various events and averages can be given. If no averages are specified,&lt;br /&gt;
-- daily info is given.&lt;br /&gt;
-- ie. The daily confirmed cases of flu per 10.000 inhabitants and the week&lt;br /&gt;
-- average of hospital occupation due to flu per 10.000 inhabitants.&lt;br /&gt;
-- The given parameters are:&lt;br /&gt;
-- [1] or src: The tabular data, ie: &amp;quot;example.tab&amp;quot;&lt;br /&gt;
-- [2] or column_names: The names of the columns for the different events.&lt;br /&gt;
-- [3] or date_name: The name of the columnthat contains the date information.&lt;br /&gt;
-- [4] or inhabitants: The population size of the given region.&lt;br /&gt;
-- [5] or nth: The power of 10 in which the result is given.&lt;br /&gt;
-- avgs: The averages of the events to be calculated. &lt;br /&gt;
--       ie: 3 (days)&lt;br /&gt;
function p.get_incidences(frame)&lt;br /&gt;
	columns = nil&lt;br /&gt;
	incidences = {}&lt;br /&gt;
	dates = {}&lt;br /&gt;
	avgs = nil&lt;br /&gt;
	if frame.args.column_names then&lt;br /&gt;
		columns = p.string2table(frame.args.column_names)&lt;br /&gt;
	else&lt;br /&gt;
		columns = p.string2table(table.remove(frame.args, 2))&lt;br /&gt;
	end&lt;br /&gt;
	if frame.args.avgs then&lt;br /&gt;
		avgs = p.string2table(frame.args.avgs)&lt;br /&gt;
	end&lt;br /&gt;
	if not avgs then&lt;br /&gt;
		for i, incidence in ipairs(columns) do&lt;br /&gt;
			frame.args.column_name = incidence&lt;br /&gt;
			incidence = p._get_all_incidence(frame.args)&lt;br /&gt;
			table.insert(incidences, incidence[1])&lt;br /&gt;
			table.insert(dates, incidence[2])&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		for i, incidence in ipairs(columns) do&lt;br /&gt;
			frame.args.column_name = incidence&lt;br /&gt;
			local all_incidence = p._get_all_incidence(frame.args)&lt;br /&gt;
			local all_args = p.join_tables(all_incidence, frame.args)&lt;br /&gt;
			all_args.period = tonumber(avgs[i])&lt;br /&gt;
			incidence = p._get_avg_incidence(all_args)&lt;br /&gt;
			table.insert(incidences, incidence[1])&lt;br /&gt;
			table.insert(dates, incidence[2])&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return_graph = frame.args.graph == &amp;quot;true&amp;quot;&lt;br /&gt;
	return_table = frame.args.ltable == &amp;quot;true&amp;quot;&lt;br /&gt;
	return_wikitable = frame.args.wtable == &amp;quot;true&amp;quot;&lt;br /&gt;
	to_return = {}&lt;br /&gt;
	if return_table then&lt;br /&gt;
		table.insert(to_return, {incidences, dates})&lt;br /&gt;
	end&lt;br /&gt;
	if return_graph or true then&lt;br /&gt;
		to_graph = {}&lt;br /&gt;
		for i, incidence in ipairs(incidences) do&lt;br /&gt;
			key = &amp;quot;y&amp;quot; .. tostring(i)&lt;br /&gt;
			to_graph[key] = p.table2string(incidence)&lt;br /&gt;
			-- xnth values are not inserted due to Module:Graph limitations.&lt;br /&gt;
		end&lt;br /&gt;
		to_graph.x = p.table2string(dates[1])&lt;br /&gt;
		to_graph = p.join_tables(to_graph, frame.args)&lt;br /&gt;
		table.insert(to_return, p._graph(to_graph))&lt;br /&gt;
	end&lt;br /&gt;
	if return_wikitable then&lt;br /&gt;
		mw.log(&amp;quot;in progress&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	if #to_return == 1 then&lt;br /&gt;
		to_return = to_return[1]&lt;br /&gt;
	end&lt;br /&gt;
	return to_return&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>imported&gt;Ajuanca</name></author>
	</entry>
</feed>