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
[modifica]La 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.21939632446477{{#invoke:random|number|100}}
→ 50{{#invoke:random|number|-100|-50}}
→ -66
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
[modifica]La 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}}
→ eee
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
[modifica]La 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}}
→ ccc · bbb · eee · ddd · aaa{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=none}}
→ aaaeeecccdddbbb{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=space}}
→ ddd eee bbb ccc aaa{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=dot}}
→ ddd · ccc · bbb · aaa · eee{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=dash}}
→ bbb – aaa – ddd – ccc – eee{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=pipe}}
→ eee | ddd | bbb | ccc | aaa{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=comma}}
→ ccc, ddd, eee, aaa, bbb{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=semicolon}}
→ aaa; ddd; eee; bbb; ccc{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep= * }}
→ ccc * ddd * bbb * eee * aaa{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=_}}
→ aaa_ccc_bbb_eee_ddd{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|sep=xxx}}
→ eeexxxdddxxxaaaxxxcccxxxbbb{{#invoke:random|list|aaa|bbb|ccc|ddd|eee|limit=3}}
→ aaa · ddd · 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=//}}
→ uno · tre · due · quattro · cinque{{#invoke:random|list|input=uno{{·}}due{{·}}tre{{·}}quattro{{·}}cinque|splitter={{·}}}}
→ quattro · due · uno · cinque · tre
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}}
→ tre · quattro · due · cinque · uno
Text list
[modifica]La 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}}
→ eee, ddd, ccc, bbb e aaa{{#invoke:random|text_list|aaa|bbb|ccc|ddd|eee|sep=semicolon}}
→ ddd; aaa; eee; bbb e ccc{{#invoke:random|text_list|aaa|bbb|ccc|ddd|eee|conj= oppure }}
→ ddd, ccc, eee, aaa oppure bbb{{#invoke:random|text_list|aaa|bbb|ccc|ddd|eee|limit=3}}
→ bbb, ccc e aaa
-- 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