throw exception on k8s wait-for-watches timeout (#1552)

--- waiter/src/waiter/scheduler/kubernetes.clj
+++ waiter/src/waiter/scheduler/kubernetes.clj
@@ -1693,20 +1693,22 @@
   (let [sleep-ms 10]
     (when (pos? init-timeout-ms)
       (loop [total-ms-slept 0]
-        (cond
-          ;; base case: both watches initialized
-          (let [current-watch-state @watch-state]
+        (let [current-watch-state @watch-state]
+          (cond
+            ;; base case: both watches initialized
             (and (get-in current-watch-state [:rs-metadata :timestamp :snapshot])
-                 (get-in current-watch-state [:pods-metadata :timestamp :snapshot])))
-          (log/info "scheduler watches ready after" total-ms-slept "milliseconds")
-          ;; recursive case: still waiting for one or both watches
-          (<= total-ms-slept init-timeout-ms)
-          (do
-            (utils/sleep sleep-ms)
-            (recur (+ total-ms-slept sleep-ms)))
-          ;; base case: init-timeout expired, but the watches still aren't ready
-          :else
-          (log/error "scheduler watches still not ready after" init-timeout-ms "milliseconds"))))))
+                 (get-in current-watch-state [:pods-metadata :timestamp :snapshot]))
+            (log/info "scheduler watches ready after" total-ms-slept "milliseconds")
+            ;; recursive case: still waiting for one or both watches
+            (<= total-ms-slept init-timeout-ms)
+            (do
+              (utils/sleep sleep-ms)
+              (recur (+ total-ms-slept sleep-ms)))
+            ;; base case: init-timeout expired, but the watches still aren't ready
+            :else
+            (let [error-msg "scheduler watches still not ready after" init-timeout-ms "milliseconds"]
+              (log/error error-msg)
+              (throw (ex-info error-msg current-watch-state)))))))))

 (defn fileserver-container-enabled?
   "Returns true when the port is configured on the fileserver configuration."


Set :externs value for :advanced compilation.

--- src/leiningen/new/quil_cljs/project.clj
+++ src/leiningen/new/quil_cljs/project.clj
@@ -14,5 +14,6 @@
   {:builds [{:source-paths ["src"]
              :compiler
              {:output-to "web/js/main.js"
+              :externs ["externs/processing-externs.js"]
               :optimizations :whitespace
               :pretty-print true}}]})


Name tags table in movie-lens example.

Name tags table in movie-lens example.

--- examples/movie-lens/src/movie_lens/tag.clj
+++ examples/movie-lens/src/movie_lens/tag.clj
@@ -21,7 +21,8 @@

 (def table-parameters
-  {:merkle-db.table/primary-key [::user/id ::movie/id ::value]
+  {:merkle-db.table/name "tags"
+   :merkle-db.table/primary-key [::user/id ::movie/id ::value]
    :merkle-db.key/lexicoder [:tuple :integer :integer :string]
    :merkle-db.index/fan-out 256
    :merkle-db.partition/limit 10000})


opus2b


Refactored update-link-count into a transaction

--- src/tropefest/db.clj
+++ src/tropefest/db.clj
@@ -5,11 +5,10 @@
             [clojurewerkz.neocons.rest.labels :as nl]
             [clojurewerkz.neocons.rest.cypher :as cy]
             [clojurewerkz.neocons.rest.relationships :as nrl]
-            [clojurewerkz.neocons.rest.index :as nri]
             [clojurewerkz.neocons.rest.transaction :as tx]
             [tropefest.base :as b]
             [com.numergent.url-tools :as ut]
-            [taoensso.timbre.profiling :as p]
+            [taoensso.timbre.profiling :as prof]
             [environ.core :refer [env]]))

@@ -17,9 +16,6 @@
   "Trivial. Returns a local connection."
   []
   (nr/connect (:db-url env)))
-
-
-

 ;
@@ -89,12 +85,15 @@
 (defn update-link-count!
   "Updates the incoming and outgoing link count for all nodes in the database"
   [conn]
-  (do
-    (cy/query conn "MATCH ()-[r:LINKSTO]->(n) WITH n, COUNT(r) as incoming SET n.incoming = incoming")
-    (cy/query conn "MATCH (n)-[r:LINKSTO]->() WITH n, COUNT(r) as outgoing SET n.outgoing = outgoing")
-    (cy/query conn "MATCH (n) WHERE n.outgoing is null WITH n SET n.outgoing = 0")
-    (cy/query conn "MATCH (n) WHERE n.incoming is null WITH n SET n.incoming = 0")
-    nil))
+  (->>
+    (tx/in-transaction
+      conn
+      (tx/statement "MATCH ()-[r:LINKSTO]->(n:Article) WITH n, COUNT(r) as incoming SET n.incoming = incoming")
+      (tx/statement "MATCH (n:Article)-[r:LINKSTO]->() WITH n, COUNT(r) as outgoing SET n.outgoing = outgoing")
+      (tx/statement "MATCH (n:Article) WHERE n.outgoing is null WITH n SET n.outgoing = 0")
+      (tx/statement "MATCH (n:Article) WHERE n.incoming is null WITH n SET n.incoming = 0"))
+    (prof/p :update-link-count))
+  )

 ;
 ; Node query and creation functions
@@ -127,7 +126,7 @@
         nil
         (-> (match "v")
             (select-keys [:data :metadata]))))
-    (p/p :query-by-code)))
+    (prof/p :query-by-code)))

 (defn query-nodes-to-crawl
   "Return the nodes that need to be crawled according to their nextupdate timestamp"
@@ -189,9 +188,9 @@
 (defn create-node!
   "Creates a node from a connection with a label"
   [conn label data-items]
-  (let [node (p/p :nn-create (nn/create conn (timestamp-create data-items)))]
+  (let [node (prof/p :nn-create (nn/create conn (timestamp-create data-items)))]
     (do
-      (p/p :nl-add (nl/add conn node label))
+      (prof/p :nl-add (nl/add conn node label))
       node)))

 (defn merge-node!
@@ -200,8 +199,8 @@
   [conn ^long id data-items]
   (let [merged (-> (nn/get conn id) (:data) (merge data-items) (timestamp-update))]
     (do
-      (p/p :nn-update (nn/update conn id merged))
-      (p/p :nn-get (nn/get conn id)))))                     ; Notice that we get it again to retrieve the updated values
+      (prof/p :nn-update (nn/update conn id merged))
+      (prof/p :nn-get (nn/get conn id)))))                     ; Notice that we get it again to retrieve the updated values

 (defn create-or-merge-node!
   "Creates a node from a connection with a label. If a node with the id
@@ -235,4 +234,4 @@
 (defn relate-nodes!
   "Links two nodes by a relationship if they aren't yet linked"
   [conn relationship n1 n2]
-  (p/p :nrl-maybe-create (nrl/maybe-create conn n1 n2 relationship)))
+  (prof/p :nrl-maybe-create (nrl/maybe-create conn n1 n2 relationship)))


Remove debug messages from rlocks ns.

Remove debug messages from rlocks ns.

