Module:Weather box/sandbox: Difference between revisions

Content deleted Content added
test
sync + try "Percentage possible sunshine" per talk proposal
 
(49 intermediate revisions by 13 users not shown)
Line 1:
-- Implement [[Template:Weather box]].
 
local precision_precision = require('Module:Math')._precision
local function precision(text)
-- Input like 'Jan precipitation inch = trace' calls this with text = 'trace'
-- which would cause _precision to throw an error since it is not numeric.
-- Workaround: Return 0 as the precision if an error occurs.
local success, result = pcall(_precision, text)
if success then
return result
end
return 0
end
 
local function stripToNil(text)
Line 20 ⟶ 30:
end
 
local function makeLabel(args, options, is_first, base, what)
local first
if isAny(args, ' ' .. what .. ' cm') then
first = 'cm'
elseif isAny(args, ' ' .. what .. ' mm') then
first = 'mm'
else
first = (what:sub(1, 4) == 'snow' or
if isAny(args, ' ' .. what .. ' mm') then
precision(args['Jan ' .. what .. ' inch'] or '0') < 1)
first = 'mm'
and 'cm'
else
first = (what == or 'snowmm' or
precision(args['Jan ' .. what .. ' inch'] or '0') < 1)
and 'cm'
or 'mm'
end
end
local second = 'inches'
Line 39 ⟶ 47:
end
if is_first then
if stripToNil(args['single line'])options.wantSingleLine then
first = first .. ' (' .. second .. ')'
end
Line 55 ⟶ 63:
if source1 or source2 then
if source1 and source2 then
text = 'Source #1: ' .. source1 .. '\n' .. result .. 'Source #2: ' .. source2
else
text = 'Source: ' .. (source1 and source1 or source2)
Line 65 ⟶ 73:
end
 
local function getDefinitionswantSingle(frame, argsparm)
--------------------------------------------------------------------------------
-- Result before July 2022 for single_line setting:
-- blank/omitted : separate table rows for metric and imperial (two rows)
-- N : bug: only one row with either metric or imperial (not both)
-- but heading like "cm (inches)"
-- Y/junk : single row with both metric/imperial in same cell
--------------------------------------------------------------------------------
-- Intend changing in July 2022 so single_line=Y is the default and
-- need single_line=N for separate lines.
-- However, this release (1 July 2022) keeps blank/omitted as meaning "no"
-- so the other large changes can be tested before switching the default.
parm = (parm or ''):lower()
return not (parm == 'no' or parm == 'n' or parm == '')
end
 
