Esempio n. 1
0
 def get_html_table_row(self) -> str:
     return tr(
         self.seqnum,
         answer(ws.webify(self.code)),
         answer(ws.webify(self.description)),
         answer(ws.webify(self.comment)),
     )
Esempio n. 2
0
 def get_gp_html(self, longform: bool) -> str:
     """Get HTML for general practitioner details."""
     if not self.gp:
         return ""
     if longform:
         return "<br>GP: <b>{}</b>".format(ws.webify(self.gp))
     return ws.webify(self.gp)
Esempio n. 3
0
 def get_address_html(self, longform: bool) -> str:
     """Get HTML for address details."""
     if not self.address:
         return ""
     if longform:
         return "<br>Address: <b>{}</b>".format(ws.webify(self.address))
     return ws.webify(self.address)
Esempio n. 4
0
    def get_all_plots_for_all_tasks_html(self) -> str:
        """HTML for all plots."""
        if self.task_tablename_list is None or len(self.task_tablename_list) == 0:
            return """
                <div class="warning">
                    Unable to generate tracker: no task types specified
                </div>"""
        if self._patient is None:
            return """
                <div class="warning">
                    Unable to generate tracker: no patient details
                </div>"""

        html = ""
        for c in range(len(self.list_of_task_instance_lists)):
            task_instance_list = self.list_of_task_instance_lists[c]
            if len(task_instance_list) == 0:
                continue
            html += """
                <div class="taskheader">
                    <b>{} ({})</b>
                </div>
            """.format(
                ws.webify(task_instance_list[0].longname), ws.webify(task_instance_list[0].shortname)
            )
            html += self.get_all_plots_for_one_task_html(task_instance_list)
        return html
Esempio n. 5
0
 def get_clinical_text(self) -> List[CtvInfo]:
     diagnoses = self.get_psychiatric_diagnoses() + \
         self.get_medical_diagnoses()
     return [
         CtvInfo(
             heading=ws.webify(WSTRING("cpft_lps_dis_discharge_reason")),
             content=self.get_discharge_reason()
         ),
         CtvInfo(
             heading=ws.webify(
                 WSTRING("cpft_lps_dis_referral_reason_t")),
             content=", ".join(self.get_referral_reasons())
         ),
         CtvInfo(
             heading=ws.webify(WSTRING("cpft_lps_dis_diagnoses_t")),
             content=", ".join(diagnoses)
         ),
         CtvInfo(
             heading=ws.webify(WSTRING("cpft_lps_dis_management_t")),
             content=", ".join(self.get_managements())
         ),
         CtvInfo(
             heading=ws.webify(WSTRING("cpft_lps_dis_outcome_t")),
             content=self.outcome
         ),
     ]
Esempio n. 6
0
 def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]:
     diagnoses = (self.get_psychiatric_diagnoses(req) +
                  self.get_medical_diagnoses())
     return [
         CtvInfo(
             heading=ws.webify(self.wxstring(req, "discharge_reason")),
             content=self.get_discharge_reason(req),
         ),
         CtvInfo(
             heading=ws.webify(self.wxstring(req, "referral_reason_t")),
             content=", ".join(self.get_referral_reasons(req)),
         ),
         CtvInfo(
             heading=ws.webify(self.wxstring(req, "diagnoses_t")),
             content=", ".join(diagnoses),
         ),
         CtvInfo(
             heading=ws.webify(self.wxstring(req, "management_t")),
             content=", ".join(self.get_managements(req)),
         ),
         CtvInfo(
             heading=ws.webify(self.wxstring(req, "outcome_t")),
             content=self.outcome,
         ),
     ]
Esempio n. 7
0
 def get_idother_html(self, longform: bool) -> str:
     """Get HTML for 'other' information."""
     if not self.other:
         return ""
     if longform:
         return "<br>Other details: <b>{}</b>".format(ws.webify(self.other))
     return ws.webify(self.other)
Esempio n. 8
0
 def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]:
     infolist = []
     for item in self.items:
         infolist.append(
             CtvInfo(content="<b>{}</b>: {}".format(
                 ws.webify(item.code), ws.webify(item.description))))
     return infolist
Esempio n. 9
0
    def get_id_generic(longform: bool,
                       idnum: int,
                       desc: str,
                       shortdesc: str,
                       serverdesc: str,
                       servershortdesc: str,
                       idnumtext: str,
                       label_id_numbers: bool = False) -> Tuple[bool, str]:
        """Returns (conflict, description).

        Gets ID description/number in HTML format, or "", plus conflict
        information.

        Args:
            longform: verbose (for most HTML) or not (for PDF headers)
            idnum: value of ID number
            desc: description
            shortdesc: short description:
            serverdesc: server's description
            servershortdesc: server's short description
            idnumtext: string used as a prefix if label_id_numbers
            label_id_numbers: whether to use prefix

        In practice:
            longform=False: used in PDF headers
            longform=True, label_id_numbers=True: used in trackers
            longform=True, label_id_numbers=False: used in tasks

        Returns (conflict, description).
            conflict: Boolean; server's description doesn't match patient's
            description: HTML
        """
        if idnum is None:
            return False, ""  # no conflict if no number!
        prefix = "<i>(" + idnumtext + ")</i> " if label_id_numbers else ""
        if longform:
            conflict = (desc != serverdesc)
            if conflict:
                finaldesc = "{} [server] or {} [tablet]".format(serverdesc,
                                                                desc)
            else:
                finaldesc = ws.webify(desc)
            return conflict, "<br>{}{}: <b>{}</b>".format(
                prefix,
                finaldesc,
                idnum
            )
        else:
            conflict = (shortdesc != servershortdesc)
            if conflict:
                finaldesc = "{} [server] or {} [tablet]".format(
                    servershortdesc, shortdesc)
            else:
                finaldesc = ws.webify(shortdesc)
            return conflict, "{}{}: {}.".format(
                prefix,
                finaldesc,
                idnum
            )
Esempio n. 10
0
 def get_clinical_text(self) -> List[CtvInfo]:
     infolist = []
     items = self.get_items()
     for item in items:
         infolist.append(CtvInfo(
             content="<b>{}</b>: {}".format(ws.webify(item.code),
                                            ws.webify(item.description))
         ))
     return infolist
Esempio n. 11
0
 def get_html_table_row(self) -> str:
     return ("<tr>" + "<td>{}</td>" * 13 + "</th>").format(
         self.trial, self.trial_ignoring_catch_trials,
         self.target_presented, self.target_time,
         ws.number_to_dp(self.intensity,
                         DP), self.choice_time, self.responded,
         self.response_time, self.response_latency_ms, self.yes, self.no,
         ws.webify(self.caught_out_reset),
         ws.webify(self.trial_num_in_calculation_sequence))
Esempio n. 12
0
 def get_psychiatric_diagnoses(self, req: CamcopsRequest) -> List[str]:
     psychiatric_diagnoses = [
         self.wxstring(req, "diagnosis_no_active_mental_health_problem")
     ] if self.diagnosis_no_active_mental_health_problem else []
     for i in range(1, 4 + 1):  # magic number
         if getattr(self, "diagnosis_psych_" + str(i) + "_icd10code"):
             psychiatric_diagnoses.append(
                 ws.webify(
                     getattr(self, "diagnosis_psych_" + str(i) +
                             "_icd10code")) + " – " +
                 ws.webify(
                     getattr(self, "diagnosis_psych_" + str(i) +
                             "_description")))
     return psychiatric_diagnoses
Esempio n. 13
0
 def get_psychiatric_diagnoses(self) -> List[str]:
     psychiatric_diagnoses = [
         WSTRING("cpft_lps_dis_diagnosis_no_active_mental_health_problem")
     ] if self.diagnosis_no_active_mental_health_problem else []
     for i in range(1, 4 + 1):  # magic number
         if getattr(self, "diagnosis_psych_" + str(i) + "_icd10code"):
             psychiatric_diagnoses.append(
                 ws.webify(getattr(self, "diagnosis_psych_" +
                                   str(i) + "_icd10code")) +
                 " – " +
                 ws.webify(getattr(self, "diagnosis_psych_" +
                                   str(i) + "_description"))
             )
     return psychiatric_diagnoses
Esempio n. 14
0
 def get_medical_diagnoses(self) -> List[str]:
     medical_diagnoses = []
     for i in range(1, 4 + 1):  # magic number
         if getattr(self, "diagnosis_medical_" + str(i)):
             medical_diagnoses.append(
                 ws.webify(getattr(self, "diagnosis_medical_" + str(i))))
     return medical_diagnoses
Esempio n. 15
0
 def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]:
     return [
         CtvInfo(
             heading=ws.webify(self.wxstring(req, "f_referral_reason_t")),
             content=self.referral_reason,
         )
     ]
 def get_html_table_row(self) -> str:
     return ("<tr>" + "<td>{}</td>" * 13 + "</th>").format(
         self.trial,
         self.trial_ignoring_catch_trials,
         self.target_presented,
         self.target_time,
         ws.number_to_dp(self.intensity, DP),
         self.choice_time,
         self.responded,
         self.response_time,
         self.response_latency_ms,
         self.yes,
         self.no,
         ws.webify(self.caught_out_reset),
         ws.webify(self.trial_num_in_calculation_sequence)
     )
Esempio n. 17
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     if self.achieved is not None:
         achieved = "{}. {}".format(self.achieved,
                                    self.get_achieved_text(req))
     else:
         achieved = None
     h = """
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {tr_is_complete}
             </table>
         </div>
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <th width="50%">Question</th>
                 <th width="50%">Answer</th>
             </tr>
             {aim}
             {achieved}
         </table>
     """.format(
         CssClass=CssClass,
         tr_is_complete=self.get_is_complete_tr(req),
         aim=tr_qa(self.wxstring(req, "q_aim"), ws.webify(self.aim)),
         achieved=tr_qa(self.wxstring(req, "q_achieved"), achieved),
     )
     return h
