Skip to content

Commit

Permalink
feat!: new interface / wrapper object api
Browse files Browse the repository at this point in the history
  • Loading branch information
MHajoha committed Jun 24, 2024
1 parent e5b9f74 commit 1c78e83
Show file tree
Hide file tree
Showing 25 changed files with 834 additions and 504 deletions.
8 changes: 5 additions & 3 deletions examples/full/python/local/full_example/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from .question_type import ExampleQuestionType
from questionpy import Package, QuestionTypeWrapper

from .question_type import ExampleQuestion

def init() -> ExampleQuestionType:
return ExampleQuestionType()

def init(package: Package) -> QuestionTypeWrapper:
return QuestionTypeWrapper(ExampleQuestion, package)
23 changes: 6 additions & 17 deletions examples/full/python/local/full_example/question_type.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
from questionpy import Attempt, AttemptUiPart, Question, QuestionType
from questionpy_common.api.attempt import ScoreModel, ScoringCode
from questionpy_common.api.question import QuestionModel, ScoringMethod
from questionpy import Attempt, Question

from .form import MyModel


class ExampleAttempt(Attempt):
def export_score(self) -> ScoreModel:
return ScoreModel(scoring_code=ScoringCode.AUTOMATICALLY_SCORED, score=0)
def _compute_score(self) -> float:
return 0

def render_formulation(self) -> AttemptUiPart:
ui_part = AttemptUiPart(content=self.jinja2.get_template("local.full_example/formulation.xhtml.j2").render())
# TODO: implement call_js method
# ui_part.call_js("main", "init") # noqa: ERA001
return ui_part # noqa: RET504
@property
def formulation(self) -> str:
return self.jinja2.get_template("local.full_example/formulation.xhtml.j2").render()


class ExampleQuestion(Question):
attempt_class = ExampleAttempt

options: MyModel

def export(self) -> QuestionModel:
return QuestionModel(scoring_method=ScoringMethod.AUTOMATICALLY_SCORABLE)


class ExampleQuestionType(QuestionType):
question_class = ExampleQuestion
4 changes: 3 additions & 1 deletion examples/full/qpy_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ name:
en: Full Example
languages: [de, en]
build_hooks:
pre: npm run build
pre:
- npm ci
- npm run build
7 changes: 4 additions & 3 deletions examples/minimal/python/local/minimal_example/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# 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 <[email protected]>
from questionpy import Package, QuestionTypeWrapper

from .question_type import ExampleQuestionType
from .question_type import ExampleQuestion


def init() -> ExampleQuestionType:
return ExampleQuestionType()
def init(package: Package) -> QuestionTypeWrapper:
return QuestionTypeWrapper(ExampleQuestion, package)
29 changes: 10 additions & 19 deletions examples/minimal/python/local/minimal_example/question_type.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
from questionpy import Attempt, AttemptUiPart, Question, QuestionType, ScoringCode
from questionpy_common.api.attempt import ScoreModel
from questionpy_common.api.question import QuestionModel, ScoringMethod
from questionpy import Attempt, Question, ResponseNotScorableError

from .form import MyModel


class ExampleAttempt(Attempt):
def export_score(self) -> ScoreModel:
def _compute_score(self) -> float:
if not self.response or "choice" not in self.response:
return ScoreModel(scoring_code=ScoringCode.RESPONSE_NOT_SCORABLE, score=None)
msg = "'choice' is missing"
raise ResponseNotScorableError(msg)

if self.response["choice"] == "B":
return ScoreModel(scoring_code=ScoringCode.AUTOMATICALLY_SCORED, score=1)
return 1

return ScoreModel(scoring_code=ScoringCode.AUTOMATICALLY_SCORED, score=0)
return 0

def render_formulation(self) -> AttemptUiPart:
return AttemptUiPart(
content=self.jinja2.get_template("local.minimal_example/formulation.xhtml.j2").render(),
placeholders={"description": "Welcher ist der zweite Buchstabe im deutschen Alphabet?"},
)
@property
def formulation(self) -> str:
self.placeholders["description"] = "Welcher ist der zweite Buchstabe im deutschen Alphabet?"
return self.jinja2.get_template("local.minimal_example/formulation.xhtml.j2").render()


class ExampleQuestion(Question):
attempt_class = ExampleAttempt

options: MyModel

def export(self) -> QuestionModel:
return QuestionModel(scoring_method=ScoringMethod.AUTOMATICALLY_SCORABLE)


class ExampleQuestionType(QuestionType):
question_class = ExampleQuestion
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from .question_type import ExampleQuestionType
from questionpy import Package, QuestionTypeWrapper

from .question_type import ExampleQuestion

def init() -> ExampleQuestionType:
return ExampleQuestionType()

def init(package: Package) -> QuestionTypeWrapper:
return QuestionTypeWrapper(ExampleQuestion, package)
Original file line number Diff line number Diff line change
@@ -1,31 +1,18 @@
from questionpy import Attempt, AttemptUiPart, Question, QuestionType
from questionpy_common.api.attempt import ScoreModel, ScoringCode
from questionpy_common.api.question import QuestionModel, ScoringMethod
from questionpy import Attempt, Question

from .form import MyModel


class ExampleAttempt(Attempt):
def export_score(self) -> ScoreModel:
return ScoreModel(scoring_code=ScoringCode.AUTOMATICALLY_SCORED, score=0)
def _compute_score(self) -> float:
return 0

def render_formulation(self) -> AttemptUiPart:
ui_part = AttemptUiPart(
content=self.jinja2.get_template("local.static_files_example/formulation.xhtml.j2").render()
)
# TODO: implement call_js method
# ui_part.call_js("test", "init", {"data": "Hello world!"}) # noqa: ERA001
return ui_part # noqa: RET504
@property
def formulation(self) -> str:
return self.jinja2.get_template("local.static_files_example/formulation.xhtml.j2").render()


class ExampleQuestion(Question):
attempt_class = ExampleAttempt

options: MyModel

def export(self) -> QuestionModel:
return QuestionModel(scoring_method=ScoringMethod.AUTOMATICALLY_SCORABLE)


class ExampleQuestionType(QuestionType):
question_class = ExampleQuestion
Loading

0 comments on commit 1c78e83

Please sign in to comment.