Skip to content

chore: dead code and unused function audit and removal#41

Merged
pbulsink merged 6 commits into
masterfrom
copilot/identify-unused-functions
May 5, 2026
Merged

chore: dead code and unused function audit and removal#41
pbulsink merged 6 commits into
masterfrom
copilot/identify-unused-functions

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 4, 2026

Removes unused/dead code across the HockeyModel package based on a thorough audit.

Changes Made

Removed functions and files

  • R/dc_iterative.R — entire iterative Dixon–Coles implementation removed (no production callers); associated exports, datasets (iterativeParameters, iterativeRankings), documentation, tests, and VCR cassette also removed. tictoc dropped from Suggests in DESCRIPTION.
  • R/utils.R: removed gId(), is_valid_gameId(), and mutate_cond() (superseded or unused in production)
  • R/dixon-coles.R: removed DCweights_old() (fully replaced by DCweights())
  • R/api-interface.R: removed updateScoresAPI_byGameID() and validateWins() (never called)
  • R/api-output.R: removed stub plumber routes (/cup-odds, /pace-graphic, /points-distribution) that always returned NULL

Dead code cleaned up

  • Removed 16 commented-out rtoot::post_toot() call sites throughout R/main.R (replaced by atrrr::post() but left as comments)
  • Removed ~186 lines of commented-out old playoff-seeding logic in R/league.R (lines 1724–1910)
  • Removed wasted metric computations in optimizeIterative_WL_Internal() and optimizeIterative_XG_Internal() in R/dc_iterative.R

Bug fix: robust prediction file discovery

  • Added get_prediction_dates(dir) internal helper in R/utils.R that filters list.files() output to only YYYY-MM-DD-predictions.RDS files via regex, validates the directory exists, and strips any NA dates from malformed filenames
  • Replaced the fragile pdates[pdates != "graphics"] pattern at all five call sites: compile_predictions(), simulatePlayoffs(), updatePredictions(), tweetPace(), plot_pace_by_team()
  • simulatePlayoffs() now emits an informative cli_alert_info() message (instead of silently returning NULL) when prediction files are missing or stale

Other

  • simulatePlayoffs() returns invisible(NULL) (with a message) when the most recent prediction is more than 7 days old
  • tweetPlayoffOdds() guards against a NULL result from simulatePlayoffs() with a properly formatted early return

Notes

Some functions listed in the original audit (historicalPoints(), formatPredsForHockeyVisContest(), buildTeamColours(), buildPWHLTeamColours(), load_or_get_nst()) were retained as they are called periodically during development.

@pbulsink
Copy link
Copy Markdown
Owner

pbulsink commented May 4, 2026

Dead Code & Unused Function Audit

This document lists functions that are never called (or only called from tests),
and dead/unreachable code blocks across the R package.
Use it as a review checklist — tick off each item once you have verified and removed it.


R/utils.R

Unused functions

  • gId() / is_valid_gameId() (lines 577–588) — @keywords internal helpers
    superseded by the exported gameIDValidator(). Neither is called anywhere in the
    package. is_valid_gameId is just Vectorize(gId), and gameIDValidator already
    handles vectorised input.

  • historicalPoints() (line 44) — called only from
    tests/testthat/test-utils.R. No production code uses it.

  • formatPredsForHockeyVisContest() (line 245) — called only from
    tests/testthat/test-utils.R. No production code uses it.

  • mutate_cond() (line 74) — exported (@export) but never called from
    any production code in R/. Only exercised in tests/testthat/test-utils.R.
    Either add real usage, remove the export, or drop it entirely.


R/dixon-coles.R

Unused functions

  • DCweights_old() (line 1038) — old DCweights implementation, fully
    replaced by the current DCweights(). Never called anywhere. Safe to delete.

R/dc_iterative.R

Unused functions

  • saveIterativePredictions() (line 631) — @keywords internal, never
    called anywhere. Saves iterative predictions to disk, but nothing in the package
    invokes it.

  • readIterativePredictions() (line 655) — @keywords internal, never
    called anywhere. Paired with saveIterativePredictions(); both are dead.

  • iterativeDailyUpdate() (line 842) — @keywords internal, never
    called anywhere. Intended to orchestrate the iterative model update pipeline, but
    getIterativeTable() is the actual entry point used everywhere.

  • iterativeOddsTable() (line 861) — called only from
    tests/testthat/test-dc_iterative.R. No production code uses it.

