tvl-depot/configs/shared/.emacs.d/wpc/me-seconds.el

246 lines
7.6 KiB
EmacsLisp
Raw Normal View History

;;; 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