--- src/uxbox/main/ui/workspace/rlocks.cljs
+++ src/uxbox/main/ui/workspace/rlocks.cljs
@@ -18,7 +18,6 @@
 (defn acquire!
   ([type]
    (when (= @lock ::none)
-     (println "acquire!" type)
      (reset! lock type)
      (rx/push! stream [type nil])))
   ([type payload]
@@ -29,7 +28,6 @@
 (defn release!
   [type]
   (when (= @lock type)
-    (println "release!" type)
     (reset! lock ::none)
     (rx/push! stream [::none nil])))


Printing analysis and providing exit code depending on its validity

--- knossos-onebip/src/knossos_onebip/core.clj
+++ knossos-onebip/src/knossos_onebip/core.clj
@@ -1,9 +1,10 @@
 (ns knossos-onebip.core
   (:gen-class)
   (:require [knossos.core :as core]
-            [knossos-onebip.model :as model]
             [clojure.java.io :as io]
-            [clojure-csv.core :refer [parse-csv]]))
+            [knossos-onebip.model]
+            [clojure-csv.core :refer [parse-csv]]
+            [clojure.pprint :refer [pprint]]))

 (defn history-from-file [path]
   (let [lines (-> (io/file path)
@@ -25,6 +26,11 @@
   "Pass a model name (e.g. 'mongo-lock' and a CSV file.
   with the structure 'timestamp,process,type,f' (e.g. '1458232058222295,pp0,invoke|ok|fail,acquire')"
   [& args]
-  (let [[model-name filename] args]
-    (check-history (ns-resolve (find-ns 'knossos-onebip.model) (symbol model-name))
-                    filename)))
+  (let [[model-name filename] args
+        model-fn (ns-resolve (find-ns 'knossos-onebip.model)
+                             (symbol model-name))
+        analysis (check-history model-fn filename)]
+    (pprint analysis)
+    (if (:valid? analysis)
+      (System/exit 0)
+      (System/exit 1))))


Adds equan?

Adds equan?

--- src/the_little_clojurian/chapter4.clj
+++ src/the_little_clojurian/chapter4.clj
@@ -225,3 +225,16 @@
   (is (= (all-nums '(1)) '(1)))
   (is (= (all-nums '(apple)) '()))
   (is (= (all-nums '(1 apple 2 pears 3 bananas)) '(1 2 3))))
+
+(with-test
+  (def equan?
+    (fn [a1 a2]
+      (cond (and (number? a1) (number? a2)) (equal a1 a2)
+            (or (number? a1) (number? a2)) false
+            :else (eq? a1 a2))))
+
+  (is (= (equan? 0 0) true))
+  (is (= (equan? 0 1) false))
+  (is (= (equan? 0 'a) false))
+  (is (= (equan? 'a 'a) true))
+  (is (= (equan? 'a 'b) false)))


testcommit

testcommit

--- resources/leiningen/new/closp/project.clj
+++ resources/leiningen/new/closp/project.clj
@@ -69,7 +69,6 @@
                :ns-routes "{{ns}}.routes"
                :ns-layout "{{ns}}.layout"
                :templates "resources/templates"}
-

   :min-lein-version "2.5.0"


Default wrap-reload to keep throwing exceptions

--- ring-devel/src/ring/middleware/reload.clj
+++ ring-devel/src/ring/middleware/reload.clj
@@ -3,6 +3,20 @@

   This middleware should be limited to use in development environments."
   (:require [ns-tracker.core :refer [ns-tracker]]))
+
+(defn- reloader [dirs retry?]
+  (let [modified-namespaces (ns-tracker dirs)
+        load-queue (java.util.concurrent.LinkedBlockingQueue.)]
+    (fn []
+      (locking load-queue
+        (doseq [ns-sym (modified-namespaces)]
+          (.offer load-queue ns-sym))
+        (loop []
+          (when-let [ns-sym (.peek load-queue)]
+            (if retry?
+              (do (require ns-sym :reload) (.remove load-queue))
+              (do (.remove load-queue) (require ns-sym :reload)))
+            (recur)))))))

 (defn wrap-reload
   "Reload namespaces of modified files before the request is passed to the
@@ -10,13 +24,15 @@

   Accepts the following options:

-  :dirs - A list of directories that contain the source files.
-          Defaults to [\"src\"]."
+  :dirs                   - A list of directories that contain the source files.
+                            Defaults to [\"src\"].
+  :reload-compile-errors? - If true, keep attempting to reload namespaces
+                            that have compile errors.  Defaults to true."
   {:arglists '([handler] [handler options])}
-  [handler & [options]]
-  (let [source-dirs (:dirs options ["src"])
-        modified-namespaces (ns-tracker source-dirs)]
+  [handler & [{:keys [dirs reload-compile-errors?]
+               :or {dirs ["src"]
+                    reload-compile-errors? true}}]]
+  (let [reload! (reloader dirs reload-compile-errors?)]
     (fn [request]
-      (doseq [ns-sym (modified-namespaces)]
-        (require ns-sym :reload))
+      (reload!)
       (handler request))))


Use port 5600, as before

Use port 5600, as before

--- app/dev/nrepl.clj
+++ app/dev/nrepl.clj
@@ -7,9 +7,10 @@
      [refactor-nrepl.middleware :as refactor.nrepl]))

 (defn start-nrepl
-  []
+  [opts]
   (let [server
         (nrepl.server/start-server
+          :port (:port opts)
           :handler
           (apply nrepl.server/default-handler

@@ -21,4 +22,4 @@
     (println "nREPL port:" (:port server))
     server))

-(def server (start-nrepl))
+(def server (start-nrepl {:port 5600}))


simplify homepage sub-headings

simplify homepage sub-headings

--- src-cljs/frontend/components/landing.cljs
+++ src-cljs/frontend/components/landing.cljs
@@ -241,8 +241,7 @@
            [:div.our-philosophy-wrap
             [:div.our-philosophy.content
              [:h1 "Prototyping and team collaboration should be simple. "]
-             [:p {:style {:letter-spacing "-.0067px;"}} ; style is inline so it gets deleted if copy ever changes (dirty hack to get text on single line for phone)
-              "No nonsense. That's why we made Precursor."]
+             [:p "That's why we made Precursor."]
              [:div.calls-to-action
               (om/build make-button (select-keys app [:document/id]))]]]]
           [:div.our-proof
@@ -336,7 +335,7 @@
            [:div.our-philosophy-wrap
             [:div.our-philosophy.content
              [:h1 "It's a blackboard designed to help teams brainstorm."]
-             [:p "Communicate ideas to your team more effectively."]
+             [:p "Precursor is no-nonsense prototyping."]
              (if (utils/logged-in? owner)
                [:div.calls-to-action
                 (om/build make-button (select-keys app [:document/id])


First cut of breadcrumbs.

First cut of breadcrumbs.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -205,15 +205,15 @@
                          [:h2 {:id "projects"} (str  "Projects " (title-for programmes))]
                          (om/build table projects {:opts {:histkey :project}})

-                         [:h2  {:id "properties"} (str "Properties" (title-for projects))]
+                         [:h2  {:id "properties"} (str "Properties" (title-for projects)) [:small (title-for programmes)]]
                          (om/build table properties {:opts {:histkey :property}})

-                         [:h2 {:id "devices"} "Devices" (title-for properties :title-key :addressStreetTwo)]
+                         [:h2 {:id "devices"} "Devices" (title-for properties :title-key :addressStreetTwo) [:small (title-for programmes) (title-for projects)]]
                          (om/build table devices {:opts {:histkey :device}})

                          (om/build device-detail devices)

-                         [:h2 {:id "sensors"} "Sensors" (title-for devices :title-key [:location :name])]
+                         [:h2 {:id "sensors"} "Sensors" (title-for devices :title-key [:location :name]) [:small (title-for programmes) (title-for projects) (title-for properties :title-key :addressStreetTwo)]]
                          (om/build sensor/table data {:opts {:histkey :sensor
                                                              :path    :readings}})
                          (om/build sensor/define-data-set-button data)


Better programme table column order.

Better programme table column order.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -163,9 +163,13 @@
         (html
          [:table {:className "table table-hover"}
           [:thead
-           [:tr [:th "ID"] [:th "Organisations"] [:th "Name"] [:th "Created At"]]]
+           [:tr
+            [:th "Name"]
+            [:th "Organisations"]
+            [:th "ID"]
+            [:th "Created At"]]]
           [:tbody
-           (for [row (sort-by :id (:data programmes))]
+           (for [row (sort-by :name (:data programmes))]
              (let [{:keys [id lead-organisations name description created-at]} row]
                [:tr {:onClick (fn [_ _]
                                 (om/update! programmes :selected id)
@@ -173,7 +177,10 @@
                                 (fixed-scroll-to-element "projects-div"))
                      :className (if (= id (:selected programmes)) "success")
                      :id (str table-id "-selected")}
-                [:td id [:a {:id (str "row-" id)}]] [:td lead-organisations] [:td name] [:td created-at]]))]])))))
+                [:td name]
+                [:td lead-organisations]
+                [:td id]
+                [:td created-at]]))]])))))

 (defn programmes-div [data owner]
   (reify


Fix parser trace test

Fix parser trace test

--- test/com/wsscode/pathom/parser_test.clj
+++ test/com/wsscode/pathom/parser_test.clj
@@ -106,9 +106,14 @@
             {:com.wsscode.pathom.core/path   []
              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
              :key                            :a}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
             {:com.wsscode.pathom.core/path   []
              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/value-return
              :key                            :a}
@@ -122,30 +127,72 @@
                   [:a :b]))
            {:a 1 :b 2}))
     (is (= (comparable-trace @trace)
-           [{:com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop
-             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
-             :com.wsscode.pathom.core/path       []}
-            {:key :a :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key :com.wsscode.pathom.core/path []}
-            {:key :a :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read :com.wsscode.pathom.core/path []}
-            {:com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/provided-return
-             :com.wsscode.pathom.parser/provides #{:b :a}
-             :com.wsscode.pathom.core/path       []}
-            {:key :b :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key :com.wsscode.pathom.core/path []}
-            {:key :b :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/skip-wait-key :com.wsscode.pathom.core/path []}
-            {:com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending
-             :com.wsscode.pathom.parser/provides       #{:b :a}
-             :com.wsscode.pathom.parser/merge-result?  false
-             :com.wsscode.pathom.core/path             []
-             :com.wsscode.pathom.parser/response-value {:a 1 :b 2}}
-            {:key :b :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key :com.wsscode.pathom.core/path []}
-            {:key :b :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read :com.wsscode.pathom.core/path []}
-            {:key :b :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/value-return :com.wsscode.pathom.core/path []}
-            {:key :a :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key :com.wsscode.pathom.core/path []}
-            {:key :a :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read :com.wsscode.pathom.core/path []}
-            {:key :a :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/value-return :com.wsscode.pathom.core/path []}
-            {:com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop
-             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
-             :com.wsscode.pathom.core/path       []}])))
+           [{:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.parser/provides #{:a
+                                                   :b}
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/provided-return}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+             :key                            :b}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/skip-wait-key
+             :key                            :b}
+            {:com.wsscode.pathom.core/path             []
+             :com.wsscode.pathom.parser/merge-result?  false
+             :com.wsscode.pathom.parser/provides       #{:a
+                                                         :b}
+             :com.wsscode.pathom.parser/response-value {:a 1
+                                                        :b 2}
+             :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
+            {:com.wsscode.pathom.core/path        []
+             :com.wsscode.pathom.parser/loop-keys [:b
+                                                   :a]
+             :com.wsscode.pathom.trace/event      :com.wsscode.pathom.parser/reset-loop}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+             :key                            :b}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :b}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :b}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/value-return
+             :key                            :b}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/value-return
+             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}])))

   (testing "async return"
     (reset! trace [])
@@ -159,9 +206,14 @@
             {:com.wsscode.pathom.core/path   []
              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
              :key                            :a}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
             {:com.wsscode.pathom.core/path   []
              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/async-return
              :key                            :a}
@@ -170,6 +222,9 @@
              :com.wsscode.pathom.parser/provides       #{:a}
              :com.wsscode.pathom.parser/response-value {:a :done}
              :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
+            {:com.wsscode.pathom.core/path             []
+             :com.wsscode.pathom.parser/response-value {:a :done}
+             :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/merge-result}
             {:com.wsscode.pathom.core/path       []
              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}])))
