FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Remove defunct parts of the random module · pythoncapi/cpython@28de64f · GitHub

forked from python/cpython

Commit 28de64f

Browse files
committed
Remove defunct parts of the random module
1 parent f7ec7a8 commit 28de64f

6 files changed

Lines changed: 32 additions & 360 deletions

File tree

‎Doc/library/random.rst‎

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,14 @@ for cryptographic purposes.
2828

2929
The functions supplied by this module are actually bound methods of a hidden
3030
instance of the :class:`random.Random` class. You can instantiate your own
31-
instances of :class:`Random` to get generators that don't share state. This is
32-
especially useful for multi-threaded programs, creating a different instance of
33-
:class:`Random` for each thread, and using the :meth:`jumpahead` method to make
34-
it likely that the generated sequences seen by each thread don't overlap.
31+
instances of :class:`Random` to get generators that don't share state.
3532

3633
Class :class:`Random` can also be subclassed if you want to use a different
3734
basic generator of your own devising: in that case, override the :meth:`random`,
38-
:meth:`seed`, :meth:`getstate`, :meth:`setstate` and :meth:`jumpahead` methods.
35+
:meth:`seed`, :meth:`getstate`, and :meth:`setstate`.
3936
Optionally, a new generator can supply a :meth:`getrandombits` method --- this
4037
allows :meth:`randrange` to produce selections over an arbitrarily large range.
4138

42-
As an example of subclassing, the :mod:`random` module provides the
43-
:class:`WichmannHill` class that implements an alternative generator in pure
44-
Python. The class provides a backward compatible way to reproduce results from
45-
earlier versions of Python, which used the Wichmann-Hill algorithm as the core
46-
generator. Note that this Wichmann-Hill generator can no longer be recommended:
47-
its period is too short by contemporary standards, and the sequence generated is
48-
known to fail some stringent randomness tests. See the references below for a
49-
recent variant that repairs these flaws.
5039

5140
Bookkeeping functions:
5241

@@ -79,17 +68,6 @@ Bookkeeping functions:
7968
the time :func:`setstate` was called.
8069

8170

82-
.. function:: jumpahead(n)
83-
84-
Change the internal state to one different from and likely far away from the
85-
current state. *n* is a non-negative integer which is used to scramble the
86-
current state vector. This is most useful in multi-threaded programs, in
87-
conjuction with multiple instances of the :class:`Random` class:
88-
:meth:`setstate` or :meth:`seed` can be used to force all instances into the
89-
same internal state, and then :meth:`jumpahead` can be used to force the
90-
instances' states far apart.
91-
92-
9371
.. function:: getrandbits(k)
9472

9573
Returns a python integer with *k* random bits. This method is supplied with
@@ -224,24 +202,6 @@ be found in any statistics text.
224202

225203
Alternative Generators:
226204

227-
.. class:: WichmannHill([seed])
228-
229-
Class that implements the Wichmann-Hill algorithm as the core generator. Has all
230-
of the same methods as :class:`Random` plus the :meth:`whseed` method described
231-
below. Because this class is implemented in pure Python, it is not threadsafe
232-
and may require locks between calls. The period of the generator is
233-
6,953,607,871,644 which is small enough to require care that two independent
234-
random sequences do not overlap.
235-
236-
237-
.. function:: whseed([x])
238-
239-
This is obsolete, supplied for bit-level compatibility with versions of Python
240-
prior to 2.1. See :func:`seed` for details. :func:`whseed` does not guarantee
241-
that distinct integer arguments yield distinct internal states, and can yield no
242-
more than about 2\*\*24 distinct internal states in all.
243-
244-
245205
.. class:: SystemRandom([seed])
246206

247207
Class that uses the :func:`os.urandom` function for generating random numbers
@@ -281,6 +241,4 @@ Examples of basic usage::
281241
equidistributed uniform pseudorandom number generator", ACM Transactions on
282242
Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998.
283243

284-
Wichmann, B. A. & Hill, I. D., "Algorithm AS 183: An efficient and portable
285-
pseudo-random number generator", Applied Statistics 31 (1982) 188-190.
286244

‎Lib/random.py‎

Lines changed: 4 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@
3030
3131
* The period is 2**19937-1.
3232
* It is one of the most extensively tested generators in existence.
33-
* Without a direct way to compute N steps forward, the semantics of
34-
jumpahead(n) are weakened to simply jump to another distant state and rely
35-
on the large period to avoid overlapping sequences.
3633
* The random() method is implemented in C, executes in a single Python step,
3734
and is, therefore, threadsafe.
3835
@@ -49,7 +46,7 @@
4946
"randrange","shuffle","normalvariate","lognormvariate",
5047
"expovariate","vonmisesvariate","gammavariate",
5148
"gauss","betavariate","paretovariate","weibullvariate",
52-
"getstate","setstate","jumpahead", "WichmannHill", "getrandbits",
49+
"getstate","setstate", "getrandbits",
5350
"SystemRandom"]
5451

