Python

индекс
250,37

Простой консольный прогрессбар на питоне

В связи с некоторыми вычислениями на питоне (например, подсчётом коэффициента симметрии карты реликтового излучения) мне захотелось сделать процесс более наглядным. Ну хотя бы добавить прогресс-бар. Скучно, знаете ли, сидеть перед пустой консолью и втыкать на запущенную команду. То ли работает, то ли висит… с ходу не понять. А делать какой-нибудь лог исполнения не хочется, так как потом в полученом хаосе глаз теряется.

Недавно нашёл выход: модуль progressbar. Модуль существует в deb-репозиториях (я нашёл его в репозиториях ubuntu 9.10), ставится пакетом python-progressbar:
Copy Source | Copy HTML
  1. sudo apt-get install python-progressbar


Для начала можно попробовать запустить небольшой пример:
Copy Source | Copy HTML
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import progressbar
  4. import time
  5.  
  6. bar = progressbar.ProgressBar().start() # Создаём новый progress bar
  7.  
  8. for t in xrange(101):
  9.     bar.update(t) # Таким образом можно устанавливать значение.
  10.     time.sleep(0.01)
  11. bar.finish() # Заканчиваем обновлять -- далее можно
  12. print "finished =)"


Теперь немного поподробнее о самых простых и часто встречающихся случаях использования (насколько могу себе их помыслить).

Во-первых в конструкторе progressbar.ProgressBar(maxval=100) есть аргумет maxval, задающий максимальное значение в полоске. Он может быть как целый, так и вещественный. Соответственно, в progressbar.ProgressBar.update() можно также передавать вещественное число.
Copy Source | Copy HTML
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import progressbar
  4. import time
  5.  
  6. bar = progressbar.ProgressBar(maxval=10.0).start()
  7.  
  8. t = 0.0
  9. while t <= 1.0:
  10.     bar.update(t)
  11.     time.sleep(0.01)
  12.     t += 0.01
  13. bar.finish()


И, наконец, о вкусном: виджеты. Ещё одним аргументом в конструктор progressbar.ProgressBar() можно передать массив виджетов. Каждый виджет имеет ряд своих настроек. Наибольшее количество, видимо, у штуки progressbar.Bar. Из следующего примера должно быть очевидно, как можно просто и непринуждённо использовать свой набор виджетов:
Copy Source | Copy HTML
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import progressbar
  4. import time
  5.  
  6. bar = progressbar.ProgressBar(maxval=10.0, widgets=[
  7.     'Just a progress bar test: ', # Статический текст
  8.     progressbar.Bar(left='[', marker='=', right=']'), # Прогресс
  9.     progressbar.ReverseBar(left='[', marker='*', right=']'), # Регресс
  10.     progressbar.SimpleProgress(), # Надпись "6 из 10"
  11. ]).start()
  12.  
  13. t = 0.0
  14. while t <= 10.0:
  15.     bar.update(t)
  16.     time.sleep(0.01)
  17.     t += 0.1
  18. bar.finish()


image

К модулю прилогается подробная документация. Так что проблем с освоением возникнуть не должно. Хотя последний пример, я думаю, покрывает 90% всех задач.

Из минусов модуля можно отметить нежелание работать в консоли Windows.

UPD by xvoland: python-progressbar on pypi.python.org
+59
21 января 2010, 23:15
83

комментарии (30)

+2
otaqsun #
А скриншоты?
+1
Dair_Targ #
Вам консоль сфотографировть? Сейчас будет =)
0
Averrin #
о, вроде стандартная штука, а я не знал. Пасиб, забираю в избранное. на досуге попробую применить.
0
spanasik #
Можете перенести в «Язык программирования Python» :-)
0
Dair_Targ #
Как-раз карма набралась =)
0
spanasik #
ага, питоноводов всегда плюсую :-)
0
iOrange #
Спасибо, отличная плюшка, давно хотел такую
0
AlienZzzz #
____
супер реально, я свое написал
Всего: 1428, Обработано: 1230 ( 86% ), осталось: 198 ( 22.04: 22.01.10 12:35:44 ), Время 3.34( 0.11 в сек )

