diff options
author | Thanos Apollo <[email protected]> | 2024-01-16 09:57:13 +0200 |
---|---|---|
committer | Thanos Apollo <[email protected]> | 2024-01-16 09:57:13 +0200 |
commit | 0b76877a49348e211a3ce49147f55a0eb11dea7d (patch) | |
tree | 97a3c1e67e1e04529fa1d1142b0fa6d79be67f41 | |
parent | 8ca53e1a0e7f1cde295b2aab29893439be07a89a (diff) | |
parent | 70b1af5810b8c13afc61508d82163c172bfce047 (diff) |
Merge branch 'version-0.1.1' into master
- Fix bug for multiple clozes review
- Fix gnosis-review-y-or-n for new inputs
- Update gnosis-algorithm implementation
- Fix minor bugs on gnosis-algorithm
Reviews for all note types should work fine with this version
-rw-r--r-- | README.md | 95 | ||||
-rw-r--r-- | gnosis-algorithm.el | 14 | ||||
-rw-r--r-- | gnosis.el | 15 |
3 files changed, 109 insertions, 15 deletions
@@ -1,12 +1,25 @@ -# Gnosis +# Gnosis (γνῶσις) ## About -*Gnosis is currently under development* -Gnosis is a [Spaced -Repetition](https://en.wikipedia.org/wiki/Spaced_repetition) package -for GNU Emacs. +Gnosis (γνῶσις), pronounced "noh-sis", meaning knowledge in Greek, is +a [Spaced Repetition](https://en.wikipedia.org/wiki/Spaced_repetition) +package for GNU Emacs. + +### Differences with other SRS +Gnosis does not implement flashcard type review sessions where the +user rates his own answer on an arbitrary scale. Instead implements +"note" types that require user input. Some of these note types, like +the `MCQ` *multiple choice question*, even allow for simulating +real-life exams. + +Unlike other SRS implementations for GNU Emacs that rely on +`org-mode`, which I've found not an ideal option for a database +replacement. Instead utilizes an +[sqlite](https://www.sqlite.org/index.html) database, thanks to +[emacsql](https://github.com/magit/emacsql), enabling efficient data +management and manipulation. ## Installation ### Straight.el @@ -29,3 +42,75 @@ $ git clone https://git.thanosapollo.org/gnosis (load-file "~/path/to/gnosis.el") (require 'gnosis) ``` + + +## Adding notes + +Creating notes for gnosis can be done with a simple +`M-x gnosis-add-note` + + +Everything is done through the mini-buffer. My personal workflow takes +advantage of that by not really leaving `gnosis-add-note` prompt until +I finish studying a chapter/section, using +[pdf-tools](https://github.com/vedang/pdf-tools "Emacs pdf-tools") or +[nov.el](https://depp.brause.cc/nov.el/ "Emacs nov.el"). + +### Creating cloze type notes +Cloze type note questions are formatted similarly to Anki's syntax, like so: +> {c1:Cyproheptadine} is a(n) {c2:5-HT2} receptor antagonist used to treat {c2:serotonin syndrome} + + +*NOTE*: You can also format clozes like Anki if you so prefer; e.g +`{{c1::Cyproheptadine}}` + ++ For each `cX`-tag there will be created a cloze type note, the above + example creates 2 cloze type notes. + ++ Each `cX` tag can have multiple clozes, but each cloze must be a + *UNIQUE* word (or a unique combination of words) in given note. + +## Customizing gnosis algorithm + +### `gnosis-algorithm-interval` + +This is a list of 2 numbers, for the first 2 intervals after a +successful review. For example: + +``` emacs-lisp +(setq gnosis-algorithm-interval '(1 3)) +``` + +After first successfully reviewing a note, you will see it again +tomorrow, if you successfully review said note again, the next review +will be after 3 days. + +### `gnosis-algorithm-ef` + +This is gnosis "easiness factor", it's basically a list that consists +of 3 items. The first item is the increase factor, used to increase +the easiness factor upon successful review. Second item refers to the +decrease factor, used to decrease the easiness factor upon an +unsuccessful review. The third item is the initial total easiness +factor, used to calculate the next interval. + +The basic's of how this is used is that it's being multiplied with the +last interval, e.g if you last reviewed a note 6 days ago, and the +easiness factor of this note is 2.0, your next interval would be 6 * +2.0. The next easiness will be 2.0 + increase-factor as well. + +For example: + +``` emacs-lisp +(setq gnosis-algorithm-ef '(0.3 0.3 1.3)) +``` + +### `gnsois-algorithm-ff` + +This is the value of gnosis forgetting factor(ff), it needs to be a floating number below 1. The 101 is that it's used to calculate the next interval upon an unsuccessful review, by being multiplied with last interval, if for a note with a value of last-interval of 6 days and a ff of 0.5, upon an unsuccessful review the next interval will be 6 * 0.5 + +For example: + +``` emacs-lisp +(setq gnosis-algorithm-ff 0.5) +``` diff --git a/gnosis-algorithm.el b/gnosis-algorithm.el index 4107b8a..2dcd33d 100644 --- a/gnosis-algorithm.el +++ b/gnosis-algorithm.el @@ -58,7 +58,9 @@ it below 2.0" (defcustom gnosis-algorithm-ff 0.5 "Gnosis forgetting factor. -Used to calcuate new interval for failed questions." +Used to calcuate new interval for failed questions. + +NOTE: Do not change this value above 1" :group 'gnosis :type 'float) @@ -115,6 +117,11 @@ Returns a tuple: (INTERVAL N EF) where, - EF : Modified based on the recall success for the item." (cl-assert (and (>= success 0) (<= success 1))) + ;; Check if gnosis-algorithm-ff is lower than 1 & is total-ef above 1.3 + (cond ((>= gnosis-algorithm-ff 1) + (error "Value of `gnosis-algorithm-ff' must be lower than 1")) + ((< (nth 2 gnosis-algorithm-ef) 1.3) + (error "Value of total-ef from `gnosis-algorithm-ef' must be above 1.3"))) ;; Calculate the next easiness factor. (let* ((next-ef (gnosis-algorithm-e-factor ef success)) ;; Calculate the next interval. @@ -123,13 +130,13 @@ Returns a tuple: (INTERVAL N EF) where, (interval (cond ;; First successful review -> first interval - ((and (= successful-reviews 1) + ((and (= successful-reviews 0) (= success 1) (< n 10) (< ef 3.0)) (car gnosis-algorithm-interval)) ;; Second successful review -> second interval - ((and (= successful-reviews 2) + ((and (= successful-reviews 1) (< n 10) (= success 1) (< ef 3.0)) @@ -138,6 +145,7 @@ Returns a tuple: (INTERVAL N EF) where, ((and (= last-interval 0) (= success 1)) (* ef 1)) + ;; For everything else (t (if (= success 1) (* ef last-interval) (* ff last-interval)))))) @@ -850,10 +850,10 @@ SUCCESS is a binary value, 1 = success, 0 = failure. Returns a list of the form ((yyyy mm dd) ef)." (let ((ff gnosis-algorithm-ff) (ef (nth 2 (gnosis-get 'ef 'review `(= id ,id)))) - (c-success (gnosis-get 'c-success 'review-log `(= id ,id)))) + (t-success (gnosis-get 't-success 'review-log `(= id ,id)))) (gnosis-algorithm-next-interval (gnosis-review--get-offset id) (gnosis-get 'n 'review-log `(= id ,id)) - ef success ff c-success))) + ef success ff t-success))) (defun gnosis-review-due-notes--with-tags () "Return a list of due note tags." @@ -933,7 +933,7 @@ SUCCESS is a binary value, 1 is for successful review." (gnosis-review--update id (if success 1 0)) (gnosis-display--next-review id))) -(defun gnosis-review-y-or-p (id) +(defun gnosis-review-y-or-n (id) "Review y-or-n type note for ID." (gnosis-display--image id) (gnosis-display--question id) @@ -941,7 +941,7 @@ SUCCESS is a binary value, 1 is for successful review." (let* ((answer (gnosis-get 'answer 'notes `(= id ,id))) (user-input (read-char-choice "[y]es or [n]o: " '(?y ?n))) (success (equal answer user-input))) - (gnosis-display-y-or-n-answer :answer answer :success success :user-input user-input) + (gnosis-display-y-or-n-answer :answer answer :success success) (gnosis-display--extra id) (gnosis-review--update id (if success 1 0)) (gnosis-display--next-review id))) @@ -975,7 +975,6 @@ Used to reveal all clozes left with `gnosis-face-cloze-unanswered' face." (if (equal (car input) t) ;; Reveal only one cloze (progn (gnosis-display-cloze-reveal :replace cloze) - (gnosis-review--update id 1) (setf num (1+ num))) ;; Reveal cloze for wrong input, with `gnosis-face-false' (gnosis-display-cloze-reveal :replace cloze :success nil) @@ -985,7 +984,9 @@ Used to reveal all clozes left with `gnosis-face-cloze-unanswered' face." (when (< num clozes-num) (gnosis-review-cloze-reveal-unaswered clozes)) (gnosis-display-cloze-user-answer (cdr input)) (gnosis-review--update id 0) - (cl-return))))) + (cl-return))) + ;; Update note after all clozes are revealed successfully + finally (gnosis-review--update id 1))) (gnosis-display--extra id) (gnosis-display--next-review id)) @@ -999,7 +1000,7 @@ Used to reveal all clozes left with `gnosis-face-cloze-unanswered' face." ("mcq" (gnosis-review-mcq id)) ("basic" (gnosis-review-basic id)) ("cloze" (gnosis-review-cloze id)) - ("y-or-n" (gnosis-review-y-or-p id)) + ("y-or-n" (gnosis-review-y-or-n id)) (_ (error "Malformed note type"))))))) (defun gnosis-review-commit (note-num) |