about summary refs log tree commit diff
path: root/emacs/.emacs.d/wpc/me-seconds.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacs/.emacs.d/wpc/me-seconds.el')
-rw-r--r--emacs/.emacs.d/wpc/me-seconds.el245
1 files changed, 245 insertions, 0 deletions
diff --git a/emacs/.emacs.d/wpc/me-seconds.el b/emacs/.emacs.d/wpc/me-seconds.el
new file mode 100644
index 0000000000..f03e5d07d7
--- /dev/null
+++ b/emacs/.emacs.d/wpc/me-seconds.el
@@ -0,0 +1,245 @@
+;;; me-seconds.el --- How valuable is my time? -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Inspired by Google's concept of SWE-seconds, I decided to try and compute how
+;; value my personal time is.
+;;
+;; This library should integrate with another library that handles currency
+;; conversions using locally cached data for historial values and network
+;; requests for current values.
+;;
+;; Context sensitivity:
+;; Many of the values herein are based on my values that are a function of the
+;; year, my current salary, my current company holiday policy, and my current
+;; country holiday policy.  As such, many of these constants need to be updated
+;; whenever changes occur in order for these functions to be useful.
+;;
+;; Units of time:
+;; - seconds
+;; - minutes
+;; - hours
+;; - days
+;; - weeks
+;; - months
+;; - years
+;;
+;; Wish list:
+;; - I should create a money.el struct to work with herein.  This module would
+;;   expose basic algebra for working with money structs, which would be handy.
+;; - I should create a time.el struct for working with hours in the day.  I'd
+;;   like to be able to do (+ 9:15 17:45) cleanly.
+;;
+;; Terminology:
+;; SWE hours give an order of magnitude approximation to the cost of resources
+;; in dollars per hour at 2115 hours per year.
+;; - SWE hour (SWEh)
+;; - SWE year (SWEy)
+;; - SWE nominal
+;; - SWE opportunity
+;;
+;; Other isomorphisms include:
+;; - Borg GCU
+;; - Borg RAM
+;; - Tape (library)
+;; - Tape (vault)
+;; - Spindles (low latency)
+;; - Spindles (throughput)
+;; - Spindles (throughput)
+;; - Tape (throughput)
+;; - SWE (nominal)
+;; - SWE (opportunity)
+
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Dependencies
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'macros)
+(require 'string)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Constants
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun me-seconds/salary (amt)
+  "Return the yearly rate of AMT of money in GBP.
+f :: Integer -> Rate"
+  (make-rate :money (make-money :whole amt :fractional 0 :currency 'GBP)
+             :unit 'year))
+
+(defconst me-seconds/salary (me-seconds/salary 80000)
+  "My salary in GBP.")
+
+;; TODO: Consider changing these into units of time.
+(defconst me-seconds/months-per-year 12
+  "Number of months in a year.")
+
+(defconst me-seconds/days-per-year 365
+  "Number of days in a year.")
+
+(defconst me-seconds/hours-per-year (* 24 me-seconds/days-per-year)
+  "Number of hours in a year.")
+
+(defconst me-seconds/minutes-per-year (* 60 me-seconds/hours-per-year)
+  "Number of minutes in a year.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Vacation
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst me-seconds/bank-holidays-per-year 8
+  "Number of bank holidays in the UK each year.")
+
+(defconst me-seconds/pto-days-vacation-per-year 25
+  "Number of days of paid-time-off I receive each year in the UK.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Sleeping
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst me-seconds/sleeping-hours-per-day 8
+  "An approximation of the number of hours I sleep each night on average.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Waking
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst me-seconds/waking-hours-per-day
+  (- 24 me-seconds/sleeping-hours-per-night)
+  "An approximation of the number of hours I sleep each night on average.")
+
+;; TODO: Adjust this for vacation time.
+(defconst me-seconds/waking-hours-per-year
+  (* me-seconds/waking-hours-per-day me-seconds/days-per-year)
+  "The number of hours that I work each year.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Working
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst me-seconds/working-hours-per-day
+  (- 17 9)
+  "An approximation of the number of hours I work each weekday on average.
+Note that this differs from the assumed SWE hours per day calculation, which
+  assumes 9 working hours.  See the discussion about this of go/rules-of-thumb.")
+
+(defconst me-seconds/working-hours-per-year 2115
+  "This number is borrowed from go/rules-of-thumb.")
+
+;; Keep in mind that the following classifications of time:
+;; - 9:00-17:00 M-F. Is this more expensive than time sleeping?
+;; - Weekend
+;; - Weekday
+;; - Working hours
+;; - Waking hours
+;; - Sleeping hours
+;; - Vacation hours
+;;
+;; TODO: Consider tax implications (i.e. after-tax amounts and pre-tax amounts).
+;;
+;; Should these all be treated the same since they all pull from the same pot of
+;; time? Or perhaps there are multiples involved? Much to think about. How does
+;; Google handle this?
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Library
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Supported currencies:
+;; - GBP
+;; NOTE: Amount is an integer.
+(cl-defstruct money whole fractional currency)
+(cl-defstruct rate money unit)
+
+;; TODO: Add to money.el.
+(defun money/to-string (x)
+  "Return the string representation of X.
+f :: Money -> String"
+  (let ((currency (money-currency x))
+        (whole (int-to-string (money-whole x)))
+        (fract (int-to-string (money-fractional x))))
+    (pcase currency
+      ('GBP (string/concat "£" whole "." fract))
+      ('USD (string/concat "$" whole "." fract))
+      (_ (error (string/concat
+                 "Currency: \""
+                 (symbol-name currency)
+                 "\" not supported"))))))
+
+(macros/comment
+ (money/to-string
+  (make-money :whole 100 :fractional 99 :currency 'GBP)))
+
+;; TODO: Add to rate.el.
+(defun rate/to-string (x)
+  "Message X as a rate.
+f :: Rate -> String"
+  (string/concat
+   (money/to-string (rate-money x))
+   " / "
+   (pcase (rate-unit x)
+     ('second "sec")
+     ('minute "min")
+     ('hour   "hr")
+     ('day    "day")
+     ('week   "week")
+     ('month  "month")
+     ('year   "year"))))
+
+(macros/comment
+ (rate/to-string
+  (make-rate
+   :money (make-money :whole 10 :fractional 10 :currency 'GBP)
+   :unit 'day)))
+
+;; TODO: Move this to math.el?
+(defun ensure-float (x)
+  "Ensures X is treated as a float."
+  (+ 0.0 x))
+
+;; TODO: Move these to basic time mapping module.
+;; TODO: Consider making this an isomorphism.
+(defun minutes/to-hours (x)
+  "Convert X minutes to n hours."
+  (/ x 60.0))
+
+(defun hours/to-minutes (x)
+  "Convert X hours to n minutes."
+  (* x 60))
+
+(defun days/to-minutes (x)
+  "Convert X days to n minutes."
+  (* x 24 60))
+
+(defun weeks/to-minutes (x)
+  "Convert X weeks to n minutes."
+  (* x 7 24 60))
+
+(defun months/to-minutes (x)
+  "Convert X months to n minutes.
+This approximates the number of days in a month to 30."
+  (* x 30 24 60))
+
+;; TODO: Support algebraic functions with money structs.
+;; TODO: Support isomorphisms for rates to other units of time.  That would
+;; subsume most of this module's use.
+(defun me-seconds/value-per-minute (salary)
+  "Computes my value per minute based on my current SALARY.
+Signature: f :: Rate -> Rate
+This is assuming that all of my time is equally valuable.  See the above
+  discussion about the various classifications of my time.")
+
+;; TODO: See note above about isomorphisms between various rates.
+(defun me-seconds/value (salary x)
+  "Compute the value of X minutes of my time at my current SALARY.
+f :: Rate -> Integer -> Money")
+
+(macros/comment
+ (rate/to-string me-seconds/salary)
+ )
+
+(provide 'me-seconds)
+;;; me-seconds.el ends here