Получение пользовательского ввода в циклах tqdm - PullRequest
0 голосов
/ 27 июня 2019

Я пишу скрипт, в котором пользователь должен вводить данные для каждого элемента большого списка. Я пытаюсь использовать tqdm для предоставления индикатора выполнения для пользователя, но я не могу найти хороший способ получить ввод в цикле tqdm, не прерывая вывод.

Мне известно о tqdm.write() для записи на терминал во время цикла tqdm, но есть ли способ получить ввод?

В качестве примера того, что я пытаюсь сделать, рассмотрите код ниже:

from tqdm import tqdm
import sys
from time import sleep

def do_stuff(x): sleep(0.5)

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

for thing in tqdm(stuff_list):
    input_string = input(thing + ": ")
    do_stuff(input_string)

Если я запускаю этот код, я получаю следующий вывод:

0%|                                                                                            | 0/4 [00:00<?, ?it/s]Alpha: A
 25%|█████████████████████                                                               | 1/4 [00:02<00:07,  2.54s/it]Beta: B
 50%|██████████████████████████████████████████                                          | 2/4 [00:03<00:04,  2.09s/it]Gamma: C
 75%|███████████████████████████████████████████████████████████████                     | 3/4 [00:04<00:01,  1.72s/it]Omega: D
100%|████████████████████████████████████████████████████████████████████████████████████| 4/4 [00:05<00:00,  1.56s/it]

Я пытался использовать tqdm.external_write_mode, но это просто не отображало индикатор выполнения всякий раз, когда ввод ожидал, что не является тем поведением, которое я ищу.

Есть ли простой способ сделать это, или мне придется поменять местами библиотеки?

1 Ответ

0 голосов
/ 27 июня 2019

Невозможно отобразить индикатор выполнения, пока он находится внутри функции input (), потому что после завершения строки ее больше нельзя удалить.Это техническое ограничение работы командной строки.Вы можете удалить только текущую строку, пока не напишите новую строку.

Поэтому я думаю, что единственное решение - удалить строку состояния, разрешить ввод данных пользователем и затем отобразить ее снова.

from tqdm import tqdm
import sys
from time import sleep

def do_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)

Если вам не нравится тот факт, что объект progress_iterator существует после цикла, используйте синтаксис with:

with tqdm(stuff_list) as progress_iterator:
    for thing in progress_iterator:
        ...

EDIT: Если вы готовы пожертвоватьНезависимость от платформы, вы можете свободно перемещать курсор и удалять строки с помощью this :

from tqdm import tqdm
import sys
from time import sleep

def do_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)

Я думаю, что это самое близкое к tqdm.write().Обратите внимание, что поведение input() никогда не может быть идентичным tqdm.write(), поскольку tqdm.write() сначала удаляет полосу, затем записывает сообщение, а затем снова записывает полосу.Если вы хотите отобразить панель, находясь в input(), у вас есть для выполнения некоторых платформо-зависимых вещей, подобных этой.

...