This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-02-24
Channels
- # beginners (113)
- # boot (9)
- # cider (6)
- # cljs-dev (33)
- # cljsjs (1)
- # clojure (73)
- # clojure-italy (4)
- # clojure-russia (6)
- # clojure-spec (13)
- # clojure-uk (21)
- # clojured (1)
- # clojurescript (79)
- # core-async (6)
- # core-logic (4)
- # datascript (5)
- # datomic (5)
- # duct (12)
- # events (1)
- # figwheel (9)
- # fulcro (143)
- # garden (2)
- # leiningen (1)
- # luminus (24)
- # off-topic (1)
- # parinfer (7)
- # protorepl (12)
- # re-frame (4)
- # reagent (32)
- # rum (1)
- # shadow-cljs (46)
- # spacemacs (4)
- # specter (27)
- # sql (6)
- # unrepl (3)
- # videos (1)
Hi - I'm learning spec. I've googled and doc'ed but can't find a clue how to spec the sum of all numbers in a collection (a map) in this case
(s/def ::percentage (s/and double? #(>= % 0) #(<= % 100)))
(s/def ::scores (s/map-of keyword? ::percentage))
(s/valid? ::percentage 50.05)
(s/valid? ::scores {:a 70.49 :b 20.21 :c 9.29})
I'd like to confirm that the sum of ::scores = 100#(= 100 (apply + (vals %)))
surely?
Does anyone here have an open source repo where they're using spec? I feel like I'm missing something fundamental about spec and I'm hoping that looking at a few good examples of it being used within a project might help solidify some of the core concepts for me.
@yogidevbear We wrote https://github.com/functionalfoundry/entitydb some time ago. Starting from workflo.entitydb.core/empty-db
, most functions and input/output data have specs to allow random testing and integrity checking.
Something less complex perhaps: specs for the Om Next query language: https://github.com/functionalfoundry/macros/blob/master/src/main/workflo/macros/specs/om_query.cljc
@robert-stuttaford sorry I worded the question badly. I can't figure out how to compose a spec using map-of and
#(= 100 (apply + (vals %)))
. (s/def ::scores (s/and (s/map-of keyword? ::percentage) #(= 100 (apply + (vals %)))))
doesn't work. Also, wouldn't we want to be the kind of community to support and encourage beginners, surely?(defn approx=
"Return a fn that checks that a value is approximately `n` (within `e`)"
[n e]
#(-> (apply + (vals %))
(- n)
(Math/abs)
(< e)))
(s/def ::percentage (s/and double? #(>= % 0) #(<= % 100)))
(s/def ::scores
(s/and (s/map-of keyword? ::percentage)
(approx= 100 0.1)))
(s/def ::scores-restrictive
(s/and (s/map-of keyword? ::percentage)
(approx= 100 0.001)))
(s/valid? ::percentage 50.05)
(def the-map {:a 70.49 :b 20.21 :c 9.29})
(apply + (vals the-map))
(s/valid? ::scores the-map)
(s/valid? ::scores-restrictive the-map)
Actually, @poppetew, your (s/and ,,, #(= 100 (apply + (vals %))))
would work, if you were using integers. That’s why we needed the approx=
fn up there.
(def the-map {:a 70.49, :b 20.21, :c 9.29})
=> #'cognitect.transcriptor.t_1/the-map
(apply + (vals the-map))
=> 99.98999999999998
(s/valid? :cognitect.transcriptor.t_1/scores the-map)
=> true
(s/valid? :cognitect.transcriptor.t_1/scores-restrictive the-map)
=> false
@poppetew i apologise if my rapidly typed response wasn’t suitably welcoming for you - i figured something would be better than nothing. i recognise now that it could have come across as condescending - not my intent! looks like @luskwater provided a far more considered response, which has taught me something!
@poppetew i am incredibly supportive of beginners 🙂
Wouldn't have had an answer for @poppetew so quickly, had it not been for @robert-stuttaford and his initial suggestion. Collaboration across timezones takes a little time itself.