@@ -186,9 +241,14 @@
             {:com.wsscode.pathom.core/path   []
              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
              :key                            :a}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
             {:com.wsscode.pathom.core/path   []
              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/value-return
              :key                            :a}
@@ -208,20 +268,28 @@
                   [:b :c]))
            {:b 2 :c 12}))
     (is (= (comparable-trace-in-any-order @trace)
-           '{{:com.wsscode.pathom.core/path             [:c]
+           '{{:com.wsscode.pathom.core/path        [:c]
+              :com.wsscode.pathom.parser/loop-keys [:b]
+              :com.wsscode.pathom.trace/event      :com.wsscode.pathom.parser/reset-loop}           1
+             {:com.wsscode.pathom.core/path             [:c]
               :com.wsscode.pathom.parser/merge-result?  false
               :com.wsscode.pathom.parser/provides       #{:b}
               :com.wsscode.pathom.parser/response-value nil
               :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending} 1
              {:com.wsscode.pathom.core/path       [:c]
               :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+              :key                                :b}                                               1
+             {:com.wsscode.pathom.core/path       [:c]
+              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
               :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}            1
              {:com.wsscode.pathom.core/path       [:c]
               :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+              :key                                :b}                                               1
+             {:com.wsscode.pathom.core/path       [:c]
+              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
               :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}            1
-             {:com.wsscode.pathom.core/path   [:c]
-              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-              :key                            :b}                                                   1
              {:com.wsscode.pathom.core/path   [:c]
               :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/external-wait-key
               :key                            :b}                                                   1
@@ -231,6 +299,9 @@
              {:com.wsscode.pathom.core/path   [:c]
               :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/value-return
               :key                            :b}                                                   1
+             {:com.wsscode.pathom.core/path        []
+              :com.wsscode.pathom.parser/loop-keys [:b]
+              :com.wsscode.pathom.trace/event      :com.wsscode.pathom.parser/reset-loop}           1
              {:com.wsscode.pathom.core/path             []
               :com.wsscode.pathom.parser/merge-result?  false
               :com.wsscode.pathom.parser/provides       #{:a
@@ -247,24 +318,37 @@
               :com.wsscode.pathom.parser/provides #{:a
                                                     :b}
               :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/provided-return}       1
+             {:com.wsscode.pathom.core/path             []
+              :com.wsscode.pathom.parser/response-value {:c 12}
+              :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/merge-result}    1
              {:com.wsscode.pathom.core/path            []
               :com.wsscode.pathom.parser/watcher-count 1
               :com.wsscode.pathom.trace/event          :com.wsscode.pathom.parser/flush-watchers
               :key                                     :b}                                          1
              {:com.wsscode.pathom.core/path       []
               :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+              :key                                :b}                                               2
+             {:com.wsscode.pathom.core/path       []
+              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+              :key                                :c}                                               1
+             {:com.wsscode.pathom.core/path       []
+              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
               :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}            1
+             {:com.wsscode.pathom.core/path       []
+              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+              :key                                :b}                                               2
+             {:com.wsscode.pathom.core/path       []
+              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+              :key                                :c}                                               1
              {:com.wsscode.pathom.core/path       []
               :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
               :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}            1
              {:com.wsscode.pathom.core/path   []
               :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/async-return
-              :key                            :c}                                                   1
-             {:com.wsscode.pathom.core/path   []
-              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-              :key                            :b}                                                   2
-             {:com.wsscode.pathom.core/path   []
-              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
               :key                            :c}                                                   1
              {:com.wsscode.pathom.core/path   []
               :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
@@ -288,9 +372,14 @@
             {:com.wsscode.pathom.core/path   []
              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
              :key                            :a}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
             {:com.wsscode.pathom.core/path       []
              :com.wsscode.pathom.parser/provides #{:a}
              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/provided-return}
@@ -299,12 +388,20 @@
              :com.wsscode.pathom.parser/provides       #{:a}
              :com.wsscode.pathom.parser/response-value {}
              :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
-             :key                            :a}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-             :key                            :a}
+            {:com.wsscode.pathom.core/path        []
+             :com.wsscode.pathom.parser/loop-keys [:a]
+             :com.wsscode.pathom.trace/event      :com.wsscode.pathom.parser/reset-loop}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
             {:com.wsscode.pathom.core/path       []
              :com.wsscode.pathom.parser/provides #{:a}
              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/provided-return}
@@ -313,12 +410,20 @@
              :com.wsscode.pathom.parser/provides       #{:a}
              :com.wsscode.pathom.parser/response-value {}
              :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
-             :key                            :a}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-             :key                            :a}
+            {:com.wsscode.pathom.core/path        []
+             :com.wsscode.pathom.parser/loop-keys [:a]
+             :com.wsscode.pathom.trace/event      :com.wsscode.pathom.parser/reset-loop}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
             {:com.wsscode.pathom.core/path       []
              :com.wsscode.pathom.parser/provides #{:a}
              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/provided-return}
@@ -327,12 +432,20 @@
              :com.wsscode.pathom.parser/provides       #{:a}
              :com.wsscode.pathom.parser/response-value {}
              :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
-             :key                            :a}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-             :key                            :a}
+            {:com.wsscode.pathom.core/path        []
+             :com.wsscode.pathom.parser/loop-keys [:a]
+             :com.wsscode.pathom.trace/event      :com.wsscode.pathom.parser/reset-loop}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
             {:com.wsscode.pathom.core/path       []
              :com.wsscode.pathom.parser/provides #{:a}
              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/provided-return}
@@ -341,12 +454,20 @@
              :com.wsscode.pathom.parser/provides       #{:a}
              :com.wsscode.pathom.parser/response-value {}
              :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
-             :key                            :a}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-             :key                            :a}
+            {:com.wsscode.pathom.core/path        []
+             :com.wsscode.pathom.parser/loop-keys [:a]
+             :com.wsscode.pathom.trace/event      :com.wsscode.pathom.parser/reset-loop}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+             :key                            :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/call-read
+             :key                                :a}
             {:com.wsscode.pathom.core/path       []
              :com.wsscode.pathom.parser/provides #{:a}
              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/provided-return}
@@ -355,6 +476,9 @@
              :com.wsscode.pathom.parser/provides       #{:a}
              :com.wsscode.pathom.parser/response-value {}
              :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
+            {:com.wsscode.pathom.core/path        []
+             :com.wsscode.pathom.parser/loop-keys [:a]
+             :com.wsscode.pathom.trace/event      :com.wsscode.pathom.parser/reset-loop}
             {:com.wsscode.pathom.core/path   []
              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
              :key                            :a}


Update calcs to handle flagged as disagreement

--- src/clj/collect_earth_online/db/plots.clj
+++ src/clj/collect_earth_online/db/plots.clj
@@ -80,11 +80,11 @@
        users-samples))

 (defn- sample-disagreement [& answers]
-  (let [mode-count (->> answers
-                        (frequencies)
-                        (filterm (fn [[k _]] (some? k)))
-                        (vals)
-                        (apply max))]
+  (let [mode-count (as-> answers %
+                     (frequencies %)
+                     (assoc % nil 1)
+                     (vals %)
+                     (apply max %))]
     (if (= 1 mode-count)
       100.0
       (->> (/ mode-count
@@ -93,13 +93,9 @@
            (* 100.0)))))

 (defn- question-disagreement [sample-answers]
-  (if (< 1 (->> sample-answers
-                (remove #(every? nil? %))
-                (count)))
-    (average (apply map
-                    sample-disagreement
-                    sample-answers))
-    -1))
+  (->> sample-answers
+       (apply map sample-disagreement)
+       (average)))

 (defn- filter-plot-disagreement [project-id grouped-plots threshold]
   (let [survey-questions (get-survey-questions project-id)]


Failsafe when *print-length* is out of our control

refs #120

--- src/clj/reply/reader/jline/completion.clj
+++ src/clj/reply/reader/jline/completion.clj
@@ -23,6 +23,6 @@
             (if (empty? possible-completions)
               -1
               (do
-                (.addAll candidates possible-completions)
+                (.addAll candidates (map str possible-completions))
                 (redraw-line-fn)
                 (- cursor prefix-length)))))))))


Added buffering to publication

Added buffering to publication

--- src/clj/salava/core/components/pubsub.clj
+++ src/clj/salava/core/components/pubsub.clj
@@ -1,7 +1,7 @@
 (ns salava.core.components.pubsub
   (:require [clojure.tools.logging :as log]
             [com.stuartsierra.component :as component]
-            [clojure.core.async :refer [chan pub sub go-loop <! close! unsub-all]]
+            [clojure.core.async :refer [chan pub sub go-loop <! close! unsub-all buffer]]
             [salava.core.util :as u]))

 (defn- sub-loop [our-pub]
@@ -27,7 +27,7 @@

   (start [this]
     (let [input-chan (chan)
-          our-pub  (pub input-chan :topic)
+          our-pub (pub input-chan :topic (fn [_] (buffer 100)))
           context {:config     (:config config)
                    :db         (:datasource db)
                    :input-chan input-chan}]


Put data inside no script tags

Put data inside no script tags

--- src/cljs/gtfve/components/maps_panel.cljs
+++ src/cljs/gtfve/components/maps_panel.cljs
@@ -77,7 +77,7 @@
         (put! kill-ch (js/Date.))))
     om/IRender
     (render [_]
-      (html [:noscript]))))
+      (html [:noscript (pr-str data)]))))

 (defn maps-canvas [{:keys [ui data]} owner]
   (reify


Set AJAX error handler.

Set AJAX error handler.

--- src/cljs/hatnik/web/client/z_actions.cljs
+++ src/cljs/hatnik/web/client/z_actions.cljs
@@ -21,6 +21,7 @@
             :contentType "application/json"
             :dataType "json"
             :async true
+            :error #(msg/danger "Invalid request! Check out your request data!")
             :success callback}))

 (defn get-github-repos [github-name callback error-handler]


Update color on mouse leave

Update color on mouse leave

--- src/cljs/koeeoadi/components/palette.cljs
+++ src/cljs/koeeoadi/components/palette.cljs
@@ -163,9 +163,9 @@
     (let [{:keys [palette-widget/closure-comp
                   palette-widget/active-color] :as props} (om/props this)]

-      (dom/div #js {:onMouseUp #(color-update this)
+      (dom/div #js {:onMouseUp    #(color-update this)
+                    :onMouseLeave #(color-update this)
                     :id  "palette-widget"
-                    ;;:onTouchEnd #(color-update this active-color closure-comp)
                     :ref "paletteWidget"} nil))))

 (def palette-widget (om/factory PaletteWidget))