Dead code in active functions

  • Wasted computation in optimizeIterative_WL_Internal() (line 502) —
    acc and rocauc are computed but the function always returns only ll:
    return(list(ll, acc, rocauc)[1]). The extra metric calculations are dead work.

  • Wasted computation in optimizeIterative_XG_Internal() (line 559) —
    r2 and mse are computed but the function always returns only rmse:
    return(list(rmse, r2, mse)[1]). Same pattern.


R/api-interface.R

Unused functions

  • updateScoresAPI_byGameID() (line 437) — @keywords internal, never
    called. updateScoresAPI() handles all score updates without this helper.

  • validateWins() (line 759) — defined but never called. Parses playoff
    series status strings, but getAPISeries() (the only natural caller) never
    invokes it.

Developer-local hardcoded path (not strictly dead, but broken on any other machine)

  • load_or_get_nst() (line 292) — uses a hardcoded ~/Documents/natstattrick.csv
    path and system2("grep", ...). Called by get_xg() (line 346). Will silently
    fail on any machine other than the original developer's. Needs either a proper data
    injection approach or removal if xG via NST is no longer supported.

R/api-output.R

Stub plumber routes that always return NULL

  • /cup-odds (lines 47–52) — route body is NULL. Either implement or remove.

  • /pace-graphic (lines 62–67) — route body is NULL. Either implement or remove.

  • /points-distribution (lines 69–75) — route body is NULL. Either implement or remove.


R/data.R

Unused functions

  • buildTeamColours() (line 239) — @keywords internal, never called from
    any package code. Developer utility to regenerate the teamColours data object.
    If it is still needed for data-raw workflows, move it to data-raw/; otherwise remove.

R/pwhl-api-interface.R

Unused functions

  • buildPWHLTeamColours() (line 520) — @keywords internal, never called.
    Same pattern as buildTeamColours() above. Move to data-raw/ or remove.

R/main.R

Commented-out dead code (rtoot calls)

The rtoot::post_toot() calls throughout the social-media posting functions have
been replaced by atrrr::post() but the old calls were left in as comments rather
than deleted. Sixteen instances spread across:

  • Lines 148, 172, 196 — inside tweet()
  • Line 285, 302, 334 — inside tweetPace() / tweetLikelihoods()
  • Line 563, 595 — inside tweetGames() or equivalent
  • Line 613 — tweet helper
  • Line 670 — inside series-tweet helper
  • Line 762, 807 — inside tweetPlayoffOdds() area
  • Line 864 — another tweet function
  • Lines 948, 990, 995 — end of file tweet functions

R/league.R

Large commented-out old playoff seeding logic

  • Lines 1724–1910 — ~186 lines of fully commented-out if/else if/else
    blocks using the old completedSeries/currentSeries seeding approach.
    The live code immediately above these comments uses the new single_series_solver()
    approach. This dead block is pure comment noise and can be removed.

Summary counts

Category Count
Functions never called in production 10
Functions called only from tests 4
Dead/wasted computation blocks 2
Unimplemented stub API routes 3
Commented-out rtoot call sites 16
Commented-out old seeding logic (lines) ~186

@pbulsink
Copy link
Copy Markdown
Owner

pbulsink commented May 4, 2026

@copilot could I completely remove the R/dc_iterative.R file without messing up any of the function calls from R/main.R?

If I remove the R/api-output.R file as I don't use plumber interaction, what else can I remove (i.e. in DESCRIPTION) to clean up the package code?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 4, 2026

@copilot could I completely remove the R/dc_iterative.R file without messing up any of the function calls from R/main.R?

If I remove the R/api-output.R file as I don't use plumber interaction, what...

Removing R/dc_iterative.R

Yes, you can safely remove the entire file. No production code in any other R file calls its functions — I searched all of R/main.R, R/league.R, R/graphics.R, R/pwhl-model.R, and the rest. The three exported symbols (iterativeGamePredict, getIterativeTable, getReplacementIterativeParameters) are only exercised in tests, never in the application code.