Esempio n. 18
0
    def get_task_html(self) -> str:
        score = self.total_score()
        h = """
            <div class="summary">
                <table class="summary">
        """
        h += self.get_is_complete_tr()
        h += tr(WSTRING("total_score"), answer(score) + " / 63")
        h += """
                </table>
            </div>
            <div class="explanation">
                All questions are scored from 0–3
                (0 free of symptoms, 3 most symptomatic).
            </div>
            <table class="taskdetail">
                <tr>
                    <th width="70%">Question</th>
                    <th width="30%">Answer</th>
                </tr>
        """
        h += tr_qa(WSTRING("bdi_which_scale"), ws.webify(self.bdi_scale))

        for q in range(1, self.NQUESTIONS + 1):
            h += tr_qa("{} {}".format(WSTRING("question"), q),
                       getattr(self, "q" + str(q)))
        h += """
            </table>
        """ + DATA_COLLECTION_ONLY_DIV
        return h
Esempio n. 19
0
 def get_clinical_text(self) -> List[CtvInfo]:
     if not self.is_complete():
         return CTV_INCOMPLETE
     return [CtvInfo(
         content="{} total score {}/63".format(
             ws.webify(self.bdi_scale), self.total_score())
     )]
Esempio n. 20
0
 def get_note_as_html(self) -> str:
     """Return an HTML-formatted version of the note."""
     return "[{dt}, {user}]<br><b>{note}</b>".format(
         dt=self.note_at or "?",
         user=self.get_username() or "?",
         note=ws.webify(self.note) or "",
     )
Esempio n. 21
0
 def get_html_data_row(self,
                       showmessage: bool = False,
                       showreply: bool = False) -> bool:
     """Returns HTML table data row for this instance."""
     html = "<tr>"
     for fs in self.FIELDSPECS:
         name = fs["name"]
         if name == "message" and not showmessage:
             continue
         if name == "reply" and not showreply:
             continue
         value = ws.webify(getattr(self, name))
         if name == "serverpk":
             contents = "<a href={}>{}</a>".format(
                 cc_task.get_url_task_html(self.basetable, self.serverpk),
                 value
             )
         elif name == "run_id":
             contents = "<a href={}>{}</a>".format(
                 get_url_hl7_run(value),
                 value
             )
         else:
             contents = str(value)
         html += "<td>{}</td>".format(contents)
     html += "</tr>\n"
     return html
Esempio n. 22
0
 def get_medical_diagnoses(self) -> List[str]:
     medical_diagnoses = []
     for i in range(1, 4 + 1):  # magic number
         if getattr(self, "diagnosis_medical_" + str(i)):
             medical_diagnoses.append(
                 ws.webify(getattr(self, "diagnosis_medical_" + str(i))))
     return medical_diagnoses
Esempio n. 23
0
 def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]:
     if not self.is_complete():
         return CTV_INCOMPLETE
     return [CtvInfo(
         content="{} total score {}/{}".format(
             ws.webify(self.bdi_scale), self.total_score(), MAX_SCORE)
     )]
Esempio n. 24
0
 def get_html_table_rows(self) -> str:
     return """
         <tr class="subheading"><td>Photo {}: <b>{}</b></td></tr>
         <tr><td>{}</td></tr>
     """.format(
         self.seqnum + 1, ws.webify(self.description),
         self.get_blob_png_html(),
     )
Esempio n. 25
0
 def get_html_data_row(self) -> str:
     html = "<tr>"
     for fs in self.FIELDSPECS:
         name = fs["name"]
         value = ws.webify(getattr(self, name))
         html += "<td>{}</td>".format(value)
     html += "</tr>\n"
     return html
Esempio n. 26
0
 def get_surname_forename_upper(self) -> str:
     """
     Get "SURNAME, FORENAME" in HTML-safe format, using "(UNKNOWN)" for
     missing details.
     """
     s = self.surname.upper() if self.surname else "(UNKNOWN)"
     f = self.forename.upper() if self.surname else "(UNKNOWN)"
     return ws.webify(s + ", " + f)
Esempio n. 27
0
 def get_note_as_html(self) -> str:
     """
     Return an HTML-formatted version of the note.
     """
     return "[{dt}, {user}]<br><b>{note}</b>".format(
         dt=self.note_at or "?",
         user=self.get_username() or "?",
         note=ws.webify(self.note) or "",
     )
Esempio n. 28
0
 def get_task_html(self) -> str:
     h = """
         <table class="taskdetail">
             <tr>
                 <td width="33%">Location:</td>
                 <td width="67%"><b>{}</b></td>
             </tr>
     """.format(
         ws.webify(self.location)
     )
     h += tr_qa("Start:", format_datetime_string(self.start, DATEFORMAT.SHORT_DATETIME, None))
     h += tr_qa("End:", format_datetime_string(self.end, DATEFORMAT.SHORT_DATETIME, None))
     h += tr(italic("Calculated duration (hours:minutes)"), italic(get_duration_h_m(self.start, self.end)))
     h += tr_qa("Patient contact?", get_yes_no_none(self.patient_contact))
     h += tr_qa("Staff liaison?", get_yes_no_none(self.staff_liaison))
     h += tr_qa("Other liaison?", get_yes_no_none(self.other_liaison))
     h += tr_qa("Comment:", ws.webify(self.comment))
     return h
Esempio n. 29
0
def WXSTRING(taskname: str,
             stringname: str,
             default: str = None,
             provide_default_if_none: bool = True) -> str:
    """Returns a web-safe version of an XSTRING (see above)."""
    value = XSTRING(taskname, stringname, default,
                    provide_default_if_none=provide_default_if_none)
    if value is None and not provide_default_if_none:
        return None
    return ws.webify(value)
Esempio n. 30
0
 def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]:
     if not self.is_complete():
         return CTV_INCOMPLETE
     infolist = [
         CtvInfo(content="Pertains to: {}. Category: {}.".format(
             format_datetime(self.date_pertains_to, DateFormat.LONG_DATE),
             self.get_full_description(req)))
     ]
     if self.comments:
         infolist.append(CtvInfo(content=ws.webify(self.comments)))
     return infolist
Esempio n. 31
0
 def get_html_table_rows(self) -> str:
     # noinspection PyTypeChecker
     return """
         <tr class="{CssClass.SUBHEADING}">
             <td>Photo {num}: <b>{description}</b></td>
         </tr>
         <tr><td>{photo}</td></tr>
     """.format(CssClass=CssClass,
                num=self.seqnum,
                description=ws.webify(self.description),
                photo=get_blob_img_html(self.photo))
Esempio n. 32
0
def simple_success_message(msg, extra_html=""):
    """HTML for simple success message."""
    return cc_pls.pls.WEBSTART + """
        <h1>Success</h1>
        <div>{}</div>
        {}
        {}
    """.format(
        ws.webify(msg),
        extra_html,
        get_return_to_main_menu_line()
    ) + WEBEND
Esempio n. 33
0
 def get_clinical_text(self) -> List[CtvInfo]:
     if not self.is_complete():
         return CTV_INCOMPLETE
     infolist = [CtvInfo(
         content="Pertains to: {}. Category: {}.".format(
             format_datetime_string(self.date_pertains_to,
                                    DATEFORMAT.LONG_DATE),
             self.get_description()
         )
     )]
     if self.comments:
         infolist.append(CtvInfo(content=ws.webify(self.comments)))
     return infolist
Esempio n. 34
0
 def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]:
     if not self.is_complete():
         return CTV_INCOMPLETE
     category = (("Meets" if self.meets_criteria() else "Does not meet") +
                 " criteria for mixed affective episode")
     infolist = [
         CtvInfo(content="Pertains to: {}. {}.".format(
             format_datetime(self.date_pertains_to, DateFormat.LONG_DATE),
             category))
     ]
     if self.comments:
         infolist.append(CtvInfo(content=ws.webify(self.comments)))
     return infolist
Esempio n. 35
0
 def get_task_html(self) -> str:
     return """
         <table class="taskdetail">
             <tr class="subheading"><td>Description</td></tr>
             <tr><td>{}</td></tr>
             <tr class="subheading"><td>Photo</td></tr>
             <tr><td>{}</td></tr>
         </table>
     """.format(
         answer(ws.webify(self.description), default="(No description)",
                default_for_blank_strings=True),
         # ... xhtml2pdf crashes if the contents are empty...
         self.get_blob_png_html(self.photo_blobid, self.rotation)
     )
Esempio n. 36
0
 def get_task_html(self) -> str:
     # Avoid tables - PDF generator crashes if text is too long.
     h = """
         <div class="heading">
             {heading_location}
         </div>
         <div>
             {location}
         </div>
         <div class="heading">
             {heading_note}
         </div>
         <div>
             {note}
         </div>
     """.format(
         heading_location=WSTRING("location"),
         location=answer(ws.webify(self.location),
                         default_for_blank_strings=True),
         heading_note=WSTRING("progressnote_note"),
         note=answer(ws.webify(self.note), default_for_blank_strings=True),
     )
     return h
Esempio n. 37
0
 def get_current_user_html(self, offer_main_menu: bool = True) -> str:
     """HTML showing current database/user, +/- link to main menu."""
     if self.username:
         user = "******".format(ws.webify(self.username))
     else:
         user = ""
     database = cc_html.get_database_title_string()
     if offer_main_menu:
         menu = """ <a href="{}">Return to main menu</a>.""".format(
             cc_html.get_url_main_menu())
     else:
         menu = ""
     if not user and not database and not menu:
         return ""
     return "<div>{} {}{}</div>".format(database, user, menu)
    def get_task_html(self, req: CamcopsRequest) -> str:
        html = """
            <div class="{CssClass.SUMMARY}">
                <table class="{CssClass.SUMMARY}">
                    {is_complete_tr}
                </table>
            </div>
            <table class="{CssClass.TASKDETAIL}">
                <tr>
                    <th width="40%">{condition}</th>
                    <th width="20%">{yn}</th>
                    <th width="40%">{comment}</th>
                </tr>
        """.format(
            CssClass=CssClass,
            is_complete_tr=self.get_is_complete_tr(req),
            condition=self.xstring(req, X_HEADING_CONDITION),
            yn=self.xstring(req, X_HEADING_YN),
            comment=self.xstring(req, X_HEADING_COMMENT),
        )

        for qinfo in QUESTIONS:
            if qinfo.has_heading():
                html += tr_span_col(
                    self.xstring(req, qinfo.heading_xmlstr),
                    cols=3,
                    tr_class=CssClass.SUBHEADING,
                )
            yn_value = getattr(self, qinfo.fieldname_yn)
            yn_str = get_yes_no_none(req, yn_value)
            if yn_value:
                yn_str = bold(yn_str)
            comment_value = getattr(self, qinfo.fieldname_comment)
            html += """
                <tr>
                    <td>{question}</td>
                    <td>{yn}</td>
                    <td>{comment}</td>
                </tr>
            """.format(
                question=self.xstring(req, qinfo.question_xmlstr),
                yn=yn_str,
                comment=(bold(ws.webify(comment_value))
                         if comment_value else ""),
            )

        html += "</table>"
        return html
