Skip to content

Commit 71b637d

Browse files
committed
add copyrights and tests
1 parent c1c15d3 commit 71b637d

File tree

3 files changed

+251
-0
lines changed

3 files changed

+251
-0
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# Copyright (c) 2018, Oracle and/or its affiliates.
2+
# Copyright (C) 1996-2017 Python Software Foundation
3+
#
4+
# Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
5+
6+
import unittest
7+
import random
8+
import time
9+
10+
11+
class TestBasicOps:
12+
def __init__(self):
13+
super().__init__()
14+
self.gen = random.Random()
15+
16+
def randomlist(self, n):
17+
"""Helper function to make a list of random numbers"""
18+
return [self.gen.random() for i in range(n)]
19+
20+
def test_autoseed(self):
21+
self.gen.seed()
22+
state1 = self.gen.getstate()
23+
time.sleep(0.1)
24+
self.gen.seed() # diffent seeds at different times
25+
state2 = self.gen.getstate()
26+
self.assertNotEqual(state1, state2)
27+
28+
def test_saverestore(self):
29+
N = 1000
30+
self.gen.seed()
31+
state = self.gen.getstate()
32+
randseq = self.randomlist(N)
33+
self.gen.setstate(state) # should regenerate the same sequence
34+
self.assertEqual(randseq, self.randomlist(N))
35+
36+
def test_seedargs(self):
37+
# Seed value with a negative hash.
38+
class MySeed(object):
39+
def __hash__(self):
40+
return -1729
41+
for arg in [None, 0, 0, 1, 1, -1, -1, 10**20, -(10**20),
42+
3.14, 1+2j, 'a', tuple('abc'), MySeed()]:
43+
self.gen.seed(arg)
44+
for arg in [list(range(3)), dict(one=1)]:
45+
self.assertRaises(TypeError, self.gen.seed, arg)
46+
self.assertRaises(TypeError, self.gen.seed, 1, 2, 3, 4)
47+
self.assertRaises(TypeError, type(self.gen), [])
48+
49+
def test_shuffle(self):
50+
shuffle = self.gen.shuffle
51+
lst = []
52+
shuffle(lst)
53+
self.assertEqual(lst, [])
54+
lst = [37]
55+
shuffle(lst)
56+
self.assertEqual(lst, [37])
57+
seqs = [list(range(n)) for n in range(10)]
58+
shuffled_seqs = [list(range(n)) for n in range(10)]
59+
for shuffled_seq in shuffled_seqs:
60+
shuffle(shuffled_seq)
61+
for (seq, shuffled_seq) in zip(seqs, shuffled_seqs):
62+
self.assertEqual(len(seq), len(shuffled_seq))
63+
self.assertEqual(set(seq), set(shuffled_seq))
64+
# The above tests all would pass if the shuffle was a
65+
# no-op. The following non-deterministic test covers that. It
66+
# asserts that the shuffled sequence of 1000 distinct elements
67+
# must be different from the original one. Although there is
68+
# mathematically a non-zero probability that this could
69+
# actually happen in a genuinely random shuffle, it is
70+
# completely negligible, given that the number of possible
71+
# permutations of 1000 objects is 1000! (factorial of 1000),
72+
# which is considerably larger than the number of atoms in the
73+
# universe...
74+
lst = list(range(1000))
75+
shuffled_lst = list(range(1000))
76+
shuffle(shuffled_lst)
77+
self.assertTrue(lst != shuffled_lst)
78+
shuffle(lst)
79+
self.assertTrue(lst != shuffled_lst)
80+
81+
# def test_choice(self):
82+
# choice = self.gen.choice
83+
# with self.assertRaises(IndexError):
84+
# choice([])
85+
# self.assertEqual(choice([50]), 50)
86+
# self.assertIn(choice([25, 75]), [25, 75])
87+
88+
def test_sample(self):
89+
# For the entire allowable range of 0 <= k <= N, validate that
90+
# the sample is of the correct length and contains only unique items
91+
N = 100
92+
population = range(N)
93+
for k in range(N+1):
94+
s = self.gen.sample(population, k)
95+
self.assertEqual(len(s), k)
96+
uniq = set(s)
97+
self.assertEqual(len(uniq), k)
98+
self.assertTrue(uniq <= set(population))
99+
self.assertEqual(self.gen.sample([], 0), []) # test edge case N==k==0
100+
# Exception raised if size of sample exceeds that of population
101+
self.assertRaises(ValueError, self.gen.sample, population, N+1)
102+
self.assertRaises(ValueError, self.gen.sample, [], -1)
103+
104+
def test_sample_distribution(self):
105+
# For the entire allowable range of 0 <= k <= N, validate that
106+
# sample generates all possible permutations
107+
n = 5
108+
pop = range(n)
109+
trials = 10000 # large num prevents false negatives without slowing normal case
110+
def factorial(n):
111+
if n == 0:
112+
return 1
113+
return n * factorial(n - 1)
114+
for k in range(n):
115+
expected = factorial(n) // factorial(n-k)
116+
perms = {}
117+
for i in range(trials):
118+
perms[tuple(self.gen.sample(pop, k))] = None
119+
if len(perms) == expected:
120+
break
121+
else:
122+
self.fail()
123+
124+
def test_sample_inputs(self):
125+
# SF bug #801342 -- population can be any iterable defining __len__()
126+
self.gen.sample(set(range(20)), 2)
127+
self.gen.sample(range(20), 2)
128+
self.gen.sample(range(20), 2)
129+
self.gen.sample(str('abcdefghijklmnopqrst'), 2)
130+
self.gen.sample(tuple('abcdefghijklmnopqrst'), 2)
131+
132+
def test_sample_on_dicts(self):
133+
self.assertRaises(TypeError, self.gen.sample, dict.fromkeys('abcdef'), 2)
134+
135+
def test_choices(self):
136+
choices = self.gen.choices
137+
data = ['red', 'green', 'blue', 'yellow']
138+
str_data = 'abcd'
139+
range_data = range(4)
140+
set_data = set(range(4))
141+
142+
# basic functionality
143+
for sample in [
144+
choices(data, k=5),
145+
choices(data, range(4), k=5),
146+
choices(k=5, population=data, weights=range(4)),
147+
]:
148+
self.assertEqual(len(sample), 5)
149+
self.assertEqual(type(sample), list)
150+
self.assertTrue(set(sample) <= set(data))
151+
152+
def test_gauss(self):
153+
# Ensure that the seed() method initializes all the hidden state. In
154+
# particular, through 2.2.1 it failed to reset a piece of state used
155+
# by (and only by) the .gauss() method.
156+
157+
for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
158+
self.gen.seed(seed)
159+
x1 = self.gen.random()
160+
y1 = self.gen.gauss(0, 1)
161+
162+
self.gen.seed(seed)
163+
x2 = self.gen.random()
164+
y2 = self.gen.gauss(0, 1)
165+
166+
self.assertEqual(x1, x2)
167+
self.assertEqual(y1, y2)
168+
169+
def test_bug_9025(self):
170+
# Had problem with an uneven distribution in int(n*random())
171+
# Verify the fix by checking that distributions fall within expectations.
172+
n = 100000
173+
randrange = self.gen.randrange
174+
k = sum(randrange(6755399441055744) % 3 == 2 for i in range(n))
175+
self.assertTrue(0.30 < k/n < .37, (k/n))

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/PRandom.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,41 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates.
3+
*
4+
* The Universal Permissive License (UPL), Version 1.0
5+
*
6+
* Subject to the condition set forth below, permission is hereby granted to any
7+
* person obtaining a copy of this software, associated documentation and/or data
8+
* (collectively the "Software"), free of charge and under any and all copyright
9+
* rights in the Software, and any and all patent rights owned or freely
10+
* licensable by each licensor hereunder covering either (i) the unmodified
11+
* Software as contributed to or provided by such licensor, or (ii) the Larger
12+
* Works (as defined below), to deal in both
13+
*
14+
* (a) the Software, and
15+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
* one is included with the Software (each a "Larger Work" to which the
17+
* Software is contributed by such licensors),
18+
*
19+
* without restriction, including without limitation the rights to copy, create
20+
* derivative works of, display, perform, and distribute the Software and make,
21+
* use, sell, offer for sale, import, export, have made, and have sold the
22+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
* either these or other terms.
24+
*
25+
* This license is subject to the following condition:
26+
*
27+
* The above copyright notice and either this complete permission notice or at a
28+
* minimum a reference to the UPL must be included in all copies or substantial
29+
* portions of the Software.
30+
*
31+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37+
* SOFTWARE.
38+
*/
139
package com.oracle.graal.python.builtins.objects.random;
240

