Modulo:Random
Questo modulo Lua gestisce le funzioni del template {{random}}. Può fornire numeri casuali, selezionare un elemento casuale da una lista, riordinare totalmente o parzialmente una lista in modo casuale e visualizzarla con diversi formati. Le funzioni disponibili sono meglio descritte nelle sezioni seguenti.
Number
modificaLa funzione number
(numero) restituisce un numero casuale.
{{#invoke:random|number|m|n}}
- oppure, tramite il template
{{random|output=number|m|n}}
Gli argomenti m
e n
sono opzionali e possono essere omessi; se specificati devono poter essere convertiti in numeri interi.
- Senza argomenti, restituisce un numero reale nell'intervallo .
- Con un argomento, restituisce un numero intero nell'intervallo .
m
deve essere positivo. - Con due argomenti, restituisce un numero intero nell'intervallo .
m
en
possono essere sia positivi sia negativi. Sem
è maggiore din
, restituisce invece un numero intero nell'intervallo .
Esempi
{{#invoke:random|number}}
→ 0.13103275239981{{#invoke:random|number|100}}
→ 1{{#invoke:random|number|-100|-50}}
→ -63
La documentazione per questa funzione è in parte tratta da (EN) Scribunto Lua reference manual, basato su Lua 5.1 Reference Manual, disponibile sotto licenza MIT (Massachusetts Institute of Technology).
Item
modificaLa funzione item
(elemento) restituisce un elemento casuale di una lista.
{{#invoke:random|item|elemento 1|elemento 2|elemento 3|...}}
- oppure, tramite il template
{{random|output=item|elemento 1|elemento 2|elemento 3|...}}
Esempi
{{#invoke:random|item|aaa|bbb|ccc|ddd|eee}}
→ ccc
La lista di elementi in ingresso può essere specificata anche tramite i parametri input
e splitter
, analogamente a quanto specificato per la funzione list.
List
modificaLa funzione list
(lista) restituisce una lista riordinata in modo casuale.
Parametri nominali
modifica{{#invoke:random|list|elemento 1|elemento 2|elemento 3|...|sep=separatore|limit=numero di elementi da visualizzare}}
- oppure, tramite il template
{{random|output=list|elemento 1|elemento 2|elemento 3|...|sep=separatore|limit=numero di elementi da visualizzare}}
sep
oseparator
- eventuale separatore per gli elementi della lista. È possibile utilizzare dei valori predefiniti per particolari separatori, vedere la tabella seguente.limit
- numero di elementi da visualizzare; valore minimo = 0; valore massimo = numero totale di elementi della lista (valore predefinito).
Codice | Risultato |
---|---|
none |
nessuno spazio |
space |
spazio |
dot |
· |
dash |
– |
pipe |
| |
comma |
, |
semicolon |
; |
altri valori | qualsiasi altro valore di testo viene riportato tale e quale |
A causa di limitazioni tecniche nel software MediaWiki, non è possibile inserire direttamente spazi vuoti per il parametro separatore. In alternativa utilizzare il valore space (vedere tabella precedente) oppure  
per uno spazio normale, e
per uno spazio indivisibile (non-breaking space).
Esempi
{{#invoke:random|list|aaa|bbb|ccc|ddd|eee}}
→ eee · aaa · ddd · bbb · ccc{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=none}}
→ aaacccdddbbbeee{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=space}}
→ bbb eee ddd aaa ccc{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=dot}}
→ eee · bbb · ccc · ddd · aaa{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=dash}}
→ eee – aaa – bbb – ccc – ddd{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=pipe}}
→ ddd | eee | bbb | ccc | aaa{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=comma}}
→ ddd, aaa, bbb, eee, ccc{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=semicolon}}
→ aaa; bbb; ccc; eee; ddd{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep= * }}
→ eee * aaa * ddd * ccc * bbb{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=_}}
→ aaa_ccc_eee_ddd_bbb{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=xxx}}
→ bbbxxxeeexxxdddxxxaaaxxxccc{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|limit=3}}
→ eee · aaa · ccc
Nota
- Se non diversamente specificato, il separatore di default è " · " (dot, vedere tabella precedente).
Parametri nominali avanzati
modifica{{#invoke:random|list|input=elemento 1, elemento 2, elemento 3...|splitter=,}}
- oppure, tramite il template
{{random|output=list|input=elemento 1, elemento 2, elemento 3...|splitter=,}}
input
- eventuale lista di elementi in ingresso scritta in forma testuale. È possibile specificare in modo compatto una lista di elementi in ingresso che verranno suddivisi e separati tramite il parametrosplitter
.splitter
- separatore per gli elementi della lista d'ingresso. È possibile utilizzare ad esempio la virgola (",") o qualsiasi altro carattere o gruppo di caratteri (es. "//"), oppure il template {{·}}, ecc.
Esempi
{{#invoke:random|list|input=uno // due // tre // quattro // cinque|splitter=//}}
→ cinque · tre · quattro · due · uno{{#invoke:random|list|input=uno{{·}}due{{·}}tre{{·}}quattro{{·}}cinque|splitter={{·}}}}
→ tre · due · quattro · uno · cinque
Nota
- Il template {{random}} imposta, per le liste in ingresso, il separatore di default " · " (ottenuto tramite il template {{·}}).
{{random|output=list|input=uno{{·}}due{{·}}tre{{·}}quattro{{·}}cinque}}
→ due · cinque · quattro · tre · uno
Text list
modificaLa funzione text_list
(lista testuale) restituisce una lista riordinata in modo casuale, formattata per essere inserita in un testo. In altre parole, è simile alla funzione list
ma con un separatore differente per l'ultimo elemento della lista.
{{#invoke:random|text_list|elemento 1|elemento 2|elemento 3|...|sep=separatore|conj=congiunzione finale|limit=numero di elementi da visualizzare}}
- oppure, tramite il template
{{random|output=text_list|elemento 1|elemento 2|elemento 3|...|sep=separatore|conj=congiunzione finale|limit=numero di elementi da visualizzare}}
Il separatore può essere specificato tramite il parametro sep
o separator
; il valore di default è ", " (vedere MediaWiki:comma-separator). La congiunzione finale può essere specificata tramite il parametro conj
o conjunction
; il valore di default è " e " (vedere MediaWiki:and e MediaWiki:word-separator). Separatore e congiunzione finale possono essere specificati con gli stessi valori speciali definiti per la funzione list.
La lista di elementi in ingresso può essere specificata anche tramite i parametri input
e splitter
, analogamente a quanto specificato per la funzione list.
Il numero massimo di elementi da visualizzare può essere impostato con il parametro limit
; valore minimo = 0; valore massimo = numero totale di elementi della lista (valore predefinito).
Esempi
{{#invoke:random|text_list|aaa|bbb|ccc|ddd|eee}}
→ ccc, ddd, aaa, bbb e eee{{#invoke:random|text_list|aaa|bbb|ccc|ddd|eee|sep=semicolon}}
→ ccc; eee; ddd; bbb e aaa{{#invoke:random|text_list|aaa|bbb|ccc|ddd|eee|conj= oppure }}
→ ccc, bbb, eee, aaa oppure ddd{{#invoke:random|text_list|aaa|bbb|ccc|ddd|eee|limit=3}}
→ aaa, eee e ccc
-- This module contains a number of functions that make use of random numbers.
local p = {} -- For functions available from other Lua modules.
local l = {} -- For functions not available from other Lua modules, but that need to be accessed using table keys.
--------------------------------------------------------------------------------------
-- random number function
--------------------------------------------------------------------------------------
local function getBigRandom(l, u)
-- Gets a random integer between l and u, and is not limited to RAND_MAX.
local r = 0
local n = 2^math.random(30) -- Any power of 2.
local limit = math.ceil(53 / (math.log(n) / math.log(2)))
for i = 1, limit do
r = r + math.random(0, n - 1) / (n^i)
end
return math.floor(r * (u - l + 1)) + l
end
function l.number(args)
-- Gets 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 then
if first > second then -- Second number cannot be less than the first, or it causes an error.
first, second = second, first
end
return getBigRandom(first, second)
else
return getBigRandom(1, first)
end
else
return math.random()
end
end
--------------------------------------------------------------------------------------
-- List functions
--------------------------------------------------------------------------------------
local function randomizeArray(t, limit)
-- 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
-- If the limit parameter is set, the array is shortened to that many elements after being randomized.
-- The lowest possible value is 0, and the highest possible is the length of the array.
local len = #t
for i = len, 2, -1 do
local r = math.random(i)
t[i], t[r] = t[r], t[i]
end
if limit and limit < len then
local ret = {}
for i, v in ipairs(t) do
if i > limit then
break
end
ret[i] = v
end
return ret
else
return t
end
end
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
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 type(sep) == 'string' then
-- If the separator is a recognised separator, use that. Otherwise use the value of sep if it is a string.
local separators = {
none = '',
space = ' ',
dot = ' \'\'\'·\'\'\' ',
dash = ' – ',
pipe = ' | ',
comma = ', ',
semicolon = '; '
}
return separators[sep] or sep
end
end
local function makeRandomList(args)
local list = removeBlanks(args)
list = randomizeArray(list, tonumber(args.limit))
return list
end
function l.item(args)
-- Returns a random item from a numbered list.
local list = removeBlanks(args)
local len = #list
if len >= 1 then
return list[math.random(len)]
end
end
function l.list(args)
-- Randomizes a list and concatenates the result with a separator.
local list = makeRandomList(args)
local sep = makeSeparator(args.sep or args.separator or 'dot')
return table.concat(list, sep)
end
function l.text_list(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
function l.array(args)
-- Returns a Lua array, randomized. For use from other Lua modules.
return randomizeArray(args.t, args.limit)
end
--------------------------------------------------------------------------------------
-- The main function. Called from other Lua modules.
--------------------------------------------------------------------------------------
function p.main(funcName, args)
-- Sets the seed for the random number generator and passes control over to the other functions.
-- Generates a different number every time the module is called, even from the same page.
-- This is because of the variability of os.clock (the time in seconds that the Lua script has been running for).
math.randomseed(mw.site.stats.edits + mw.site.stats.pages + os.time() + math.floor(os.clock() * 1000000000))
if type(args) ~= 'table' then
error('the second argument to p.main must be a table')
end
return l[funcName](args)
end
--------------------------------------------------------------------------------------
-- Process arguments from #invoke
--------------------------------------------------------------------------------------
local function addListArgs(args)
-- If it exists, splits the input list and adds its items to the args.
if args.input and type(args.input) == 'string' then
local splitter = args.splitter or ''
local listArgs = mw.text.split(args.input, splitter, true)
for k, v in pairs(listArgs) do
if type(v) == 'string' then
v = mw.text.trim(v)
end
if v ~= '' then
table.insert(args, v)
end
end
end
return args
end
local function getArgs(funcName)
-- This function get and process arguments from #invoke.
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
local parent = frame:getParent()
local parentArgs = parent and parent.args or {}
for k, v in pairs(parentArgs) do
origArgs[k] = v
end
for k, v in pairs(frame.args) do
origArgs[k] = v
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
if funcName ~= 'number' then
args = addListArgs(args)
end
return p.main(funcName, args)
end
end
-- Process arguments for functions.
local funcs = {'number', 'item', 'list', 'text_list'}
for _, funcName in ipairs(funcs) do
p[funcName] = getArgs(funcName)
end
return p