Esempio n. 39
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     # noinspection PyTypeChecker
     return """
         <table class="{CssClass.TASKDETAIL}">
             <tr class="{CssClass.SUBHEADING}"><td>Description</td></tr>
             <tr><td>{description}</td></tr>
             <tr class="{CssClass.SUBHEADING}"><td>Photo</td></tr>
             <tr><td>{photo}</td></tr>
         </table>
     """.format(
         CssClass=CssClass,
         description=answer(ws.webify(self.description),
                            default="(No description)",
                            default_for_blank_strings=True),
         # ... xhtml2pdf crashes if the contents are empty...
         photo=get_blob_img_html(self.photo))
Esempio n. 40
0
def get_device_filter_dropdown(currently_selected_id: int = None) -> str:
    """Get HTML list of all known tablet devices."""
    s = """
        <select name="{}">
            <option value="">(all)</option>
    """.format(PARAM.DEVICE)
    rows = pls.db.fetchall("SELECT id FROM {table}".format(
        table=Device.TABLENAME))
    for pk in [row[0] for row in rows]:
        device = Device(pk)
        s += """<option value="{pk}"{sel}>{name}</option>""".format(
            pk=pk,
            name=ws.webify(device.get_friendly_name_and_id()),
            sel=ws.option_selected(currently_selected_id, pk),
        )
    s += """</select>"""
    return s
Esempio n. 41
0
 def get_clinical_text(self) -> List[CtvInfo]:
     if not self.is_complete():
         return CTV_INCOMPLETE
     category = (
         ("Meets" if self.meets_criteria() else "Does not meet") +
         " criteria for mixed affective episode"
     )
     infolist = [CtvInfo(
         content="Pertains to: {}. {}.".format(
             format_datetime_string(self.date_pertains_to,
                                    DATEFORMAT.LONG_DATE),
             category
         )
     )]
     if self.comments:
         infolist.append(CtvInfo(content=ws.webify(self.comments)))
     return infolist
Esempio n. 42
0
 def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]:
     if not self.is_complete():
         return CTV_INCOMPLETE
     c = self.meets_general_criteria()
     if c is None:
         category = "Unknown if met or not met"
     elif c:
         category = "Met"
     else:
         category = "Not met"
     infolist = [
         CtvInfo(
             content=("Pertains to: {}. General criteria for "
                      "schizophrenia: {}.".format(
                          format_datetime(self.date_pertains_to,
                                          DateFormat.LONG_DATE), category)))
     ]
     if self.comments:
         infolist.append(CtvInfo(content=ws.webify(self.comments)))
     return infolist
Esempio n. 43
0
def get_filter_html(filter_name: str,
                    filter_value: Any,
                    clear_action: str,
                    apply_field_html: str,
                    apply_action: str,
                    filter_list: List[str]) -> bool:
    """HTML to view or change a filter."""
    # returns: found a filter?
    no_filter_value = (
        filter_value is None or (isinstance(filter_value, str) and
                                 not filter_value)
    )
    if no_filter_value:
        filter_list.append("""
                    {filter_name}: {apply_field_html}
                    <br>
        """.format(
            filter_name=filter_name,
            apply_field_html=apply_field_html,
            # apply_action=apply_action,
        ))
        #            <input type="submit" name="{apply_action}" value="Filter">
        return False
    else:
        filter_list.append("""
                    {filter_name}: <b>{filter_value}</b>
                    <input type="submit" name="{clear_action}" value="Clear">
                    {apply_field_html}
                    <br>
        """.format(
            filter_name=filter_name,
            filter_value=ws.webify(filter_value),
            clear_action=clear_action,
            apply_field_html=apply_field_html,
            # apply_action=apply_action
        ))
        #            <input type="submit" name="{apply_action}" value="Filter">
        return True
Esempio n. 44
0
 def get_clinical_text(self) -> List[CtvInfo]:
     if not self.is_complete():
         return CTV_INCOMPLETE
     c = self.meets_criteria()
     if c is None:
         category = "Unknown if met or not met"
     elif c:
         category = "Met"
     else:
         category = "Not met"
     infolist = [CtvInfo(
         content=(
             "Pertains to: {}. Criteria for schizotypal "
             "disorder: {}.".format(
                 format_datetime_string(self.date_pertains_to,
                                        DATEFORMAT.LONG_DATE),
                 category
             )
         )
     )]
     if self.comments:
         infolist.append(CtvInfo(content=ws.webify(self.comments)))
     return infolist
Esempio n. 45
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     h = """
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <td width="33%">Location:</td>
                 <td width="67%"><b>{loc}</b></td>
             </tr>
     """.format(
         CssClass=CssClass,
         loc=ws.webify(self.location),
     )
     h += tr_qa(
         "Start:",
         format_datetime(self.start, DateFormat.SHORT_DATETIME, None))
     h += tr_qa("End:",
                format_datetime(self.end, DateFormat.SHORT_DATETIME, None))
     h += tr(italic("Calculated duration (hours:minutes)"),
             italic(get_duration_h_m(self.start, self.end)))
     h += tr_qa("Patient contact?",
                get_yes_no_none(req, self.patient_contact))
     h += tr_qa("Staff liaison?", get_yes_no_none(req, self.staff_liaison))
     h += tr_qa("Other liaison?", get_yes_no_none(req, self.other_liaison))
     h += tr_qa("Comment:", self.comment)
     return h
Esempio n. 46
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     # Avoid tables - PDF generator crashes if text is too long.
     h = """
         <div class="{CssClass.HEADING}">
             {heading_location}
         </div>
         <div>
             {location}
         </div>
         <div class="{CssClass.HEADING}">
             {heading_note}
         </div>
         <div>
             {note}
         </div>
     """.format(
         CssClass=CssClass,
         heading_location=req.wappstring("location"),
         location=answer(ws.webify(self.location),
                         default_for_blank_strings=True),
         heading_note=req.wappstring("note"),
         note=answer(self.note, default_for_blank_strings=True),
     )
     return h
