From fe12fe16fa5f8bddece8cab225a9bc4a332cfffd Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Wed, 7 Jul 2021 17:25:50 -0400 Subject: more clojure --- clojure/src/csvtool/core.clj | 132 ++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 90 deletions(-) diff --git a/clojure/src/csvtool/core.clj b/clojure/src/csvtool/core.clj index 8a061c8..8654f3a 100644 --- a/clojure/src/csvtool/core.clj +++ b/clojure/src/csvtool/core.clj @@ -9,39 +9,25 @@ (->> (zipmap keys row) (#(dissoc % :ignore)))) -;; (defn my-read [] -;; (with-open [reader (io/reader "in-file.csv")] -;; (doall -;; (map handle-record (csv/read-csv reader))))) - -;; (defn my-write [] -;; (with-open [writer (io/writer "out-file.csv")] -;; (csv/write-csv writer -;; [["abc" "def"] -;; ["ghi" "jkl"]]))) - -(defmacro wrap-matcher - ([] identity) - - ([body] - `(fn [~'record] - (let [~'get #(get ~'record %) - ~'set #(assoc ~'record %1 %2)] - ~body))) - - ([expr & next] - `(fn [record#] - ((wrap-matcher ~@next) ((wrap-matcher ~expr) record#))))) - -(defn record-action [name & rest] +(defn record-action [expr & rest] + (let [actions + {:set (fn [keyword value & rest] + (fn [record] + [(assoc record keyword value) rest])) + :mod (fn [keyword modf & rest] + (fn [record] + [(update record keyword modf) rest]))}] + (if (fn? expr) + (fn [record] [(expr record) rest]) + (apply (get actions expr) rest)))) + +(defn record-actions [& exprs] (fn [record] - (let [actions {:set (fn [keyword value] - (assoc record keyword value)) - :mod (fn [keyword modf] - (update record keyword modf))}] - (if (fn? name) - (name record) - (apply (get actions name) rest))))) + (let [[next-record rest] ((apply record-action exprs) record) + next-action (if (empty? rest) + identity + (apply record-actions rest))] + (next-action next-record)))) (defn record-test [keyword pred] (fn [record] @@ -49,17 +35,11 @@ (pred (get record keyword)) nil))) -(defn matches [keyword pattern] - (fn [record] - (re-matches pattern (get record keyword)))) - -(def always (constantly true)) - (defmacro mk-rule [test & actions] `(fn [record#] (if (~test record#) - ((~record-action ~@actions) record#) + ((~record-actions ~@actions) record#) record#))) (defmacro mk-chain @@ -77,63 +57,35 @@ [name & rules] `(def ~name (mk-chain ~@rules))) +(def always (constantly true)) + +(defn matches [keyword pattern] + (fn [record] + (and (contains? record keyword) + (re-matches pattern (get record keyword))))) + +(defn matches-any [keyword & patterns] + (fn [record] + (let [v (get record keyword)] + (some (fn [pattern] (re-matches pattern v)) patterns)))) + +(defchain dining + [(matches-any :desc + #"(?i)chipotle.*" + #"(?i)tappo- location.*") + :set :account2 "expenses:dining"]) + (defchain default - ;; Set default account [always :set :account2 "expenses:unknown"] + [always dining] + [(matches :desc #"(?i)key food.*") - :set :desc "Key Foods"] + :set :desc "Key Foods" + :set :account2 "expenses:groceries"] [(matches :desc #"(?i)google \*cloud") - :set :account2 "expenses:services"] - ) - -;; (defmacro matches -;; [keyword pattern] -;; `(wrap-matcher -;; (let [v# (~'get ~keyword)] -;; (and v# (re-matches ~pattern (~'get ~keyword)))))) - -;; (defmacro defchain -;; ([] identity) - -;; ([[pred & arg]] -;; (let [expr2 -;; (if (= :do (first arg)) -;; `((wrap-matcher ~@(rest arg))) -;; arg)] -;; `(fn [record#] -;; (if (~pred record#) -;; (~@expr2 record#) -;; record#)))) - -;; ([x & next] -;; `(fn [record#] -;; ((defchain ~@next) -;; ((defchain ~x) record#))))) - -;; (def always (constantly true)) - -;; (def other-rules -;; (defchain -;; [(matches :desc #"Amazon.com.*") -;; :do (set :desc "Amazon purchase")])) - -;; (def my-rules -;; (defchain -;; [always :do (set :account2 "expenses:unknown")] - -;; [(matches :desc #"(?i)key food.*") -;; :do -;; (set :desc "Key Foods") -;; (set :account2 "expenses:groceries")] - -;; [(matches :desc #"(?i)google \*cloud") -;; :do -;; (set :desc "Google Cloud") -;; (set :account2 "expenses:services")] - -;; [always other-rules])) + :set :account2 "expenses:services"]) (defn handle-record [row] (let [record (mk-mapping row :date :postdate :desc :category :type :amount :memo)] -- cgit v1.2.3