summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThanos Apollo <[email protected]>2024-01-16 09:57:13 +0200
committerThanos Apollo <[email protected]>2024-01-16 09:57:13 +0200
commit0b76877a49348e211a3ce49147f55a0eb11dea7d (patch)
tree97a3c1e67e1e04529fa1d1142b0fa6d79be67f41
parent8ca53e1a0e7f1cde295b2aab29893439be07a89a (diff)
parent70b1af5810b8c13afc61508d82163c172bfce047 (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.md95
-rw-r--r--gnosis-algorithm.el14
-rw-r--r--gnosis.el15
3 files changed, 109 insertions, 15 deletions
diff --git a/README.md b/README.md
index bacb41d..cb2cb5e 100644
--- a/README.md
+++ b/README.md
@@ -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))))))
diff --git a/gnosis.el b/gnosis.el
index f58e851..a3f9ca0 100644
--- a/gnosis.el
+++ b/gnosis.el
@@ -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)