Module:Autocalctable
Documentation for this module may be created at Module:Autocalctable/doc
--<pre> --|Description : Autocalctable --|Adds summation/average/min/max values of a column of a table imported from json/module/csv page --|Syntax : --|{{#invoke:Autotablecalc|page=pagename|type=datatype|calc=calculationtype}} --|Where calc = sum/avg/min/max - can be more than one separated by commas ,e.g. calc=sum,avg --| pagename = name of page/module --| datatype = json or lua or cvs local p = {} local csv = require("Module:Csv") local json = require("Module:Json") local getArgs = require("Module:Arguments").getArgs --% Extracts table columns containing numbers --@ sPage (string) A page containing the table e.g Module:Scores.json --@ sType (string) The type of data contained in the page (csv, json, lua) -lua table --: (string) A table containing calculated columns local function getTable(sPage, sType) if sPage then if sType == "lua" then return require(sPage) elseif sType == "csv" then return csv.convertToLua(sPage) end local oData = mw.title.new(sPage):getContent() if oData and sType == "json" then return json.decode(oData) end end end --% Entry point - Creates a table with automatically calculated columns --@ frame (table) A scribunto frame --: (string) A table containing calculated columns function p.main(frame) local args = getArgs(frame) local sPageName = args.page local sType = args.type local calculations = args.calc local calcTable = getTable(sPageName, sType) return p.createHtmlTable(calcTable, calculations) end --% Creates an html table --@ arrColumns (string) A column containing numbers --@ calculations (string) The types of calculations to perform (avg, min, max, sum) --: (string) An html table containing calculated columns function p.createHtmlTable(arrColumns, calculations) if not arrColumns then return end local hTable = mw.html.create("table") local storedData = {} local calc = {sum = {0}, avg = {0}, min = {0}, max = {0}, elements = {}} for i in ipairs(arrColumns) do local sTag = i == 1 and "th" or "td" hTable:tag("tr") for sKey, sData in ipairs(arrColumns[i]) do storedData[sKey] = storedData[sKey] or {} hTable:tag(sTag) :wikitext(sData) -- //gets second row because the first one is the heading if tonumber(sData) and i > 1 then storedData[sKey][#storedData[sKey] + 1] = tonumber(sData) end end end local val for index, dataTable in pairs(storedData) do for _, value in pairs(dataTable) do val = value or 0 calc.sum[index] = (calc.sum[index] or 0) + val calc.min[index] = calc.min[index] or 0 calc.max[index] = calc.max[index] or 0 calc.avg[index] = calc.avg[index] or 0 if calc.min[index] >= val then calc.min[index] = val end if calc.max[index] <= val then calc.max[index] = val end end calc.elements[index] = #dataTable if calc.sum[index] > 0 then calc.avg[index] = calc.sum[index] / #dataTable end end local calcTable = mw.text.split(calculations or "", ",") local bFlag = true local trNode for _, calctype in pairs(calcTable) do if calc[calctype] then trNode = mw.html.create("tr") for sKey in ipairs(arrColumns[1]) do trNode:tag("td") :wikitext(calc[calctype][sKey]) end if bFlag then trNode:css("border-top", "thick double #ff0000") bFlag = false end hTable:node(trNode):done() end end hTable:addClass("wikitable") hTable:done() return hTable end return p