To do a clean removal you'd also want to:

  • Delete tests/testthat/test-dc_iterative.R (and its VCR cassette tests/testthat/_vcr/iterative.yml if it exists)
  • Remove the iterativeParameters and iterativeRankings dataset docs from R/data.R (lines ~204–215) and their corresponding .rda files in data/
  • Run devtools::document() to regenerate NAMESPACE (the three exports will disappear automatically)
  • tictoc is used only in dc_iterative.R; once the file is gone you can drop tictoc from Suggests: in DESCRIPTION

Removing R/api-output.R

You can delete that file with no ripple effects — nothing in the package sources or imports it, and plumber is already absent from DESCRIPTION entirely (it was never added as a dependency). So no DESCRIPTION changes are needed for this removal. The functions it delegates to (todayDC, daily_odds_table, playoffOdds, etc.) will continue to exist in their own files; only the plumber routing layer disappears.

@pbulsink pbulsink marked this pull request as ready for review May 5, 2026 00:11
Copilot AI review requested due to automatic review settings May 5, 2026 00:11
@pbulsink
Copy link
Copy Markdown
Owner

pbulsink commented May 5, 2026

Some items were not removed as they're called periodically in dev

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes unused/dead code across the HockeyModel package, including dropping the (apparently unused) iterative Dixon–Coles implementation and cleaning out related exports, docs, tests, and legacy/commented-out sections. It also introduces new behavior around skipping playoff simulation when prediction files are “stale”.

Changes:

  • Removed iterative-model implementation (R/dc_iterative.R), its exported functions, datasets, documentation, and tests/VCR cassette.
  • Removed additional unused/internal helpers (e.g., mutate_cond, validateWins, updateScoresAPI_byGameID, DCweights_old) plus their docs/tests.
  • Cleaned up legacy/commented-out posting logic and added early-return handling when simulatePlayoffs() yields NULL.

Reviewed changes

