Module:Random: Difference between revisions

Content deleted Content added
use a different function for each html list type
add function to get random dates; and add support for random numbers over 2^32-1 (using an algorithm supplied by User:Anomie)
Line 12:
 
--------------------------------------------------------------------------------------
-- RandomError numberhelper function
--------------------------------------------------------------------------------------
 
local function raiseError(msg)
-- This helps to generate a wikitext error. It is the calling function's responsibility as to how to include it in the output.
return mw.ustring.format('<b class="error">[[Module:Random]] error: %s.</b>', msg)
end
 
--------------------------------------------------------------------------------------
-- random number function
--------------------------------------------------------------------------------------
 
local function bigRandom(l, u)
-- Gets a random integer between l and u, and is not limited to RAND_MAX (which here we assume is 2^31-1).
local r = math.random() + math.random() / 2147483648
return math.floor(r * (u - l + 1)) + l
end
 
function p._number(args)
Line 21 ⟶ 36:
-- This needs to use if statements as math.random won't accept explicit nil values as arguments.
if first then
if second andthen
if first <=> second then -- Second number cannot be less than the first, or it causes an error.
return math.random( first, second) = second, first
end
return bigRandom(first, second)
else
return math.randombigRandom(1, first)
end
else
return math.random()
end
end
 
--------------------------------------------------------------------------------------
-- Date function
--------------------------------------------------------------------------------------
 
function p._date(args)
-- This function gets random dates, and takes timestamps as positional arguments.
-- With no arguments specified, it outputs a random date in the current year.
-- With two arguments specified, it outputs a random date between the timestamps.
-- With one argument specified, the date is a random date between the unix epoch (1 Jan 1970) and the timestamp.
-- The output can be formatted using the "format" argument, which works in the same way as the #time parser function.
-- The default format is the standard Wikipedia timestamp.
local lang = mw.language.getContentLanguage()
 
local function getDate(format, ts)
local success, date = pcall(lang.formatDate, lang, format, ts)
if success then
return date
end
end
 
local function getUnixTimestamp(ts)
local unixts = getDate('U', ts)
if unixts then
return tonumber(unixts)
end
end
 
local t1 = args[1]
local t2 = args[2]
-- Find the start timestamp and the end timestamp.
local startTimestamp, endTimestamp
if not t1 then
-- Find the first and last second in the current year.
local currentYear = tonumber(getDate('Y'))
local currentYearStartUnix = tonumber(getUnixTimestamp('1 Jan ' .. tostring(currentYear)))
local currentYearEndUnix = tonumber(getUnixTimestamp('1 Jan ' .. tostring(currentYear + 1))) - 1
startTimestamp = '@' .. tostring(currentYearStartUnix) -- @ is used to denote Unix timestamps with lang:formatDate.
endTimestamp = '@' .. tostring(currentYearEndUnix)
elseif t1 and not t2 then
startTimestamp = '@0' -- the Unix epoch, 1 January 1970
endTimestamp = t1
elseif t1 and t2 then
startTimestamp = t1
endTimestamp = t2
end
 
-- Get Unix timestamps and return errors for bad input (or for bugs in the underlying PHP library, of which there are unfortunately a few)
local startTimestampUnix = getUnixTimestamp(startTimestamp)
local endTimestampUnix = getUnixTimestamp(endTimestamp)
if not startTimestampUnix then
return raiseError('"' .. tostring(startTimestamp) .. '" was not recognised as a valid timestamp')
elseif not endTimestampUnix then
return raiseError('"' .. tostring(endTimestamp) .. '" was not recognised as a valid timestamp')
elseif startTimestampUnix > endTimestampUnix then
return raiseError('the start date must not be later than the end date (start date: "' .. startTimestamp .. '", end date: "' .. endTimestamp .. '")')
end
 
-- Get a random number between the two Unix timestamps and return it using the specified format.
local randomTimestamp = bigRandom(startTimestampUnix, endTimestampUnix)
local dateFormat = args.format or 'H:i, d F Y (T)'
local result = getDate(dateFormat, '@' .. tostring(randomTimestamp))
if result then
return result
else
return raiseError('"' .. dateFormat .. '" is not a valid date format')
end
end
Line 168 ⟶ 256:
 
-- Process arguments for other functions.
local otherFuncs = {'number', 'date', 'item', 'list', 'text_list'}
for _, funcName in ipairs(otherFuncs) do
p[funcName] = makeWrapper('_' .. funcName)