local count = require "Module:fun".count
local function errorf(level, ...) if type(level)
local varargs_or_array_mt =
-- Create a function that accepts two argument formats: a list of numbers, or-- an array containing numbers followed by optional start and end indices-- (similar to the arguments to "unpack", though here the end index can be-- greater than the start index).local function make_arr_and_varargs_func(varargs_func) return setmetatable(varargs_or_array_mt)end
local function sum_varargs (...) local result = 0 for i = 1, select('#', ...) do result = result + select(i, ...) end return resultend
local ops =
local stats_mt = stats_mt.ops = ops-- Interprets a field name and then calculates, saves, and returns the desired-- value. For instance, "Stats_object.mean" returns the mean of the values in-- "Stats_object", "Stats_object.above_10" the number of values greater than 10.function stats_mt:__index(key) if type(key) ~= "string" then return nil end -- Parse field names such as "above_10" or "below_60". local op, amount = key:match("(%a+)_(%d+)") if amount then amount = tonumber(amount) local count = op
"below" and count(function(val) return val < amount end, self) or errorf("Unrecognized operation %s", op) self[key] = count return count end -- Parse field names such as "mean" or "summer_min". local season season, op = key:match("^(%a-)_?(%a+)$") if not (season
"summer" or season
"" then result = ops[op](self) else result = ops[op](self, unpack(self[season .. "_months"])) end self[key] = result return resultend
local seasons = seasons.winter = seasons.winter.south = seasons.winter.north =
-- Allows "stats_mt" to be called as a function, returning a Stats object:setmetatable(stats_mt,)
return stats_mt