Но это реально удобней.
0
AlienZzzz #
( не совсем удобно, что выводить больше (пока прогрес бар идет) ничего нельзя, так как тогда прогресс бар смещается.
0
Dair_Targ #
Ну это уже надо поуши влезать в ncurses или вообще на GUI переходить. Хотя можно просто сообщения в файлы выбрасывать и смотреть их через tail -f в соседней консоли.
–2
abelozor #
Спасибо за топик.
–2
rule #
спасибо, пригодится…
+7
highw #
Мда ребят… я такое на паскале лет 8 назад делал.

удивлен, что о такой работе пишут на хабре
+2
EvilShadow #
Вы просто молодец!
–3
scr4t #
Вау, ты смог заюзать \r! Если честно, я не понимаю, зачем постить подобное.
+2
EvilShadow #
А я не понимаю, зачем нужны такие комментарии. И что?
+3
sindrom #
А для PHP есть Console_ProgressBar. Может быть мне тоже об этом статью написать…
+1
Dair_Targ #
И сколько, из тех, кому это может пригодиться, знает об этой библиотеке?
+1
xvoland #
0
Dair_Targ #
Спасибо, проапдейтил.
+1
xvoland #
лучше ставить через easy_install progressbar

=)

p.s.: пользуйтесь
+4
RuslanT #
Автору спасибо, не знал про этот модуль. Жаль, конечно, что он не входит в стандартные, придётся зависимость добавлять в проект.

Кстати, можно легко использовать этот прогрессбар для индикации процесса скачивания файла из сети:
Copy Source | Copy HTML
  1. #!/usr/bin/python
  2. # -*- coding: utf8 -*-
  3. import urllib, progressbar
  4.  
  5. url = 'http://example.com/file.mp3'
  6.  
  7. def loadProgress(bl, blsize, size):
  8.     dldsize = min(bl*blsize, size)
  9.     p = float(dldsize) / size
  10.     bar.update(p)
  11.  
  12. bar = progressbar.ProgressBar(maxval=1. 0, widgets=[
  13.       'Загрузка файла ',
  14.       progressbar.Bar(left='[', marker='=', right=']'),
  15.       progressbar.Percentage()
  16.       ]).start()
  17.  
  18. urllib.urlretrieve(url, 'myfile.mp3', loadProgress)
  19. bar.finish()
0
kossmak #
> Из минусов модуля можно отметить нежелание работать в консоли Windows.
Заработало с первой подачи (winXPsp3, python 2.5):
winxpsp3-console-progressbar.py-run

В ваших исходниках-примерах вещественные числа «разъехались».
0
Dair_Targ #
Ну у меня не заработало (просто пустая строка была), хотя это и абсолютно не целевая, для меня, ОС. Сегодня ещё разок попробую.

Про вещественные числа — какая-то проблема с подсвечивалкой. Уже пробовал «съехать». Результат — не очень.
0
kossmak #
В примере с виджетами сругнулся на 10 строке, что в progressbar.py не найден метод:
    progressbar.SimpleProgress(), # Надпись "6 из 10"

просто комментируем и нормально работает.
0
Dair_Targ #
Посмотри доки модуля и проверь его версию (моя сейчас progressbar2.2 от 2006-05-07). Возможно у тебя нету класса progressbar.SimpleProgress.
0
pawnhearts #
Я обычно использовал dialog для этого. Вот моя питоновская обертка к нему(второй пример — как раз прогрессбар): pawnhearts.ru/software/dlg/
0
Dair_Targ #
Спасибо, буду знать. К сожалению, сейчас не могу пощупать руками — можешь показать, как это выглядит?
0
pawnhearts #
www.ambienteto.arti.beniculturali.it/doc/lg/101/misc/sunil/gauge.png
вообще просто набери dialog в консоли и поиграйся :)
ещё один плюс — легко переключится на граф. вариант — достаточно вместо dialog вызывать gdialog, kdialog, xdialog, etc.
0
neithere #
Удобная штука, мерси за хинт.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.