Merge branch 'master' into pr/232

This commit is contained in:
Paul Tagliamonte 2013-08-10 17:05:50 -04:00
commit b2951349b2
2 changed files with 133 additions and 57 deletions

View File

@ -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"])
(def *exports* ["cycle" "dec" "distinct" "drop" "even?" "filter" "inc"
"instance?" "iterable?" "iterate" "iterator?" "neg?"
"none?" "nth" "numeric?" "odd?" "pos?" "remove" "repeat"
"repeatedly" "take" "take_nth" "take_while"])

View File

@ -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,8 +259,10 @@
(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"
(setv res (list (take-nth 2 [1 2 3 4 5 6 7])))
@ -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]))