Nate finds it easier to get a broad view without a microscope.
loop
+ recur
approach is getting complicated!
reduce
. Just write "reducer" functions.reduce
is already filtered.if
for throwing away data.filter
to just pass through Sundays.map
and filter
to get the data in shape first.Related episodes:
Clojure in this episode:
loop
, recur
map
, filter
, reduce
group-by
if
->
, ->>
Code sample from this episode:
(ns time.week-03
(:require
[clojure.java.io :as io]
[clojure.string :as string]
[java-time :as jt]))
; Functions for parsing out the time format: Fri Feb 08 2019 11:30-13:45
(def timestamp-re #"(\w+\s\w+\s\d+\s\d+)\s+(\d{2}:\d{2})-(\d{2}:\d{2})")
(defn localize [dt tm]
(jt/zoned-date-time dt tm (jt/zone-id)))
(defn parse-time [time-str]
(jt/local-time "HH:mm" time-str))
(defn parse-date [date-str]
(jt/local-date "EEE MMM dd yyyy" date-str))
(defn adjust-for-midnight
[start end]
(if (jt/before? end start)
(jt/plus end (jt/days 1))
end))
(defn parse
[line]
(when-let [[whole dt start end] (re-matches timestamp-re line)]
(let [date (parse-date dt)
start (localize date (parse-time start))
end (adjust-for-midnight start (localize date (parse-time end)))]
{:date date
:start start
:end end
:minutes (jt/time-between start end :minutes)})))
; How many minutes did I work on each day?
(defn daily-total-minutes
[times]
(->> times
(group-by :date)
(map (fn [[date entries]] (vector date (reduce + (map :minutes entries)))))
(into {})))
; How many minutes total did I work on Sundays?
(defn on-sunday?
[{:keys [date]}]
(= (jt/day-of-week date) (jt/day-of-week :sunday)))
(defn sunday-minutes
[times]
(->> times
(filter on-sunday?)
(map :minutes)
(reduce +)))
; Functions for turning the time log into a sequence of time entries
(defn lines
[filename]
(->> (slurp filename)
(string/split-lines)))
(defn times
[lines]
(->> lines
(map parse)
(filter some?)))
; Process a time log with the desired summary calculation
(defn summarize
[filename calc]
(->> (lines filename)
(times)
(calc)))
(comment
(summarize "time-log.txt" daily-total-minutes)
(summarize "time-log.txt" sunday-minutes)
)