Module:User:Ale1991/Statistics

local p = {} local cargo = mw.ext.cargo local Util = require 'Module:Util'

function p.Factorial(x) local f=1 for i = 1,x-1 do		f=f*(i+1) end return f end

function p.BinomialCoefficient(n,k) return p.Factorial(n)/(p.Factorial(k)*p.Factorial(n-k)) end

function p.BinomialDistribution(n,k,a,b) return p.BinomialCoefficient(n,k)*(a^k)*(b^(n-k)) end

function p.Round(x) local e=math.ceil(x) local d=math.floor(x) if math.abs(x-e) > math.abs(x-d) then return d	elseif math.abs(x-e) < math.abs(x-d) then return e	else if (e % 2 == 0) then return e		end if (d % 2 == 0) then return d		end end end

function p.Quantile(x,p,method) local q={} local N=#x local o=x table.sort(o) for k,v in pairs(p) do		if method == 1 then h=N*v+1/2 q[k]=o[math.ceil(h-1/2)] elseif method == 2 then h=N*v+1/2 q[k]=(o[math.ceil(h-1/2)]+o[math.floor(h+1/2)])/2 elseif method == 3 then h=N*v q[k]=o[p.Round(x)] elseif method == 4 then h=N*v q[k]=o[math.floor(h)]+(h-math.floor(h))*(o[math.floor(h)+1]-o[math.floor(h)]) elseif method == 5 then h=N*v+1/2 q[k]=o[math.floor(h)]+(h-math.floor(h))*(o[math.floor(h)+1]-o[math.floor(h)]) elseif method == 6 then h=(N+1)*v q[k]=o[math.floor(h)]+(h-math.floor(h))*(o[math.floor(h)+1]-o[math.floor(h)]) elseif method == 7 then h=(N-1)*v+1 q[k]=o[math.floor(h)]+(h-math.floor(h))*(o[math.floor(h)+1]-o[math.floor(h)]) elseif method == 8 then h=(N + 1/3)*v + 1/3 q[k]=o[math.floor(h)]+(h-math.floor(h))*(o[math.floor(h)+1]-o[math.floor(h)]) elseif method == 9 then h=(N + 1/4)*v + 3/8 q[k]=o[math.floor(h)]+(h-math.floor(h))*(o[math.floor(h)+1]-o[math.floor(h)]) else end end return q end

function p.Median(x) table.sort(x) local m=#x/2 local s=x[math.ceil(m-1/2)] local d=x[math.floor(m+1/2)] return((d+s)/2) end

function p.Avedev(x) local y={} local m=p.Median(x) for k,v in pairs(x) do      y[k]=math.abs(v-m) end return(p.Average(y)) end

function p.MAD(x) local y={} local m=p.Median(x) for k,v in pairs(x) do      y[k]=math.abs(v-m) end return(p.Median(y)) end

