From f05fc37cc5700b354459a9eb6852652ad3abd944 Mon Sep 17 00:00:00 2001 From: bain Date: Thu, 3 Aug 2023 19:58:43 +0200 Subject: [PATCH] change Report data classs and fetching behaviour Most fields on ReportSubject can be disabled by the supervisor, so they're Optional. Instead of having a Report.published attribute, the Period.report property can directly return none, since the report has no data anyway. --- pronotepy/dataClasses.py | 58 +++++++++++++++++++++++++------------ pronotepy/test_pronotepy.py | 9 +++--- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/pronotepy/dataClasses.py b/pronotepy/dataClasses.py index ac584a8..119a253 100644 --- a/pronotepy/dataClasses.py +++ b/pronotepy/dataClasses.py @@ -324,42 +324,56 @@ class Report(Object): """Represents a student report. You shouldn't have to create this class manually. Attributes: - published (bool): Is the report published ? subjects (List[ReportSubject]): the subjects that are present in the report comments (List[str]): the global report comments """ - class ReportSubject(Subject): + class ReportSubject(Object): """ Represents a subject found in a report. You shouldn't have to create this class manually. Attributes: + id (str): the id of the subject (used internally) + name (str): name of the subject color (str): the color of the subject comments (List[str]): the list of the subject's comments - class_average (str): the average of the class - student_average (str): the average of the student - min_average (str): the lowest average of the class - max_average (str): the highest average of the class - coefficient (str): the coefficient of the subject + class_average (Optional[str]): the average of the class + student_average (Optional[str]): the average of the student + min_average (Optional[str]): the lowest average of the class + max_average (Optional[str]): the highest average of the class + coefficient (Optional[str]): the coefficient of the subject teachers (List[str]): the subject's teachers' names """ def __init__(self, parsed_json: dict) -> None: super().__init__(parsed_json) + self.id: str = self._resolver(str, "N") + self.name: str = self._resolver(str, "L") + self.color: str = self._resolver(str, "couleur") self.comments: List[str] = self._resolver( lambda l: [c["L"] for c in l if "L" in c], "ListeAppreciations", "V" ) - self.class_average: str = self._resolver( - Util.grade_parse, "MoyenneClasse", "V" + + def grade_or_none(grade: Any) -> Optional[str]: + return Util.grade_parse(grade) if grade else None + + self.class_average: Optional[str] = self._resolver( + grade_or_none, "MoyenneClasse", "V", strict=False + ) + self.student_average: Optional[str] = self._resolver( + grade_or_none, "MoyenneEleve", "V", strict=False ) - self.student_average: str = self._resolver( - Util.grade_parse, "MoyenneEleve", "V" + self.min_average: Optional[str] = self._resolver( + grade_or_none, "MoyenneInf", "V", strict=False + ) + self.max_average: Optional[str] = self._resolver( + grade_or_none, "MoyenneSup", "V", strict=False + ) + self.coefficient: Optional[str] = self._resolver( + str, "Coefficient", "V", strict=False ) - self.min_average: str = self._resolver(Util.grade_parse, "MoyenneInf", "V") - self.max_average: str = self._resolver(Util.grade_parse, "MoyenneSup", "V") - self.coefficient: str = self._resolver(str, "Coefficient", "V") self.teachers: List[str] = self._resolver( lambda l: [i["L"] for i in l], "ListeProfesseurs", "V", default=[] ) @@ -376,7 +390,7 @@ def __init__(self, parsed_json: dict) -> None: default=[], ) self.comments: List[str] = self._resolver( - lambda l: [c["L"] for c in l], + lambda l: [c["L"] for c in l if "L" in c], "ObjetListeAppreciations", "V", "ListeAppreciations", @@ -480,11 +494,17 @@ def __init__(self, client: ClientBase, json_dict: dict) -> None: del self._resolver @property - def report(self) -> Report: - """Gets a report from a period""" + def report(self) -> Optional[Report]: + """ + Gets a report from a period. + + Returns: + Optional[Report]: + When ``None``, then the report is not yet published or is unavailable for any other reason + """ json_data = {"periode": {"G": 2, "N": self.id, "L": self.name}} - response = self._client.post("PageBulletins", 13, json_data) - return Report(response["donneesSec"]["donnees"]) + data = self._client.post("PageBulletins", 13, json_data)["donneesSec"]["donnees"] + return Report(data) if "Message" not in data else None @property def grades(self) -> List["Grade"]: diff --git a/pronotepy/test_pronotepy.py b/pronotepy/test_pronotepy.py index 0285c44..ae522c3 100644 --- a/pronotepy/test_pronotepy.py +++ b/pronotepy/test_pronotepy.py @@ -84,11 +84,6 @@ def test_refresh(self) -> None: client.refresh() self.assertEqual(client.session_check(), True) - def test_report(self) -> None: - report = client.periods[0].report - - self.assertIsInstance(report, pronotepy.Report) - class TestPeriod(unittest.TestCase): period: pronotepy.Period @@ -138,6 +133,10 @@ def test_class_overall_average(self) -> None: a = self.period.class_overall_average self.assertTrue(type(a) is str or a is None) + def test_report(self) -> None: + report = self.period.report + self.assertTrue(report is None or isinstance(report, pronotepy.Report)) + class TestInformation(unittest.TestCase): def test_unread(self) -> None: