Модуль:Math/тести![]()
Використання з іншим модулем LuaЩоб використовувати цей модуль на звичайних вікісторінках, спеціальні знання не потрібні. Якщо ви використовуєте цей модуль з іншим модулем Lua, то вам спочатку потрібно його завантажити як на прикладі: local mm = require('Module:Math')
(Змінна Більшість функцій модуля є у версії для Lua й у версії для #invoke. Можна використовувати функції #invoke з іншими модулями Lua, але використання функції Lua має перевагу в тому, що вам не потрібно отримувати доступ до Lua frame object. Функціям Lua передує random{{#invoke:math|random}} {{#invoke:math|random|max_value}} {{#invoke:math|random|min_value|max_value}} mm._random()
mm._random(max_value)
mm._random(min_value, max_value)
Генерує випадкове число.
Функція не працюватиме належним чином для чисел менше -2^32 і більше, ніж 2^32 - 1 (може змінюватися залежно від обладнання). Якщо вам потрібно використовувати цифри поза цим діапазоном, рекомендується використовувати en:Module:Random. order{{#invoke:math|order|n}} mm._order(n)
Визначає порядок величини числа. precision{{#invoke:math|precision|n}} {{#invoke:math|precision|x=n}} mm._precision(number_string)
Визначає точність числа. Наприклад, для "4" поверне "0", для "4.567" поверне "3", і для "100" поверне "-2". Функція намагається проаналізувати строкове подання числа, і виявляє, чи використовує число у експоненціальному записі. З цієї причини коли викликається з Lua, дуже великі або дуже точні цифри, вони повинні відразу надходити як рядки задля отримання точного результату. Якщо вони вводяться як числа, інтерпретатор Lua зміниться їх експоненціальним записом і ця функція поверне точний експоненціальний запис, а не розмір початкового числа. Це не проблема, коли число викликається з #invoke, завдяки участі #invoke все подається в рядковому форматі. max{{#invoke:math|max|v1|v2|v3|...}} mm._max(v1, v2, v3, ...)
Повертає максимальне значення із вказаних значень. Значення, які не можуть бути перетворені в числа, ігноруються. median{{#invoke:math|median|v1|v2|v3|...}} mm._median(v1, v2, v3, ...)
Повертає значення медіани з вказаних значень. Значення, які не можуть бути перетворені в числа, ігноруються. min{{#invoke:math|min|v1|v2|v3|...}} mm._min(v1, v2, v3, ...)
Повертає мінімальне значення із вказаних значень. Значення, які не можуть бути перетворені в числа, ігноруються. sum{{#invoke:math|sum|v1|v2|v3|...}} mm._sum(v1, v2, v3, ...)
Повертає суму зазначених значень. Значення, які не можуть бути перетворені в числа, ігноруються. average{{#invoke:math|average|v1|v2|v3|...}} mm._average(v1, v2, v3, ...)
Повертає середнє значення із вказаних. (Точніше, це значення відповідає середньому арифметичному.) Значення, які не можуть бути перетворені в числа, ігноруються. round{{#invoke:math|round|value|precision}} {{#invoke:math|round|value=value|precision=precision}} mm._round(value, precision)
Округлює число до заданої точності як степені 10 (стандартним значення є Це робиться за наступною формулою: Зверніть увагу: Станом на жовтень 2019, є баг у відображені деяких округлених чисел. Коли намагатися округлити число, що округлюється до «n.0», як «1.02», до найближчого десятка (тобто log10{{#invoke:math | log10 | x}} mm._log10(x)
Повертає mod{{#invoke:math|mod|x|y}} mm._mod(x, y)
Отримує gcd{{#invoke:math|gcd|v1|v2|...}} mm._gcd(v1, v2, ...)
Знаходить найбільший спільний дільник із встановленого значення. Значення, які не можуть бути перетворені в числа, ігноруються. precision_format{{#invoke:math|precision_format|value_string|precision}} mm._precision_format(value_string, precision)
Заокруглення числа із зазначеною точністю і форматом відповідно до правил спочатку використовувалися для {{Rnd}}. Видається рядком. Параметр precision повинен бути цілим числом цифр після десяткової коми. Дозволяються від'ємні значення. Нецілі числа дають неочікувані результати. Додатні значення більші ніж зазначена точність додають відступи нулями, від'ємні значення більша ніж зазначений порядок можуть поглинути усі цифри. Оформлення 8765,567 з
divide{{#invoke:Math|divide|x|y|round=|precision=}} mm._divide(x, y, round, precision)
Ділення x на y.
Якщо будь-який аргумент містить теги HTML, то вони повертаються незміненими, дозволяючи передавати будь-які помилки, які виникли під час обрахування аргументів функцією ділення, шаблону, який викликається. cleanNumberlocal number, number_string = mm._cleanNumber(number_string)
Допоміжна функція, яка може бути викликана з інших модулів Lua, але не від #invoke. Вона приймає рядкове або числове значення як вхідних даних, і, якщо значення може бути перетворено в число, cleanNumber повертає число і рядок цифр. Якщо значення не може бути перетворено в число, cleanNumber повертає
-- Unit tests for [[Module:Math/sandbox]]. Click talk page to run tests.
local moduleName = 'Math/пісочниця' -- assigning this to a variable as it is later used to generate an #invoke statement.
local mm = require('Module:' .. moduleName)
local ScribuntoUnit = require('Module:ScribuntoUnit')
local suite = ScribuntoUnit:new()
-------------------------------------------------------------------------------
-- Helper functions
-------------------------------------------------------------------------------
function suite.err(msg)
return mw.ustring.format('<strong class="error">Formatting error: %s</strong>', msg)
end
function suite.getLuaResult(funcName, args)
args = args or {}
local result = mm['_' .. funcName](unpack(args))
return result
end
function suite:assertLuaEquals(expected, funcName, args)
args = args or {}
self:assertEquals(expected, self.getLuaResult(funcName, args))
end
function suite.buildInvocation(funcName, args)
args = args or {}
local argsClone = mw.clone(args)
-- Build a module invocation equivalent to the args table. Taken from [[Module:Unsubst]].
-- Numbered args first.
local ret = '{{#invoke:' .. moduleName .. '|' .. funcName
for k, v in ipairs(argsClone) do
v = tostring(v)
if string.find(v, '=', 1, true) then
-- likely something like 1=foo=bar, we need to do it as a named arg
break
end
ret = ret .. '|' .. v
argsClone[k] = nil
end
for k, v in pairs(argsClone) do
k = tostring(k)
v = tostring(v)
ret = ret .. '|' .. k .. '=' .. v
end
return ret .. '}}'
end
function suite:getInvokeResult(funcName, args, convertNumber) -- Unless convertNumber is false, the number is converted to a number, if possible, on re-entry to Lua.
args = args or {}
local invocation = self.buildInvocation(funcName, args)
local result = self.frame:preprocess(invocation)
if convertNumber ~= false and tonumber(result) then
return tonumber(result)
else
return result
end
end
function suite:assertInvokeEquals(expected, funcName, args, convertNumber)
args = args or {}
local invokeResult = self:getInvokeResult(funcName, args, convertNumber)
self:assertEquals(expected, invokeResult)
end
function suite:assertLuaAndInvokeTrue(trueFunc, funcName, args, convertNumber)
args = args or {}
local invokeResult = self:getInvokeResult(funcName, args, convertNumber)
local luaResult = self.getLuaResult(funcName, args)
self:assertTrue(trueFunc(invokeResult))
self:assertTrue(trueFunc(luaResult))
end
function suite:assertLuaAndInvokeEqual(funcName, testTable, convertNumber)
local expected = testTable[1]
local args = testTable[2] or {}
self:assertLuaEquals(expected, funcName, args)
self:assertInvokeEquals(expected, funcName, args, convertNumber)
end
function suite:assertLuaAndInvokeEqualMany(funcName, testTables, convertNumber)
for i, testTable in ipairs(testTables) do
self:assertLuaAndInvokeEqual(funcName, testTable, convertNumber)
end
end
-------------------------------------------------------------------------------
-- Test random
-------------------------------------------------------------------------------
function suite:test_random()
self:assertLuaAndInvokeTrue(function (n) return n >= 0 and n < 1 end, 'random')
self:assertLuaAndInvokeTrue(function (n) return n == 1 or n == 2 end, 'random', {2})
self:assertLuaAndInvokeTrue(function (n) return n >= 1 and n <= 10 and math.floor(n) == n end, 'random', {10})
self:assertLuaAndInvokeTrue(function (n) return n >= 10 and n <= 20 and math.floor(n) == n end, 'random', {10, 20})
end
-------------------------------------------------------------------------------
-- Test max
-------------------------------------------------------------------------------
function suite:test_max()
local tests = {
{9, {5, 6, 9}},
{-5, {-5, -6, -9}},
}
self:assertLuaAndInvokeEqualMany('max', tests)
self:assertLuaEquals(nil, 'max', {})
self:assertInvokeEquals('', 'max', {})
end
-------------------------------------------------------------------------------
-- Test average
-------------------------------------------------------------------------------
function suite:test_average()
local tests = {
{6, {5, 6, 7}},
{-7, {-7}},
{10000000002, {10000000001, 10000000002, 10000000003}},
}
self:assertLuaAndInvokeEqualMany('average', tests)
end
-------------------------------------------------------------------------------
-- Test min
-------------------------------------------------------------------------------
function suite:test_min()
local tests = {
{1, {1, 2, 3}},
{-3, {-1, -2, -3}},
}
self:assertLuaAndInvokeEqualMany('min', tests)
self:assertLuaEquals(nil, 'min', {})
self:assertInvokeEquals('', 'min', {})
end
-------------------------------------------------------------------------------
-- Test gcd
-------------------------------------------------------------------------------
function suite:test_gcd()
local tests = {
{4, {12, 8}},
{2, {12, 8, 6}},
{4, {-12, -8}},
{2, {-12, -8, -6}},
{8, {0, 8}},
{8, {0, -8}},
{0, {0}},
{0, {0, 0}},
{4, {12, nil, 8}},
}
self:assertLuaAndInvokeEqualMany('gcd', tests)
end
-------------------------------------------------------------------------------
-- Test order
-------------------------------------------------------------------------------
function suite:test_order()
local tests = {
{0, {2}},
{1, {20}},
{2, {200}},
{0, {5}},
}
self:assertLuaAndInvokeEqualMany('order', tests)
self:assertInvokeEquals(suite.err('order of magnitude input appears non-numeric'), 'order', {'string'})
self:assertInvokeEquals(0, 'order', {x = 5})
end
-------------------------------------------------------------------------------
-- Test precision
-------------------------------------------------------------------------------
function suite:test_precison()
local tests = {
{4, {1.9856}},
{1, {1.1}},
{10, {1.9999999999}},
{9, {0.000020004}},
}
self:assertLuaAndInvokeEqualMany('precision', tests)
self:assertInvokeEquals(suite.err('precision input appears non-numeric'), 'precision', {'letra'})
self:assertInvokeEquals(4, 'precision', {x = '1.9888'})
end
-------------------------------------------------------------------------------
-- Test round
-------------------------------------------------------------------------------
function suite:test_round()
local tests = {
{2, {1.99999}},
{2, {1.99999, 0}},
{1.9, {1.94, 1}},
{20, {15, -1}},
{2.0004e-05, {0.000020004}}, -- broken and returns 0 due to limit of order -5 of phps floating number
{2.0004e-05, {0.000020004, mm._precision(0.000020004)}}, -- works
}
self:assertLuaAndInvokeEqualMany('round', tests)
self:assertInvokeEquals(3, 'round', {value = '2.99999', precision = '2'})
end
-------------------------------------------------------------------------------
-- Test mod
-------------------------------------------------------------------------------
function suite:test_mod()
local tests = {
{0, {10, 2}},
{1, {11, 2}},
{0, {525000000000000120000000000, 3}}, -- With the plain % operator this returns 68719476736 due to floating point error.
}
self:assertLuaAndInvokeEqualMany('mod', tests)
self:assertInvokeEquals(suite.err('first argument to mod appears non-numeric'), 'mod', {})
self:assertInvokeEquals(suite.err('second argument to mod appears non-numeric'), 'mod', {1})
local successNoArgs = pcall(mm._mod)
self:assertFalse(successNoArgs)
local successOneArg = pcall(mm._mod, 1)
self:assertFalse(successOneArg)
end
-------------------------------------------------------------------------------
-- Test precision format
-------------------------------------------------------------------------------
function suite:test_precison_format()
local tests = {
{'10.00', {10, 2}},
{'2.00<span style="margin:0 .15em 0 .25em">×</span>10<sup>−5</sup>', {0.000020004, 7}}
}
self:assertLuaAndInvokeEqualMany('precision_format', tests, false) -- the "false" stops string values being converted to numbers on re-entry from #invoke.
end
-------------------------------------------------------------------------------
-- Test cleanNumber
-------------------------------------------------------------------------------
function suite:assertCleanNumberEquals(expectedTable, inputString)
local expectedNum, expectedNumString = expectedTable[1], expectedTable[2]
local actualNum, actualNumString = mm._cleanNumber(inputString)
self:assertEquals(expectedNum, actualNum)
self:assertEquals(expectedNumString, actualNumString)
end
function suite:test_cleanNumber()
self:assertCleanNumberEquals({0, '0'}, '0')
self:assertCleanNumberEquals({1, '1'}, 1)
self:assertCleanNumberEquals({2, '2'}, ' 2 ')
self:assertCleanNumberEquals({3, '3'}, '4-1')
self:assertCleanNumberEquals({4, '4'}, '2 + 2')
self:assertCleanNumberEquals({5, '5'}, ' 2 + 3 ')
self:assertCleanNumberEquals({6, '6'}, '+6')
self:assertCleanNumberEquals({-7, '-7'}, '-7')
self:assertCleanNumberEquals({88, '88'}, '0x58')
self:assertCleanNumberEquals({1000000000, '1e+9'}, '1e+9')
self:assertCleanNumberEquals({-88, '-88'}, '-0x58')
self:assertCleanNumberEquals({0.16667, '0.16667'}, '1/6 round 5')
self:assertCleanNumberEquals({nil, nil}, '1 foo 2') -- invalid expression
self:assertCleanNumberEquals({nil, nil}, '1+') -- missing expr operand
self:assertCleanNumberEquals({nil, nil}, '')
self:assertCleanNumberEquals({nil, nil}, ' ')
self:assertCleanNumberEquals({nil, nil}, 'string')
self:assertCleanNumberEquals({nil, nil}, ' string with padding ')
end
-------------------------------------------------------------------------------
-- Test divide
-------------------------------------------------------------------------------
function suite:test_divide()
self:assertInvokeEquals('1','divide',{1, 2, round = 'yes'}, false)
self:assertInvokeEquals('0.5','divide',{1, 2, round = 'no'}, false)
self:assertInvokeEquals('0','divide',{1, 3, round = 'yes', precision=2}, false)
self:assertInvokeEquals('0.33','divide',{1, 3, precision=2}, false)
self:assertInvokeEquals(suite.err('Empty dividend'),'divide',{'',2},false)
self:assertInvokeEquals(suite.err('Empty divisor'),'divide',{1,''},false)
self:assertInvokeEquals(suite.err('Empty divisor'),'divide',{},false)
self:assertInvokeEquals(suite.err('Empty divisor'),'divide',{'',''},false)
self:assertInvokeEquals(suite.err('Not a number: a'),'divide',{'a',2},false)
self:assertInvokeEquals(suite.err('Not a number: b'),'divide',{1,'b'},false)
self:assertInvokeEquals(suite.err('Not a number: b'),'divide',{'a','b'},false)
self:assertInvokeEquals('<big>Bad</big>','divide',{'<big>Bad</big>',2},false)
self:assertInvokeEquals('<big>Bad</big>','divide',{1,'<big>Bad</big>'},false)
self:assertInvokeEquals('<big>Bad2</big>','divide',{'<big>Bad1</big>','<big>Bad2</big>'},false)
end
return suite
|
Portal di Ensiklopedia Dunia