filter timestamps from results since they're hard to test :/

--- test/metabase/driver/query_processor_test.clj
+++ test/metabase/driver/query_processor_test.clj
@@ -775,3 +775,34 @@
  {:source_table (id :users)
   :aggregation  ["rows"]
   :order_by     [[(id :users :id) "ascending"]]})
+
+(datasets/expect-with-all-datasets
+ {:status :completed,
+  :row_count 15,
+  :data
+  {:columns (->columns "id" "last_login" "name"),
+   :cols [(users-col :id) (users-col :last_login) (users-col :name)],
+   :rows [[1 "Plato Yeshua"]
+          [2 "Felipinho Asklepios"]
+          [3 "Kaneonuskatew Eiran"]
+          [4 "Simcha Yan"]
+          [5 "Quentin Sören"]
+          [6 "Shad Ferdynand"]
+          [7 "Conchúr Tihomir"]
+          [8 "Szymon Theutrich"]
+          [9 "Nils Gotam"]
+          [10 "Frans Hevel"]
+          [11 "Spiros Teofil"]
+          [12 "Kfir Caj"]
+          [13 "Dwight Gresham"]
+          [14 "Broen Olujimi"]
+          [15 "Rüstem Hebel"]]}}
+ ;; Filter out the timestamps from the results since they're hard to test :/
+ (-> (driver/process-query
+      {:type :query,
+       :database (db-id),
+       :query
+       {:source_table (id :users),
+        :aggregation ["rows"],
+        :order_by [[(id :users :id) "ascending"]]}})
+     (update-in [:data :rows] (partial mapv (partial filterv #(not (isa? (type %) java.util.Date)))))))


remove redudant fn

remove redudant fn

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/wimdu/mysql-replay.git/'


Stub for new test module: db-interface

Stub for new test module: db-interface

error: pathspec 'test/arachnida/db_interface_test.clj' did not match any file(s) known to git

--- test/arachnida/db_interface_test.clj
+++ test/arachnida/db_interface_test.clj
@@ -0,0 +1,17 @@
+;
+;  (C) Copyright 2015  Pavel Tisnovsky
+;
+;  All rights reserved. This program and the accompanying materials
+;  are made available under the terms of the Eclipse Public License v1.0
+;  which accompanies this distribution, and is available at
+;  http://www.eclipse.org/legal/epl-v10.html
+;
+;  Contributors:
+;      Pavel Tisnovsky
+;
+
+(ns arachnida.db-interface-test
+  (:require [clojure.test :refer :all]
+            [arachnida.db-interface :refer :all]))
+
+


io ns kendu

io ns kendu

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lnmnd/magnet.zer.git/'


:pre condition for meta<-rf

:pre condition for meta<-rf

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/michaelsbradleyjr/transwarp.git/'


add .boot Clojure sample

add .boot Clojure sample

error: pathspec 'samples/Clojure/build.boot' did not match any file(s) known to git

--- samples/Clojure/build.boot
+++ samples/Clojure/build.boot
@@ -0,0 +1,15 @@
+;; from: https://github.com/boot-clj/boot#configure-task-options
+
+(set-env!
+  :source-paths #{"src"}
+  :dependencies '[[me.raynes/conch "0.8.0"]])
+
+(task-options!
+  pom {:project 'my-project
+       :version "0.1.0"}
+  jar {:manifest {"Foo" "bar"}})
+
+(deftask build
+  "Build my project."
+  []
+  (comp (pom) (jar) (install)))


React also escapes dot in keys

React also escapes dot in keys

--- src/rum/server_render.clj
+++ src/rum/server_render.clj
@@ -207,6 +207,7 @@
   [^String text]
   (.. text
     (replace "=" "=0")
+    (replace "." "=1")
     (replace ":" "=2")))


on collection abstraction

on collection abstraction

error: pathspec 'src/language/colAbstr.clj' did not match any file(s) known to git

--- src/language/colAbstr.clj
+++ src/language/colAbstr.clj
@@ -0,0 +1,23 @@
+(ns language.colAbstr)
+
+(ns language.hello)
+
+(defn scaffold
+  [interface]
+  (doseq [[iface methods] (->> interface
+                               .getMethods
+                               (map #(vector (.getName (.getDeclaringClass %))
+                                             (symbol (.getName %))
+                                             (count (.getParameterTypes %))))
+                               (group-by first))]
+    (println (str " " iface))
+    (doseq [[_ name argcount] methods]
+      (println (str " "
+                    (list name (into '[this] (take argcount (repeatedly gensym)))))))))
+
+(map #(.getName %) (.getMethods clojure.lang.IPersistentSet))
+
+(map #(.getDeclaringClass %) (.getMethods clojure.lang.IPersistentSet))
+(map #(.getName (.getDeclaringClass %)) (.getMethods clojure.lang.IPersistentSet))
+
+(map #(.getParameterTypes %) (.getMethods clojure.lang.IPersistentSet))


soem common i/o stuff

soem common i/o stuff

error: pathspec 'src/sormilla/io_utils.clj' did not match any file(s) known to git

--- src/sormilla/io_utils.clj
+++ src/sormilla/io_utils.clj
@@ -0,0 +1,27 @@
+(ns sormilla.io-utils
+  (:require [sormilla.bin :as bin])
+  (:import [java.io InputStream]
+           [java.net Socket InetAddress InetSocketAddress]
+           [org.apache.commons.io IOUtils]))
+
+(defn read-fully [^InputStream in ^bytes buffer ^long offset ^long size]
+  (IOUtils/readFully in buffer offset size)
+  buffer)
+
+(defn skip-fully [^InputStream in ^long size]
+  (IOUtils/skipFully in size))
+
+(defn open-socket ^Socket [^InetAddress addr port]
+  (doto (Socket.)
+    (.setSoTimeout 2000)
+    (.connect (InetSocketAddress. addr port))))
+
+(defn write-to-socket ^Socket [^Socket socket & data]
+  (doto (.getOutputStream socket)
+    (.write (byte-array (map bin/ubyte data)))
+    (.flush))
+  socket)
+
+(defn open-video-socket ^Socket [^InetAddress addr]
+  (doto (open-socket addr 5555)
+    (write-to-socket 1 0 0 0)))


Adding tests the wrong way

Adding tests the wrong way

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mstang/pathdatabase.git/'


Add InfluxDB 0.9.x batch writer.

Add InfluxDB 0.9.x batch writer.

error: pathspec 'src/riemann/influxdb_9.clj' did not match any file(s) known to git

--- src/riemann/influxdb_9.clj
+++ src/riemann/influxdb_9.clj
@@ -0,0 +1,113 @@
+(ns riemann.influxdb-9
+  "Functions to write events as points to an InfluxDB 0.9 series cluster."
+  (:require
+    [cheshire.core :as json]
+    [clj-http.client :as http]
+    [clojure.set :as set]
+    [riemann.common :refer [unix-to-iso8601]]))
+
+
+(defn write-endpoint
+  "Generates a URL for the write endpoint based on an InfluxDB opts map."
+  [opts]
+  (str (if (:tls opts) "https" "http")
+       "://" (:host opts)
+       \: (:port opts)
+       "/write"))
+
+
+(defn event-tags
+  "Generates a map of InfluxDB tags from a Riemann event. Any entries in the
+  event which are named in `tag-keys` will be converted to a string key/value
+  entry in the tag map. The event's `host` is always included."
+  [tag-keys event]
+  (->> (conj tag-keys :host)
+       (select-keys event)
+       (map #(vector (name (key %)) (str (val %))))
+       (into {})))
+
+
+(defn event-fields
+  "Generates a map of InfluxDB fields from a Riemann event. The event's
+  `metric` is converted to the `value` field, and any additional event entries
+  which are not standard Riemann fields or in `tag-keys` will also be present."
+  [tag-keys event]
+  (let [standard-keys #{:host :service :time :metric :description :tags :ttl}
+        ignored-keys (set/union standard-keys tag-keys)]
+    (-> event
+        (->> (remove (comp ignored-keys key))
+             (map #(vector (name (key %)) (val %)))
+             (into {}))
+        (assoc "value" (:metric event)))))
+
+
+(defn event->point
+  "Converts a Riemann event into an InfluxDB point if it has a time, service,
+  and metric."
+  [tag-keys event]
+  (when (and (:time event) (:service event) (:metric event))
+    {"name" (:service event)
+     "timestamp" (unix-to-iso8601 (:time event))
+     "tags" (event-tags tag-keys event)
+     "fields" (event-fields tag-keys event)}))
+
+
+(defn events->points
+  "Converts a collection of Riemann events into InfluxDB points. Events which
+  map to nil are removed from the final collection."
+  [tag-keys events]
+  (vec (remove nil? (map (partial event->point tag-keys) events))))
+
+
+(defn influxdb
+  "Returns a function which accepts an event, or sequence of events, and writes
+  them to InfluxDB as a batch of measurement points.
+
+  (batch 500 1
+    (influxdb {:host \"influxdb.example.com\"
+               :port 8086
+               :database \"my_db\"}))
+
+  Options:
+
+  `:host`           Hostname to write points to.
+
+  `:port`           API port number.
+
+  `:tls`            Whether to write using HTTPS. (optional)
+
+  `:database`       Name of database to write to.
+
+  `:retention`      Name of retention policy to use. (optional)
+
+  `:username`       Database user to authenticate as.
+
+  `:password`       Password to authenticate with.
+
+  `:tags`           A common map of tags to apply to all events. (optional)
+
+  `:tag-keys`       A set of event fields to map into InfluxDB series tags.
+                    (optional)"
+  [opts]
+  (let [write-url (write-endpoint opts)
+        tag-keys (:tag-keys opts #{})
+        payload-base (cond-> {"database" (:database opts)}
+                       (:retention opts)
+                         (assoc "retentionPolicy" (:retention opts))
+                       (seq (:tags opts))
+                         (assoc "tags" (:tags opts)))
+        http-opts {:socket-timeout 5000 ; ms
+                   :conn-timeout   5000 ; ms
+                   :content-type   :json
+                   :basic-auth [(:username opts)
+                                (:password opts)]}]
+    (fn stream
+      [events]
+      (let [events (if (sequential? events) events (list events))
+            points (events->points tag-keys events)]
+        (when-not (empty? points)
+          (->> points
+               (assoc payload-base "points")
+               (json/generate-string)
+               (assoc http-opts :body)
+               (http/post write-url)))))))


[WM] log authority create tx's at debug level

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/election-authority-works.git/'


[WM] remove unneccessary datomic.api/touch call

It's basically never necessary to call this in code. It's more of a REPL
convenience function.


Initial tests for git namespace

Initial tests for git namespace

error: pathspec 'test/shuppet/git_test.clj' did not match any file(s) known to git

--- test/shuppet/git_test.clj
+++ test/shuppet/git_test.clj
@@ -0,0 +1,21 @@
+(ns shuppet.git-test
+  (:require [midje.sweet :refer :all]
+            [shuppet.git :refer :all]
+            [tentacles
+             [repos :as repos]]))
+
+(fact "that getting the data for the poke environment uses the master branch"
+      (get-data "poke" "application")
+      => "poke-content"
+      (provided
+       (repos/contents "shuppet" "application" "application.clj" {:ref "master"
+                                                                  :str? true})
+       => {:content "poke-content"}))
+
+(fact "that getting the data for the prod environment doesn't use the master branch"
+      (get-data "prod" "application")
+      => "prod-content"
+      (provided
+       (repos/contents "shuppet" "application" "application.clj" {:ref "prod"
+                                                                  :str? true})
+       => {:content "prod-content"}))


restore team name

restore team name

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/clojurecup/cc2014-frontend.git/'


Shen REPL should still launch if rlwrap was not found

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/michaelsbradleyjr/shen.clj.git/'


konponketa: DB hasieratu behar bada konfigurazioa kargatu


Better logging when :releases-url isn't set.

--- src/clojars/promote.clj
+++ src/clojars/promote.clj
@@ -108,13 +108,14 @@
    (println "checking" group "/" name "for promotion...")
    (let [blockers (blockers info)]
      (if (empty? blockers)
-       (when (config :releases-url)
-         (println "Promoting" info)
-         (deploy-to-s3 info)
-         ;; TODO: this doesn't seem to be happening. db locked?
-         (update db/jars
-                 (set-fields {:promoted_at (java.util.Date.)})
-                 (where {:group_name group :jar_name name :version version})))
+       (if (config :releases-url)
+         (do
+           (println "Promoting" info)
+           (deploy-to-s3 info)
+           (update db/jars
+                   (set-fields {:promoted_at (java.util.Date.)})
+                   (where {:group_name group :jar_name name :version version})))
+         (println "Didn't promote since :releases-url wasn't set."))
        (do (println "...failed.")
            blockers)))))


test parse functionality with concrete functionality taken from babel.francais.* namespaces

error: pathspec 'test/babel/test/parse.cljc' did not match any file(s) known to git

--- test/babel/test/parse.cljc
+++ test/babel/test/parse.cljc
@@ -0,0 +1,57 @@
+(ns ^{:doc "Parsing Testing Code"}
+    babel.test.parse
+  (:refer-clojure :exclude [get-in])
+  (:require [babel.engine :as engine]
+            [babel.forest :as forest]
+            [babel.francais.grammar :refer [small medium]]
+            [babel.francais.lexicon :refer [lexicon]]
+            [babel.francais.morphology :refer [analyze fo replace-patterns]]
+            [babel.francais.workbook :as workbook]
+            [babel.over :as over]
+            [babel.parse :refer [create-bigram-map create-ngram-map create-trigram-map
+                                 create-unigram-map create-xgram-map parse tokenizer toks toks2]]
+            [clojure.string :as string]
+            #?(:clj [clojure.test :refer [deftest is]])
+            #?(:cljs [cljs.test :refer-macros [deftest is]])
+            #?(:clj [clojure.tools.logging :as log])
+            #?(:cljs [babel.logjs :as log])
+            [dag_unify.core :refer [fail-path fail? get-in strip-refs unifyc]]))
+
+;; TODO: (lookup) and (over) convenience functions are duplicated in
+;; babel.workbook.francais: factor out to babel.francais.
+;; TODO: do morphological analysis
+;; do find non-infinitives (e.g. find 'parler' given 'parle')
+;; and then apply conjugated parts to lexeme
+;; i.e. if input is 'parle', return
+;; list of lexemes; for each, [:synsem :agr :person] will be
+;; 1st, 2nd, or 3rd, and for all, number will be singular.
+(defn lookup [lexeme]
+  (get (:lexicon medium) lexeme))
+
+(defn over
+  ([arg1]
+   (over/over (vals (:grammar-map medium)) (lookup arg1)))
+  ([grammar arg1]
+   (over/over grammar (lookup arg1)))
+  ([grammar arg1 arg2]
+   (cond (string? arg1)
+         (over grammar (lookup arg1)
+               arg2)
+
+         (string? arg2)
+         (over grammar arg1 (lookup arg2))
+
+         true
+         (over/over grammar arg1 arg2))))
+
+(deftest split
+  (is (= 2 (count (string/split "je suis" tokenizer)))))
+
+(deftest toks-test1
+  (is (= 2 (count (toks "je suis" lexicon lookup)))))
+
+(deftest toks-test2
+  (is (= 2 (count (nth (toks "je suis" lexicon lookup) 0)))))
+
+(deftest toks-test3
+  (is (= 2 (count (nth (toks "je suis" lexicon lookup) 1)))))


Implementation of the Last Index of Zero problem.

This is my stab at implementing the Last Index of Zero problem from iJava, where the goal is to take a list of integers containing at least one zero, and return the zero-based index of the last zero in the list.

Most of this was based on a previous problem from thelmuth. The most "creative" part was creating the test suite, which he should definitely look over before pulling this in and using it.

error: pathspec 'src/clojush/problems/software/last_index_of_zero.clj' did not match any file(s) known to git

--- src/clojush/problems/software/last_index_of_zero.clj
+++ src/clojush/problems/software/last_index_of_zero.clj
@@ -0,0 +1,169 @@
+;; last_index_of_zero.clj
+;; Nic McPhee, mcphee@morris.umn.edu
+;;
+;; Problem Source: iJava (http://ijava.cs.umass.edu/)
+;;
+;; Given a vector of integers of length <= 50, each integer in the range [-20,20],
+;; at least one of which is 0, return the index of the last occurance of 0 in the vector.
+;;
+;; input stack has 1 input vector of integers
+
+(ns clojush.problems.software.last-index-of-zero
+  (:use clojush.pushgp.pushgp
+        [clojush pushstate interpreter random util globals]
+        clojush.instructions.tag
+        [clojure.math numeric-tower combinatorics]
+        ))
+
+; Atom generators
+(def last-index-of-zero-atom-generators
+  (concat (list
+            ^{:generator-label "Random numbers in the range [0, 50)"}
+            (fn [] (lrand-int 50))
+            ;;; end ERCs
+            (tag-instruction-erc [:integer :boolean :vector_integer :exec] 1000)
+            (tagged-instruction-erc 1000)
+            ;;; end tag ERCs
+            'in1
+            ;;; end input instructions
+            )
+          (registered-for-stacks [:integer :boolean :vector_integer :exec])))
+
+;; Define test cases
+(defn random-sequence-with-at-least-one-zero
+  [max-extra-zeros num-additional-values]
+  (shuffle
+   (concat
+    [0] ; To ensure at least one zero
+    (repeat (lrand-int max-extra-zeros) 0)
+    (repeatedly num-additional-values #(- (lrand-int 100) 50)))))
+
+;; A list of data domains for the problem. Each domain is a vector containing
+;; a "set" of inputs and two integers representing how many cases from the set
+;; should be used as training and testing cases respectively. Each "set" of
+;; inputs is either a list or a function that, when called, will create a
+;; random element of the set.
+(def last-index-of-zero-data-domains
+  [^{:domain-label "length 2 vectors"}
+   [(list [0 1]
+          [1 0]
+          [7 0]
+          [0 8]
+          [0 -1]
+          [-1 0]
+          [-7 0]
+          [0 -8]) 8 0]
+   ^{:domain-label "vectors of all zeros"}
+   [(map #(repeat (inc %) 0) (range 50)) 30 20]
+   ^{:domain-label "permutations of a 4 item vector with one zero"}
+   [(permutations [0 5 -8 9]) 20 4]
+   ^{:domain-label "permutations of a 4 item vector with two zeros"}
+   [(permutations [0 0 -8 9]) 20 4]
+   ^{:domain-label "permutations of a 4 item vector with three zeros"}
+   [(permutations [0 0 0 9]) 20 4]
+   ^{:domain-label "random cases"}
+   [(fn [] (random-sequence-with-at-least-one-zero 5 20)) 100 100]
+   ])
+
+;;Can make Last Index of Zero test data like this:
+;(test-and-train-data-from-domains last-index-of-zero-data-domains)
+
+; Helper function for error function
+(defn last-index-of-zero-test-cases
+  "Takes a sequence of inputs and gives IO test cases of the form
+   [input output]."
+  [inputs]
+  (map #(vector % (.lastIndexOf % 0))
+       inputs))
+
+; Define error function. For now, each run uses different random inputs
+(defn last-index-of-zero-error-function
+  "Returns the error function for the last-index-of-zero problem. Takes
+   Last Index of Zero data domains as input."
+  [data-domains]
+  (let [[train-cases test-cases] (map last-index-of-zero-test-cases
+                                      (test-and-train-data-from-domains data-domains))]
+    (when true ;; Change to false to not print test cases
+      (doseq [[i case] (map vector (range) train-cases)]
+        (println (format "Train Case: %3d | Input/Output: %s" i (str case))))
+      (doseq [[i case] (map vector (range) test-cases)]
+        (println (format "Test Case: %3d | Input/Output: %s" i (str case)))))
+    (fn the-actual-last-index-of-zero-error-function
+      ([program]
+        (the-actual-last-index-of-zero-error-function program :train))
+      ([program data-cases] ;; data-cases should be :train or :test
+        (the-actual-last-index-of-zero-error-function program data-cases false))
+      ([program data-cases print-outputs]
+        (let [behavior (atom '())
+              errors (doall
+                      (for [[[input] correct-output] (case data-cases
+                                                       :train train-cases
+                                                       :test test-cases
+                                                       [])]
+                        (let [final-state (run-push program
+                                                    (->> (make-push-state)
+                                                         (push-item input :input)))
+                              result (top-item :integer final-state)]
+                          (when print-outputs
+                            (println (format "Correct output: %2d | Program output: %s"
+                                             correct-output
+                                             (str result))))
+                          ; Record the behavior
+                          (when @global-print-behavioral-diversity
+                            (swap! behavior conj result))
+                          ; Error is absolute distance from correct index
+                          (if (number? result)
+                             (abs (- result correct-output)) ; distance from correct integer
+                             1000000) ; penalty for no return value
+                          )))]
+          (when @global-print-behavioral-diversity
+            (swap! population-behaviors conj @behavior))
+          errors)))))
+
+(defn last-index-of-zero-report
+  "Custom generational report."
+  [best population generation error-function report-simplifications]
+  (let [best-program (not-lazy (:program best))
+        best-test-errors (error-function best-program :test)
+        best-total-test-error (apply +' best-test-errors)]
+    (println ";;******************************")
+    (printf ";; -*- Last Index of Zero problem report - generation %s\n" generation)(flush)
+    (println "Test total error for best:" best-total-test-error)
+    (println (format "Test mean error for best: %.5f" (double (/ best-total-test-error (count best-test-errors)))))
+    (when (zero? (:total-error best))
+      (doseq [[i error] (map vector
+                             (range)
+                             best-test-errors)]
+        (println (format "Test Case  %3d | Error: %d" i error))))
+    (println ";;------------------------------")
+    (println "Outputs of best individual on training cases:")
+    (error-function best-program :train true)
+    (println ";;******************************")
+    )) ;; To do validation, could have this function return an altered best individual
+       ;; with total-error > 0 if it had error of zero on train but not on validation
+       ;; set. Would need a third category of data cases, or a defined split of training cases.
+
+
+; Define the argmap
+(def argmap
+  {:error-function (last-index-of-zero-error-function last-index-of-zero-data-domains)
+   :atom-generators last-index-of-zero-atom-generators
+   :max-points 300
+   :max-points-in-initial-program 150
+   :evalpush-limit 600
+   :population-size 1000
+   :max-generations 300
+   :parent-selection :lexicase
+   :genetic-operator-probabilities {:alternation 0.2
+                                    :uniform-mutation 0.2
+                                    :uniform-close-mutation 0.1
+                                    [:alternation :uniform-mutation] 0.5
+                                    }
+   :alternation-rate 0.01
+   :alignment-deviation 10
+   :uniform-mutation-rate 0.01
+   :problem-specific-report last-index-of-zero-report
+   :print-behavioral-diversity true
+   :report-simplifications 0
+   :final-report-simplifications 5000
+   })