aaronsnoswell
aaronsnoswell

Reputation: 6261

tqdm progress bar with estimated duration

I want to use TQDM to show a progress bar for a process. I know roughly how long this process will take (based on an empirical model I have fit).

The tqdm() length parameter makes it easy to set a progress bar's length based on a known iterable size, but I can't see a way to do the same thing when you know a duration, not a size.

Upvotes: 1

Views: 1594

Answers (1)

blhsing
blhsing

Reputation: 107015

In order to use tqdm to display a progress bar at all, you need to make your long-running process a generator that yields periodically so that the progress bar can be updated in the interim.

With the periodic yield implemented, you can then create a generator that iterates over the generator that is your long-running process while also iterating over a separate tqdm object according to the number of seconds elapsed. The separate tqdm object should be created over an indefinitely repeating iterator (such as itertools.cycle(' ')) with the total argument specified with the number of seconds your long-running process is expected to run, so that the number of seconds elapsed will be scaled properly when the progress bar is displayed.

The example below shows you such a generator over a long-running process that takes a total of 9 seconds to run, while yielding updates in the interim with 2, 4 and 3-second intervals:

from tqdm import tqdm
from time import time, sleep
from itertools import cycle

def tqdm_duration(iterable, duration):
    progress_bar = iter(tqdm(cycle(' '), total=duration, mininterval=0))
    next(progress_bar)
    last_progress = 0
    start_time = time()
    for _ in iterable:
        progress = int(time() - start_time)
        for _ in range(last_progress, progress):
            next(progress_bar)
        last_progress = progress
        yield

def nine_second_work(): # your long-running process, taking 9 seconds in this example
    for interval in 2, 4, 3: # 2 + 4 + 3 == 9
        sleep(interval) # actual work is done here
        yield # this gives a chance for tqdm to update the progress bar

for _ in tqdm_duration(nine_second_work(), 9):
    pass

Demo: https://replit.com/@blhsing/DapperAustereFrontpage

Upvotes: 1

Related Questions