Skip to content

Commit

Permalink
closes #67; Modify Month/Season enums to take string values instead o…
Browse files Browse the repository at this point in the history
…f integers
  • Loading branch information
paul-florentin-charles committed Aug 15, 2024
1 parent d457950 commit 4a2e81b
Show file tree
Hide file tree
Showing 16 changed files with 171 additions and 145 deletions.
12 changes: 6 additions & 6 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def average_rainfall() -> Response:
),
"begin_year": params[1],
"end_year": params[2] or all_rainfall.get_last_year(),
"time_mode": TimeMode[params[0]],
"time_mode": TimeMode(params[0]),
}
)

Expand All @@ -100,7 +100,7 @@ def normal_rainfall() -> Response:
"value": all_rainfall.get_normal(*params),
"begin_year": params[1],
"end_year": params[1] + 29,
"time_mode": TimeMode[params[0]],
"time_mode": TimeMode(params[0]),
}
)

Expand Down Expand Up @@ -133,7 +133,7 @@ def rainfall_relative_distance_to_normal() -> Response:
"normal_year": params[1],
"begin_year": params[2],
"end_year": params[3] or all_rainfall.get_last_year(),
"time_mode": TimeMode[params[0]],
"time_mode": TimeMode(params[0]),
}
)

Expand Down Expand Up @@ -164,7 +164,7 @@ def rainfall_standard_deviation() -> Response:
"value": all_rainfall.get_rainfall_standard_deviation(*params),
"begin_year": params[1],
"end_year": params[2] or all_rainfall.get_last_year(),
"time_mode": TimeMode[params[0]],
"time_mode": TimeMode(params[0]),
}
)

Expand Down Expand Up @@ -197,7 +197,7 @@ def years_below_normal() -> Response:
"normal_year": params[1],
"begin_year": params[2],
"end_year": params[3] or all_rainfall.get_last_year(),
"time_mode": TimeMode[params[0]],
"time_mode": TimeMode(params[0]),
}
)

Expand Down Expand Up @@ -230,7 +230,7 @@ def years_above_normal() -> Response:
"normal_year": params[1],
"begin_year": params[2],
"end_year": params[3] or all_rainfall.get_last_year(),
"time_mode": TimeMode[params[0]],
"time_mode": TimeMode(params[0]),
}
)

Expand Down
8 changes: 4 additions & 4 deletions src/api/swagger/parameters_specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
}

