The Complete Computing Environment

Spaced Repetition Study

LifeTechEmacsTopicsArcology

flashcard based learning, a Knowledge Management system designed around the idea that recall is best solidified if it's done as close to forgetting as possible.

Spaced repetition is an evidence-based learning technique that is usually performed with flashcards. Newly introduced and more difficult flashcards are shown more frequently while older and less difficult flashcards are shown less frequently in order to exploit the psychological spacing effect. The use of spaced repetition has been shown to increase rate of learning.

Anki is the go-to digital solution for general study these days, but I'd have to extract cards from my notes, and I would rather not. I used org-contrib's org-drill for a while but it didn't scale to many files in the org-roam paradigm very well. I used Wani Kani for a bit too but syncing my score between local cards and what is in Wani Kani; once I started making cards from my own readings things kind of went off course and even though I have a lifetime subscription to it. It's a good tool, but without making custom cards for it it sort of falls short.

So these days I use a piece of software called org-fc which uses awk and find to generate an index across all files and stores the scores in a drawer alongside each heading. It's not MELPA so it's a bit of a "sleeper hit", but I use it across my Knowledge Base and Japanese Study but also in things like Tokipona.

(provide 'cce/org-fc)
(use-package org-fc
  :ensure t
  :custom
  (org-fc-directories '("~/org/"))
  (org-fc-review-history-file (expand-file-name "~/org/org-fc-reviews.tsv"))
  (org-fc-shuffle-positions nil)
  <<org-fc-contexts>>
  :config
  (require 'org-fc-hydra)
  (defalias 'srs #'org-fc-dashboard)

  <<org-fc-customization>>

  (evil-define-minor-mode-key '(normal insert emacs) 'org-fc-review-flip-mode
    (kbd "RET") 'org-fc-review-flip
    (kbd "n") 'org-fc-review-flip
    (kbd "s") 'org-fc-review-suspend-card
    (kbd "q") 'org-fc-review-quit)

  (evil-define-minor-mode-key '(normal insert emacs) 'org-fc-review-rate-mode
    (kbd "a") 'org-fc-review-rate-again
    (kbd "h") 'org-fc-review-rate-hard
    (kbd "g") 'org-fc-review-rate-good
    (kbd "e") 'org-fc-review-rate-easy
    (kbd "s") 'org-fc-review-suspend-card
    (kbd "q") 'org-fc-review-quit))

Since it's not in MELPA, I have to package it myself. This gets crammed in overrides to be in the epkgs "index" in Arroyo Emacs definition:

org-fc = let
  versions = pkgs.lib.pkgVersions;
in epkgs.melpaBuild {
  pname = "org-fc";
  version = "20220823.2107";
  commit = versions.org-fc.rev;

  src = pkgs.callPackage versions.org-fc.src {};

  recipe = pkgs.writeText "recipe" ''
    (org-fc
     :files (:defaults "awk")
     :repo "l3kn/org-fc"
     :fetcher github)
  '';

  packageRequires = [ pkgs.gawk epkgs.hydra pkgs.findutils ];

  meta = {
    homepage = "https://www.leonrische.me/fc/index.html";
    license = lib.licenses.gpl3Plus;
  };
};

This probably doesn't need to be hereā€¦, but why not

{ pkgs, ... }:

{
  home.packages = with pkgs; [ findutils gawk ];
}

Some Custom SRS contexts

Sometimes it's nice to focus on one thing at a time. org-fc gives us custom contexts and here's how I use it:

(setq org-tags-exclude-from-inheritance '("kanji" "jokugo"))
(setq org-fc-custom-contexts
      '((japanese . (:filter (and (tag "japanese")
                                  (tag "vocabulary"))))
        (buddhism . (:filter (and (not (tag "vocabulary"))
                                  (tag "Buddhism"))))
        (trivia . (:filter (tag "trivia")))
        (kanji . (:filter (or (tag "jokugo") (tag "kanji"))))
        (poetry . (:filter (tag "poem")))
        (tokipona . (:filter (tag "tokipona")))
        (row . (:filter (and
                         (not (tag "Buddhism"))
                         (not (tag "vocabulary")))))))

Some org-fc hacks

I have a node_modules directory with a Node package used for some of my Literate Programming shenanigans and it includes a directory with a .org suffix. This modifies the find command to exclude those.

(defun org-fc-awk--find (paths)
  "Generate shell code to search PATHS for org files.
Matches all .org files ignoring ones with names don't start with
a '.' to exclude temporary / backup files.
With the '-L' option, 'find' follows symlinks."
  (format
   "find -L %s -type f -name \"*.org\" -not -name \".*\" -print0"
   (mapconcat
    (lambda (path) (shell-quote-argument (expand-file-name path)))
    paths " ")))

I add a customization option which allows me to do my reviews in smaller bursts. it makes it easier to come back to things which I have forgotten; if i have a stack I haven't touched in Too Long, it'll take a really long time to retain because i will get through 40 or 80 or them and the ones i have to repeat will be at the bottom of the pile. Adjusting this down lets me get through my stacks faster.

(defcustom org-fc-review-count 30
  "if numeric, truncate reviews to this many positions")

(defun org-fc--truncate-reviews (oldfn &rest args)
  (take org-fc-review-count (apply oldfn args)))
(advice-add 'org-fc-index-positions :around 'org-fc--truncate-reviews)

Cards to Add

NEXT [#A] PNW Trees

NEXT [#A] PNW birds

NEXT [#A] PNW native plants

NEXT [#B] iNaturalist observations

NEXT take better notes