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

created EEWeatherWarning #26

Merged
merged 6 commits into from
Aug 21, 2018
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Information about version updates and instructions for upgrading where
needed.

## 0.3.4

Created an EEWeatherWarning object to capture distance warnings.

## 0.3.2

Bug fix in `select_stations`.
2 changes: 1 addition & 1 deletion eeweather/__version__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
__title__ = 'eeweather'
__description__ = 'Weather for Open Energy Efficiency Meter'
__url__ = 'https://github.com/openeemeter/eeweather'
__version__ = '0.3.3'
__version__ = '0.3.4'
__author__ = 'Phil Ngo'
__author_email__ = '[email protected]'
__license__ = 'Apache 2.0'
Expand Down
27 changes: 23 additions & 4 deletions eeweather/ranking.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .geo import get_lat_long_climate_zones
from .stations import ISDStation
from .utils import lazy_property
from .warnings import EEWeatherWarning

__all__ = (
'rank_stations',
Expand Down Expand Up @@ -343,9 +344,16 @@ def _test_station(station):

def _station_warnings(station, distance_meters):
return [
(
'Distance from target to weather station is greater than {}km.'
.format(round(d / 1000))
EEWeatherWarning(
qualified_name='eeweather.exceeds_maximum_distance',
description=(
'Distance from target to weather station is greater'
'than the specified km.'
),
data={
'distance_meters': distance_meters,
'max_distance_meters': d
}
)
for d in distance_warnings
if distance_meters > d
Expand All @@ -359,4 +367,15 @@ def _station_warnings(station, distance_meters):
if n_stations_passed == rank:
return station, _station_warnings(station, row.distance_meters)

return None, ['No weather station qualified.']
no_station_warning = EEWeatherWarning(
qualified_name='eeweather.no_weather_station_selected',
description=(
'No weather station found with the specified rank and'
' minimum fracitional coverage.'
),
data={
'rank': rank,
'min_fraction_coverage': min_fraction_coverage
}
)
return None, [no_station_warning]
32 changes: 32 additions & 0 deletions eeweather/warnings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class EEWeatherWarning(object):
''' An object representing a warning and data associated with it.

Attributes
----------
qualified_name : :any:`str`
Qualified name, e.g., `'eeweather.method_abc.missing_data'`.
description : :any:`str`
Prose describing the nature of the warning.
data : :any:`dict`
Data that reproducibly shows why the warning was issued.
'''

def __init__(self, qualified_name, description, data):
self.qualified_name = qualified_name
self.description = description
self.data = data

def __repr__(self):
return 'EEWeatherWarning(qualified_name={})'.format(self.qualified_name)

def json(self):
''' Return a JSON-serializable representation of this result.

The output of this function can be converted to a serialized string
with :any:`json.dumps`.
'''
return {
'qualified_name': self.qualified_name,
'description': self.description,
'data': self.data,
}
87 changes: 75 additions & 12 deletions scripts/tutorial.ipynb

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions tests/test_ranking.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,24 @@ def test_select_station_with_empty_tempC(
min_fraction_coverage=0.8
)
assert station.usaf_id == '747020'


def test_select_station_distance_warnings_check(lat_long_africa):
lat, lng = lat_long_africa
df = rank_stations(lat, lng)
station, warnings = select_station(df)
assert len(warnings) == 2
assert warnings[0].qualified_name == 'eeweather.exceeds_maximum_distance'
assert warnings[1].qualified_name == 'eeweather.exceeds_maximum_distance'
assert warnings[0].data['max_distance_meters'] == 50000
assert warnings[1].data['max_distance_meters'] == 200000


def test_select_station_no_station_warnings_check():
df = pd.DataFrame()
station, warnings = select_station(df)
assert warnings[0].qualified_name == 'eeweather.no_weather_station_selected'
assert warnings[0].data == {
'rank': 1,
'min_fraction_coverage': 0.9
}
26 changes: 26 additions & 0 deletions tests/test_warnings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pytest

from eeweather.warnings import EEWeatherWarning


@pytest.fixture
def generic_eeweather_warning():
return EEWeatherWarning(
qualified_name='qualified_name',
description='description',
data={}
)


def test_str_repr(generic_eeweather_warning):
assert str(generic_eeweather_warning) == (
'EEWeatherWarning(qualified_name=qualified_name)'
)


def test_json_repr(generic_eeweather_warning):
assert generic_eeweather_warning.json() == {
'qualified_name': 'qualified_name',
'description': 'description',
'data': {},
}