Module:WeatherBox
This module is rated as ready for general use. It has reached a mature form and is thought to be bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
Usage
{{#invoke:WeatherBox|function_name}}
Climate data for Edmonton City Centre (Blatchford Field) Airport (1981−2010) | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Month | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | Year |
Record high °C (°F) | 11.7 (53.1) |
14.0 (57.2) |
23.9 (75) |
31.1 (88) |
32.3 (90.1) |
34.9 (94.8) |
34.6 (94.3) |
34.5 (94.1) |
33.9 (93) |
28.6 (83.5) |
21.7 (71.1) |
16.7 (62.1) |
34.9 (94.8) |
Average high °C (°F) | −6.0 (21.2) |
−2.7 (27.1) |
2.2 (36) |
11.2 (52.2) |
17.5 (63.5) |
21.0 (69.8) |
23.1 (73.6) |
22.6 (72.7) |
17.1 (62.8) |
10.4 (50.7) |
0.0 (32) |
−4.5 (23.9) |
9.3 (48.7) |
Daily mean °C (°F) | −10.4 (13.3) |
−7.6 (18.3) |
−2.5 (27.5) |
5.4 (41.7) |
11.5 (52.7) |
15.5 (59.9) |
17.7 (63.9) |
16.9 (62.4) |
11.4 (52.5) |
5.1 (41.2) |
−4.1 (24.6) |
−8.8 (16.2) |
4.2 (39.6) |
Average low °C (°F) | −14.8 (5.4) |
−12.5 (9.5) |
−7.2 (19) |
−0.5 (31.1) |
5.4 (41.7) |
9.9 (49.8) |
12.3 (54.1) |
11.3 (52.3) |
5.8 (42.4) |
−0.2 (31.6) |
−8.2 (17.2) |
−13.1 (8.4) |
−1.0 (30.2) |
Record low °C (°F) | −44.4 (−47.9) |
−46.1 (−51) |
−36.1 (−33) |
−25.6 (−14.1) |
−12.2 (10) |
−1.1 (30) |
0.6 (33.1) |
−1.2 (29.8) |
−11.7 (10.9) |
−25.0 (−13) |
−34.1 (−29.4) |
−48.3 (−54.9) |
−48.3 (−54.9) |
Record low wind chill | −52.8 | −50.7 | −44.6 | −37.5 | −14.5 | 0.0 | 0.0 | −3.7 | −13.3 | −34.3 | −50.2 | −55.5 | −55.5 |
Average precipitation mm (inches) | 21.7 (0.854) |
12.0 (0.472) |
15.8 (0.622) |
28.8 (1.134) |
46.1 (1.815) |
77.5 (3.051) |
93.8 (3.693) |
61.9 (2.437) |
43.5 (1.713) |
21.7 (0.854) |
18.0 (0.709) |
15.0 (0.591) |
455.7 (17.941) |
Average rainfall mm (inches) | 1.3 (0.051) |
0.76 (0.0299) |
1.7 (0.067) |
14.5 (0.571) |
40.7 (1.602) |
77.5 (3.051) |
93.8 (3.693) |
61.8 (2.433) |
42.4 (1.669) |
10.9 (0.429) |
1.6 (0.063) |
0.73 (0.0287) |
347.8 (13.693) |
Average snowfall cm (inches) | 24.5 (9.65) |
13.4 (5.28) |
17.4 (6.85) |
15.3 (6.02) |
4.9 (1.93) |
0.0 (0) |
0.0 (0) |
0.0 (0) |
1.0 (0.39) |
11.6 (4.57) |
19.1 (7.52) |
16.4 (6.46) |
123.5 (48.62) |
Average precipitation days (≥ 0.2 mm) | 11.0 | 7.9 | 8.3 | 8.8 | 11.0 | 14.2 | 14.6 | 11.1 | 9.8 | 8.0 | 8.8 | 9.4 | 122.9 |
Average rainy days (≥ 0.2 mm) | 1.1 | 0.83 | 1.4 | 5.9 | 10.5 | 14.2 | 14.6 | 11.1 | 9.6 | 5.6 | 1.5 | 0.75 | 77.3 |
Average snowy days (≥ 0.2 cm) | 10.7 | 7.7 | 7.7 | 4.2 | 1.2 | 0.0 | 0.0 | 0.0 | 0.50 | 3.2 | 7.9 | 9.3 | 52.4 |
Average relative humidity (%) | 65.2 | 61.2 | 56.5 | 42.9 | 40.4 | 48.2 | 52.6 | 51.4 | 50.1 | 50.5 | 64.7 | 65.4 | 54.1 |
Mean monthly sunshine hours | 100.8 | 121.7 | 176.3 | 244.2 | 279.9 | 285.9 | 307.5 | 282.3 | 192.7 | 170.8 | 98.4 | 84.5 | 2,344.8 |
Percent possible sunshine | 40.2 | 44.1 | 48.1 | 58.2 | 56.8 | 56.2 | 60.2 | 61.5 | 50.4 | 52.0 | 37.8 | 36.0 | 50.1 |
Source: Environment Canada[1] |
References
These references will appear in the article, but this list appears only on this page.
- ↑ "Edmonton City Centre Airport". Canadian Climate Normals 1981−2010. Environment Canada. August 19, 2013. Retrieved September 10, 2013.
w = {}; math_mod = require( "Module:Math" ); wbc = require( "Module:WeatherBoxColors" ); function checkFlag( flag ) if flag == nil then return nil; 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 function w.buildRow( frame ) local mode = (frame.args.mode or 'basic'):lower(); local group_name = frame.args.group_name; local first_value_string, second_value_string; local first_value_number, second_value_number, 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 or 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 or true ); local second_line = checkFlag( frame.args.second_line ) or false; local prefer_cm = checkFlag( frame.args.prefer_cm ) or false; local result; local pframe = frame:getParent(); local imperial_first = checkFlag( frame.args['imperial first'] ); if imperial_first == nil then imperial_first = checkFlag( pframe.args['imperial first'] ); end local metric_first = checkFlag( frame.args['metric first'] ); if metric_first == nil then metric_first = checkFlag( pframe.args['metric first'] ); end local single_line = checkFlag( frame.args['single line'] ); if single_line == nil then single_line = checkFlag( pframe.args['single line'] ); end if imperial_first == nil and metric_first ~= nil then imperial_first = not metric_first; else imperial_first = true; end if mode == 'basic' then first_value_string, first_value_number = getInputs( pframe, group_name, nil, include_space ); second_value_string = nil; second_value_number = nil; elseif mode == 'temperature' then first_value_string, first_value_number = getInputs( pframe, group_name, {'C'}, include_space ); second_value_string, second_value_number = getInputs( pframe, group_name, {'F'}, include_space ); first_value_string, first_value_number, second_value_string, second_value_number = reconcileTemperature( first_value_string, first_value_number, second_value_string, second_value_number ) elseif mode == "precipitation" then first_value_string, first_value_number, variant = getInputs( pframe, group_name, {'cm', 'mm'}, include_space ); second_value_string, second_value_number = getInputs( pframe, group_name, {'inch'}, include_space ); first_value_string, first_value_number, second_value_string, second_value_number, variant = reconcilePrecipitation( first_value_string, first_value_number, second_value_string, second_value_number, variant, prefer_cm ) else error( 'Requested mode not recognized' ); end local good = false; for i = 1,13 do if first_value_string[i] ~= nil and first_value_string[i] ~= '' then good = true; break; end end if not good then return ''; end if first_value_string[13] == nil or first_value_string[13] == '' then first_value_string[13], first_value_number[13] = getAnnualValue( first_value_number, annual_mode ); end if second_value_string ~= nil then if second_value_string[13] == nil or second_value_string[13] == '' then second_value_string[13], second_value_number[13] = getAnnualValue( second_value_number, annual_mode ); end if mode == 'precipitation' then for i = 1,12 do if variant[i] ~= 0 then variant[13] = variant[i]; break; end end end end color_scheme = wbc.interpret_color_code( color_scheme ); color_values = {}; month_adj = { 31/30, 28/30, 31/30, 1, 31/30, 1, 31/30, 31/30, 1, 31/30, 1, 31/30, 12.175 }; local adj; for i = 1,13 do if first_value_number[i] ~= nil and first_value_number[i] ~= -9999 then adj = scale_factor; if date_mode then adj = adj / month_adj[i]; end if mode == "precipitation" then if variant[i] == 1 then adj = adj * 10; end end table.insert( color_values, color_scheme( first_value_number[i] * adj ) ); else table.insert( color_values, color_scheme( nil ) ); end end local lang = mw.getContentLanguage(); for i = 1,13 do if first_value_number[i] ~= nil and first_value_number[i] ~= -9999 then if math.abs(first_value_number[i]) >= 1000 then first_value_string[i] = lang:formatNum( math.abs(first_value_number[i]) ); if first_value_number[i] < 0 then first_value_string[i] = '−' .. first_value_string[i]; end elseif first_value_number[i] < 0 then first_value_string[i] = '−' .. first_value_string[i]:sub(2); end end if second_value_number ~= nil then if second_value_number[i] ~= nil and second_value_number[i] ~= -9999 then if math.abs(first_value_number[i]) >= 1000 then second_value_string[i] = lang:formatNum( math.abs(second_value_number[i]) ); if second_value_number[i] < 0 then second_value_string[i] = '−' .. second_value_string[i]; end elseif second_value_number[i] < 0 then second_value_string[i] = '−' .. second_value_string[i]:sub(2); end end end end if imperial_first and second_value_string ~= nil then local t = first_value_string; first_value_string = second_value_string; second_value_string = t; end if not single_line then if second_line and second_value_string ~= nil then first_value_string = second_value_string; end second_value_string = nil; end return makeLine( label, first_value_string, second_value_string, color_values, color_scheme ); end function makeLine( label, first_value_string, second_value_string, color_values, color_scheme ) local result, color_str, value_str; result = {'|- \n! height="16" | ', label, "\n"} for i = 1,13 do 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 value_str = first_value_string[i]; if value_str ~= '' and value_str ~= nil then table.insert( result, value_str ); if second_value_string ~= nil then value_str = second_value_string[i]; if value_str ~= '' and value_str ~= nil then table.insert( result, "<br /> (" .. value_str .. ")" ); end end else table.insert( result, '—' ); end table.insert( result, "\n" ); end return table.concat( result ); end 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, str2, val; local output_string = {}; local output_value = {}; local variant = {}; if suffix == nil then for _, 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 val, str2 = math_mod._cleanNumber( str ); if val ~= nil then table.insert( output_string, str2 ); table.insert( output_value, val ); else table.insert( output_string, str ); table.insert( output_value, -9999 ); end end else local updated = false; for _, mon in ipairs( month_names ) do updated = false; for i, 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 val, str2 = math_mod._cleanNumber( str ); if val ~= nil then table.insert( output_string, str2 ); table.insert( output_value, val ); else table.insert( output_string, str ); table.insert( output_value, -9999 ); end table.insert( variant, i ); updated = true; break; end end if not updated then table.insert( output_string, '' ); table.insert( output_value, -9999 ); table.insert( variant, 0 ); end end end return output_string, output_value, variant; end function getAnnualValue( values, mode ) local total = 0; local val = 0; if mode == 'avg' or mode == 'sum' then local p1, p2; p1 = 0; for i = 1, 12 do val = values[i]; if val == -9999 then return '', -9999; end p2 = math_mod._precision( val ); if p2 > p1 then p1 = p2; end total = total + val; end if mode == 'avg' then total = math_mod._round( total / 12, p1 + 1 ); end return tostring( total ), total; elseif mode == 'min' then local min_val = nil; for i = 1, 12 do val = values[i]; if val ~= -9999 then if min_val == nil or val < min_val then min_val = val; end end end return tostring( min_val ), min_val; elseif mode == 'max' then local max_val = nil; for i = 1, 12 do val = values[i]; if val ~= -9999 then if max_val == nil or val > max_val then max_val = val; end end end return tostring(max_val), max_val; else error( 'Unrecognized Annual Mode' ); end end function reconcileTemperature( C_degree_strings, C_degree_values, F_degree_strings, F_degree_values ) local p; for i = 1,13 do if C_degree_strings[i] == '' then if F_degree_values[i] ~= -9999 then p = math.max( 0, math_mod._precision( F_degree_strings[i] ) ); C_degree_values[i] = math_mod._round( (F_degree_values[i] - 32)*5/9, p ); C_degree_strings[i] = tostring( C_degree_values[i] ); end elseif F_degree_strings[i] == '' then if C_degree_values[i] ~= -9999 then p = math.max( 0, math_mod._precision( C_degree_strings[i] ) ); F_degree_values[i] = math_mod._round( C_degree_values[i]*9/5 + 32, p ); F_degree_strings[i] = tostring( F_degree_values[i] ); end end end return C_degree_strings, C_degree_values, F_degree_strings, F_degree_values; end function reconcilePrecipitation( M_degree_strings, M_degree_values, I_degree_strings, I_degree_values, variant, prefer_cm ) local p; local v_class = 0; for i = 1,13 do if variant[i] == 1 then v_class = 1; elseif variant[i] == 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 if M_degree_strings[i] == '' then if I_degree_values[i] ~= -9999 then if v_class == 1 then p = math.max( 0, math_mod._precision( I_degree_strings[i] ) ); M_degree_values[i] = math_mod._round( I_degree_values[i]*2.54, p ); variant[i] = v_class; else p = math.max( 0, math_mod._precision( I_degree_strings[i] ) ) - 1; M_degree_values[i] = math_mod._round( I_degree_values[i]*25.4, p ); variant[i] = v_class; end M_degree_strings[i] = tostring( M_degree_values[i] ); end elseif I_degree_strings[i] == '' then if M_degree_values[i] ~= -9999 then if variant[i] == 1 then p = math.max( 0, math_mod._precision( M_degree_strings[i] ) ) + 1; I_degree_values[i] = M_degree_values[i]/2.54; else p = math.max( 0, math_mod._precision( M_degree_strings[i] ) ) + 2; I_degree_values[i] = M_degree_values[i]/25.4; end I_degree_values[i] = math_mod._round( I_degree_values[i], p ); I_degree_strings[i] = tostring( I_degree_values[i] ); end end end return M_degree_strings, M_degree_values, I_degree_strings, I_degree_values, variant; end return w;