Jump to content
 







Main menu
   


Navigation  



Main page
Contents
Current events
Random article
About Wikipedia
Contact us
Donate
 




Contribute  



Help
Learn to edit
Community portal
Recent changes
Upload file
 








Search  

































Create account

Log in
 









Create account
 Log in
 




Pages for logged out editors learn more  



Contributions
Talk
 

















Module:Weather box/row






العربية
Azərbaycanca

Čeština
Dansk
الدارجة


Hausa
Ilokano

Kernowek
Македонски


Occitan
Oʻzbekcha / ўзбекча
Scots
Slovenščina
کوردی
Српски / srpski
Suomi
Twi
Vèneto
Tiếng Vit

 

Edit links
 









Module
Talk
 

















Read
View source
View history
 








Tools
   


Actions  



Read
View source
View history
 




General  



What links here
Related changes
Upload file
Special pages
Permanent link
Page information
Get shortened URL
Download QR code
Wikidata item
 




Print/export  



Download as PDF
Printable version
 




In other projects  



Wikibooks
 
















Appearance
   

 





Permanently protected module

From Wikipedia, the free encyclopedia
 

< Module:Weather box

local math_mod = require('Module:Math')

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
  table.insert(result,
   '|style="' .. color_values[i] ..
   (i == 13 and ' border-left-width:medium"' or '"') ..
   ' class="notheme"| '
  )
  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(args, 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 = args[ mon .. ' ' .. group_name ] or ''
   else
    str = 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 = args[ mon .. ' ' .. group_name .. ' ' .. suf ]
    else
     str = 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

local function _buildRow(definition, args, options)
 options = options or {}
 local wbc = require('Module:Weather box/colors' .. (options.sandbox or ''))
 local mode = (definition.mode or 'basic'):lower()
 local group_name = definition.group_name
 local first_values, second_values
 local color_values
 local color_scheme = definition.color_scheme or 't'
 local scale_factor = math_mod._cleanNumber(definition.scale_factor) or 1
 local date_mode = checkFlag(definition.date_mode, false)
 local label = definition.label or ''
 local annual_mode = (definition.annual_mode or 'avg'):lower()
 local include_space = checkFlag(definition.include_space, true)
 local second_line = checkFlag(definition.second_line, false)
 local prefer_cm = checkFlag(definition.prefer_cm, false)
 local imperial_first = checkFlag(args['imperial first'])
 local metric_first = checkFlag(args['metric first'])
 local wantSingleLine = options.wantSingleLine or checkFlag(args['single line'])
 local trace = 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(args, group_name, nil, include_space)
  second_values = nil
 elseif mode == 'temperature' then
  first_values = getInputs(args, group_name, {'C'}, include_space)
  second_values = getInputs(args, group_name, {'F'}, include_space)
  reconcileTemperature(first_values, second_values)
 elseif mode == "precipitation" then
  first_values = getInputs(args, group_name, {'cm', 'mm'}, include_space)
  second_values = getInputs(args, 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 wantSingleLine 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

local function buildRow(frame)
 return _buildRow(frame.args, frame:getParent().args)  -- row definition, template parameters
end

return {
 buildRow = buildRow,
 _buildRow = _buildRow,
}

Retrieved from "https://en.wikipedia.org/w/index.php?title=Module:Weather_box/row&oldid=1189173848"

Hidden category: 
Wikipedia template-protected modules
 



This page was last edited on 10 December 2023, at 05:26 (UTC).

Text is available under the Creative Commons Attribution-ShareAlike License 4.0; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization.



Privacy policy

About Wikipedia

Disclaimers

Contact Wikipedia

Code of Conduct

Developers

Statistics

Cookie statement

Mobile view



Wikimedia Foundation
Powered by MediaWiki