From 667b55824e0bd4d4bb4fd1b7645998ac0830de21 Mon Sep 17 00:00:00 2001 From: Maximilian Haye Date: Thu, 19 Dec 2024 19:06:39 +0100 Subject: [PATCH] docs: add a multichoice example package --- examples/multichoice/.gitignore | 2 ++ .../python/local/multichoice/__init__.py | 8 +++++ .../python/local/multichoice/form.py | 18 ++++++++++ .../python/local/multichoice/question_type.py | 35 +++++++++++++++++++ .../templates/formulation.xhtml.j2 | 23 ++++++++++++ examples/multichoice/qpy_config.yml | 9 +++++ 6 files changed, 95 insertions(+) create mode 100644 examples/multichoice/.gitignore create mode 100644 examples/multichoice/python/local/multichoice/__init__.py create mode 100644 examples/multichoice/python/local/multichoice/form.py create mode 100644 examples/multichoice/python/local/multichoice/question_type.py create mode 100644 examples/multichoice/python/local/multichoice/templates/formulation.xhtml.j2 create mode 100644 examples/multichoice/qpy_config.yml diff --git a/examples/multichoice/.gitignore b/examples/multichoice/.gitignore new file mode 100644 index 00000000..098b60fc --- /dev/null +++ b/examples/multichoice/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +/dist diff --git a/examples/multichoice/python/local/multichoice/__init__.py b/examples/multichoice/python/local/multichoice/__init__.py new file mode 100644 index 00000000..48416cd5 --- /dev/null +++ b/examples/multichoice/python/local/multichoice/__init__.py @@ -0,0 +1,8 @@ +# This file is part of the QuestionPy SDK. (https://questionpy.org) +# The QuestionPy SDK is free software released under terms of the MIT license. See LICENSE.md. +# (c) Technische Universität Berlin, innoCampus +from questionpy import make_question_type_init + +from .question_type import MultichoiceQuestion + +init = make_question_type_init(MultichoiceQuestion) diff --git a/examples/multichoice/python/local/multichoice/form.py b/examples/multichoice/python/local/multichoice/form.py new file mode 100644 index 00000000..2aa10e51 --- /dev/null +++ b/examples/multichoice/python/local/multichoice/form.py @@ -0,0 +1,18 @@ +from questionpy.form import FormModel, OptionEnum, checkbox, generated_id, option, repeat, select, text_input + + +class ChoiceMode(OptionEnum): + SELECT = option(" element') + + +class Choice(FormModel): + id: str = generated_id() + text: str = text_input("Text", required=True) + correct: bool = checkbox("Korrekt") + + +class MultichoiceFormModel(FormModel): + description: str = text_input("Beschreibung", required=True) + mode: ChoiceMode = select("Auswahlelement", ChoiceMode, required=True) + choices: list[Choice] = repeat(Choice, initial=3, minimum=2) diff --git a/examples/multichoice/python/local/multichoice/question_type.py b/examples/multichoice/python/local/multichoice/question_type.py new file mode 100644 index 00000000..4c319ab8 --- /dev/null +++ b/examples/multichoice/python/local/multichoice/question_type.py @@ -0,0 +1,35 @@ +from typing import Any + +from questionpy import Attempt, Question, ResponseNotScorableError + +from .form import ChoiceMode, MultichoiceFormModel + + +class MultichoiceAttempt(Attempt): + def _compute_score(self) -> float: + if not self.response or "choice" not in self.response: + msg = "'choice' is missing" + raise ResponseNotScorableError(msg) + + chosen_id = self.response["choice"] + correct_choice_ids = [choice.id for choice in self.question.options.choices if choice.correct] + + if chosen_id in correct_choice_ids: + return 1 + + return 0 + + def __init__(self, *args: Any): + super().__init__(*args) + + self.placeholders["description"] = self.question.options.description + + @property + def formulation(self) -> str: + return self.jinja2.get_template("local.multichoice/formulation.xhtml.j2").render(ChoiceMode=ChoiceMode) + + +class MultichoiceQuestion(Question): + attempt_class = MultichoiceAttempt + + options: MultichoiceFormModel diff --git a/examples/multichoice/python/local/multichoice/templates/formulation.xhtml.j2 b/examples/multichoice/python/local/multichoice/templates/formulation.xhtml.j2 new file mode 100644 index 00000000..53f3a5b7 --- /dev/null +++ b/examples/multichoice/python/local/multichoice/templates/formulation.xhtml.j2 @@ -0,0 +1,23 @@ +
+

+

+ {% if question.options.mode == ChoiceMode.SELECT %} + + {% else %} +

+ {% for choice in question.options.choices %} + + {% endfor %} +
+ {% endif %} +

+
diff --git a/examples/multichoice/qpy_config.yml b/examples/multichoice/qpy_config.yml new file mode 100644 index 00000000..d731411e --- /dev/null +++ b/examples/multichoice/qpy_config.yml @@ -0,0 +1,9 @@ +short_name: multichoice +namespace: local +version: 0.1.0 +api_version: "0.1" +author: Jane Doe +name: + de: Multiple-Choice + en: Multiple-Choice +languages: [de, en]