Вы когда-нибудь задумывались, где находится ваша длительная обработка и когда она закончится? Вы обычно нажимаете RETURN
несколько раз, чтобы убедиться, что он не сломался или SSH-соединение не зависло? Вы когда-нибудь думали, что было бы здорово иметь возможность без проблем приостановить некоторую обработку , вернуться к командной строке Python, чтобы вручную исправить некоторые элементы, а затем плавно возобновить ее? Я сделал...
Я запустил этот новый индикатор выполнения, думая обо всем этом, вот живой прогресс ! ?
Представляем новейшую концепцию индикаторов выполнения для Python! alive-progress
представляет собой отдельный класс, обладающий множеством интересных функций, которые выделяют его среди других. Вот несколько основных моментов:
check()
, который поможет вам создавать собственные анимации! Вы можете увидеть, как будут выглядеть сгенерированные кадры и циклы анимации в разобранном виде на вашем экране, и даже увидеть их вживую перед установкой в alive-progress
! Это самый крутой инструмент в мире! Раскройте свой творческий потенциал! Этот README постоянно развивается, поэтому время от времени просматривайте его более подробно... Возможно, вы найдете новые интересные подробности в других разделах! ?
alive-progress
bar()
Примерно через год обнадеживающей стабильности наконец-то появился новый alive-progress
!
Основные особенности и улучшения:
bar()
с 0
и даже -N
, чтобы заставить его двигаться назад! Полезно, когда вы не смогли добиться прогресса в итерации или вам пришлось что-то откатить!И многое другое!
enrich_offset
, которое будет использоваться для печатных или зарегистрированных сообщений, что позволит вам начать с on 1:
или продолжить с того места, где вы остановились в предыдущих вычислениях! Здесь очень крутое обновление! В дополнение к доработке и улучшению поддержки терминалов, теперь alive-progress
поддерживает возобновление вычислений!
При обработке огромных наборов данных или задач, которые занимают много времени, вы можете использовать пакеты или кэшировать частичные результаты. Затем, если он останавливается и перезапускается, вы в конечном итоге очень быстро пропускаете все уже выполненные элементы, из-за чего alive_bar
думает, что вы обрабатываете тысячи элементов в секунду, что, в свою очередь, полностью разрушает ETA... Но не больше ! Просто скажите bar()
, что вы пропустили элементы... ?
Вы можете использовать его двумя способами:
1. Если вы знаете, где остановились:
with alive_bar ( 120000 ) as bar :
bar ( 60000 , skipped = True )
for i in range ( 60000 , 120000 ):
# process item
bar ()
Да, просто вызовите bar(N, skipped=True)
один раз, указав количество элементов.
2. Если вы не знаете или предметы разбросаны:
with alive_bar ( 120000 ) as bar :
for i in range ( 120000 ):
if done ( i ):
bar ( skipped = True )
continue
# process item
bar ()
Да, это так просто! Просто вызовите bar(skipped=True)
когда элемент уже выполнен, или bar()
как обычно, в противном случае. Вы также можете поделиться одним вызовом bar(skipped=?)
в конце с логическим значением, указывающим, пропустили ли вы этот элемент или нет. Круто, да?
Также в этой версии:
max_cols
, количество столбцов, которые следует использовать, если его невозможно получить, как в Jupyter и других платформах, которые не поддерживают размерДа, я наконец-то смог выпустить эту версию! Это новые вкусности:
B
, bytes
или даже °C
!sys.stderr
и других файлов вместо sys.stdout
!Долгожданные исправления:
TypeError: unhashable type: 'types.SimpleNamespace'
.RotatingFileHandler
! Да, ищите поддержку здесь.И последнее, но не менее важное: более совершенный макет, позволяющий вам наслаждаться своим прогрессом!
Теперь alive_bar
поддерживает двухстрочный текстовый режим!
Если вы когда-нибудь хотели разместить на панели более длинные ситуационные сообщения, вы, вероятно, чувствовали себя сжатыми в одну строку. Вам приходилось сжимать красиво анимированную панель или, что еще хуже, удалять виджеты (!), чтобы увидеть то, что вам нужно...
Уже нет!! Теперь вы можете сделать панель двойной линией и поместить под ней текст!
Да, сообщение есть под всей полосой, а любые другие сообщения печати/регистрации прокручиваются над ней!
letters = [ chr ( ord ( 'A' ) + x ) for x in range ( 26 )]
with alive_bar ( 26 , dual_line = True , title = 'Alphabet' ) as bar :
for c in letters :
bar . text = f'-> Teaching the letter: { c } , please wait...'
if c in 'HKWZ' :
print ( f'fail " { c } ", retry later' )
time . sleep ( 0.3 )
bar ()
Выход:
on 7: fail "H", retry later
on 10: fail "K", retry later
Alphabet |███████████████████████████▊ | ▃▅▇ 18/26 [69%] in 6s (3.2/s, eta: 3s)
-> Teaching the letter: S, please wait...
В alive_it
также появился новый параметр функции finalize
, который позволяет вам установить заголовок и/или текст окончательной квитанции, а также улучшенная поддержка ведения журналов, позволяющая обнаруживать настроенные средства ведения журналов.
Все дело в настройке; основные виджеты теперь можно изменить:
monitor
, elapsed
и stats
, чтобы они выглядели так, как вы хотите!Невероятно, что эти строки поддерживают все функции формата Python, поэтому вы можете, например,
{percent:.1%}
.
Их можно дополнительно настроить при окончательной квитанции !
monitor_end
, elapsed_end
и stats_end
с динамическими форматами, унаследованными от стандартных!Если раньше вы скрывали некоторые виджеты, чтобы они не появлялись в квитанции, теперь вы можете увидеть их во всей красе и скрыть только те, которые есть в квитанции! Или наоборот?
Еще одно дополнение: теперь alive-progress
прекрасно отображает свою классную финальную квитанцию всякий раз, когда он остановлен, даже если вы нажмете CTRL+C преждевременно! Не знаю, почему я не подумал об этом раньше...
Download |██████████████████︎ | (!) 45/100 [45%] in 4.8s (9.43/s)
И, наконец, вы можете вообще отключить CTRL+C! По умолчанию используется более безопасный вариант ctrl_c=True
, при котором сочетание клавиш CTRL-C работает как обычно.
Отключите его ctrl_c=False
, чтобы сделать интерактивную alive_bar
более удобной в использовании (если вы ее остановите, трассировки стека не будет) и/или если она находится на верхнем уровне вашей программы!
Остерегайтесь: если он, например, находится внутри цикла for, он просто продолжит следующую итерацию, которая может быть, а может и не быть тем, что вы хотите...
for i in range ( 10 ):
with alive_bar ( 100 , ctrl_c = False , title = f'Download { i } ' ) as bar :
for i in range ( 100 ):
time . sleep ( 0.02 )
bar ()
Выход:
Download 0 |████████▊︎ | (!) 22/100 [22%] in 0.6s (36.40/s)
Download 1 |████████████████▊︎ | (!) 42/100 [42%] in 1.0s (41.43/s)
Download 2 |██████▍︎ | (!) 16/100 [16%] in 0.4s (39.29/s)
Download 3 |█████▋︎ | (!) 14/100 [14%] in 0.4s (33.68/s)
Download 4 |█████████████▎︎ | (!) 33/100 [33%] in 0.8s (39.48/s)
Download 5 |███████▎︎ | (!) 18/100 [18%] in 0.5s (37.69/s)
Download 6 |█████▎︎ | (!) 13/100 [13%] in 0.3s (37.28/s)
Download 7 |████████████︎ | (!) 30/100 [30%] in 0.8s (38.43/s)
Download 8 |██████︎ | (!) 15/100 [15%] in 0.4s (36.26/s)
...
Некоторые важные новые функции, о которых часто просили, наконец-то появились!
click.echo()
ДА! Теперь alive-progress
поддерживает Jupyter Notebooks, а также включает состояние «Отключено» ! Оба пользовались большим спросом и наконец-то появились!
И что еще лучше, я реализовал механизм автоматического обнаружения для блокнотов Jupyter, так что он просто работает «из коробки», без каких-либо изменений в вашем коде!
Посмотрите сами:
Кажется, это работает очень хорошо, но на данный момент его следует считать экспериментальным .
Были случаи, когда появлялись некоторые визуальные сбои, например, два обновленияalive_bar
объединялись вместе, а не поверх друг друга... И я думаю, что с этим невозможно справиться: кажется, что Jupyter иногда обновляет холст в нечетное время, что приводит к потере некоторых данных. Пожалуйста, дайте мне знать по вопросам, если возникнет что-то более смешное.
Это крупный прорыв в alive-progress
!
Я потратил 1 год на его разработку и очень горжусь тем, чего достиг o/
.check()
которые компилируют и прекрасно визуализируют все кадры всех циклов анимации счетчиков и полосок! они могут даже включать полные данные кадра, внутренние коды и даже их анимацию! ?alive-progress
!alive_it
, который принимает итерацию и вызывает для вас bar()
!Поскольку это существенное изменение версии, прямая обратная совместимость не гарантируется. Если что-то поначалу не работает, просто проверьте новый импорт и сигнатуры функций, и все готово. Все предыдущие функции должны здесь работать! ?
alive-progress
Просто установите с помощью pip:
❯ pip install alive-progress
Если вам интересно, какие стили встроены, самое showtime
! ;)
from alive_progress . styles import showtime
showtime ()
Примечание. Не обращайте внимания на путь на анимированном GIF-изображении ниже, правильный путь указан выше. Создание этих длинных гифок занимает очень много времени, поэтому я не могу создавать новые при каждом изменении. Спасибо за понимание.
Я создал эти стили просто для того, чтобы опробовать все созданные мной фабрики анимации, но я думаю, что некоторые из них получились очень, очень крутыми! Используйте их по своему желанию и смешивайте, сколько душе угодно!
Хотите ли вы увидеть настоящие alive-progress
прекрасно работающие в вашей системе, прежде чем пробовать их самостоятельно?
❯ python -m alive_progress.tools.demo
Круто, да?? Теперь введите REPL ipython
и попробуйте следующее:
from alive_progress import alive_bar
import time
for x in 1000 , 1500 , 700 , 0 :
with alive_bar ( x ) as bar :
for i in range ( 1000 ):
time . sleep ( .005 )
bar ()
Вы увидите что-то вроде этого, с классной анимацией на протяжении всего процесса?:
|████████████████████████████████████████| 1000/1000 [100%] in 5.8s (171.62/s)
|██████████████████████████▋︎ | (!) 1000/1500 [67%] in 5.8s (172.62/s)
|████████████████████████████████████████✗︎ (!) 1000/700 [143%] in 5.8s (172.06/s)
|████████████████████████████████████████| 1000 in 5.8s (172.45/s)
Приятно, да? Понравилось? Я знал, что ты это сделаешь, спасибо?
Чтобы использовать его, просто оберните свой обычный цикл в контекстный менеджер alive_bar
следующим образом:
with alive_bar ( total ) as bar : # declare your expected total
for item in items : # <<-- your original loop
print ( item ) # process each item
bar () # call `bar()` at the end
И оно живое! ?
Итак, в двух словах: извлеките элементы, как всегда, войдите в контекстный менеджер alive_bar
с количеством элементов, а затем переберите/обработайте эти элементы, вызвав bar()
в конце! Это так просто! :)
items
могут быть любыми итерируемыми, например, набором запросов;alive_bar
— это ожидаемая сумма, например qs.count()
для наборов запросов, len(items)
для итераций с длиной или даже статическое число;bar()
— это то, что заставляет полосу двигаться вперед — вы обычно вызываете его на каждой итерации, сразу после завершения элемента;bar()
слишком часто (или слишком мало в конце), столбец графически отобразит это отклонение от ожидаемого total
, что позволит очень легко заметить переполнение и недополнение;bar.current
.Вы можете проявить творческий подход! Поскольку полоса движется вперед только тогда, когда вы вызываете
bar()
, она не зависит от цикла ! Таким образом, вы можете использовать его для мониторинга всего, что захотите, например, ожидающих транзакций, сломанных элементов и т. д., или даже вызывать его несколько раз за одну итерацию! Итак, в конце концов вы узнаете, сколько было этих «особых» событий, включая их процент по отношению к общему количеству!
Находясь внутри контекста alive_bar
, вы можете легко отображать сообщения, тесно интегрированные с текущим отображаемым индикатором выполнения! Он никоим образом не сломается и даже обогатит ваше послание!
bar.text('message')
и bar.text = 'message'
устанавливают ситуационное сообщение прямо внутри панели, где вы можете отобразить что-то о текущем элементе или фазе обработки;bar.title('Title')
и bar.title = 'Title'
— смешайте с title_length
, чтобы полоса не меняла свой вид. длина;print()
, где alive_bar
красиво очищает строку, печатает ваше сообщение рядом с текущей позицией панели в данный момент и продолжает полосу прямо под ней;logging
Python, включая вывод файлов, также расширена точно так же, как и предыдущая;click.echo()
для печати стилизованного текста.Потрясающе, правда? И все это работает одинаково как в терминале, так и в блокноте Jupyter!
Теперь у вас есть более быстрый способ контролировать что угодно! Здесь товары автоматически отслеживаются для вас!
alive_bar
alive_it
Просто оберните им свои предметы и проведите по ним циклом, как обычно!
Бар просто будет работать; это так просто!
from alive_progress import alive_it
for item in alive_it ( items ): # <<-- wrapped items
print ( item ) # process each item
КАК ЭТО КРУТО?! ?
Применяются все параметры alive_bar
, кроме total
, что более разумно (если оно не указано, оно будет автоматически выведено из ваших данных с помощью len
или length_hint
), и manual
, что здесь не имеет смысла.
Обратите внимание, что здесь вообще нет bar
ручки. Но что, если вам это нужно, например, для установки текстовых сообщений или просмотра текущего прогресса?
Вы можете взаимодействовать с внутренним alive_bar
, просто назначив alive_it
такой переменной:
bar = alive_it ( items ) # <<-- bar with wrapped items
for item in bar : # <<-- iterate on bar
print ( item ) # process each item
bar . text ( f'ok: { item } ' ) # WOW, it works!
Обратите внимание, что это немного особенный bar
, который не поддерживает bar()
, поскольку адаптер итератора автоматически отслеживает элементы. Кроме того, он поддерживает finalize
, который позволяет вам установить заголовок и/или текст окончательного чека:
alive_it ( items , finalize = lambda bar : bar . text ( 'Success!' ))
...
В двух словах:
- полное использование всегда происходит
with alive_bar() as bar
, где вы выполняете итерацию и вызываетеbar()
когда захотите;- быстрое использование адаптера предназначено
for item in alive_it(items)
, где элементы отслеживаются автоматически;- Полное использование адаптера —
bar = alive_it(items)
, где в дополнение к автоматически отслеживаемым элементам вы получаете специальную итерируемуюbar
позволяющую настраивать внутреннийalive_progress
по своему усмотрению.
Режимы по умолчанию — auto иknown , в которых для отслеживания прогресса используется внутренний счетчик . Они подсчитывают количество обработанных элементов и используют его для соответствующего обновления индикатора выполнения.
total
аргумент не является обязательным. Если вы его предоставите, панель перейдет в автоматический режим . В этом режиме ход операции отслеживается автоматически, и доступны все виджеты, которые может предложить alive-progress
: точная полоса, счетчик, процент, счетчик, пропускная способность и расчетное время прибытия.
Если вы не укажете total
, панель перейдет в неизвестный режим . В этом режиме прогресс не определен, а следовательно, и расчетное время прибытия, поэтому весь индикатор выполнения постоянно анимируется. Доступны следующие виджеты: анимированная полоса, счетчик, счетчик и пропускная способность.
Крутой счетчик работает совершенно независимо от анимированной панели, одновременно запуская собственную анимацию, создавая уникальное шоу на вашем терминале! ?
И последнее, но не менее важное: автоматический режим обладает уникальной способностью: отмечать элементы как пропущенные, что значительно повышает точность определения пропускной способности и расчетного времени прибытия! Подробнее об этом позже.
Ручной режим , активируемый вручную аргументом manual=True
, использует внутренние проценты для отслеживания прогресса. Это позволяет вам получить полный контроль над положением штанги. Обычно он используется для мониторинга процессов, которые сообщают вам только о проценте завершения, или для создания некоторых случайных специальных эффектов.
Вы можете использовать его напрямую с alive_bar
или через config_handler
, и он позволяет отправлять проценты в обработчик bar()
! Например, чтобы установить завершение на 15%, просто вызовите bar(0.15)
— что равно 15/100.
Здесь вы также можете указать total
. Если вы это сделаете, alive-progress
автоматически определит внутренний счетчик и, таким образом, сможет предложить вам все те же виджеты, которые доступны в автоматическом режиме!
Если вы не укажете total
, вы, по крайней мере, получите приблизительные версии виджетов пропускной способности и ETA, рассчитанные как «%/s» (процент в секунду) и до 100% соответственно. Ни один из них не очень точен, но это лучше, чем ничего.
Когда указано total
, все круто:
режим | прилавок | процент | пропускная способность | расчетное время прибытия | переполнение/недополнение |
---|---|---|---|---|---|
авто | ✅ (галочка пользователя) | ✅ (предполагаемый) | ✅ | ✅ | ✅ |
руководство | ✅ (предполагаемый) | ✅ (набор пользователя) | ✅ | ✅ | ✅ |
В противном случае приходится идти на некоторые компромиссы:
режим | прилавок | процент | пропускная способность | расчетное время прибытия | переполнение/недополнение |
---|---|---|---|---|---|
неизвестный | ✅ (галочка пользователя) | ✅ | |||
руководство | ✅ (набор пользователя) | ✅ |
Но на самом деле понять это просто: вам не нужно думать о том, какой режим вам использовать!
total
, если она у вас есть, и используйте manual
если оно вам нужно!Вот и все! Он просто будет работать как можно лучше! ? о/
bar()
Обработчики bar()
поддерживают как относительную, так и абсолютную семантику, в зависимости от режима:
bar()
чтобы увеличить счетчик на единицу, или отправить любое другое приращение, например bar(200)
для увеличения на 200 сразу;они даже поддерживают
bar(0)
иbar(-5)
для хранения или уменьшения при необходимости!
bar(0.35)
чтобы индикатор мгновенно подскочил до 35% прогресса.Оба режима позволяют вам проявить творческий подход! Поскольку вы можете просто мгновенно переместить штангу в любое желаемое положение, вы можете:
- заставить его двигаться назад — например, чтобы графически отобразить тайм-аут чего-либо;
- создавать специальные эффекты — например, для имитации какого-либо аналогового датчика реального времени.
Вы можете вызывать bar()
столько раз, сколько захотите! Частота обновления терминала всегда будет асинхронно рассчитываться в соответствии с текущей пропускной способностью и прогрессом, поэтому вы не рискуете загружать терминал большим количеством обновлений, чем необходимо.
В любом случае, чтобы получить текущий счетчик/процент, просто вызовите bar.current
:
Наконец, обработчик bar()
использует уникальную возможность автоматического режима: просто вызовите bar(skipped=True)
или bar(N, skipped=True)
чтобы использовать его. Если для параметра skipped
установлено значение= True
, связанные элементы исключаются из вычислений пропускной способности, что предотвращает неточное влияние пропущенных элементов на расчетное время прибытия.
Поддерживать проект с открытым исходным кодом сложно и отнимает много времени, и я вложил в это много ❤️ и усилий.
Если вы оценили мою работу, вы можете поддержать меня пожертвованием! Спасибо ?
У выставки showtime
есть необязательный аргумент для выбора шоу: Show.SPINNERS
(по умолчанию), Show.BARS
или Show.THEMES
, обязательно взгляните на них! ;)
from alive_progress . styles import showtime , Show
showtime ( Show . BARS )
showtime ( Show . THEMES )
Примечание. Не обращайте внимания на путь на анимированном GIF-изображении ниже, правильный путь указан выше. Создание этих длинных гифок занимает очень много времени, поэтому я не могу создавать новые при каждом изменении. Спасибо за понимание.
И одна тема (? новая в 2.0):
Выставка showtime
также допускает некоторые варианты настройки:
Например, чтобы получить морское шоу, вы можете showtime(pattern='boat|fish|crab')
:
Вы также можете получить доступ к этим шоу с помощью сокращений
show_bars()
,show_spinners()
иshow_themes()
!
Также есть небольшая утилита
print_chars()
, которая поможет найти этот классный символ для размещения в ваших настроенных счетчиках и полосах или определить, поддерживает ли ваш терминал символы Юникода.
Есть несколько вариантов настройки как внешнего вида, так и поведения!
Все они могут быть установлены как непосредственно в alive_bar
, так и глобально в config_handler
!
Это параметры — значения по умолчанию в скобках:
title
: необязательный, всегда видимый заголовок панели.length
: [ 40
] количество столбцов для отображения анимированного индикатора выполнения.max_cols
: [ 80
] максимальное количество столбцов, которое можно использовать, если его невозможно получить, как в Jupyter.spinner
: стиль счетчика, который будет отображаться рядом с панелью.bar
: стиль панели, который будет отображаться в известных режимах.unknown
: стиль панели, который будет отображаться в неизвестном режиме.theme
: [ 'smooth'
] набор соответствующих счетчиков, полосок и неизвестныхforce_tty
: [ None
] принудительно включает или выключает анимацию или согласно tty (подробнее здесь)file
: [ sys.stdout
] используемый файловый объект: sys.stdout
, sys.stderr
или аналогичный TextIOWrapper
disable
: [ False
] если True, полностью отключает весь вывод, не устанавливайте перехватчикиmanual
: [ False
] установлено для ручного управления положением панели.enrich_print
: [ True
] дополняет print() и протоколирует сообщения позицией бара.enrich_offset
: [ 0
] смещение, применяемое к rich_printreceipt
: [ True
] печатает окончательную красивую квитанцию, отключается, если Falsereceipt_text
: [ False
] установлено для повтора последнего текстового сообщения в окончательной квитанции.monitor
(bool|str): [ True
] настраивает виджет монитора 152/200 [76%]
{count}
, {total}
и {percent}
чтобы настроить ееelapsed
(bool|str): [ True
] настраивает виджет прошедшего времени in 12s
{elapsed}
чтобы настроить ееstats
(bool|str): [ True
] настраивает виджет статистики (123.4/s, eta: 12s)
{rate}
и {eta}
чтобы настроить ееmonitor_end
(bool|str): [ True
] настраивает виджет монитора в окончательной квитанции.monitor
.elapsed_end
(bool|str): [ True
] настраивает виджет прошедшего времени в окончательной квитанции.elapsed
stats_end
(bool|str): [ True
] настраивает виджет статистики в окончательной квитанции.{rate}
чтобы настроить ее (не имеет отношения к статистике)title_length
: [ 0
] фиксирует длину заголовков или 0 для неограниченной длины.spinner_length
: [ 0
] устанавливает длину счетчика или 0
для ее естественной длины.refresh_secs
: [ 0
] принудительно устанавливает период обновления, 0
— это реактивная визуальная обратная связь.ctrl_c
: [ True
] если False, отключает CTRL+C (фиксирует его)dual_line
: [ False
] если True, текст помещается под панелью.unit
: любой текст, обозначающий ваши объекты.scale
: масштабирование, применяемое к единицам измерения: None
, SI
, IEC
или SI2
False
или ''
-> None
, True
-> SI
, 10
или '10'
-> SI
, 2
или '2'
-> IEC
precision
: [ 1
] сколько десятичных знаков отображается при масштабировании И есть еще один, который можно установить только локально в контексте alive_bar
:
calibrate
: максимальная теоретическая пропускная способность для калибровки скорости анимации (подробнее здесь) Чтобы установить их локально, просто отправьте их в качестве аргументов ключевого слова в alive_bar
:
with alive_bar ( total , title = 'Processing' , length = 20 , bar = 'halloween' ) as bar :
...
Чтобы использовать их глобально, отправьте их в config_handler
, и любой alive_bar
созданный после этого, будет включать эти параметры! И вы можете смешивать и сопоставлять их, локальные параметры всегда имеют приоритет над глобальными:
from alive_progress import config_handler
config_handler . set_global ( length = 20 , spinner = 'wait' )
with alive_bar ( total , bar = 'blocks' , spinner = 'twirls' ) as bar :
# the length is 20, the bar is 'blocks' and the spinner is 'twirls'.
...
Да, вы можете собрать свои собственные спиннеры! И это легко!
Я создал множество спецэффектов, так что вы можете комбинировать их так, как захотите! Есть кадры, прокрутка, подпрыгивание, последовательные, боковые и задержанные спиннеры! Проявите творческий подход! ?
Анимации спиннеров создаются с помощью очень продвинутых генераторных выражений, находящихся глубоко внутри нескольких слоев метафабрик, фабрик и генераторов?!
alive_bar
, так и в config_handler
;Эти генераторы способны выполнять несколько различных циклов анимации в зависимости от поведения спиннера, например, прыгающий спиннер может выполнить один цикл, чтобы плавно перенести объект на сцену, затем неоднократно перемещать его до другой стороны, а затем плавно исчезать со сцены = > И это всё только один цикл! Затем за ним может последовать еще один цикл, чтобы повторить все заново, но в обратном порядке! А прыгающие спиннеры также принимают разные и чередующиеся шаблоны как в правом, так и в левом направлениях, что заставляет их генерировать декартово произведение всех комбинаций, возможно, производя десятки разных циклов, пока они не начнут их повторять! ?
И это еще, я думаю, одно из самых впечатляющих достижений, которые я получил в этой системе анимации (помимо самого компилятора спиннера)... Они дают больше кадров анимации только до тех пор, пока текущий цикл не исчерпается, а затем они останавливаются ! Да, следующий цикл еще не начался! Такое поведение создает естественные перерывы именно в нужных местах, где анимация не прерывается, поэтому я могу плавно связываться с любой другой анимацией, которую захочу!
Это имеет множество интересных последствий: циклы могут иметь разное количество кадров, разную длину экрана, их не нужно синхронизировать, они могут создавать длинные разные последовательности сами по себе, они могут совместно воспроизводить циклы последовательно или параллельно, и я может удивить вас, отображая одновременно несколько совершенно разных анимаций без каких-либо помех!
Они как будто были... живы !! ?
==> Да, отсюда и название этого проекта!
Теперь эти генераторы циклов и кадров полностью загодя потребляются компилятором Spinner ! Это очень крутой новый процессор, который я создал в рамках проекта Cell Architecture , чтобы все эти анимации работали даже при наличии широких символов или сложных кластеров графем! Было очень сложно заставить эти кластеры плавно входить и выходить из кадров, не допуская при этом нарушения кодировки Unicode и особенно сохраняя свою первоначальную длину во всех кадрах! Да, несколько символов подряд могут представлять совершенно другой символ, поэтому их нельзя разделить! Они должны входить и выходить из кадра всегда вместе, все одновременно, иначе графема вообще не появится (например, эмодзи)!! Войдите в компилятор Spinner ......
Это сделало возможными невероятные вещи!! Поскольку этот компилятор заранее генерирует все данные кадра счетчика:
Итак, я могу просто собрать всю готовую к воспроизведению анимацию и покончить с этим, вообще без накладных расходов во время выполнения ! ?
Кроме того, скомпилировав и сохранив полные данные кадра, я мог бы создать несколько команд для рефакторинга этих данных, таких как изменение форм, замена символов, добавление визуальных пауз (повторение кадров), создание эффектов подпрыгивания по требованию для любого контента и даже транспонирование циклов. с рамками!!
Но как увидеть эти эффекты? Эффект, который вы создали, выглядит хорошо? Или это работает не так, как вы думали? ДА, теперь вы можете видеть все сгенерированные циклы и кадры аналитически, в очень красивом исполнении!!
Мне нравится то, чего я здесь достиг?, Это, наверное, самый красивый инструмент, который я когда -либо создавал ... вот check
инструмент !!
Это здорово, если я сам так скажу, не так ли? И очень сложная часть программного обеспечения, которым я горжусь, взгляните на его код, если хотите.
И check
инструмент намного мощнее! Например, вы можете увидеть Codepoints рамки !!! И, возможно, взгляните на то, почему эта версия была такой, очень сложной и сложной, чтобы сделать ...
Красным вы видите кластеры графем, которые занимают одно или два «логические позиции», независимо от их фактических размеров ... это «ячейки» новой клеточной архитектуры ...
Посмотрите, как круто представлен флаг смайликов:
Флаг, кажется, движется так плавно, потому что он использует «полу-характер»! Поскольку это широкий символ, alive-progress
знает, что он будет отображаться с «двумя видимыми очагами», и анимации рассматривают это, но составляют пространства, которые занимают только один. Когда кто -то использует смешанный фон, ситуация гораздо сложнее ...
Типы заводов, которые я создал:
frames
: рисует любую последовательность символов по желанию, которые будут воспроизведены кадром по кадру в последовательности;scrolling
: генерирует плавный поток с одной стороны к другой, прячась или обертываясь на невидимых границах - позволяет использовать субъектов по одному, генерируя несколько циклов различных символов;bouncing
: похоже на scrolling
, но заставляет анимацию отскочить назад к началу, прячаясь или сразу же подпрыгивая на невидимых границах;sequential
получите несколько заводов и разыгрывайте их один после другого последовательно! позволяет смешать их или нет;alongside
несколько заводов и играть на них одновременно, зачем выбирать, когда вы можете их все?! Позволяет выбрать стержень анимации;delayed
: Получите любую другую фабрику и скопируйте его несколько раз, все чаще пропускает некоторые кадры на каждом из них! Очень крутые эффекты сделаны здесь!Для получения более подробной информации, пожалуйста, посмотрите на их Docstrings, которые очень полны.
Настройка баров далеко не так вовлечена. Допустим, они «непосредственные», пассивные объекты. Они не поддерживают анимацию, то есть они всегда будут генерировать одно и то же исполнение, учитывая одинаковые параметры. Помните, что прядильщики - это бесконечные генераторы, способные генерировать длинные и сложные последовательности.
Что ж, бары также имеют мета -завод, используйте закрытие для хранения параметров стиля и получения дополнительных рабочих параметров, но тогда фактическая фабрика не может генерировать какой -либо контент сам по себе. Ему все еще нужен дополнительный параметр, номер с плавающей запятой от 0 до 1, что является процентным дозором для самостоятельного отображения.
alive_bar
вычисляет этот процент автоматически в зависимости от счетчика и общего числа, но вы можете отправить его самостоятельно вmanual
режиме!
Бэры также не имеют компилятора стержня, но они предоставляют контрольный инструмент !! ?
Вы можете даже смешать и сочетать широкие уборки и обычные карты, как в Spinners! (И все сохраняется идеально выровненным?)
Используйте инструменты проверки для вашего сердца! У них еще больше вкусностей, ожидающих вас, даже анимации в реальном времени!
Создайте самую дикую и крутую анимацию, которую вы можете, и отправьте их мне!
Я думаю о создании какого-то пакетаcontrib
, с помощью пользователя, связанных с прядильщиками и барами!
Вау, если вы прочитали все здесь, вы должны иметь звуковые знания об использовании alive-progress
! ?
Но приготовьтесь к себе, потому что есть еще больше, захватывающие вещи впереди!
Поддержание проекта с открытым исходным кодом-это сложно и отнимает много времени, и я вложил в это много усилий.
Если вы оценили мою работу, вы можете поддержать меня с пожертвованием! Спасибо ?
О, ты хочешь приостановить это вообще, я слышу? Это удивительная новая концепция, нигде не найденная.
С этим вы можете действовать на некоторые предметы вручную , по желанию, прямо в середине продолжающейся обработки !!
Да, вы можете вернуться к приглашению и исправить, изменить, отправлять вещи, и бар просто «запомнит», где это было ...
Предположим, вам нужно примирить платежные транзакции (были там, сделали это). Вам необходимо итерацию над тысячами, как -то обнаружить неисправные и исправить их. Это исправление не является простым и не детерминированным, вам нужно изучить каждого, чтобы понять, что делать. Они могут пропустить получателя, или иметь неправильную сумму, или не синхронизировать с сервером и т. Д., Трудно даже представить все возможности.
Как правило, вам придется разрешить процесс обнаружения до завершения, добавив в список каждого несоответствия, которое он находит и ожидает, потенциально долго, пока вы, наконец, не сможете начать их исправлять ... вы, конечно, смягчить это, обрабатывая кусочки , или печатать их и действовать через другую оболочку и т. Д., Но у них есть свои недостатки ...?
Теперь есть лучший способ! Просто сделайте паузу фактического процесса обнаружения на некоторое время! Тогда вам просто нужно подождать, пока не найдена следующая ошибка, и действовать почти в режиме реального времени!
Чтобы использовать механизм паузы, вам просто нужно написать функцию, чтобы код мог yield
элементы, с которыми вы хотите взаимодействовать. Скорее всего, вы уже используете один в своем коде, но в оболочке ipython
или в другой реплике вы, вероятно, нет. Так что просто оберните код отладки в функцию, затем введите в контексте bar.pause()
!!
def reconcile_transactions ():
qs = Transaction . objects . filter () # django example, or in sqlalchemy: session.query(Transaction).filter()
with alive_bar ( qs . count ()) as bar :
for transaction in qs :
if faulty ( transaction ):
with bar . pause ():
yield transaction
bar ()
Вот и все! Это так просто! o/
Теперь запустите gen = reconcile_transactions()
чтобы создать генератор, и всякий раз, когда вы хотите следующую неисправную транзакцию, просто позвоните next(gen, None)
! Я люблю это...
Бар alive-progress
начнется и работает как обычно, но как только будет обнаружено любое несоответствие, бар будет паузой, отключает потоку обновления и запомнив его точное состояние и даст вам транзакцию непосредственно по подсказке! Это почти волшебство! ?
In [11]: gen = reconcile_transactions()
In [12]: next(gen, None)
|█████████████████████ | 105/200 [52%] in 5s (18.8/s, eta: 4s)
Out[12]: Transaction<#123>
Затем вы можете осмотреть транзакцию с обычным _
ярлыком ipython
(или просто напрямую назначить ее с t = next(gen, None)
), и все готово это исправить!
Когда вы закончите, просто реактивируйте планку с тем же next
вызовом, что и раньше !! Бар вновь появляется, снова включает все и продолжается, как будто он никогда не останавливался !! ОК, это волшебство?
In [21]: next(gen, None)
|█████████████████████ | ▁▃▅ 106/200 [52%] in 5s (18.8/s, eta: 4s)
Промойте и повторите до появления окончательной квитанции, и больше не будет неисправных транзакций. ?
Итак, вам нужно отслеживать фиксированную работу, без каких -либо петлей, верно?
Это сработает наверняка! Вот наивный пример (у нас будет лучше через мгновение):
with alive_bar ( 4 ) as bar :
corpus = read_file ( file )
bar () # file was read, tokenizing
tokens = tokenize ( corpus )
bar () # tokens generated, processing
data = process ( tokens )
bar () # process finished, sending response
resp = send ( data )
bar () # we're done! four bar calls with `total=4`
Это наивно, потому что он предполагает, что все шаги занимают одинаковое количество времени, но на самом деле каждый из них может занять совсем другое время. Подумайте read_file
и tokenize
может быть чрезвычайно быстрым, что заставляет процент взлететь до 50%, а затем долго останавливаться на шаге process
... вы понимаете, это может разрушить пользовательский опыт и создать очень вводящую в заблуждение ETA.
Чтобы улучшить это, вам нужно соответствующим образом распределить проценты шагов! С тех пор, как вы рассказали alive_bar
было четыре шага, когда первый был завершен, он понял, что 1/4 или 25% всей обработки была завершена ... Таким Увеличьте процент бара на нужную сумму на каждом шаге!
Вы можете использовать мой другой проект с открытым исходным кодом, чтобы легко измерить эти продолжительности! Просто попробуйте смоделировать с некоторыми репрезентативными входами, чтобы получить лучшие результаты. Что -то вроде:
from about_time import about_time
with about_time () as t_total : # this about_time will measure the whole time of the block.
with about_time () as t1 : # the other four will get the relative timings within the whole.
corpus = read_file ( file ) # `about_time` supports several calling conventions, including one-liners.
with about_time () as t2 : # see its documentation for more details.
tokens = tokenize ( corpus )
with about_time () as t3 :
data = process ( tokens )
with about_time () as t4 :
resp = send ( data )
print ( f'percentage1 = { t1 . duration / t_total . duration } ' )
print ( f'percentage2 = { t2 . duration / t_total . duration } ' )
print ( f'percentage3 = { t3 . duration / t_total . duration } ' )
print ( f'percentage4 = { t4 . duration / t_total . duration } ' )
Вот иди! Теперь вы знаете относительные сроки всех шагов и можете использовать их для улучшения вашего исходного кода! Просто получите кумулятивные времена и поместите их в ручной режим alive_bar
!
Например, если время, которое вы обнаружили, составляли 10%, 30%, 20%и 40%, вы бы использовали 0,1, 0,4, 0,6 и 1,0 (последний всегда должен быть 1,0):
with alive_bar ( 4 , manual = True ) as bar :
corpus = read_big_file ()
bar ( 0.1 ) # 10%
tokens = tokenize ( corpus )
bar ( 0.4 ) # 30% + 10% from previous steps
data = process ( tokens )
bar ( 0.6 ) # 20% + 40% from previous steps
resp = send ( data )
bar ( 1. ) # always 1. in the last step
Вот и все! Пользовательский опыт и ETA должны быть значительно улучшены сейчас.
Да, вы можете калибровать скорость спиннера!
Барсы alive-progress
имеют прохладную визуальную обратную связь с текущей пропускной способностью, поэтому вы можете увидеть , насколько быстро ваша обработка, поскольку прядильщик работает быстрее или медленнее.
Чтобы это произошло, я собрал и внедрил несколько кривых FPS, чтобы эмпирически найти, какой из них дал лучшее ощущение скорости:
(Интерактивная версия [здесь] (https://www.desmos.com/calculator/ema05elsux)))
На графике показаны логарифмические (красные), параболические (синие) и линейные (зеленые) кривые, с которыми я начал. Это была нелегкая задача, я сделал десятки тестов и никогда не нашел такую, которая действительно вдохновила на то, что я искал. Лучший, казалось, был логарифмическим, но он плохо реагировал с небольшими числами. Я знаю, что могу заставить его работать с несколькими поворотами для этих небольших чисел, поэтому я много экспериментировал и отрегулировал логарифмическую кривую (пунктирное оранжевое), пока я наконец не нашел поведение, которое я ожидал! Это тот, который, казалось, обеспечивал лучшие всеобъемлющие воспринимаемые изменения скорости на протяжении всего спектра от нескольких до миллиардов ... это та кривая, с которой я установил, и она используется во всех режимах и условиях. В будущем, и если кто -то найдет это полезным, эта кривая может быть настраиваемой.
Что ж, калибровка alive-progress
по умолчанию составляет 1 000 000 в ограниченных режимах, то есть, для бара требуется 1 миллион итераций в секунду, чтобы обновить себя со скоростью 60 кадров в секунду. В ручном режиме это 1,0 (100%). Оба обеспечивают обширный эксплуатационный диапазон и, как правило, работают довольно хорошо.
Например, взгляните на эффект, который обладают этими совершенно разными калибровками, запустив тот же код с той же скоростью! Обратите внимание на ощущение, что прядильщик передает пользователю, идет ли эта обработка медленной или быстро? И помните, что это не только прядильщик, но и вся линия, в комплекте с барной версией и всеми виджетами, так что все становится более гладким или вялым:
Итак, если ваша обработка едва ли достигает 20 пунктов в секунду, и вы думаете, что
alive-progress
делает вялый, вы можете увеличить это чувство скорости, калибруя его, скажем,40
, и она будет работать быстрее ... это быстрее ... это Лучше всегда оставлять немного запаса и откалибровать его до чего -то на 50% и 100% больше, а затем настраивайте его оттуда, чтобы найти тот, который вам нравится больше всего! :)
Откажится ли эти удивительные анимации анимации alive-progress
?
Pycharm потрясающий, мне это нравится! Но я никогда не пойму, почему они отключили эмуляцию терминала по умолчанию ... если вы используете выходную консоль Pycharm, пожалуйста, включите это во всех ваших конфигурациях.
Я даже рекомендую вам перейти в
File
>New Projects Setup
>Run Configuration Templates
, выберитеPython
, а также включить его там, поэтому любые новые, которые вы создаете, уже будут иметь этот набор.
В дополнение к этому, некоторые терминалы сообщают о себе как «неинтерактивные», например, когда заканчивается реальная терминал (например, pycharm и jupyter), в Shell Pipelines ( cat file.txt | python program.py
) или в фоновом режиме. процессы (не подключены к TTY).
Когда alive-progress
оказывается в неинтерактивном терминале, он автоматически отключает все виды анимации, печатая только окончательный квитанция. Это сделано для того, чтобы избежать того, чтобы как испортить вывод трубопровода, так и спамить файл журнала тысячами обновлений alive-progress
.
Итак, когда вы знаете, что это безопасно, вы можете заставить их увидеть, alive-progress
во всей ее славе! Вот аргумент force_tty
:
with alive_bar ( 1000 , force_tty = True ) as bar :
for i in range ( 1000 ):
time . sleep ( .01 )
bar ()
Принятые значения:
force_tty=True
-> Всегда включает анимацию и автоматические ноутбуки Jupyter!force_tty=False
-> всегда отключает анимацию, сохраняя только окончательную квитанциюforce_tty=None
(по умолчанию) -> обнаружение Auto, в соответствии с состоянием терминала TTY Вы также можете установить его по всей системе с помощью config_handler
, поэтому вам больше не нужно передавать его вручную.
Обратите внимание, что консоль Pycharm и записные тетради Jupyter в значительной степени инструментальны и, следовательно, имеют гораздо больше накладных расходов, поэтому результат может быть не таким плавным, как вы ожидаете. Кроме того, ноутбуки Jupyter не поддерживают коды побега ANSI, поэтому мне пришлось разработать некоторые обходные пути, чтобы подражать таким функциям, как «Очистить линию» и «ясно из курсора» ... чтобы увидеть плавную и плавную анимацию
alive_bar
, как я собирался , всегда предпочитаю полноценный терминал.
alive-progress
не было никакой зависимости. Теперь у него есть два: один-это время (еще один мой интересный проект, если я так говорю), который используется для отслеживания времени, которое необходимо для компиляции Spinner, и для создания его удобства для человека. Другой - это Grapheme, чтобы обнаружить разрывы графем кластеров (я открыл проблему, спрашивающую о будущем и правильности, и автор гарантирует, что он намерен обновить проект по каждой новой версии Unicode);alive-progress
не было ни одного класса Python! Теперь у него есть несколько крошечных по очень конкретным причинам (измените Callables, итераторные адаптеры и некоторые дескрипторы для виджетов alive_bar
).alive_bar
- это просто функция! Хотя, честно говоря, это «просто» функция, в которой я динамически подключаю несколько закрытий изнутри (помните, что функции Python имеют __dict__
точно так же, как классы?). alive_bar
замечает изменения размера терминала, но просто усекает линию соответственно).contrib
, чтобы позволить простому способу поделиться прохладными прядильщиками и полосами от пользователей.skipped
предметамиstderr
и других файлов вместо stdout
monitor
, elapsed
, stats
Завершите здесь.
alive_it
, обнаружение вложенного использования Alive_progress и добавьте более четкое сообщение об ошибкеalive_it
skipped
элементами, новая настройка конфигурации max_cols
для Юпитера, исправляя размер терминала при использовании STDERR, официально поддерживает Python 3.11sys.stderr
и других файлов вместо sys.stdout
, сгладили оценку скорости, больше запросов в в настоящее время запущенные виджеты ' Данные, система помощи в ошибках конфигурацииmonitor
, elapsed
и stats
виджеты Core, New monitor_end
, elapsed_end
и виджеты stats_end
, лучшая поддержка CTRL+C, что делает alive_bar
остановкуclick.echo()
Поддержка; Более высокая производительность; более безопасное обнаружение терминальных колонн; bar.current
действует как собственность; Снимите Python 3.6.check()
инструменты как в спиннерах, так и в барах; Батовые и прядильщики двигатели обновляются; Новые режимы анимации в вместе и последовательные спиннеры; новые строительные прядильщики, бары и темы; Динамическое шоу с темами, защита прокрутки и шаблоны фильтра; Улучшение журнала для файлов; Несколько новых параметров конфигурации для настройки внешнего вида; Новый итераторный адаптер alive_it
; использует time.perf_counter()
. Требуется Python 3.6+ (и официально поддерживает Python 3.9 и 3.10)bar.current()
Метод; Новые линии печатаются на ванильной питоне; Бар усечен до 80 Chars в Windowsbar.text()
Метод, чтобы установить ситуационные сообщения в любое время, без увеличения позиции (оправдывает «текстовый» параметр в bar()
); Оптимизация производительностиbackground
параметр вместо blank
, который принимает строки произвольного размера и остается фиксированным на заднем плане, имитируя стержень, идущий «над ним»show_spinners
и show_bars
, новый утилита print_chars
, show_bars
получают некоторые расширенные демонстрации (попробуйте еще раз!) alive_progress
всегда будет пытаться не отставать от Python, поэтому, начиная с версии 2.0, я остановлюсь поддержкой всех версий Python, которые входят в EOL. Смотрите их график здесь.
Но не волнуйтесь, если вы пока не можете мигрировать: версии alive_progress
являются многолетними, так что продолжайте использовать тот, который работает для вас, и вы хороши.
Я просто настоятельно рекомендую установить старые пакеты alive_progress
в файле TEDS.TXT со следующими форматами. Они всегда будут получать последние релизы сборки до данной версии, поэтому, если я когда -нибудь выпущу исправления ошибок, вы получите их тоже.
❯ pip install -U " alive_progress<2 "
❯ pip install -U " alive_progress<2.2 "
❯ pip install -U " alive_progress<3.2 "
Это программное обеспечение лицензировано по лицензии MIT. Полный текст лицензии см. в файле LICENSE в верхнем каталоге распространения.
Поддержание проекта с открытым исходным кодом-это сложно и отнимает много времени, и я вложил в это много усилий.
Если вы оценили мою работу, вы можете поддержать меня с пожертвованием! Спасибо ?