Textualize / rich

Rich is a Python library for rich text and beautiful formatting in the terminal.
https://rich.readthedocs.io/en/latest/
MIT License
48.1k stars 1.69k forks source link

Progress: Added an option to TimeRemainingColumn to estimate the speed using an exponential moving average #3396

Closed Akulen closed 1 day ago

Akulen commented 1 week ago

Type of changes

Checklist

Description

I added a new attribute speed_ema to the Task class that stores a speed estimate using an Exponential Moving Average (EMA). It is updated whenever progress.update or progress.advance are called with new completed steps.

In addition, a parameter speed_estimate_alpha was added to Progress to control the EMA. The base formula used was: $$S{i+1}=\left(\frac{\alpha}{s} + \frac{1-\alpha}{S{i}}\right)^{-1}$$ where we do an harmonic weighted average of the speed, or a weighted average of the estimated remaining time. By interpolating this formula extension to $k$ consecutive speed updates with the same speed, we get the general formula $$S{i+x} = \left(\frac{1 - (1 - \alpha)^x}{s} + \frac{(1-\alpha)^x}{S{i}}\right)^{-1}$$ for an arbitrary $x>0$

At the start, as we have no previous estimate, so $S_0 = s_0$, and for the first few updates, we use a larger $\alpha$ so that the first few speed estimates do not get a disproportionate weight. In practice, we use $\alpha=max(\frac{1}{i+1}, \text{speed\_estimate\_alpha})$

Extra

The variable names are not ideal, being: speed_estimate_alpha, speed_ema, and time_remaining_ema, with ema abbreviating exponential_moving_average

I also updated pycvn in the pre-commit hooks to work in python 3.12

willmcgugan commented 1 day ago

Thanks, but I think this is best done as an external class, and not the core lib.

https://textual.textualize.io/blog/2023/07/29/pull-requests-are-cake-or-puppies/