Welcome to the Mother Ship of amateur comedy writing! (Amateur means we don't pay you to do it.)
This is where the original Uncyclopedia wound up. You might as well pick a user name. We have no "partners" that want to sell you stuff. Giving your email simply lets you recover your password; we don't send spam. Uncyclopedians get a talk page, private edit area, and a welcome, maybe, if you actually edit; and we won't de-platform you for your views, if they're funny.
Module:Weather box/row
Jump to navigation
Jump to search
![]() |
This module depends on the following other modules: |
To update this module against Wikipedia's version, copy the content of wikipedia:Module:Weather box and paste it into Uncyclopedia's Module:Weather box.
local w = {}
local math_mod = require('Module:Math')
local wbc = require('Module:Weather box/colors')
local traceText
local Value
Value = {
lang = mw.getContentLanguage(),
getDisplay = function (self, second)
if not self:isValid() then
return nil
end
local display = self.string
if display == 'trace' then
if second then
-- If a cell displays "cm (inch)", show "trace" not "trace (trace)".
return nil
end
return traceText or 'trace'
end
if math.abs(self.number) >= 1000 then
display = self.lang:formatNum(math.abs(self.number))
if self.number < 0 then
display = '−' .. display
end
elseif self.number < 0 then
display = '−' .. display:sub(2)
end
return display
end,
getPrecision = function (self)
local result = rawget(self, 'precision')
if not result then
if self:isValid() then
result = math.max(0, math_mod._precision(self.string))
else
result = 0
end
rawset(self, 'precision', result)
end
return result
end,
isValid = function (self)
return self.number ~= nil and self.number ~= -9999
end,
new = function (v)
local val, str, precision
if type(v) == 'string' then
if v == 'trace' then
val, str, precision = 0, 'trace', 0
else
val, str = math_mod._cleanNumber(v)
end
elseif type(v) == 'number' then
val, str = v, tostring(v)
end
if not val then
val, str = -9999, ''
end
return setmetatable({
number = val,
string = str,
precision = precision,
}, Value)
end,
converts = {
in2cm = { factor = 2.54 },
in2mm = { factor = 25.4 },
cm2in = { factor = 1/2.54, p2max = 1 },
mm2in = { factor = 1/25.4, p2max = 0 },
},
setConvert = function (self, invalue, units)
-- Use method modified from [[Module:Convert]] to determine precision.
if invalue.string == 'trace' then
self.number, self.string, self.precision = 0, 'trace', 0
return
end
local convert = self.converts[units] or error('Unknown units')
local outnum = invalue.number * convert.factor
local precision = invalue:getPrecision()
if outnum > 0 then
local adjust = math.log10(1/convert.factor) + math.log10(2)
local p1 = math.floor(precision + adjust)
local p2 = 1 - math.floor(math.log10(outnum))
if convert.p2max then
p2 = math.min(p2, convert.p2max)
end
precision = math.max(p1, p2)
end
self:setNumberRounded(outnum, precision)
end,
setNumberRounded = function (self, number, precision)
if precision > 2 then
precision = 2
end
self.number = math_mod._round(number, precision)
if precision < 0 then
self.string = tostring(self.number)
else
local fmt = '%.' .. string.format('%d', precision) .. 'f'
self.string = string.format(fmt, self.number)
end
end,
}
Value.__index = Value
local function checkFlag( flag, default )
if flag == nil then
return default
elseif type( flag ) == 'boolean' then
return flag
elseif type( flag ) == 'string' then
flag = flag:lower()
if flag == '0' or flag == 'false' or
flag == '' or flag == 'no' or
flag == 'n' then
return false
else
return true
end
else
return error( 'Flag type not valid' )
end
end
local function makeLine( label, first_values, second_values, color_values )
local result = {'|- style="text-align: center;"\n! scope="row" style="height: 16px;" | ', label, "\n"}
for i = 1,13 do
local color_str = color_values[i]
if i == 13 then
table.insert( result, table.concat( {'|style="', color_str, ' border-left-width:medium" | '} ) )
else
table.insert( result, table.concat( {'|style="', color_str, '" | '} ) )
end
local display = first_values[i]:getDisplay()
if display then
table.insert( result, display )
if second_values ~= nil then
display = second_values[i]:getDisplay(true)
if display then
table.insert( result, "<br />(" .. display .. ")" )
end
end
else
table.insert( result, '—' )
end
table.insert( result, "\n" )
end
return table.concat( result )
end
local function getInputs( frame, group_name, suffix, include_space )
local month_names = { 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'year' }
local str
local values = {}
if suffix == nil then
for i, mon in ipairs( month_names ) do
if include_space then
str = frame.args[ mon .. ' ' .. group_name ] or ''
else
str = frame.args[ mon .. group_name ] or ''
end
values[i] = Value.new(str)
end
else
for i, mon in ipairs( month_names ) do
local value, updated
for var, suf in ipairs( suffix ) do
if include_space then
str = frame.args[ mon .. ' ' .. group_name .. ' ' .. suf ]
else
str = frame.args[ mon .. group_name .. ' ' .. suf ]
end
if str ~= nil and str ~= '' then
value = Value.new(str)
value.variant = var
updated = true
break
end
end
if not updated then
value = Value.new()
value.variant = 0
end
values[i] = value
end
end
return values
end
local function getAnnualValue( values, mode )
if mode == 'avg' or mode == 'sum' then
local total = 0
local p1, p2, variant
p1 = 0
for i = 1, 12 do
if not values[i]:isValid() then
return Value.new()
end
if not variant then
local var = values[i].variant
if var and var ~= 0 then
variant = var
end
end
p2 = values[i]:getPrecision()
if p2 > p1 then
p1 = p2
end
total = total + values[i].number
end
local value = Value.new(total)
if mode == 'avg' then
value:setNumberRounded( total / 12, p1 )
end
value.variant = variant
return value
elseif mode == 'min' then
local target
for i = 1, 12 do
if values[i]:isValid() then
if target == nil or values[i].number < target.number then
target = values[i]
end
end
end
return target or Value.new()
elseif mode == 'max' then
local target
for i = 1, 12 do
if values[i]:isValid() then
if target == nil or values[i].number > target.number then
target = values[i]
end
end
end
return target or Value.new()
else
error( 'Unrecognized Annual Mode' )
end
end
local function reconcileTemperature( C_values, F_values )
for i = 1,13 do
local p
if C_values[i].string == '' then
if F_values[i]:isValid() then
p = F_values[i]:getPrecision()
C_values[i]:setNumberRounded( (F_values[i].number - 32)*5/9, p )
end
elseif F_values[i].string == '' then
if C_values[i]:isValid() then
p = C_values[i]:getPrecision()
F_values[i]:setNumberRounded( C_values[i].number*9/5 + 32, p )
end
end
end
end
local function reconcilePrecipitation( M_values, I_values, prefer_cm )
local v_class = 0
for i = 1,13 do
if M_values[i].variant == 1 then
v_class = 1
elseif M_values[i].variant == 2 then
v_class = 2
end
end
if v_class == 0 then
if prefer_cm then
v_class = 1
else
v_class = 2
end
end
for i = 1,13 do
local units
if M_values[i].string == '' then
if I_values[i]:isValid() then
if v_class == 1 then
units = 'in2cm'
else
units = 'in2mm'
end
M_values[i]:setConvert( I_values[i], units )
M_values[i].variant = v_class
end
elseif I_values[i].string == '' then
if M_values[i]:isValid() then
if M_values[i].variant == 1 then
units = 'cm2in'
else
units = 'mm2in'
end
I_values[i]:setConvert( M_values[i], units )
end
end
end
end
function w.buildRow( frame )
local mode = (frame.args.mode or 'basic'):lower()
local group_name = frame.args.group_name
local first_values, second_values
local color_values
local color_scheme = frame.args.color_scheme or 't'
local scale_factor = math_mod._cleanNumber( frame.args.scale_factor) or 1
local date_mode = checkFlag( frame.args.date_mode, false )
local label = frame.args.label or ''
local annual_mode = (frame.args.annual_mode or 'avg'):lower()
local include_space = checkFlag( frame.args.include_space, true )
local second_line = checkFlag( frame.args.second_line, false )
local prefer_cm = checkFlag( frame.args.prefer_cm, false )
local pframe = frame:getParent()
local imperial_first = checkFlag( frame.args['imperial first'] or pframe.args['imperial first'] )
local metric_first = checkFlag( frame.args['metric first'] or pframe.args['metric first'] )
local single_line = checkFlag( frame.args['single line'] or pframe.args['single line'] )
local trace = pframe.args.trace
if trace and trace ~= '' then
traceText = trace
end
if imperial_first == nil then
imperial_first = metric_first == nil and true or not metric_first
end
if mode == 'basic' then
first_values = getInputs( pframe, group_name, nil, include_space )
second_values = nil
elseif mode == 'temperature' then
first_values = getInputs( pframe, group_name, {'C'}, include_space )
second_values = getInputs( pframe, group_name, {'F'}, include_space )
reconcileTemperature( first_values, second_values )
elseif mode == "precipitation" then
first_values = getInputs( pframe, group_name, {'cm', 'mm'}, include_space )
second_values = getInputs( pframe, group_name, {'inch'}, include_space )
reconcilePrecipitation( first_values, second_values, prefer_cm )
else
error( 'Requested mode not recognized' )
end
local good = false
for i = 1,13 do
if first_values[i].string ~= '' then
good = true
break
end
end
if not good then
return ''
end
if first_values[13].string == '' then
first_values[13] = getAnnualValue( first_values, annual_mode )
end
if second_values ~= nil then
if second_values[13].string == '' then
second_values[13] = getAnnualValue( second_values, annual_mode )
end
end
color_scheme = wbc.interpret_color_code( color_scheme )
color_values = {}
local month_adj = { 31/30, 28.25/30, 31/30, 1, 31/30, 1,
31/30, 31/30, 1, 31/30, 1, 31/30, 365.25/30 }
for i = 1,13 do
if first_values[i]:isValid() then
local adj = scale_factor
if date_mode then
adj = adj / month_adj[i]
end
if mode == "precipitation" then
if first_values[i].variant == 1 then
adj = adj * 10
end
end
table.insert( color_values, color_scheme( first_values[i].number * adj ) )
else
table.insert( color_values, color_scheme( nil ) )
end
end
if imperial_first and second_values ~= nil then
first_values, second_values = second_values, first_values
end
if not single_line then
if second_line and second_values ~= nil then
first_values = second_values
end
second_values = nil
end
return makeLine( label, first_values, second_values, color_values )
end
return w