Skip to content

Instantly share code, notes, and snippets.

@xificurC
Created June 4, 2021 07:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xificurC/fc563a48a7b40bd419a8696a16a2de73 to your computer and use it in GitHub Desktop.
Save xificurC/fc563a48a7b40bd419a8696a16a2de73 to your computer and use it in GitHub Desktop.
Plover training script
#!/usr/bin/env bb
(ns user
(:require
[clojure.edn :as edn]
[clojure.java.io :as io]
[clojure.string :as str]
[babashka.fs :as fs]))
(def wpms-kept 10)
(def drop-at-least 5)
(def look-and-newline-nanos 400000000)
(def data-root (fs/path (System/getProperty "user.home") ".config/eagle"))
(defn read-entry-list []
(let [f (fs/path data-root "list")]
(if (fs/readable? f)
(fs/read-all-lines f)
(throw (ex-info (str "Please create an entry list file at " f) {:error :client :file-missing f})))))
(def db-path (fs/path data-root "db.edn"))
(defn read-db []
(let [db-file db-path]
(if (fs/exists? db-file) (-> db-file fs/file io/reader java.io.PushbackReader. edn/read) [])))
(defn avg [xs] (if (seq xs) (long (/ (reduce + xs) (count xs))) 0))
(defn wpm-avg [e] (-> e :wpms avg))
(defn init [e] {:entry e :active true :wpms '()})
(defn init-entries [db entries]
(let [in (into #{} (map :entry) db)] (reduce (fn [db e] (if (in e) db (conj db (init e)))) db entries)))
(defn mark-active [db entries]
(let [active (set entries)] (reduce (fn [ac e] (conj ac (assoc e :active (boolean (active (:entry e)))))) [] db)))
(defn wpm-sort [db] (sort-by #(if (:active %) (wpm-avg %) 999999) db))
(defn calc-wpm [t nchars] (-> nchars (/ t) (* 1000 1000 1000 60) (/ 5) long))
(defn add-wpm-entry [wpms wpm] (take wpms-kept (cons wpm wpms)))
(defn update-entry [e wpm] (update e :wpms add-wpm-entry wpm))
(defn main-loop []
(let [entries (read-entry-list), db (-> (read-db) (init-entries entries) (mark-active entries) wpm-sort)]
(loop [[e & db :as full] db]
(spit (fs/file db-path) full)
(println "---")
(println (:entry e))
(let [t1 (System/nanoTime)
in (read-line)
t (- (System/nanoTime) t1 look-and-newline-nanos)
wpm (calc-wpm t (count (:entry e)))]
(if (= (str/trim in) (:entry e))
(let [head (vec (take drop-at-least db))]
(println wpm "WPM")
(recur (into head (wpm-sort (cons (update-entry e wpm) (drop drop-at-least db))))))
(recur (cons (update-entry e 0) db)))))))
(main-loop)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment