Commit 2db91358 authored by Guido van Rossum's avatar Guido van Rossum

Misc changes and new modules. whrandom is "objectified". SOCKET.py

is moved to the sgi subdirectory.
parent 0cb8e8cf
......@@ -11,7 +11,7 @@
# - Monday is the first day of the week (numbered 0)
# These are really parameters of the 'time' module:
epoch = 1970 # Time began on January 1 of this year (00:00:00 UCT)
epoch = 1970 # Time began on January 1 of this year (00:00:00 UTC)
day_0 = 3 # The epoch begins on a Thursday (Monday = 0)
# Return 1 for leap years, 0 for non-leap years
......@@ -58,7 +58,7 @@ def leapdays(y1, y2):
return (y2+3)/4 - (y1+3)/4
# Inverse of gmtime():
# Turn UCT calendar time (less yday, wday) into seconds since epoch
# Turn UTC calendar time (less yday, wday) into seconds since epoch
def mktime(year, month, day, hours, mins, secs):
days = day - 1
for m in range(January, month): days = days + mdays[m]
......@@ -96,8 +96,8 @@ def asctime(year, month, day, hours, mins, secs, yday, wday):
return s + ' ' + `year`
# Localization: Minutes West from Greenwich
# timezone = -2*60 # Middle-European time with DST on
timezone = 5*60 # EST (sigh -- THINK time() doesn't return UCT)
timezone = -2*60 # Middle-European time with DST on
# timezone = 5*60 # EST (sigh -- THINK time() doesn't return UTC)
# Local time ignores DST issues for now -- adjust 'timezone' to fake it
def localtime(secs):
......
......@@ -35,13 +35,29 @@ def test_gif(h, f):
tests.append(test_gif)
def test_pnm(h, f):
# PBM, PGM, PPM (portable {bit,gray,pix}map; together portable anymap)
def test_pbm(h, f):
# PBM (portable bitmap)
if len(h) >= 3 and \
h[0] == 'P' and h[1] in '123456' and h[2] in ' \t\n\r':
return 'pnm'
h[0] == 'P' and h[1] in '14' and h[2] in ' \t\n\r':
return 'pbm'
tests.append(test_pnm)
tests.append(test_pbm)
def test_pgm(h, f):
# PGM (portable graymap)
if len(h) >= 3 and \
h[0] == 'P' and h[1] in '25' and h[2] in ' \t\n\r':
return 'pgm'
tests.append(test_pgm)
def test_ppm(h, f):
# PPM (portable pixmap)
if len(h) >= 3 and \
h[0] == 'P' and h[1] in '36' and h[2] in ' \t\n\r':
return 'ppm'
tests.append(test_ppm)
def test_tiff(h, f):
# TIFF (can be in Motorola or Intel byte order)
......
# Convert "arbitrary" image files to rgb files (SGI's image format).
# Input may be compressed.
# The uncompressed file type may be PBM, PGM, PPM, GIF, TIFF, or Sun raster.
# An exception is raised if the file is not of a recognized type.
# Returned filename is either the input filename or a temporary filename;
# in the latter case the caller must ensure that it is removed.
# Other temporary files used are removed by the function.
import os
import tempfile
import pipes
import imghdr
table = {}
t = pipes.Template().init()
t.append('fromppm $IN $OUT', 'ff')
table['ppm'] = t
t = pipes.Template().init()
t.append('pnmtoppm', '--')
t.append('fromppm $IN $OUT', 'ff')
table['pnm'] = t
table['pgm'] = t
table['pbm'] = t
t = pipes.Template().init()
t.append('fromgif $IN $OUT', 'ff')
table['gif'] = t
t = pipes.Template().init()
t.append('tifftopnm', '--')
t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
t.append('fromppm $IN $OUT', 'ff')
table['tiff'] = t
t = pipes.Template().init()
t.append('rasttopnm', '--')
t.append('pnmtoppm', '--')
t.append('fromppm $IN $OUT', 'ff')
table['rast'] = t
uncompress = pipes.Template().init()
uncompress.append('uncompress', '--')
error = 'torgb.error' # Exception
def torgb(filename):
temps = []
ret = None
try:
ret = _torgb(filename, temps)
finally:
for temp in temps[:]:
if temp <> ret:
try:
os.unlink(temp)
except os.error:
pass
temps.remove(temp)
return ret
def _torgb(filename, temps):
if filename[-2:] == '.Z':
fname = tempfile.mktemp()
temps.append(fname)
sts = uncompress.copy(filename, fname)
if sts:
raise error, filename + ': uncompress failed'
else:
fname = filename
try:
ftype = imghdr.what(fname)
except IOError, msg:
if type(msg) == type(()) and len(msg) == 2 and \
type(msg[0]) == type(0) and type(msg[1]) == type(''):
msg = msg[1]
if type(msg) <> type(''):
msg = `msg`
raise error, filename + ': ' + msg
if ftype == 'rgb':
return fname
if ftype == None or not table.has_key(ftype):
raise error, \
filename + ': unsupported image file type ' + `ftype`
temp = tempfile.mktemp()
sts = table[ftype].copy(fname, temp)
if sts:
raise error, filename + ': conversion to rgb failed'
return temp
# Conversion pipeline templates
# =============================
# The problem:
# ------------
#
# Suppose you have some data that you want to convert to another format
# (e.g. from GIF image format to PPM image format). Maybe the
# conversion involves several steps (e.g. piping it through compress or
# uuencode). Some of the conversion steps may require that their input
# is a disk file, others may be able to read standard input; similar for
# their output. The input to the entire conversion may also be read
# from a disk file or from an open file, and similar for its output.
#
# The module lets you construct a pipeline template by sticking one or
# more conversion steps together. It will take care of creating and
# removing temporary files if they are necessary to hold intermediate
# data. You can then use the template to do conversions from many
# different sources to many different destinations. The temporary
# file names used are different each time the template is used.
#
# The templates are objects so you can create templates for many
# different conversion steps and store them in a dictionary, for
# instance.
# Directions:
# -----------
#
# To create a template:
# t = Template().init()
#
# To add a conversion step to a template:
# t.append(command, kind)
# where kind is a string of two characters: the first is '-' if the
# command reads its standard input or 'f' if it requires a file; the
# second likewise for the output. The command must be valid /bin/sh
# syntax. If input or output files are required, they are passed as
# $IN and $OUT; otherwise, it must be possible to use the command in
# a pipeline.
#
# To add a conversion step at the beginning:
# t.prepend(command, kind)
#
# To convert a file to another file using a template:
# sts = t.copy(infile, outfile)
# If infile or outfile are the empty string, standard input is read or
# standard output is written, respectively. The return value is the
# exit status of the conversion pipeline.
#
# To open a file for reading or writing through a conversion pipeline:
# fp = t.open(file, mode)
# where mode is 'r' to read the file, or 'w' to write it -- just like
# for the built-in function open() or for os.popen().
#
# To create a new template object initialized to a given one:
# t2 = t.clone()
#
# For an example, see the function test() at the end of the file.
import sys
import regex
import os
import tempfile
import string
# Conversion step kinds
FILEIN_FILEOUT = 'ff' # Must read & write real files
STDIN_FILEOUT = '-f' # Must write a real file
FILEIN_STDOUT = 'f-' # Must read a real file
STDIN_STDOUT = '--' # Normal pipeline element
SOURCE = '.-' # Must be first, writes stdout
SINK = '-.' # Must be last, reads stdin
stepkinds = [FILEIN_FILEOUT, STDIN_FILEOUT, FILEIN_STDOUT, STDIN_STDOUT, \
SOURCE, SINK]
# A pipeline template is a Template object:
class Template:
# Template().init() returns a fresh pipeline template
def init(self):
self.debugging = 0
self.reset()
return self
# t.__repr__() implements `t`
def __repr__(self):
return '<Template instance, steps=' + `self.steps` + '>'
# t.reset() restores a pipeline template to its initial state
def reset(self):
self.steps = []
# t.clone() returns a new pipeline template with identical
# initial state as the current one
def clone(self):
t = Template().init()
t.steps = self.steps[:]
t.debugging = self.debugging
return t
# t.debug(flag) turns debugging on or off
def debug(self, flag):
self.debugging = flag
# t.append(cmd, kind) adds a new step at the end
def append(self, cmd, kind):
if type(cmd) <> type(''):
raise TypeError, \
'Template.append: cmd must be a string'
if kind not in stepkinds:
raise ValueError, \
'Template.append: bad kind ' + `kind`
if kind == SOURCE:
raise ValueError, \
'Template.append: SOURCE can only be prepended'
if self.steps <> [] and self.steps[-1][1] == SINK:
raise ValueError, \
'Template.append: already ends with SINK'
if kind[0] == 'f' and regex.search('\$IN', cmd) < 0:
raise ValueError, \
'Template.append: missing $IN in cmd'
if kind[1] == 'f' and regex.search('\$OUT', cmd) < 0:
raise ValueError, \
'Template.append: missing $OUT in cmd'
self.steps.append((cmd, kind))
# t.prepend(cmd, kind) adds a new step at the front
def prepend(self, cmd, kind):
if type(cmd) <> type(''):
raise TypeError, \
'Template.prepend: cmd must be a string'
if kind not in stepkinds:
raise ValueError, \
'Template.prepend: bad kind ' + `kind`
if kind == SINK:
raise ValueError, \
'Template.prepend: SINK can only be appended'
if self.steps <> [] and self.steps[0][1] == SOURCE:
raise ValueError, \
'Template.prepend: already begins with SOURCE'
if kind[0] == 'f' and regex.search('\$IN\>', cmd) < 0:
raise ValueError, \
'Template.prepend: missing $IN in cmd'
if kind[1] == 'f' and regex.search('\$OUT\>', cmd) < 0:
raise ValueError, \
'Template.prepend: missing $OUT in cmd'
self.steps.insert(0, (cmd, kind))
# t.open(file, rw) returns a pipe or file object open for
# reading or writing; the file is the other end of the pipeline
def open(self, file, rw):
if rw == 'r':
return self.open_r(file)
if rw == 'w':
return self.open_w(file)
raise ValueError, \
'Template.open: rw must be \'r\' or \'w\', not ' + `rw`
# t.open_r(file) and t.open_w(file) implement
# t.open(file, 'r') and t.open(file, 'w') respectively
def open_r(self, file):
if self.steps == []:
return open(file, 'r')
if self.steps[-1][1] == SINK:
raise ValueError, \
'Template.open_r: pipeline ends width SINK'
cmd = self.makepipeline(file, '')
return os.popen(cmd, 'r')
def open_w(self, file):
if self.steps == []:
return open(file, 'w')
if self.steps[0][1] == SOURCE:
raise ValueError, \
'Template.open_w: pipeline begins with SOURCE'
cmd = self.makepipeline('', file)
return os.popen(cmd, 'w')
def copy(self, infile, outfile):
return os.system(self.makepipeline(infile, outfile))
def makepipeline(self, infile, outfile):
cmd = makepipeline(infile, self.steps, outfile)
if self.debugging:
print cmd
cmd = 'set -x; ' + cmd
return cmd
def makepipeline(infile, steps, outfile):
# Build a list with for each command:
# [input filename or '', command string, kind, output filename or '']
list = []
for cmd, kind in steps:
list.append(['', cmd, kind, ''])
#
# Make sure there is at least one step
#
if list == []:
list.append(['', 'cat', '--', ''])
#
# Take care of the input and output ends
#
[cmd, kind] = list[0][1:3]
if kind[0] == 'f' and not infile:
list.insert(0, ['', 'cat', '--', ''])
list[0][0] = infile
#
[cmd, kind] = list[-1][1:3]
if kind[1] == 'f' and not outfile:
list.append(['', 'cat', '--', ''])
list[-1][-1] = outfile
#
# Invent temporary files to connect stages that need files
#
garbage = []
for i in range(1, len(list)):
lkind = list[i-1][2]
rkind = list[i][2]
if lkind[1] == 'f' or rkind[0] == 'f':
temp = tempfile.mktemp()
garbage.append(temp)
list[i-1][-1] = list[i][0] = temp
#
for item in list:
[inf, cmd, kind, outf] = item
if kind[1] == 'f':
cmd = 'OUT=' + quote(outf) + '; ' + cmd
if kind[0] == 'f':
cmd = 'IN=' + quote(inf) + '; ' + cmd
if kind[0] == '-' and inf:
cmd = cmd + ' <' + quote(inf)
if kind[1] == '-' and outf:
cmd = cmd + ' >' + quote(outf)
item[1] = cmd
#
cmdlist = list[0][1]
for item in list[1:]:
[cmd, kind] = item[1:3]
if item[0] == '':
if 'f' in kind:
cmd = '{ ' + cmd + '; }'
cmdlist = cmdlist + ' |\n' + cmd
else:
cmdlist = cmdlist + '\n' + cmd
#
if garbage:
rmcmd = 'rm -f'
for file in garbage:
rmcmd = rmcmd + ' ' + quote(file)
trapcmd = 'trap ' + quote(rmcmd + '; exit') + ' 1 2 3 13 14 15'
cmdlist = trapcmd + '\n' + cmdlist + '\n' + rmcmd
#
return cmdlist
# Reliably quote a string as a single argument for /bin/sh
_safechars = string.letters + string.digits + '!@%_-+=:,./' # Safe unquoted
_funnychars = '"`$\\' # Unsafe inside "double quotes"
def quote(file):
for c in file:
if c not in _safechars:
break
else:
return file
if '\'' not in file:
return '\'' + file + '\''
res = ''
for c in file:
if c in _funnychars:
c = '\\' + c
res = res + c
return '"' + res + '"'
# Small test program and example
def test():
import os
print 'Testing...'
t = Template().init()
t.append('togif $IN $OUT', 'ff')
t.append('giftoppm', '--')
t.append('ppmtogif >$OUT', '-f')
t.append('fromgif $IN $OUT', 'ff')
t.debug(1)
FILE = '/usr/local/images/rgb/rogues/guido.rgb'
t.copy(FILE, '@temp')
print 'Done.'
# Convert "arbitrary" image files to rgb files (SGI's image format).
# Input may be compressed.
# The uncompressed file type may be PBM, PGM, PPM, GIF, TIFF, or Sun raster.
# An exception is raised if the file is not of a recognized type.
# Returned filename is either the input filename or a temporary filename;
# in the latter case the caller must ensure that it is removed.
# Other temporary files used are removed by the function.
import os
import tempfile
import pipes
import imghdr
table = {}
t = pipes.Template().init()
t.append('fromppm $IN $OUT', 'ff')
table['ppm'] = t
t = pipes.Template().init()
t.append('pnmtoppm', '--')
t.append('fromppm $IN $OUT', 'ff')
table['pnm'] = t
table['pgm'] = t
table['pbm'] = t
t = pipes.Template().init()
t.append('fromgif $IN $OUT', 'ff')
table['gif'] = t
t = pipes.Template().init()
t.append('tifftopnm', '--')
t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
t.append('fromppm $IN $OUT', 'ff')
table['tiff'] = t
t = pipes.Template().init()
t.append('rasttopnm', '--')
t.append('pnmtoppm', '--')
t.append('fromppm $IN $OUT', 'ff')
table['rast'] = t
uncompress = pipes.Template().init()
uncompress.append('uncompress', '--')
error = 'torgb.error' # Exception
def torgb(filename):
temps = []
ret = None
try:
ret = _torgb(filename, temps)
finally:
for temp in temps[:]:
if temp <> ret:
try:
os.unlink(temp)
except os.error:
pass
temps.remove(temp)
return ret
def _torgb(filename, temps):
if filename[-2:] == '.Z':
fname = tempfile.mktemp()
temps.append(fname)
sts = uncompress.copy(filename, fname)
if sts:
raise error, filename + ': uncompress failed'
else:
fname = filename
try:
ftype = imghdr.what(fname)
except IOError, msg:
if type(msg) == type(()) and len(msg) == 2 and \
type(msg[0]) == type(0) and type(msg[1]) == type(''):
msg = msg[1]
if type(msg) <> type(''):
msg = `msg`
raise error, filename + ': ' + msg
if ftype == 'rgb':
return fname
if ftype == None or not table.has_key(ftype):
raise error, \
filename + ': unsupported image file type ' + `ftype`
temp = tempfile.mktemp()
sts = table[ftype].copy(fname, temp)
if sts:
raise error, filename + ': conversion to rgb failed'
return temp
......@@ -163,3 +163,15 @@ def expandtabs(s, tabsize):
res = res + line
line = ''
return res + line
# Try importing optional built-in module "strop" -- if it exists,
# it redefines some string operations that are 100-1000 times faster.
# The manipulation with index_error is needed for compatibility.
try:
from strop import *
from strop import index
index_error = ValueError
except ImportError:
pass # Use the original, slow versions
......@@ -163,3 +163,15 @@ def expandtabs(s, tabsize):
res = res + line
line = ''
return res + line
# Try importing optional built-in module "strop" -- if it exists,
# it redefines some string operations that are 100-1000 times faster.
# The manipulation with index_error is needed for compatibility.
try:
from strop import *
from strop import index
index_error = ValueError
except ImportError:
pass # Use the original, slow versions
# Convert "arbitrary" sound files to AIFF files (Apple and SGI's audio format).
# Input may be compressed.
# Uncompressed file type may be AIFF, WAV, VOC, 8SVX, NeXT/Sun, and others.
# An exception is raised if the file is not of a recognized type.
# Returned filename is either the input filename or a temporary filename;
# in the latter case the caller must ensure that it is removed.
# Other temporary files used are removed by the function.
import os
import tempfile
import pipes
import sndhdr
table = {}
t = pipes.Template().init()
t.append('sox -t au - -t aiff -r 8000 -', '--')
table['au'] = t
# XXX The following is actually sub-optimal.
# XXX The HCOM sampling rate can be 22k, 22k/2, 22k/3 or 22k/4.
# XXX We must force the output sampling rate else the SGI won't play
# XXX files sampled at 5.5k or 7.333k; however this means that files
# XXX sampled at 11k are unnecessarily expanded.
# XXX Similar comments apply to some other file types.
t = pipes.Template().init()
t.append('sox -t hcom - -t aiff -r 22050 -', '--')
table['hcom'] = t
t = pipes.Template().init()
t.append('sox -t voc - -t aiff -r 11025 -', '--')
table['voc'] = t
t = pipes.Template().init()
t.append('sox -t wav - -t aiff -', '--')
table['wav'] = t
t = pipes.Template().init()
t.append('sox -t 8svx - -t aiff -r 16000 -', '--')
table['8svx'] = t
t = pipes.Template().init()
t.append('sox -t sndt - -t aiff -r 16000 -', '--')
table['sndt'] = t
t = pipes.Template().init()
t.append('sox -t sndr - -t aiff -r 16000 -', '--')
table['sndr'] = t
uncompress = pipes.Template().init()
uncompress.append('uncompress', '--')
error = 'toaiff.error' # Exception
def toaiff(filename):
temps = []
ret = None
try:
ret = _toaiff(filename, temps)
finally:
for temp in temps[:]:
if temp <> ret:
try:
os.unlink(temp)
except os.error:
pass
temps.remove(temp)
return ret
def _toaiff(filename, temps):
if filename[-2:] == '.Z':
fname = tempfile.mktemp()
temps.append(fname)
sts = uncompress.copy(filename, fname)
if sts:
raise error, filename + ': uncomress failed'
else:
fname = filename
try:
ftype = sndhdr.whathdr(fname)
if ftype:
ftype = ftype[0] # All we're interested in
except IOError:
if type(msg) == type(()) and len(msg) == 2 and \
type(msg[0]) == type(0) and type(msg[1]) == type(''):
msg = msg[1]
if type(msg) <> type(''):
msg = `msg`
raise error, filename + ': ' + msg
if ftype == 'aiff':
return fname
if ftype == None or not table.has_key(ftype):
raise error, \
filename + ': unsupported audio file type ' + `ftype`
temp = tempfile.mktemp()
temps.append(temp)
sts = table[ftype].copy(fname, temp)
if sts:
raise error, filename + ': conversion to aiff failed'
return temp
# Parse a timezone specification.
# XXX Unfinished.
# XXX Only the typical form "XXXhhYYY;ddd/hh,ddd/hh" is currently supported.
tzpat = '^\([A-Z][A-Z][A-Z]\)\([-+]?[0-9]+\)\([A-Z][A-Z][A-Z]\);' + \
'\([0-9]+\)/\([0-9]+\),\([0-9]+\)/\([0-9]+\)$'
tzprog = None
def tzparse(tzstr):
global tzprog
if tzprog == None:
import regex
tzprog = regex.compile(tzpat)
if not tzprog.match(tzstr):
raise ValueError, 'not the TZ syntax I understand'
regs = tzprog.regs
subs = []
for i in range(1, 8):
a, b = regs[i]
subs.append(tzstr[a:b])
for i in (1, 3, 4, 5, 6):
subs[i] = eval(subs[i])
[tzname, delta, dstname, daystart, hourstart, dayend, hourend] = subs
return (tzname, delta, dstname, daystart, hourstart, dayend, hourend)
def tzlocaltime(time, params):
import calendar
(tzname, delta, dstname, daystart, hourstart, dayend, hourend) = params
year, month, days, hours, mins, secs, yday, wday = \
calendar.gmtime(time - delta*3600)
if (daystart, hourstart) <= (yday+1, hours) < (dayend, hourend):
tzname = dstname
hours = hours + 1
return year, month, days, hours, mins, secs, yday, wday, tzname
def tzset():
global tzparams, timezone, altzone, daylight, tzname
import os
tzstr = os.environ['TZ']
tzparams = tzparse(tzstr)
timezone = tzparams[1] * 3600
altzone = timezone + 3600
daylight = 1
tzname = tzparams[0], tzparams[2]
def isdst(time):
import calendar
(tzname, delta, dstname, daystart, hourstart, dayend, hourend) = \
tzparams
year, month, days, hours, mins, secs, yday, wday = \
calendar.gmtime(time - delta*3600)
return (daystart, hourstart) <= (yday+1, hours) < (dayend, hourend)
tzset()
def localtime(time):
return tzlocaltime(time, tzparams)
def test():
from calendar import asctime, gmtime
import time, sys
now = time.time()
x = localtime(now)
print 'now =', now, '=', asctime(x[:-1]), x[-1]
now = now - now % (24*3600)
if sys.argv[1:]: now = now + eval(sys.argv[1])
x = gmtime(now)
print 'gmtime =', now, '=', asctime(x), 'yday =', x[-2]
jan1 = now - x[-2]*24*3600
x = localtime(jan1)
print 'jan1 =', jan1, '=', asctime(x[:-1]), x[-1]
for d in range(85, 95) + range(265, 275):
t = jan1 + d*24*3600
x = localtime(t)
print 'd =', d, 't =', t, '=', asctime(x[:-1]), x[-1]
......@@ -18,57 +18,88 @@
# whrandom.random() yields double precision random numbers
# uniformly distributed between 0 and 1.
#
# whrandom.seed() must be called before whrandom.random()
# whrandom.seed(x, y, z) must be called before whrandom.random()
# to seed the generator
#
# There is also an interface to create multiple independent
# random generators, and to choose from other ranges.
# Translated by Guido van Rossum from C source provided by
# Adrian Baddeley.
# The seed
#
_seed = [0, 0, 0]
# Set the seed
#
def seed(x, y, z):
_seed[:] = [x, y, z]
# Return the next random number in the range [0.0 .. 1.0)
#
def random():
from math import floor # floor() function
class whrandom:
#
# Initialize an instance.
# Without arguments, initialize from current time.
# With arguments (x, y, z), initialize from them.
#
[x, y, z] = _seed
x = 171 * (x % 177) - 2 * (x/177)
y = 172 * (y % 176) - 35 * (y/176)
z = 170 * (z % 178) - 63 * (z/178)
def init(self, *xyz):
if not xyz:
# Initialize from current time
import time
t = time.time()
t, x = divmod(t, 256)
t, y = divmod(t, 256)
t, z = divmod(t, 256)
else:
# Initialize from arguments (x, y, z)
x, y, z = xyz
self.seed(x, y, z)
return self
#
if x < 0: x = x + 30269
if y < 0: y = y + 30307
if z < 0: z = z + 30323
# Set the seed from (x, y, z).
# These must be integers in the range [0, 256).
#
_seed[:] = [x, y, z]
def seed(self, *xyz):
if type(xyz) <> type(()) or len(xyz) <> 3:
raise TypeError, '3 seeds required'
x, y, z = xyz
if not type(x) == type(y) == type(z) == type(0):
raise TypeError, 'seeds must be integers'
if not 0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256:
raise ValueError, 'seeds must be in range(0, 256)'
self._seed = xyz
#
term = float(x)/30269.0 + float(y)/30307.0 + float(z)/30323.0
rand = term - floor(term)
# Get the next random number in the range [0.0, 1.0).
#
if rand >= 1.0: rand = 0.0 # floor() inaccuracy?
def random(self):
x, y, z = self._seed
#
x1, x2 = divmod(x, 177)
y1, y2 = divmod(y, 176)
z1, z2 = divmod(z, 178)
#
x = (171 * x2 - 2 * x1) % 30269
y = (172 * y2 - 35 * y1) % 30307
z = (170 * z2 - 63 * z1) % 30323
#
self._seed = x, y, z
#
return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
#
return rand
# Get a random number in the range [a, b).
#
def uniform(self, a, b):
return a + (b-a) * self.random()
#
# Get a random integer in the range [a, b] including both end points.
#
def randint(self, a, b):
return a + int(self.random() * (b+1-a))
#
# Choose a random element from a non-empty sequence.
#
def choice(self, seq):
return seq[int(self.random() * len(seq))]
# Initialize from the current time
#
def init():
import time
t = time.time()
seed(t%256, t/256%256, t/65536%256)
# Make sure the generator is preset to a nonzero value
#
init()
_inst = whrandom().init()
seed = _inst.seed
random = _inst.random
uniform = _inst.uniform
randint = _inst.randint
choice = _inst.choice
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment