diff options
author | Thanos Apollo <[email protected]> | 2023-11-27 22:03:03 +0200 |
---|---|---|
committer | Thanos Apollo <[email protected]> | 2023-11-27 22:03:03 +0200 |
commit | 77f0491e8aafc6cd6c40ac0e39c4fcde59ae5ede (patch) | |
tree | 9df7a956f21cdb3ab79ff854cf3be713836be224 /gnosis.el | |
parent | 9c147582ee4e4ec7880e259613e4058271c09cdc (diff) |
Rename to gnosis
I'm not really good with anglo naming, qbank does not feel right, so I
will stick with simple greek names for my packages from now on for I'm
more familiar with them.
Diffstat (limited to 'gnosis.el')
-rw-r--r-- | gnosis.el | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/gnosis.el b/gnosis.el new file mode 100644 index 0000000..64fc46a --- /dev/null +++ b/gnosis.el @@ -0,0 +1,128 @@ +;;; gnosis.el --- Learning tool for GNU Emacs -*- lexical-binding: t; -*- + +;; Copyright (C) 2023 Thanos Apollo + +;; Author: Thanos Apollo <[email protected]> +;; Keywords: extensions +;; URL: https://git.thanosapollo.org/gnosis +;; Version: 0.0.1 + +;; Package-Requires: ((emacs "27.2") (compat "29.1.4.2")) + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Work in progress + +;;; Code: + +;; TODO: Create cloze question type & make it easily extensible for +;; other types + + +(require 'emacsql) +(require 'cl-lib) +(require 'animate) + +(cl-defun gnosis--select (table values &optional (restrictions '1=1)) + "Select VALUES from TABLE, optionally with RESTRICTIONS." + (emacsql-with-connection (db (emacsql-sqlite "test2.db")) + (emacsql db `[:select ,values :from ,table :where ,restrictions]))) + +(cl-defun gnosis--create-table (table-name &optional values) + "Create TABLE-NAME for VALUES." + (emacsql-with-connection (db (emacsql-sqlite "test2.db")) + (emacsql db `[:create-table ,table-name ,values]))) + +(cl-defun gnosis--insert-into (table-name values) + "Insert VALUES to TABLE-NAME." + (emacsql-with-connection (db (emacsql-sqlite "test2.db")) + (emacsql db `[:insert :into ,table-name :values ,values]))) + +(defun gnosis--get-question (id) + "Get question row for question ID." + (caar (gnosis--select 'gnosis1 'question `(= question_id ,id)))) + +(defun gnosis--get-correct-answer (id) + "Get correct answer for question ID." + (caar (gnosis--select 'gnosis1 'answer `(= question_id ,id)))) + +(defun gnosis--get-mcanswers (id) + "Get multiple choices for question ID." + (caar (gnosis--select 'gnosis1 'mchoices `(= question_id ,id)))) + +(defun gnosis--display-question (id) + "Display question for question ID." + (let ((question (gnosis--get-question id))) + ;; Animate.el is used only for testing purposes. + (animate-string question 5))) + +(defun gnosis--mcanswers-choice (id) + "Display multiple choice answers for question ID." + (let ((mcanswers (gnosis--get-mcanswers id))) + (completing-read "Answer: " mcanswers))) + +(defun gnosis--input-mcanswers () + "Prompt user for multiple choice answers." + (let ((mcqs nil)) + (while (not (equal (car mcqs) "q")) + (add-to-list 'mcqs (read-string "Choices (q for quit): "))) + (when (equal (car mcqs) "q") + (pop mcqs)) + (reverse mcqs))) + +(cl-defun gnosis-create-mcq-question (&key question choices correct-answer) + "Create a QUESTION with a list of multiple CHOICES and one CORRECT-ANSWER. + +This function can be used interactively, or if you prefer you may also +use it like this: + (gnosis-create-mcq-question + :question \"Which one is the greatest editor?\" + :choices (list \"Emacs\" \"Vim\" \"VSCode\" \"Ed\") + :correct-answer 1)" + (interactive + (list :question (read-string "Question: ") + :choices (gnosis--input-mcanswers) + :correct-answer (string-to-number (read-string "Which is the correct answer? ")))) + (gnosis--insert-into 'qbank1 `([nil ,question ,choices ,correct-answer]))) + +(defun gnosis-create-question (type) + "Create question as TYPE." + (interactive (list (completing-read "Type: " '(MCQ Cloze Basic)))) + (pcase type + ("MCQ" (call-interactively 'gnosis-create-mcq-question)) + ("Cloze" (message "Not ready yet.")) + ("Basic" (message "Not ready yet.")) + (_ (message "No such type.")))) + +;; Fix: review for seperate question types. +(defun gnosis-review (id) + "Start review for question ID." + (let ((canswer (gnosis--get-correct-answer id)) + (choices (gnosis--get-mcanswers id)) + (user-choice (gnosis--mcanswers-choice id))) + (if (equal (nth (- canswer 1) choices) user-choice) + (message "Correct!") + (message "False")))) + +(defun gnosis-test-buffer () + "Create testing buffer." + (interactive) + (with-current-buffer + (switch-to-buffer (get-buffer-create "*gnosis*")) + (gnosis--display-question 13) + (gnosis-review 13))) + +;;; gnosis.el ends here |