Module:Random
Appearance
-- This module contains a number of functions that make use of random numbers.
local cfg = {}
cfg.space = 'space'
local p = {}
-- Set the seed for the random number to the current number of edits made to Wikipedia.
-- The English Wikipedia gets dozens of edits each minute, so this is as close to a random seed
-- as we have. On smaller wikis this will produce the same number if the edit count has not changed,
-- so please use it with caution.
math.randomseed(mw.site.stats.edits)
local function removeBlanks(t)
-- Removes blank entries from an array so that it can be used with ipairs.
local ret = {}
for k, v in pairs(t) do
if type(k) == 'number' then -- Make sure we have no non-string portal names.
table.insert(ret, k)
end
end
table.sort(ret)
for i, v in ipairs(ret) do
ret[i] = t[v]
end
return ret
end
local function makeSeparator(sep)
if sep == cfg.space then
-- Include an easy way to use spaces as separators.
return ' '
elseif type(sep) == 'string' then
-- If the separator is a recognised MediaWiki separator, use that. Otherwise use the value of sep if it is a string.
local mwseparators = {'dot', 'pipe', 'comma', 'tpt-languages'}
for _, mwsep in ipairs(mwseparators) do
if sep == mwsep then
return mw.message.new( sep .. '-separator' ):plain()
end
end
return sep
end
end
local function randomizeArray(t)
-- Randomizes an array. It works by iterating through the list backwards, each time swapping the entry
-- "i" with a random entry. Courtesy of Xinhuan at http://forums.wowace.com/showthread.php?p=279756
for i = #t, 2, -1 do
local r = math.random(i)
t[i], t[r] = t[r], t[i]
end
return t
end
local function makeRandomList(args)
local list = removeBlanks(args)
list = randomizeArray(list)
return list
end
function p._number(args)
-- Returns a random number.
first = tonumber(args[1])
second = tonumber(args[2])
-- This needs to use if statements as math.random won't accept explicit nil values as arguments.
if first then
if second and first <= second then -- Second number cannot be less than the first, or it causes an error.
return math.random(first, second)
else
return math.random(first)
end
else
return math.random()
end
end
function p._item(args)
-- Returns a random item from a numbered list.
local list = removeBlanks(args)
if #list >= 1 then
return list[math.random(#list)]
end
end
function p._randomize(args)
-- Randomizes a list and concatenates the result with a separator.
local list = makeRandomList(args)
local sep = makeSeparator(args.sep or args.separator)
return table.concat(list, sep)
end
function p._randomizeToText(args)
-- Randomizes a list and concatenates the result, text-style. Accepts separator and conjunction arguments.
local list = makeRandomList(args)
local sep = makeSeparator(args.sep or args.separator)
local conj = makeSeparator(args.conj or args.conjunction)
return mw.text.listToText(list, sep, conj)
end
local function makeWrapper(funcName)
return function (frame)
-- If called via #invoke, use the args passed into the invoking template, or the args passed to #invoke if any exist.
-- Otherwise assume args are being passed directly in from the debug console or from another Lua module.
local origArgs
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
for k, v in pairs(frame.args) do
origArgs = frame.args
break
end
else
origArgs = frame
end
-- Trim whitespace and remove blank arguments.
local args = {}
for k, v in pairs(origArgs) do
if type(v) == 'string' then
v = mw.text.trim(v)
end
if v ~= '' then
args[k] = v
end
end
return p[funcName](args)
end
end
local funcNames = {'number', 'item', 'randomize', 'randomizeToText'}
for _, funcName in ipairs(funcNames) do
p[funcName] = makeWrapper('_' .. funcName)
end
return p