more mea culpa failures

more mea culpa failures

--- scheduler/src/cook/mesos/schema.clj
+++ scheduler/src/cook/mesos/schema.clj
@@ -1026,7 +1026,7 @@
     :reason/code 3001
     :reason/string "Invalid Mesos framework id"
     :reason/name :mesos-invalid-framework-id
-    :reason/mea-culpa? false
+    :reason/mea-culpa? true
     :reason/mesos-reason :reason-invalid-frameworkid}
    {:db/id (d/tempid :db.part/user)
     :reason/code 3002
@@ -1099,13 +1099,13 @@
     :reason/code 4005
     :reason/string "Agent disconnected"
     :reason/name :mesos-slave-disconnected
-    :reason/mea-culpa? false
+    :reason/mea-culpa? true
     :reason/mesos-reason :reason-slave-disconnected}
    {:db/id (d/tempid :db.part/user)
     :reason/code 4006
     :reason/string "Unable to contact agent"
     :reason/name :heartbeat-lost
-    :reason/mea-culpa? false}
+    :reason/mea-culpa? true}

    {:db/id (d/tempid :db.part/user)
     :reason/code 5000


check db when using next-id instead of when generating it

--- src-cljs/frontend/db.cljs
+++ src-cljs/frontend/db.cljs
@@ -43,11 +43,12 @@
    ids (probably due to an error).
    Returns a map of :entity-id and new :frontend-id-state"
   [db {:keys [multiple remainder next-id] :as frontend-id-state}]
-  {:entity-id next-id
-   :frontend-id-state (assoc frontend-id-state :next-id (loop [res (+ next-id multiple)]
-                                                          (if (first (d/datoms db :eavt res))
-                                                            (recur (+ res multiple))
-                                                            res)))})
+  (let [eid (loop [res next-id]
+              (if (first (d/datoms db :eavt res))
+                (recur (+ res multiple))
+                res))]
+    {:entity-id eid
+     :frontend-id-state (assoc frontend-id-state :next-id (+ eid multiple))}))

 (defn generate-entity-ids
   "Same as generate-entity-id, but returns a list of :entity-ids"


add test cases for bam indexing

add test cases for bam indexing

--- test/cljam/t_bam.clj
+++ test/cljam/t_bam.clj
@@ -1,8 +1,10 @@
 (ns cljam.t-bam
   (:use midje.sweet
         cljam.t-common)
-  (:require [cljam.bam :as bam]
-            [cljam.io :as io]))
+  (:require [clojure.java.io :refer [copy file]]
+            [cljam.bam :as bam]
+            [cljam.io :as io]
+            [cljam.bam-indexer :as bai]))

 (fact "about slurp-bam"
       (with-open [r (bam/reader test-bam-file)]
@@ -10,7 +12,7 @@
          :alignments (doall (io/read-alignments r {}))}) => test-sam)

 (with-state-changes [(before :facts (prepare-cache!))
-                     (after  :facts (clean-cache!))]
+                     (after :facts (clean-cache!))]
   (fact "about spit-bam"
     (let [temp-file (str temp-dir "/test.bam")]
      (bam/spit temp-file test-sam) => nil?
@@ -20,8 +22,17 @@

 (with-state-changes [(before :facts (do (prepare-cache!)
                                         (bam/spit (str temp-dir "/test.bam") test-sam)))
-                     (after  :facts (clean-cache!))]
+                     (after :facts (clean-cache!))]
   (fact "about BAMReader"
         (let [temp-file (str temp-dir "/test.bam")
               rdr (bam/reader temp-file)]
           (io/read-refs rdr) => test-sam-refs)))
+
+(with-state-changes [(before :facts (do (prepare-cache!)
+                                        (copy (file test-sorted-bam-file) (file (str temp-dir "/test.sorted.bam")))))
+                     (after :facts (clean-cache!))]
+  (fact "about BAM indexer"
+        (let [f (str temp-dir "/test.sorted.bam")]
+          (bai/create-index f (str f ".bai"))) => nil
+        (with-open [r (bam/reader (str temp-dir "/test.sorted.bam"))]
+          (io/read-alignments r {:chr "ref" :start 0 :end 1000})) => (filter #(= "ref" (:rname %)) (:alignments test-sam-sorted-by-pos))))


Got refresh-prices working and changed arity of add-price\!

--- src/hackerati_interval_web_app/schema.clj
+++ src/hackerati_interval_web_app/schema.clj
@@ -44,7 +44,7 @@
     (insert tracked-links (values {:userid userid :productid productid}))))

 (defn add-price!
-  ([productid price]
+  ([{productid :productid price :price}]
      (add-price! productid (java.util.Date.) price))
   ([productid date price]
      (try
@@ -88,17 +88,16 @@
        first
        :password))

-;; IN PROGRESS
-;; Currently returns e.g. {1 $18.44}
-;; Need to return {:productid 1 :price $18.44}
+;; TODO refactor
 (defn refresh-prices []
   (let [products (select products)
         ids (map :productid products)
         urls (map :url products)
         ps (scrape/get-price-from-urls urls)
-        m (map hash-map ids ps)]
-    (insert prices
-            (values m))))
+        m (reduce #(conj %1 (assoc {} :productid (first %2) :price (second %2)))  [] (partition 2 (interleave ids ps)))]
+;; TODO optimize by including all values within one insert statement, instead of mapping across the bunch
+;; Although, one advantage of doing it this way is that one error doesn't ruin the whole insertion.
+    (map add-price! m)))

 (defn user-exists? [username]
   (seq (select users (where {:username username}))))


day 9 bleat'

day 9 bleat'

--- src/adventofcode/day9.clj
+++ src/adventofcode/day9.clj
@@ -1,7 +1,6 @@
 (ns adventofcode.day9
   (:require [clojure.java.io :as io]
-            [clojure.string :as str]
-            [clojure.set :as set]))
+            [clojure.string :as str]))

 (def distances (->> "day9.txt"
                     io/resource
@@ -9,50 +8,43 @@
                     slurp
                     str/split-lines
                     (reduce #(let [[_ from to dist] (re-find #"(\w+) to (\w+) = (\d+)" %2)]
-                               (assoc-in %1 [from to] (read-string dist)))
+                               (-> %1
+                                   (assoc-in [from to] (read-string dist))
+                                   (assoc-in [to from] (read-string dist))))
                             {})))