Esempio n. 47
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        score = self.total_score()

        # Suicidal thoughts:
        suicidality_score = getattr(self, SUICIDALITY_FN)
        if suicidality_score is None:
            suicidality_text = bold("? (not completed)")
            suicidality_css_class = CssClass.INCOMPLETE
        elif suicidality_score == 0:
            suicidality_text = str(suicidality_score)
            suicidality_css_class = ""
        else:
            suicidality_text = bold(str(suicidality_score))
            suicidality_css_class = CssClass.WARNING

        # Custom somatic score for Khandaker Insight study:
        somatic_css_class = ""
        if self.is_bdi_ii():
            somatic_values = self.get_values(
                CUSTOM_SOMATIC_KHANDAKER_BDI_II_FIELDS)
            somatic_missing = False
            somatic_score = 0
            for v in somatic_values:
                if v is None:
                    somatic_missing = True
                    somatic_css_class = CssClass.INCOMPLETE
                    break
                else:
                    somatic_score += int(v)
            somatic_text = ("incomplete"
                            if somatic_missing else str(somatic_score))
        else:
            somatic_text = "N/A"  # not the BDI-II

        # Question rows:
        q_a = ""
        qdict = TOPICS_BY_SCALE.get(self.bdi_scale)
        topic = "?"
        for q in range(1, NQUESTIONS + 1):
            if qdict:
                topic = qdict.get(q, "??")
            q_a += tr_qa(
                f"{req.sstring(SS.QUESTION)} {q} ({topic})",
                getattr(self, "q" + str(q)),
            )

        # HTML:
        tr_somatic_score = tr(
            td("Custom somatic score for Insight study <sup>[2]</sup> "
               "(sum of scores for questions {}, for BDI-II only)".format(
                   ", ".join(
                       "Q" + str(qnum)
                       for qnum in CUSTOM_SOMATIC_KHANDAKER_BDI_II_QNUMS))),
            td(somatic_text, td_class=somatic_css_class),
            literal=True,
        )
        tr_which_scale = tr_qa(
            req.wappstring(AS.BDI_WHICH_SCALE) + " <sup>[3]</sup>",
            ws.webify(self.bdi_scale),
        )
        return f"""
Esempio n. 48
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     h = f"""
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {self.get_is_complete_tr(req)}
             </table>
         </div>
         <div class="{CssClass.EXPLANATION}">
             1. Simple discrimination (SD), and 2. reversal (SDr);
             3. compound discrimination (CD), and 4. reversal (CDr);
             5. intradimensional shift (ID), and 6. reversal (IDr);
             7. extradimensional shift (ED), and 8. reversal (EDr).
         </div>
         <table class="{CssClass.TASKCONFIG}">
             <tr>
                 <th width="50%">Configuration variable</th>
                 <th width="50%">Value</th>
             </tr>
     """
     h += tr_qa(self.wxstring(req, "last_stage"), self.last_stage)
     h += tr_qa(
         self.wxstring(req, "max_trials_per_stage"),
         self.max_trials_per_stage,
     )
     h += tr_qa(
         self.wxstring(req, "progress_criterion_x"),
         self.progress_criterion_x,
     )
     h += tr_qa(
         self.wxstring(req, "progress_criterion_y"),
         self.progress_criterion_y,
     )
     h += tr_qa(self.wxstring(req, "min_number"), self.min_number)
     h += tr_qa(self.wxstring(req, "max_number"), self.max_number)
     h += tr_qa(self.wxstring(req, "pause_after_beep_ms"),
                self.pause_after_beep_ms)
     h += tr_qa(self.wxstring(req, "iti_ms"), self.iti_ms)
     h += tr_qa(
         self.wxstring(req, "counterbalance_dimensions") + "<sup>[1]</sup>",
         self.counterbalance_dimensions,
     )
     h += tr_qa(req.sstring(SS.VOLUME_0_TO_1), self.volume)
     h += tr_qa(self.wxstring(req, "offer_abort"), self.offer_abort)
     h += tr_qa(
         self.wxstring(req, "debug_display_stimuli_only"),
         self.debug_display_stimuli_only,
     )
     h += tr_qa(
         "Shapes (as a JSON-encoded array of SVG "
         "definitions; X and Y range both –60 to +60)",
         ws.webify(self.shape_definitions_svg),
     )
     h += f"""
         </table>
         <table class="{CssClass.TASKDETAIL}">
             <tr><th width="50%">Measure</th><th width="50%">Value</th></tr>
     """
     h += tr_qa("Aborted?", get_yes_no_none(req, self.aborted))
     h += tr_qa("Finished?", get_yes_no_none(req, self.finished))
     h += tr_qa("Last trial completed", self.last_trial_completed)
     h += ("""
             </table>
             <div>Stage specifications and results:</div>
         """ + self.get_stage_html() +
           "<div>Trial-by-trial results:</div>" + self.get_trial_html() +
           f"""
             <div class="{CssClass.FOOTNOTES}">
                 [1] Counterbalancing of dimensions is as follows, with
                 notation X/Y indicating that X is the first relevant
                 dimension (for stages SD–IDr) and Y is the second relevant
                 dimension (for stages ED–EDr).
                 0: shape/colour.
                 1: colour/number.
                 2: number/shape.
                 3: shape/number.
                 4: colour/shape.
                 5: number/colour.
             </div>
         """)
     return h
Esempio n. 49
0
 def subsubhead_text(self, req: CamcopsRequest, fieldname: str) -> str:
     return (
         self.subsubheading(req, fieldname) +
         '<div><b>{}</b></div>'.format(ws.webify(getattr(self, fieldname))))
Esempio n. 50
0
def bold_webify(x: str) -> str:
    """
    Webifies the string, then makes it bold.
    """
    return bold(ws.webify(x))
Esempio n. 51
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        score = self.total_score()

        # Suicidal thoughts:
        suicidality_score = getattr(self, SUICIDALITY_FN)
        if suicidality_score is None:
            suicidality_text = bold("? (not completed)")
            suicidality_css_class = CssClass.INCOMPLETE
        elif suicidality_score == 0:
            suicidality_text = str(suicidality_score)
            suicidality_css_class = ""
        else:
            suicidality_text = bold(str(suicidality_score))
            suicidality_css_class = CssClass.WARNING

        # Custom somatic score for Khandaker Insight study:
        somatic_css_class = ""
        if self.is_bdi_ii():
            somatic_values = self.get_values(
                CUSTOM_SOMATIC_KHANDAKER_BDI_II_FIELDS)
            somatic_missing = False
            somatic_score = 0
            for v in somatic_values:
                if v is None:
                    somatic_missing = True
                    somatic_css_class = CssClass.INCOMPLETE
                    break
                else:
                    somatic_score += int(v)
            somatic_text = ("incomplete" if somatic_missing
                            else str(somatic_score))
        else:
            somatic_text = "N/A"  # not the BDI-II

        # Question rows:
        q_a = ""
        qdict = TOPICS_BY_SCALE.get(self.bdi_scale)
        topic = "?"
        for q in range(1, NQUESTIONS + 1):
            if qdict:
                topic = qdict.get(q, "??")
            q_a += tr_qa(
                "{question} {qnum} ({topic})".format(
                    question=req.wappstring("question"),
                    qnum=q,
                    topic=topic,
                ),
                getattr(self, "q" + str(q))
            )

        # HTML:
        h = """
            <div class="{CssClass.SUMMARY}">
                <table class="{CssClass.SUMMARY}">
                    {tr_is_complete}
                    {tr_total_score}
                    <tr>
                        <td>
                            Suicidal thoughts/wishes score
                            (Q{suicidality_qnum}) <sup>[1]</sup>
                        </td>
                        {td_suicidality}
                    </tr>
                    {tr_somatic_score}
                </table>
            </div>
            <div class="{CssClass.EXPLANATION}">
                All questions are scored from 0–3
                (0 free of symptoms, 3 most symptomatic).
            </div>
            <table class="{CssClass.TASKDETAIL}">
                <tr>
                    <th width="70%">Question</th>
                    <th width="30%">Answer</th>
                </tr>
                {tr_which_scale}
                {q_a}
            </table>
            <div class="{CssClass.FOOTNOTES}">
                [1] Suicidal thoughts are asked about in Q{suicidality_qnum}
                    for all of: BDI-I (1961), BDI-IA (1978), and BDI-II (1996).

                [2] Insight study:
                    <a href="https://doi.org/10.1186/ISRCTN16942542">doi:10.1186/ISRCTN16942542</a>

                [3] See the
                    <a href="https://camcops.readthedocs.io/en/latest/tasks/bdi.html">CamCOPS
                    BDI help</a> for full references and bibliography for the
                    citations that follow.

                    <b>The BDI rates “right now” [Beck1988].
                    The BDI-IA rates the past week [Beck1988].
                    The BDI-II rates the past two weeks [Beck1996b].</b>

                    1961 BDI(-I) question topics from [Beck1988].
                    1978 BDI-IA question topics from [Beck1996b].
                    1996 BDI-II question topics from [Steer1999], [Gary2018].
                </ul>

            </div>
            {data_collection_only_div}
        """.format(  # noqa
            CssClass=CssClass,
            tr_is_complete=self.get_is_complete_tr(req),
            tr_total_score=tr(
                req.wappstring("total_score"),
                answer(score) + " / {}".format(MAX_SCORE)
            ),
            suicidality_qnum=SUICIDALITY_QNUM,
            td_suicidality=td(suicidality_text, td_class=suicidality_css_class),  # noqa
            tr_somatic_score=tr(
                td(
                    "Custom somatic score for Insight study <sup>[2]</sup> "
                    "(sum of scores for questions {}, for BDI-II only)".format(
                        ", ".join("Q" + str(qnum) for qnum in
                                  CUSTOM_SOMATIC_KHANDAKER_BDI_II_QNUMS))
                ),
                td(somatic_text, td_class=somatic_css_class),
                literal=True
            ),
            tr_which_scale=tr_qa(
                req.wappstring("bdi_which_scale") + " <sup>[3]</sup>",
                ws.webify(self.bdi_scale)
            ),
            q_a=q_a,
            data_collection_only_div=DATA_COLLECTION_ONLY_DIV
        )
        return h
Esempio n. 52
0
    def get_task_html(self) -> str:
        h = self.get_standard_clinician_comments_block(self.comments) + """
            <div class="summary">
                <table class="summary">
        """ + self.get_is_complete_tr()
        h += tr_qa(WSTRING("date_pertains_to"),
                   format_datetime_string(self.date_pertains_to,
                                          DATEFORMAT.LONG_DATE, default=None))
        h += tr_qa(WSTRING("icd10pd_meets_general_criteria"),
                   get_yes_no_none(self.has_pd()))
        h += tr_qa(WSTRING("icd10_paranoid_pd_title"),
                   get_yes_no_none(self.has_paranoid_pd()))
        h += tr_qa(WSTRING("icd10_schizoid_pd_title"),
                   get_yes_no_none(self.has_schizoid_pd()))
        h += tr_qa(WSTRING("icd10_dissocial_pd_title"),
                   get_yes_no_none(self.has_dissocial_pd()))
        h += tr_qa(WSTRING("icd10_eu_pd_i_title"),
                   get_yes_no_none(self.has_eupd_i()))
        h += tr_qa(WSTRING("icd10_eu_pd_b_title"),
                   get_yes_no_none(self.has_eupd_b()))
        h += tr_qa(WSTRING("icd10_histrionic_pd_title"),
                   get_yes_no_none(self.has_histrionic_pd()))
        h += tr_qa(WSTRING("icd10_anankastic_pd_title"),
                   get_yes_no_none(self.has_anankastic_pd()))
        h += tr_qa(WSTRING("icd10_anxious_pd_title"),
                   get_yes_no_none(self.has_anxious_pd()))
        h += tr_qa(WSTRING("icd10_dependent_pd_title"),
                   get_yes_no_none(self.has_dependent_pd()))

        h += """
                </table>
            </div>
            <div>
                <p><i>Vignette:</i></p>
                <p>{}</p>
            </div>
            <table class="taskdetail">
                <tr>
                    <th width="80%">Question</th>
                    <th width="20%">Answer</th>
                </tr>
        """.format(
            answer(ws.webify(self.vignette), default_for_blank_strings=True)
        )

        # General
        h += subheading_spanning_two_columns(WSTRING("icd10pd_general"))
        h += self.get_twocol_bool_row_true_false("g1", WSTRING("icd10pd_G1"))
        h += self.pd_b_text("icd10pd_G1b")
        for i in range(1, Icd10SpecPD.N_GENERAL_1 + 1):
            h += self.get_twocol_bool_row_true_false(
                "g1_" + str(i), WSTRING("icd10pd_G1_" + str(i)))
        for i in range(2, Icd10SpecPD.N_GENERAL + 1):
            h += self.get_twocol_bool_row_true_false(
                "g" + str(i), WSTRING("icd10pd_G" + str(i)))

        # Paranoid, etc.
        h += self.standard_pd_html("paranoid", Icd10SpecPD.N_PARANOID)
        h += self.standard_pd_html("schizoid", Icd10SpecPD.N_SCHIZOID)
        h += self.standard_pd_html("dissocial", Icd10SpecPD.N_DISSOCIAL)

        # EUPD is special
        h += self.pd_heading("icd10_eu_pd_title")
        h += self.pd_skiprow("eu")
        h += self.pd_general_criteria_bits()
        h += self.pd_subheading("icd10_eu_pd_i_title")
        h += self.pd_b_text("icd10_eu_pd_i_B")
        for i in range(1, Icd10SpecPD.N_EUPD_I + 1):
            h += self.pd_basic_row("eu", i)
        h += self.pd_subheading("icd10_eu_pd_b_title")
        h += self.pd_b_text("icd10_eu_pd_b_B")
        for i in range(Icd10SpecPD.N_EUPD_I + 1, Icd10SpecPD.N_EU + 1):
            h += self.pd_basic_row("eu", i)

        # Back to plain ones
        h += self.standard_pd_html("histrionic", Icd10SpecPD.N_HISTRIONIC)
        h += self.standard_pd_html("anankastic", Icd10SpecPD.N_ANANKASTIC)
        h += self.standard_pd_html("anxious", Icd10SpecPD.N_ANXIOUS)
        h += self.standard_pd_html("dependent", Icd10SpecPD.N_DEPENDENT)

        # Done
        h += """
            </table>
        """ + ICD10_COPYRIGHT_DIV
        return h
Esempio n. 53
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     dict_q1 = {None: None}
     dict_q3 = {None: None}
     dict_q4 = {None: None}
     dict_q5 = {None: None}
     dict_q11 = {None: None}
     dict_q12 = {None: None}
     for option in range(1, 5):
         dict_q1[option] = self.wxstring(req, "q1_option" + str(option))
     for option in range(1, 6):
         dict_q3[option] = self.wxstring(req, "q3_option" + str(option))
         dict_q11[option] = self.wxstring(req, "q11_option" + str(option))
     for option in range(0, 6):
         prefix = str(option) + " – " if option > 0 else ""
         dict_q4[option] = prefix + self.wxstring(req,
                                                  "q4_option" + str(option))
         dict_q5[option] = prefix + self.wxstring(req,
                                                  "q5_option" + str(option))
     for option in range(1, 17):
         dict_q12[option] = self.wxstring(req,
                                          "ethnicity_option" + str(option))
     h = f"""
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {self.get_is_complete_tr(req)}
             </table>
         </div>
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <th width="60%">Question</th>
                 <th width="40%">Answer</th>
             </tr>
     """
     ell = "&hellip; "  # horizontal ellipsis
     sep_row = subheading_spanning_two_columns("<br>")
     blank_cell = td("", td_class=CssClass.SUBHEADING)
     h += tr_qa(self.wxstring(req, "q_doctor"), ws.webify(self.doctor))
     h += sep_row
     h += tr_qa(self.wxstring(req, "q1"), get_from_dict(dict_q1, self.q1))
     h += tr(td(self.wxstring(req, "q2")), blank_cell, literal=True)
     h += tr_qa(
         ell + self.wxstring(req, "q2_a"),
         get_yes_no_none(req, self.q2a),
         default="",
     )
     h += tr_qa(
         ell + self.wxstring(req, "q2_b"),
         get_yes_no_none(req, self.q2b),
         default="",
     )
     h += tr_qa(
         ell + self.wxstring(req, "q2_c"),
         get_yes_no_none(req, self.q2c),
         default="",
     )
     h += tr_qa(
         ell + self.wxstring(req, "q2_d"),
         get_yes_no_none(req, self.q2d),
         default="",
     )
     h += tr_qa(
         ell + self.wxstring(req, "q2_e"),
         get_yes_no_none(req, self.q2e),
         default="",
     )
     h += tr_qa(
         ell + self.wxstring(req, "q2_f"),
         get_yes_no_none(req, self.q2f),
         default="",
     )
     h += tr_qa(
         ell + ell + self.wxstring(req, "q2f_s"),
         ws.webify(self.q2f_details),
     )
     h += tr_qa(self.wxstring(req, "q3"), get_from_dict(dict_q3, self.q3))
     h += tr(td(self.wxstring(req, "q4")), blank_cell, literal=True)
     h += tr_qa(ell + self.wxstring(req, "q4_a"),
                get_from_dict(dict_q4, self.q4a))
     h += tr_qa(ell + self.wxstring(req, "q4_b"),
                get_from_dict(dict_q4, self.q4b))
     h += tr_qa(ell + self.wxstring(req, "q4_c"),
                get_from_dict(dict_q4, self.q4c))
     h += tr_qa(ell + self.wxstring(req, "q4_d"),
                get_from_dict(dict_q4, self.q4d))
     h += tr_qa(ell + self.wxstring(req, "q4_e"),
                get_from_dict(dict_q4, self.q4e))
     h += tr_qa(ell + self.wxstring(req, "q4_f"),
                get_from_dict(dict_q4, self.q4f))
     h += tr_qa(ell + self.wxstring(req, "q4_g"),
                get_from_dict(dict_q4, self.q4g))
     h += tr(td(self.wxstring(req, "q5")), blank_cell, literal=True)
     h += tr_qa(ell + self.wxstring(req, "q5_a"),
                get_from_dict(dict_q5, self.q5a))
     h += tr_qa(ell + self.wxstring(req, "q5_b"),
                get_from_dict(dict_q5, self.q5b))
     h += tr_qa(self.wxstring(req, "q6"), get_yes_no_none(req, self.q6))
     h += tr_qa(self.wxstring(req, "q7"), get_yes_no_none(req, self.q7))
     h += tr_qa(self.wxstring(req, "q8"), get_yes_no_none(req, self.q8))
     h += tr_qa(self.wxstring(req, "q9_s"), ws.webify(self.q9))
     h += sep_row
     h += tr_qa(req.sstring(SS.SEX), ws.webify(self.q10))
     h += tr_qa(self.wxstring(req, "q11"),
                get_from_dict(dict_q11, self.q11))
     h += tr_qa(self.wxstring(req, "q12"),
                get_from_dict(dict_q12, self.q12))
     h += tr_qa(
         ell + self.wxstring(req, "ethnicity_other_s"),
         ws.webify(self.q12_details),
     )
     h += """
         </table>
     """
     return h
Esempio n. 54
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     if self.modality == MODALITY_AUDITORY:
         modality = req.wappstring("auditory")
     elif self.modality == MODALITY_VISUAL:
         modality = req.wappstring("visual")
     else:
         modality = None
     h = """
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {tr_is_complete}
             </table>
         </div>
         <div class="{CssClass.EXPLANATION}">
             The ExpDet-Threshold task measures visual and auditory
             thresholds for stimuli on a noisy background, using a
             single-interval up/down method. It is intended as a prequel to
             the Expectation–Detection task.
         </div>
         <table class="{CssClass.TASKCONFIG}">
             <tr>
                 <th width="50%">Configuration variable</th>
                 <th width="50%">Value</th>
             </tr>
     """.format(
         CssClass=CssClass,
         tr_is_complete=self.get_is_complete_tr(req),
     )
     h += tr_qa("Modality", modality)
     h += tr_qa("Target number", self.target_number)
     h += tr_qa("Background filename", ws.webify(self.background_filename))
     h += tr_qa("Background intensity", self.background_intensity)
     h += tr_qa("Target filename", ws.webify(self.target_filename))
     h += tr_qa("(For visual targets) Target duration (s)",
                self.visual_target_duration_s)
     h += tr_qa("Start intensity (minimum)", self.start_intensity_min)
     h += tr_qa("Start intensity (maximum)", self.start_intensity_max)
     h += tr_qa("Initial (large) intensity step",
                self.initial_large_intensity_step)
     h += tr_qa("Main (small) intensity step",
                self.main_small_intensity_step)
     h += tr_qa("Number of trials in main sequence",
                self.num_trials_in_main_sequence)
     h += tr_qa("Probability of a catch trial", self.p_catch_trial)
     h += tr_qa("Prompt", self.prompt)
     h += tr_qa("Intertrial interval (ITI) (s)", self.iti_s)
     h += """
         </table>
         <table class="{CssClass.TASKDETAIL}">
             <tr><th width="50%">Measure</th><th width="50%">Value</th></tr>
     """.format(CssClass=CssClass)
     h += tr_qa("Finished?", get_yes_no_none(req, self.finished))
     h += tr_qa("Logistic intercept", ws.number_to_dp(self.intercept, DP))
     h += tr_qa("Logistic slope", ws.number_to_dp(self.slope, DP))
     h += tr_qa("Logistic k (= slope)", ws.number_to_dp(self.k, DP))
     h += tr_qa("Logistic theta (= –intercept/slope)",
                ws.number_to_dp(self.theta, DP))
     h += tr_qa("Intensity for {}% detection".format(100 * LOWER_MARKER),
                ws.number_to_dp(self.logistic_x_from_p(LOWER_MARKER), DP))
     h += tr_qa("Intensity for 50% detection",
                ws.number_to_dp(self.theta, DP))
     h += tr_qa("Intensity for {}% detection".format(100 * UPPER_MARKER),
                ws.number_to_dp(self.logistic_x_from_p(UPPER_MARKER), DP))
     h += """
         </table>
     """
     h += self.get_trial_html(req)
     return h
Esempio n. 55
0
    def get_current_filter_html(self) -> str:
        """HTML showing current filters and offering ways to set them."""
        # Consider also multiple buttons in a single form:
        # http://stackoverflow.com/questions/942772
        # ... might allow "apply all things entered here" button
        # ... HOWEVER, I think this would break the ability to press Enter
        # after entering information in any box (which is nice).
        found_one = False
        filters = []
        id_filter_values = []
        id_filter_descs = []
        for n in range(1, NUMBER_OF_IDNUMS + 1):
            nstr = str(n)
            id_filter_values.append(getattr(self, "filter_idnum" + nstr))
            id_filter_descs.append(pls.get_id_desc(n))
        id_filter_value = None
        id_filter_name = "ID number"
        for index, value in enumerate(id_filter_values):
            if value is not None:
                id_filter_value = value
                id_filter_name = id_filter_descs[index]
        which_idnum_temp = """
                {picker}
                <input type="number" name="{PARAM.IDNUM_VALUE}">
        """.format(
            picker=cc_html.get_html_which_idnum_picker(PARAM.WHICH_IDNUM),
            PARAM=PARAM,
        )
        found_one = get_filter_html(
            id_filter_name,
            id_filter_value,
            ACTION.CLEAR_FILTER_IDNUMS,
            which_idnum_temp,
            ACTION.APPLY_FILTER_IDNUMS,
            filters
        ) or found_one
        found_one = get_filter_html(
            "Surname",
            self.filter_surname,
            ACTION.CLEAR_FILTER_SURNAME,
            """<input type="text" name="{}">""".format(PARAM.SURNAME),
            ACTION.APPLY_FILTER_SURNAME,
            filters
        ) or found_one
        found_one = get_filter_html(
            "Forename",
            self.filter_forename,
            ACTION.CLEAR_FILTER_FORENAME,
            """<input type="text" name="{}">""".format(PARAM.FORENAME),
            ACTION.APPLY_FILTER_FORENAME,
            filters
        ) or found_one
        found_one = get_filter_html(
            "Date of birth",
            cc_dt.format_datetime(self.get_filter_dob(), DATEFORMAT.LONG_DATE),
            ACTION.CLEAR_FILTER_DOB,
            """<input type="date" name="{}">""".format(PARAM.DOB),
            ACTION.APPLY_FILTER_DOB,
            filters
        ) or found_one
        found_one = get_filter_html(
            "Sex",
            self.filter_sex,
            ACTION.CLEAR_FILTER_SEX,
            cc_html.get_html_sex_picker(param=PARAM.SEX,
                                        selected=self.filter_sex,
                                        offer_all=True),
            ACTION.APPLY_FILTER_SEX,
            filters
        ) or found_one
        found_one = get_filter_html(
            "Task type",
            self.filter_task,
            ACTION.CLEAR_FILTER_TASK,
            cc_task.get_task_filter_dropdown(self.filter_task),
            ACTION.APPLY_FILTER_TASK,
            filters
        ) or found_one
        found_one = get_filter_html(
            "Task completed",
            cc_html.get_yes_no_none(self.filter_complete),
            ACTION.CLEAR_FILTER_COMPLETE,
            """
                <select name="{PARAM.COMPLETE}">
                    <option value="">(all)</option>
                    <option value="1"{selected_1}>Complete</option>
                    <option value="0"{selected_0}>Incomplete</option>
                </select>
            """.format(PARAM=PARAM,
                       selected_1=ws.option_selected(self.filter_complete, 1),
                       selected_0=ws.option_selected(self.filter_complete, 0)),
            ACTION.APPLY_FILTER_COMPLETE,
            filters
        ) or found_one
        found_one = get_filter_html(
            "Include old (overwritten) versions",
            cc_html.get_yes_no_none(self.filter_include_old_versions),
            ACTION.CLEAR_FILTER_INCLUDE_OLD_VERSIONS,
            """
                <select name="{PARAM.INCLUDE_OLD_VERSIONS}">
                    <option value="">(exclude)</option>
                    <option value="1"{y}>Include</option>
                    <option value="0"{n}>Exclude</option>
                </select>
            """.format(PARAM=PARAM,
                       y=ws.option_selected(self.filter_include_old_versions,
                                            1),
                       n=ws.option_selected(self.filter_include_old_versions,
                                            0)),
            ACTION.APPLY_FILTER_INCLUDE_OLD_VERSIONS,
            filters
        ) or found_one
        # found_one = get_filter_html(
        #     "Tablet device",
        #     self.filter_device_id,
        #     ACTION.CLEAR_FILTER_DEVICE,
        #     cc_device.get_device_filter_dropdown(self.filter_device_id),
        #     ACTION.APPLY_FILTER_DEVICE,
        #     filters
        # ) or found_one
        found_one = get_filter_html(
            "Adding user",
            cc_user.get_username_from_id(self.filter_user_id),
            ACTION.CLEAR_FILTER_USER,
            cc_user.get_user_filter_dropdown(self.filter_user_id),
            ACTION.APPLY_FILTER_USER,
            filters
        ) or found_one
        found_one = get_filter_html(
            "Start date (UTC)",
            cc_dt.format_datetime(self.get_filter_start_datetime(),
                                  DATEFORMAT.LONG_DATE),
            ACTION.CLEAR_FILTER_START_DATETIME,
            """<input type="date" name="{}">""".format(PARAM.START_DATETIME),
            ACTION.APPLY_FILTER_START_DATETIME,
            filters
        ) or found_one
        found_one = get_filter_html(
            "End date (UTC)",
            cc_dt.format_datetime(self.get_filter_end_datetime(),
                                  DATEFORMAT.LONG_DATE),
            ACTION.CLEAR_FILTER_END_DATETIME,
            """<input type="date" name="{}">""".format(PARAM.END_DATETIME),
            ACTION.APPLY_FILTER_END_DATETIME,
            filters
        ) or found_one
        found_one = get_filter_html(
            "Text contents",
            ws.webify(self.filter_text),
            ACTION.CLEAR_FILTER_TEXT,
            """<input type="text" name="{}">""".format(PARAM.TEXT),
            ACTION.APPLY_FILTER_TEXT,
            filters
        ) or found_one

        clear_filter_html = """
                <input type="submit" name="{ACTION.CLEAR_FILTERS}"
                        value="Clear all filters">
                <br>
        """.format(
            ACTION=ACTION,
        )
        no_filters_applied = "<p><b><i>No filters applied</i></b></p>"
        html = """
            <form class="filter" method="POST" action="{script}">

                <input type="hidden" name="{PARAM.ACTION}"
                        value="{ACTION.FILTER}">

                <input type="submit" class="important"
                        name="{ACTION.APPLY_FILTERS}"
                        value="Apply new filters">
                <br>
                <!-- First submit button is default on pressing Enter,
                which is why the Apply button is at the top of the form -->

                {clearbutton}

                {filters}
            </form>
        """.format(
            script=pls.SCRIPT_NAME,
            ACTION=ACTION,
            PARAM=PARAM,
            clearbutton=clear_filter_html if found_one else no_filters_applied,
            filters="".join(filters),
        )
        return html
Esempio n. 56
0
 def get_ctv_description_content(self, req: CamcopsRequest,
                                 x: str) -> CtvInfo:
     return CtvInfo(description=self.wxstring(req, x),
                    content=ws.webify(getattr(self, x)))
Esempio n. 57
0
 def get_sex_verbose(self, default: str = "sex unknown") -> str:
     """
     Returns HTML-safe version of sex, or default.
     """
     return default if not self.sex else ws.webify(self.sex)
Esempio n. 58
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        h = self.get_standard_clinician_comments_block(req, self.comments)
        h += """
            <div class="{CssClass.SUMMARY}">
                <table class="{CssClass.SUMMARY}">
        """.format(CssClass=CssClass, )
        h += self.get_is_complete_tr(req)
        h += tr_qa(
            req.wappstring("date_pertains_to"),
            format_datetime(self.date_pertains_to,
                            DateFormat.LONG_DATE,
                            default=None))
        h += tr_qa(self.wxstring(req, "meets_general_criteria"),
                   get_yes_no_none(req, self.has_pd()))
        h += tr_qa(self.wxstring(req, "paranoid_pd_title"),
                   get_yes_no_none(req, self.has_paranoid_pd()))
        h += tr_qa(self.wxstring(req, "schizoid_pd_title"),
                   get_yes_no_none(req, self.has_schizoid_pd()))
        h += tr_qa(self.wxstring(req, "dissocial_pd_title"),
                   get_yes_no_none(req, self.has_dissocial_pd()))
        h += tr_qa(self.wxstring(req, "eu_pd_i_title"),
                   get_yes_no_none(req, self.has_eupd_i()))
        h += tr_qa(self.wxstring(req, "eu_pd_b_title"),
                   get_yes_no_none(req, self.has_eupd_b()))
        h += tr_qa(self.wxstring(req, "histrionic_pd_title"),
                   get_yes_no_none(req, self.has_histrionic_pd()))
        h += tr_qa(self.wxstring(req, "anankastic_pd_title"),
                   get_yes_no_none(req, self.has_anankastic_pd()))
        h += tr_qa(self.wxstring(req, "anxious_pd_title"),
                   get_yes_no_none(req, self.has_anxious_pd()))
        h += tr_qa(self.wxstring(req, "dependent_pd_title"),
                   get_yes_no_none(req, self.has_dependent_pd()))

        h += """
                </table>
            </div>
            <div>
                <p><i>Vignette:</i></p>
                <p>{vignette}</p>
            </div>
            <table class="{CssClass.TASKDETAIL}">
                <tr>
                    <th width="80%">Question</th>
                    <th width="20%">Answer</th>
                </tr>
        """.format(
            CssClass=CssClass,
            vignette=answer(ws.webify(self.vignette),
                            default_for_blank_strings=True),
        )

        # General
        h += subheading_spanning_two_columns(self.wxstring(req, "general"))
        h += self.get_twocol_bool_row_true_false(req, "g1",
                                                 self.wxstring(req, "G1"))
        h += self.pd_b_text(req, "G1b")
        for i in range(1, Icd10SpecPD.N_GENERAL_1 + 1):
            h += self.get_twocol_bool_row_true_false(
                req, "g1_" + str(i), self.wxstring(req, "G1_" + str(i)))
        for i in range(2, Icd10SpecPD.N_GENERAL + 1):
            h += self.get_twocol_bool_row_true_false(
                req, "g" + str(i), self.wxstring(req, "G" + str(i)))

        # Paranoid, etc.
        h += self.standard_pd_html(req, "paranoid", Icd10SpecPD.N_PARANOID)
        h += self.standard_pd_html(req, "schizoid", Icd10SpecPD.N_SCHIZOID)
        h += self.standard_pd_html(req, "dissocial", Icd10SpecPD.N_DISSOCIAL)

        # EUPD is special
        h += self.pd_heading(req, "eu_pd_title")
        h += self.pd_skiprow(req, "eu")
        h += self.pd_general_criteria_bits(req)
        h += self.pd_subheading(req, "eu_pd_i_title")
        h += self.pd_b_text(req, "eu_pd_i_B")
        for i in range(1, Icd10SpecPD.N_EUPD_I + 1):
            h += self.pd_basic_row(req, "eu", i)
        h += self.pd_subheading(req, "eu_pd_b_title")
        h += self.pd_b_text(req, "eu_pd_b_B")
        for i in range(Icd10SpecPD.N_EUPD_I + 1, Icd10SpecPD.N_EU + 1):
            h += self.pd_basic_row(req, "eu", i)

        # Back to plain ones
        h += self.standard_pd_html(req, "histrionic", Icd10SpecPD.N_HISTRIONIC)
        h += self.standard_pd_html(req, "anankastic", Icd10SpecPD.N_ANANKASTIC)
        h += self.standard_pd_html(req, "anxious", Icd10SpecPD.N_ANXIOUS)
        h += self.standard_pd_html(req, "dependent", Icd10SpecPD.N_DEPENDENT)

        # Done
        h += """
            </table>
        """ + ICD10_COPYRIGHT_DIV
        return h
Esempio n. 59
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        def percent(score: int, maximum: int) -> str:
            return ws.number_to_dp(100 * score / maximum, PERCENT_DP)

        a = self.attn_score()
        m = self.mem_score()
        f = self.fluency_score()
        lang = self.lang_score()
        v = self.vsp_score()
        t = a + m + f + lang + v
        if self.is_complete():
            figsize = (
                PlotDefaults.FULLWIDTH_PLOT_WIDTH / 3,
                PlotDefaults.FULLWIDTH_PLOT_WIDTH / 4,
            )
            width = 0.9
            fig = req.create_figure(figsize=figsize)
            ax = fig.add_subplot(1, 1, 1)
            scores = numpy.array([a, m, f, lang, v])
            maxima = numpy.array(
                [ATTN_MAX, MEMORY_MAX, FLUENCY_MAX, LANG_MAX, VSP_MAX])
            y = 100 * scores / maxima
            x_labels = ["Attn", "Mem", "Flu", "Lang", "VSp"]
            # noinspection PyTypeChecker
            n = len(y)
            xvar = numpy.arange(n)
            ax.bar(xvar, y, width, color="b")
            ax.set_ylabel("%", fontdict=req.fontdict)
            ax.set_xticks(xvar)
            x_offset = -0.5
            ax.set_xlim(0 + x_offset, len(scores) + x_offset)
            ax.set_xticklabels(x_labels, fontdict=req.fontdict)
            fig.tight_layout()  # or the ylabel drops off the figure
            # fig.autofmt_xdate()
            req.set_figure_font_sizes(ax)
            figurehtml = req.get_html_from_pyplot_figure(fig)
        else:
            figurehtml = "<i>Incomplete; not plotted</i>"
        return (
            self.get_standard_clinician_comments_block(req, self.comments) +
            f"""
                <div class="{CssClass.SUMMARY}">
                    <table class="{CssClass.SUMMARY}">
                        <tr>
                            {self.get_is_complete_td_pair(req)}
                            <td class="{CssClass.FIGURE}"
                                rowspan="7">{figurehtml}</td>
                        </tr>
            """ + tr("Total ACE-III score <sup>[1]</sup>",
                     answer(t) + " / 100") +
            tr(
                "Attention",
                answer(a) + f" / {ATTN_MAX} ({percent(a, ATTN_MAX)}%)",
            ) + tr(
                "Memory",
                answer(m) + f" / {MEMORY_MAX} ({percent(m, MEMORY_MAX)}%)",
            ) + tr(
                "Fluency",
                answer(f) + f" / {FLUENCY_MAX} ({percent(f, FLUENCY_MAX)}%)",
            ) + tr(
                "Language",
                answer(lang) + f" / {LANG_MAX} ({percent(lang, LANG_MAX)}%)",
            ) + tr(
                "Visuospatial",
                answer(v) + f" / {VSP_MAX} ({percent(v, VSP_MAX)}%)",
            ) + f"""
                    </table>
                </div>
                <table class="{CssClass.TASKDETAIL}">
                    <tr>
                        <th width="75%">Question</th>
                        <th width="25%">Answer/score</td>
                    </tr>
            """ + tr_qa(
                "Age on leaving full-time education",
                self.age_at_leaving_full_time_education,
            ) + tr_qa("Occupation", ws.webify(self.occupation)) +
            tr_qa("Handedness", ws.webify(self.handedness)) +
            subheading_spanning_two_columns("Attention") + tr(
                "Day? Date? Month? Year? Season?",
                ", ".join(
                    answer(x) for x in (
                        self.attn_time1,
                        self.attn_time2,
                        self.attn_time3,
                        self.attn_time4,
                        self.attn_time5,
                    )),
            ) + tr(
                "House number/floor? Street/hospital? Town? County? Country?",
                ", ".join(
                    answer(x) for x in (
                        self.attn_place1,
                        self.attn_place2,
                        self.attn_place3,
                        self.attn_place4,
                        self.attn_place5,
                    )),
            ) + tr(
                "Repeat: Lemon? Key? Ball?",
                ", ".join(
                    answer(x) for x in (
                        self.attn_repeat_word1,
                        self.attn_repeat_word2,
                        self.attn_repeat_word3,
                    )),
            ) + tr(
                "Repetition: number of trials <i>(not scored)</i>",
                answer(self.attn_num_registration_trials,
                       formatter_answer=italic),
            ) + tr(
                "Serial subtractions: First correct? Second? Third? Fourth? "
                "Fifth?",
                ", ".join(
                    answer(x) for x in (
                        self.attn_serial7_subtraction1,
                        self.attn_serial7_subtraction2,
                        self.attn_serial7_subtraction3,
                        self.attn_serial7_subtraction4,
                        self.attn_serial7_subtraction5,
                    )),
            ) + subheading_spanning_two_columns("Memory (1)") + tr(
                "Recall: Lemon? Key? Ball?",
                ", ".join(
                    answer(x) for x in (
                        self.mem_recall_word1,
                        self.mem_recall_word2,
                        self.mem_recall_word3,
                    )),
            ) + subheading_spanning_two_columns("Fluency") + tr(
                "Score for words beginning with ‘P’ <i>(≥18 scores 7, 14–17 "
                "scores 6, 11–13 scores 5, 8–10 scores 4, 6–7 scores 3, "
                "4–5 scores 2, 2–3 scores 1, 0–1 scores 0)</i>",
                answer(self.fluency_letters_score) + " / 7",
            ) + tr(
                "Score for animals <i>(≥22 scores 7, 17–21 scores 6, "
                "14–16 scores 5, 11–13 scores 4, 9–10 scores 3, "
                "7–8 scores 2, 5–6 scores 1, &lt;5 scores 0)</i>",
                answer(self.fluency_animals_score) + " / 7",
            ) + subheading_spanning_two_columns("Memory (2)") + tr(
                "Third trial of address registration: Harry? Barnes? 73? "
                "Orchard? Close? Kingsbridge? Devon?",
                ", ".join(
                    answer(x) for x in (
                        self.mem_repeat_address_trial3_1,
                        self.mem_repeat_address_trial3_2,
                        self.mem_repeat_address_trial3_3,
                        self.mem_repeat_address_trial3_4,
                        self.mem_repeat_address_trial3_5,
                        self.mem_repeat_address_trial3_6,
                        self.mem_repeat_address_trial3_7,
                    )),
            ) + tr(
                "Current PM? Woman who was PM? USA president? USA president "
                "assassinated in 1960s?",
                ", ".join(
                    answer(x) for x in (
                        self.mem_famous1,
                        self.mem_famous2,
                        self.mem_famous3,
                        self.mem_famous4,
                    )),
            ) + subheading_spanning_two_columns("Language") + tr(
                "<i>Practice trial (“Pick up the pencil and then the "
                "paper”)</i>",
                answer(self.lang_follow_command_practice,
                       formatter_answer=italic),
            ) + tr_qa(
                "“Place the paper on top of the pencil”",
                self.lang_follow_command1,
            ) + tr_qa(
                "“Pick up the pencil but not the paper”",
                self.lang_follow_command2,
            ) + tr_qa(
                "“Pass me the pencil after touching the paper”",
                self.lang_follow_command3,
            ) + tr(
                "Sentence-writing: point for ≥2 complete sentences about "
                "the one topic? Point for correct grammar and spelling?",
                ", ".join(
                    answer(x) for x in (
                        self.lang_write_sentences_point1,
                        self.lang_write_sentences_point2,
                    )),
            ) + tr(
                "Repeat: caterpillar? eccentricity? unintelligible? "
                "statistician? <i>(score 2 if all correct, 1 if 3 correct, "
                "0 if ≤2 correct)</i>",
                "<i>{}, {}, {}, {}</i> (score <b>{}</b> / 2)".format(
                    answer(self.lang_repeat_word1, formatter_answer=italic),
                    answer(self.lang_repeat_word2, formatter_answer=italic),
                    answer(self.lang_repeat_word3, formatter_answer=italic),
                    answer(self.lang_repeat_word4, formatter_answer=italic),
                    self.get_repeat_word_score(),
                ),
            ) + tr_qa(
                "Repeat: “All that glitters is not gold”?",
                self.lang_repeat_sentence1,
            ) + tr_qa(
                "Repeat: “A stitch in time saves nine”?",
                self.lang_repeat_sentence2,
            ) + tr(
                "Name pictures: spoon, book, kangaroo/wallaby",
                ", ".join(
                    answer(x) for x in (
                        self.lang_name_picture1,
                        self.lang_name_picture2,
                        self.lang_name_picture3,
                    )),
            ) + tr(
                "Name pictures: penguin, anchor, camel/dromedary",
                ", ".join(
                    answer(x) for x in (
                        self.lang_name_picture4,
                        self.lang_name_picture5,
                        self.lang_name_picture6,
                    )),
            ) + tr(
                "Name pictures: harp, rhinoceros/rhino, barrel/keg/tub",
                ", ".join(
                    answer(x) for x in (
                        self.lang_name_picture7,
                        self.lang_name_picture8,
                        self.lang_name_picture9,
                    )),
            ) + tr(
                "Name pictures: crown, alligator/crocodile, "
                "accordion/piano accordion/squeeze box",
                ", ".join(
                    answer(x) for x in (
                        self.lang_name_picture10,
                        self.lang_name_picture11,
                        self.lang_name_picture12,
                    )),
            ) + tr(
                "Identify pictures: monarchy? marsupial? Antarctic? nautical?",
                ", ".join(
                    answer(x) for x in (
                        self.lang_identify_concept1,
                        self.lang_identify_concept2,
                        self.lang_identify_concept3,
                        self.lang_identify_concept4,
                    )),
            ) + tr_qa(
                "Read all successfully: sew, pint, soot, dough, height",
                self.lang_read_words_aloud,
            ) + subheading_spanning_two_columns("Visuospatial") +
            tr("Copy infinity",
               answer(self.vsp_copy_infinity) + " / 1") +
            tr("Copy cube",
               answer(self.vsp_copy_cube) + " / 2") + tr(
                   "Draw clock with numbers and hands at 5:10",
                   answer(self.vsp_draw_clock) + " / 5",
               ) + tr(
                   "Count dots: 8, 10, 7, 9",
                   ", ".join(
                       answer(x) for x in (
                           self.vsp_count_dots1,
                           self.vsp_count_dots2,
                           self.vsp_count_dots3,
                           self.vsp_count_dots4,
                       )),
               ) + tr(
                   "Identify letters: K, M, A, T",
                   ", ".join(
                       answer(x) for x in (
                           self.vsp_identify_letter1,
                           self.vsp_identify_letter2,
                           self.vsp_identify_letter3,
                           self.vsp_identify_letter4,
                       )),
               ) + subheading_spanning_two_columns("Memory (3)") + tr(
                   "Recall address: Harry? Barnes? 73? Orchard? Close? "
                   "Kingsbridge? Devon?",
                   ", ".join(
                       answer(x) for x in (
                           self.mem_recall_address1,
                           self.mem_recall_address2,
                           self.mem_recall_address3,
                           self.mem_recall_address4,
                           self.mem_recall_address5,
                           self.mem_recall_address6,
                           self.mem_recall_address7,
                       )),
               ) +
            tr(
                "Recognize address: Jerry Barnes/Harry Barnes/Harry Bradford?",
                self.get_recog_text(
                    (self.mem_recall_address1 == 1
                     and self.mem_recall_address2 == 1),
                    self.mem_recognize_address1,
                ),
            ) + tr(
                "Recognize address: 37/73/76?",
                self.get_recog_text(
                    (self.mem_recall_address3 == 1),
                    self.mem_recognize_address2,
                ),
            ) + tr(
                "Recognize address: Orchard Place/Oak Close/Orchard "
                "Close?",
                self.get_recog_text(
                    (self.mem_recall_address4 == 1
                     and self.mem_recall_address5 == 1),
                    self.mem_recognize_address3,
                ),
            ) + tr(
                "Recognize address: Oakhampton/Kingsbridge/Dartington?",
                self.get_recog_text(
                    (self.mem_recall_address6 == 1),
                    self.mem_recognize_address4,
                ),
            ) + tr(
                "Recognize address: Devon/Dorset/Somerset?",
                self.get_recog_text(
                    (self.mem_recall_address7 == 1),
                    self.mem_recognize_address5,
                ),
            ) + subheading_spanning_two_columns("Photos of test sheet") +
            tr_span_col(get_blob_img_html(self.picture1),
                        td_class=CssClass.PHOTO) +
            tr_span_col(get_blob_img_html(self.picture2),
                        td_class=CssClass.PHOTO) + f"""
                </table>
                <div class="{CssClass.FOOTNOTES}">
                    [1] In the ACE-R (the predecessor of the ACE-III),
                    scores ≤82 had sensitivity 0.84 and specificity 1.0 for
                    dementia, and scores ≤88 had sensitivity 0.94 and
                    specificity 0.89 for dementia, in a context of patients
                    with AlzD, FTD, LBD, MCI, and controls
                    (Mioshi et al., 2006, PMID 16977673).
                </div>
                <div class="{CssClass.COPYRIGHT}">
                    ACE-III: Copyright © 2012, John Hodges.
                    “The ACE-III is available for free. The copyright is held
                    by Professor John Hodges who is happy for the test to be
                    used in clinical practice and research projects. There is
                    no need to contact us if you wish to use the ACE-III in
                    clinical practice.”
                    (ACE-III FAQ, 7 July 2013, www.neura.edu.au).
                </div>
            """)
Esempio n. 60
0
 def get_task_html(self) -> str:
     dict_q1 = {None: None}
     dict_q3 = {None: None}
     dict_q4 = {None: None}
     dict_q5 = {None: None}
     dict_q11 = {None: None}
     dict_q12 = {None: None}
     for option in range(1, 5):
         dict_q1[option] = WSTRING("gmcpq_q1_option" + str(option))
     for option in range(1, 6):
         dict_q3[option] = WSTRING("gmcpq_q3_option" + str(option))
         dict_q11[option] = WSTRING("gmcpq_q11_option" + str(option))
     for option in range(0, 6):
         prefix = str(option) + " – " if option > 0 else ""
         dict_q4[option] = prefix + WSTRING("gmcpq_q4_option" + str(option))
         dict_q5[option] = prefix + WSTRING("gmcpq_q5_option" + str(option))
     for option in range(1, 17):
         dict_q12[option] = WSTRING("gmcpq_ethnicity_option" + str(option))
     h = """
         <div class="summary">
             <table class="summary">
                 {}
             </table>
         </div>
         <table class="taskdetail">
             <tr>
                 <th width="60%">Question</th>
                 <th width="40%">Answer</th>
             </tr>
     """.format(
         self.get_is_complete_tr()
     )
     ell = "&hellip; "  # horizontal ellipsis
     sep_row = subheading_spanning_two_columns("")
     blank_cell = td("", td_class="subheading")
     h += tr_qa(WSTRING("gmcpq_q_doctor"), ws.webify(self.doctor))
     h += sep_row
     h += tr_qa(WSTRING("gmcpq_q1"), get_from_dict(dict_q1, self.q1))
     h += tr(td(WSTRING("gmcpq_q2")), blank_cell, literal=True)
     h += tr_qa(ell + WSTRING("gmcpq_q2_a"), get_yes_no_none(self.q2a))
     h += tr_qa(ell + WSTRING("gmcpq_q2_b"), get_yes_no_none(self.q2b))
     h += tr_qa(ell + WSTRING("gmcpq_q2_c"), get_yes_no_none(self.q2c))
     h += tr_qa(ell + WSTRING("gmcpq_q2_d"), get_yes_no_none(self.q2d))
     h += tr_qa(ell + WSTRING("gmcpq_q2_e"), get_yes_no_none(self.q2e))
     h += tr_qa(ell + WSTRING("gmcpq_q2_f"), get_yes_no_none(self.q2f))
     h += tr_qa(ell + ell + WSTRING("gmcpq_q2f_s"), ws.webify(self.q2f_details))
     h += tr_qa(WSTRING("gmcpq_q3"), get_from_dict(dict_q3, self.q3))
     h += tr(td(WSTRING("gmcpq_q4")), blank_cell, literal=True)
     h += tr_qa(ell + WSTRING("gmcpq_q4_a"), get_from_dict(dict_q4, self.q4a))
     h += tr_qa(ell + WSTRING("gmcpq_q4_b"), get_from_dict(dict_q4, self.q4b))
     h += tr_qa(ell + WSTRING("gmcpq_q4_c"), get_from_dict(dict_q4, self.q4c))
     h += tr_qa(ell + WSTRING("gmcpq_q4_d"), get_from_dict(dict_q4, self.q4d))
     h += tr_qa(ell + WSTRING("gmcpq_q4_e"), get_from_dict(dict_q4, self.q4e))
     h += tr_qa(ell + WSTRING("gmcpq_q4_f"), get_from_dict(dict_q4, self.q4f))
     h += tr_qa(ell + WSTRING("gmcpq_q4_g"), get_from_dict(dict_q4, self.q4g))
     h += tr(td(WSTRING("gmcpq_q5")), blank_cell, literal=True)
     h += tr_qa(ell + WSTRING("gmcpq_q5_a"), get_from_dict(dict_q5, self.q5a))
     h += tr_qa(ell + WSTRING("gmcpq_q5_b"), get_from_dict(dict_q5, self.q5b))
     h += tr_qa(WSTRING("gmcpq_q6"), get_yes_no_none(self.q6))
     h += tr_qa(WSTRING("gmcpq_q7"), get_yes_no_none(self.q7))
     h += tr_qa(WSTRING("gmcpq_q8"), get_yes_no_none(self.q8))
     h += tr_qa(WSTRING("gmcpq_q9_s"), ws.webify(self.q9))
     h += sep_row
     h += tr_qa(WSTRING("sex"), ws.webify(self.q10))
     h += tr_qa(WSTRING("gmcpq_q11"), get_from_dict(dict_q11, self.q11))
     h += tr_qa(WSTRING("gmcpq_q12"), get_from_dict(dict_q12, self.q12))
     h += tr_qa(ell + WSTRING("gmcpq_ethnicity_other_s"), ws.webify(self.q12_details))
     h += """
         </table>
     """
     return h