Jump to content

Module:Random

विकिपीडिया से
Mr. Stradivarius (बातचीत | योगदान) (add an html_list function, and rename the randomize functions) के द्वारा 12:21, 14 नवंबर 2013 के बदलाव
-- This module contains a number of functions that make use of random numbers.

local makeList = require('Module:List').makeList

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._list(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._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 p._html_list(args)
	-- Randomizes a list and turns it into an HTML list. Uses [[Module:List]].
	local listArgs = makeRandomList(args) -- Arguments for [[Module:List]].
	local listType = args.list_type or 'bulleted'
	args.list_type = nil
	for k, v in pairs(args) do
		if type(k) == 'string' then
			listArgs[k] = v
		end
	end
	return makeList(listType, listArgs)
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', 'list', 'text_list', 'html_list'}
for _, funcName in ipairs(funcNames) do
	p[funcName] = makeWrapper('_' .. funcName)
end

return p