time_mode: dict[str, Any] = {
"default": TimeMode.YEARLY.name,
"default": TimeMode.YEARLY.value,
"required": True,
"type": "string",
"enum": TimeMode.names(),
"enum": TimeMode.values(),
"name": "time_mode",
"in": "query",
}
Expand All @@ -44,7 +44,7 @@
"default": None,
"required": False,
"type": "string",
"enum": Month.names(),
"enum": Month.values(),
"name": "month",
"in": "query",
}
Expand All @@ -53,7 +53,7 @@
"default": None,
"required": False,
"type": "string",
"enum": Season.names(),
"enum": Season.values(),
"name": "season",
"in": "query",
}
Expand Down
16 changes: 8 additions & 8 deletions src/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,24 @@ def return_time_mode_error_or_fill_response_dict(
If time mode is set to seasonal and season is None.
:param response_dict: Dict where to store response fields.
:param time_mode: A string setting the time period ['YEARLY', 'MONTHLY', 'SEASONAL']
:param time_mode: A string setting the time period ['yearly', 'monthly', 'seasonal'].
:param month: A string corresponding to the month name.
Set if time_mode is 'MONTHLY' (optional)
Set if time_mode is 'monthly' (optional).
:param season: A string corresponding to the season name.
Possible values are within ['WINTER', 'SPRING', 'SUMMER', 'FALL'].
Set if time_mode is 'SEASONAL' (optional)
Possible values are within ['winter', 'spring', 'summer', 'fall'].
Set if time_mode is 'seasonal' (optional).
:return: Either a Flask Response if there is an error or None.
"""
if time_mode == TimeMode.MONTHLY.name:
if time_mode == TimeMode.MONTHLY.value:
if month is None:
return bad_request("Month cannot be null.")

response_dict["month"] = Month[month]
response_dict["month"] = Month(month)

if time_mode == TimeMode.SEASONAL.name:
if time_mode == TimeMode.SEASONAL.value:
if season is None:
return bad_request("Season cannot be null.")

response_dict["season"] = Season[season]
response_dict["season"] = Season(season)

return None
80 changes: 40 additions & 40 deletions src/core/models/all_rainfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ def __init__(
self.raw_data, start_year, round_precision
)
self.monthly_rainfalls = {
month.name: MonthlyRainfall(
month.value: MonthlyRainfall(
self.raw_data, month, start_year, round_precision
)
for month in Month
}
self.seasonal_rainfalls = {
season.name: SeasonalRainfall(
season.value: SeasonalRainfall(
self.raw_data, season, start_year, round_precision
)
for season in Season
Expand Down Expand Up @@ -101,12 +101,12 @@ def export_as_csv(
Export the data state of a specific time mode as a CSV.
Could be for a yearly time frame, a specific month or a given season.
:param time_mode: A string setting the time period ['YEARLY', 'MONTHLY', 'SEASONAL']
:param time_mode: A string setting the time period ['yearly', 'monthly', 'seasonal'].
:param month: A string corresponding to the month name.
Set if time_mode is 'MONTHLY' (optional)
Set if time_mode is 'monthly' (optional).
:param season: A string corresponding to the season name.
Possible values are within ['WINTER', 'SPRING', 'SUMMER', 'FALL'].
Set if time_mode is 'SEASONAL' (optional)
Possible values are within ['winter', 'spring', 'summer', 'fall'].
Set if time_mode is 'seasonal' (optional).
:param path: path to csv file to save our data (optional).
:return: CSV data as a string if no path is set.
None otherwise.
Expand All @@ -130,16 +130,16 @@ def get_average_rainfall(
"""
Computes Rainfall average for a specific year range and time mode.
:param time_mode: A string setting the time period ['YEARLY', 'MONTHLY', 'SEASONAL']
:param time_mode: A string setting the time period ['yearly', 'monthly', 'seasonal'].
:param begin_year: An integer representing the year
to start getting our rainfall values.
:param end_year: An integer representing the year
to end getting our rainfall values (optional).
:param month: A string corresponding to the month name.
Set if time_mode is 'MONTHLY' (optional)
Set if time_mode is 'monthly' (optional).
:param season: A string corresponding to the season name.
Possible values are within ['WINTER', 'SPRING', 'SUMMER', 'FALL'].
Set if time_mode is 'SEASONAL' (optional)
Possible values are within ['winter', 'spring', 'summer', 'fall'].
Set if time_mode is 'seasonal' (optional).
:return: A float representing the average Rainfall.
"""
entity = self.get_entity_for_time_mode(time_mode, month, season)
Expand All @@ -159,14 +159,14 @@ def get_normal(
"""
Computes Rainfall normal from a specific year and time mode.
:param time_mode: A string setting the time period ['YEARLY', 'MONTHLY', 'SEASONAL']
:param time_mode: A string setting the time period ['yearly', 'monthly', 'seasonal'].
:param begin_year: An integer representing the year
to start computing rainfall normal.
:param month: A string corresponding to the month name.
Set if time_mode is 'MONTHLY' (optional)
Set if time_mode is 'monthly' (optional).
:param season: A string corresponding to the season name.
Possible values are within ['WINTER', 'SPRING', 'SUMMER', 'FALL'].
Set if time_mode is 'SEASONAL' (optional)
Possible values are within ['winter', 'spring', 'summer', 'fall'].
Set if time_mode is 'seasonal' (optional).
:return: A float representing the Rainfall normal.
"""

Expand All @@ -189,18 +189,18 @@ def get_relative_distance_from_normal(
"""
Computes relative distance to Rainfall normal for a specific year range and time mode.
:param time_mode: A string setting the time period ['YEARLY', 'MONTHLY', 'SEASONAL']
:param time_mode: A string setting the time period ['yearly', 'monthly', 'seasonal'].
:param normal_year: An integer representing the year
to start computing the 30 years normal of the rainfall.
:param begin_year: An integer representing the year
to start getting our rainfall values.
:param end_year: An integer representing the year
to end getting our rainfall values (optional).
:param month: A string corresponding to the month name.
Set if time_mode is 'MONTHLY' (optional)
Set if time_mode is 'monthly' (optional).
:param season: A string corresponding to the season name.
Possible values are within ['WINTER', 'SPRING', 'SUMMER', 'FALL'].
Set if time_mode is 'SEASONAL' (optional)
Possible values are within ['winter', 'spring', 'summer', 'fall'].
Set if time_mode is 'seasonal' (optional).
:return: A float representing the relative distance to rainfall normal.
"""
entity = self.get_entity_for_time_mode(time_mode, month, season)
Expand All @@ -225,16 +225,16 @@ def get_rainfall_standard_deviation(
for a specific year range and time mode.
By default, it uses the 'Rainfall' column.
:param time_mode: A string setting the time period ['YEARLY', 'MONTHLY', 'SEASONAL']
:param time_mode: A string setting the time period ['yearly', 'monthly', 'seasonal'].
:param begin_year: An integer representing the year
to start getting our rainfall values (optional).
:param end_year: An integer representing the year
to end getting our rainfall values (optional).
:param month: A string corresponding to the month name.
Set if time_mode is 'MONTHLY' (optional)
Set if time_mode is 'monthly' (optional).
:param season: A string corresponding to the season name.
Possible values are within ['WINTER', 'SPRING', 'SUMMER', 'FALL'].
Set if time_mode is 'SEASONAL' (optional)
Possible values are within ['winter', 'spring', 'summer', 'fall'].
Set if time_mode is 'seasonal' (optional).
:return: The standard deviation as a float.
Nothing if the specified column does not exist.
"""
Expand All @@ -257,18 +257,18 @@ def get_years_below_normal(
"""
Computes the number of years below rainfall normal for a specific year range and time mode.
:param time_mode: A string setting the time period ['YEARLY', 'MONTHLY', 'SEASONAL']
:param time_mode: A string setting the time period ['yearly', 'monthly', 'seasonal'].
:param normal_year: An integer representing the year
to start computing the 30 years normal of the rainfall.
:param begin_year: An integer representing the year
to start getting our rainfall values.
:param end_year: An integer representing the year
to end getting our rainfall values (optional).
:param month: A string corresponding to the month name.
Set if time_mode is 'MONTHLY' (optional)
Set if time_mode is 'monthly' (optional).
:param season: A string corresponding to the season name.
Possible values are within ['WINTER', 'SPRING', 'SUMMER', 'FALL'].
Set if time_mode is 'SEASONAL' (optional)
Possible values are within ['winter', 'spring', 'summer', 'fall'].
Set if time_mode is 'seasonal' (optional).
:return: A float representing the relative distance to rainfall normal.
"""
entity = self.get_entity_for_time_mode(time_mode, month, season)
Expand All @@ -290,18 +290,18 @@ def get_years_above_normal(
"""
Computes the number of years above rainfall normal for a specific year range and time mode.
:param time_mode: A string setting the time period ['YEARLY', 'MONTHLY', 'SEASONAL']
:param time_mode: A string setting the time period ['yearly', 'monthly', 'seasonal'].
:param normal_year: An integer representing the year
to start computing the 30 years normal of the rainfall.
:param begin_year: An integer representing the year
to start getting our rainfall values.
:param end_year: An integer representing the year
to end getting our rainfall values (optional).
:param month: A string corresponding to the month name.
Set if time_mode is 'MONTHLY' (optional)
Set if time_mode is 'monthly' (optional).
:param season: A string corresponding to the season name.
Possible values are within ['WINTER', 'SPRING', 'SUMMER', 'FALL'].
Set if time_mode is 'SEASONAL' (optional)
Possible values are within ['winter', 'spring', 'summer', 'fall'].
Set if time_mode is 'seasonal' (optional).
:return: A float representing the relative distance to rainfall normal.
"""
entity = self.get_entity_for_time_mode(time_mode, month, season)
Expand Down Expand Up @@ -338,7 +338,7 @@ def bar_rainfall_averages(
If False, plots seasonal rainfall averages. Defaults to True (optional).
:return: A list of the Rainfall averages for each month or season.
"""
label = f"Average rainfall (mm) between {begin_year or self.starting_year} and {self.get_last_year()}"
label = f"Average rainfall (mm) between {begin_year or self.starting_year} and {end_year or self.get_last_year()}"
if monthly:
return plotting.bar_monthly_rainfall_averages(
list(self.monthly_rainfalls.values()),
Expand Down Expand Up @@ -379,23 +379,23 @@ def get_entity_for_time_mode(
amongst instances of YearlyRainfall, MonthlyRainfall or SeasonsalRainfall.
Month or Season should be specified according to time mode.
:param time_mode: A string setting the time period ['YEARLY', 'MONTHLY', 'SEASONAL']
:param time_mode: A string setting the time period ['yearly', 'monthly', 'seasonal'].
:param month: A string corresponding to the month name.
Set if time_mode is 'MONTHLY' (optional)
Set if time_mode is 'monthly' (optional).
:param season: A string corresponding to the season name.
Possible values are within ['WINTER', 'SPRING', 'SUMMER', 'FALL'].
Set if time_mode is 'SEASONAL' (optional)
Possible values are within ['winter', 'spring', 'summer', 'fall'].
Set if time_mode is 'seasonal' (optional).
:return: Corresponding entity as a class instance.
None if time mode is unknown, time mode is 'MONTHLY' and month is None
or time mode is 'SEASONAL' and season is None.
None if time mode is unknown, time mode is 'monthly' and month is None
or time mode is 'seasonal' and season is None.
"""
entity: YearlyRainfall | MonthlyRainfall | SeasonalRainfall | None = None

if time_mode.casefold() == TimeMode.YEARLY:
if time_mode.casefold() == TimeMode.YEARLY.value:
entity = self.yearly_rainfall
elif time_mode.casefold() == TimeMode.MONTHLY and month:
elif time_mode.casefold() == TimeMode.MONTHLY.value and month:
entity = self.monthly_rainfalls[month]
elif time_mode.casefold() == TimeMode.SEASONAL and season:
elif time_mode.casefold() == TimeMode.SEASONAL.value and season:
entity = self.seasonal_rainfalls[season]

return entity
2 changes: 1 addition & 1 deletion src/core/models/monthly_rainfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ def load_yearly_rainfall(self) -> pd.DataFrame:
for instance month according to year.
"""

return self.load_rainfall(self.month.value, self.month.value + 1)
return self.load_rainfall(self.month)
3 changes: 2 additions & 1 deletion src/core/models/seasonal_rainfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ def load_yearly_rainfall(self) -> pd.DataFrame:
"""

return self.load_rainfall(
self.season.value[0].value, self.season.value[2].value + 1
self.season.get_months()[0],
self.season.get_months()[-1],
)
18 changes: 10 additions & 8 deletions src/core/models/yearly_rainfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,25 @@ def load_yearly_rainfall(self) -> pd.DataFrame:
:return: A pandas DataFrame displaying rainfall data (in mm) according to year.
"""

return self.load_rainfall(Month.JANUARY.value)
return self.load_rainfall(Month.JANUARY, Month.DECEMBER)

def load_rainfall(
self, start_month: int, end_month: int | None = None
self, start_month: Month, end_month: Month | None = None
) -> pd.DataFrame:
"""
Generic function to load Yearly Rainfall data from raw data stored in pandas DataFrame.
Raw data has to be shaped as rainfall values for each month according to year.
:param start_month: An integer representing the month
to start getting our rainfall values (compulsory)
:param end_month: An integer representing the month
to end getting our rainfall values (optional)
:param start_month: A Month Enum representing the month
to start getting our rainfall values.
:param end_month: A Month Enum representing the month
to end getting our rainfall values (optional).
If not given, we load rainfall data only for given start_month.
:return: A pandas DataFrame displaying rainfall data (in mm) according to year.
:raise DataFormatError: If raw_data attribute of instance doesn't have exactly 13 columns.
1 for the year; 12 for every monthly rainfall.
"""

if not isinstance(self.raw_data, pd.DataFrame) or len(
self.raw_data.columns
) != 1 + len(Month):
Expand All @@ -75,8 +77,8 @@ def load_rainfall(
self.raw_data,
self.starting_year,
self.round_precision,
start_month,
end_month,
start_month.get_rank(),
end_month.get_rank() if end_month else None,
)

def get_yearly_rainfall(
Expand Down
Loading

0 comments on commit 4a2e81b

Please sign in to comment.