random.choice gives different results on Python 2 and 3 -
background
i want test code depends on random
module.
the problematic pr https://github.com/axelrod-python/axelrod/pull/202 , code here https://github.com/axelrod-python/axelrod/blob/master/axelrod/strategies/qlearner.py
the problem
since random
module produces pseudo-random numbers, set random.seed(x)
known value x
. works consecutive test runs. however, python 3 seems give different numbers python 2 when using random.choice([d, c])
following snippet:
import random random.seed(1) in range(10): print(random.choice(['c', 'd']), end=', ')
gives different result python 2 , 3
$ python2 test.py c, d, d, c, c, c, d, d, c, c $ python3 test.py c, c, d, c, d, d, d, d, c, c
however, random.random
method works same on 2.x , 3.x:
import random random.seed(1) in range(10): print(random.random()) $ python3 test.py 0.13436424411240122 0.8474337369372327 0.763774618976614 0.2550690257394217 0.49543508709194095 0.4494910647887381 0.651592972722763 0.7887233511355132 0.0938595867742349 0.02834747652200631 $ python2 test.py 0.134364244112 0.847433736937 0.763774618977 0.255069025739 0.495435087092 0.449491064789 0.651592972723 0.788723351136 0.0938595867742 0.028347476522
workaround
i can mock
output of random.choice
, works simple test cases. however, complicated test cases, i'm not able mock output, because don't know how should like.
the question
have done wrong when calling random.choice
method?
according https://docs.python.org/2/library/random.html, rng changed in python 2.4 , may use operating system resources. based on , other answer question, it's not reasonable expect random give same result on 2 different versions of python, 2 different operating systems, or 2 different computers. of knows, next version of python implement random function uses system's microphone generate random sequence.
short version: should never depend on rng give deterministic result. if need known sequence satisfy unit test, need either redesign method or unit test.
one way might split method 2 parts: 1 part generates random number. second part consumes value , acts on it. write 2 unit tests: 1 test coverage of generated values, , separate 1 test output of method based on specific inputs.
another way might change method output not result random number created result. can modify unit test compare 2 , pass or fail test based on expected output of known pairs.
or perhaps unit test can modified run test n number of times , spread confirms sort of randomness.
Comments
Post a Comment