summaryrefslogtreecommitdiff
path: root/gnosis.el
diff options
context:
space:
mode:
authorThanos Apollo <[email protected]>2023-11-27 22:03:03 +0200
committerThanos Apollo <[email protected]>2023-11-27 22:03:03 +0200
commit77f0491e8aafc6cd6c40ac0e39c4fcde59ae5ede (patch)
tree9df7a956f21cdb3ab79ff854cf3be713836be224 /gnosis.el
parent9c147582ee4e4ec7880e259613e4058271c09cdc (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.el128
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