Permanently protected module

Module:WeatherBox

From Wikipedia, the free encyclopedia
Jump to navigation Jump to search
Module documentation[view] [edit] [history] [purge]

Usage

This module is used by {{Weather box}}.

{{#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

  1. ^ "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.25/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 = {'|- style="text-align: center;"\n! scope="row" style="height: 16px;" | ', 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 );
        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;