Changeset 9db70f7 in flexograder


Ignore:
Timestamp:
11/27/25 11:25:20 (4 months ago)
Author:
Enrico Schwass <ennoausberlin@…>
Branches:
fake-data, main, master
Children:
8e6a433
Parents:
e70dd79
Message:

some fixes

Files:
1 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • builder/exam.py

    re70dd79 r9db70f7  
    145145        meta = data.get("exam", {})
    146146        domains = data.get("domains", {})
    147        
     147 
    148148        flexo_id = FlexOID(meta.get("flexo_id"))
    149149
     
    214214    def to_question_catalog(self, questions, catalog_id, title, author="unknown", version="1.0"):
    215215        catalog = {
    216             "meta": {
    217                 "catalog_id": catalog_id,
     216            "QuestionCatalog": {
     217                "flexo_id": catalog_id,
    218218                "title": title,
    219219                "created_on": datetime.utcnow().isoformat() + "Z",
  • builder/exam_elements.py

    re70dd79 r9db70f7  
    5353        return cls.with_domain_id(domain_id="DEF_DEFAULT")
    5454
    55     @property
    56     @abstractmethod
    57     def qtype(self):
    58         pass
    59 
    6055    @abstractmethod
    6156    def to_html(self) -> str:
     
    7772
    7873    def __hash__(self):
    79         return hash((self.flexo_id, self.qtype))
     74        return hash((self.flexo_id, self.subtype))
    8075
    8176    def evaluate(self, answer):
     
    123118        return obj
    124119
    125     def to_dict(self):
    126         base = super().to_dict()  # from FlexoEntity
    127         base.update({
     120    def _serialize_content(self):
     121        return {
    128122            "topic": self.topic,
    129             "qtype": self.qtype,  # avoid name clash with built-in type
    130123            "text": self.text,
    131124            "media": [m.to_dict() for m in self.media],
    132         })
    133         return base
     125        }
    134126
    135127    def has_media(self):
     
    153145    def __post_init__(self):
    154146        super().__post_init__()
    155 
    156     @property
    157     def qtype(self):
    158         return "instruction"
    159147
    160148    @property
     
    201189        super().__post_init__()
    202190
    203     @property
    204     @abstractmethod
    205     def qtype(self):
    206         pass
    207 
    208     def to_dict(self):
    209         base = super().to_dict()
    210         base.update({
    211             "options": [opt.to_dict() for opt in self.options],
    212         })
    213         return base
     191    def _serialize_content(self):
     192        return {
     193            "options": [opt.to_dict() for opt in self.options]
     194        }
    214195
    215196    @classmethod
     
    239220@dataclass
    240221class SingleChoiceQuestion(ChoiceQuestion):
    241 
    242     @property
    243     def qtype(self):
    244         return "single_choice"
    245222
    246223    def to_html(self) -> str:
     
    269246@dataclass
    270247class MultipleChoiceQuestion(ChoiceQuestion):
    271 
    272     @property
    273     def qtype(self):
    274         return "multiple_choice"
    275248
    276249    def to_html(self) -> str:
     
    311284    validation: Optional[Validation] = None
    312285
    313     @property
    314     def qtype(self):
    315         return "text"
    316 
    317286    @classmethod
    318287    def from_dict(cls, data):
     
    323292        return obj
    324293
    325     def to_dict(self):
    326         d = super().to_dict()
    327         if self.validation:
    328             d["validation"] = self.validation.to_dict()
    329         return d
     294    def _serialize_content(self):
     295        return {
     296            "validation": self.validation.to_dict()
     297        }
    330298
    331299    def answer_options_for_display(self):
     
    355323
    356324@dataclass
    357 class CandidateIDQuestion(ExamElement):
     325class IDForm(ExamElement):
    358326
    359327    fields: List[dict] = field(default_factory=list)
    360 
    361     @property
    362     def qtype(self):
    363         return "candidate_id"
    364328
    365329    def __post_init__(self):
     
    393357        return [("Last Name, First Name, Personal ID", "0")]
    394358
    395     def to_dict(self):
    396         d = super().to_dict()
    397         d["fields"] = self.fields
    398         return d
     359    def _serialize_content(self):
     360        return {
     361            "fields": self.fields
     362        }
    399363
    400364    @classmethod
  • builder/question_factory.py

    re70dd79 r9db70f7  
    55    MultipleChoiceQuestion,
    66    TextQuestion,
    7     CandidateIDQuestion,
     7    IDForm,
    88    InstructionBlock,
    99    AnswerOption,
     
    3333    """
    3434
    35     qtype = q.get("qtype")
    36     if not qtype:
    37         raise ValueError("Question missing 'qtype'")
     35    subtype = q.get("subtype")
     36    if not subtype:
     37        raise ValueError("Question missing 'subtype'")
    3838
    39     mapping = {
    40         "single_choice": SingleChoiceQuestion,
    41         "multiple_choice": MultipleChoiceQuestion,
    42         "text": TextQuestion,
    43         "instruction": InstructionBlock,
    44         "candidate_id": CandidateIDQuestion,
    45     }
    46 
    47     cls = mapping.get(qtype)
     39    cls = globals()[subtype]
    4840    if not cls:
    4941        raise ValueError(f"Unknown question type: {qtype}")
  • tests/conftest.py

    re70dd79 r9db70f7  
    66    SingleChoiceQuestion,
    77    MultipleChoiceQuestion,
    8     CandidateIDQuestion,
     8    IDForm,
    99    InstructionBlock,
    1010    TextQuestion,
     
    3131    # ──────────────────────────────────────────────────────────────
    3232
    33     q_id = CandidateIDQuestion.with_domain_id(domain_id="ADMIN_CANDIDATE",
     33    q_id = IDForm.with_domain_id(domain_id="ADMIN_CANDIDATE",
    3434                                              text="Please enter your candidate ID and name.",
    3535                                              fields=["Name", "Candidate ID"],
  • tests/test_question_factory.py

    re70dd79 r9db70f7  
    55
    66def test_radio_question_autoid():
    7     q = {"domain_id": "WIP_TEST", "qtype": "single_choice", "text": "What is Ohm’s law?",
     7    q = {"domain_id": "WIP_TEST", "subtype": "SingleChoiceQuestion", "text": "What is Ohm’s law?",
    88         "options": [{"id": "A", "text": "U = R / I"}, {"id": "B", "text": "U = R * I"}]}
    99    obj = question_factory(q)
     
    1616def test_multiple_choice_question_existing_id():
    1717    Domain.with_domain_id("WIP_TEST")
    18     q = {"domain_id": "WIP_TEST", "qtype": "multiple_choice",
     18    q = {"domain_id": "WIP_TEST", "subtype": "MultipleChoiceQuestion",
    1919         "text": "Select power units"}
    2020    obj = question_factory(q)
     
    2727def test_text_question_validation_optional():
    2828    Domain.with_domain_id(domain_id="WIP_TEST")
    29     q = {"domain_id": "WIP_TEST", "qtype": "text",
     29    q = {"domain_id": "WIP_TEST", "subtype": "TextQuestion",
    3030         "text": "Explain", "validation": {"maxlength": 5}}
    3131    obj = question_factory(q)
Note: See TracChangeset for help on using the changeset viewer.