Source code for camcops_server.cc_modules.cc_summaryelement

#!/usr/bin/env python



    Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
    Created by Rudolf Cardinal (

    This file is part of CamCOPS.

    CamCOPS is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    CamCOPS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with CamCOPS. If not, see <>.


**Classes to represent summary information created by tasks.**

For example, the PHQ9 task calculates a total score; that's part of its summary


from collections import OrderedDict
from typing import Any, Dict, List, Optional, Set, Type, TYPE_CHECKING, Union

from cardinal_pythonlib.reprfunc import auto_repr
from sqlalchemy.sql.schema import Column
from sqlalchemy.sql.type_api import TypeEngine

from camcops_server.cc_modules.cc_dataclasses import SummarySchemaInfo
from camcops_server.cc_modules.cc_db import TaskDescendant
from camcops_server.cc_modules.cc_spreadsheet import SpreadsheetPage
from camcops_server.cc_modules.cc_xml import XmlElement

    from camcops_server.cc_modules.cc_task import Task

# =============================================================================
# SummaryElement
# =============================================================================

[docs]class SummaryElement(object): """ Returned by tasks to represent extra summary information that they calculate. Use this for extra information that can be added to a row represented by a task or its ancillary object. """
[docs] def __init__( self, name: str, coltype: TypeEngine, value: Any, comment: str = None ) -> None: """ Args: name: column name coltype: SQLAlchemy column type; e.g. ``Integer()``, ``String(length=50)`` value: value comment: explanatory comment """ = name self.coltype = coltype self.value = value self.comment = comment
@property def decorated_comment(self) -> Optional[str]: return "(SUMMARY) " + self.comment if self.comment else None
# ============================================================================= # ExtraSummaryTable # =============================================================================
[docs]class ExtraSummaryTable(TaskDescendant): """ Additional summary information returned by a task. Use this to represent an entire table that doesn't have a 1:1 relationship with rows of a task or ancillary object. """
[docs] def __init__( self, tablename: str, xmlname: str, columns: List[Column], rows: List[Union[Dict[str, Any], OrderedDict]], task: "Task", ) -> None: """ Args: tablename: name of the additional summary table xmlname: name of the XML tag to encapsulate this information columns: list of SQLAlchemy columns rows: list of rows, where each row is a dictionary mapping column names to values task: parent task (for cross-referencing in some kinds of export) """ self.tablename = tablename self.xmlname = xmlname self.columns = columns self.rows = rows self.task = task
[docs] def get_xml_element(self) -> XmlElement: """ Returns an :class:`camcops_server.cc_modules.cc_xml.XmlElement` representing this summary table. """ itembranches = [] # type: List[XmlElement] for valuedict in self.rows: leaves = [] # type: List[XmlElement] for k, v in valuedict.items(): leaves.append(XmlElement(name=k, value=v)) branch = XmlElement(name=self.tablename, value=leaves) itembranches.append(branch) return XmlElement(name=self.xmlname, value=itembranches)
[docs] def get_spreadsheet_page(self) -> SpreadsheetPage: """ Returns an :class:`camcops_server.cc_modules.cc_spreadsheet.SpreadsheetPage` representing this summary table. """ return SpreadsheetPage(name=self.tablename, rows=self.rows)
[docs] def get_spreadsheet_schema_elements(self) -> Set[SummarySchemaInfo]: """ Schema equivalent to :func:`get_spreadsheet_page`. """ return set( SummarySchemaInfo.from_column( c, table_name=self.tablename, source=SummarySchemaInfo.SSV_SUMMARY, ) for c in self.columns )
def __repr__(self) -> str: return auto_repr(self) # ------------------------------------------------------------------------- # TaskDescendant overrides # ------------------------------------------------------------------------- @classmethod def task_ancestor_class(cls) -> Optional[Type["Task"]]: return None
[docs] def task_ancestor(self) -> Optional["Task"]: return self.task