Exemple #1
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     score = self.total_score()
     severity = self.severity(req)
     answer_dicts_dict = {}
     for q in self.SCORED_QUESTIONS:
         d = {None: None}
         for option in range(0, 8):
             if option > 4 and q == "q10":
                 continue
             d[option] = self.wxstring(req, q + "_option" + str(option))
         answer_dicts_dict[q] = d
     q_a = ""
     for q in range(1, Ciwa.NSCOREDQUESTIONS + 1):
         q_a += tr_qa(
             self.wxstring(req, "q" + str(q) + "_s"),
             get_from_dict(answer_dicts_dict["q" + str(q)],
                           getattr(self, "q" + str(q))))
     h = """
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {tr_is_complete}
                 {total_score}
                 {severity}
             </table>
         </div>
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <th width="35%">Question</th>
                 <th width="65%">Answer</th>
             </tr>
             {q_a}
             {subhead_vitals}
             {t}
             {hr}
             {bp}
             {rr}
         </table>
         <div class="{CssClass.FOOTNOTES}">
             [1] Total score ≥15 severe, ≥8 moderate, otherwise
                 mild/minimal.
         </div>
     """.format(
         CssClass=CssClass,
         tr_is_complete=self.get_is_complete_tr(req),
         total_score=tr(req.wappstring("total_score"),
                        answer(score) + " / {}".format(self.MAX_SCORE)),
         severity=tr_qa(
             self.wxstring(req, "severity") + " <sup>[1]</sup>", severity),
         q_a=q_a,
         subhead_vitals=subheading_spanning_two_columns(
             self.wxstring(req, "vitals_title")),
         t=tr_qa(self.wxstring(req, "t"), self.t),
         hr=tr_qa(self.wxstring(req, "hr"), self.hr),
         bp=tr(self.wxstring(req, "bp"),
               answer(self.sbp) + " / " + answer(self.dbp)),
         rr=tr_qa(self.wxstring(req, "rr"), self.rr),
     )
     return h
Exemple #2
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     (total, extrapolated) = self.totalscore_extrapolated()
     main_dict = {
         None: None,
         1: "1 — " + self.wxstring(req, "a1"),
         2: "2 — " + self.wxstring(req, "a2"),
         3: "3 — " + self.wxstring(req, "a3"),
         4: "4 — " + self.wxstring(req, "a4"),
         MISSING_VALUE: self.wxstring(req, "no_response"),
     }
     last_q_dict = {
         None: None,
         1: "1 — " + self.wxstring(req, "q29_a1"),
         2: "2 — " + self.wxstring(req, "q29_a2"),
         3: "3 — " + self.wxstring(req, "q29_a3"),
         4: "4 — " + self.wxstring(req, "q29_a4"),
         MISSING_VALUE: self.wxstring(req, "no_response"),
     }
     instruction_dict = {
         1: self.wxstring(req, "instruction11"),
         14: self.wxstring(req, "instruction12"),
         20: self.wxstring(req, "instruction13"),
         29: self.wxstring(req, "instruction14"),
     }
     # https://docs.python.org/2/library/stdtypes.html#mapping-types-dict
     # http://paltman.com/try-except-performance-in-python-a-simple-test/
     h = f"""
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {self.get_is_complete_tr(req)}
                 <tr>
                     <td>Total score ({self.MIN_SCORE}–{self.MAX_SCORE}),
                         higher better</td>
                     <td>{answer(ws.number_to_dp(total, DP))}</td>
                 </tr>
                 <tr>
                     <td>Total score extrapolated using incomplete
                     responses? <sup>[1]</sup></td>
                     <td>{answer(get_yes_no(req, extrapolated))}</td>
                 </tr>
             </table>
         </div>
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <th width="50%">Question</th>
                 <th width="50%">Answer</th>
             </tr>
     """
     for n in range(1, self.NQUESTIONS + 1):
         if n in instruction_dict:
             h += subheading_spanning_two_columns(instruction_dict.get(n))
         d = main_dict if n <= self.N_SCORED_QUESTIONS else last_q_dict
         q = self.get_q(req, n)
         a = get_from_dict(d, getattr(self, "q" + str(n)))
         h += tr_qa(q, a)
     h += END_DIV + COPYRIGHT_DIV
     return h