local function getDefinitions(frame, args, options)
-- Return a list of tables or strings that define each row.
local navbar = require('Module:Navbar')._navbar
local function _if(parm, a, b)
return stripToNil(args[parm]) and a or b or ''
Line 76 ⟶ 99:
local function _ifany(suffix)
return isAny(args, suffix)
end
local function _ifSingle(a, b)
return options.wantSingleLine and a or b or ''
end
local function _colorscheme(what, default)
return stripToNil(args[what .. ' colour']) or stripToNil(args[what .. ' color']) or default
end
local function _margin()
if stripToNil(args.margin) then
return 'margin:' .. args.margin .. ';'
end
return ''
end
local ___location = _if('___location', args.___location, '{{{___location}}}') -- show "{{{___location}}}" to alert editor if parameter is blank
local navbarText
if not stripToNil(args.open) then
if stripToNil(args.name) then
local navbar = require('Module:Navbar')._navbar
navbarText = navbar({'Climate data for ' .. ___location, args.name, collapsible=1})
end
end
return {
 
----------- HEADER ----------
'{| class="wikitable ' .. _if('open', '', 'mw-collapsible' .. _if('collapsed', ' mw-collapsed')) ..
'" style="width:' .. _ifset('width', '100%auto') ..
'; text-align:center; line-height: 1.2em; margin:' ..
_ifset_margin('margin', 'auto') .. ';"' ..
_if('open',
'\n|+Climate data for ' .. _if('___location', args.___location, '{{{___location}}}'),
'\n|-' ..
'\n!colspan="14" | ' .. _if('name', navbarText, 'Climate data for ' .. ___location)
_if('name',
navbar({'Climate data for ' .. _if('___location', args.___location, '{{{___location}}}'), args.name, collapsible=1}),
'Climate data for ' .. _if('___location', args.___location, '{{{___location}}}')
)
) ..
[=[
Line 113 ⟶ 152:
 
{---------- FIRST LINE MAXIMUM HUMIDEX ----------
WANTROW = _ifany(' maximum humidex') and (_ifset('metric first') or _ifset('single line')options.wantSingleLine),
mode = 'basic',
group_name = 'maximum humidex',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'Record high [[humidex]]',
Line 125 ⟶ 164:
mode = 'temperature',
group_name = 'record high',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'Record high °' .. _if('metric first', 'C', 'F') .. _if_ifSingle('single line', ' (°' .. _if('metric first', 'F', 'C') .. ')'),
annual_mode = 'max',
},
Line 134 ⟶ 173:
mode = 'temperature',
group_name = 'avg record high',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'Mean maximum °' .. _if('metric first', 'C', 'F') .. _if_ifSingle('single line', ' (°' .. _if('metric first', 'F', 'C') .. ')'),
annual_mode = 'max',
},
{---------- FIRST LINE AVERAGEMEAN HIGHDAILY MAXIMUM TEMPERATURES ----------
WANTROW = _ifany(' high C') or _ifany(' high F'),
mode = 'temperature',
group_name = 'high',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'AverageMean highdaily maximum °' .. _if('metric first', 'C', 'F') .. _if_ifSingle('single line', ' (°' .. _if('metric first', 'F', 'C') .. ')'),
annual_mode = 'avg',
},
Line 152 ⟶ 191:
mode = 'temperature',
group_name = 'mean',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'Daily mean °' .. _if('metric first', 'C', 'F') .. _if_ifSingle('single line', ' (°' .. _if('metric first', 'F', 'C') .. ')'),
annual_mode = 'avg',
},
{---------- FIRST LINE AVERAGEMEAN LOWDAILY MINIMUM TEMPERATURES ----------
WANTROW = _ifany(' low C') or _ifany(' low F'),
mode = 'temperature',
group_name = 'low',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'AverageMean lowdaily minimum °' .. _if('metric first', 'C', 'F') .. _if_ifSingle('single line', ' (°' .. _if('metric first', 'F', 'C') .. ')'),
annual_mode = 'avg',
},
Line 170 ⟶ 209:
mode = 'temperature',
group_name = 'avg record low',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'Mean minimum °' .. _if('metric first', 'C', 'F') .. _if_ifSingle('single line', ' (°' .. _if('metric first', 'F', 'C') .. ')'),
annual_mode = 'min',
},
Line 179 ⟶ 218:
mode = 'temperature',
group_name = 'record low',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'Record low °' .. _if('metric first', 'C', 'F') .. _if_ifSingle('single line', ' (°' .. _if('metric first', 'F', 'C') .. ')'),
annual_mode = 'min',
},
{---------- FIRST LINE MINIMUM WIND CHILL ----------
WANTROW = _ifany(' chill') and (_ifset('metric first') or _ifset('single line')options.wantSingleLine),
mode = 'basic',
group_name = 'chill',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'Record low [[wind chill]]',
Line 197 ⟶ 236:
mode = 'precipitation',
group_name = 'precipitation',
color_scheme = _ifset_colorscheme('precipitation colour', 'p'),
date_mode = true,
scale_factor = '1',
prefer_cm = precision(_ifset('Jan precipitation inch', '0')) < 1,
label = makeLabel(args, options, true, 'Average [[precipitation]]', 'precipitation'),
annual_mode = 'sum',
},
Line 208 ⟶ 247:
mode = 'precipitation',
group_name = 'rain',
color_scheme = _ifset_colorscheme('rain colour', 'p'),
date_mode = true,
scale_factor = '1',
prefer_cm = precision(_ifset('Jan rain inch', '0')) < 1,
label = makeLabel(args, options, true, 'Average rainfall', 'rain'),
annual_mode = 'sum',
},
Line 220 ⟶ 259:
group_name = 'snow',
prefer_cm = true,
color_scheme = _ifset_colorscheme('snow colour', 'p'),
date_mode = true,
scale_factor = '1',
label = makeLabel(args, options, true, 'Average snowfall', 'snow'),
annual_mode = 'sum',
},
{---------- FIRST LINE AVERAGE EXTREME SNOW DEPTH ----------
WANTROW = _ifany(' snow depth cm') or _ifany(' snow depth mm') or _ifany(' snow depth inch'),
mode = 'precipitation',
group_name = 'snow depth',
prefer_cm = true,
color_scheme = _colorscheme('snow', 'p'),
scale_factor = '0.2',
label = makeLabel(args, options, true, 'Average extreme snow depth', 'snow depth'),
annual_mode = 'max',
},
{---------- SECOND LINE MAXIMUM HUMIDEX ----------
WANTROW = not _ifset('single line')options.wantSingleLine and _ifany(' maximum humidex'),
mode = 'basic',
group_name = 'maximum humidex',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = '[[Humidex]]',
Line 237 ⟶ 286:
},
{---------- SECOND LINE RECORD HIGH TEMPERATURES ----------
WANTROW = not _ifset('single line')options.wantSingleLine and (_ifany(' record high C') or _ifany(' record high F')),
mode = 'temperature',
group_name = 'record high',
second_line = true,
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'Record high °' .. _if('metric first', 'F', 'C'),
annual_mode = 'max',
},
{---------- SECOND LINE AVERAGEMEAN HIGHDAILY MAXIMUM TEMPERATURES ----------
WANTROW = not _ifset('single line')options.wantSingleLine and (_ifany(' high C') or _ifany(' high F')),
mode = 'temperature',
group_name = 'high',
second_line = true,
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'AverageMean highdaily maximum °' .. _if('metric first', 'F', 'C'),
annual_mode = 'avg',
},
{---------- SECOND LINE DAILY MEAN TEMPERATURES ----------
WANTROW = not _ifset('single line')options.wantSingleLine and (_ifany(' mean C') or _ifany(' mean F')),
mode = 'temperature',
group_name = 'mean',
second_line = true,
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'Daily mean °' .. _if('metric first', 'F', 'C'),
Line 267 ⟶ 316:
annual_mode = 'avg',
},
{---------- SECOND LINE AVERAGEMEAN LOWDAILY MINIMUM TEMPERATURES ----------
WANTROW = not _ifset('single line')options.wantSingleLine and (_ifany(' low C') or _ifany(' low F')),
mode = 'temperature',
group_name = 'low',
second_line = true,
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'AverageMean lowdaily minimum °' .. _if('metric first', 'F', 'C'),
show = _if('metric first', '2', '1'),
annual_mode = 'avg',
},
{---------- SECOND LINE RECORD LOW TEMPERATURES ----------
WANTROW = not _ifset('single line')options.wantSingleLine and (_ifany(' record low C') or _ifany(' record low F')),
mode = 'temperature',
group_name = 'record low',
second_line = true,
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = 'Record low °' .. _if('metric first', 'F', 'C'),
Line 290 ⟶ 339:
},
{---------- SECOND LINE MINIMUM WIND CHILL ----------
WANTROW = not _ifset('single line')options.wantSingleLine and (_ifany(' chill') and _if('metric first')),
mode = 'basic',
group_name = 'chill',
color_scheme = _ifset_colorscheme('temperature colour', 't'),
scale_factor = '1',
label = '[[Wind chill]]',
Line 299 ⟶ 348:
},
{---------- SECOND LINE TOTAL PRECIPITATION ----------
WANTROW = not _ifset('single line')options.wantSingleLine and (_ifany(' precipitation cm') or _ifany(' precipitation mm') or _ifany(' precipitation inch')),
mode = 'precipitation',
group_name = 'precipitation',
second_line = true,
color_scheme = _ifset_colorscheme('precipitation colour', 'p'),
date_mode = true,
scale_factor = '1',
prefer_cm = precision(_ifset('Jan precipitation inch', '0')) < 1,
label = makeLabel(args, options, false, 'Average [[precipitation]]', 'precipitation'),
annual_mode = 'sum',
},
{---------- SECOND LINE RAINFALL ----------
WANTROW = not _ifset('single line')options.wantSingleLine and (_ifany(' rain cm') or _ifany(' rain mm') or _ifany(' rain inch')),
mode = 'precipitation',
group_name = 'rain',
second_line = true,
color_scheme = _ifset_colorscheme('rain colour', 'p'),
date_mode = true,
scale_factor = '1',
prefer_cm = precision(_ifset('Jan rain inch', '0')) < 1,
label = makeLabel(args, options, false, 'Average rainfall', 'rain'),
annual_mode = 'sum',
},
{---------- SECOND LINE SNOWFALL ----------
WANTROW = not _ifset('single line')options.wantSingleLine and (_ifany(' snow cm') or _ifany(' snow mm') or _ifany(' snow inch')),
mode = 'precipitation',
group_name = 'snow',
second_line = true,
prefer_cm = true,
color_scheme = _ifset_colorscheme('snow colour', 'p'),
date_mode = true,
scale_factor = '1',
label = makeLabel(args, options, false, 'Average snowfall', 'snow'),
annual_mode = 'sum',
},
{---------- SECOND LINE AVERAGE EXTREME SNOW DEPTH ----------
WANTROW = not options.wantSingleLine and (_ifany(' snow depth cm') or _ifany(' snow depth mm') or _ifany(' snow depth inch')),
mode = 'precipitation',
group_name = 'snow depth',
second_line = true,
prefer_cm = true,
color_scheme = _colorscheme('snow', 'p'),
scale_factor = '0.2',
label = makeLabel(args, options, false, 'Average extreme snow depth', 'snow depth'),
annual_mode = 'max',
},
{---------- PRECIPITATION DAYS ----------
Line 338 ⟶ 398:
mode = 'basic',
group_name = 'precipitation days',
color_scheme = _ifset_colorscheme('precip days colour', 'd'),
date_mode = true,
scale_factor = '1',
Line 348 ⟶ 408:
mode = 'basic',
group_name = 'rain days',
color_scheme = _ifset_colorscheme('precip days colour', 'd'),
date_mode = true,
scale_factor = '1',
Line 358 ⟶ 418:
mode = 'basic',
group_name = 'snow days',
color_scheme = _ifset_colorscheme('precip days colour', 'd'),
date_mode = true,
scale_factor = '1',
Line 368 ⟶ 428:
mode = 'basic',
group_name = 'humidity',
color_scheme = _ifset_colorscheme('humidity colour', 'h'),
scale_factor = '1',
label = 'Average [[relative humidity]] (%)' ..
_if('time day', ' <span style="font-size:90%;" class="nowrap">(at {{{' .. _ifset('time day}}}', '') .. ')</span>') ..
_if('daily', ' <span style="font-size:90%;" class="nowrap">(daily average)</span>'),
annual_mode = 'avg',
Line 379 ⟶ 439:
mode = 'basic',
group_name = 'afthumidity',
color_scheme = _ifset_colorscheme('humidity colour', 'h'),
scale_factor = '1',
label = 'Average afternoon [[relative humidity]] (%)' ..
_if('time day', ' <span style="font-size:90%;" class="nowrap">(at {{{' .. _ifset('time day}}}', '') .. ')</span>') ..
_if('daily', ' <span style="font-size:90%;" class="nowrap">(daily average)</span>'),
annual_mode = 'avg',
},
{---------- FIRST LINE AVERAGE DEW POINT ----------
WANTROW = _ifany(' dew point C') or _ifany(' dew point F'),
mode = 'temperature',
group_name = 'dew point',
color_scheme = _colorscheme('temperature', 't'),
scale_factor = '1',
label = 'Average [[dew point]] °' .. _if('metric first', 'C', 'F') .. _ifSingle(' (°' .. _if('metric first', 'F', 'C') .. ')'),
annual_mode = 'avg',
},
{---------- SECOND LINE AVERAGE DEW POINT----------
WANTROW = not options.wantSingleLine and (_ifany(' dew point C') or _ifany(' dew point F')),
mode = 'temperature',
group_name = 'dew point',
second_line = true,
color_scheme = _colorscheme('temperature', 't'),
scale_factor = '1',
label = 'Average [[dew point]] °' .. _if('metric first', 'F', 'C'),
show = _if('metric first', '2', '1'),
annual_mode = 'avg',
},
Line 390 ⟶ 470:
mode = 'basic',
group_name = 'sun',
color_scheme = _ifset_colorscheme('sun colour', 's'),
date_mode = true,
scale_factor = '1',
Line 400 ⟶ 480:
mode = 'basic',
group_name = 'd sun',
color_scheme = _ifset_colorscheme('sun colour', 's'),
include_space = false,
scale_factor = '30.44',
label = 'Mean daily [[Sunshine duration|sunshine hours]]',
annual_mode = 'avg',
},
{---------- DAILY DAYLIGHT HOURS ----------
WANTROW = _ifany(' light'),
mode = 'basic',
group_name = ' light',
color_scheme = _colorscheme('sun', 's'),
include_space = false,
scale_factor = '30.44',
label = 'Mean daily [[Daytime|daylight hours]]',
annual_mode = 'avg',
},
Line 410 ⟶ 500:
mode = 'basic',
group_name = 'percentsun',
color_scheme = _ifset_colorscheme('sun colour', 's'),
scale_factor = '7.2',
label = 'PercentPercentage [[Sunshine duration|possible sunshine]]',
annual_mode = 'avg',
},
Line 419 ⟶ 509:
mode = 'basic',
group_name = 'uv',
color_scheme = _ifset_colorscheme('uv colour', 'u'),
scale_factor = '1',
label = 'Average [[ultraviolet index]]',
Line 427 ⟶ 517:
makeSources(frame, args),
}
end
 
local function makeFrame(self_args, parent_args)
-- Kludge to pass arguments for a single row to buildRow.
-- Later: Refactor buildRow so this is not needed.
return {
args = self_args,
getParent = function (self) return makeFrame(parent_args, nil) end,
}
end
 
local function main(frame)
local buildRowsandbox = requireframe:getTitle('Module):Weatherfind('sandbox', box/row1, true) and '/sandbox').buildRow or ''
local buildRow = require('Module:Weather box/row' .. sandbox)._buildRow
local args = frame:getParent().args
local options = {
wantSingleLine = wantSingle(args['single line']),
sandbox = sandbox,
}
local results = {}
for i, defdefinition in ipairs(getDefinitions(frame, args, options)) do
local row
if type(defdefinition) == 'string' then
row = defdefinition
elseif defdefinition.WANTROW then
row = buildRow(makeFrame(defdefinition, args), options)
else
row = ''
Line 453 ⟶ 539:
results[i] = row
end
return string'<div>\n'..sub( table.concat(results),..'\n</div>' 2 )-- prevent Scribunto from inserting a blank line before the table
end