Rudolf Adamkovič Personal site


Exercise log

… is modeled as the function

\[\begin{equation*}
  f : D \to T,
\end{equation*}
\]
where\(d \in D\)is the exercise day,
measured in \(24\)-hour days from the Unix epoch; and
\(t > 0 \in T\)is the total exercise duration on day \(d\),
measured in seconds.

\(f\) is computed, as a hash table, from Org Clock data by

(defun my-exercise-log ()
  "Return a hash map with exercise durations per day."
  (let ((lexical-binding t))
    (save-excursion
      (org-id-goto my-exercise-id)
      (goto-char (org-log-beginning))
      (named-let recur ((days (make-hash-table :test 'equal)))
        (let ((element (org-element-at-point-no-context)))
          (if (eq 'clock (org-element-type element))
              (let* ((day (org-element-property :value element))
                     (day (org-format-timestamp day "%s"))
                     (day (string-to-number day))
                     (day (/ (float day) 60 60 24))
                     (time (org-element-property :duration element))
                     (time (org-duration-to-minutes time))
                     (time (* time 60)))
                (puthash day (+ (gethash day days 0) time) days)
                (org-forward-element)
                (recur days))
            days))))))

where the ‘my-exercise-id’ is

(defcustom my-exercise-id "0DB14413-C66D-41F6-A6C0-17F433F0B740"
  "ID of the Org heading on which all exercises are clocked.")

Total exercise days

… is the total count of exercise days

\[\begin{equation*}
  \sum_{d \in D} 1 = |D| = \boxed{564} ~ \text{days} \thinspace,
\end{equation*}
\]

computed by

(defun my-total-exercise-days ()
  (hash-table-count (my-exercise-log)))

Total exercise duration

… is the sum of all exercise durations

\[\begin{equation*}
  \frac{\sum_{d \in D} f(d)}{60 \cdot 60}
  \approx
  \boxed{409.03} \, \text{hours},
\end{equation*}
\]

computed by

(defun my-total-exercise-hours ()
  "Return the sum of all exercise durations in hours."
  (format "%0.2f"
          (/ (let ((total-duration 0))
               (maphash (lambda (day duration)
                          (setq total-duration
                                (+ total-duration duration)))
                        (my-exercise-log))
               total-duration)
             (* 60 60))))

Average exercise duration

… is the artihmetic mean of all exercise durations

\[\begin{equation*}
  \frac{\sum_{d \in D} f(d)}{60 \thinspace |D|}
  \approx
  \boxed{43.51} \, \text{minutes},
\end{equation*}
\]

computed by

(defun my-average-exercise-duration ()
  "Return the average exercise duration in minutes."
  (let ((log (my-exercise-log)))
    (format "%0.2f"
            (/ (let ((total-duration 0))
                 (maphash (lambda (day duration)
                            (setq total-duration
                                  (+ total-duration duration)))
                          log)
                 total-duration)
               (* 60 (hash-table-count log))))))

Exercise anniversary

… is derived from the earliest exercise day

\[\begin{equation*}
  \min D \approx 19386.958333333332
  = \underbrace{\> \text{2023-01-30} \>}
  _{\substack{\text{ISO 8601} \\ \text{date}}}
\end{equation*}
\]

computed by

(defun my-exercise-anniversary-date ()
  (format-time-string "%Y-%m-%d"
                      (* (my-exercise-anniversary)
                         24 60 60)))
(defun my-exercise-anniversary ()
  (let ((anniversary nil))
    (maphash (lambda (day _)
               (when (or (not anniversary)
                         (< day anniversary))
                 (setq anniversary day)))
             (my-exercise-log))
    anniversary))

The Org Agenda anniversary is computed by

(defun my-exercise-org-anniversary ()
  (interactive)
  (format (concat "%%%%(org-anniversary %s)"
                  " /me starts exercising, %%d year(s) ago")
          (format-time-string "%Y %m %d"
                              (* (my-exercise-anniversary)
                                 24 60 60))))


© 2024 Rudolf Adamkovič under GNU General Public License version 3.
Made with Emacs and secret alien technologies of yesteryear.