Skip to content Skip to sidebar Skip to footer

Getting User Input Within Tqdm Loops

I'm writing a script where a user has to provide input for each element of a large list. I'm trying to use tqdm to provide a progress bar for the user, but I can't find a good way

Solution 1:

It isn't possible to display the progress bar while inside the input() function, because once a line is finished, it cannot be removed any more. It's a technical limitation of how command lines work. You can only remove the current line until you wrote a newline.

Therefore, I think the only solution is to remove the status bar, let the user input happen and then display it again.

from tqdm import tqdm
import sys
from time import sleep

defdo_stuff(x): sleep(0.5)

stuff_list = ['Alpha', 'Beta', 'Gamma', 'Omega']

# To have more fine-control, you need to create a tqdm object
progress_iterator = tqdm(stuff_list)

for thing in progress_iterator:
    # Remove progress bar
    progress_iterator.clear()

    # User input
    input_string = input(thing + ": ")

    # Write the progress bar again
    progress_iterator.refresh()

    # Do stuff
    do_stuff(input_string)

If you don't like the fact that the progress_iterator object exists after the loop, use the with syntax:

withtqdm(stuff_list) as progress_iterator:
    for thing in progress_iterator:
        ...

EDIT: If you are willed to sacrifice platform independence, you can freely move the cursor and delete lines with this:

from tqdm import tqdm
import sys
from time import sleep

defdo_stuff(x): sleep(0.5)

stuff_list = ['Alpha', 'Beta', 'Gamma', 'Omega']

# Special console commands
CURSOR_UP_ONE = '\x1b[1A'# To have more fine-control, you need to create a tqdm object
progress_iterator = tqdm(stuff_list)

for thing in progress_iterator:

    # Move the status bar one down
    progress_iterator.clear()
    print(file=sys.stderr)
    progress_iterator.refresh()

    # Move the cursor back up
    sys.stderr.write('\r')
    sys.stderr.write(CURSOR_UP_ONE)

    # User input
    input_string = input(thing + ": ")

    # Refresh the progress bar, to move the cursor back to where it should be.# This step can be omitted.
    progress_iterator.refresh()

    # Do stuff
    do_stuff(input_string)

I think this is the closest you will get to tqdm.write(). Note that the behaviour of input() can never be identical to tqdm.write(), because tqdm.write() first deletes the bar, then writes the message, and then writes the bar again. If you want to display the bar while being in input(), you have to do some platform-dependent stuff like this.

Post a Comment for "Getting User Input Within Tqdm Loops"