Merge branch 'master' into pr/232
This commit is contained in:
commit
b2951349b2
@ -3,33 +3,38 @@
|
||||
;;;;
|
||||
|
||||
|
||||
(defn _numeric-check [x]
|
||||
(if (not (numeric? x))
|
||||
(raise (TypeError (.format "{0!r} is not a number" x)))))
|
||||
|
||||
(defn cycle [coll]
|
||||
"Yield an infinite repetition of the items in coll"
|
||||
(while true
|
||||
(for [x coll]
|
||||
(setv seen [])
|
||||
(for [x coll]
|
||||
(yield x)
|
||||
(.append seen x))
|
||||
(while seen
|
||||
(for [x seen]
|
||||
(yield x))))
|
||||
|
||||
(defn dec [n]
|
||||
"Decrement n by 1"
|
||||
(_numeric-check n)
|
||||
(- n 1))
|
||||
|
||||
(defn distinct [coll]
|
||||
"Return a generator from the original collection with duplicates
|
||||
removed"
|
||||
(let [ [seen [] ]
|
||||
[citer (iter coll)]
|
||||
[val (next citer)] ]
|
||||
(while (not (none? val))
|
||||
(do
|
||||
(if (not_in val seen)
|
||||
(do
|
||||
(yield val)
|
||||
(.append seen val)))
|
||||
(setv val (next citer))))))
|
||||
(let [[seen []] [citer (iter coll)]]
|
||||
(for [val citer]
|
||||
(if (not_in val seen)
|
||||
(do
|
||||
(yield val)
|
||||
(.append seen val))))))
|
||||
|
||||
(defn drop [count coll]
|
||||
"Drop `count` elements from `coll` and yield back the rest"
|
||||
(let [ [citer (iter coll)] ]
|
||||
(let [[citer (iter coll)]]
|
||||
(try (for [i (range count)]
|
||||
(next citer))
|
||||
(catch [StopIteration]))
|
||||
@ -37,18 +42,19 @@
|
||||
|
||||
(defn even? [n]
|
||||
"Return true if n is an even number"
|
||||
(_numeric-check n)
|
||||
(= (% n 2) 0))
|
||||
|
||||
(defn filter [pred coll]
|
||||
"Return all elements from coll that pass filter"
|
||||
(let [ [citer (iter coll)] [val (next citer)] ]
|
||||
(while (not (none? val))
|
||||
"Return all elements from `coll` that pass `pred`"
|
||||
(let [[citer (iter coll)]]
|
||||
(for [val citer]
|
||||
(if (pred val)
|
||||
(yield val))
|
||||
(setv val (next citer)))))
|
||||
(yield val)))))
|
||||
|
||||
(defn inc [n]
|
||||
"Increment n by 1"
|
||||
(_numeric-check n)
|
||||
(+ n 1))
|
||||
|
||||
(defn instance? [klass x]
|
||||
@ -72,12 +78,17 @@
|
||||
|
||||
(defn neg? [n]
|
||||
"Return true if n is < 0"
|
||||
(_numeric-check n)
|
||||
(< n 0))
|
||||
|
||||
(defn none? [x]
|
||||
"Return true if x is None"
|
||||
(is x None))
|
||||
|
||||
(defn numeric? [x]
|
||||
(import numbers)
|
||||
(instance? numbers.Number x))
|
||||
|
||||
(defn nth [coll index]
|
||||
"Return nth item in collection or sequence, counting from 0"
|
||||
(if (not (neg? index))
|
||||
@ -90,19 +101,20 @@
|
||||
|
||||
(defn odd? [n]
|
||||
"Return true if n is an odd number"
|
||||
(_numeric-check n)
|
||||
(= (% n 2) 1))
|
||||
|
||||
(defn pos? [n]
|
||||
"Return true if n is > 0"
|
||||
(_numeric_check n)
|
||||
(> n 0))
|
||||
|
||||
(defn remove [pred coll]
|
||||
"Return coll with elements removed that pass `pred`"
|
||||
(let [ [citer (iter coll)] [val (next citer)] ]
|
||||
(while (not (none? val))
|
||||
(let [[citer (iter coll)]]
|
||||
(for [val citer]
|
||||
(if (not (pred val))
|
||||
(yield val))
|
||||
(setv val (next citer)))))
|
||||
(yield val)))))
|
||||
|
||||
(defn repeat [x &optional n]
|
||||
"Yield x forever or optionally n times"
|
||||
@ -116,33 +128,33 @@
|
||||
(while true
|
||||
(yield (func))))
|
||||
|
||||
(defn take [count what]
|
||||
"Take `count` elements from `what`, or the whole set if the total
|
||||
number of entries in `what` is less than `count`."
|
||||
(setv what (iter what))
|
||||
(for [i (range count)]
|
||||
(yield (next what))))
|
||||
(defn take [count coll]
|
||||
"Take `count` elements from `coll`, or the whole set if the total
|
||||
number of entries in `coll` is less than `count`."
|
||||
(let [[citer (iter coll)]]
|
||||
(for [_ (range count)]
|
||||
(yield (next citer)))))
|
||||
|
||||
(defn take-nth [n coll]
|
||||
"Return every nth member of coll
|
||||
raises ValueError for (not (pos? n))"
|
||||
(if (pos? n)
|
||||
(let [ [citer (iter coll)] [val (next citer)] ]
|
||||
(while (not (none? val))
|
||||
(let [[citer (iter coll)] [skip (dec n)]]
|
||||
(for [val citer]
|
||||
(yield val)
|
||||
(for [_ (range (dec n))]
|
||||
(next citer))
|
||||
(setv val (next citer))))
|
||||
(for [_ (range skip)]
|
||||
(next citer))))
|
||||
(raise (ValueError "n must be positive"))))
|
||||
|
||||
(defn take-while [pred coll]
|
||||
"Take all elements while `pred` is true"
|
||||
(let [ [citer (iter coll)] [val (next citer)] ]
|
||||
(while (pred val)
|
||||
(yield val)
|
||||
(setv val (next citer)))))
|
||||
(let [[citer (iter coll)]]
|
||||
(for [val citer]
|
||||
(if (pred val)
|
||||
(yield val)
|
||||
(break)))))
|
||||
|
||||
(def *exports* ["cycle" "dec" "distinct" "drop" "even?" "filter" "inc"
|
||||
"instance?" "iterable?" "iterate" "iterator?" "neg?"
|
||||
"none?" "nth" "odd?" "pos?" "remove" "repeat" "repeatedly"
|
||||
"take" "take_nth" "take_while"])
|
||||
"none?" "nth" "numeric?" "odd?" "pos?" "remove" "repeat"
|
||||
"repeatedly" "take" "take_nth" "take_while"])
|
||||
|
@ -13,14 +13,22 @@
|
||||
|
||||
(defn test-cycle []
|
||||
"NATIVE: testing cycle"
|
||||
(assert-equal (list (cycle [])) [])
|
||||
(assert-equal (list (take 7 (cycle [1 2 3]))) [1 2 3 1 2 3 1])
|
||||
(assert-equal (list (take 2 (cycle [1 2 3]))) [1 2]))
|
||||
(assert-equal (list (take 2 (cycle [1 2 3]))) [1 2])
|
||||
(assert-equal (list (take 4 (cycle [1 None 3]))) [1 None 3 1]))
|
||||
|
||||
(defn test-dec []
|
||||
"NATIVE: testing the dec function"
|
||||
(assert-equal 0 (dec 1))
|
||||
(assert-equal -1 (dec 0))
|
||||
(assert-equal 0 (dec (dec 2))))
|
||||
(assert-equal 0 (dec (dec 2)))
|
||||
(try (do (dec "foo") (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (do (dec []) (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (do (dec None) (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
|
||||
|
||||
(defn test-distinct []
|
||||
"NATIVE: testing the distinct function"
|
||||
@ -32,14 +40,19 @@
|
||||
;; now with an iter
|
||||
(setv test_iter (iter [1 2 3 4 3 5 2]))
|
||||
(setv res (list (distinct test_iter)))
|
||||
(assert-equal res [1 2 3 4 5]))
|
||||
(assert-equal res [1 2 3 4 5])
|
||||
; make sure we can handle None in the list
|
||||
(setv res (list (distinct [1 2 3 2 5 None 3 4 None])))
|
||||
(assert-equal res [1 2 3 5 None 4]))
|
||||
|
||||
(defn test-drop []
|
||||
"NATIVE: testing drop function"
|
||||
(setv res (list (drop 2 [1 2 3 4 5])))
|
||||
(assert-equal res [ 3 4 5])
|
||||
(assert-equal res [3 4 5])
|
||||
(setv res (list (drop 3 (iter [1 2 3 4 5]))))
|
||||
(assert-equal res [ 4 5])
|
||||
(assert-equal res [4 5])
|
||||
(setv res (list (drop 3 (iter [1 2 3 None 4 5]))))
|
||||
(assert-equal res [None 4 5])
|
||||
(setv res (list (drop 0 [1 2 3 4 5])))
|
||||
(assert-equal res [1 2 3 4 5])
|
||||
(setv res (list (drop -1 [1 2 3 4 5])))
|
||||
@ -53,7 +66,13 @@
|
||||
"NATIVE: testing the even? function"
|
||||
(assert-true (even? -2))
|
||||
(assert-false (even? 1))
|
||||
(assert-true (even? 0)))
|
||||
(assert-true (even? 0))
|
||||
(try (even? "foo")
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (even? [])
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (even? None)
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
|
||||
|
||||
(defn test-filter []
|
||||
"NATIVE: testing the filter function"
|
||||
@ -63,12 +82,26 @@
|
||||
(setv res (list (filter pos? (iter [ 1 2 3 -4 5 -6]))))
|
||||
(assert-equal res [ 1 2 3 5])
|
||||
(setv res (list (filter neg? [ -1 -4 5 3 4])))
|
||||
(assert-false (= res [1 2])))
|
||||
(assert-false (= res [1 2]))
|
||||
;; test with empty list
|
||||
(setv res (list (filter neg? [])))
|
||||
(assert-equal res [])
|
||||
;; test with None in the list
|
||||
(setv res (list (filter even? (filter numeric? [1 2 None 3 4 None 4 6]))))
|
||||
(assert-equal res [2 4 4 6])
|
||||
(setv res (list (filter none? [1 2 None 3 4 None 4 6])))
|
||||
(assert-equal res [None None]))
|
||||
|
||||
(defn test-inc []
|
||||
"NATIVE: testing the inc function"
|
||||
(assert-equal 3 (inc 2))
|
||||
(assert-equal 0 (inc -1)))
|
||||
(assert-equal 0 (inc -1))
|
||||
(try (do (inc "foo") (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (do (inc []) (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (do (inc None) (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
|
||||
|
||||
(defn test-instance []
|
||||
"NATIVE: testing instance? function"
|
||||
@ -140,7 +173,13 @@
|
||||
"NATIVE: testing the neg? function"
|
||||
(assert-true (neg? -2))
|
||||
(assert-false (neg? 1))
|
||||
(assert-false (neg? 0)))
|
||||
(assert-false (neg? 0))
|
||||
(try (do (neg? "foo") (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (do (neg? []) (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (do (neg? None) (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
|
||||
|
||||
(defn test-none []
|
||||
"NATIVE: testing for `is None`"
|
||||
@ -166,13 +205,25 @@
|
||||
"NATIVE: testing the odd? function"
|
||||
(assert-true (odd? -3))
|
||||
(assert-true (odd? 1))
|
||||
(assert-false (odd? 0)))
|
||||
(assert-false (odd? 0))
|
||||
(try (do (odd? "foo") (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (do (odd? []) (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (do (odd? None) (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
|
||||
|
||||
(defn test-pos []
|
||||
"NATIVE: testing the pos? function"
|
||||
(assert-true (pos? 2))
|
||||
(assert-false (pos? -1))
|
||||
(assert-false (pos? 0)))
|
||||
(assert-false (pos? 0))
|
||||
(try (do (pos? "foo") (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (do (pos? []) (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
|
||||
(try (do (pos? None) (assert False))
|
||||
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
|
||||
|
||||
(defn test-remove []
|
||||
"NATIVE: testing the remove function"
|
||||
@ -180,7 +231,9 @@
|
||||
(assert-equal r [2 4 6])
|
||||
(assert-equal (list (remove even? [1 2 3 4 5])) [1 3 5])
|
||||
(assert-equal (list (remove neg? [1 2 3 4 5])) [1 2 3 4 5])
|
||||
(assert-equal (list (remove pos? [1 2 3 4 5])) []))
|
||||
(assert-equal (list (remove pos? [1 2 3 4 5])) [])
|
||||
;; deal with embedded None
|
||||
(assert-equal (list (remove (fn [x] (not (numeric? x))) [1 2 None 3 None 4])) [1 2 3 4]))
|
||||
|
||||
(defn test-repeat []
|
||||
"NATIVE: testing repeat"
|
||||
@ -206,7 +259,9 @@
|
||||
(setv res (list (take 0 (repeat "s"))))
|
||||
(assert-equal res [])
|
||||
(setv res (list (take -1 (repeat "s"))))
|
||||
(assert-equal res []))
|
||||
(assert-equal res [])
|
||||
(setv res (list (take 6 [1 2 None 4])))
|
||||
(assert-equal res [1 2 None 4]))
|
||||
|
||||
(defn test-take-nth []
|
||||
"NATIVE: testing the take-nth function"
|
||||
@ -222,6 +277,11 @@
|
||||
(assert-equal res [1 7])
|
||||
(setv res (list (take-nth 7 [1 2 3 4 5 6 7])))
|
||||
(assert-equal res [1])
|
||||
;; what if there are None's in list
|
||||
(setv res (list (take-nth 2 [1 2 3 None 5 6])))
|
||||
(assert-equal res [1 3 5])
|
||||
(setv res (list (take-nth 3 [1 2 3 None 5 6])))
|
||||
(assert-equal res [1 None])
|
||||
;; using 0 should raise ValueError
|
||||
(let [[passed false]]
|
||||
(try
|
||||
@ -232,6 +292,10 @@
|
||||
(defn test-take-while []
|
||||
"NATIVE: testing the take-while function"
|
||||
(setv res (list (take-while pos? [ 1 2 3 -4 5])))
|
||||
(assert-equal res [ 1 2 3 ])
|
||||
(assert-equal res [1 2 3])
|
||||
(setv res (list (take-while neg? [ -1 -4 5 3 4])))
|
||||
(assert-false (= res [1 2])))
|
||||
(assert-false (= res [1 2]))
|
||||
(setv res (list (take-while none? [None None 1 2 3])))
|
||||
(assert-equal res [None None])
|
||||
(setv res (list (take-while (fn [x] (not (none? x))) [1 2 3 4 None 5 6 None 7])))
|
||||
(assert-equal res [1 2 3 4]))
|
||||
|
Loading…
Reference in New Issue
Block a user