Ответы пользователя по тегу Индикатор выполнения
  • Правильное отображение прогрессбара на Python - что не так?

    Kademn
    @Kademn
    Злой
    Давайте по-порядку.
    Вот участок кода, отвечающий за прогресс-бар:
    for i in range(lenLi):
        sys.stdout.write('\r')
        sys.stdout.write("[%-30s] %d%%" % ('='*i, i))
        sys.stdout.flush()

    Во-первых вывод в консоль у вас неправильный. Длина вашего прогресс-бара 30 символов. Значит при каждой итерации нужно выводить количество символов, соответствующее итерации, не забывая, что нельзя выводить дробное количество символов. К примеру, если длина списка у вас 5, значит 30/5=6 символов добавляет каждая итерация цикла. Но вы переписываете весь прогресс-бар, поэтому можно посчитать "часть" от всей длины (30 символов) для этого шага. Например для длины 5, шаг 1 - это 1/5 длины, шаг 2 это 2/5 длины и т.д. Тогда количество символов это количество символов для "полной" длины умножить на полученную часть.
    part = float(i)/(lenLi-1)
    symbols_num = int(30 * part)

    lenLi -1, так как выше вы увеличивали длину на единицу (видимо для range), то тогда range стоило бы начинать с 1, а не с нуля. А проценты легко получить умножив part на 100, не забыв сменить форматирование вывода с '%s%%' на, скажем, '%3.2f%%', так как в выводе дробное число и оно очень плохо смотрится, если %s.
    Теперь прогресс-бар будет выводиться правильно:
    for i in range(1, lenLi):
        sys.stdout.write('\r')
        part = float(i)/(lenLi-1)
        symbols_num = int(30 * part)
        sys.stdout.write("[%-30s] %3.2f%%" % ('='*symbols_num, part*100))
        sys.stdout.flush()

    Правда, чтобы успеть увидеть изменения, добавьте в цикл wait(), иначе все 100% заполнятся за доли секунды.
    UPD
    Да, вы для каждой ссылки заполняете прогресс-бар от нуля до 100 процентов. Цикл внутри цикла не нужен. Прогресс-бар должен быть частью for x in li:. Но, для правильного отображения прогресс-бара, вам необходимо считать номер шага. Для это можно либо завести переменную, которая будет считать шаги, либо использовать функцию enumerate:
    for step_number, x in enumerate(li):
    Учитывая, что вам удобнее нумеровать шаги с единицы, правильнее было бы использовать
    for step_number, x in enumerate(li, 1):
    А вообще, если вы хотите использовать прогресс-бар и в других местах кода, то стоило бы завести отдельную функцию для печати прогресса, которая принимает дробное число от 0 до 1 или процент в качестве аргумента и выводит в консоль соответствующий прогресс-бар, возвращая каретку в начало строки.
    Полагаю, что этих подсказок более, чем достаточно. Дальше попробуйте сами.
    Ответ написан
    3 комментария