Copilot reviewed 39 out of 41 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
DESCRIPTION Removes tictoc from Suggests.
NAMESPACE Removes exports for iterative-model and other deleted helpers.
R/api-interface.R Deletes unused internal helpers (updateScoresAPI_byGameID(), validateWins()).
R/api-output.R Removes unused/unimplemented plumber route stubs.
R/data.R Removes documentation entries for iterative datasets.
R/dc_iterative.R Deletes the iterative Dixon–Coles implementation entirely.
R/dixon-coles.R Removes deprecated internal weighting helper DCweights_old().
R/league.R Adds staleness gating/early return when loading predictions implicitly in simulatePlayoffs().
R/main.R Removes commented-out rtoot calls; adds NULL guard for tweetPlayoffOdds() when simulatePlayoffs() returns NULL.
R/utils.R Removes mutate_cond() and gameId validator helpers (gId(), is_valid_gameId).
tests/testthat/_vcr/iterative.yml Removes VCR cassette for iterative tests.
tests/testthat/test-dc_iterative.R Removes iterative-model test coverage.
tests/testthat/test-utils.R Removes tests for mutate_cond() (function also removed).
man/DCweights_old.Rd Removes documentation for deleted internal helper.
man/gId.Rd Removes documentation for deleted internal helper.
man/getIterativePredictions.Rd Removes documentation for deleted iterative helper.
man/getIterativeTable.Rd Removes documentation for deleted exported function.
man/getNewIterativeRankings.Rd Removes documentation for deleted internal helper.
man/getReplacementIterativeParameters.Rd Removes documentation for deleted exported function.
man/getReplacementRankings.Rd Removes documentation for deleted exported function.
man/getTeamRankings.Rd Removes documentation for deleted iterative helper.
man/iterateGame.Rd Removes documentation for deleted iterative helper.
man/iterateSeason.Rd Removes documentation for deleted iterative helper.
man/iterativeDailyUpdate.Rd Removes documentation for deleted iterative helper.
man/iterativeGamePredict.Rd Removes documentation for deleted exported function.
man/iterativeOddsTable.Rd Removes documentation for deleted iterative helper.
man/iterativeParameters.Rd Removes documentation for removed dataset.
man/iterativeRankings.Rd Removes documentation for removed dataset.
man/iterative_season_progress.Rd Removes documentation for deleted iterative helper.
man/mutate_cond.Rd Removes documentation for deleted exported function.
man/optimizeIterative.Rd Removes documentation for deleted exported function.
man/optimizeIterative_WL_Internal.Rd Removes documentation for deleted internal helper.
man/optimizeIterative_XG_Internal.Rd Removes documentation for deleted internal helper.
man/readIterativePredictions.Rd Removes documentation for deleted internal helper.
man/saveIterativePredictions.Rd Removes documentation for deleted internal helper.
man/updateIterativeRankings.Rd Removes documentation for deleted internal helper.
man/updateRankingsToToday.Rd Removes documentation for deleted internal helper.
man/updateScoresAPI_byGameID.Rd Removes documentation for deleted internal helper.
man/validateWins.Rd Removes documentation for deleted internal helper.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread R/league.R Outdated
Comment on lines +963 to +967
pdates <- substr(filelist, 1, 10) # gets the dates list of prediction
pdates <- pdates[pdates != "graphics"]
lastp <- as.Date(max(pdates))
if(as.Date(lastp) < Sys.Date()-7){
return(NULL)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback. Note that there's other areas where lastp is determined like this so please confirm all are in sync

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in commits 25034b1 and a2216e5.

Added get_prediction_dates(dir) in R/utils.R — it filters list.files() to files matching ^YYYY-MM-DD-predictions\.RDS$ via regex, strips out any NA dates, validates the directory exists, and returns a sorted Date vector.

All five call sites are now in sync:

  • compile_predictions() (league.R) — uses helper, aborts with informative error if empty
  • simulatePlayoffs() (league.R) — uses helper, emits cli_alert_info() (not silent NULL) for both empty and stale cases
  • updatePredictions() (main.R) — uses helper, falls back to season-start date if no files yet
  • tweetPace() (main.R) — uses helper, aborts if empty
  • plot_pace_by_team() (graphics.R) — uses helper, aborts if empty

Comment thread R/main.R Outdated
Comment thread NAMESPACE
Comment on lines 18 to 27
export(getAPISeries)
export(getCurrentPWHLSeason)
export(getCurrentSeason8)
export(getIterativeTable)
export(getM)
export(getNHLSchedule)
export(getNHLScores)
export(getPWHLPlayoffSeries)
export(getPWHLSchedule)
export(getPWHLScores)
export(getPWHLSeasons)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused, no need for NEWS entry.

Comment thread DESCRIPTION
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI and others added 2 commits May 5, 2026 00:36
…files

Adds get_prediction_dates() in R/utils.R that filters list.files() output
to only YYYY-MM-DD-predictions.RDS entries via regex, returning a sorted
Date vector. Replaces the fragile pdates[pdates != "graphics"] pattern
at all five call sites (compile_predictions, simulatePlayoffs,
updatePredictions, tweetPace, plot_pace_by_team).

simulatePlayoffs() now emits cli_alert_info() instead of silently
returning NULL when predictions are missing or stale.

Agent-Logs-Url: https://github.com/pbulsink/HockeyModel/sessions/c9b20b30-ae42-41d3-a25e-3c11ece18973

Co-authored-by: pbulsink <5419974+pbulsink@users.noreply.github.com>
- Validate dir exists before calling list.files(); abort with informative
  message if NULL or non-existent
- Filter out NA dates produced by any malformed filenames that pass regex
- Fix cli_alert_info() message to use {.val {lastp}} so the date is
  properly interpolated in the CLI output

Agent-Logs-Url: https://github.com/pbulsink/HockeyModel/sessions/c9b20b30-ae42-41d3-a25e-3c11ece18973

Co-authored-by: pbulsink <5419974+pbulsink@users.noreply.github.com>
Copilot AI changed the title chore: dead code and unused function audit chore: dead code and unused function audit and removal May 5, 2026
Copilot AI requested a review from pbulsink May 5, 2026 00:40
@pbulsink pbulsink merged commit fe2edee into master May 5, 2026
12 of 13 checks passed
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.

3 participants