Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ready to publish v1.5.6 #18

Merged
merged 2 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
Changelog
=========

Version 1.5.6
-------------

Release date: 2023-12-29


Fixed
^^^^^
- Introduced a new exception class ``InvalidObserverLatitudeError`` in ``exceptions.py`` for better error handling of invalid observer latitude values.
- Updated ``IrradiationCalculator`` in ``numerical_integration.py`` to handle cases where the ``irradiance_components`` dictionary is empty, providing a meaningful return value based on observer latitude.
- Fixed ``Observer`` class validation in ``observer.py`` to include a check for the observer's latitude being within the valid range.


Testing
^^^^^^^
- Added test case ``test_calculate_sunrise_sunset_invalid_latitude`` to ensure exceptions are properly raised for invalid latitude inputs.
- Added missing tests for invalid observer latitude in ``test_observer.py``.



Version 1.5.5
-------------

Expand Down
3 changes: 2 additions & 1 deletion paper/paper.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ The energy collected by a solar panel can be calculated using the formula in Equ
E(n,\phi) = \frac{I(n)}{\Omega} \int_{\omega_s}^{\omega_t}\cos(\theta) \times H(\cos(\theta)) \times \tau_b~d\omega
\end{equation}


# Acknowledgements
Amir Aghamohammadi would like to acknowledge the research council of the Alzahra University for the financial support.


# References
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = pysolorie
version = 1.5.5
version = 1.5.6
description = Orientation Analysis of Solar Panel
long_description = file: README.md
long_description_content_type = text/markdown
Expand Down
31 changes: 31 additions & 0 deletions src/pysolorie/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,34 @@ def __str__(self) -> str:
:rtype: str
"""
return f"{self.message}"


class InvalidObserverLatitudeError(ValueError):
"""
Exception raised when the observer's latitude is not within the valid range.

:param message: explanation of the error, defaults to
"Invalid data: Observer latitude.
Please ensure to provide a latitude between -88 and 88 degrees."
:type message: str, optional
"""

def __init__(
self,
message: str = (
"Invalid data: Observer latitude. "
"Please ensure to provide a latitude between -88 and 88 degrees."
),
):
self.message = message
super().__init__(self.message)

def __str__(self) -> str:
"""
String representation of the exception.

:return: formatted string indicating the invalid
latitude and the error message
:rtype: str
"""
return f"{self.message}"
9 changes: 9 additions & 0 deletions src/pysolorie/numerical_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,13 @@ def neg_irradiation(beta: float):
neg_irradiation, bounds=(-math.pi / 2, math.pi / 2), method="bounded"
)
optimal_beta = result.x

# Check if irradiance_components is empty
if not self.calculate_direct_irradiation(
math.degrees(optimal_beta), day_of_year
):
observer_latitude = self._observer._ensure_latitude_provided()
# Return 90 or -90 based on observer_latitude
return 90 if observer_latitude >= 0 else -90

return math.degrees(optimal_beta)
4 changes: 3 additions & 1 deletion src/pysolorie/observer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import math
from typing import Optional

from .exceptions import MissingObserverLatitudeError
from .exceptions import InvalidObserverLatitudeError, MissingObserverLatitudeError
from .sun_position import SunPosition


Expand Down Expand Up @@ -117,6 +117,8 @@ def calculate_sunrise_sunset(self, day_of_year: int) -> tuple:
def _ensure_latitude_provided(self) -> float:
if self.observer_latitude is None:
raise MissingObserverLatitudeError()
if not math.radians(-88) <= self.observer_latitude <= math.radians(88):
raise InvalidObserverLatitudeError()
return self.observer_latitude

_observer_latitude: Optional[float]
Expand Down
12 changes: 11 additions & 1 deletion tests/test_observer.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
13 * 60 * 60,
1.547,
), # Test at Fairbanks on the 1st day of the year at 1pm
(90, 0, 1, 13 * 60 * 60, 1.972), # Test at North Pole on January 1st at 1pm
],
)
def test_calculate_zenith_angle(
Expand Down Expand Up @@ -114,3 +113,14 @@ def test_calculate_sunrise_sunset(
)
assert sunrise_hour_angle == pytest.approx(expected_sunrise_hour_angle, abs=1e-3)
assert sunset_hour_angle == pytest.approx(expected_sunset_hour_angle, abs=1e-3)


def test_calculate_sunrise_sunset_invalid_latitude():
invalid_latitudes = [89, -89]
for invalid_latitude in invalid_latitudes:
observer = Observer(invalid_latitude)
with pytest.raises(
ValueError,
match="Invalid data: Observer latitude. ",
):
observer.calculate_sunrise_sunset(day_of_year=172)