Module:Sandbox/Johnuniq/grosstonnage
Appearance
-- Test idea from Wnt to convert GT (gross tonnage) to/from volume.
-- Usage: {{#invoke:Sandbox/Johnuniq/grosstonnage | run_tests | vol1 | vol2 | step}}
-- where parameters vol1, vol2, step are optional numbers.
-- Using {{#invoke:sandbox/Johnuniq/grosstonnage | run_tests}}
-- sets vol1 = 0, vol2 = 100,000, step = 1000
-- which outputs results from 0 to 100,000 cubic meters, in steps of 1000.
--
-- In the debug console, can do quick calculations:
-- =p.gt(10000)
-- =p.vol(2800)
local abs = math.abs
local log10 = math.log10
local function collection()
-- Return a table to hold lines of text.
return {
n = 0,
add = function (self, s)
self.n = self.n + 1
self[self.n] = s
end,
join = function (self, sep)
return table.concat(self, sep or '\n')
end,
}
end
local function gross_tonnage(volume)
-- Return GT equivalent to given volume in cubic meters.
-- GT = (0.2 + 0.02 * log10(cubic_meters)) * cubic_meters
if volume > 0 then
return (0.2 + 0.02 * log10(volume)) * volume
end
return 0
end
local function volume_from_gt(gross_tonnage)
-- Return volume in cubic meters equivalent to given gross tonnage.
-- GT = (0.2 + 0.02 * log10(cubic_meters)) * cubic_meters
if gross_tonnage <= 0 then
return 0
end
local k_factor = 0.20
local volume = gross_tonnage / k_factor
for i = 1, 100 do
k_factor = 0.20 + 0.02 * log10(volume)
local new_volume = gross_tonnage / k_factor
if abs(new_volume - volume) < 0.1 then
return new_volume, i -- also return i for curiosity
end
volume = new_volume
end
print('Bug: Too many iterations')
return 0
end
local function run_tests(frame)
local args = frame.args
local vol1 = tonumber(args[1]) or 0
local vol2 = tonumber(args[2]) or 1e5
local step = tonumber(args[3]) or 1000
local results = collection()
results:add('<pre>')
results:add(' Vol_input Gross_ton Vol_output Iter')
for v = vol1, vol2, step do
local gt = gross_tonnage(v)
local vout, iterations = volume_from_gt(gt)
results:add(string.format('%12.2f %12.2f %12.5f %3d', v, gt, vout, iterations or 0))
end
results:add('</pre>')
return results:join()
end
return { gt = gross_tonnage, vol = volume_from_gt, run_tests = run_tests }