5552
NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
@@ -70,14 +67,11 @@ class Random(_random.Random):
7067
"""Random number generator base class used by bound module functions.
7168
7269
Used to instantiate instances of Random to get generators that don't
73-
share state. Especially useful for multi-threaded programs, creating
74-
a different instance of Random for each thread, and using the jumpahead()
75-
method to ensure that the generated sequences seen by each thread don't
76-
overlap.
70+
share state.
7771
7872
Class Random can also be subclassed if you want to use a different basic
7973
generator of your own devising: in that case, override the following
80-
methods: random(), seed(), getstate(), setstate() and jumpahead().
74+
methods: random(), seed(), getstate(), and setstate().
8175
Optionally, implement a getrandombits() method so that randrange()
8276
can cover arbitrarily large ranges.
8377
@@ -615,156 +609,6 @@ def weibullvariate(self, alpha, beta):
615609
u = 1.0 - self.random()
616610
return alpha * pow(-_log(u), 1.0/beta)
617611

618-
## -------------------- Wichmann-Hill -------------------
619-
620-
class WichmannHill(Random):
621-
622-
VERSION = 1 # used by getstate/setstate
623-
624-
def seed(self, a=None):
625-
"""Initialize internal state from hashable object.
626-
627-
None or no argument seeds from current time or from an operating
628-
system specific randomness source if available.
629-
630-
If a is not None or an int or long, hash(a) is used instead.
631-
632-
If a is an int or long, a is used directly. Distinct values between
633-
0 and 27814431486575L inclusive are guaranteed to yield distinct
634-
internal states (this guarantee is specific to the default
635-
Wichmann-Hill generator).
636-
"""
637-
638-
if a is None:
639-
try:
640-
a = int(_hexlify(_urandom(16)), 16)
641-
except NotImplementedError:
642-
import time
643-
a = int(time.time() * 256) # use fractional seconds
644-
645-
if not isinstance(a, int):
646-
a = hash(a)
647-
648-
a, x = divmod(a, 30268)
649-
a, y = divmod(a, 30306)
650-
a, z = divmod(a, 30322)
651-
self._seed = int(x)+1, int(y)+1, int(z)+1
652-
653-
self.gauss_next = None
654-
655-
def random(self):
656-
"""Get the next random number in the range [0.0, 1.0)."""
657-
658-
# Wichman-Hill random number generator.
659-
#
660-
# Wichmann, B. A. & Hill, I. D. (1982)
661-
# Algorithm AS 183:
662-
# An efficient and portable pseudo-random number generator
663-
# Applied Statistics 31 (1982) 188-190
664-
#
665-
# see also:
666-
# Correction to Algorithm AS 183
667-
# Applied Statistics 33 (1984) 123
668-
#
669-
# McLeod, A. I. (1985)
670-
# A remark on Algorithm AS 183
671-
# Applied Statistics 34 (1985),198-200
672-
673-
# This part is thread-unsafe:
674-
# BEGIN CRITICAL SECTION
675-
x, y, z = self._seed
676-
x = (171 * x) % 30269
677-
y = (172 * y) % 30307
678-
z = (170 * z) % 30323
679-
self._seed = x, y, z
680-
# END CRITICAL SECTION
681-
682-
# Note: on a platform using IEEE-754 double arithmetic, this can
683-
# never return 0.0 (asserted by Tim; proof too long for a comment).
684-
return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
685-
686-
def getstate(self):
687-
"""Return internal state; can be passed to setstate() later."""
688-
return self.VERSION, self._seed, self.gauss_next
689-
690-
def setstate(self, state):
691-
"""Restore internal state from object returned by getstate()."""
692-
version = state[0]
693-
if version == 1:
694-
version, self._seed, self.gauss_next = state
695-
else:
696-
raise ValueError("state with version %s passed to "
697-
"Random.setstate() of version %s" %
698-
(version, self.VERSION))
699-
700-
def jumpahead(self, n):
701-
"""Act as if n calls to random() were made, but quickly.
702-
703-
n is an int, greater than or equal to 0.
704-
705-
Example use: If you have 2 threads and know that each will
706-
consume no more than a million random numbers, create two Random
707-
objects r1 and r2, then do
708-
r2.setstate(r1.getstate())
709-
r2.jumpahead(1000000)
710-
Then r1 and r2 will use guaranteed-disjoint segments of the full
711-
period.
712-
"""
713-
714-
if not n >= 0:
715-
raise ValueError("n must be >= 0")
716-
x, y, z = self._seed
717-
x = int(x * pow(171, n, 30269)) % 30269
718-
y = int(y * pow(172, n, 30307)) % 30307
719-
z = int(z * pow(170, n, 30323)) % 30323
720-
self._seed = x, y, z
721-
722-
def __whseed(self, x=0, y=0, z=0):
723-
"""Set the Wichmann-Hill seed from (x, y, z).
724-
725-
These must be integers in the range [0, 256).
726-
"""
727-
728-
if not type(x) == type(y) == type(z) == int:
729-
raise TypeError('seeds must be integers')
730-
if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
731-
raise ValueError('seeds must be in range(0, 256)')
732-
if 0 == x == y == z:
733-
# Initialize from current time
734-
import time
735-
t = int(time.time() * 256)
736-
t = int((t&0xffffff) ^ (t>>24))
737-
t, x = divmod(t, 256)
738-
t, y = divmod(t, 256)
739-
t, z = divmod(t, 256)
740-
# Zero is a poor seed, so substitute 1
741-
self._seed = (x or 1, y or 1, z or 1)
742-
743-
self.gauss_next = None
744-
745-
def whseed(self, a=None):
746-
"""Seed from hashable object's hash code.
747-
748-
None or no argument seeds from current time. It is not guaranteed
749-
that objects with distinct hash codes lead to distinct internal
750-
states.
751-
752-
This is obsolete, provided for compatibility with the seed routine
753-
used prior to Python 2.1. Use the .seed() method instead.
754-
"""
755-
756-
if a is None:
757-
self.__whseed()
758-
return
759-
a = hash(a)
760-
a, x = divmod(a, 256)
761-
a, y = divmod(a, 256)
762-
a, z = divmod(a, 256)
763-
x = (x + a) % 256 or 1
764-
y = (y + a) % 256 or 1
765-
z = (z + a) % 256 or 1
766-
self.__whseed(x, y, z)
767-
768612
## --------------- Operating System Random Source ------------------
769613

770614
class SystemRandom(Random):
@@ -789,10 +633,9 @@ def getrandbits(self, k):
789633
x = int(_hexlify(_urandom(bytes)), 16)
790634
return x >> (bytes * 8 - k) # trim excess bits
791635

792-
def _stub(self, *args, **kwds):
636+
def seed(self, *args, **kwds):
793637
"Stub method. Not used for a system random number generator."
794638
return None
795-
seed = jumpahead = _stub
796639

797640
def _notimplemented(self, *args, **kwds):
798641
"Method should not be called for a system random number generator."
@@ -866,7 +709,6 @@ def _test(N=2000):
866709
weibullvariate = _inst.weibullvariate
867710
getstate = _inst.getstate
868711
setstate = _inst.setstate
869-
jumpahead = _inst.jumpahead
870712
getrandbits = _inst.getrandbits
871713

872714
if __name__ == '__main__':

‎Lib/test/test_generators.py‎

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@
444444
>>> roots = sets[:]
445445
446446
>>> import random
447-
>>> gen = random.WichmannHill(42)
447+
>>> gen = random.Random(42)
448448
>>> while 1:
449449
... for s in sets:
450450
... print(" %s->%s" % (s, s.find()), end='')
@@ -458,29 +458,29 @@
458458
... else:
459459
... break
460460
A->A B->B C->C D->D E->E F->F G->G H->H I->I J->J K->K L->L M->M
461-
merged D into G
462-
A->A B->B C->C D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M
463-
merged C into F
464-
A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M
461+
merged I into A
462+
A->A B->B C->C D->D E->E F->F G->G H->H I->A J->J K->K L->L M->M
463+
merged D into C
464+
A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->K L->L M->M
465+
merged K into H
466+
A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->H L->L M->M
465467
merged L into A
466-
A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->A M->M
467-
merged H into E
468-
A->A B->B C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M
469-
merged B into E
470-
A->A B->E C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M
468+
A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->H L->A M->M
469+
merged E into A
470+
A->A B->B C->C D->C E->A F->F G->G H->H I->A J->J K->H L->A M->M
471+
merged B into G
472+
A->A B->G C->C D->C E->A F->F G->G H->H I->A J->J K->H L->A M->M
473+
merged A into F
474+
A->F B->G C->C D->C E->F F->F G->G H->H I->F J->J K->H L->F M->M
475+
merged H into G
476+
A->F B->G C->C D->C E->F F->F G->G H->G I->F J->J K->G L->F M->M
477+
merged F into J
478+
A->J B->G C->C D->C E->J F->J G->G H->G I->J J->J K->G L->J M->M
479+
merged M into C
480+
A->J B->G C->C D->C E->J F->J G->G H->G I->J J->J K->G L->J M->C
471481
merged J into G
472-
A->A B->E C->F D->G E->E F->F G->G H->E I->I J->G K->K L->A M->M
473-
merged E into G
474-
A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->M
475-
merged M into G
476-
A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->G
477-
merged I into K
478-
A->A B->G C->F D->G E->G F->F G->G H->G I->K J->G K->K L->A M->G
479-
merged K into A
480-
A->A B->G C->F D->G E->G F->F G->G H->G I->A J->G K->A L->A M->G
481-
merged F into A
482-
A->A B->G C->A D->G E->G F->A G->G H->G I->A J->G K->A L->A M->G
483-
merged A into G
482+
A->G B->G C->C D->C E->G F->G G->G H->G I->G J->G K->G L->G M->C
483+
merged C into G
484484
A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G
485485
486486
"""

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL