Add manual progress fallback when progress package unavailable#124
Conversation
When show_progress_bar = TRUE but the progress package is not installed, rather than silently doing nothing, emit a one-time warning then print 10%-interval progress messages with elapsed time to the console. Changes in R/chains.R: - Add is_package_available() wrapper around requireNamespace() to allow mocking in tests - Replace single use_progress_bar boolean with two separate booleans (show_progress_bar, progress_available) passed through sample_chain() and chain_loop(), keeping the two concerns distinct - Print upfront message in sample_chain() when progress package is missing but progress bar was requested - Update get_progress_bar() signature to accept the two booleans - Add start_time tracking in chain_loop() using proc.time() - Add fallback else-if branch in chain_loop() printing formatted percentage/elapsed messages at 10% intervals - Add post-loop guard to print 100% done when n_iteration is not a multiple of tick_amount - Update @param show_progress_bar roxygen doc to reflect new behaviour Changes in tests/testthat/test-chains.R: - Add make_fallback_test_inputs() helper to deduplicate test setup - Add test verifying fallback messages are emitted (count, 10%, 100%) - Add test verifying no messages when show_progress_bar = FALSE
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #124 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 11 11
Lines 595 620 +25
=========================================
+ Hits 595 620 +25 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
matt-graham
left a comment
There was a problem hiding this comment.
Hi @jennajiali. This is looking really good. I have suggested some minor changes to resolve linter warnings and improve code readability and maintainability a bit.
As well as the linter warnings, currently the checks are also failing as your changes to the roxygen comment for sample_chains needs a corresponding change to the man/sample_chain.Rd manual page which is generated from this comment. If you have devtools loaded, running document() in an R session should regenerate this file and then you can commit updated version.
Some of the failing checks are run as part of our pre-commit (https://pre-commit.com/) hooks for the project. If you install pre-commit locally and install the hooks in your local repository by running
pre-commit install
from the root of the repository, this will run the checks each time you try to make a commit and give an error and/or changes to fix when you try to commit.
The linter warning here is due to indentation. We can avoid need to split line and repetition of chain_iteration %% tick_amount == 0 expression by factoring out in to a variable and reusing. We also don't need to explicitly check !progress_available in second condition as this is implied by the fact first condition didn't evaluate to TRUE. Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
Reflowing this line should fix linter line length warning. Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
… running devtools::document()
…progress-fallback
…resolve linter warning To reduce line length to avoid linter warning here and make code more readable we can define a variable progress_unfinished which checks whether progress updates are complete and then use this in conditions. We ideally also want to use else if here rather than an independent if clause as we don't need to check the second condition if the first evaluates to TRUE. This also suggests changing progress$finished to use progress_unfinished variable as this should be functionally equivalent and makes it clear we are using the same condition irrespective of whether using the progress package or not.
…he scope of the mock_bindings
This will cause the linter warning on cyclomatic complexity for this function to be ignored. As per the comment below it's not clear how useful the cyclomatic complexity measure is here so we may want to consider disabling globally, and either way I think it is justified to ignore it for now here and potentially consider possible refactorings to reduce complexity of this function in a separate PR. Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
…tion %% tick_amount != 0` Using a number of iterations which is not an exact multiple of 10 here will ensure the final conditions which ensure progress updates are completed when n_iteration %% tick_amount != 0 are entered as part of the tests and so avoid the warning about that line of code not being covered by tests from codecov check. Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
|
Hi @jennajiali - apologies for all the back and forth. Some of my suggested changes introduced a new styler error causing the pre-commit check to fail and also didn't fix the missing lines in coverage as I'd expected. I've opened a PR off the top of your PR in jennajiali#1 which should resolve the remaining failing checks 🤞 (or at least I get no styler warnings and 100% coverage locally with those changes). |
Minor fixes to progress fallback PR
🤞 this will resolve both the styler warning (which wants this comment to be on a separate line) and the linter warning (which requires the nolint directive to be on the line used to open the function) by disabling styler for this specific line. Running both styler and lintr checks locally with this change doesn't raise any warnings. Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
#29
Summary
Fixes the issue where calling
sample_chain()withshow_progress_bar = TRUEwould silently produce no output if theprogresspackage was not installed, making it appear to the user as though the program had halted — particularly problematic for long chains.When
progressis unavailable, the function now emits a one-time informational message and then prints percentage-based progress updates with elapsed time at 10% intervals to the console.Example output when
progressis not installed:Changes
R/chains.Ris_package_available()helper — a thin wrapper aroundrequireNamespace()that lives in the package namespace, making it mockable in tests viawith_mocked_bindings()use_progress_barinto two booleans —progress_available(is the package installed?) andshow_progress_bar(did the user ask for progress?) are now kept separate and passed independently throughsample_chain()andchain_loop(), so the fallback path can distinguish between the two casessample_chain()— prints a one-time message whenshow_progress_bar = TRUEbutprogressis unavailableget_progress_bar()signature — now acceptsshow_progress_barandprogress_availableseparately instead of the collapseduse_progress_barchain_loop()— addedelse ifbranch alongside the existing progress bar tick, printing a formattedstage: X% done (n/total) | elapsed: Xsmessage at every 10% interval usingproc.time()(base R, no dependencies)n_iterationis not an exact multiple oftick_amount, ensuring completion is always reported@param show_progress_barroxygen doc — reflects that the parameter now controls both the progress bar (whenprogressis installed) and the fallback text output (when it is not)tests/testthat/test-chains.Rmake_fallback_test_inputs()helper — extracts shared setup (target distribution, adapters, initial position) used by both new tests into a single function to avoid duplicationis_package_available()to returnFALSE, captures all messages withcapture_messages(), and asserts the correct total count, that the upfront warning is present, and that both 10% and 100% interval messages appearshow_progress_bar = FALSE— same mock, assertsexpect_no_message()confirming the fallback is correctly gated on the user's flagTesting
All existing tests continue to pass. The two new tests covering the fallback path and the silent-when-disabled case also pass.
Notes
This PR is a draft / work in progress