Moving all of my Emacs-related files into their own directory at the root of this repository.
		
			
				
	
	
		
			245 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
			
		
		
	
	
			245 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
;;; 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
 |