341
import java.util.Random;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,41 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates.
3+
*
4+
* The Universal Permissive License (UPL), Version 1.0
5+
*
6+
* Subject to the condition set forth below, permission is hereby granted to any
7+
* person obtaining a copy of this software, associated documentation and/or data
8+
* (collectively the "Software"), free of charge and under any and all copyright
9+
* rights in the Software, and any and all patent rights owned or freely
10+
* licensable by each licensor hereunder covering either (i) the unmodified
11+
* Software as contributed to or provided by such licensor, or (ii) the Larger
12+
* Works (as defined below), to deal in both
13+
*
14+
* (a) the Software, and
15+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
* one is included with the Software (each a "Larger Work" to which the
17+
* Software is contributed by such licensors),
18+
*
19+
* without restriction, including without limitation the rights to copy, create
20+
* derivative works of, display, perform, and distribute the Software and make,
21+
* use, sell, offer for sale, import, export, have made, and have sold the
22+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
* either these or other terms.
24+
*
25+
* This license is subject to the following condition:
26+
*
27+
* The above copyright notice and either this complete permission notice or at a
28+
* minimum a reference to the UPL must be included in all copies or substantial
29+
* portions of the Software.
30+
*
31+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37+
* SOFTWARE.
38+
*/
139
package com.oracle.graal.python.builtins.objects.random;
240

341
import java.math.BigInteger;

0 commit comments

Comments
 (0)