Changeset 0f50a20 in flexograder


Ignore:
Timestamp:
11/09/25 10:24:21 (2 months ago)
Author:
Enrico Schwass <ennoausberlin@…>
Branches:
master
Children:
e77bfb3
Parents:
066f7d9
Message:

simplify id handling

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • builder/exam.py

    r066f7d9 r0f50a20  
    8282    def default(cls):
    8383        return cls()
    84 
    85     @staticmethod
    86     def _qid_of(q: ExamElement | str) -> str:
    87         if isinstance(q, str):
    88             return q
    89         # prefer flexo_id, fallback to id if needed
    90         return str(getattr(q, "flexo_id", getattr(q, "id")))
    91 
    9284    def add_question(self, question: ExamElement):
    9385        self.questions.append(question)
    9486
    9587    def remove_question(self, qid: str):
    96         qid = str(qid)
    97         self.questions = [q for q in self.questions if self._qid_of(q) != qid]
     88        self.questions = [q for q in self.questions if q.flexo_id != qid]
    9889        self.layout.purge_question(qid)
    9990
    10091    def get_question_by_id(self, qid: str) -> Optional[ExamElement]:
    10192        qid = str(qid)
    102         return next((q for q in self.questions if self._qid_of(q) == qid), None)
     93        return next((q for q in self.questions if q.flexo_id == qid), None)
    10394
    10495    def __post_init__(self):
     
    217208    def add_question_to_page(self, page_title: str, question: ExamElement | str):
    218209        """Assign a question to a page (by object or id)."""
    219         qid = self._qid_of(question)
    220         self.layout.assign(page_title, qid)
     210        self.layout.assign(page_title, question.flexo_id)
    221211   
    222212    # FIXME: This needs to be addressed somewhere else now
     
    307297                    continue
    308298                # prefer flexo_id as the answer key
    309                 key = self._qid_of(q)
    310                 submitted = submission.get_answer_for(key)
     299                submitted = submission.get_answer_for(q.flexo_id)
    311300                score = q.evaluate(submitted)
    312301                total_score += score
  • builder/question_catalog.py

    r066f7d9 r0f50a20  
    111111            int(q.id.split("_")[-1])
    112112            for q in self.questions
    113             if q.id.startswith(f"{abbrev}_") and q.id.split("_")[-1].isdigit()
     113            if q.flexo_id.startswith(f"{abbrev}_") and q.flexo_id.split("_")[-1].isdigit()
    114114        ]
    115115        next_num = max(existing_numbers, default=0) + 1
  • gui/gui.py

    r066f7d9 r0f50a20  
    4848        self._recent_actions = []
    4949        self.domain_set = set()
    50         self.clipboard = []  # holds copied/cut Question objects
    51         self.clipboard_action = None  # "copy" or "cut"
     50        self.clipboard = []  # holds copied Question objects
     51        self.clipboard_action = None  # "copy"
    5252        self.clipboard_source_catalog = None
    5353        self.create_menu()
     
    5858        self.session = SessionManager(catalog_manager=self.catalog_manager,
    5959                                      exam_manager=self.exam_manager)
    60         self.session.load()
     60        geometry = self.session.load()
     61        self.geometry(geometry)
    6162        self.refresh_catalog_list()
    6263        self.refresh_exam_list()
     
    201202        ttk.Button(frame_buttons, text="Copy",
    202203                   command=self.copy_selected_question).grid(row=0, column=1, padx=2, sticky="ew")
    203         ttk.Button(frame_buttons, text="Cut",
    204                    command=self.cut_selected_question).grid(row=0, column=2, padx=2, sticky="ew")
    205204        ttk.Button(frame_buttons, text="Paste",
    206205                   command=self.paste_selected_question).grid(row=0, column=3, padx=2, sticky="ew")
     
    236235
    237236        ttk.Label(frame_right, text="Question Text").grid(row=0, column=0, sticky="w")
    238         self.txt_question = tk.Text(frame_right, wrap="word", height=5)
     237        self.txt_question = tk.Text(frame_right, wrap="word", height=3)
    239238        self.txt_question.grid(row=1, column=0, sticky="nsew")
    240239
     
    352351        # Always provide deterministic order (e.g. by question ID)
    353352        return sorted(self.active_catalog.questions, key=lambda q: q.id)
    354 
    355     def switch_catalog(self):
    356         catalogs = self.catalog_manager.list_catalogs()
    357         if not catalogs:
    358             messagebox.showinfo("No Catalogs", "No catalogs loaded.")
    359             return
    360 
    361         selection = simpledialog.askstring(
    362             "Switch Catalog",
    363             f"Available catalogs:\n{', '.join(catalogs)}\nEnter catalog ID to activate:",
    364         )
    365         if not selection:
    366             return
    367 
    368         try:
    369             self.catalog_manager.set_active(selection)
    370             self.refresh_question_tree()
    371             self.log_action(f"Switched - Active catalog: {selection}")
    372         except ValueError:
    373             messagebox.showerror("Invalid", f"No catalog with ID '{selection}'")
    374         self.refresh_status_bar()
    375353
    376354    def create_catalog(self):
     
    653631            text = q.text.strip().replace("\n", " ")
    654632            if len(text) > 100:
    655                 text = text[:97] + "..."
     633                text = text # [:97] + "..."
    656634
    657635            # Try to display a readable status name
     
    783761                target.add_questions([new_q])
    784762                transferred.append(new_q)
    785 
    786         elif self.clipboard_action == "cut":
    787             # Move from source to target
    788             source = self.catalog_manager.catalogs[self.clipboard_source_catalog]
    789             for q in list(self.clipboard):
    790                 # Remove from source
    791                 try:
    792                     source.remove(q.id)
    793                 except ValueError:
    794                     pass  # maybe already removed or invalid state
    795                 # Add to target
    796                 target.add_questions([q])
    797                 transferred.append(q)
    798 
    799763        else:
    800764            messagebox.showwarning("Paste", f"Unknown clipboard action: {self.clipboard_action}")
  • gui/session_manager.py

    r066f7d9 r0f50a20  
    3232            for ex_id, each in self.exam_manager.exams.items():
    3333                path = self.exam_dir / f"{ex_id}.json"
    34                
     34
    3535                if isinstance(each.flexo_id, str):
    3636                    print(f"[WARN] Catalog {each.title} has string flexo_id: {each.flexo_id}")
     
    5151    def load(self):
    5252        """Restore the previous workspace if available."""
     53        geometry = "800x600+50+50"
    5354        if not self.session_file.exists():
    5455            print("[Session] No previous session found.")
    55             return
    56 
    57         geometry = "800x600+50+50"
     56            return geometry
    5857
    5958        try:
     
    6261
    6362            # 1. Restore window
    64 
    6563            geometry = data["geometry"]
    6664
  • tests/test_question_catalog.py

    r066f7d9 r0f50a20  
    3131    qid = sample_question.flexo_id
    3232    assert any(q.flexo_id == qid for q in catalog.questions)
    33     assert catalog.remove(sample_question.id)  # removes if DRAFT
     33    assert catalog.remove(sample_question.flexo_id)  # removes if DRAFT
    3434    assert not any(q.flexo_id == qid for q in catalog.questions)
    3535
     
    3838    sample_question.approve()
    3939    with pytest.raises(ValueError):
    40         catalog.remove(sample_question.id)
     40        catalog.remove(sample_question.flexo_id)
    4141
    4242def test_next_question_id(catalog):
Note: See TracChangeset for help on using the changeset viewer.