Thanks for posting your code, but at 178 lines (most of which are either 
commented out or irrelevent to your question) its a hard slog to work out what 
you're doing.

And as for the seemingly endless sequence of "Random number ... Value entered", 
what did information did you think we would get from that? Did you think we 
would study each and every pair of lines, looking for a pattern?

When asking questions about code, it helps to [post a **minimal** 
example](https://stackoverflow.com/help/minimal-reproducible-example) that we 
[can easily run](http://sscce.org/).

In this case, we can compare the Mersenne Twister PRNG with the operating 
system's cryptographically strong RNG and see if we get similar results.

The beauty of a PRNG like the Mersenne Twister is that it is perfectly 
repeatable if you know the seed. So if you repeat this *exact* code, you should 
get the *exact* same output.

(Well, almost. Technically only the output of `random.random` is guaranteed not 
to change from one version to another. But in practice `random.randint` is also 
very stable.)


```python
import random
from statistics import mean, stdev
random.seed(299)
d1 = [random.randint(1, 9) for i in range(100000)]
triples = 0  # Count the number of triples.
for i in range(len(d1)-3):
    a, b, c = d1[i:i+3]
    if a == b == c:  triples += 1

print("mean =", mean(d1))
print("stdev =", stdev(d1))
print("runs of three:", triples)
```

If you run that code, the output you get in Python 3.10 should be:

```text
mean = 4.99025
stdev = 2.586159666323446
runs of three: 1244
```

So out of 100000-3 = 99997 groups of three random integers, 1244 or 1.2% are a 
triplet (a run of three).

Now let's compare the same with the OS's cryptographically strong RNG. Because 
this uses environmental randomness, there's no seed, so we can't replicate the 
results, but you should usually get something similar.


```python
import random
from statistics import mean, stdev
R2 = random.SystemRandom()
d2 = [random.randint(1, 9) for i in range(100000)]
triples = 0  # Count the number of triples.
for i in range(len(d2)-3):
    a, b, c = d2[i:i+3]
    if a == b == c:  triples += 1

print("mean =", mean(d2))
print("stdev =", stdev(d2))
print("runs of three:", triples)
```

And output should usually be something like this:

```text
mean = 4.99198
stdev = 2.5882045258492763
runs of three: 1228
```

Virtually no difference.

Of course there is a *tiny* chance that you could get something outlandishly 
unlikely, like a run of fifty thousand 6s in a row. If such a fluke was 
impossible, it wouldn't be *random*.

You can see that there is no significant difference between the Mersenne 
Twister and the much more expensive crypto-strength SystemRandom.

The MT is a **very** vigorously studied PRNG. It has **excellent** statistical 
properties, without being too expensive to generate random numbers. And it 
allows replicable results: if you know the seed, you can repeat the output.

The only real disadvantage of MT is that it is not secure for cryptographic 
purposes.

(By the way, using `SystemRandom`, I also got 134 runs of four and 14 runs of 
five.)

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/OX3OIARPY3CV37M4LX46SFKO7FT2LCPH/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to