Exemple #3
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        answers = {
            None: None,
            0: "0 — " + self.wxstring(req, "a0"),
            1: "1 — " + self.wxstring(req, "a1"),
            2: "2 — " + self.wxstring(req, "a2"),
            3: "3 — " + self.wxstring(req, "a3"),
            4: "4 — " + self.wxstring(req, "a4"),
        }
        subscore_html = ""
        answer_html = ""

        for info in self.GROUPS:
            heading = self.wxstring(req, info.heading_xstring_name)
            subscore = info.subscore(self)
            subscore_html += tr(heading, (answer(round(subscore, DISPLAY_DP)) +
                                          " / {}".format(info.max_score)))
            answer_html += subheading_spanning_two_columns(heading)
            for q in info.fieldnames:
                if q == self.OPTIONAL_Q:
                    # insert additional row
                    answer_html += tr_qa(self.xstring(req, "prefer_no_answer"),
                                         self.ignore_s_q7)
                answer_val = getattr(self, q)
                answer_html += tr_qa(self.wxstring(req, q),
                                     get_from_dict(answers, answer_val))

        tscore = round(self.total_score(), DISPLAY_DP)

        h = """
            <div class="{CssClass.SUMMARY}">
                 <table class="{CssClass.SUMMARY}">
                     {tr_is_complete}
                     {total_score}
                     {subscore_html}
                 </table>
            </div>
            <table class="{CssClass.TASKDETAIL}">
                <tr>
                    <th width="50%">Question</th>
                    <th width="50%">Answer</th>
                </tr>
                {answer_html}
        """.format(
            CssClass=CssClass,
            tr_is_complete=self.get_is_complete_tr(req),
            total_score=tr(
                req.wappstring("total_score"),
                answer(tscore) + " / {}".format(self.MAX_SCORE_TOTAL)),
            subscore_html=subscore_html,
            answer_html=answer_html,
        )
        h += """
            </table>
        """
        return h
 def get_task_html(self, req: CamcopsRequest) -> str:
     h = f"""
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {self.get_is_complete_tr(req)}
                 {tr_qa("Overall distress (0–10)", self.distress)}
             </table>
         </div>
         <div class="{CssClass.EXPLANATION}">
             All questions relate to distress/problems “in the past week,
             including today” (yes = problem, no = no problem).
         </div>
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <th width="50%">Question</th>
                 <th width="50%">Answer</th>
             </tr>
     """
     h += tr_qa("Distress (0 no distress – 10 extreme distress)",
                self.distress)
     h += subheading_spanning_two_columns("Practical problems")
     for i in range(1, 5 + 1):
         h += tr_qa(
             f"{i}. {self.wxstring(req, 'q' + str(i))}",
             get_yes_no_none(req, getattr(self, "q" + str(i))),
         )
     h += subheading_spanning_two_columns("Family problems")
     for i in range(6, 8 + 1):
         h += tr_qa(
             f"{i}. {self.wxstring(req, 'q' + str(i))}",
             get_yes_no_none(req, getattr(self, "q" + str(i))),
         )
     h += subheading_spanning_two_columns("Emotional problems")
     for i in range(9, 14 + 1):
         h += tr_qa(
             f"{i}. {self.wxstring(req, 'q' + str(i))}",
             get_yes_no_none(req, getattr(self, "q" + str(i))),
         )
     h += subheading_spanning_two_columns("Spiritual problems")
     for i in range(15, 15 + 1):
         h += tr_qa(
             f"{i}. {self.wxstring(req, 'q' + str(i))}",
             get_yes_no_none(req, getattr(self, "q" + str(i))),
         )
     h += subheading_spanning_two_columns("Physical problems")
     for i in range(16, self.NQUESTIONS + 1):
         h += tr_qa(
             f"{i}. {self.wxstring(req, 'q' + str(i))}",
             get_yes_no_none(req, getattr(self, "q" + str(i))),
         )
     h += subheading_spanning_two_columns("Other problems")
     h += tr_qa(self.wxstring(req, "other_s"), self.other)
     h += """
         </table>
     """
     return h
