AdaptiveETA

AdaptiveETA estimates time remaining from the last few seconds.

Reach for it when the processing rate can change mid-run (resuming a paused job, or one that starts slow and speeds up) so the estimate should track the current pace rather than the whole-run average that plain ETA uses. The window size comes from SamplesMixin’s samples argument: an update count or a time span. In the demo, the run starts slow and speeds up partway through, and the countdown visibly drops as the estimate catches on.

class progressbar.widgets.AdaptiveETA(exponential_smoothing=True, exponential_smoothing_factor=0.1, **kwargs)[source]

Bases: ETA, SamplesMixin

WidgetBase which attempts to estimate the time of arrival.

Uses a sampled average of the speed based on the 10 last updates. Very convenient for resuming the progress halfway. For an estimate based on an exponential moving average (EMA) of the speed instead of a windowed sample, use SmoothingETA.

Store exponential-smoothing config.

Parameters:
  • exponential_smoothing – Accepted for backward compatibility; not read by AdaptiveETA.__call__, which always averages over the sampled window (see SamplesMixin). Use SmoothingETA for an actual EMA-based estimate.

  • exponential_smoothing_factor – Same caveat as exponential_smoothing.

  • **kwargs – Forwarded to the next class in the cooperative __init__ chain.

Example

AdaptiveETA
"""``AdaptiveETA`` estimates time remaining from the last few seconds.

Reach for it when the processing rate can change mid-run -- resuming a
paused job, or one that starts slow and speeds up -- so the estimate
should track the *current* pace rather than the whole-run average that
plain ``ETA`` uses. This example runs slower at first and speeds up
partway through so the adaptive estimate visibly reacts; a uniform run
like most examples in this set would look identical to ``ETA``.

It also runs longer than most in this set: the ETA is only shown to
whole-second resolution, so too short a run shows only a tick or two rather
than a real countdown reacting to the pace change.
"""

import time

import progressbar

STEPS = 40


def main() -> None:
    widgets = [
        progressbar.Percentage(),
        ' ',
        progressbar.Bar(),
        ' ',
        progressbar.AdaptiveETA(),
    ]
    with progressbar.ProgressBar(max_value=STEPS, widgets=widgets) as bar:
        for step in range(STEPS):
            bar.update(step + 1)
            time.sleep(0.32 if step < STEPS // 2 else 0.04)


if __name__ == '__main__':
    main()

See also

  • ETA: the plain whole-run-average estimate this reacts faster than.

  • SmoothingETA: an exponential moving average instead of a fixed sample window.

  • AbsoluteETA: a clock time instead of a countdown.