Skip to content

Fix model_dir NameError, optimize sunrise/sunset caching, replace assert with ValueError#3

Merged
bartzbeielstein merged 3 commits into
mainfrom
copilot/fix-nameerror-model-dir-scope
Feb 11, 2026
Merged

Fix model_dir NameError, optimize sunrise/sunset caching, replace assert with ValueError#3
bartzbeielstein merged 3 commits into
mainfrom
copilot/fix-nameerror-model-dir-scope

Conversation

Copilot AI commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

Addresses four code quality and correctness issues in n2n_predict_with_covariates.py.

Changes

  • Fix NameError when model_dir is None: Move model_dir = get_cache_home() / "forecasters" inside the if block where get_cache_home() is imported. Previously caused NameError due to scope issue.

  • Cache sunrise/sunset per unique date: Normalize extended_index to unique calendar dates and compute sun() once per date instead of per timestamp. Reduces redundant calculations by ~16-24x for hourly data.

# Before: O(n) sun() calls for n timestamps
sunrise_hour = [sun(..., date=date)["sunrise"] for date in extended_index]

# After: O(d) sun() calls for d unique dates
normalized_dates = extended_index.normalize()
unique_dates = normalized_dates.unique()
sunrise_map = {d: sun(..., date=d)["sunrise"] for d in unique_dates}
sunrise_series = pd.Series([sunrise_map[d] for d in normalized_dates], index=extended_index)
  • Replace assert with explicit ValueError: Change runtime validation from assert sum(...) == 0 to if missing_count != 0: raise ValueError(...). Assertions can be disabled with -O flag.

  • Split chained PolynomialFeatures call: Separate constructor and set_output() into two lines for readability.

Original prompt
Please apply the following diffs and create a pull request.
Once the PR is ready, give it a title based on the messages of the fixes being applied.

