Source code for uw.local.teaching.db.aids

"""Examination aids editing objects.

Classes for editing the permitted aids for an examination.  This exists
because formerly there was another editor for editing the default permitted
aids for an admin unit.  The implementation here shared code between the two
editors.  If it were re-implemented from scratch all of this would live in
webui/aids_edit.py.
"""

from operator import attrgetter

from ll.xist.ns import html

from uw.web.html.form import render_checkbox, render_select
from uw.web.html.format import make_table_format, format_email

[docs]def strip_prefix (str, prefix): if str.startswith (prefix): return str[len (prefix):] else: return None
[docs]def get_aid_classes (cursor): return dict ((c.aid_class_code, c) for c in cursor.execute_tuples ("select * from exam_aid_class"))
[docs]class AidsEditor (object): def __init__ (self, cursor): super (AidsEditor, self).__init__ () self.__cursor = cursor @property def cursor (self): return self.__cursor
[docs] def render_aids (self, classes=None): if classes is None: classes = get_aid_classes (self.cursor) result = [] openbook = self.openbook if openbook is None: return None elif openbook: aids = None class_code = 'O' else: aids = self.aids class_code = 'S' if aids else 'C' result.append (html.p (html.b (classes[class_code].aid_class_title))) result.append (html.p ('Candidates may bring ', classes[class_code].aid_class_description, '.')) if aids: ul = html.ul () for aid in aids: ul.append (html.li (aid.exam_exam_aid_format)) result.append (ul) instructions = self.instructions if instructions is not None: result.append (html.p (instructions)) return result
[docs] def render_form (self): return html.form ( html.p ('Permitted aids are extra materials that examination candidates may bring with them to the examination. Candidates are always permitted to bring pens, pencils, and drafting instruments.'), html.p (html.label ( 'Open Book:', render_checkbox ("openbook", self.openbook), ' (Selecting “Open Book” will remove any specific aids specified.)' )), make_table_format ( ('Aid', attrgetter ('aid_type_title')), ('Special Notes', attrgetter ('aid_notes')), ('Actions', lambda r: html.label (render_checkbox ("delete-%s" % r.aid_type_code, False), ' Delete')), footer_row=lambda: html.tr (html.td (render_select ("add-code", self.cursor.execute_tuples ("select aid_type_code, aid_type_title from exam_aid_type order by aid_type_code"))), html.td (html.input (type="text", name="add-notes")), html.td ('← Add')) ) (self.aids), html.p ( 'Instructions are additional brief important information you wish to communicate to candidates. Instructions must not authorize permitted aids; to do that, use the above section. If the aid you need is not listed in the drop-down menu, please contact ', format_email ('odyssey@uwaterloo.ca'), '.', html.br (), html.textarea (self.instructions, name="notes", rows=4, cols=40) ), html.p ( html.input (type="submit", value="Update!") ), method="post", action="" )
[docs] def handle_post (self, form): openbook = "openbook" in form notes = form.required_field_value ("notes").strip () or None if openbook: # Remove permitted aids self.delete_aids () else: # Remove permitted aids that are to be deleted for code in [_f for _f in (strip_prefix (name, "delete-") for name in form) if _f]: self.delete_aid (code) # Add new permitted aid if specified add_code = form.optional_field_value ("add-code") or None if add_code is not None: aid_notes = form.optional_field_value ("add-notes") if aid_notes is not None: aid_notes = aid_notes.strip () or None self.insert_aid (add_code, aid_notes) self.update_aids (openbook, notes)
[docs]class ExamAidsEditor (AidsEditor): def __init__ (self, cursor, exam): super (ExamAidsEditor, self).__init__ (cursor) self.__exam = exam @property def exam (self): return self.__exam @property def openbook (self): return self.exam.exam_openbook @property def aids (self): return self.cursor.exam_aids (exam_id=self.exam.exam_id) @property def instructions (self): return self.exam.exam_instructions
[docs] def delete_aids (self): self.cursor.execute_none ("delete from exam_exam_aid where exam_id=%(exam_id)s", exam_id=self.exam.exam_id)
[docs] def delete_aid (self, code): self.cursor.execute_none ("delete from exam_exam_aid where (exam_id, aid_type_code) = (%(exam_id)s, %(code)s)", exam_id=self.exam.exam_id, code=code)
[docs] def insert_aid (self, add_code, aid_notes): self.cursor.execute_none ("insert into exam_exam_aid values (%(exam_id)s, %(aid_type_code)s, %(aid_notes)s)", exam_id=self.exam.exam_id, aid_type_code=add_code, aid_notes=aid_notes)
[docs] def update_aids (self, openbook, notes): self.cursor.execute_none ("update exam_exam set exam_openbook=%(openbook)s, exam_instructions=%(notes)s where exam_id=%(exam_id)s", exam_id=self.exam.exam_id, openbook=openbook, notes=notes)