Skip to content

Commit 69aab7f

Browse files
authored
Add simple random functions (#402)
* Add simple random functions * Add tests * Formatting * Ignore linting
1 parent 67806f7 commit 69aab7f

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

src/basilisp/core.lpy

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,6 +1651,40 @@
16511651
{}
16521652
maps)))
16531653

1654+
;;;;;;;;;;;;;;;;;;;;;;
1655+
;; Random Functions ;;
1656+
;;;;;;;;;;;;;;;;;;;;;;
1657+
1658+
(import* random)
1659+
1660+
(defn rand
1661+
"Return a random real number between lower (default: 0) and upper (default: 1) inclusive."
1662+
([] (random/uniform 0 1))
1663+
([upper] (random/uniform 0 upper))
1664+
([lower upper] (random/uniform lower upper)))
1665+
1666+
(defn rand-int
1667+
"Return a random integer between lower (default: 0) and upper inclusive."
1668+
([upper]
1669+
(random/randrange 0 upper))
1670+
([lower upper]
1671+
(random/randrange lower upper)))
1672+
1673+
(defn rand-nth
1674+
"Return a random element from coll."
1675+
[coll]
1676+
(nth coll (rand-int (count coll))))
1677+
1678+
(defn random-sample
1679+
"Return elements from coll with the random probability of prob."
1680+
[prob coll]
1681+
(filter (fn [_] (< (rand) prob)) coll))
1682+
1683+
(defn shuffle
1684+
"Return a random permutation of coll."
1685+
[coll]
1686+
(vec (random/sample (python/list coll) (count coll))))
1687+
16541688
;;;;;;;;;;;;;;;;;;;;
16551689
;; Utility Macros ;;
16561690
;;;;;;;;;;;;;;;;;;;;

src/basilisp/lang/list.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def list(members, meta=None) -> List: # pylint:disable=redefined-builtin
9090
)
9191

9292

93-
def l(*members, meta=None) -> List:
93+
def l(*members, meta=None) -> List: # noqa
9494
"""Creates a new list from members."""
9595
return List( # pylint: disable=abstract-class-instantiated
9696
plist(iterable=members), meta=meta

tests/basilisp/core_test.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,57 @@ def test_not_is_not_any(self, coll):
12281228
assert True is core.not_any__Q__(core.odd__Q__, coll)
12291229

12301230

1231+
class TestRandom:
1232+
COLLS = [
1233+
vec.v("a", "b", "c"),
1234+
llist.l("a", "b", "c"),
1235+
lset.s("a", "b", "c"),
1236+
["a", "b", "c"],
1237+
("a", "b", "c"),
1238+
{"a", "b", "c"},
1239+
]
1240+
1241+
@pytest.fixture(scope="class", params=COLLS)
1242+
def coll(self, request):
1243+
return request.param
1244+
1245+
def test_rand_no_arg(self):
1246+
x = core.rand()
1247+
assert isinstance(x, float)
1248+
assert 0 <= x <= 1
1249+
1250+
def test_rand_only_upper(self):
1251+
x = core.rand(100)
1252+
assert isinstance(x, float)
1253+
assert 0 <= x <= 100
1254+
1255+
def test_rand_upper_and_lower(self):
1256+
x = core.rand(10, 100)
1257+
assert isinstance(x, float)
1258+
assert 10 <= x <= 100
1259+
1260+
def test_rand_int_only_upper(self):
1261+
i = core.rand_int(100)
1262+
assert isinstance(i, int)
1263+
assert 0 <= i <= 100
1264+
1265+
def test_rand_int_upper_and_lower(self):
1266+
i = core.rand_int(10, 100)
1267+
assert isinstance(i, int)
1268+
assert 10 <= i <= 100
1269+
1270+
def test_rand_nth(self, coll):
1271+
e = core.rand_nth(coll)
1272+
assert e in set(coll)
1273+
1274+
def test_random_sample(self, coll):
1275+
coll_elems = set(coll)
1276+
assert all(e in coll_elems for e in core.random_sample(0.5, coll))
1277+
1278+
def test_shuffle(self, coll):
1279+
assert set(coll) == set(core.shuffle(coll))
1280+
1281+
12311282
def test_merge():
12321283
assert None is core.merge()
12331284
assert lmap.Map.empty() == core.merge(lmap.Map.empty())

0 commit comments

Comments
 (0)