Exemple #5
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        answers = {
            None: None,
            0: "0 — " + self.wxstring(req, "a0"),
            1: "1 — " + self.wxstring(req, "a1"),
            2: "2 — " + self.wxstring(req, "a2"),
            3: "3 — " + self.wxstring(req, "a3"),
            4: "4 — " + self.wxstring(req, "a4"),
        }
        subscore_html = ""
        answer_html = ""

        for info in self.GROUPS:
            heading = self.wxstring(req, info.heading_xstring_name)
            subscore = info.subscore(self)
            subscore_html += tr(
                heading,
                (answer(round(subscore, DISPLAY_DP)) + f" / {info.max_score}"),
            )
            answer_html += subheading_spanning_two_columns(heading)
            for q in info.fieldnames:
                if q == self.OPTIONAL_Q:
                    # insert additional row
                    answer_html += tr_qa(self.xstring(req, "prefer_no_answer"),
                                         self.ignore_s_q7)
                answer_val = getattr(self, q)
                answer_html += tr_qa(self.wxstring(req, q),
                                     get_from_dict(answers, answer_val))

        tscore = round(self.total_score(), DISPLAY_DP)

        tr_total_score = tr(
            req.sstring(SS.TOTAL_SCORE),
            answer(tscore) + f" / {self.MAX_SCORE_TOTAL}",
        )
        return f"""
Exemple #6
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     d = self.get_score_dict()
     h = f"""
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {self.get_is_complete_tr(req)}
                 <tr>
                     <td>Total</td>
                     <td>{self.report_score(d['total'])}</td>
                     </tr>
                 <tr>
                     <td>Activity: hygiene</td>
                     <td>{self.report_score(d['hygiene'])}</td>
                 </tr>
                 <tr>
                     <td>Activity: dressing</td>
                     <td>{self.report_score(d['dressing'])}</td>
                 </tr>
                 <tr>
                     <td>Activity: continence</td>
                     <td>{self.report_score(d['continence'])}</td>
                 </tr>
                 <tr>
                     <td>Activity: eating</td>
                     <td>{self.report_score(d['eating'])}</td>
                 </tr>
                 <tr>
                     <td>Basic activities of daily living (BADLs) (hygiene,
                     dressing, continence, eating)</td>
                     <td>{self.report_score(d['badl'])}</td>
                 </tr>
                 <tr>
                     <td>Activity: meal preparation</td>
                     <td>{self.report_score(d['mealprep'])}</td>
                 </tr>
                 <tr>
                     <td>Activity: telephone</td>
                     <td>{self.report_score(d['telephone'])}</td>
                 </tr>
                 <tr>
                     <td>Activity: outings</td>
                     <td>{self.report_score(d['outing'])}</td>
                 </tr>
                 <tr>
                     <td>Activity: finance</td>
                     <td>{self.report_score(d['finance'])}</td>
                 </tr>
                 <tr>
                     <td>Activity: medications</td>
                     <td>{self.report_score(d['medications'])}</td>
                 </tr>
                 <tr>
                     <td>Activity: leisure</td>
                     <td>{self.report_score(d['leisure'])}</td>
                 </tr>
                 <tr>
                     <td>Instrumental activities of daily living (IADLs)
                     (meal prep., telephone, outings, finance, medications,
                     leisure)</td>
                     <td>{self.report_score(d['iadl'])}</td>
                 </tr>
                 <tr>
                     <td>Phase: initiation</td>
                     <td>{self.report_score(d['initiation'])}</td>
                 </tr>
                 <tr>
                     <td>Phase: planning/organisation</td>
                     <td>{self.report_score(d['planning'])}</td>
                 </tr>
                 <tr>
                     <td>Phase: execution/performance</td>
                     <td>{self.report_score(d['execution'])}</td>
                 </tr>
             </table>
         </div>
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <th width="50%">Question (I = initiation, P = planning,
                     E = execution)</th>
                 <th width="50%">Answer</th>
             </tr>
     """
     for group in self.GROUPS:
         h += subheading_spanning_two_columns(self.wxstring(req, group))
         for item in self.ITEMS:
             if not item.startswith(group):
                 continue
             q = self.wxstring(req, item)
             if "_init_" in item:
                 q += " (I)"
             elif "_plan_" in item:
                 q += " (P)"
             elif "_exec_" in item:
                 q += " (E)"
             else:
                 # Shouldn't happen
                 q += " (?)"
             h += tr(q, self.report_answer(item))
     h += f"""
         </table>
         {DATA_COLLECTION_UNLESS_UPGRADED_DIV}
     """
     return h
Exemple #7
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
Exemple #8
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
Exemple #9
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        section_a = ""
        for i in range(1, 13 + 1):
            section_a += tr_qa(
                self.get_q(req, i),
                self.get_answer(req, i, getattr(self, "q" + str(i))))
        section_b = ""
        for i in range(14, self.NQUESTIONS + 1):
            section_b += tr_qa(
                self.get_q(req, i),
                self.get_answer(req, i, getattr(self, "q" + str(i))))

        h = """
            <div class="{CssClass.SUMMARY}">
                <table class="{CssClass.SUMMARY}">
                    {tr_is_complete}
                    {total_score}
                    {section_a_total}
                    {section_b_total}
                </table>
            </div>
            <table class="{CssClass.TASKDETAIL}">
                <tr>
                    <th width="50%">Question</th>
                    <th width="50%">Answer <sup>[1]</sup></th>
                </tr>
                {period_rated}
                {section_a_subhead}
                {section_a}
                {section_b_subhead}
                {section_b}
            </table>
            <div class="{CssClass.FOOTNOTES}">
                {FOOTNOTE_SCORING}
            </div>
            {copyright_div}
        """.format(
            CssClass=CssClass,
            tr_is_complete=self.get_is_complete_tr(req),
            total_score=tr(
                req.wappstring("total_score"),
                answer(self.total_score()) + " / {}".format(self.MAX_SCORE)),
            section_a_total=tr(
                self.wxstring(req, "section_a_total"),
                answer(self.section_a_score()) +
                " / {}".format(self.MAX_SECTION_A)),
            section_b_total=tr(
                self.wxstring(req, "section_b_total"),
                answer(self.section_b_score()) +
                " / {}".format(self.MAX_SECTION_B)),
            period_rated=tr_qa(self.wxstring(req, "period_rated"),
                               self.period_rated),
            section_a_subhead=subheading_spanning_two_columns(
                self.wxstring(req, "section_a_title")),
            section_a=section_a,
            section_b_subhead=subheading_spanning_two_columns(
                self.wxstring(req, "section_b_title")),
            section_b=section_b,
            FOOTNOTE_SCORING=FOOTNOTE_SCORING,
            copyright_div=self.COPYRIGHT_DIV,
        )
        return h
Exemple #10
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        h = """
            <div class="{CssClass.SUMMARY}">
                <table class="{CssClass.SUMMARY}">
                    {tr_is_complete}
                </table>
            </div>
            <table class="{CssClass.TASKDETAIL}">
                <col width="40%">
                <col width="60%">
        """.format(
            CssClass=CssClass,
            tr_is_complete=self.get_is_complete_tr(req),
        )
        h += tr_qa(
            self.wxstring(req, "discharge_date"),
            format_datetime(self.discharge_date,
                            DateFormat.LONG_DATE_WITH_DAY,
                            default=None), "")
        h += tr_qa(self.wxstring(req, "discharge_reason"),
                   self.get_discharge_reason(req), "")
        h += tr_qa(self.wxstring(req, "leaflet_or_discharge_card_given"),
                   get_yes_no_none(req, self.leaflet_or_discharge_card_given),
                   "")
        h += tr_qa(self.wxstring(req, "frequent_attender"),
                   get_yes_no_none(req, self.frequent_attender), "")
        h += tr_qa(self.wxstring(req, "patient_wanted_copy_of_letter"),
                   self.patient_wanted_copy_of_letter, "")
        h += tr_qa(self.wxstring(req, "gaf_at_first_assessment"),
                   self.gaf_at_first_assessment, "")
        h += tr_qa(self.wxstring(req, "gaf_at_discharge"),
                   self.gaf_at_discharge, "")

        h += subheading_spanning_two_columns(
            self.wxstring(req, "referral_reason_t"))
        h += tr_span_col(answer(", ".join(self.get_referral_reasons(req))),
                         cols=2)
        h += tr_qa(self.wxstring(req, "referral_reason_transplant_organ"),
                   self.referral_reason_transplant_organ, "")
        h += tr_qa(self.wxstring(req, "referral_reason_other_detail"),
                   self.referral_reason_other_detail, "")

        h += subheading_spanning_two_columns(self.wxstring(req, "diagnoses_t"))
        h += tr_qa(self.wxstring(req, "psychiatric_t"),
                   "\n".join(self.get_psychiatric_diagnoses(req)), "")
        h += tr_qa(self.wxstring(req, "medical_t"),
                   "\n".join(self.get_medical_diagnoses()), "")

        h += subheading_spanning_two_columns(self.wxstring(
            req, "management_t"))
        h += tr_span_col(answer(", ".join(self.get_managements(req))), cols=2)
        h += tr_qa(self.wxstring(req, "management_other_detail"),
                   self.management_other_detail, "")

        h += subheading_spanning_two_columns(self.wxstring(req, "outcome_t"))
        h += tr_qa(self.wxstring(req, "outcome_t"), self.outcome, "")
        h += tr_qa(self.wxstring(req, "outcome_hospital_transfer_detail"),
                   self.outcome_hospital_transfer_detail, "")
        h += tr_qa(self.wxstring(req, "outcome_other_detail"),
                   self.outcome_other_detail, "")

        h += """
            </table>
        """
        return h
Exemple #11
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        vsp = self.score_vsp()
        naming = self.score_naming()
        attention = self.score_attention()
        language = self.score_language()
        abstraction = self.score_abstraction()
        memory = self.score_memory()
        orientation = self.score_orientation()
        totalscore = self.total_score()
        category = self.category(req)

        h = """
            {clinician_comments}
            <div class="{CssClass.SUMMARY}">
                <table class="{CssClass.SUMMARY}">
                    {tr_is_complete}
                    {total_score}
                    {category}
                </table>
            </div>
            <table class="{CssClass.TASKDETAIL}">
                <tr>
                    <th width="69%">Question</th>
                    <th width="31%">Score</th>
                </tr>
        """.format(
            clinician_comments=self.get_standard_clinician_comments_block(
                req, self.comments),
            CssClass=CssClass,
            tr_is_complete=self.get_is_complete_tr(req),
            total_score=tr(
                req.sstring(SS.TOTAL_SCORE),
                answer(totalscore) + f" / {self.MAX_SCORE}",
            ),
            category=tr_qa(
                self.wxstring(req, "category") + " <sup>[1]</sup>", category),
        )

        h += tr(
            self.wxstring(req, "subscore_visuospatial"),
            answer(vsp) + " / 5",
            tr_class=CssClass.SUBHEADING,
        )
        h += tr(
            "Path, cube, clock/contour, clock/numbers, clock/hands",
            ", ".join(
                answer(x)
                for x in (self.q1, self.q2, self.q3, self.q4, self.q5)),
        )

        h += tr(
            self.wxstring(req, "subscore_naming"),
            answer(naming) + " / 3",
            tr_class=CssClass.SUBHEADING,
        )
        h += tr(
            "Lion, rhino, camel",
            ", ".join(answer(x) for x in (self.q6, self.q7, self.q8)),
        )

        h += tr(
            self.wxstring(req, "subscore_attention"),
            answer(attention) + " / 6",
            tr_class=CssClass.SUBHEADING,
        )
        h += tr(
            "5 digits forwards, 3 digits backwards, tapping, serial 7s "
            "[<i>scores 3</i>]",
            ", ".join(
                answer(x) for x in (self.q9, self.q10, self.q11, self.q12)),
        )

        h += tr(
            self.wxstring(req, "subscore_language"),
            answer(language) + " / 3",
            tr_class=CssClass.SUBHEADING,
        )
        h += tr(
            "Repeat sentence 1, repeat sentence 2, fluency to letter ‘F’",
            ", ".join(answer(x) for x in (self.q13, self.q14, self.q15)),
        )

        h += tr(
            self.wxstring(req, "subscore_abstraction"),
            answer(abstraction) + " / 2",
            tr_class=CssClass.SUBHEADING,
        )
        h += tr(
            "Means of transportation, measuring instruments",
            ", ".join(answer(x) for x in (self.q16, self.q17)),
        )

        h += tr(
            self.wxstring(req, "subscore_memory"),
            answer(memory) + " / 5",
            tr_class=CssClass.SUBHEADING,
        )
        h += tr(
            "Registered on first trial [<i>not scored</i>]",
            ", ".join(
                answer(x, formatter_answer=italic) for x in (
                    self.register_trial1_1,
                    self.register_trial1_2,
                    self.register_trial1_3,
                    self.register_trial1_4,
                    self.register_trial1_5,
                )),
        )
        h += tr(
            "Registered on second trial [<i>not scored</i>]",
            ", ".join(
                answer(x, formatter_answer=italic) for x in (
                    self.register_trial2_1,
                    self.register_trial2_2,
                    self.register_trial2_3,
                    self.register_trial2_4,
                    self.register_trial2_5,
                )),
        )
        h += tr(
            "Recall FACE, VELVET, CHURCH, DAISY, RED with no cue",
            ", ".join(
                answer(x)
                for x in (self.q18, self.q19, self.q20, self.q21, self.q22)),
        )
        h += tr(
            "Recall with category cue [<i>not scored</i>]",
            ", ".join(
                answer(x, formatter_answer=italic) for x in (
                    self.recall_category_cue_1,
                    self.recall_category_cue_2,
                    self.recall_category_cue_3,
                    self.recall_category_cue_4,
                    self.recall_category_cue_5,
                )),
        )
        h += tr(
            "Recall with multiple-choice cue [<i>not scored</i>]",
            ", ".join(
                answer(x, formatter_answer=italic) for x in (
                    self.recall_mc_cue_1,
                    self.recall_mc_cue_2,
                    self.recall_mc_cue_3,
                    self.recall_mc_cue_4,
                    self.recall_mc_cue_5,
                )),
        )

        h += tr(
            self.wxstring(req, "subscore_orientation"),
            answer(orientation) + " / 6",
            tr_class=CssClass.SUBHEADING,
        )
        h += tr(
            "Date, month, year, day, place, city",
            ", ".join(
                answer(x) for x in (
                    self.q23,
                    self.q24,
                    self.q25,
                    self.q26,
                    self.q27,
                    self.q28,
                )),
        )

        h += subheading_spanning_two_columns(self.wxstring(req, "education_s"))
        h += tr_qa("≤12 years’ education?", self.education12y_or_less)
        # noinspection PyTypeChecker
        h += """
            </table>
            <table class="{CssClass.TASKDETAIL}">
                {tr_subhead_images}
                {tr_images_1}
                {tr_images_2}
            </table>
            <div class="{CssClass.FOOTNOTES}">
                [1] Normal is ≥26 (Nasreddine et al. 2005, PubMed ID 15817019).
            </div>
            <div class="{CssClass.COPYRIGHT}">
                MoCA: Copyright © Ziad Nasreddine. In 2012, could be reproduced
                without permission for CLINICAL and EDUCATIONAL use (with
                permission from the copyright holder required for any other
                use), with no special restrictions on electronic versions.
                However, as of 2021, electronic versions are prohibited without
                specific authorization from the copyright holder; see <a
                href="https://camcops.readthedocs.io/en/latest/tasks/moca.html">
                https://camcops.readthedocs.io/en/latest/tasks/moca.html</a>.
            </div>
        """.format(
            CssClass=CssClass,
            tr_subhead_images=subheading_spanning_two_columns(
                "Images of tests: trail, cube, clock", th_not_td=True),
            tr_images_1=tr(
                td(
                    get_blob_img_html(self.trailpicture),
                    td_class=CssClass.PHOTO,
                    td_width="50%",
                ),
                td(
                    get_blob_img_html(self.cubepicture),
                    td_class=CssClass.PHOTO,
                    td_width="50%",
                ),
                literal=True,
            ),
            tr_images_2=tr(
                td(
                    get_blob_img_html(self.clockpicture),
                    td_class=CssClass.PHOTO,
                    td_width="50%",
                ),
                td("", td_class=CssClass.SUBHEADING),
                literal=True,
            ),
        )
        return h
 def subheading(_xstringname: str) -> None:
     q_a_list.append(
         subheading_spanning_two_columns(
             self.wxstring(req, _xstringname)))
Exemple #13
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     score = self.total_score()
     category = self.category(req)
     h = """
         {clinician_comments}
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {tr_is_complete}
                 {total_score}
                 {category}
             </table>
         </div>
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <th width="80%">Question</th>
                 <th width="20%">Score</th>
             </tr>
     """.format(
         clinician_comments=self.get_standard_clinician_comments_block(
             req, self.comments),
         CssClass=CssClass,
         tr_is_complete=self.get_is_complete_tr(req),
         total_score=tr(
             req.sstring(SS.TOTAL_SCORE),
             answer(score) + f" / {self.MAX_SCORE}",
         ),
         category=tr_qa(
             req.sstring(SS.CATEGORY) + " <sup>[1]</sup>", category),
     )
     h += tr_qa(self.wxstring(req, "alert_s"),
                get_yes_no_none(req, self.alert))
     h += tr_qa(
         self.wxstring(req, "highschool_s"),
         get_yes_no_none(req, self.highschooleducation),
     )
     h += tr_qa(self.wxstring(req, "q1_s"), self.q1)
     h += tr_qa(self.wxstring(req, "q2_s"), self.q2)
     h += tr_qa(self.wxstring(req, "q3_s"), self.q3)
     h += tr(
         "Q5 <sup>[2]</sup> (money spent, money left "
         "[<i>scores 2</i>]",
         ", ".join(answer(x) for x in (self.q5a, self.q5b)),
     )
     h += tr_qa(
         "Q6 (animal fluency) [<i>≥15 scores 3, 10–14 scores 2, "
         "5–9 scores 1, 0–4 scores 0</i>]",
         self.q6,
     )
     h += tr(
         "Q7 (recall: apple, pen, tie, house, car)",
         ", ".join(
             answer(x)
             for x in (self.q7a, self.q7b, self.q7c, self.q7d, self.q7e)),
     )
     h += tr(
         "Q8 (backwards: 648, 8537)",
         ", ".join(answer(x) for x in (self.q8b, self.q8c)),
     )
     h += tr(
         "Q9 (clock: hour markers, time [<i>score 2 each</i>]",
         ", ".join(answer(x) for x in (self.q9a, self.q9b)),
     )
     h += tr(
         "Q10 (X in triangle; which is biggest?)",
         ", ".join(answer(x) for x in (self.q10a, self.q10b)),
     )
     h += tr(
         "Q11 (story: Female’s name? Job? When back to work? "
         "State she lived in? [<i>score 2 each</i>])",
         ", ".join(
             answer(x)
             for x in (self.q11a, self.q11b, self.q11c, self.q11d)),
     )
     h += f"""
         </table>
         <table class="{CssClass.TASKDETAIL}">
     """
     h += subheading_spanning_two_columns("Images of tests: clock, shapes")
     # noinspection PyTypeChecker
     h += tr(
         td(
             get_blob_img_html(self.clockpicture),
             td_width="50%",
             td_class=CssClass.PHOTO,
         ),
         td(
             get_blob_img_html(self.shapespicture),
             td_width="50%",
             td_class=CssClass.PHOTO,
         ),
         literal=True,
     )
     h += f"""
         </table>
         <div class="{CssClass.FOOTNOTES}">
             [1] With high school education:
             ≥27 normal, ≥21 MCI, ≤20 dementia.
             Without high school education:
             ≥25 normal, ≥20 MCI, ≤19 dementia.
             (Tariq et al. 2006, PubMed ID 17068312.)
             [2] Q4 (learning the five words) isn’t scored.
         </div>
     """
     return h
Exemple #14
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        h = """
            {clinician_comments}
            <div class="{CssClass.SUMMARY}">
                <table class="{CssClass.SUMMARY}">
                    {tr_is_complete}
                    {date_pertains_to}
                    {category}
                    {psychotic_symptoms}
                </table>
            </div>
            <div class="{CssClass.EXPLANATION}">
                {icd10_symptomatic_disclaimer}
            </div>
            <table class="{CssClass.TASKDETAIL}">
                <tr>
                    <th width="80%">Question</th>
                    <th width="20%">Answer</th>
                </tr>
        """.format(
            clinician_comments=self.get_standard_clinician_comments_block(
                req, self.comments),
            CssClass=CssClass,
            tr_is_complete=self.get_is_complete_tr(req),
            date_pertains_to=tr_qa(
                req.wappstring(AS.DATE_PERTAINS_TO),
                format_datetime(self.date_pertains_to,
                                DateFormat.LONG_DATE,
                                default=None),
            ),
            category=tr_qa(
                req.sstring(SS.CATEGORY) + " <sup>[1,2]</sup>",
                self.get_description(req),
            ),
            psychotic_symptoms=tr_qa(
                self.wxstring(req, "psychotic_symptoms") + " <sup>[2]</sup>",
                get_present_absent_none(req, self.psychosis_present()),
            ),
            icd10_symptomatic_disclaimer=req.wappstring(
                AS.ICD10_SYMPTOMATIC_DISCLAIMER),
        )

        h += self.text_row(req, "core")
        for x in self.CORE_NAMES:
            h += self.row_true_false(req, x)

        h += self.text_row(req, "hypomania_mania")
        for x in self.HYPOMANIA_MANIA_NAMES:
            h += self.row_true_false(req, x)

        h += self.text_row(req, "other_mania")
        for x in self.MANIA_NAMES:
            h += self.row_true_false(req, x)

        h += self.text_row(req, "other_criteria")
        for x in self.OTHER_CRITERIA_NAMES:
            h += self.row_true_false(req, x)

        h += subheading_spanning_two_columns(self.wxstring(req, "psychosis"))
        for x in self.PSYCHOSIS_NAMES:
            h += self.row_true_false(req, x)

        h += f"""
            </table>
            <div class="{CssClass.FOOTNOTES}">
                [1] Hypomania:
                    elevated/irritable mood
                    + sustained for ≥4 days
                    + at least 3 of the “other hypomania” symptoms
                    + some interference with functioning.
                Mania:
                    elevated/irritable mood
                    + sustained for ≥7 days or hospital admission required
                    + at least 3 of the “other mania/hypomania” symptoms
                      (4 if mood only irritable)
                    + severe interference with functioning.
                [2] ICD-10 nonpsychotic mania requires mania without
                    hallucinations/delusions.
                ICD-10 psychotic mania requires mania plus
                hallucinations/delusions other than those that are
                “typically schizophrenic”.
                ICD-10 does not clearly categorize mania with only
                schizophreniform psychotic symptoms; however, Schneiderian
                first-rank symptoms can occur in manic psychosis
                (e.g. Conus P et al., 2004, PMID 15337330.).
            </div>
            {ICD10_COPYRIGHT_DIV}
        """
        return h
 def text_row(self, req: CamcopsRequest, wstringname: str) -> str:
     return subheading_spanning_two_columns(self.wxstring(req, wstringname))
Exemple #16
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     (total, extrapolated) = self.totalscore_extrapolated()
     main_dict = {
         None: None,
         1: "1 — " + self.wxstring(req, "a1"),
         2: "2 — " + self.wxstring(req, "a2"),
         3: "3 — " + self.wxstring(req, "a3"),
         4: "4 — " + self.wxstring(req, "a4"),
         MISSING_VALUE: self.wxstring(req, "no_response")
     }
     last_q_dict = {
         None: None,
         1: "1 — " + self.wxstring(req, "q29_a1"),
         2: "2 — " + self.wxstring(req, "q29_a2"),
         3: "3 — " + self.wxstring(req, "q29_a3"),
         4: "4 — " + self.wxstring(req, "q29_a4"),
         MISSING_VALUE: self.wxstring(req, "no_response")
     }
     instruction_dict = {
         1: self.wxstring(req, "proxy_instruction11"),
         12: self.wxstring(req, "proxy_instruction12"),
         21: self.wxstring(req, "proxy_instruction13"),
         32: self.wxstring(req, "proxy_instruction14"),
     }
     h = """
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {is_complete_tr}
                 <tr>
                     <td>Total score ({min}–{max}), higher better</td>
                     <td>{t}</td>
                 </tr>
                 <tr>
                     <td>Total score extrapolated using incomplete
                     responses? <sup>[1]</sup></td>
                     <td>{e}</td>
                 </tr>
             </table>
         </div>
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <th width="50%">Question</th>
                 <th width="50%">Answer</th>
             </tr>
     """.format(
         CssClass=CssClass,
         is_complete_tr=self.get_is_complete_tr(req),
         min=self.MIN_SCORE,
         max=self.MAX_SCORE,
         t=answer(ws.number_to_dp(total, DP)),
         e=answer(get_yes_no(req, extrapolated)),
     )
     for n in range(1, self.NQUESTIONS + 1):
         if n in instruction_dict:
             h += subheading_spanning_two_columns(instruction_dict.get(n))
         d = main_dict if n <= self.N_SCORED_QUESTIONS else last_q_dict
         q = self.get_q(req, n)
         a = get_from_dict(d, getattr(self, "q" + str(n)))
         h += tr_qa(q, a)
     h += END_DIV + COPYRIGHT_DIV
     return h
Exemple #17
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     score = self.total_score()
     num_symptomatic = self.num_symptomatic()
     num_symptomatic_b = self.num_symptomatic_b()
     num_symptomatic_c = self.num_symptomatic_c()
     num_symptomatic_d = self.num_symptomatic_d()
     ptsd = self.ptsd()
     answer_dict = {None: None}
     for option in range(1, 6):
         answer_dict[option] = (str(option) + " – " +
                                self.wxstring(req, "option" + str(option)))
     q_a = ""
     if hasattr(self, "event") and hasattr(self, "eventdate"):
         # PCL-S
         q_a += tr_qa(self.wxstring(req, "s_event_s"), self.event)
         q_a += tr_qa(self.wxstring(req, "s_eventdate_s"), self.eventdate)
     for q in range(1, self.NQUESTIONS + 1):
         if q == 1 or q == 6 or q == 13:
             section = "B" if q == 1 else ("C" if q == 6 else "D")
             q_a += subheading_spanning_two_columns(
                 f"DSM-IV-TR section {section}")
         q_a += tr_qa(
             self.wxstring(req, "q" + str(q) + "_s"),
             get_from_dict(answer_dict, getattr(self, "q" + str(q))),
         )
     h = """
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {tr_is_complete}
                 {total_score}
                 {num_symptomatic}
                 {dsm_criteria_met}
             </table>
         </div>
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <th width="70%">Question</th>
                 <th width="30%">Answer</th>
             </tr>
             {q_a}
         </table>
         <div class="{CssClass.FOOTNOTES}">
             [1] Questions with scores ≥3 are considered symptomatic.
             [2] ≥1 ‘B’ symptoms and ≥3 ‘C’ symptoms and
                 ≥2 ‘D’ symptoms.
         </div>
     """.format(
         CssClass=CssClass,
         tr_is_complete=self.get_is_complete_tr(req),
         total_score=tr_qa(f"{req.sstring(SS.TOTAL_SCORE)} (17–85)", score),
         num_symptomatic=tr(
             "Number symptomatic <sup>[1]</sup>: B, C, D (total)",
             answer(num_symptomatic_b) + ", " + answer(num_symptomatic_c) +
             ", " + answer(num_symptomatic_d) + " (" +
             answer(num_symptomatic) + ")",
         ),
         dsm_criteria_met=tr_qa(
             self.wxstring(req, "dsm_criteria_met") + " <sup>[2]</sup>",
             get_yes_no(req, ptsd),
         ),
         q_a=q_a,
     )
     return h
    def get_task_html(self, req: CamcopsRequest) -> str:
        def loadvalues(_dict: Dict[int, str], _first: int, _last: int,
                       _xstringprefix: str) -> None:
            for val in range(_first, _last + 1):
                _dict[
                    val] = f"{val} — {self.wxstring(req, f'{_xstringprefix}{val}')}"

        respondent_dict = {}  # type: Dict[int, str]
        loadvalues(
            respondent_dict,
            self.VAL_QA_PATIENT,
            self.VAL_QA_PARTNER_OTHER,
            "qa_a",
        )
        service_dict = {}  # type: Dict[int, str]
        loadvalues(service_dict, self.VAL_QB_INPATIENT, self.VAL_QB_COMMUNITY,
                   "qb_a")
        mh_dict = {}  # type: Dict[int, str]
        loadvalues(
            mh_dict,
            self.VAL_Q1_VERY_WELL,
            self.VAL_Q1_EXTREMELY_UNWELL,
            "q1_a",
        )
        agree_dict = {}  # type: Dict[int, str]
        loadvalues(
            agree_dict,
            self.VAL_STRONGLY_AGREE,
            self.VAL_STRONGLY_DISAGREE,
            "agreement_a",
        )

        q_a_list = []  # type: List[str]

        def addqa(_fieldname: str, _valuedict: Dict[int, str]) -> None:
            xstringname = _fieldname + "_q"
            q_a_list.append(
                tr_qa(
                    self.xstring(req, xstringname),  # not wxstring
                    get_from_dict(_valuedict, getattr(self, _fieldname)),
                ))

        def subheading(_xstringname: str) -> None:
            q_a_list.append(
                subheading_spanning_two_columns(
                    self.wxstring(req, _xstringname)))

        # Preamble
        addqa(self.FN_QA_RESPONDENT, respondent_dict)
        addqa(self.FN_QB_SERVICE_TYPE, service_dict)
        # The bulk
        subheading("q1_stem")
        for fieldname in self.Q1_FIELDS:
            addqa(fieldname, mh_dict)
        subheading("q2_stem")
        for fieldname in self.Q2_FIELDS:
            addqa(fieldname, agree_dict)
        if self.was_inpatient():
            subheading("q3_stem")
            for fieldname in self.Q3_FIELDS:
                addqa(fieldname, agree_dict)
        # General
        q_a_list.append(
            subheading_spanning_two_columns(req.sstring(SS.GENERAL)))
        q_a_list.append(
            tr_qa(self.wxstring(req, "general_comments_q"),
                  self.general_comments))
        q_a_list.append(
            tr_qa(
                self.wxstring(req, "participation_q"),
                get_yes_no_none(req, self.future_participation),
            ))
        if self.offering_participation():
            q_a_list.append(
                tr_qa(
                    self.wxstring(req, "contact_details_q"),
                    self.contact_details,
                ))

        q_a = "\n".join(q_a_list)
        return f"""
