Search code examples
python-3.xdecoratortqdm

`tqdm` wrapper for function with while loop


I have a long-standing library function I cannot edit that runs a while loop and returns a value. In essence, something like this:

import time

def myfunc():
    i = 0
    while i < 5 * 1000:
        i += 1
        time.sleep(0.001)
    return i

Is there a way I can wrap this function, perhaps in a decorator, in such a way that it can be passed to tqdm and spit out a progress bar? I'm not quite sure how I would achieve this since I cannot edit the code inside myfunc.

My goal is to make a progress bar for myfunc without touching it. Does anyone have any suggestsions?


Solution

  • There are no legal ways to do that, unless this function returns an Iterable/Generator. But, of course, you might to launch that function in a thread, and just simulate loading by doing something like

    import time, tqdm, concurrent
    
    def myfunc():
        i = 0
        while i < 5 * 1000:
            i += 1
            time.sleep(0.001)
        return i
    
    
    def simulate_loading(background_function):
        with concurrent.futures.ThreadPoolExecutor() as executor:
            future = executor.submit(background_function)
            while not future.done():
                yield
                time.sleep(0.05)
            return future.result()
    
    for _ in tqdm.tqdm(simulate_loading(myfunc)):
        pass
    
    115it [00:05, 19.85it/s]