Skip to content

Commit

Permalink
Merge pull request #8 from aaghamohammadi/dev
Browse files Browse the repository at this point in the history
Add ReportGenerator and Logging
  • Loading branch information
aaghamohammadi authored Dec 13, 2023
2 parents e82a023 + e087d38 commit b38990d
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 2 deletions.
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ max-line-length = 88

[tool:pytest]
testpaths = tests
addopts = --cov --strict-markers --cov-report=xml
addopts = --cov --strict-markers --cov-report=term --cov-report=xml
xfail_strict = True

[coverage:run]
Expand Down
2 changes: 2 additions & 0 deletions src/pysolorie/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from .model import HottelModel
from .numerical_integration import IrradiationCalculator
from .observer import Observer
from .report import ReportGenerator
from .sun_position import SunPosition

__all__ = [
Expand All @@ -26,4 +27,5 @@
"Observer",
"AtmosphericTransmission",
"IrradiationCalculator",
"ReportGenerator",
]
30 changes: 30 additions & 0 deletions src/pysolorie/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2023 Alireza Aghamohammadi

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging


def logger_decorator(cls):
class WithLogging(cls): # type: ignore
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.logger = logging.getLogger(cls.__name__)
self.logger.setLevel(logging.INFO)
self.logger.propagate = False
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)

return WithLogging
58 changes: 58 additions & 0 deletions src/pysolorie/report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright 2023 Alireza Aghamohammadi

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import csv
from pathlib import Path

from .logger import logger_decorator
from .numerical_integration import IrradiationCalculator


@logger_decorator
class ReportGenerator:
def generate_optimal_orientation_csv_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 CSV format.
:param path: A Path object that points to the CSV 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
"""
with open(path, "w", newline="") as file:
writer = csv.writer(file)
writer.writerow(["Day", "Beta (degrees)"])

for day in range(from_day, to_day):
beta = irradiation_calculator.find_optimal_orientation(day)
logger_name = "logger"
getattr(self, logger_name).info(
f"On day {day},"
+ "the solar panel's optimal orientation is {beta} degrees."
)

# Write the result to the CSV file
writer.writerow([day, beta])
35 changes: 34 additions & 1 deletion tests/test_pysolorie.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import csv
import math
from pathlib import Path
from typing import Tuple

import pytest
Expand All @@ -22,6 +23,7 @@
HottelModel,
IrradiationCalculator,
Observer,
ReportGenerator,
SolarIrradiance,
SunPosition,
)
Expand Down Expand Up @@ -270,3 +272,34 @@ def test_find_optimal_orientation(
)
result = irradiation_calculator.find_optimal_orientation(day_of_year)
assert pytest.approx(result, abs=1e-3) == expected_result


def test_generate_optimal_orientation_csv_report(tmpdir):
# Create a temporary directory for the test
temp_dir = Path(tmpdir)

# Initialize the ReportGenerator
report_generator = ReportGenerator()

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

# Define the path for the CSV file
csv_path = temp_dir / "report.csv"
from_day = 60
to_day = 70
# Call the method to generate the report
report_generator.generate_optimal_orientation_csv_report(
csv_path, irradiation_calculator, from_day, to_day
)

# Check the CSV file
with open(csv_path, "r") as file:
reader = csv.reader(file)
header = next(reader)
assert header == ["Day", "Beta (degrees)"]
for i, row in enumerate(reader, start=from_day):
day, beta = row
assert int(day) == i
expected_beta = irradiation_calculator.find_optimal_orientation(i)
assert pytest.approx(float(beta), abs=1e-3) == expected_beta

0 comments on commit b38990d

Please sign in to comment.