Skip to content

Commit 95c239f

Browse files
authored
Merge pull request #37 from cyiallou/fix/flake8-fixes
Fix flake8 issues
2 parents 4f7ca89 + 0865331 commit 95c239f

File tree

6 files changed

+57
-23
lines changed

6 files changed

+57
-23
lines changed

src/frequenz/lib/notebooks/solar/maintenance/data_fetch.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ def _handle_outliers(
380380
381381
Returns:
382382
The reporting data after outlier detection and replacement.
383+
384+
Raises:
385+
TypeError: If the bounds, method, or method_params are not of the
386+
expected type.
383387
"""
384388
message_1 = (
385389
"Columns that denote power values (will use these for outlier detection): "
@@ -393,10 +397,12 @@ def _handle_outliers(
393397
bounds = params.get("bounds", (0.0, 0.0))
394398
method = params.get("method", "")
395399
method_params = params.get("params", {})
396-
# sanity checks
397-
assert isinstance(bounds, tuple)
398-
assert isinstance(method, str)
399-
assert isinstance(method_params, dict)
400+
if not isinstance(bounds, tuple):
401+
raise TypeError("bounds must be a tuple")
402+
if not isinstance(method, str):
403+
raise TypeError("method must be a string")
404+
if not isinstance(method_params, dict):
405+
raise TypeError("method_params must be a dictionary")
400406
data = outlier_removal(
401407
data=data,
402408
columns=power_column_labels,

src/frequenz/lib/notebooks/solar/maintenance/data_processing.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,13 @@ def parse_unit(unit_str: str) -> tuple[float, str]:
135135
time_diff_seconds_series = time_diff_seconds_arr[
136136
time_diff_seconds_arr.notna() & (time_diff_seconds_arr != 0)
137137
]
138-
try:
139-
assert (
140-
time_diff_seconds_series.nunique() == 1
141-
), "Time differences are not constant. Taking the most frequent value."
138+
if time_diff_seconds_series.nunique() == 1:
142139
time_diff_seconds = time_diff_seconds_series.values[0]
143-
except AssertionError:
140+
else:
141+
warnings.warn(
142+
"Detected multiple unique time differences; this may indicate inconsistent "
143+
"timestamps. Falling back to the mode of the time differences."
144+
)
144145
time_diff_seconds = time_diff_seconds_series.mode()[0]
145146
for unit in energy_units:
146147
energy_factor, base_unit = parse_unit(unit)

src/frequenz/lib/notebooks/solar/maintenance/models.py

+14-6
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ def sampled_moving_average(
250250
prediction (i.e. the moving average) corresponding to the ground truth
251251
does not include the ground truth itself. This can be achieved by
252252
shifting the Series by sampling_interval.
253+
254+
Raises:
255+
TypeError: If the output is not a pandas Series.
253256
"""
254257
sampling_interval = abs(int(sampling_interval))
255258
data_index = pd.to_datetime(data.index).to_series()
@@ -270,7 +273,8 @@ def sampled_moving_average(
270273
).apply(lambda x: x[::sampling_interval].mean(), raw=True)
271274
if isinstance(predictions, pd.DataFrame):
272275
predictions = predictions.squeeze()
273-
assert isinstance(predictions, pd.Series) # for type checker
276+
if not isinstance(predictions, pd.Series):
277+
raise TypeError("Output is not a pandas Series.")
274278
predictions.name = "predictions"
275279
return predictions
276280

@@ -303,7 +307,8 @@ def naive_efficiency_factor_irr_to_power( # pylint: disable=too-many-arguments
303307
A pandas Series containing the predicted power (in kilo-Watts) output.
304308
305309
Raises:
306-
ValueError: If the input dataframe contains duplicate index entries.
310+
ValueError: If the input dataframe contains duplicate index entries or
311+
if the validity_ts is not unique.
307312
"""
308313
data_copy = data.copy(deep=True)
309314
data_copy.sort_values(by=["creation_ts", "validity_ts"], inplace=True)
@@ -319,9 +324,8 @@ def naive_efficiency_factor_irr_to_power( # pylint: disable=too-many-arguments
319324
to_include.loc[to_include.index[position + 1 :]] = True
320325
data_copy = data_copy[to_include]
321326

322-
assert (
323-
data_copy.validity_ts.nunique() == data_copy.validity_ts.count()
324-
), "validity_ts is not unique"
327+
if data_copy.validity_ts.nunique() != data_copy.validity_ts.count():
328+
raise ValueError("validity_ts is not unique")
325329
data_copy.set_index("validity_ts", inplace=True)
326330
data_copy.index.name = "timestamp"
327331
if resample_rate:
@@ -450,6 +454,9 @@ def _get_pvgis_hourly(
450454
Returns:
451455
A pandas DataFrame containing the hourly data.
452456
457+
Raises:
458+
ValueError: If the minute values in the index are not unique.
459+
453460
References:
454461
- https://pvlib-python.readthedocs.io/en/stable/reference/generated/
455462
pvlib.iotools.get_pvgis_hourly.html
@@ -462,7 +469,8 @@ def _get_pvgis_hourly(
462469
raddatabase="PVGIS-SARAH2",
463470
url="https://re.jrc.ec.europa.eu/api/v5_2/",
464471
)
465-
assert pvgis_df.index.minute.nunique() == 1 # sanity check
472+
if pvgis_df.index.minute.nunique() != 1:
473+
raise ValueError("Minute values in the index are not unique.")
466474
pvgis_df.index = pvgis_df.index - pd.Timedelta(
467475
minutes=pvgis_df.index.minute.unique()[0]
468476
)

src/frequenz/lib/notebooks/solar/maintenance/plot_manager.py

+18-6
Original file line numberDiff line numberDiff line change
@@ -562,13 +562,19 @@ def _update_axes_legends(
562562
axs: List of matplotlib Axes objects.
563563
modifications: A dictionary containing modifications.
564564
**legend_kwargs: Additional keyword arguments for the legend function.
565+
566+
Raises:
567+
TypeError: If the inputs are invalid.
565568
"""
566569
additional_items, remove_label, replace_label = self._get_modifications(
567570
modifications
568571
)
569-
assert self._is_additional_items_type(additional_items)
570-
assert self._is_text_modification_type(remove_label)
571-
assert self._is_replace_label_type(replace_label)
572+
if not self._is_additional_items_type(additional_items):
573+
raise TypeError("additional_items must be of type AdditionalItemsType")
574+
if not self._is_text_modification_type(remove_label):
575+
raise TypeError("remove_label must be of type TextModificationType")
576+
if not self._is_replace_label_type(replace_label):
577+
raise TypeError("replace_label must be of type ReplaceLabelType")
572578

573579
for i, ax in enumerate(axs):
574580
handles, labels = ax.get_legend_handles_labels()
@@ -602,13 +608,19 @@ def _update_figure_legend(
602608
axs: List of matplotlib Axes objects.
603609
modifications: A dictionary containing modifications.
604610
**legend_kwargs: Additional keyword arguments for the legend function.
611+
612+
Raises:
613+
TypeError: If the inputs are invalid.
605614
"""
606615
additional_items, remove_label, replace_label = self._get_modifications(
607616
modifications
608617
)
609-
assert self._is_additional_items_type(additional_items)
610-
assert self._is_text_modification_type(remove_label)
611-
assert self._is_replace_label_type(replace_label)
618+
if not self._is_additional_items_type(additional_items):
619+
raise TypeError("additional_items must be of type AdditionalItemsType")
620+
if not self._is_text_modification_type(remove_label):
621+
raise TypeError("remove_label must be of type TextModificationType")
622+
if not self._is_replace_label_type(replace_label):
623+
raise TypeError("replace_label must be of type ReplaceLabelType")
612624

613625
all_handles, all_labels = [], []
614626
for ax in axs:

src/frequenz/lib/notebooks/solar/maintenance/solar_maintenance_app.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ async def run_workflow(
9090
This is not an issue in this version because the column labels
9191
(i.e. `short_term_view_col_to_plot` and
9292
`stat_profile_view_col_to_plot`) are hardcoded.
93+
- If the timezone of the data does not match the timezone in the
94+
configuration.
9395
"""
9496
config, all_client_site_info = _load_and_validate_config(user_config_changes)
9597

@@ -221,7 +223,8 @@ async def run_workflow(
221223
)
222224
normalisation_factor = 1
223225
timezone = str(pd.to_datetime(data.index).tzinfo)
224-
assert timezone == config.time_zone.key, "Timezone mismatch." # sanity check
226+
if timezone != config.time_zone.key:
227+
raise ValueError("Timezone mismatch.")
225228

226229
pv_system = None
227230
if "simulation" in config.baseline_models:

tests/test_config.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ def _assert_optional_field(value: float | None, expected: float) -> None:
160160
Args:
161161
value: The optional field value to check.
162162
expected: The expected value to assert if `value` is not None.
163+
164+
Raises:
165+
AssertionError: If `value` is not None and does not match `expected`.
163166
"""
164167
if value is not None:
165-
assert value == expected
168+
if value != expected:
169+
raise AssertionError(f"Expected {expected}, got {value}")

0 commit comments

Comments
 (0)