Anda dapat membuat halaman dokumentasi untuk buat pada modul Scribunto ini.
Penyunting dapat melakukan uji coba pada halaman bak pasir (buat | cermin) dan kasus uji (buat) modul ini.
Subhalaman modul ini.
Penyunting dapat melakukan uji coba pada halaman bak pasir (buat | cermin) dan kasus uji (buat) modul ini.
Subhalaman modul ini.
-- This module contains a number of functions that make use of random numbers. localcfg={} -------------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------------- -- Set this to true if your wiki has a traffic rate of less than one edit every two minutes or so. -- This will prevent the same "random" number being generated many times in a row until a new edit is made -- to the wiki. This setting is only relevant if the |same= parameter is set. cfg.lowTraffic=false -- If cfg.lowTraffic is set to true, and the |same= parameter is set, this value is used for the refresh rate of the random seed. -- This is the number of seconds until the seed is changed. Getting this right is tricky. If you set it too high, the same number -- will be returned many times in a row. If you set it too low, you may get different random numbers appearing on the same page, -- particularly for pages that take many seconds to process. cfg.seedRefreshRate=60 -------------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------------- localp={}-- For functions available from other Lua modules. locall={}-- For functions not available from other Lua modules, but that need to be accessed using table keys. localyesno=require('Modul:Yesno') localmakeList=require('Modul:List').makeList -------------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------------- localfunctionraiseError(msg) -- This helps to generate a wikitext error. It is the calling function's responsibility as to how to include it in the output. returnmw.ustring.format('<b class="error">[[Modul:Random]] error: %s.</b>',msg) end -------------------------------------------------------------------------------------- -- random number function -------------------------------------------------------------------------------------- localfunctiongetBigRandom(l,u) -- Gets a random integer between l and u, and is not limited to RAND_MAX. localr=0 localn=2^math.random(30)-- Any power of 2. locallimit=math.ceil(53/(math.log(n)/math.log(2))) fori=1,limitdo r=r+math.random(0,n-1)/(n^i) end returnmath.floor(r*(u-l+1))+l end functionl.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. iffirstthen ifsecondthen iffirst>secondthen-- Second number cannot be less than the first, or it causes an error. first,second=second,first end returngetBigRandom(first,second) else returngetBigRandom(1,first) end else returnmath.random() end end -------------------------------------------------------------------------------------- -- Date function -------------------------------------------------------------------------------------- functionl.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. locallang=mw.language.getContentLanguage() localfunctiongetDate(format,ts) localsuccess,date=pcall(lang.formatDate,lang,format,ts) ifsuccessthen returndate end end localfunctiongetUnixTimestamp(ts) localunixts=getDate('U',ts) ifunixtsthen returntonumber(unixts) end end localt1=args[1] localt2=args[2] -- Find the start timestamp and the end timestamp. localstartTimestamp,endTimestamp ifnott1then -- Find the first and last second in the current year. localcurrentYear=tonumber(getDate('Y')) localcurrentYearStartUnix=tonumber(getUnixTimestamp('1 Jan '..tostring(currentYear))) localcurrentYearEndUnix=tonumber(getUnixTimestamp('1 Jan '..tostring(currentYear+1)))-1 startTimestamp='@'..tostring(currentYearStartUnix)-- @ is used to denote Unix timestamps with lang:formatDate. endTimestamp='@'..tostring(currentYearEndUnix) elseift1andnott2then startTimestamp='@0'-- the Unix epoch, 1 January 1970 endTimestamp=t1 elseift1andt2then 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) localstartTimestampUnix=getUnixTimestamp(startTimestamp) localendTimestampUnix=getUnixTimestamp(endTimestamp) ifnotstartTimestampUnixthen returnraiseError('"'..tostring(startTimestamp)..'" tidak dikenali sebagai stempel waktu yang valid') elseifnotendTimestampUnixthen returnraiseError('"'..tostring(endTimestamp)..'" tidak dikenali sebagai stempel waktu yang valid') elseifstartTimestampUnix>endTimestampUnixthen returnraiseError('waktu mulai harus tidak lebih dari waktu akhir (start date: "'..startTimestamp..'", end date: "'..endTimestamp..'")') end -- Get a random number between the two Unix timestamps and return it using the specified format. localrandomTimestamp=getBigRandom(startTimestampUnix,endTimestampUnix) localdateFormat=args.formator'H:i, d F Y (T)' localresult=getDate(dateFormat,'@'..tostring(randomTimestamp)) ifresultthen returnresult else returnraiseError('"'..dateFormat..'" bukan format tanggal yang valid') end end -------------------------------------------------------------------------------------- -- List functions -------------------------------------------------------------------------------------- localfunctionrandomizeArray(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. locallen=#t fori=len,2,-1do localr=math.random(i) t[i],t[r]=t[r],t[i] end iflimitandlimit<lenthen localret={} fori,vinipairs(t)do ifi>limitthen break end ret[i]=v end returnret else returnt end end localfunctionremoveBlanks(t) -- Removes blank entries from an array so that it can be used with ipairs. localret={} fork,vinpairs(t)do iftype(k)=='number'then table.insert(ret,k) end end table.sort(ret) fori,vinipairs(ret)do ret[i]=t[v] end returnret end localfunctionmakeSeparator(sep) ifsep=='space'then -- Include an easy way to use spaces as separators. return' ' elseifsep=='newline'then -- Ditto for newlines return'\n' elseiftype(sep)=='string'then -- If the separator is a recognised MediaWiki separator, use that. Otherwise use the value of sep if it is a string. localmwseparators={'dot','pipe','comma','tpt-languages'} for_,mwsepinipairs(mwseparators)do ifsep==mwsepthen returnmw.message.new(sep..'-separator'):plain() end end returnsep end end localfunctionmakeRandomList(args) locallist=removeBlanks(args) list=randomizeArray(list,tonumber(args.limit)) returnlist end functionl.item(args) -- Returns a random item from a numbered list. locallist=removeBlanks(args) locallen=#list iflen>=1then returnlist[math.random(len)] end end functionl.list(args) -- Randomizes a list and concatenates the result with a separator. locallist=makeRandomList(args) localsep=makeSeparator(args.seporargs.separator) returntable.concat(list,sep) end functionl.text_list(args) -- Randomizes a list and concatenates the result, text-style. Accepts separator and conjunction arguments. locallist=makeRandomList(args) localsep=makeSeparator(args.seporargs.separator) localconj=makeSeparator(args.conjorargs.conjunction) returnmw.text.listToText(list,sep,conj) end functionl.array(args) -- Returns a Lua array, randomized. For use from other Lua modules. returnrandomizeArray(args.t,args.limit) end -------------------------------------------------------------------------------------- -- HTML list function -------------------------------------------------------------------------------------- functionl.html_list(args,listType) -- Randomizes a list and turns it into an HTML list. Uses [[Modul:List]]. listType=listTypeor'bulleted' locallistArgs=makeRandomList(args)-- Arguments for [[Modul:List]]. fork,vinpairs(args)do iftype(k)=='string'then listArgs[k]=v end end returnmakeList(listType,listArgs) end -------------------------------------------------------------------------------------- -- The main function. Called from other Lua modules. -------------------------------------------------------------------------------------- functionp.main(funcName,args,listType) -- Sets the seed for the random number generator and passes control over to the other functions. localsame=yesno(args.same) ifnotsamethen -- 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)) else ifnotcfg.lowTrafficthen -- Make the seed as random as possible without using anything time-based. This means that the same random number -- will be generated for the same input from the same page - necessary behaviour for some wikicode templates that -- assume bad pseudo-random-number generation. localstats=mw.site.stats localviews=stats.viewsor0-- This is not always available, so we need a backup. localseed=views+stats.pages+stats.articles+stats.files+stats.edits+stats.users+stats.activeUsers+stats.admins-- Make this as random as possible without using os.time() or os.clock() math.randomseed(seed) else -- Make the random seed change every n seconds, where n is set by cfg.seedRefreshRate. -- This is useful for low-traffic wikis where new edits may not happen very often. math.randomseed(math.floor(os.time()/cfg.seedRefreshRate)) end end iftype(args)~='table'then error('Argumen kedua untuk p.main harus berupa table') end returnl[funcName](args,listType) end -------------------------------------------------------------------------------------- -- Process arguments from #invoke -------------------------------------------------------------------------------------- localfunctionmakeWrapper(funcName,listType) -- This function provides a wrapper for argument-processing from #invoke. -- listType is only used with p.html_list, and is nil the rest of the time. returnfunction(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. localorigArgs ifframe==mw.getCurrentFrame()then origArgs=frame:getParent().args fork,vinpairs(frame.args)do origArgs=frame.args break end else origArgs=frame end -- Trim whitespace and remove blank arguments. localargs={} fork,vinpairs(origArgs)do iftype(v)=='string'then v=mw.text.trim(v) end ifv~=''then args[k]=v end end returnp.main(funcName,args,listType) end end -- Process arguments for HTML list functions. localhtmlListFuncs={ bulleted_list='bulleted', unbulleted_list='unbulleted', horizontal_list='horizontal', ordered_list='ordered', horizontal_ordered_list='horizontal_ordered' } forfuncName,listTypeinpairs(htmlListFuncs)do p[funcName]=makeWrapper('html_list',listType) end -- Process arguments for other functions. localotherFuncs={'number','date','item','list','text_list'} for_,funcNameinipairs(otherFuncs)do p[funcName]=makeWrapper(funcName) end returnp