<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3AWeather</id>
	<title>Module:Weather - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3AWeather"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Weather&amp;action=history"/>
	<updated>2026-05-06T22:43:29Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Weather&amp;diff=147625&amp;oldid=prev</id>
		<title>imported&gt;Erutuon: merge multi-line comments</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Weather&amp;diff=147625&amp;oldid=prev"/>
		<updated>2017-03-10T03:22:20Z</updated>

		<summary type="html">&lt;p&gt;merge multi-line comments&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[&lt;br /&gt;
Efficient (fast) functions to implement cells in tables of weather data.&lt;br /&gt;
Temperature conversion is built-in, but for simplicity, temperatures&lt;br /&gt;
are assumed to be for habitable locations (from -100 to 100 °C).&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local MINUS = &amp;#039;−&amp;#039;  -- Unicode U+2212 MINUS SIGN&lt;br /&gt;
&lt;br /&gt;
local function temperature_style(palette, value, out_rgb)&lt;br /&gt;
	-- Return style for a table cell based on the given value which&lt;br /&gt;
	-- should be a temperature in °C.&lt;br /&gt;
	local function style(bg, fg)&lt;br /&gt;
		local min, max = unpack(palette.white or { -23, 35 })&lt;br /&gt;
		if not fg and value and (value &amp;lt; min or value &amp;gt;= max) then&lt;br /&gt;
			fg = &amp;#039;FFFFFF&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		if fg then&lt;br /&gt;
			fg = &amp;#039;color:#&amp;#039; .. fg .. &amp;#039;;&amp;#039;&lt;br /&gt;
		else&lt;br /&gt;
			fg = &amp;#039;&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		return &amp;#039;style=&amp;quot;background:#&amp;#039; .. bg .. &amp;#039;;&amp;#039; .. fg .. &amp;#039; font-size:100%;&amp;quot;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if type(value) ~= &amp;#039;number&amp;#039; then&lt;br /&gt;
		return style(&amp;#039;FFFFFF&amp;#039;, &amp;#039;000000&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	local rgb = out_rgb or {}&lt;br /&gt;
	for i, v in ipairs(palette) do&lt;br /&gt;
		local a, b, c, d = unpack(v)&lt;br /&gt;
		if value &amp;lt;= a then&lt;br /&gt;
			rgb[i] = 0&lt;br /&gt;
		elseif value &amp;lt; b then&lt;br /&gt;
			rgb[i] = (value - a) * 255 / (b - a)&lt;br /&gt;
		elseif value &amp;lt;= c then&lt;br /&gt;
			rgb[i] = 255&lt;br /&gt;
		elseif value &amp;lt; d then&lt;br /&gt;
			rgb[i] = 255 - ( (value - c) * 255 / (d - c) )&lt;br /&gt;
		else&lt;br /&gt;
			rgb[i] = 0&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return style(string.format(&amp;#039;%02X%02X%02X&amp;#039;, rgb[1], rgb[2], rgb[3]))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function format_cell(palette, value, intext, outtext)&lt;br /&gt;
	-- Return one line of wikitext to make a cell in a table.&lt;br /&gt;
	if not value then&lt;br /&gt;
		return &amp;#039;|\n&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	local text&lt;br /&gt;
	if outtext then&lt;br /&gt;
		text = intext .. &amp;#039;&amp;lt;br&amp;gt;(&amp;#039; .. outtext .. &amp;#039;)&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		text = intext&lt;br /&gt;
	end&lt;br /&gt;
	return &amp;#039;| &amp;#039; .. temperature_style(palette, value) .. &amp;#039; | &amp;#039; .. text .. &amp;#039;\n&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function process_temperature(intext, inunit, swap)&lt;br /&gt;
	--[[	Convert °C to °F or vice versa, assuming the temperature is for a&lt;br /&gt;
			habitable location, well inside the range -100 to 100 °C.&lt;br /&gt;
			That simplifies determining precision and formatting (no commas are needed).&lt;br /&gt;
			Return (celsius_value, intext, outtext) if valid; otherwise return nil.&lt;br /&gt;
			The returned input and output are swapped if requested.&lt;br /&gt;
			Each returned string has a Unicode MINUS as sign, if negative.	]]&lt;br /&gt;
	local invalue = tonumber(intext)&lt;br /&gt;
	if not invalue then return nil end&lt;br /&gt;
	local integer, dot, decimals = intext:match(&amp;#039;^%s*%-?(%d+)(%.?)(%d*)%s*$&amp;#039;)&lt;br /&gt;
	if not integer then return nil end&lt;br /&gt;
	if invalue &amp;lt; 0 then&lt;br /&gt;
		intext = MINUS .. integer .. dot .. decimals&lt;br /&gt;
	end&lt;br /&gt;
	local outtext&lt;br /&gt;
	if inunit == &amp;#039;C&amp;#039; or inunit == &amp;#039;F&amp;#039; then&lt;br /&gt;
		local celsius_value, outvalue&lt;br /&gt;
		if inunit == &amp;#039;C&amp;#039; then&lt;br /&gt;
			outvalue = invalue * (9/5) + 32&lt;br /&gt;
			celsius_value = invalue&lt;br /&gt;
		else&lt;br /&gt;
			outvalue = (invalue - 32) * (5/9)&lt;br /&gt;
			celsius_value = outvalue&lt;br /&gt;
		end&lt;br /&gt;
		local precision = dot == &amp;#039;&amp;#039; and 0 or #decimals&lt;br /&gt;
		outtext = string.format(&amp;#039;%.&amp;#039; .. precision .. &amp;#039;f&amp;#039;, math.abs(outvalue) + 2e-14)&lt;br /&gt;
		if outvalue &amp;lt; 0 and tonumber(outtext) ~= 0 then&lt;br /&gt;
			-- Don&amp;#039;t show minus if result is negative but rounds to zero.&lt;br /&gt;
			outtext = MINUS .. outtext&lt;br /&gt;
		end&lt;br /&gt;
		if swap then&lt;br /&gt;
			return celsius_value, outtext, intext&lt;br /&gt;
		end&lt;br /&gt;
		return celsius_value, intext, outtext&lt;br /&gt;
	end&lt;br /&gt;
	-- LATER Think about whether a no-conversion option would be useful.&lt;br /&gt;
	return invalue, intext, outtext&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function temperature_row(palette, row, inunit, swap)&lt;br /&gt;
	--[[&lt;br /&gt;
	Return 13 lines specifying the style/content of 13 table cells.&lt;br /&gt;
	Input is 13 space-separated words, each a number (°C or °F).&lt;br /&gt;
	Any word that is not a number gives a blank cell (&amp;quot;M&amp;quot; for a missing cell).&lt;br /&gt;
	Any excess words are ignored.&lt;br /&gt;
	&lt;br /&gt;
	Function  Input   Output&lt;br /&gt;
	------------------------&lt;br /&gt;
	CtoF        C       C/F&lt;br /&gt;
	FfromC      C       F/C&lt;br /&gt;
	CfromF      F       C/F&lt;br /&gt;
	FtoC        F       F/C		]]&lt;br /&gt;
	local nrcol = 13&lt;br /&gt;
	local results, n = {}, 0&lt;br /&gt;
	for word in row:gmatch(&amp;#039;%S+&amp;#039;) do&lt;br /&gt;
		n = n + 1&lt;br /&gt;
		if n &amp;gt; nrcol then&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
		results[n] = format_cell(palette, process_temperature(word, inunit, swap))&lt;br /&gt;
	end&lt;br /&gt;
	for i = n + 1, nrcol do&lt;br /&gt;
		results[i] = format_cell()&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(results)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local palettes = {&lt;br /&gt;
	-- A background color entry in a palette is a table of four numbers,&lt;br /&gt;
	-- say { 11, 22, 33, 44 } (values in °C).&lt;br /&gt;
	-- That means the color is 0 below 11 and above 44, and is 255 from 22 to 33.&lt;br /&gt;
	-- The color rises from 0 to 255 between 11 and 22, and falls between 33 and 44.&lt;br /&gt;
	cool = {&lt;br /&gt;
		{ -42.75,   4.47, 41.5, 60   },&lt;br /&gt;
		{ -42.75,   4.47,  4.5, 41.5 },&lt;br /&gt;
		{ -90   , -42.78,  4.5, 23   },&lt;br /&gt;
		white = { -23.3, 37.8 },&lt;br /&gt;
	},&lt;br /&gt;
	cool2 = {&lt;br /&gt;
		{ -42.75,   4.5 , 41.5, 56   },&lt;br /&gt;
		{ -42.75,   4.5 ,  4.5, 41.5 },&lt;br /&gt;
		{ -90   , -42.78,  4.5, 23   },&lt;br /&gt;
		white = { -23.3, 35 },&lt;br /&gt;
	},&lt;br /&gt;
	cool2avg = {&lt;br /&gt;
		{ -38,   4.5, 25  , 45   },&lt;br /&gt;
		{ -38,   4.5,  4.5, 30   },&lt;br /&gt;
		{ -70, -38  ,  4.5, 23   },&lt;br /&gt;
		white = { -23.3, 25 },&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function temperatures(frame, inunit, swap)&lt;br /&gt;
	local palette = palettes[frame.args.palette] or palettes.cool&lt;br /&gt;
	return temperature_row(palette, frame.args[1], inunit, swap)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function CtoF(frame)&lt;br /&gt;
	return temperatures(frame, &amp;#039;C&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function CfromF(frame)&lt;br /&gt;
	return temperatures(frame, &amp;#039;F&amp;#039;, true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function FtoC(frame)&lt;br /&gt;
	return temperatures(frame, &amp;#039;F&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function FfromC(frame)&lt;br /&gt;
	return temperatures(frame, &amp;#039;C&amp;#039;, true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local chart = [[&lt;br /&gt;
{{Graph:Chart&lt;br /&gt;
|width=600&lt;br /&gt;
|height=180&lt;br /&gt;
|xAxisTitle=Celsius&lt;br /&gt;
|yAxisTitle=__COLOR&lt;br /&gt;
|type=line&lt;br /&gt;
|x=__XVALUES&lt;br /&gt;
|y=__YVALUES&lt;br /&gt;
|colors=__COLOR&lt;br /&gt;
}}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function show(frame)&lt;br /&gt;
	--[[	For testing, return wikitext to show graphs of how the red/green/blue colors&lt;br /&gt;
			vary with temperature, and a table of the resulting colors.		]]&lt;br /&gt;
	local function collection()&lt;br /&gt;
		-- Return a table to hold items.&lt;br /&gt;
		return {&lt;br /&gt;
			n = 0,&lt;br /&gt;
			add = function (self, item)&lt;br /&gt;
				self.n = self.n + 1&lt;br /&gt;
				self[self.n] = item&lt;br /&gt;
			end,&lt;br /&gt;
			join = function (self, sep)&lt;br /&gt;
				return table.concat(self, sep)&lt;br /&gt;
			end,&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	local function make_chart(result, color, xvalues, yvalues)&lt;br /&gt;
		result:add(&amp;#039;\n&amp;#039;)&lt;br /&gt;
		result:add(frame:preprocess((chart:gsub(&amp;#039;__[A-Z]+&amp;#039;, {&lt;br /&gt;
			__COLOR = color,&lt;br /&gt;
			__XVALUES = xvalues:join(&amp;#039;,&amp;#039;),&lt;br /&gt;
			__YVALUES = yvalues:join(&amp;#039;,&amp;#039;),&lt;br /&gt;
		}))))&lt;br /&gt;
	end&lt;br /&gt;
	local function with_minus(value)&lt;br /&gt;
		if value &amp;lt; 0 then&lt;br /&gt;
			return MINUS .. tostring(-value)&lt;br /&gt;
		end&lt;br /&gt;
		return tostring(value)&lt;br /&gt;
	end&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local first = args[1] or -90&lt;br /&gt;
	local last = args[2] or 59&lt;br /&gt;
	local palette = palettes[args.palette] or palettes.cool&lt;br /&gt;
	local xvals, reds, greens, blues = collection(), collection(), collection(), collection()&lt;br /&gt;
	local wikitext = collection()&lt;br /&gt;
	wikitext:add(&lt;br /&gt;
[[&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
]]&lt;br /&gt;
	)&lt;br /&gt;
	local columns = 0&lt;br /&gt;
	for celsius = first, last do&lt;br /&gt;
		local rgb = {}&lt;br /&gt;
		local style = temperature_style(palette, celsius, rgb)&lt;br /&gt;
		local R = math.floor(rgb[1])&lt;br /&gt;
		local G = math.floor(rgb[2])&lt;br /&gt;
		local B = math.floor(rgb[3])&lt;br /&gt;
		xvals:add(celsius)&lt;br /&gt;
		reds:add(R)&lt;br /&gt;
		greens:add(G)&lt;br /&gt;
		blues:add(B)&lt;br /&gt;
		wikitext:add(&amp;#039;| &amp;#039; .. style .. &amp;#039; | &amp;#039; .. with_minus(celsius) .. &amp;#039;\n&amp;#039;)&lt;br /&gt;
		columns = columns + 1&lt;br /&gt;
		if columns &amp;gt;= 10 then&lt;br /&gt;
			columns = 0&lt;br /&gt;
			wikitext:add(&amp;#039;|-\n&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	wikitext:add(&amp;#039;|}\n&amp;#039;)&lt;br /&gt;
	make_chart(wikitext, &amp;#039;Red&amp;#039;, xvals, reds)&lt;br /&gt;
	make_chart(wikitext, &amp;#039;Green&amp;#039;, xvals, greens)&lt;br /&gt;
	make_chart(wikitext, &amp;#039;Blue&amp;#039;, xvals, blues)&lt;br /&gt;
	return wikitext:join()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	CtoF = CtoF,&lt;br /&gt;
	CfromF = CfromF,&lt;br /&gt;
	FtoC = FtoC,&lt;br /&gt;
	FfromC = FfromC,&lt;br /&gt;
	show = show,&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>imported&gt;Erutuon</name></author>
	</entry>
</feed>