[{"message":"The model_dir assignment is outside the if block where get_cache_home() is imported. This will cause a NameError when model_dir is None because get_cache_home is not in scope.","fixFiles":[{"filePath":"src/spotforecast2_safe/processing/n2n_predict_with_covariates.py","diff":"diff --git a/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py b/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py\n--- a/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py\n+++ b/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py\n@@ -725,9 +725,8 @@\n     # Set default model_dir if not provided\n     if model_dir is None:\n         from spotforecast2_safe.data.fetch_data import get_cache_home\n+        model_dir = get_cache_home() / \"forecasters\"\n \n-    model_dir = get_cache_home() / \"forecasters\"\n-\n     # Input Validation\n     if forecast_horizon <= 0:\n         raise ValueError(f\"forecast_horizon must be positive, got {forecast_horizon}\")\n"}]},{"message":"Using a list comprehension to iterate over extended_index and call sun() for each date is inefficient. Consider vectorizing this operation or caching results for repeated dates.","fixFiles":[{"filePath":"src/spotforecast2_safe/processing/n2n_predict_with_covariates.py","diff":"diff --git a/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py b/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py\n--- a/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py\n+++ b/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py\n@@ -278,18 +278,30 @@\n \n     extended_index = pd.date_range(start=start, end=cov_end, freq=freq, tz=timezone)\n \n-    sunrise_hour = [\n-        sun(location.observer, date=date, tzinfo=location.timezone)[\"sunrise\"]\n-        for date in extended_index\n-    ]\n-    sunset_hour = [\n-        sun(location.observer, date=date, tzinfo=location.timezone)[\"sunset\"]\n-        for date in extended_index\n-    ]\n+    # Cache sunrise and sunset times per unique calendar date to avoid\n+    # recomputing them for every timestamp in the extended_index.\n+    normalized_dates = extended_index.normalize()\n+    unique_dates = normalized_dates.unique()\n \n-    sunrise_hour = pd.Series(sunrise_hour, index=extended_index).dt.round(\"h\").dt.hour\n-    sunset_hour = pd.Series(sunset_hour, index=extended_index).dt.round(\"h\").dt.hour\n+    sunrise_map = {}\n+    sunset_map = {}\n+    for d in unique_dates:\n+        s = sun(location.observer, date=d, tzinfo=location.timezone)\n+        sunrise_map[d] = s[\"sunrise\"]\n+        sunset_map[d] = s[\"sunset\"]\n \n+    sunrise_series = pd.Series(\n+        [sunrise_map[d] for d in normalized_dates],\n+        index=extended_index,\n+    )\n+    sunset_series = pd.Series(\n+        [sunset_map[d] for d in normalized_dates],\n+        index=extended_index,\n+    )\n+\n+    sunrise_hour = sunrise_series.dt.round(\"h\").dt.hour\n+    sunset_hour = sunset_series.dt.round(\"h\").dt.hour\n+\n     sun_light_features = pd.DataFrame(\n         {\n             \"sunrise_hour\": sunrise_hour,\n"}]},{"message":"Using a list comprehension to iterate over extended_index and call sun() for each date is inefficient. Consider vectorizing this operation or caching results for repeated dates.","fixFiles":[{"filePath":"src/spotforecast2_safe/processing/n2n_predict_with_covariates.py","diff":"diff --git a/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py b/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py\n--- a/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py\n+++ b/src/spotforecast2_safe/processing/n2n_predict_with_covariates.py\n@@ -278,24 +278,35 @@\n \n     extended_index = pd.date_range(start=start, end=cov_end, freq=freq, tz=timezone)\n \n-    sunrise_hour = [\n-        sun(location.observer, date=date, tzinfo=location.timezone)[\"sunrise\"]\n-        for date in extended_index\n-    ]\n-    sunset_hour = [\n-        sun(location.observer, date=date, tzinfo=location.timezone)[\"sunset\"]\n-        for date in extended_index\n-    ]\n+    # Compute sunrise and sunset once per unique date to avoid redundant calculations\n+    dates = extended_index.normalize()\n+    unique_dates = dates.unique()\n \n-    sunrise_hour = pd.Series(sunrise_hour, index=extended_index).dt.round(\"h\").dt.hour\n-    sunset_hour = pd.Series(sunset_hour, index=extended_index).dt.round(\"h\").dt.hour\n+    sunrise_by_date = {}\n+    sunset_by_date = {}\n+    for d in unique_dates:\n+        sun_times = sun(location.observer, date=d, tzinfo=location.timezone)\n+        sunrise_by_date[d] = sun_times[\"sunrise\"]\n+        sunset_by_date[d] = sun_times[\"sunset\"]\n \n-    sun_light_features = pd.DataFrame(\n+    # Build daily DataFrame with ...

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@codecov

codecov Bot commented Feb 11, 2026

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered ☂️

Copilot AI and others added 2 commits February 11, 2026 19:54
…ty improvements

Co-authored-by: bartzbeielstein <32470350+bartzbeielstein@users.noreply.github.com>
Co-authored-by: bartzbeielstein <32470350+bartzbeielstein@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix NameError in model_dir assignment scope Fix model_dir NameError, optimize sunrise/sunset caching, replace assert with ValueError Feb 11, 2026
@bartzbeielstein bartzbeielstein marked this pull request as ready for review February 11, 2026 20:01
@bartzbeielstein

Copy link
Copy Markdown
Collaborator

copilot ai

@bartzbeielstein bartzbeielstein merged commit 3663631 into main Feb 11, 2026
12 checks passed
@bartzbeielstein bartzbeielstein deleted the copilot/fix-nameerror-model-dir-scope branch February 11, 2026 22:37
bartzbeielstein added a commit that referenced this pull request Jun 8, 2026
…robabilistic-head

feat(forecaster): quantile-LightGBM probabilistic head factory (#3)
bartzbeielstein pushed a commit that referenced this pull request Jun 8, 2026
## [19.3.0-rc.2](v19.3.0-rc.1...v19.3.0-rc.2) (2026-06-08)

### Features

* **forecaster:** quantile-LightGBM probabilistic head factory ([d44093f](d44093f)), closes [#3](#3)
bartzbeielstein pushed a commit that referenced this pull request Jun 8, 2026
## [19.4.0-rc.1](v19.3.0...v19.4.0-rc.1) (2026-06-08)

### Features

* **configurator:** mirror new feature flags onto ConfigEntsoe (parity) ([a211271](a211271))
* **forecaster:** quantile-LightGBM probabilistic head factory ([d44093f](d44093f)), closes [#3](#3)
bartzbeielstein pushed a commit that referenced this pull request Jun 8, 2026
## [19.4.0](v19.3.0...v19.4.0) (2026-06-08)

### Features

* **configurator:** mirror new feature flags onto ConfigEntsoe (parity) ([a211271](a211271))
* **forecaster:** quantile-LightGBM probabilistic head factory ([d44093f](d44093f)), closes [#3](#3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants