diff options
-rw-r--r-- | doc/gnosis.info | 53 | ||||
-rw-r--r-- | doc/gnosis.org | 11 | ||||
-rw-r--r-- | doc/gnosis.texi | 15 | ||||
-rw-r--r-- | gnosis-algorithm.el | 38 | ||||
-rw-r--r-- | gnosis-test.el | 30 | ||||
-rw-r--r-- | gnosis.el | 37 |
6 files changed, 112 insertions, 72 deletions
diff --git a/doc/gnosis.info b/doc/gnosis.info index a96d4c1..712033c 100644 --- a/doc/gnosis.info +++ b/doc/gnosis.info @@ -50,6 +50,7 @@ Customization & Extension * Adjust string comparison:: * Creating Custom Note Types:: * Customizing Gnosis Algorithm:: +* Auto push changes:: Customizing Gnosis Algorithm @@ -276,6 +277,7 @@ enter ‘n’ (no) at the prompt "Start development env?" * Adjust string comparison:: * Creating Custom Note Types:: * Customizing Gnosis Algorithm:: +* Auto push changes:: File: gnosis.info, Node: Adjust string comparison, Next: Creating Custom Note Types, Up: Customization & Extension @@ -331,7 +333,7 @@ should be done. ‘gnosis-display’ functions -File: gnosis.info, Node: Customizing Gnosis Algorithm, Prev: Creating Custom Note Types, Up: Customization & Extension +File: gnosis.info, Node: Customizing Gnosis Algorithm, Next: Auto push changes, Prev: Creating Custom Note Types, Up: Customization & Extension 5.3 Customizing Gnosis Algorithm ================================ @@ -404,28 +406,41 @@ by being multiplied with last interval. 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 + +File: gnosis.info, Node: Auto push changes, Prev: Customizing Gnosis Algorithm, Up: Customization & Extension + +5.4 Auto push changes +===================== + +When setting ‘gnosis-auto-push’ to ‘t’, at the end of every review +session the changes to ‘gnosis-db’ will be pushed to the pre-configured +push remote. You have to set your push remote manually. + + (setf gnosis-auto-push t) + Tag Table: Node: Top246 -Node: Introduction1397 -Node: Installation1877 -Node: Using straightel2246 -Node: Installing manually from source2758 -Node: Adding notes3447 -Node: Note Types4863 -Node: Cloze5087 -Node: Basic Type6060 -Node: Double6338 -Node: MCQ (Multiple Choice Question)6684 -Node: y-or-n7093 -Node: Customization & Extension7519 -Node: Adjust string comparison8223 -Node: Creating Custom Note Types9019 -Node: Customizing Gnosis Algorithm10154 -Node: Gnosis Algorithm Initial Interval10470 -Node: Gnosis Algorithm Easiness Factor11061 -Node: Gnosis Algorithm Forgetting Factor12065 +Node: Introduction1419 +Node: Installation1899 +Node: Using straightel2268 +Node: Installing manually from source2780 +Node: Adding notes3469 +Node: Note Types4885 +Node: Cloze5109 +Node: Basic Type6082 +Node: Double6360 +Node: MCQ (Multiple Choice Question)6706 +Node: y-or-n7115 +Node: Customization & Extension7541 +Node: Adjust string comparison8267 +Node: Creating Custom Note Types9063 +Node: Customizing Gnosis Algorithm10198 +Node: Gnosis Algorithm Initial Interval10540 +Node: Gnosis Algorithm Easiness Factor11131 +Node: Gnosis Algorithm Forgetting Factor12135 +Node: Auto push changes12713 End Tag Table diff --git a/doc/gnosis.org b/doc/gnosis.org index 29c4188..c2ffcf1 100644 --- a/doc/gnosis.org +++ b/doc/gnosis.org @@ -291,3 +291,14 @@ Example: 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 + + +** Auto push changes +When setting =gnosis-auto-push= to =t=, at the end of every review +session the changes to ~gnosis-db~ will be pushed to the pre-configured +push remote. You have to set your push remote manually. + +#+begin_src emacs-lisp +(setf gnosis-auto-push t) +#+end_src + diff --git a/doc/gnosis.texi b/doc/gnosis.texi index f2762af..efb9e18 100644 --- a/doc/gnosis.texi +++ b/doc/gnosis.texi @@ -76,6 +76,7 @@ Customization & Extension * Adjust string comparison:: * Creating Custom Note Types:: * Customizing Gnosis Algorithm:: +* Auto push changes:: Customizing Gnosis Algorithm @@ -288,6 +289,7 @@ enter @samp{n} (no) at the prompt ``Start development env?'' * Adjust string comparison:: * Creating Custom Note Types:: * Customizing Gnosis Algorithm:: +* Auto push changes:: @end menu @node Adjust string comparison @@ -420,4 +422,15 @@ Example: 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 -@bye
\ No newline at end of file +@node Auto push changes +@section Auto push changes + +When setting @samp{gnosis-auto-push} to @samp{t}, at the end of every review +session the changes to @code{gnosis-db} will be pushed to the pre-configured +push remote. You have to set your push remote manually. + +@lisp +(setf gnosis-auto-push t) +@end lisp + +@bye diff --git a/gnosis-algorithm.el b/gnosis-algorithm.el index c10d9c9..9117ad9 100644 --- a/gnosis-algorithm.el +++ b/gnosis-algorithm.el @@ -84,16 +84,12 @@ The structure of the given date is (YEAR MONTH DAY)." (- (time-to-days (current-time)) (time-to-days given-date)))) -(defun gnosis-algorithm-e-factor (ef quality) - "Calculate new e-factor given existing EF and binary QUALITY, 0 or 1." - (cond - ((not (numberp quality)) - (error "Invalid argument passed to gnosis-algorithm-e-factor")) - ((= quality 0) ;; If the quality score is 0 (fail), decrease the ef by a small penalty - (max 1.3 (- ef (cadr gnosis-algorithm-ef)))) - ((= quality 1) ;; If the quality score is 1 (pass), increase the ef by a small reward - (+ ef (car gnosis-algorithm-ef))) - (t (error "Invalid quality score passed to gnosis-algorithm-e-factor")))) + +(defun gnosis-algorithm-e-factor (ef success) + "Calculate the new e-factor given existing EF and SUCCESS, either t or nil." + (pcase success + (`t (+ ef (car gnosis-algorithm-ef))) + (`nil (max 1.3 (- ef (cadr gnosis-algorithm-ef)))))) (cl-defun gnosis-algorithm-next-interval (&key last-interval review-num ef success failure-factor successful-reviews successful-reviews-c fails-c fails-t initial-interval) @@ -114,8 +110,6 @@ Returns a list of: (INTERVAL N EF) where, - Next review date in (yyyy mm dd) format. - REVIEW-NUM: Incremented by 1. - 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")) @@ -128,23 +122,21 @@ Returns a list of: (INTERVAL N EF) where, ;; thus ignore initial intervals (interval (cond + ;; TODO: Rewrite this! ;; First successful review -> first interval - ((and (= successful-reviews 0) - (= success 1)) - (car initial-interval)) + ((and (= successful-reviews 0) success + (car initial-interval))) ;; Second successful review -> second interval - ((and (= successful-reviews 1) - (= success 1) - (= fails-c 0)) + ((and (= successful-reviews 1) success) (cadr initial-interval)) ;; When successful-reviews-c is above 3, use 150% or 180% ;; of ef depending on the value of successful-reviews - ((and (= success 1) + ((and success (>= successful-reviews-c 3) (>= review-num 5) (> last-interval 1)) (* (* ef (if (>= successful-reviews 10) 1.8 1.5)) last-interval)) - ((and (= success 0) + ((and (equal success nil) (> fails-c 3) (>= review-num 5) (> last-interval 1)) @@ -152,10 +144,10 @@ Returns a list of: (INTERVAL N EF) where, ;; failure-factor depending on the value of total failed ;; reviews. (* (max (min 0.8 (* failure-factor (if (>= fails-t 10) 1.8 1.5))) - failure-factor) - last-interval)) + failure-factor) + last-interval)) ;; For everything else - (t (if (= success 1) + (t (if success (* ef last-interval) (* failure-factor last-interval)))))) (list (gnosis-algorithm-date (round interval)) next-ef))) diff --git a/gnosis-test.el b/gnosis-test.el index 854cb50..c168e25 100644 --- a/gnosis-test.el +++ b/gnosis-test.el @@ -1,4 +1,4 @@ -;;; gnosis-algorithm.el --- Gnosis development tools -*- lexical-binding: t; -*- +;;; gnosis-algorithm.el --- Gnosis testing module -*- lexical-binding: t; -*- ;; Copyright (C) 2023 Thanos Apollo @@ -24,19 +24,19 @@ ;;; Commentary: -;; Development module for gnosis, to make development of gnosis.el +;; Development module for gnosis, make testing of gnosis ;; easier by creating a testing environment with random inputs. ;;; Code: (require 'gnosis) -(defvar gnosis-dev-tags '("anatomy" "thoracic" "serratus-anterior" +(defvar gnosis-test-tags '("anatomy" "thoracic" "serratus-anterior" "biochemistry" "informatics" "amino-acids" "microbiology" "gram-positive" "gram-negative" "fungi" "parasites")) -(defun gnosis-dev-random-items (list x) +(defun gnosis-test-random-items (list x) "Select X random items from LIST." (let ((shuffled-list (copy-sequence list)) selected-items) @@ -47,7 +47,7 @@ (setq shuffled-list (append (butlast shuffled-list index) (nthcdr (1+ index) shuffled-list))))) selected-items)) -(defun gnosis-dev-add-fields (&optional num deck) +(defun gnosis-test-add-fields (&optional num deck) "Add random inputs to test. NUM: Number of random inputs to add. @@ -72,7 +72,7 @@ deltoid, the spinal accessory nerve innervates the sternocleidomastoid and trapezius, the dorsal scapular nerve supplies the rhomboid muscles and levator scapulae, and the latissimus dorsi is the muscle supplied by the thoracodorsal nerve." - :tags (gnosis-dev-random-items gnosis-dev-tags 2)))) + :tags (gnosis-test-random-items gnosis-test-tags 2)))) (when (y-or-n-p "Add Basic type questions?") (dotimes (_ num) (gnosis-add-note--basic :deck testing-deck @@ -80,20 +80,20 @@ by the thoracodorsal nerve." :hint "hint" :answer "answer" :extra "extra" - :tags (gnosis-dev-random-items gnosis-dev-tags 2)))) + :tags (gnosis-test-random-items gnosis-test-tags 2)))) (when (y-or-n-p "Add single cloze type?") (dotimes (_ num) (gnosis-add-note--cloze :deck testing-deck :note "this is a {c1:note}" :hint "note" - :tags (gnosis-dev-random-items gnosis-dev-tags 2) + :tags (gnosis-test-random-items gnosis-test-tags 2) :extra "extra"))) (when (y-or-n-p "Add note with multiple clozes?") (dotimes (_ num) (gnosis-add-note--cloze :deck testing-deck :note "this is a {c1:note} with multiple {c1:clozes}" :hint "note" - :tags (gnosis-dev-random-items gnosis-dev-tags 2) + :tags (gnosis-test-random-items gnosis-test-tags 2) :extra "extra"))) (when (y-or-n-p "Add note type y-or-n?") (dotimes (_ num) @@ -102,12 +102,12 @@ by the thoracodorsal nerve." :hint "hint" :answer 110 :extra "extra" - :tags (gnosis-dev-random-items gnosis-dev-tags 2)))))) + :tags (gnosis-test-random-items gnosis-test-tags 2)))))) -(defun gnosis-dev-test () +(defun gnosis-test-start () "Begin/End testing env. -If ask nil, leave development env" +If ask nil, leave testing env" (interactive) (let ((ask (y-or-n-p "Start development env (n for exit)?")) (testing-dir (expand-file-name gnosis-dir "testing"))) @@ -122,7 +122,7 @@ If ask nil, leave development env" (gnosis--drop-table table) (error (message "No %s table to drop." table)))) (gnosis-db-init) - (gnosis-dev-add-fields) + (gnosis-test-add-fields) (message "Adding testing values...") (message "Development env is ready for testing.")) (setf gnosis-db (emacsql-sqlite-open (expand-file-name "gnosis.db" gnosis-dir))) @@ -130,5 +130,5 @@ If ask nil, leave development env" (message "Exited development env.")))) -(provide 'gnosis-dev) -;;; gnosis-dev.el ends here +(provide 'gnosis-test) +;;; gnosis-test.el ends here @@ -5,7 +5,7 @@ ;; Author: Thanos Apollo <[email protected]> ;; Keywords: extensions ;; URL: https://git.thanosapollo.org/gnosis -;; Version: 0.1.5 +;; Version: 0.1.6 ;; Package-Requires: ((emacs "27.2") (compat "29.1.4.2") (emacsql "20240124")) @@ -64,6 +64,11 @@ between two strings to consider them as similar." :type 'integer :group 'gnosis) +(defcustom gnosis-auto-push nil + "Automatically run `git push' at the end of every review session." + :type 'boolean + :group 'gnosis) + (defvar gnosis-images-dir (expand-file-name "images" gnosis-dir) "Gnosis images directory.") @@ -840,7 +845,8 @@ well." (defun gnosis-review--algorithm (id success) "Return next review date & ef for note with value of id ID. -SUCCESS is a binary value, 1 = success, 0 = failure. +SUCCESS is a boolean value, t for success, nil for 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)))) @@ -875,8 +881,8 @@ such as the easiness factor (ef)." (defun gnosis-review-new-ef (id success) "Return new ef for note with value of id ID. -SUCCESS is a binary value, 1 = success, 0 = failure. -Returns a list of the form (ef-increase ef-decrease ef)." +Returns a list of the form (ef-increase ef-decrease ef). +SUCCESS is a boolean value, t for success, nil for failure." (let ((ef (nth 1 (gnosis-review--algorithm id success))) (old-ef (gnosis-get 'ef 'review `(= id ,id)))) (cl-substitute (gnosis-review-round ef) (nth 2 old-ef) old-ef))) @@ -884,15 +890,16 @@ Returns a list of the form (ef-increase ef-decrease ef)." (defun gnosis-review--update (id success) "Update review-log for note with value of id ID. -SUCCESS is a binary value, 1 is for successful review." - (let ((ef (gnosis-review-new-ef id success))) +SUCCESS is a boolean value, t for success, nil for failure." + (let ((ef (gnosis-review-new-ef id success)) + (next-rev (car (gnosis-review--algorithm id success)))) ;; Update review-log (gnosis-update 'review-log `(= last-rev ',(gnosis-algorithm-date)) `(= id ,id)) - (gnosis-update 'review-log `(= next-rev ',(car (gnosis-review--algorithm id success))) `(= id ,id)) + (gnosis-update 'review-log `(= next-rev ',next-rev) `(= id ,id)) (gnosis-update 'review-log `(= n (+ 1 ,(gnosis-get 'n 'review-log `(= id ,id)))) `(= id ,id)) ;; Update review (gnosis-update 'review `(= ef ',ef) `(= id ,id)) - (if (= success 1) + (if success (progn (gnosis-update 'review-log `(= c-success ,(1+ (gnosis-get 'c-success 'review-log `(= id ,id)))) `(= id ,id)) (gnosis-update 'review-log `(= t-success ,(1+ (gnosis-get 't-success 'review-log `(= id ,id)))) `(= id ,id)) (gnosis-update 'review-log `(= c-fails 0) `(= id ,id))) @@ -909,9 +916,9 @@ SUCCESS is a binary value, 1 is for successful review." (user-choice (gnosis-mcq-answer id))) (if (string= answer user-choice) (progn - (gnosis-review--update id 1) + (gnosis-review--update id t) (message "Correct!")) - (gnosis-review--update id 0) + (gnosis-review--update id nil) (message "False")) (gnosis-display-correct-answer-mcq answer user-choice) (gnosis-display-extra id) @@ -927,7 +934,7 @@ SUCCESS is a binary value, 1 is for successful review." (success (gnosis-compare-strings answer user-input))) (gnosis-display-basic-answer answer success user-input) (gnosis-display-extra id) - (gnosis-review--update id (if success 1 0)) + (gnosis-review--update id success) (gnosis-display-next-review id))) (defun gnosis-review-y-or-n (id) @@ -940,7 +947,7 @@ SUCCESS is a binary value, 1 is for successful review." (success (equal answer 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-review--update id success) (gnosis-display-next-review id))) (defun gnosis-review-cloze--input (cloze) @@ -980,10 +987,10 @@ Used to reveal all clozes left with `gnosis-face-cloze-unanswered' face." ;; clozes. (when (< num clozes-num) (gnosis-review-cloze-reveal-unaswered clozes)) (gnosis-display-cloze-user-answer (cdr input)) - (gnosis-review--update id 0) + (gnosis-review--update id nil) (cl-return))) ;; Update note after all clozes are revealed successfully - finally (gnosis-review--update id 1))) + finally (gnosis-review--update id t))) (gnosis-display-extra id) (gnosis-display-next-review id)) @@ -1019,6 +1026,8 @@ NOTE-NUM: The number of notes reviewed in the session." (shell-command (concat git " add " (shell-quote-argument "gnosis.db"))) (shell-command (concat git " commit -m " (shell-quote-argument (concat (format "Total notes for session: %d " note-num))))) + (when gnosis-auto-push + (shell-command (concat git " push"))) (message "Review session finished. %d notes reviewed." note-num))) (defun gnosis-review--session (notes) |