-2

I tried two different ways to get a coin flip result, seeding the RNG first in order to get reproducible results.

First, I tried using random.randint:

import random

random.seed(23412)

flip = random.randint(0,1)
if flip == 0:
    print("Tails")
else:
    print("Heads")

For this seed, I get a Heads result; the flip result is 1.

Then, I tried rounding the result of random.random:

import random

random.seed(23412)

flip = random.random()
print(flip) # for testing purposes
new_flip = round(flip)

if new_flip == 0:
    print("Tails")
else:
    print("Heads")

This time, I get a value for flip of 0.27484468113952387, which rounds to 0, i.e. a Tails result.

Why does the result differ? Shouldn't random.randint pull the same random value (since the seed was the same), and flip the coin the same way?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153

2 Answers2

0

Once you set a seed, all random numbers that follow will be consistent. It does not mean that all random numbers will be the same (and not be random any more).

However, once you re-set the seed, the random number generation will start from the beginning. Therefore it's predictable what will happen, e.g. like this, where 200 random numbers are generated in a 100 loops and I can predict each outcome (via assertions)

import random

for i in range(100):
    test_seed = 23412
    random.seed(test_seed)

    flip = round(random.random())
    assert flip == 0                # predict "Tails"
    if flip == 0:
        print("Tails")
    else:
        print("Heads")

    flip = random.randint(0,1)
    assert flip == 1                # predict "Heads"
    if flip == 0:
        print("Tails")
    else:
        print("Heads")
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • sorry i didn't explain my problem well enough to start with. hopefully the edit clarifies my issue, i thought it had something to do with round() but i could be(most definitely) wrong – WildSpaceCadet Oct 02 '22 at 22:16
  • Wait, hold on. Are you saying that you have **two completely separate programs**, where one of them uses `round(random.random())` with that seed value, and the other uses `random.randint(0, 1)` with that seed value? – Karl Knechtel Oct 02 '22 at 22:20
  • yeah thats it, im very new here and dont know how to portray that in my answer so i just did them 1 above the other. but when i run the program i only use 1 method at a time. and with the seed number being 23412 ive also confirmed that the random number is the same yet the top program returns tails and the bottom program returns heads – WildSpaceCadet Oct 02 '22 at 22:39
  • I will edit the question to ask it properly. There are numerous other things that can be improved in the style of asking. – Karl Knechtel Oct 02 '22 at 22:43
  • thanks for your help on making this clearer, ive done yet another edit and hoped that would help but if you have a better way im all ears! – WildSpaceCadet Oct 02 '22 at 22:45
  • Not sure if it's fair to modify the question in a way that existing answers no longer answer the question. The way you had your code initially does absolutely not match the question as it is now. – Thomas Weller Oct 03 '22 at 13:38
0

Seeding a random number generator ensures a reproducible stream of underlying raw data. Different random module methods will compute their results in different ways, using different amounts of data.

The exact computation is an implementation detail. In the implementation I use (although I suspect it is the same for many other versions), random.randint will use the next single bit of raw data from the stream - it does a bunch of math first to figure out how many possible answers there are in range, then rounds that up to the next power of two, then chooses the corresponding number of bits to get a value (0..2n-1), repeats that until it's in range, and finally does more math to scale that to the original range. (If you tried, for example, random.randint(0, 2), it would repeatedly grab two bits interpreted as an integer, until the result isn't 3 which is out of range.)

The implementation of random.random is hidden in the C code, but I assume that it grabs multiple bits of data (at least 53) in order to fill the mantissa of a machine double-precision floating-point value.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • Thanks for the explanation, its very technical and i don't understand it fully but i am sure the more i study the clearer it will become. I did grasp the basic concept though and I appreciate you time. :) – WildSpaceCadet Oct 02 '22 at 23:08
  • It will probably help to study first the underlying theory of how random number generators work. – Karl Knechtel Oct 02 '22 at 23:09