function p.Max(x) table.sort(x) return(x[#x]) end

function p.Min(x) table.sort(x) return(x[1]) end

function p.Average(x) local s=0; for k,v in pairs(x) do       s=s+v; end return(s/(#x)) end

function p.IndexFromTableIfLower(t,n) local r = #t+1 for k, v in ipairs(t) do		if n <= v then r = k			break end end return r end

function p._maxStatsTableStatistics(args) local WEAPON_SORT = Util.getWeaponSortOrder local MOVE_SORT = Util.getMoveSortOrder

-- Cargo Query

local tables = 'HeroMaxStats,Heroes' local queryFields = "HeroMaxStats._pageName=_pageName,HeroMaxStats.HP=HP,HeroMaxStats.Atk=Atk,HeroMaxStats.Spd=Spd,HeroMaxStats.Def=Def,HeroMaxStats.Res=Res,Heroes.WeaponType=WeaponType,Heroes.MoveType=MoveType" local queryArgs = { where = 'HeroMaxStats.Variation="Neut" and HeroMaxStats.Rarity=5 and DATEDIFF(Heroes.ReleaseDate,NOW)<=0', join = 'HeroMaxStats._pageName = Heroes._pageName', groupBy = 'HeroMaxStats._pageName', limit = '500' } local queryResult = cargo.query(tables, queryFields, queryArgs) if queryResult == nil then return "(no values)" end

-- Initialize the table local tbl = mw.html.create('table') :addClass('wikitable sortable') :css('text-align','center') :css('width','100%')

-- Table Headers tbl:tag('th') :addClass('unsortable') :css('width', '30px') tbl:tag('th') :wikitext('Name') tbl:tag('th') :css('width', '4%') tbl:tag('th') :css('width', '4%') tbl:tag('th') :wikitext('HP') tbl:tag('th') :wikitext('ATK') tbl:tag('th') :wikitext('SPD') tbl:tag('th') :wikitext('DEF') tbl:tag('th') :wikitext('RES') tbl:tag('th') :wikitext('Total') tbl:tag('th') :wikitext('Min') tbl:tag('th') :wikitext('Max') tbl:tag('th') :wikitext('Average') tbl:tag('th') :wikitext('Median') tbl:tag('th') :wikitext('MAD') tbl:tag('th') :wikitext('HpQ') tbl:tag('th') :wikitext('AtkQ') tbl:tag('th') :wikitext('SpdQ') tbl:tag('th') :wikitext('DefQ') tbl:tag('th') :wikitext('ResQ')

local hpT = {} local atkT = {} local spdT = {} local defT = {} local resT = {}

if type( queryResult ) == "table" then -- Go through all the heroes in the query result for key, hero in ipairs(queryResult) do			hpT[key] = tonumber(Util.returnDefaultIfEmpty(hero.HP)) atkT[key] = tonumber(Util.returnDefaultIfEmpty(hero.Atk)) spdT[key] = tonumber(Util.returnDefaultIfEmpty(hero.Spd)) defT[key] = tonumber(Util.returnDefaultIfEmpty(hero.Def)) resT[key] = tonumber(Util.returnDefaultIfEmpty(hero.Res)) end end

local met = 8 local perc = {0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9} local qH = p.Quantile(hpT,perc,met) local qA = p.Quantile(atkT,perc,met) local qS = p.Quantile(spdT,perc,met) local qD = p.Quantile(defT,perc,met) local qR = p.Quantile(resT,perc,met)

if type( queryResult ) == "table" then -- Go through all the heroes in the query result for _, hero in ipairs(queryResult) do           local tr = tbl:tag('tr') tr:addClass('hero-filter-element'):done

-- Icon tr:tag('td') :wikitext(Util.getHeroIcon(hero._pageName, '30px')) -- Character Name tr:tag('td') :wikitext(  .. hero._pageName ..  )

-- Weapon Type tr:attr( 'data-weapon-type', hero.WeaponType ) :tag('td') :wikitext( '' ) :attr( 'data-sort-value', WEAPON_SORT[hero.WeaponType] ) -- Movement Type tr:attr( 'data-move-type', hero.MoveType ) :tag('td') :wikitext( '' ) :attr( 'data-sort-value', MOVE_SORT[hero.MoveType] ) local hp = Util.returnDefaultIfEmpty(hero.HP) local atk = Util.returnDefaultIfEmpty(hero.Atk) local spd = Util.returnDefaultIfEmpty(hero.Spd) local def = Util.returnDefaultIfEmpty(hero.Def) local res = Util.returnDefaultIfEmpty(hero.Res) local total = '' local tab={tonumber(hp), tonumber(atk) , tonumber(spd) , tonumber(def) , tonumber(res)} local avedev = p.MAD(tab) local median = p.Median(tab) local average = p.Average(tab) local max = p.Max(tab) local min = p.Min(tab) local HPtier = p.IndexFromTableIfLower(qH,tonumber(hp)) local ATKtier = p.IndexFromTableIfLower(qA,tonumber(atk)) local SPDtier = p.IndexFromTableIfLower(qS,tonumber(spd)) local DEFtier = p.IndexFromTableIfLower(qD,tonumber(def)) local REStier = p.IndexFromTableIfLower(qR,tonumber(res))

if tonumber(hp) == nil or tonumber(atk) == nil or tonumber(spd) == nil or tonumber(def) == nil or tonumber(res) == nil then total = '-' else total = tonumber(hp) + tonumber(atk) + tonumber(spd) + tonumber(def) + tonumber(res) end tr:tag('td') :wikitext( hp ) tr:tag('td') :wikitext( atk ) tr:tag('td') :wikitext( spd ) tr:tag('td') :wikitext( def ) tr:tag('td') :wikitext( res ) tr:tag('td') :wikitext( total ) tr:tag('td') :wikitext( min ) tr:tag('td') :wikitext( max ) tr:tag('td') :wikitext( average ) tr:tag('td') :wikitext( median ) tr:tag('td') :wikitext( avedev ) tr:tag('td') :wikitext( HPtier ) tr:tag('td') :wikitext( ATKtier ) tr:tag('td') :wikitext( SPDtier ) tr:tag('td') :wikitext( DEFtier ) tr:tag('td') :wikitext( REStier ) end return tostring(tbl) end end function p.maxStatsTableStatistics(frame) return p._maxStatsTableStatistics end

return p