Why won't anyone think of the Americans! *sobs lightly*
(defvar my/prompt-returns
(cl-mapcan
#'(lambda (a)
(mapcar
#'(lambda (b)
(cons (format "%d * %d = ?" a b) (* a b)))
(number-sequence a 9)))
(number-sequence 2 9)))
(defun my/times-table-helper (time-expectation prompt-return-alist)
(let (incorrect-alist)
(while prompt-return-alist
(let* ((too-slow-p)
(timer (run-with-timer time-expectation nil #'(lambda () (setq too-slow-p t))))
(q-and-a (seq-random-elt prompt-return-alist))
(attempt (read-number (format "Evaluate: %s\n" (car q-and-a)))))
(cancel-timer timer)
(cond ((/= attempt (cdr q-and-a))
(message (format "You answered %d instead of %d." attempt (cdr q-and-a)))
(push q-and-a incorrect-alist))
(too-slow-p
(message "You answered too slowly.")
(push q-and-a incorrect-alist))
(t (message "Correct!")))
(setq prompt-return-alist (remove q-and-a prompt-return-alist))
(sleep-for 0.5)))
incorrect-alist))
(defun my/times-table (time-expectation)
(interactive "P")
(cond ((not time-expectation) (setq time-expectation 2))
((not (floatp time-expectation)) (error "time-expectatation must be a float."))
((<= time-expectation 0) (error "time-expectatation must be positive.")))
(let ((prompt-return-alist my/prompt-returns))
(while (setq prompt-return-alist
(my/times-table-helper time-expectation prompt-return-alist))
(prin1 prompt-return-alist))))