-#_(def distances {:london {:dublin 464
-                           :belfast 518}
-                  :dublin {:belfast 141}})
-
-(def all-cities
-  (set/union
-   (->> distances keys (into #{}))
-   (->> distances
-        (map #(-> % second keys))
-        (reduce #(into %1 %2) #{}))))
-
-(defn next-destination [curr unvisited]
+(defn destination-by [criteria curr unvisited]
   (when-not (dead-end? curr unvisited)
     (->> (select-keys (get distances curr) unvisited)
-         (apply min-key second))))
+         (apply criteria second))))

 (defn dead-end? [curr unvisited]
   (or (not (contains? distances curr))
       (empty? (select-keys (get distances curr) unvisited))))

-(defn shortest-distance [from]
+(defn distance-by [criteria from]
   (loop [distance 0
          curr from
-         unvisited (disj all-cities from)
-         path (conj [] from)]
+         unvisited (disj (into #{} (keys distances)) from)]
     (if (empty? unvisited)
       distance
-      (if-let [[city dist] (next-destination curr unvisited)]
+      (if-let [[city dist] (destination-by criteria curr unvisited)]
         (recur (+ distance dist)
                city
-               (disj unvisited city)
-               (conj path city))
-        {:dead-end path}))))
+               (disj unvisited city))
+        :dead-end))))
+
+(def shortest (partial distance-by min-key))
+(def longest (partial distance-by max-key))

 (defn part-one []
   (->> (keys distances)
-       (map shortest-distance)
-       #_(filter #(not= :dead-end %))
-       #_(apply min)))
+       (map shortest)
+       (filter #(not= :dead-end %))
+       (apply min)))

-(comment
-  (part-one)
-  (clojure.pprint/pprint all-cities)
-  (clojure.pprint/pprint distances))
+(defn part-two []
+  (->> (keys distances)
+       (map longest)
+       (filter #(not= :dead-end %))
+       (apply max)))


[#2309] Double spec

[#2309] Double spec


hide-thread (per user) instead of close-thread

--- src/chat/client/core.cljs
+++ src/chat/client/core.cljs
@@ -17,10 +17,11 @@
   (reset! app-state
           {:session {:user-id 1}
            :users {1 {:id 1
-                      :icon "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2015-05-08/4801271456_41230ac0b881cdf85c28_72.jpg" }
+                      :icon "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2015-05-08/4801271456_41230ac0b881cdf85c28_72.jpg"
+                      :hidden-thread-ids []}
                    2 {:id 2
-                      :icon "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2015-05-09/4805955000_07dc272f0a7f9de7719e_192.jpg"}}
-           :threads {123 {:id 123}}
+                      :icon "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2015-05-09/4805955000_07dc272f0a7f9de7719e_192.jpg"
+                      :hidden-thread-ids []}}
            :messages {99 {:id 99 :content "Hello?" :thread-id 123 :user-id 1 :created-at (js/Date. 1)}
                       98 {:id 98 :content "Hi!" :thread-id 123 :user-id 2 :created-at (js/Date. 2)}
                       97 {:id 97 :content "Oh, great, someone else is here." :thread-id 123 :user-id 1 :created-at (js/Date. 3)}
@@ -36,8 +37,8 @@
                                          :user-id (get-in @app-state [:session :user-id])
                                          :created-at (js/Date.)}))))

-(defmethod dispatch! :close-thread [_ data]
-  (transact! [:threads (data :thread-id)] #(assoc % :closed true)))
+(defmethod dispatch! :hide-thread [_ data]
+  (transact! [:users (get-in @app-state [:session :user-id]) :hidden-thread-ids] #(conj % (data :thread-id))))

 (defn message-view [message owner]
   (reify
@@ -67,7 +68,7 @@
       (dom/div #js {:className "thread"}
         (dom/div #js {:className "close"
                       :onClick (fn [_]
-                                 (dispatch! :close-thread {:thread-id (thread :id)}))} "×")
+                                 (dispatch! :hide-thread {:thread-id (thread :id)}))} "×")
         (apply dom/div #js {:className "messages"}
           (om/build-all message-view (thread :messages)))
         (om/build new-message-view {:thread-id (thread :id) :placeholder "Reply..."})))))
@@ -83,16 +84,15 @@
   (reify
     om/IRender
     (render [_]
-      (let [threads (->> (data :messages)
+      (let [remove-keys (fn [ks coll]
+                          (apply dissoc coll ks))
+            threads (->> (data :messages)
                          vals
                          (sort-by :created-at)
                          (group-by :thread-id)
-                         (map (fn [[id ms]] [id {:id id
-                                                 :messages ms}]))
-                         (into {})
-                         (merge-with merge (data :threads))
-                         vals
-                         (remove (comp true? :closed)))]
+                         (remove-keys (get-in data [:users (get-in data [:session :user-id]) :hidden-thread-ids]))
+                         (map (fn [[id ms]] {:id id
+                                             :messages ms})))]
         (dom/div nil
           (apply dom/div nil
             (concat (om/build-all thread-view threads)


fix setting empty movable dests

fix setting empty movable dests

--- src/chessground/data.cljs
+++ src/chessground/data.cljs
@@ -134,7 +134,9 @@
     nil))

 (defn set-config [state raw-config]
-  (let [config (update-in raw-config [:movable :dests] common/stringify-keys)]
+  (let [config (if (get-in raw-config [:movable :dests])
+                 (update-in raw-config [:movable :dests] common/stringify-keys)
+                 raw-config)]
     (reduce (fn [st [cfg k f]]
               (if (contains? cfg k)
                 (f st (get cfg k))


CLJS-409: Extract emit-provide function

CLJS-409: Extract emit-provide function

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -129,6 +129,11 @@

 (defn ^String emit-str [expr]
   (with-out-str (emit-top-level expr)))
+
+(defn emit-provide [sym]
+  (when-not (or (nil? *emitted-provides*) (contains? @*emitted-provides* sym))
+    (swap! *emitted-provides* conj sym)
+    (emitln "goog.provide('" (munge sym) "');")))

 (defmulti emit-constant class)
 (defmethod emit-constant nil [x] (emits "null"))
@@ -682,10 +687,7 @@
 (defmethod emit :deftype*
   [{:keys [t fields pmasks]}]
   (let [fields (map munge fields)]
-    (when-not (or (nil? *emitted-provides*) (contains? @*emitted-provides* t))
-      (swap! *emitted-provides* conj t)
-      (emitln "")
-      (emitln "goog.provide('" (munge t) "');"))
+    (emit-provide t)
     (emitln "")
     (emitln "/**")
     (emitln "* @constructor")
@@ -700,10 +702,7 @@
 (defmethod emit :defrecord*
   [{:keys [t fields pmasks]}]
   (let [fields (concat (map munge fields) '[__meta __extmap])]
-    (when-not (or (nil? *emitted-provides*) (contains? @*emitted-provides* t))
-      (swap! *emitted-provides* conj t)
-      (emitln "")
-      (emitln "goog.provide('" (munge t) "');"))
+    (emit-provide t)
     (emitln "")
     (emitln "/**")
     (emitln "* @constructor")


Remove old map tx data

Remove old map tx data

--- src/clj/zetawar/data.cljs
+++ src/clj/zetawar/data.cljs
@@ -107,459 +107,6 @@
     :terrain-effect/movement-cost 3}
    ])

-(def maps
-  {:sterlings-aruba
-   [;; Map
-
-    {:db/id -101
-     :map/id :sterlings-aruba
-     :map/name "Sterling's Aruba"
-     :map/initial-credits 300
-     :map/credits-per-base 100
-     :game/_map :game}
-
-    ;; Terrains
-
-    ;; Row 1
-    {:db/id -201
-     :terrain/q 1
-     :terrain/r 0
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -202
-     :terrain/q 2
-     :terrain/r 0
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -203
-     :terrain/q 3
-     :terrain/r 0
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -204
-     :terrain/q 4
-     :terrain/r 0
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -205
-     :terrain/q 5
-     :terrain/r 0
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -206
-     :terrain/q 6
-     :terrain/r 0
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    ;; Row 2
-    {:db/id -207
-     :terrain/q 0
-     :terrain/r 1
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -208
-     :terrain/q 1
-     :terrain/r 1
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -209
-     :terrain/q 2
-     :terrain/r 1
-     :terrain/type [:terrain-type/id :terrain-type.id/base]
-     :map/_terrains -101}
-    {:db/id -210
-     :terrain/q 3
-     :terrain/r 1
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -211
-     :terrain/q 4
-     :terrain/r 1
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -212
-     :terrain/q 5
-     :terrain/r 1
-     :terrain/type [:terrain-type/id :terrain-type.id/woods]
-     :map/_terrains -101}
-    {:db/id -213
-     :terrain/q 6
-     :terrain/r 1
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -214
-     :terrain/q 7
-     :terrain/r 1
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    ;; Row 3
-    {:db/id -215
-     :terrain/q 0
-     :terrain/r 2
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -216
-     :terrain/q 1
-     :terrain/r 2
-     :terrain/type [:terrain-type/id :terrain-type.id/base]
-     :map/_terrains -101}
-    {:db/id -218
-     :terrain/q 2
-     :terrain/r 2
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -219
-     :terrain/q 3
-     :terrain/r 2
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -220
-     :terrain/q 4
-     :terrain/r 2
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -221
-     :terrain/q 5
-     :terrain/r 2
-     :terrain/type [:terrain-type/id :terrain-type.id/woods]
-     :map/_terrains -101}
-    {:db/id -222
-     :terrain/q 6
-     :terrain/r 2
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -223
-     :terrain/q 7
-     :terrain/r 2
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -224
-     :terrain/q 8
-     :terrain/r 2
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    ;; Row 4
-    {:db/id -225
-     :terrain/q 0
-     :terrain/r 3
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -226
-     :terrain/q 1
-     :terrain/r 3
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -228
-     :terrain/q 2
-     :terrain/r 3
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -229
-     :terrain/q 3
-     :terrain/r 3
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -230
-     :terrain/q 4
-     :terrain/r 3
-     :terrain/type [:terrain-type/id :terrain-type.id/woods]
-     :map/_terrains -101}
-    {:db/id -231
-     :terrain/q 5
-     :terrain/r 3
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -232
-     :terrain/q 6
-     :terrain/r 3
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -233
-     :terrain/q 7
-     :terrain/r 3
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -234
-     :terrain/q 8
-     :terrain/r 3
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    ;; Row 5
-    {:db/id -235
-     :terrain/q 0
-     :terrain/r 4
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -236
-     :terrain/q 1
-     :terrain/r 4
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -238
-     :terrain/q 2
-     :terrain/r 4
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -239
-     :terrain/q 3
-     :terrain/r 4
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -240
-     :terrain/q 4
-     :terrain/r 4
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -241
-     :terrain/q 5
-     :terrain/r 4
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -242
-     :terrain/q 6
-     :terrain/r 4
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -243
-     :terrain/q 7
-     :terrain/r 4
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -244
-     :terrain/q 8
-     :terrain/r 4
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    ;; Row 6
-    {:db/id -245
-     :terrain/q 0
-     :terrain/r 5
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -246
-     :terrain/q 1
-     :terrain/r 5
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -248
-     :terrain/q 2
-     :terrain/r 5
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -249
-     :terrain/q 3
-     :terrain/r 5
-     :terrain/type [:terrain-type/id :terrain-type.id/woods]
-     :map/_terrains -101}
-    {:db/id -250
-     :terrain/q 4
-     :terrain/r 5
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -251
-     :terrain/q 5
-     :terrain/r 5
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -252
-     :terrain/q 6
-     :terrain/r 5
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -253
-     :terrain/q 7
-     :terrain/r 5
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -254
-     :terrain/q 8
-     :terrain/r 5
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    ;; Row 7
-    {:db/id -255
-     :terrain/q 0
-     :terrain/r 6
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -256
-     :terrain/q 1
-     :terrain/r 6
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -258
-     :terrain/q 2
-     :terrain/r 6
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -259
-     :terrain/q 3
-     :terrain/r 6
-     :terrain/type [:terrain-type/id :terrain-type.id/woods]
-     :map/_terrains -101}
-    {:db/id -260
-     :terrain/q 4
-     :terrain/r 6
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -261
-     :terrain/q 5
-     :terrain/r 6
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -262
-     :terrain/q 6
-     :terrain/r 6
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -263
-     :terrain/q 7
-     :terrain/r 6
-     :terrain/type [:terrain-type/id :terrain-type.id/base]
-     :map/_terrains -101}
-    {:db/id -264
-     :terrain/q 8
-     :terrain/r 6
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    ;; Row 8
-    {:db/id -265
-     :terrain/q 0
-     :terrain/r 7
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -266
-     :terrain/q 1
-     :terrain/r 7
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -268
-     :terrain/q 2
-     :terrain/r 7
-     :terrain/type [:terrain-type/id :terrain-type.id/woods]
-     :map/_terrains -101}
-    {:db/id -269
-     :terrain/q 3
-     :terrain/r 7
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -270
-     :terrain/q 4
-     :terrain/r 7
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -271
-     :terrain/q 5
-     :terrain/r 7
-     :terrain/type [:terrain-type/id :terrain-type.id/base]
-     :map/_terrains -101}
-    {:db/id -272
-     :terrain/q 6
-     :terrain/r 7
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -273
-     :terrain/q 7
-     :terrain/r 7
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    ;; Row 9
-    {:db/id -274
-     :terrain/q 1
-     :terrain/r 8
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -275
-     :terrain/q 2
-     :terrain/r 8
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -276
-     :terrain/q 3
-     :terrain/r 8
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -277
-     :terrain/q 4
-     :terrain/r 8
-     :terrain/type [:terrain-type/id :terrain-type.id/deep-water]
-     :map/_terrains -101}
-    {:db/id -278
-     :terrain/q 5
-     :terrain/r 8
-     :terrain/type [:terrain-type/id :terrain-type.id/mountains]
-     :map/_terrains -101}
-    {:db/id -279
-     :terrain/q 6
-     :terrain/r 8
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-    {:db/id -280
-     :terrain/q 7
-     :terrain/r 8
-     :terrain/type [:terrain-type/id :terrain-type.id/plains]
-     :map/_terrains -101}
-
-    ;; Factions
-
-    {:db/id -301
-     :faction/color :faction.color/blue
-     :faction/order 1
-     :faction/credits 300
-     :faction/ai false
-     :map/_starting-faction -101
-     :game/_factions :game
-     :game/_current-faction :game
-     :terrain/_owner -216}
-
-    {:db/id -302
-     :faction/color :faction.color/red
-     :faction/order 2
-     :faction/credits 300
-     :faction/ai true
-     :game/_factions :game
-     :terrain/_owner -263
-     :faction/_next-faction -301
-     :faction/next-faction -301}
-
-    ;; Units
-
-    {:db/id -401
-     :unit/q 2
-     :unit/r 2
-     :unit/type [:unit-type/id :unit-type.id/infantry]
-     :unit/count 10
-     :unit/round-built 0
-     :unit/move-count 0
-     :unit/attack-count 0
-     :unit/repaired false
-     :unit/capturing false
-     :faction/_units -301}
-
-    {:db/id -402
-     :unit/q 7
-     :unit/r 7
-     :unit/type [:unit-type/id :unit-type.id/infantry]
-     :unit/count 10
-     :unit/round-built 0
-     :unit/move-count 0
-     :unit/attack-count 0
-     :unit/repaired false
-     :unit/capturing false
-     :faction/_units -302}
-
-    {:db/id -403
-     :unit/q 7
-     :unit/r 8
-     :unit/type [:unit-type/id :unit-type.id/infantry]
-     :unit/count 10
-     :unit/round-built 0
-     :unit/move-count 0
-     :unit/attack-count 0
-     :unit/capturing false
-     :unit/repaired false
-     :faction/_units -302}]
-    })

 (def map-definitions
   {:sterlings-aruba


Naming consistency, :p -> :ps, :q -> :qs, :r -> :rs

--- src/cljs/fatlip/core.cljs
+++ src/cljs/fatlip/core.cljs
@@ -50,8 +50,8 @@
         g (-> graph
               (update-in [:layers p-layer-id :nodes] conj p-node)
               (update-in [:layers q-layer-id :nodes] conj q-node)
-              (update-in [:p] conj p-node)
-              (update-in [:q] conj q-node)
+              (update-in [:ps] conj p-node)
+              (update-in [:qs] conj q-node)
               (add-edge last-node p-node characters)
               (add-edge p-node q-node characters))]
     [g q-node]))
@@ -65,7 +65,7 @@
         r-node (make-node graph r-layer-id {:characters characters})
         g (-> graph
               (update-in [:layers r-layer-id :nodes] conj r-node)
-              (update-in [:r] conj r-node)
+              (update-in [:rs] conj r-node)
               (add-edge last-node r-node characters))]
     [g r-node]))

@@ -152,9 +152,9 @@
                         {:layers []
                          :succs {}
                          :preds {}
-                         :p #{}
-                         :q #{}
-                         :r #{}
+                         :ps #{}
+                         :qs #{}
+                         :rs #{}
                          :marked #{}
                          :last-nodes-by-character {}
                          :last-nodes-by-node {}}))
@@ -176,7 +176,7 @@
   "Step 1 of ESK - replace all p nodes with edges and merge segment containers"
   [graph layer]
   (->> (:ordered layer)
-       (map #(if (contains? (:p graph) %)
+       (map #(if (contains? (:ps graph) %)
                ;; p nodes always have only one successor
                [(-> (:succs graph) (get %) first)]
                %))
@@ -213,7 +213,7 @@
 (defn- set-qs-non-qs
   "ESK requires a layer's nodes to be split into lists of q-nodes and non-q-nodes"
   [graph layer]
-  (->> ((juxt filter remove) #(contains? (:q graph) %) (:nodes layer))
+  (->> ((juxt filter remove) #(contains? (:qs graph) %) (:nodes layer))
        (map set)
        (interleave [:qs :non-qs])
        (apply (partial assoc layer))))
@@ -534,8 +534,8 @@
   (assoc graph
     :succs (:preds graph)
     :preds (:succs graph)
-    :p (:q graph)
-    :q (:p graph)
+    :ps (:qs graph)
+    :qs (:ps graph)
     :layers (vec (rseq (:layers graph)))))


cleanup network

cleanup network

--- src/cljs/mpd/network.cljs
+++ src/cljs/mpd/network.cljs
@@ -6,9 +6,9 @@

 (def websocket (js/WebSocket. "ws://localhost:8192"))

-(def lastFramePlayer nil)
+(def lastFramePlayer (atom nil))

-(def inbox [])
+(def inbox (atom []))

 (defn clj->json
   [ds]
@@ -37,11 +37,11 @@

   (fn [state]
     ; erase inbox queue for now
-    (def inbox [])
+    (reset! inbox [])
     (let [player (:player @state)]
-      (when (not= player lastFramePlayer)
+      (when (not= player @lastFramePlayer)
         (let [json (clj->json player)]
           (send json)
           (log " player data sent to server")))
-      (def lastFramePlayer player))
+      (reset! lastFramePlayer player))
     state))


shorten route handler

shorten route handler

--- src/cljs/server/core.cljs
+++ src/cljs/server/core.cljs
@@ -22,9 +22,7 @@
 ;; github route
 (. app (get "/api/github"
             (fn [req res]
-              (take! (gh/get-activity)
-                     (fn [result]
-                       (.send res (str result)))))))
+              (take! (gh/get-activity) #(.send res (str %1))))))

 ;; bitbucket route
 (. app (get "/api/bitbucket" (fn [req res] (.send res "Hello, World!"))))


Stop stupid react warnings during tests

Stop stupid react warnings during tests

--- spec/cljs/iframe_app/core_test.cljs
+++ spec/cljs/iframe_app/core_test.cljs
@@ -12,6 +12,8 @@
             [iframe-app.core :refer [main app]]))

 (enable-console-print!)
+
+(set! (.-warn js/console) (fn [t] nil))

 ; TODO: use test.check to generate fixtures
 ; TODO: make finders that wait til they find what they're looking for (like Capybara)


Removed experimental stuff from geometry.clj.

--- src/examples/geometry.clj
+++ src/examples/geometry.clj
@@ -3,8 +3,7 @@
 ;; Lee Spector, lspector@hampshire.edu, 2012

 (ns examples.geometry
-  (:use [clojush :exclude [#_mutate #_select pushgp]])
-  (:require [clojure.contrib.string :as string]))
+  (:use [clojush]))

 ;;;;;;;;;;;;
 ;; Multiple geometric formulae. An integer indicates the desired formula and
@@ -57,260 +56,6 @@
     ;4: volume of a sphere: 4/3 pi R^3
     (doall (for [r (range 1 5 0.25)]
              [4 [r 0] (* 4/3 Math/PI r r r)]))))
-
-
-;;; tagging mutation
-
-#_(defn mutate
-  "Returns a mutated version of the given individual."
-  [ind mutation-max-points max-points atom-generators]
-  (let [new-program
-        (if (zero? (rand-int 2))
-          (insert-code-at-point (:program ind)
-                                (select-node-index (:program ind))
-                                (random-code mutation-max-points atom-generators))
-          (let [index (select-node-index (:program ind))]
-            (insert-code-at-point (:program ind)
-                                  index
-                                  (let [tag (lrand-int 1000)] ;; hardcoded limit
-                                        (list (symbol (str "tag_exec_" tag))
-                                              (code-at-point (:program ind) index)
-                                              (symbol (str "tagged_" tag)))))))]
-    (if (> (count-points new-program) max-points)
-      ind
-      (make-individual :program new-program :history (:history ind)
-                       :ancestors (if maintain-ancestors
-                                    (cons (:program ind) (:ancestors ind))
-                                    (:ancestors ind))))))
-
-;;; lexicographic parsimony pressure
-
-#_(defn select
-  "Conducts a tournament and returns the individual with the lower total error."
-  [pop tournament-size radius location]
-  (let [tournament-set
-        (doall
-          (for [_ (range tournament-size)]
-            (nth pop
-              (if (zero? radius)
-                (lrand-int (count pop))
-                (mod (+ location (- (lrand-int (+ 1 (* radius 2))) radius))
-                  (count pop))))))]
-    (reduce (fn [i1 i2] (cond (< (:total-error i1) (:total-error i2)) i1
-                              (< (:total-error i2) (:total-error i1)) i2
-                              (< (count-points (:program i1)) (count-points (:program i2))) i1
-                              :else i2))
-	     tournament-set)))
-
-;;; improve or die (marked ;;IOD)
-
-(defn improved-over ;;IOD
-  [gens population population-size max-points atom-generators error-function]
-  (let [filtered (filter #(or (< (count (:history %)) gens)
-                              (< (first (:history %)) (nth (:history %) (dec gens))))
-                         population)]
-    (if (empty? filtered)
-      (do (println "Regenerating")
-          (doall (map #(evaluate-individual % error-function (java.util.Random. (rand-int 1000000)))
-                      (make-individual
-                        :program (random-code max-points atom-generators)))))
-      (do (println "Number improved:" (count filtered))
-          filtered))))
-
-
-(defn changed-over ;;IOD
-  [gens population population-size max-points atom-generators error-function]
-  (let [filtered (filter #(or (< (count (:history %)) gens)
-                              (not (= (first (:history %)) (nth (:history %) (dec gens)))))
-                         population)]
-    (if (empty? filtered)
-      (do (println "Regenerating")
-          (doall (map #(evaluate-individual % error-function (java.util.Random. (rand-int 1000000)))
-                      (make-individual
-                        :program (random-code max-points atom-generators)))))
-      (do (println "Number improved:" (count filtered))
-          filtered))))
-
-(defn improved-or-significantly-changed-over ;;IOD
-  [gens population population-size max-points atom-generators error-function]
-  (let [filtered (filter #(or (< (count (:history %)) gens)
-                              (< (first (:history %)) (nth (:history %) (dec gens)))
-                              (> (nth (:history %) (dec gens)) (+ 30 (first (:history %)))))
-                         population)]
-    (if (empty? filtered)
-      (do (println "Regenerating")
-          (doall (map #(evaluate-individual % error-function (java.util.Random. (rand-int 1000000)))
-                      (make-individual
-                        :program (random-code max-points atom-generators)))))
-      (do (println "Number improved:" (count filtered))
-          filtered))))
-
-
-(defn pushgp
-  "The top-level routine of pushgp."
-  [& {:keys [error-function error-threshold population-size max-points atom-generators max-generations
-             max-mutations mutation-probability mutation-max-points crossover-probability
-             simplification-probability tournament-size report-simplifications final-report-simplifications
-             reproduction-simplifications trivial-geography-radius decimation-ratio decimation-tournament-size
-             evalpush-limit evalpush-time-limit node-selection-method node-selection-leaf-probability
-             node-selection-tournament-size pop-when-tagging gaussian-mutation-probability
-             gaussian-mutation-per-number-mutation-probability gaussian-mutation-standard-deviation
-             reuse-errors problem-specific-report use-single-thread random-seed
-             use-historically-assessed-hardness]
-      :or {error-function (fn [p] '(0)) ;; pgm -> list of errors (1 per case)
-           error-threshold 0
-           population-size 1000
-           max-points 50
-           atom-generators (concat @registered-instructions
-                                   (list
-                                     (fn [] (lrand-int 100))
-                                     (fn [] (lrand))))
-           max-generations 1001
-           mutation-probability 0.4
-           mutation-max-points 20
-           crossover-probability 0.4
-           simplification-probability 0.1
-           tournament-size 7
-           report-simplifications 100
-           final-report-simplifications 1000
-           reproduction-simplifications 1
-           trivial-geography-radius 0
-           decimation-ratio 1
-           decimation-tournament-size 2
-           evalpush-limit 150
-           evalpush-time-limit 0
-           node-selection-method :unbiased
-           node-selection-leaf-probability 0.1
-           node-selection-tournament-size 2
-           pop-when-tagging true
-           gaussian-mutation-probability 0.0
-           gaussian-mutation-per-number-mutation-probability 0.5
-           gaussian-mutation-standard-deviation 0.1
-           reuse-errors true
-           problem-specific-report default-problem-specific-report
-           use-single-thread false
-           random-seed (System/nanoTime)
-           use-historically-assessed-hardness false
-           }}]
-  (binding [thread-local-random-generator (java.util.Random. random-seed)]
-    ;; set globals from parameters
-    (reset! global-atom-generators atom-generators)
-    (reset! global-max-points-in-program max-points)
-    (reset! global-evalpush-limit evalpush-limit)
-    (reset! global-evalpush-time-limit evalpush-time-limit)
-    (reset! global-node-selection-method node-selection-method)
-    (reset! global-node-selection-leaf-probability node-selection-leaf-probability)
-    (reset! global-node-selection-tournament-size node-selection-tournament-size)
-    (reset! global-pop-when-tagging pop-when-tagging)
-    (reset! global-reuse-errors reuse-errors)
-    (reset! global-use-historically-assessed-hardness use-historically-assessed-hardness)
-    (printf "\nStarting PushGP run.\n\n") (flush)
-    (printf "Clojush version = ")
-    (try
-      (let [version-number (string/drop 1 (string/chop
-                                            (re-find #"\".*\""
-                                                     (first (string/split-lines
-                                                              (local-file/slurp* "project.clj"))))))]
-        (if (empty? version-number)
-          (throw Exception)
-          (printf (str version-number "\n"))))
-      (flush)
-      (catch Exception e
-             (printf "version number unavailable\n")
-             (flush)))
-    (try
-      (let [git-hash (git-last-commit-hash)]
-        (if (empty? git-hash)
-          (throw Exception)
-          (do
-            ;; NOTES: - Last commit hash will only be correct if this code has
-            ;;          been committed already.
-            ;;        - GitHub link will only work if commit has been pushed
-            ;;          to GitHub.
-            (printf (str "Hash of last Git commit = " git-hash "\n"))
-            (printf (str "GitHub link = https://github.com/lspector/Clojush/commit/"
-                         git-hash
-                         "\n"))
-            (flush))))
-      (catch Exception e
-             (printf "Hash of last Git commit = unavailable\n")
-             (printf "GitHub link = unavailable\n")
-             (flush)))
-    (print-params
-      (error-function error-threshold population-size max-points atom-generators max-generations
-                      mutation-probability mutation-max-points crossover-probability
-                      simplification-probability gaussian-mutation-probability
-                      gaussian-mutation-per-number-mutation-probability gaussian-mutation-standard-deviation
-                      tournament-size report-simplifications final-report-simplifications
-                      trivial-geography-radius decimation-ratio decimation-tournament-size evalpush-limit
-                      evalpush-time-limit node-selection-method node-selection-tournament-size
-                      node-selection-leaf-probability pop-when-tagging reuse-errors
-                      use-single-thread random-seed use-historically-assessed-hardness
-                      ))
-    (printf "\nGenerating initial population...\n") (flush)
-    (let [pop-agents (vec (doall (for [_ (range population-size)]
-                                   ((if use-single-thread atom agent)
-                                        (make-individual
-                                          :program (random-code max-points atom-generators))
-                                        :error-handler (fn [agnt except] (println except))))))
-          child-agents (vec (doall (for [_ (range population-size)]
-                                     ((if use-single-thread atom agent)
-                                          (make-individual)
-                                          :error-handler (fn [agnt except] (println except))))))
-          rand-gens (vec (doall (for [k (range population-size)]
-                                  (java.util.Random. (+ random-seed (inc k))))))]
-      (loop [generation 0]
-        (printf "\n\n-----\nProcessing generation: %s\nComputing errors..." generation) (flush)
-        (dorun (map #((if use-single-thread swap! send) % evaluate-individual error-function %2) pop-agents rand-gens))
-        (when-not use-single-thread (apply await pop-agents)) ;; SYNCHRONIZE ; might this need a dorun?
-        (printf "\nDone computing errors.") (flush)
-        ;; calculate solution rates if necessary for historically-assessed hardness
-        (when use-historically-assessed-hardness
-          (reset! solution-rates
-                  (let [error-seqs (map :errors (map deref pop-agents))
-                        num-cases (count (first error-seqs))]
-                    (doall (for [i (range num-cases)]
-                             (/ (count (filter #(<= % error-threshold) (map #(nth % i) error-seqs)))
-                                population-size)))))
-          (printf "\nSolution rates: ")
-          (println (doall (map float @solution-rates))))
-        ;; report and check for success
-        (let [best (report (vec (doall (map deref pop-agents))) generation error-function
-                           report-simplifications problem-specific-report)]
-          (if (<= (:total-error best) error-threshold)
-            (do (printf "\n\nSUCCESS at generation %s\nSuccessful program: %s\nErrors: %s\nTotal error: %s\nHistory: %s\nSize: %s\n\n"
-                        generation (not-lazy (:program best)) (not-lazy (:errors best)) (:total-error best)
-                        (not-lazy (:history best)) (count-points (:program best)))
-                (when print-ancestors-of-solution
-                  (printf "\nAncestors of solution:\n")
-                  (println (:ancestors best)))
-                (auto-simplify best error-function final-report-simplifications true 500))
-            (do (if (>= generation max-generations)
-                  (printf "\nFAILURE\n")
-                  (do (printf "\nProducing offspring...") (flush)
-                      (let [pop (;;IOD
-                                  changed-over ;;IOD
-                                  2 ;;IOD
-                                  (decimate (vec (doall (map deref pop-agents))) ;;IOD
-                                            (int (* decimation-ratio population-size)) ;;IOD
-                                            decimation-tournament-size ;;IOD
-                                            trivial-geography-radius) ;;IOD
-                                  population-size max-points atom-generators error-function)] ;;IOD
-                        (dotimes [i population-size]
-                          ((if use-single-thread swap! send)
-                               (nth child-agents i)
-                               breed i (nth rand-gens i) pop error-function population-size max-points atom-generators
-                               mutation-probability mutation-max-points crossover-probability
-                               simplification-probability tournament-size reproduction-simplifications
-                               trivial-geography-radius gaussian-mutation-probability
-                               gaussian-mutation-per-number-mutation-probability gaussian-mutation-standard-deviation)))
-                      (when-not use-single-thread (apply await child-agents)) ;; SYNCHRONIZE
-                      (printf "\nInstalling next generation...") (flush)
-                      (dotimes [i population-size]
-                        ((if use-single-thread swap! send)
-                             (nth pop-agents i) (fn [av] (deref (nth child-agents i)))))
-                      (when-not use-single-thread (apply await pop-agents)) ;; SYNCHRONIZE
-                      (recur (inc generation)))))))))))

 ;; input instructions
@@ -357,24 +102,6 @@
                                  'formula
                                  'r
                                  'h
-                                 (tag-instruction-erc [:exec :integer :float :boolean] 1000)
-                                 (tagged-instruction-erc 1000)
-                                 (tag-instruction-erc [:exec :integer :float :boolean] 1000)
-                                 (tagged-instruction-erc 1000)
-                                 (tag-instruction-erc [:exec :integer :float :boolean] 1000)
-                                 (tagged-instruction-erc 1000)
-                                 (tag-instruction-erc [:exec :integer :float :boolean] 1000)
-                                 (tagged-instruction-erc 1000)
-                                 (tag-instruction-erc [:exec :integer :float :boolean] 1000)
-                                 (tagged-instruction-erc 1000)
-                                 (tag-instruction-erc [:exec :integer :float :boolean] 1000)
-                                 (tagged-instruction-erc 1000)
-                                 (tag-instruction-erc [:exec :integer :float :boolean] 1000)
-                                 (tagged-instruction-erc 1000)
-                                 (tag-instruction-erc [:exec :integer :float :boolean] 1000)
-                                 (tagged-instruction-erc 1000)
-                                 (tag-instruction-erc [:exec :integer :float :boolean] 1000)
-                                 (tagged-instruction-erc 1000)
                                  (tag-instruction-erc [:exec :integer :float :boolean] 1000)
                                  (tagged-instruction-erc 1000))
                            '(integer_add
@@ -440,21 +167,21 @@
                               ;boolean_yankdup
                               boolean_dup
                               boolean_pop)
-                           '(exec_y
+                           '(;exec_y
                               ;exec_fromziprights
                               exec_pop
                               exec_eq
                               ;exec_stackdepth
-                              exec_rot
-                              exec_do*times
-                              exec_do*count
-                              exec_s
-                              exec_do*range
+                              ;exec_rot
+                              ;exec_do*times
+                              ;exec_do*count
+                              ;exec_s
+                              ;exec_do*range
                               ;exec_fromzipnode
                               exec_if
                               ;exec_fromziplefts
                               ;exec_fromzipchildren
-                              exec_k
+                              ;exec_k
                               ;exec_yank
                               ;exec_flush
                               ;exec_yankdup
@@ -466,13 +193,13 @@
   :error-function e
   :population-size 1000
   :use-single-thread false
-  :error-threshold 0.00001
+  :error-threshold 0.01
   :max-points 100
   :max-generations 1001
-  :mutation-probability 0.5 ;0.4 ;0.6 ;0.4
+  :mutation-probability 0.4
   :mutation-max-points 20
-  :crossover-probability 0.5 ;0.4 ;0.2 ;0.3 ;0.4
-  :simplification-probability 0.0 ;0.2 ;0.0 ;0.1
+  :crossover-probability 0.4
+  :simplification-probability 0.1
   :tournament-size 7
   :report-simplifications 100
   :final-report-simplifications 1000
@@ -482,7 +209,7 @@
   :decimation-tournament-size 2
   :evalpush-limit 200
   :evalpush-time-limit 0
-  :node-selection-method :size-tournament ;:unbiased
+  :node-selection-method :size-tournament
   :node-selection-leaf-probability 0.1
   :node-selection-tournament-size 2
   :pop-when-tagging true
@@ -490,6 +217,6 @@
   :gaussian-mutation-per-number-mutation-probability 0.5
   :gaussian-mutation-standard-deviation 0.1
   :reuse-errors true
-  :use-historically-assessed-hardness false
+  :use-historically-assessed-hardness false
   )


add debugging code to find flakyness in travis build

--- src/lambdacd_git/core.clj
+++ src/lambdacd_git/core.clj
@@ -17,6 +17,10 @@
                                 (key))
         last-seen-revision (get old-revisions changed-ref)
         new-revision       (get new-revisions changed-ref)]
+    (binding [*out* *err*]
+      (println "new entries: " new-entries)
+      (if (> (count new-entries) 1)
+        (println "OMG IT COULD BE ANYTHING!")))
     {:changed-ref  changed-ref
      :revision     new-revision
      :old-revision last-seen-revision}))


refactor

refactor

--- src/leech/server/web.cljs
+++ src/leech/server/web.cljs
@@ -78,12 +78,6 @@
       (handle-not-found conn))
   (log {:fn "handle-core" :at "finish" :conn-id conn-id}))

-(defn wrap-force-https [handler]
-  (fn [{:keys [headers server-name uri] :as req}]
-    (if (and (conf/force-https?) (not= (get headers "x-forwarded-proto") "https"))
-      (redirect (format "https://%s%s" server-name uri))
-      (handler req))))
-
 (defn parse-req [req]
   (let [url-parsed (.parse url (.url req) true)]
     {:method (.method req)
@@ -91,15 +85,17 @@
      :query-params (js->clj (.query url-parsed))
      :headers (js->clj (.headers req))}))

+(defn wrap-force-https [next]
+  (if (and (conf/force-https?) (not= (get headers "x-forwarded-proto") "https"))
+    (write-res conn 302 {"Location" (conf/canonical-host)} "You are being redirected.")
+    (next conn)))
+
 (def handle
   (fn [req res]
     (let [conn-id (node-uuid)
          {:keys [method path query-params headers]} (parse-req req)
           conn {:conn-id conn-id :req req :res res :method method :path path :query-params query-params :headers headers}]
-      (prn headers)
-      (if (and (conf/force-https?) (not= (get headers "x-forwarded-proto") "https"))
-        (write-res conn 302 {"Location" (conf/canonical-host)} "You are being redirected.")
-        (handle-core conn)))))
+      (wrap-force-https handle-core))))

 (defn listen [handle-fn port callback]
   (log {:fn "listen" :at "start" :port port})


Don't freak out if OS isn't in native-names. Fixes #81.

--- src/leiningen/compile.clj
+++ src/leiningen/compile.clj
@@ -76,12 +76,13 @@
   "Returns a File representing the directory where native libs for the
   current platform are located."
   [project]
-  (let [osdir (name (get-os))
-        archdir (name (get-arch))
-        f (file "native" osdir archdir)]
-    (if (.exists f)
-      f
-      nil)))
+  (when (and (get-os) (get-arch))
+    (let [osdir (name (get-os))
+          archdir (name (get-arch))
+          f (file "native" osdir archdir)]
+      (if (.exists f)
+        f
+        nil))))

 (defn get-jvm-args
   [project]


don't let negated tags end up nil

don't let negated tags end up nil

Signed-off-by: Chris Granger <5654cde260ae99bc4d30054171b8bcd902efd19a@gmail.com>

--- src/lt/objs/settings.cljs
+++ src/lt/objs/settings.cljs
@@ -84,8 +84,8 @@
         final (if (and ws-diff (not (empty? ws-diff)))
                 (behavior-diff (safe-read ws-diff "workspace.behaviors") final)
                 final)]
-    (reset! object/negated-tags (:- final))
-    (reset! object/tags (:+ final))))
+    (reset! object/negated-tags (or (:- final) {}))
+    (reset! object/tags (or (:+ final) {}))))

 (defn refresh-diffed [diff]
   (->> (concat (keys (:+ diff))


Update pmap-dir-files docstring

Update pmap-dir-files docstring

--- src/atom_finder/util/30_fs_util.clj
+++ src/atom_finder/util/30_fs_util.clj
@@ -36,7 +36,7 @@
         s))

 (s/defn pmap-dir-files
-  "Apply a function to the AST of every c file in a directory"
+  "Apply a function to the filename of every c file in a directory"
   [f dirname]
   (pmap
    (fn [file]


Makes a solid decision on classifier creation.

--- src/cadence/pattern_recognition.clj
+++ src/cadence/pattern_recognition.clj
@@ -31,14 +31,22 @@
   [] (sess/get :training-cadences #{}))

 (defn gen-phrase-classifier
-  "Creates a trained SVM classifier using the given dataset."
+  "Creates a trained SVM classifier using the given dataset with a RBF kernel."
   [training-data]
   (classifier-train
-    (make-classifier :support-vector-machine :smo
-                     {:fit-logistics-model true
-                      :random-seed (long (* (rand) Integer/MAX_VALUE))
-                      ;:kernel_function "rbf"
-                      })
+    (make-classifier
+      :support-vector-machine :smo
+      ;:decision-tree :c45
+      ;:bayes :naive
+      ;:decision-tree :boosted-stump
+      ;:neural-network :multilayer-perceptron
+      {:fit-logistic-models true
+       :reduce-error-pruning true
+       :kernel-function {:radial-basis {:gamma 0.02}}
+       :random-seed (long (* (rand) Integer/MAX_VALUE))
+       :normalize 1 ; When set to 1 it means standardize
+       ;:folds-for-cross-validation 30
+       })
     training-data))

 (defn cadence-to-vector [class cadence]