Exemple #19
0
    def get_task_html(self, req: CamcopsRequest) -> str:
        score = self.total_score()
        num_symptomatic = self.num_symptomatic()
        num_symptomatic_b = self.num_symptomatic_b()
        num_symptomatic_c = self.num_symptomatic_c()
        num_symptomatic_d = self.num_symptomatic_d()
        num_symptomatic_e = self.num_symptomatic_e()
        ptsd = self.ptsd()
        answer_dict = {None: None}
        for option in range(5):
            answer_dict[option] = (str(option) + " – " +
                                   self.wxstring(req, "a" + str(option)))
        q_a = ""

        section_start = {
            1: "B (intrusion symptoms)",
            6: "C (avoidance)",
            8: "D (negative cognition/mood)",
            15: "E (arousal/reactivity)",
        }

        for q in range(1, self.N_QUESTIONS + 1):
            if q in section_start:
                section = section_start[q]
                q_a += subheading_spanning_two_columns(
                    f"DSM-5 section {section}")

            q_a += tr_qa(
                self.wxstring(req, "q" + str(q) + "_s"),
                get_from_dict(answer_dict, getattr(self, "q" + str(q))),
            )

        h = """
            <div class="{CssClass.SUMMARY}">
                <table class="{CssClass.SUMMARY}">
                    {tr_is_complete}
                    {total_score}
                    {num_symptomatic}
                    {dsm_criteria_met}
                </table>
            </div>
            <table class="{CssClass.TASKDETAIL}">
                <tr>
                    <th width="70%">Question</th>
                    <th width="30%">Answer</th>
                </tr>
                {q_a}
            </table>
            <div class="{CssClass.FOOTNOTES}">
                [1] Questions with scores ≥2 are considered symptomatic; see
                    https://www.ptsd.va.gov/professional/assessment/adult-sr/ptsd-checklist.asp
                [2] ≥1 ‘B’ symptoms and ≥1 ‘C’ symptoms and ≥2 ‘D’ symptoms
                    and ≥2 ‘E’ symptoms.
            </div>
        """.format(  # noqa
            CssClass=CssClass,
            tr_is_complete=self.get_is_complete_tr(req),
            total_score=tr_qa(f"{req.sstring(SS.TOTAL_SCORE)} (0–80)", score),
            num_symptomatic=tr(
                "Number symptomatic <sup>[1]</sup>: B, C, D, E (total)",
                answer(num_symptomatic_b) + ", " + answer(num_symptomatic_c) +
                ", " + answer(num_symptomatic_d) + ", " +
                answer(num_symptomatic_e) + " (" + answer(num_symptomatic) +
                ")",
            ),
            dsm_criteria_met=tr_qa(
                self.wxstring(req, "dsm_criteria_met") + " <sup>[2]</sup>",
                get_yes_no(req, ptsd),
            ),
            q_a=q_a,
        )
        return h
