Artwork

Content provided by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones. All podcast content including episodes, graphics, and podcast descriptions are uploaded and provided directly by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones or their podcast platform partner. If you believe someone is using your copyrighted work without your permission, you can follow the process outlined here https://player.fm/legal.
Player FM - Podcast App
Go offline with the Player FM app!

Ep 019: Dazed by Weak Weeks

29:56
 
Share
 

Manage episode 228863110 series 2463849
Content provided by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones. All podcast content including episodes, graphics, and podcast descriptions are uploaded and provided directly by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones or their podcast platform partner. If you believe someone is using your copyrighted work without your permission, you can follow the process outlined here https://player.fm/legal.

Nate wants to see more than data structures in a REPL.

  • Goal: see a text-based calendar of hours worked by day and week.
  • "With the power of the predicate, I summon thee from the bag of data!"
  • If data items share structure, you only need one predicate function, not separate functions per "type".
  • Common pattern: filter then map, then reduce
  • Output:
    • Looks like a calendar with one line per week
    • Show daily total for each day
    • Show weekly total
  • Problem: how do we split the days into weeks?
  • "I don't remember split-weeks in the Clojure cheat sheet."
  • "What day does your week start on? My week starts on Tuesday."
  • "I always assume that when a programmer says 'most', they mean 'most of the people around me'." "I actually think it just means 'me'."
  • "Anecdata: when you have two anecdotes, it makes data."
  • Create higher-level summaries: entry → day → week
  • Sift through data at the level of your question.
  • Problem: A date identifies a "day", but what identifies a week? A "week ID", so to speak.
  • It would be nice if that week ID was ordered, so we could sort on it.
  • Idea: Use the date of the first day of the week
    • uniq, sortable, spans years
    • weeks that start on Tuesday will never have the same ID as weeks that start on Sunday
  • Might as well have the starting day of the week in the map too: :sunday, :tuesday, etc.
  • Convenient to have two different views for the same data in the same data structure
    • immutable data won't change and get inconsistent.
    • it's pre-calculated if you need to use it a lot vs just using a predicate "on the fly".
  • Want to group-by the week:
    • need a predicate from "date ID" → "week ID": (week-id starting-day-of-week day)
    • need to take a "date" and produce "date of first day in week"
    • Eg. (week-id :sunday {:date "2019-03-08" ...}) => "2019-03-03"
  • "You're teaching Clojure core how to describe your data by giving it vocabulary."
  • Write something that converts data to data, not data to println.
  • Principle: move the I/O to the edges
    • make the println a trivial step at the end
    • even making the strings is a data transform
    • everything prior to the println could be tested, even the formatting!
  • "Test it to the level of detail you can tolerate."
  • Much easier to reason about pure functions.

Related episodes:

Clojure in this episode:

  • filter, map, reduce
  • group-by
  • sort-by with partition-by
  • take-while, drop-while, and split-with

Code sample from this episode:

