Skip to content

Commit

Permalink
Implement XML Report Generation and Expand Testing
Browse files Browse the repository at this point in the history
- Imported xml.etree.ElementTree module in report.py for XML support.
- Introduced `generate_optimal_orientation_xml_report` method in ReportGenerator.
- The new method generates an XML formatted report of optimal solar panel orientations.
- Extended the `ReportGenerator` class to include data serialization into XML format.
- Augmented unit tests to validate XML report output in test_pysolorie.py.
- Ensured consistency and efficacy of the XML report content through comprehensive testing.
  • Loading branch information
aaghamohammadi committed Dec 20, 2023
1 parent 5b5067f commit 3a8383f
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/pysolorie/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import csv
import json
import logging
import xml.etree.ElementTree as ET
from pathlib import Path
from typing import Dict, List, Union

Expand Down Expand Up @@ -154,3 +155,50 @@ def generate_optimal_orientation_json_report(
# Write the data list to the JSON file
with open(path, "w") as file:
json.dump(data, file, indent=4)

@logger_decorator
def generate_optimal_orientation_xml_report(
self,
path: Path,
irradiation_calculator: IrradiationCalculator,
from_day: int,
to_day: int,
) -> None:
r"""
This method generates a report of optimal solar panel orientation in XML format.
It uses the ``_calculate_optimal_orientation_and_irradiation``
method to get the data.
:param path: A Path object that points to the XML file
where the report will be written.
:type path: Path
:param irradiation_calculator: An instance of the IrradiationCalculator class.
:type irradiation_calculator: pysolorie.IrradiationCalculator
:param from_day: The starting day of the report.
:type from_day: int
:param to_day: The ending day of the report.
:type to_day: int
"""
data = self._calculate_optimal_orientation_and_irradiation(
irradiation_calculator, from_day, to_day
)

# Create the root element
root = ET.Element("Report")

for row in data:
# Create a 'Day' element for each day
day_element = ET.SubElement(root, "Day")
day_element.set("id", str(row["Day"]))

# Create 'Beta' and 'TotalDirectIrradiation' elements for each day
beta_element = ET.SubElement(day_element, "Beta")
beta_element.text = str(row["Beta (degrees)"])
tdi_element = ET.SubElement(day_element, "TotalDirectIrradiation")
tdi_element.text = str(
row["Total Direct Irradiation (Megajoules per square meter)"]
)

# Write the XML data to the file
tree = ET.ElementTree(root)
tree.write(path)
45 changes: 45 additions & 0 deletions tests/test_pysolorie.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import csv
import json
import math
import xml.etree.ElementTree as ET
from pathlib import Path
from typing import Any, Dict, List, Tuple
from unittest.mock import MagicMock
Expand Down Expand Up @@ -431,6 +432,50 @@ def test_generate_optimal_orientation_json_report(tmpdir) -> None:
)


def test_generate_optimal_orientation_xml_report(tmpdir) -> None:
# Create a temporary directory for the test
temp_dir: Path = Path(tmpdir)

# Initialize the ReportGenerator
report_generator: ReportGenerator = ReportGenerator()

# Initialize the IrradiationCalculator for Tehran
irradiation_calculator: IrradiationCalculator = IrradiationCalculator(
"MIDLATITUDE SUMMER", 1200, 35.6892
)

# Define the path for the XML file
xml_path: Path = temp_dir / "report.xml"
from_day: int = 60
to_day: int = 70
# Call the method to generate the report
report_generator.generate_optimal_orientation_xml_report(
xml_path, irradiation_calculator, from_day, to_day
)

# Check the XML file
tree = ET.parse(xml_path)
root = tree.getroot()

for i, day_element in enumerate(root.findall("Day"), start=from_day):
day = int(day_element.get("id"))
beta = float(day_element.find("Beta").text)
total_direct_irradiation = float(
day_element.find("TotalDirectIrradiation").text
)

assert day == i
expected_beta = irradiation_calculator.find_optimal_orientation(i)
expected_total_direct_irradiation = (
irradiation_calculator.calculate_direct_irradiation(beta, i)
)
assert pytest.approx(beta, abs=1e-3) == expected_beta
assert (
pytest.approx(total_direct_irradiation, abs=1e-3)
== expected_total_direct_irradiation
)


def test_plot_optimal_orientation(tmpdir) -> None:
# Create a temporary directory for the test
temp_dir: Path = Path(tmpdir)
Expand Down

0 comments on commit 3a8383f

Please sign in to comment.