Updated contrib/org-drill.el to latest version (2.3.5)

This commit is contained in:
Paul Sexton 2011-07-01 09:24:11 +12:00
parent 934aae8812
commit d6fb52e157
1 changed files with 144 additions and 42 deletions

View File

@ -2,7 +2,7 @@
;;; org-drill.el - Self-testing using spaced repetition ;;; org-drill.el - Self-testing using spaced repetition
;;; ;;;
;;; Author: Paul Sexton <eeeickythump@gmail.com> ;;; Author: Paul Sexton <eeeickythump@gmail.com>
;;; Version: 2.3.3 ;;; Version: 2.3.5
;;; Repository at http://bitbucket.org/eeeickythump/org-drill/ ;;; Repository at http://bitbucket.org/eeeickythump/org-drill/
;;; ;;;
;;; ;;;
@ -307,6 +307,15 @@ pace of learning."
:type 'sexp) :type 'sexp)
(defcustom org-drill-sm5-initial-interval
4.0
"In the SM5 algorithm, the initial interval after the first
successful presentation of an item is always 4 days. If you wish to change
this, you can do so here."
:group 'org-drill
:type 'float)
(defcustom org-drill-add-random-noise-to-intervals-p (defcustom org-drill-add-random-noise-to-intervals-p
nil nil
"If true, the number of days until an item's next repetition "If true, the number of days until an item's next repetition
@ -334,6 +343,27 @@ is used."
:type 'boolean) :type 'boolean)
(defcustom org-drill-cloze-text-weight
4
"For card types 'hide1_firstmore', 'show1_lastmore' and 'show1_firstless',
this number determines how often the 'less favoured' situation
should arise. It will occur 1 in every N trials, where N is the
value of the variable.
For example, with the hide1_firstmore card type, the first piece
of clozed text should be hidden more often than the other
pieces. If this variable is set to 4 (default), the first item
will only be shown 25% of the time (1 in 4 trials). Similarly for
show1_lastmore, the last item will be shown 75% of the time, and
for show1_firstless, the first item would only be shown 25% of the
time.
If the value of this variable is NIL, then weighting is disabled, and
all weighted card types are treated as their unweighted equivalents."
:group 'org-drill
:type '(choice integer (const nil)))
(defcustom org-drill-cram-hours (defcustom org-drill-cram-hours
12 12
"When in cram mode, items are considered due for review if "When in cram mode, items are considered due for review if
@ -436,6 +466,7 @@ for review unless they were already reviewed in the recent past?")
(put 'org-drill-hide-item-headings-p 'safe-local-variable 'booleanp) (put 'org-drill-hide-item-headings-p 'safe-local-variable 'booleanp)
(put 'org-drill-spaced-repetition-algorithm 'safe-local-variable (put 'org-drill-spaced-repetition-algorithm 'safe-local-variable
'(lambda (val) (memq val '(simple8 sm5 sm2)))) '(lambda (val) (memq val '(simple8 sm5 sm2))))
(put 'org-drill-sm5-initial-interval 'safe-local-variable 'floatp)
(put 'org-drill-add-random-noise-to-intervals-p 'safe-local-variable 'booleanp) (put 'org-drill-add-random-noise-to-intervals-p 'safe-local-variable 'booleanp)
(put 'org-drill-adjust-intervals-for-early-and-late-repetitions-p (put 'org-drill-adjust-intervals-for-early-and-late-repetitions-p
'safe-local-variable 'booleanp) 'safe-local-variable 'booleanp)
@ -446,6 +477,8 @@ for review unless they were already reviewed in the recent past?")
(put 'org-drill-scope 'safe-local-variable (put 'org-drill-scope 'safe-local-variable
'(lambda (val) (or (symbolp val) (listp val)))) '(lambda (val) (or (symbolp val) (listp val))))
(put 'org-drill-save-buffers-after-drill-sessions-p 'safe-local-variable 'booleanp) (put 'org-drill-save-buffers-after-drill-sessions-p 'safe-local-variable 'booleanp)
(put 'org-drill-cloze-text-weight 'safe-local-variable
'(lambda (val) (or (null val) (integerp val))))
;;;; Utilities ================================================================ ;;;; Utilities ================================================================
@ -891,9 +924,23 @@ Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), wher
;;; SM5 Algorithm ============================================================= ;;; SM5 Algorithm =============================================================
(defun initial-optimal-factor-sm5 (n ef)
(if (= 1 n)
org-drill-sm5-initial-interval
ef))
(defun get-optimal-factor-sm5 (n ef of-matrix)
(let ((factors (assoc n of-matrix)))
(or (and factors
(let ((ef-of (assoc ef (cdr factors))))
(and ef-of (cdr ef-of))))
(initial-optimal-factor-sm5 n ef))))
(defun inter-repetition-interval-sm5 (last-interval n ef &optional of-matrix) (defun inter-repetition-interval-sm5 (last-interval n ef &optional of-matrix)
(let ((of (get-optimal-factor n ef (or of-matrix (let ((of (get-optimal-factor-sm5 n ef (or of-matrix
org-drill-optimal-factor-matrix)))) org-drill-optimal-factor-matrix))))
(if (= 1 n) (if (= 1 n)
of of
(* of last-interval)))) (* of last-interval))))
@ -917,20 +964,20 @@ Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), wher
(let ((next-ef (modify-e-factor ef quality)) (let ((next-ef (modify-e-factor ef quality))
(old-ef ef) (old-ef ef)
(new-of (modify-of (get-optimal-factor n ef of-matrix) (new-of (modify-of (get-optimal-factor-sm5 n ef of-matrix)
quality org-drill-learn-fraction)) quality org-drill-learn-fraction))
(interval nil)) (interval nil))
(when (and org-drill-adjust-intervals-for-early-and-late-repetitions-p (when (and org-drill-adjust-intervals-for-early-and-late-repetitions-p
delta-days (minusp delta-days)) delta-days (minusp delta-days))
(setq new-of (org-drill-early-interval-factor (setq new-of (org-drill-early-interval-factor
(get-optimal-factor n ef of-matrix) (get-optimal-factor-sm5 n ef of-matrix)
(inter-repetition-interval-sm5 (inter-repetition-interval-sm5
last-interval n ef of-matrix) last-interval n ef of-matrix)
delta-days))) delta-days)))
(setq of-matrix (setq of-matrix
(set-optimal-factor n next-ef of-matrix (set-optimal-factor n next-ef of-matrix
(round-float new-of 3))) ; round OF to 3 d.p. (round-float new-of 3))) ; round OF to 3 d.p.
(setq ef next-ef) (setq ef next-ef)
@ -939,7 +986,7 @@ Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), wher
((<= quality org-drill-failure-quality) ((<= quality org-drill-failure-quality)
(list -1 1 old-ef (1+ failures) meanq (1+ total-repeats) (list -1 1 old-ef (1+ failures) meanq (1+ total-repeats)
of-matrix)) ; Not clear if OF matrix is supposed to be of-matrix)) ; Not clear if OF matrix is supposed to be
; preserved ; preserved
;; For a zero-based quality of 4 or 5, don't repeat ;; For a zero-based quality of 4 or 5, don't repeat
;; ((and (>= quality 4) ;; ((and (>= quality 4)
;; (not org-learn-always-reschedule)) ;; (not org-learn-always-reschedule))
@ -1101,12 +1148,15 @@ item will be scheduled exactly this many days into the future."
(if (numberp days-ahead) (if (numberp days-ahead)
(setq next-interval days-ahead)) (setq next-interval days-ahead))
(org-drill-store-item-data next-interval repetitions failures
total-repeats meanq ease)
(if (and (null days-ahead) (if (and (null days-ahead)
(numberp weight) (plusp weight) (numberp weight) (plusp weight)
(not (minusp next-interval))) (not (minusp next-interval)))
(setq next-interval (max 1.0 (/ next-interval weight)))) (setq next-interval
(max 1.0 (+ last-interval
(/ (- next-interval last-interval) weight)))))
(org-drill-store-item-data next-interval repetitions failures
total-repeats meanq ease)
(if (eql 'sm5 org-drill-spaced-repetition-algorithm) (if (eql 'sm5 org-drill-spaced-repetition-algorithm)
(setq org-drill-optimal-factor-matrix new-ofmatrix)) (setq org-drill-optimal-factor-matrix new-ofmatrix))
@ -1150,7 +1200,8 @@ of QUALITY."
((not (plusp next-interval)) ((not (plusp next-interval))
0) 0)
((and (numberp weight) (plusp weight)) ((and (numberp weight) (plusp weight))
(max 1.0 (/ next-interval weight))) (+ last-interval
(max 1.0 (/ (- next-interval last-interval) weight))))
(t (t
next-interval)))))) next-interval))))))
@ -1722,46 +1773,84 @@ chosen at random."
(defun org-drill-present-multicloze-hide1-firstmore () (defun org-drill-present-multicloze-hide1-firstmore ()
"Three out of every four repetitions, hides the FIRST piece of "Commonly, hides the FIRST piece of text that is marked for
text that is marked for cloze deletion. One out of every four cloze deletion. Uncommonly, hide one of the other pieces of text,
repetitions, hide one of the other pieces of text, chosen at chosen at random.
random."
The definitions of 'commonly' and 'uncommonly' are determined by
the value of `org-drill-cloze-text-weight'."
;; The 'firstmore' and 'lastmore' functions used to randomly choose whether ;; The 'firstmore' and 'lastmore' functions used to randomly choose whether
;; to hide the 'favoured' piece of text. However even when the chance of ;; to hide the 'favoured' piece of text. However even when the chance of
;; hiding it was set quite high (80%), the outcome was too unpredictable over ;; hiding it was set quite high (80%), the outcome was too unpredictable over
;; the small number of repetitions where most learning takes place for each ;; the small number of repetitions where most learning takes place for each
;; item. In other words, the actual frequency during the first 10 repetitions ;; item. In other words, the actual frequency during the first 10 repetitions
;; was often very different from 80%. Hence we use modulo instead. ;; was often very different from 80%. Hence we use modulo instead.
(if (zerop (mod (1+ (org-drill-entry-total-repeats 0)) 4)) (cond
;; 25% of time, hide any item except the first ((null org-drill-cloze-text-weight)
(org-drill-present-multicloze-hide-n 1 t) ;; Behave as hide1cloze
;; 75% of time, hide first item (org-drill-present-multicloze-hide1))
(org-drill-present-multicloze-hide-first))) ((not (and (integerp org-drill-cloze-text-weight)
(plusp org-drill-cloze-text-weight)))
(error "Illegal value for org-drill-cloze-text-weight: %S"
org-drill-cloze-text-weight))
((zerop (mod (1+ (org-drill-entry-total-repeats 0))
org-drill-cloze-text-weight))
;; Uncommonly, hide any item except the first
(org-drill-present-multicloze-hide-n 1 t))
(t
;; Commonly, hide first item
(org-drill-present-multicloze-hide-first))))
(defun org-drill-present-multicloze-show1-lastmore () (defun org-drill-present-multicloze-show1-lastmore ()
"Three out of every four repetitions, hides all pieces except "Commonly, hides all pieces except the last. Uncommonly, shows
the last. One out of every four repetitions, shows any random any random piece. The effect is similar to 'show1cloze' except
piece. The effect is similar to 'show1cloze' except that the last that the last item is much less likely to be the item that is
item is much less likely to be the item that is visible." visible.
(if (zerop (mod (1+ (org-drill-entry-total-repeats 0)) 4))
;; 25% of time, show any item except the last The definitions of 'commonly' and 'uncommonly' are determined by
(org-drill-present-multicloze-hide-n -1 nil nil t) the value of `org-drill-cloze-text-weight'."
;; 75% of time, show the LAST item (cond
(org-drill-present-multicloze-hide-n -1 nil t))) ((null org-drill-cloze-text-weight)
;; Behave as show1cloze
(org-drill-present-multicloze-show1))
((not (and (integerp org-drill-cloze-text-weight)
(plusp org-drill-cloze-text-weight)))
(error "Illegal value for org-drill-cloze-text-weight: %S"
org-drill-cloze-text-weight))
((zerop (mod (1+ (org-drill-entry-total-repeats 0))
org-drill-cloze-text-weight))
;; Uncommonly, show any item except the last
(org-drill-present-multicloze-hide-n -1 nil nil t))
(t
;; Commonly, show the LAST item
(org-drill-present-multicloze-hide-n -1 nil t))))
(defun org-drill-present-multicloze-show1-firstless () (defun org-drill-present-multicloze-show1-firstless ()
"Three out of every four repetitions, hides all pieces except "Commonly, hides all pieces except one, where the shown piece
one, where the shown piece is guaranteed NOT to be the first is guaranteed NOT to be the first piece. Uncommonly, shows any
piece. One out of every four repetitions, shows any random random piece. The effect is similar to 'show1cloze' except that
piece. The effect is similar to 'show1cloze' except that the the first item is much less likely to be the item that is
first item is much less likely to be the item that is visible." visible.
(if (zerop (mod (1+ (org-drill-entry-total-repeats 0)) 4))
;; 25% of time, show the first item The definitions of 'commonly' and 'uncommonly' are determined by
(org-drill-present-multicloze-hide-n -1 t) the value of `org-drill-cloze-text-weight'."
;; 75% of time, show any item, except the first (cond
(org-drill-present-multicloze-hide-n -1 nil nil t))) ((null org-drill-cloze-text-weight)
;; Behave as show1cloze
(org-drill-present-multicloze-show1))
((not (and (integerp org-drill-cloze-text-weight)
(plusp org-drill-cloze-text-weight)))
(error "Illegal value for org-drill-cloze-text-weight: %S"
org-drill-cloze-text-weight))
((zerop (mod (1+ (org-drill-entry-total-repeats 0))
org-drill-cloze-text-weight))
;; Uncommonly, show the first item
(org-drill-present-multicloze-hide-n -1 t))
(t
;; Commonly, show any item, except the first
(org-drill-present-multicloze-hide-n -1 nil nil t))))
(defun org-drill-present-multicloze-show1 () (defun org-drill-present-multicloze-show1 ()
@ -2195,6 +2284,19 @@ one of the following values:
due)))) due))))
(defun org-drill-progress-message (collected scanned)
(when (zerop (% scanned 50))
(let* ((meter-width 40)
(sym1 (if (oddp (floor scanned (* 50 meter-width))) ?| ?.))
(sym2 (if (eql sym1 ?.) ?| ?.)))
(message "Collecting due drill items:%4d %s%s"
collected
(make-string (% (ceiling scanned 50) meter-width)
sym2)
(make-string (- meter-width (% (ceiling scanned 50) meter-width))
sym1)))))
(defun org-drill (&optional scope resume-p) (defun org-drill (&optional scope resume-p)
"Begin an interactive 'drill session'. The user is asked to "Begin an interactive 'drill session'. The user is asked to
review a series of topics (headers). Each topic is initially review a series of topics (headers). Each topic is initially
@ -2255,14 +2357,13 @@ than starting a new one."
(warned-about-id-creation nil)) (warned-about-id-creation nil))
(org-map-drill-entries (org-map-drill-entries
(lambda () (lambda ()
(when (zerop (% (incf cnt) 50)) (org-drill-progress-message
(message "Processing drill items: %4d%s"
(+ (length *org-drill-new-entries*) (+ (length *org-drill-new-entries*)
(length *org-drill-overdue-entries*) (length *org-drill-overdue-entries*)
(length *org-drill-young-mature-entries*) (length *org-drill-young-mature-entries*)
(length *org-drill-old-mature-entries*) (length *org-drill-old-mature-entries*)
(length *org-drill-failed-entries*)) (length *org-drill-failed-entries*))
(make-string (ceiling cnt 50) ?.))) (incf cnt))
(cond (cond
((not (org-drill-entry-p)) ((not (org-drill-entry-p))
nil) ; skip nil) ; skip
@ -2361,6 +2462,7 @@ than starting a new one."
(org-drill-save-optimal-factor-matrix)) (org-drill-save-optimal-factor-matrix))
(if org-drill-save-buffers-after-drill-sessions-p (if org-drill-save-buffers-after-drill-sessions-p
(save-some-buffers)) (save-some-buffers))
(message "Drill session finished!")
)))) ))))