Exemple #20
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>
            """)
Exemple #21
0
 def get_task_html(self, req: CamcopsRequest) -> str:
     severity_dict = {
         None: None,
         1: self.wxstring(req, "i_option1"),
         2: self.wxstring(req, "i_option2"),
         3: self.wxstring(req, "i_option3"),
         4: self.wxstring(req, "i_option4"),
         5: self.wxstring(req, "i_option5"),
         6: self.wxstring(req, "i_option6"),
         7: self.wxstring(req, "i_option7"),
     }
     change_dict = {
         None: None,
         1: self.wxstring(req, "ii_option1"),
         2: self.wxstring(req, "ii_option2"),
         3: self.wxstring(req, "ii_option3"),
         4: self.wxstring(req, "ii_option4"),
         5: self.wxstring(req, "ii_option5"),
         6: self.wxstring(req, "ii_option6"),
         7: self.wxstring(req, "ii_option7"),
         9: self.wxstring(req, "ii_option9"),
     }
     h = """
         <div class="{CssClass.SUMMARY}">
             <table class="{CssClass.SUMMARY}">
                 {tr_is_complete}
             </table>
         </div>
         <table class="{CssClass.TASKDETAIL}">
             <tr>
                 <th width="70%">Question</th>
                 <th width="30%">Answer <sup>[1]</sup></th>
             </tr>
     """.format(
         CssClass=CssClass,
         tr_is_complete=self.get_is_complete_tr(req)
     )
     h += subheading_spanning_two_columns(self.wxstring(req, "i_title"))
     h += tr_span_col(self.wxstring(req, "i_question"), cols=2)
     h += tr_qa(self.wxstring(req, "q1"),
                get_from_dict(severity_dict, self.severity1))
     h += tr_qa(self.wxstring(req, "q2"),
                get_from_dict(severity_dict, self.severity2))
     h += tr_qa(self.wxstring(req, "q3"),
                get_from_dict(severity_dict, self.severity3))
     h += tr_qa(self.wxstring(req, "q4"),
                get_from_dict(severity_dict, self.severity4))
     h += tr_qa(self.wxstring(req, "q5"),
                get_from_dict(severity_dict, self.severity5))
     h += subheading_spanning_two_columns(self.wxstring(req, "ii_title"))
     h += tr_span_col(self.wxstring(req, "ii_question"), cols=2)
     h += tr_qa(self.wxstring(req, "q1"),
                get_from_dict(change_dict, self.change1))
     h += tr_qa(self.wxstring(req, "q2"),
                get_from_dict(change_dict, self.change2))
     h += tr_qa(self.wxstring(req, "q3"),
                get_from_dict(change_dict, self.change3))
     h += tr_qa(self.wxstring(req, "q4"),
                get_from_dict(change_dict, self.change4))
     h += tr_qa(self.wxstring(req, "q5"),
                get_from_dict(change_dict, self.change5))
     h += """
         </table>
         <div class="{CssClass.FOOTNOTES}">
             [1] All questions are scored 1–7, or 9 (not applicable, for
             change questions).
             {postscript}
         </div>
     """.format(
         CssClass=CssClass,
         postscript=self.wxstring(req, "ii_postscript"),
     )
     return h