diff options
author | Guido van Rossum <guido@python.org> | 1992-10-18 17:09:59 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1992-10-18 17:09:59 (GMT) |
commit | 2db91358def94cf8081f27b736988320d14eba39 (patch) | |
tree | f73562d6cfd16adf8723bbe702be55d13e2122f5 /Lib/whrandom.py | |
parent | 0cb8e8cfc09dd0919882da968c3e95bf070e257d (diff) | |
download | cpython-2db91358def94cf8081f27b736988320d14eba39.zip cpython-2db91358def94cf8081f27b736988320d14eba39.tar.gz cpython-2db91358def94cf8081f27b736988320d14eba39.tar.bz2 |
Misc changes and new modules. whrandom is "objectified". SOCKET.py
is moved to the sgi subdirectory.
Diffstat (limited to 'Lib/whrandom.py')
-rw-r--r-- | Lib/whrandom.py | 105 |
1 files changed, 68 insertions, 37 deletions
diff --git a/Lib/whrandom.py b/Lib/whrandom.py index 2ce5f8f..6623904 100644 --- a/Lib/whrandom.py +++ b/Lib/whrandom.py @@ -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 |