(ns time.week-05  (:require  [time.week-04 :as week-04]  [java-time :as jt]  ))   ; Date helpers  (defn start-of-week  "Get the the starting date of the week containing local-date. The week will  start on the named day. Eg. :sunday"  [starting-day-of-week local-date]  (jt/adjust local-date :previous-or-same-day-of-week (jt/day-of-week starting-day-of-week)))  (defn week-dates  "Create a week's worth of dates starting from the given date."  [starting-date]  (->> (range 0 7)  (map #(jt/plus starting-date (jt/days %)))))   ; Aggregates  (defn sum-minutes  "Sums the minutes for all kinds: entry, day, week"  [entries]  (->> entries  (map :minutes)  (reduce +)))   ; Conversions  (defn entries->days  "Convert a seq of entries to days."  [entries]  (->> (group-by :date entries)  (map (fn [[date xs]] {:date date :minutes (sum-minutes xs)}))))  (defn days->week  "Convert a seq of days into a week. Week is picked by first date."  [starting-day-of-week days]  (let [lookup (into {} (map (juxt :date identity) days))  starting-date (start-of-week starting-day-of-week (:date (first days)))  all-days (->> (week-dates starting-date)  (map #(or (get lookup %)  {:date %  :minutes 0})))]  {:starting-day-of-week starting-day-of-week  :date starting-date  :days (vec all-days)  :minutes (sum-minutes all-days)}))  (defn partition-weeks  [starting-day-of-week days]  (->> days  (sort-by :date)  (partition-by #(start-of-week starting-day-of-week (:date %)))))  (defn days->weeks  "Convert a seq of days into an ordered seq of weeks."  [starting-day-of-week days]  (->> (partition-weeks starting-day-of-week days)  (map (partial days->week starting-day-of-week))))   (comment  (->> (week-04/log-times "time-log.txt")  (entries->days))   (->> (week-04/log-times "time-log.txt")  (entries->days)  (days->weeks :sunday))  )
  continue reading

118 episodes

Artwork

Ep 019: Dazed by Weak Weeks

Functional Design in Clojure

91 subscribers

published

iconShare
 
Manage episode 228863110 series 2463849
Content provided by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones. All podcast content including episodes, graphics, and podcast descriptions are uploaded and provided directly by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones or their podcast platform partner. If you believe someone is using your copyrighted work without your permission, you can follow the process outlined here https://player.fm/legal.

Nate wants to see more than data structures in a REPL.

  • Goal: see a text-based calendar of hours worked by day and week.
  • "With the power of the predicate, I summon thee from the bag of data!"
  • If data items share structure, you only need one predicate function, not separate functions per "type".
  • Common pattern: filter then map, then reduce
  • Output:
    • Looks like a calendar with one line per week
    • Show daily total for each day
    • Show weekly total
  • Problem: how do we split the days into weeks?
  • "I don't remember split-weeks in the Clojure cheat sheet."
  • "What day does your week start on? My week starts on Tuesday."
  • "I always assume that when a programmer says 'most', they mean 'most of the people around me'." "I actually think it just means 'me'."
  • "Anecdata: when you have two anecdotes, it makes data."
  • Create higher-level summaries: entry → day → week
  • Sift through data at the level of your question.
  • Problem: A date identifies a "day", but what identifies a week? A "week ID", so to speak.
  • It would be nice if that week ID was ordered, so we could sort on it.
  • Idea: Use the date of the first day of the week
    • uniq, sortable, spans years
    • weeks that start on Tuesday will never have the same ID as weeks that start on Sunday
  • Might as well have the starting day of the week in the map too: :sunday, :tuesday, etc.
  • Convenient to have two different views for the same data in the same data structure
    • immutable data won't change and get inconsistent.
    • it's pre-calculated if you need to use it a lot vs just using a predicate "on the fly".
  • Want to group-by the week:
    • need a predicate from "date ID" → "week ID": (week-id starting-day-of-week day)
    • need to take a "date" and produce "date of first day in week"
    • Eg. (week-id :sunday {:date "2019-03-08" ...}) => "2019-03-03"
  • "You're teaching Clojure core how to describe your data by giving it vocabulary."
  • Write something that converts data to data, not data to println.
  • Principle: move the I/O to the edges
    • make the println a trivial step at the end
    • even making the strings is a data transform
    • everything prior to the println could be tested, even the formatting!
  • "Test it to the level of detail you can tolerate."
  • Much easier to reason about pure functions.

Related episodes:

Clojure in this episode:

  • filter, map, reduce
  • group-by
  • sort-by with partition-by
  • take-while, drop-while, and split-with

Code sample from this episode:

(ns time.week-05  (:require  [time.week-04 :as week-04]  [java-time :as jt]  ))   ; Date helpers  (defn start-of-week  "Get the the starting date of the week containing local-date. The week will  start on the named day. Eg. :sunday"  [starting-day-of-week local-date]  (jt/adjust local-date :previous-or-same-day-of-week (jt/day-of-week starting-day-of-week)))  (defn week-dates  "Create a week's worth of dates starting from the given date."  [starting-date]  (->> (range 0 7)  (map #(jt/plus starting-date (jt/days %)))))   ; Aggregates  (defn sum-minutes  "Sums the minutes for all kinds: entry, day, week"  [entries]  (->> entries  (map :minutes)  (reduce +)))   ; Conversions  (defn entries->days  "Convert a seq of entries to days."  [entries]  (->> (group-by :date entries)  (map (fn [[date xs]] {:date date :minutes (sum-minutes xs)}))))  (defn days->week  "Convert a seq of days into a week. Week is picked by first date."  [starting-day-of-week days]  (let [lookup (into {} (map (juxt :date identity) days))  starting-date (start-of-week starting-day-of-week (:date (first days)))  all-days (->> (week-dates starting-date)  (map #(or (get lookup %)  {:date %  :minutes 0})))]  {:starting-day-of-week starting-day-of-week  :date starting-date  :days (vec all-days)  :minutes (sum-minutes all-days)}))  (defn partition-weeks  [starting-day-of-week days]  (->> days  (sort-by :date)  (partition-by #(start-of-week starting-day-of-week (:date %)))))  (defn days->weeks  "Convert a seq of days into an ordered seq of weeks."  [starting-day-of-week days]  (->> (partition-weeks starting-day-of-week days)  (map (partial days->week starting-day-of-week))))   (comment  (->> (week-04/log-times "time-log.txt")  (entries->days))   (->> (week-04/log-times "time-log.txt")  (entries->days)  (days->weeks :sunday))  )
  continue reading

118 episodes

All episodes

×
 
Loading …

Welcome to Player FM!

Player FM is scanning the web for high-quality podcasts for you to enjoy right now. It's the best podcast app and works on Android, iPhone, and the web. Signup to sync subscriptions across devices.

 

Quick Reference Guide