Module:Temperature

From Wikibooks, open books for an open world
Jump to: navigation, search
Documentation[edit] [history] [purge]

This module will convert a temperature from one unit to many others in a call to {{H:title}}.

Usage[edit]

In prose:

{{#invoke:Temperature|f|350}}
350°F
{{#invoke:Temperature|c|220}}
220°C
{{#invoke:Temperature|gm|4}}
Gas mark 4
{{#invoke:Temperature|k|490}}
490K
-- Module for temperature conversion
 
local refgroup = 'Temp'
 
local output_temp = {
	f = function ( val )
		return val .. '°F'
	end,
 
	c = function ( val )
		return val .. '°C'
	end,
 
	gm = function ( val )
		return 'Gas mark ' .. val
	end,
 
	k = function ( val )
		return val .. 'K'
	end
}
 
-- All ranges in celsius
local gmranges = {
	{
		start = 93,
		finish = 120,
		best = 107,
		val = '1/4'
	},
 
	{
		start = 120,
		finish = 134,
		best = 121,
		val = '1/2'
	},
 
	{
		start = 135,
		finish = 140,
		best = 135,
		val = '1'
	},
 
	{
		start = 141,
		finish = 150,
		best = 149,
		val = '2'
	},
 
	{
		start = 151,
		finish = 170,
		best = 163,
		val = '3'
	},
 
	{
		start = 171,
		finish = 180,
		best = 177,
		val = '4'
	},
 
	{
		start = 181,
		finish = 191,
		best = 190,
		val = '5'
	},
 
	{
		start = 192,
		finish = 217,
		best = 200,
		val = '6'
	},
 
	{
		start = 205,
		finish = 220,
		best = 218,
		val = '7'
	},
 
	{
		start = 221,
		finish = 232,
		best = 230,
		val = '8'
	},
 
	{
		start = 233,
		finish = 250,
		best = 246,
		val = '9'
	},
 
	{
		start = 251,
		finish = 260,
		best = 260,
		val = '10'
	}
}
 
local build_ref_from_table = function ( frame, basetemp, temps )
	local reflist = {}
	local baseval
 
	for _, temp in ipairs( temps ) do
		local val = output_temp[temp[1]]( temp[2] )
 
		if temp[1] == basetemp then
			baseval = val
			table.insert( reflist, 1, val )
		else
			table.insert( reflist, val )
		end
	end
 
	return frame:expandTemplate{ title = 'H:title', args = { table.concat( reflist, ' = ' ), baseval } }
end
 
local conversions, convert
 
conversions = {
	f = {
		c = function ( val )
			return ( val - 32.0 ) * ( 5.0 / 9.0 )
		end,
 
		k = function ( val )
			return convert( 'c', 'k', convert( 'f', 'c', val ) )
		end,
 
		gm = function ( val )
			return convert( 'c', 'gm', convert( 'f', 'c', val ) )
		end
	},
 
	c = {
		f = function ( val )
			return ( val * ( 9.0 / 5.0 ) ) + 32.0
		end,
 
		k = function ( val )
			return val + 273.15;
		end,
 
		gm = function ( val )
			val = tonumber( val )
 
			if val == nil then
				return nil
			end
 
			for _, range in ipairs( gmranges ) do
				if val > range.start and val <= range.finish then
					return range.val
				end
			end
 
			return nil
		end
	},
 
	gm = {
		f = function ( val )
			return convert( 'c', 'f', convert( 'gm', 'c', val ) )
		end,
 
		c = function ( val )
			for _, range in ipairs( gmranges ) do
				if val == range.val then
					return range.best
				end
			end
 
			return nil
		end,
 
		k = function ( val )
			return convert( 'c', 'k', convert( 'gm', 'c', val ) )
		end
	},
 
	k = {
		f = function ( val )
			return convert( 'c', 'f', ( val - 273.15 ) )
		end,
 
		c = function ( val )
			return val - 273.15
		end,
 
		gm = function ( val )
			return convert( 'c', 'gm', convert( 'k', 'c', val ) )
		end
	}
}
 
convert = function ( from, to, val )
	return conversions[from][to]( val )
end
 
local templist = {
	'f',
	'c',
	'gm',
	'k'
}
 
local build_table = function ( basetemp, baseval )
	local tbl = {}
	local thisVal = nil
 
	for _, temp in ipairs( templist ) do
		if temp == basetemp then
			table.insert( tbl, { temp, baseval } )
		else
			thisVal = convert( basetemp, temp, baseval )
			if thisVal ~= nil then
				table.insert( tbl, { temp, math.floor( thisVal ) } )
			end
		end
	end
 
	return tbl
end
 
local build_ref = function ( basetemp, frame )
	return build_ref_from_table( frame, basetemp, build_table( basetemp, frame.args[1] ) )
end
 
return {
	f = function ( frame )
		return build_ref( 'f', frame )
	end,
 
	c = function ( frame )
		return build_ref( 'c', frame )
	end,
 
	k = function ( frame )
		return build_ref( 'k', frame )
	end,
 
	gm = function ( frame )
		return build_ref( 'gm', frame )
	end
}