From a05f85cdd7b69589b6d39af7671ea898c46be87a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Luk=C3=A1ny?= Date: Thu, 10 Aug 2023 14:25:34 +0200 Subject: [PATCH 1/2] feat: make addition of ToC idempotent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By design it was possible to add table of contents multiple times. The rendered report then contained multiple table of contents. Having a separate argument for table of contents instead of having it in sections list makes multiple calls of add_table_of_contents() idempotent — always only one ToC is rendered in the end. --- edvart/report.py | 17 ++++++++--------- edvart/report_sections/table_of_contents.py | 6 ++---- tests/test_report.py | 12 ++++++------ 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/edvart/report.py b/edvart/report.py index fead723..7961963 100755 --- a/edvart/report.py +++ b/edvart/report.py @@ -46,14 +46,14 @@ def __init__( self.df = dataframe self.sections: list[Section] = [] self.verbosity = Verbosity(verbosity) + self._table_of_contents = None def show(self) -> None: """Renders the report in the calling notebook.""" + if self._table_of_contents is not None: + self._table_of_contents.show(self.sections) for section in self.sections: - if isinstance(section, TableOfContents): - section.show(self.sections) - else: - section.show(self.df) + section.show(self.df) def _select_columns( self, @@ -173,11 +173,10 @@ def _generate_notebook( nb["cells"].append(nbf4.new_code_cell(load_df)) # Generate code for each report section + if self._table_of_contents is not None: + self._table_of_contents.add_cells(self.sections, nb["cells"]) for section in self.sections: - if isinstance(section, TableOfContents): - section.add_cells(self.sections, nb["cells"]) - else: - section.add_cells(nb["cells"]) + section.add_cells(nb["cells"]) return nb @@ -592,7 +591,7 @@ def add_table_of_contents(self, include_subsections: bool = True) -> "ReportBase contents. However, they won't be included in an exported notebook created by report's export_notebook function. """ - self.sections.append(TableOfContents(include_subsections)) + self._table_of_contents = TableOfContents(include_subsections) return self diff --git a/edvart/report_sections/table_of_contents.py b/edvart/report_sections/table_of_contents.py index cf8aeb5..2889fba 100644 --- a/edvart/report_sections/table_of_contents.py +++ b/edvart/report_sections/table_of_contents.py @@ -89,8 +89,7 @@ def add_cells(self, sections: List[Section], cells: List[Dict[str, Any]]) -> Non # Add links to all main sections (not including subsections) besides the first (table of # content) section for section in sections: - if not isinstance(section, TableOfContents): - lines.append(TableOfContents._get_section_link(section, 1)) + lines.append(TableOfContents._get_section_link(section, 1)) cells.append(nbfv4.new_markdown_cell("\n".join(lines))) # pylint: disable=arguments-renamed @@ -108,6 +107,5 @@ def show(self, sections: List[Section]) -> None: # Add links to all sections including their subsections besides the first (table of content) # section for section in sections: - if not isinstance(section, TableOfContents): - self._add_section_lines(section, 1, lines, self._include_subsections) + self._add_section_lines(section, 1, lines, self._include_subsections) display(Markdown("\n".join(lines))) diff --git a/tests/test_report.py b/tests/test_report.py index b40e48f..7d2cd67 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -40,14 +40,14 @@ def test_default_report(): ) assert len(report.sections) > 0, "Default report should not be empty" - assert report.sections[1].verbosity == Verbosity.MEDIUM, "Wrong section verbosity" - assert report.sections[1].columns is None, "Default column selection should be None" + assert report.sections[0].verbosity == Verbosity.MEDIUM, "Wrong section verbosity" + assert report.sections[0].columns is None, "Default column selection should be None" - assert report.sections[2].verbosity == Verbosity.HIGH, "Wrong section verbosity" - assert report.sections[2].columns is None, "Default column selection should be None" + assert report.sections[1].verbosity == Verbosity.HIGH, "Wrong section verbosity" + assert report.sections[1].columns is None, "Default column selection should be None" - assert report.sections[3].verbosity == Verbosity.LOW, "Wrong section verbosity" - assert report.sections[3].columns == ["Col1", "Col2", "Col3"], "Wrong columns" + assert report.sections[2].verbosity == Verbosity.LOW, "Wrong section verbosity" + assert report.sections[2].columns == ["Col1", "Col2", "Col3"], "Wrong columns" def test_column_selection(): From 70a062a68cf6e5443315e894ab8461f67f3df80c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Luk=C3=A1ny?= Date: Fri, 11 Aug 2023 10:05:34 +0200 Subject: [PATCH 2/2] Remove now redundant comments --- edvart/report_sections/table_of_contents.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/edvart/report_sections/table_of_contents.py b/edvart/report_sections/table_of_contents.py index 2889fba..4aeea73 100644 --- a/edvart/report_sections/table_of_contents.py +++ b/edvart/report_sections/table_of_contents.py @@ -86,8 +86,6 @@ def add_cells(self, sections: List[Section], cells: List[Dict[str, Any]]) -> Non cells.append(section_header) lines: List[str] = [] - # Add links to all main sections (not including subsections) besides the first (table of - # content) section for section in sections: lines.append(TableOfContents._get_section_link(section, 1)) cells.append(nbfv4.new_markdown_cell("\n".join(lines))) @@ -104,8 +102,6 @@ def show(self, sections: List[Section]) -> None: display(Markdown(self.get_title(section_level=1))) lines = [] - # Add links to all sections including their subsections besides the first (table of content) - # section for section in sections: self._add_section_lines(section, 1, lines, self._include_subsections) display(Markdown("\n".join(lines)))