هل سبق لك أن تساءلت أين وصلت عملية المعالجة المطولة، ومتى ستنتهي؟ هل تضغط عادةً على RETURN
عدة مرات للتأكد من عدم تعطله، أو عدم تجميد اتصال SSH؟ هل فكرت يومًا أنه سيكون من الرائع أن تكون قادرًا على إيقاف بعض العمليات مؤقتًا دون أي متاعب، والعودة إلى مطالبة Python لإصلاح بعض العناصر يدويًا، ثم استئنافها بسلاسة ؟ فعلتُ...
لقد بدأت شريط التقدم الجديد هذا بالتفكير في كل ذلك، انظر إلى التقدم الحي ! ؟
تقديم أحدث مفهوم في أشرطة التقدم لبيثون! يعتبر alive-progress
فئة خاصة به، مع مجموعة من الميزات الرائعة التي تميزه. فيما يلي بعض النقاط البارزة:
check()
قوية جدًا تساعدك على تصميم الرسوم المتحركة الخاصة بك! يمكنك أن ترى كيف ستبدو الإطارات ودورات الرسوم المتحركة التي تم إنشاؤها، وتنفجر على شاشتك، ويمكنك حتى رؤيتها حية قبل التثبيت في alive-progress
! إنها أروع أداة في العالم! أطلق العنان لإبداعك! يتطور هذا الملف التمهيدي دائمًا، لذا قم بإلقاء نظرة أكثر شمولاً من وقت لآخر... قد تجد تفاصيل جديدة رائعة في أقسام أخرى! ؟
alive-progress
bar()
المختلفة بعد حوالي عام من الاستقرار المطمئن، وصل alive-progress
الجديد أخيرًا!
الميزات والتحسينات الرئيسية هي:
bar()
مع 0
وحتى -N
لجعله يتراجع! مفيد عندما لا تتمكن من إحراز أي تقدم في التكرار أو تضطر إلى التراجع عن شيء ما!وأكثر!
enrich_offset
مخصصة لاستخدامها في الرسائل المطبوعة أو المسجلة، مما يسمح لك بالبدء بـ on 1:
أو المتابعة من حيث توقفت من الحسابات السابقة! تحديث رائع جدًا هنا! بالإضافة إلى تحسين الأمور وتحسين الدعم الطرفي، يدعم الآن alive-progress
استئناف العمليات الحسابية!
عند معالجة مجموعات بيانات ضخمة أو أشياء تستغرق وقتًا طويلاً، يمكنك إما استخدام دفعات أو تخزين النتائج الجزئية مؤقتًا. بعد ذلك، في حالة توقفه وإعادة تشغيله، سينتهي بك الأمر بتخطي كل العناصر التي تم إنجازها بالفعل بسرعة كبيرة، مما يجعل شريط alive_bar
يعتقد أنك تقوم بمعالجة آلاف العناصر في الثانية، وهو ما يؤدي بدوره إلى تدمير الوقت المتوقع للوصول تمامًا... ولكن ليس بعد الآن ! فقط أخبر 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
s! نعم، طلب الدعم هنا.وأخيرًا وليس آخرًا، تصميم أكثر صقلًا لتتمكن من الاستمتاع بتقدمك!
الآن، 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...
هناك أيضًا معلمة جديدة لوظيفة finalize
في alive_it
والتي تمكنك من تعيين عنوان و/أو نص الإيصال النهائي، ودعم التسجيل المحسن الذي يكتشف أدوات تسجيل البيانات المخصصة.
هذا كل شيء عن التخصيص؛ يمكن الآن تغيير الأدوات الأساسية:
monitor
elapsed
stats
لجعلها تبدو بأي طريقة تريدها!إنه أمر لا يصدق أن هذه السلاسل تدعم جميع ميزات تنسيق بايثون، لذلك يمكنك على سبيل المثال،
{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-loop، فسوف يستمر إلى التكرار التالي، والذي قد يكون أو لا يكون ما تريده...
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
!
لقد استغرق تطويره عامًا واحدًا، وأنا فخور جدًا بما أنجزته o/
.check()
جديدة وقوية ومصقولة تقوم بتجميع جميع الإطارات وعرضها بشكل جميل من جميع دورات الرسوم المتحركة للأقراص الدوارة والأشرطة! يمكنهم أيضًا تضمين بيانات الإطار الكاملة ونقاط التشفير الداخلية وحتى الرسوم المتحركة الخاصة بهم! ؟alive-progress
!alive_it
، الذي يقبل bar()
لك!نظرًا لأن هذا تغيير كبير في الإصدار، فلا يتم ضمان التوافق المباشر مع الإصدارات السابقة. إذا لم يعمل شيء ما في البداية، فما عليك سوى التحقق من الواردات الجديدة وتوقيعات الوظائف، ويجب أن تكون جاهزًا للبدء. يجب أن تظل جميع الميزات السابقة تعمل هنا! ؟
alive-progress
فقط قم بالتثبيت باستخدام النقطة:
❯ pip install alive-progress
إذا كنت تتساءل عن الأنماط المضمنة، فهذا هو showtime
! ;)
from alive_progress . styles import showtime
showtime ()
ملاحظة: يرجى تجاهل المسار الموجود في الصورة المتحركة أدناه، فالمسار الصحيح موجود أعلاه. يستغرق إنشاء هذه الصور المتحركة الطويلة وقتًا طويلاً، لذا لا يمكنني عمل صورة أخرى عند كل تغيير. شكرا لتفهمك.
لقد صنعت هذه الأنماط فقط لتجربة جميع مصانع الرسوم المتحركة التي أنشأتها، لكنني أعتقد أن بعضها انتهى به الأمر بشكل رائع جدًا! استخدامها في الإرادة، ومزجها لمحتوى قلبك!
هل تريد أن ترى أشرطة alive-progress
قيد التشغيل بشكل رائع في نظامك قبل تجربتها بنفسك؟
❯ python -m alive_progress.tools.demo
رائع، هاه؟؟ أدخل الآن ipython
REPL وجرب هذا:
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_it
=> محول التكرار alive_bar
!
ما عليك سوى لف العناصر الخاصة بك بها، ثم لفها كالمعتاد!
سوف يعمل الشريط فقط؛ الأمر بهذه البساطة!
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
الداخلي كيفما تريد.
الأوضاع الافتراضية هي تلقائية وغير معروفة ، والتي تستخدم عدادًا داخليًا لتتبع التقدم. يقومون بإحصاء عدد العناصر التي تمت معالجتها، ويستخدمونها لتحديث شريط التقدم وفقًا لذلك.
الوسيطة total
اختيارية. إذا قمت بتوفيره، يدخل الشريط في الوضع التلقائي . في هذا الوضع، يتم تتبع تقدم العملية تلقائيًا، وتتوفر جميع الأدوات التي يقدمها alive-progress
: الشريط الدقيق، والدوار، والنسبة المئوية، والعداد، والإنتاجية، ووقت الوصول المتوقع.
إذا لم تقم بتوفير total
، يدخل الشريط في وضع غير معروف . في هذا الوضع، يكون التقدم غير قابل للتحديد، وبالتالي فإن الوقت المتوقع للوصول، لذلك يتم تحريك شريط التقدم بالكامل بشكل مستمر. الأدوات المتاحة هي: الشريط المتحرك، والدوار، والعداد، والإنتاجية.
يعمل القرص الدوار الرائع بشكل مستقل تمامًا عن شريط الرسوم المتحركة، حيث يقوم كلاهما بتشغيل الرسوم المتحركة الخاصة بهما في نفس الوقت، مما يقدم عرضًا فريدًا في جهازك الطرفي! ؟
أخيرًا وليس آخرًا، يتمتع الوضع التلقائي بقدرة فريدة: وضع علامة على العناصر على أنها تم تخطيها، مما يجعل الإنتاجية ووقت الوصول المقدر أكثر دقة! المزيد عن ذلك لاحقًا.
يستخدم الوضع اليدوي ، الذي يتم تنشيطه يدويًا بواسطة manual=True
، نسبة مئوية داخليًا لتتبع التقدم. أنها تمكنك من الحصول على السيطرة الكاملة على موقف الشريط. يتم استخدامه عادةً لمراقبة العمليات التي تغذيك فقط بنسبة مئوية من الإنجاز، أو لإنشاء بعض المؤثرات الخاصة العشوائية.
يمكنك استخدامه مباشرةً مع alive_bar
أو عبر config_handler
، ويتيح لك إرسال النسب المئوية إلى معالج bar()
! على سبيل المثال، لتعيينه على نسبة اكتمال 15%، ما عليك سوى الاتصال bar(0.15)
— وهو 15/100.
يمكنك أيضًا تقديم total
هنا. إذا قمت بذلك، فسوف يستنتج alive-progress
تلقائيًا عدادًا داخليًا، وبالتالي سيكون قادرًا على أن يقدم لك نفس الأدوات المتوفرة في الوضع التلقائي!
إذا لم تقم بتوفير total
، فستحصل على الأقل على إصدارات تقريبية من عناصر واجهة المستخدم الخاصة بالإنتاجية ووقت الوصول المتوقع، والتي يتم حسابها كـ "%/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 )
ملاحظة: يرجى تجاهل المسار الموجود في الصورة المتحركة أدناه، فالمسار الصحيح موجود أعلاه. يستغرق إنشاء هذه الصور المتحركة الطويلة وقتًا طويلاً، لذا لا يمكنني عمل صورة أخرى عند كل تغيير. شكرا لتفهمك.
والمواضيع واحدة (؟ جديدة في 2.0):
يقبل معرض showtime
أيضًا بعض خيارات التخصيص:
على سبيل المثال، للحصول على عرض بحري، يمكنك showtime(pattern='boat|fish|crab')
:
يمكنك أيضًا الوصول إلى هذه العروض باستخدام الاختصارات
show_bars()
وshow_spinners()
وshow_themes()
!
هناك أيضًا أداة مساعدة صغيرة تسمى
print_chars()
، للمساعدة في العثور على هذا الحرف الرائع لوضعه في الأقراص الدوارة والأشرطة المخصصة، أو لتحديد ما إذا كان جهازك الطرفي يدعم أحرف Unicode.
هناك عدة خيارات لتخصيص المظهر والسلوك!
يمكن ضبطها جميعًا مباشرةً في alive_bar
أو عالميًا في config_handler
!
هذه هي الخيارات - القيم الافتراضية بين قوسين:
title
: عنوان شريط اختياري ومرئي دائمًاlength
: [ 40
] عدد الأعمدة لعرض شريط التقدم المتحركmax_cols
: [ 80
] الحد الأقصى لعدد الأعمدة الذي يجب استخدامه إذا لم يكن من الممكن جلبه، كما هو الحال في jupyterspinner
: نمط الدوار الذي سيتم عرضه بجوار الشريطbar
: نمط الشريط الذي سيتم عرضه في الأوضاع المعروفةunknown
: نمط الشريط الذي سيتم عرضه في الوضع غير المعروفtheme
: [ 'smooth'
] مجموعة من المطابقة الدوارة والشريطية وغير المعروفةforce_tty
: [ None
] يفرض تشغيل الرسوم المتحركة أو إيقافها أو وفقًا لـ tty (مزيد من التفاصيل هنا)file
: [ sys.stdout
] كائن الملف المطلوب استخدامه: sys.stdout
أو sys.stderr
أو TextIOWrapper
مشابهdisable
: [ False
] إذا كان صحيحًا، فسيتم تعطيل جميع المخرجات تمامًا، فلا تقم بتثبيت الخطافاتmanual
: تم ضبط [ False
] للتحكم في موضع الشريط يدويًاenrich_print
: [ True
] يُثري print() ويسجل الرسائل باستخدام موضع الشريطenrich_offset
: [ 0
] الإزاحة التي سيتم تطبيقها على rich_printreceipt
: [ True
] يطبع الإيصال النهائي الجميل، ويعطله إذا كان خطأreceipt_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
] إذا كان خطأ، يعطل 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 Compiler ! هذا معالج جديد رائع جدًا قمت بإنشائه ضمن جهد هندسة الخلية ، لجعل كل هذه الرسوم المتحركة تعمل حتى في حالة وجود أحرف واسعة أو مجموعات حروف معقدة! كان من الصعب للغاية جعل هذه المجموعات تدخل وتخرج من الإطارات بشكل تدريجي، بسلاسة، مع الحفاظ عليها من كسر ترميز Unicode وخاصة الحفاظ على أطوالها الأصلية في جميع الإطارات! نعم، يمكن أن تمثل عدة أحرف متتالية رمزًا آخر مختلفًا تمامًا، لذلك لا يمكن تقسيمها على الإطلاق! يجب عليهم الدخول والخروج من الإطار دائمًا معًا، مرة واحدة، وإلا فلن يظهر الحرف على الإطلاق (رمز تعبيري على سبيل المثال)!! أدخل مترجم سبينر ......
لقد جعل هذا من الممكن بعض الأشياء المذهلة !! نظرًا لأن هذا المترجم يقوم بإنشاء بيانات الإطار الدوار بالكامل مسبقًا:
لذلك، يمكنني فقط جمع كل ما هو جاهز لتشغيل الرسوم المتحركة والانتهاء منها، دون أي تكاليف تشغيل على الإطلاق!! ؟
أيضًا، من خلال تجميع بيانات الإطار الكاملة واستمرارها، يمكنني إنشاء عدة أوامر لإعادة معالجة تلك البيانات، مثل تغيير الأشكال، واستبدال الأحرف، وإضافة فترات توقف مؤقتة (تكرار الإطار)، وإنشاء تأثيرات مرتدة عند الطلب على أي محتوى، وحتى تبديل الدورات مع إطارات!!
ولكن كيف يمكنك رؤية هذه التأثيرات؟ هل يبدو التأثير الذي قمت بإنشائه جيدًا؟ أم أنها لا تعمل كما كنت تعتقد؟ نعم، الآن يمكنك رؤية جميع الدورات والإطارات التي تم إنشاؤها بشكل تحليلي، في عرض جميل جدًا !!
أحب ما حققته هنا؟ ، ربما تكون أجمل أداة قمت بإنشائها على الإطلاق ... ها أداة check
!!
إنه لأمر رائع إذا قلت ذلك بنفسي ، أليس كذلك؟ وبرامج معقدة للغاية أفتخر بها ، ألق نظرة على الكود الخاص به إذا كنت ترغب في ذلك.
وأداة check
أكثر قوة! على سبيل المثال ، يمكنك رؤية نقاط الترميز للإطارات !!! وربما يكون لديك لمحة عن سبب وجود هذا الإصدار ، صعب للغاية ومعقد لتكوينه ...
في اللون الأحمر ، ترى مجموعات Grapheme ، التي تشغل "مواقع منطقية" واحدة أو اثنين ، بغض النظر عن أحجامها الفعلية ... هذه هي "خلايا" بنية الخلية الجديدة ...
انظروا إلى أي مدى يتم تمثيل علم الرموز التعبيرية:
يبدو أن العلم يتحرك بسلاسة لأنه يستخدم "نصف الشحنات"! نظرًا لأنها شحنة واسعة ، alive-progress
يعرف أنه سيتم تقديمه بـ "اثنين من المشاربين المرئيين" ، والرسوم المتحركة تعتبر هذا ، ولكنها تتألف مع المساحات ، التي تشغل واحدة فقط. عندما يستخدم المرء خلفيات مختلطة ، يكون الموقف أكثر تعقيدًا ...
أنواع المصانع التي أنشأتها هي:
frames
: يرسم أي سلسلة من الأحرف في الإرادة ، والتي سيتم تشغيلها إطارًا حسب الإطار بالتسلسل ؛scrolling
: يولد تدفقًا سلسًا من جانب إلى آخر ، يختبئ خلفه أو التفاف على حدود غير مرئية - يسمح باستخدام الموضوعات واحدة تلو الأخرى ، وتوليد عدة دورات من الشخصيات المتميزة ؛bouncing
: على غرار scrolling
، ولكن يجعل الرسوم المتحركة ترتد إلى البداية ، وتختبئ خلفها أو ترتد على الفور على الحدود غير المرئية ؛sequential
الحصول على حفنة من المصانع ولعبها واحدة تلو الأخرى بالتتابع! يسمح بتقاطعها أم لا ؛alongside
الحصول على حفنة من المصانع ولعبها جنبًا إلى جنب في وقت واحد ، لماذا تختار متى يمكنك الحصول عليها جميعًا؟! يسمح باختيار محور الرسوم المتحركة.delayed
: احصل على أي مصنع آخر ونسخه عدة مرات ، وتخطي بعض الإطارات بشكل متزايد على كل واحدة! يتم صنع تأثيرات رائعة جدا هنا!لمزيد من التفاصيل ، يرجى إلقاء نظرة على المستندات الخاصة بهم ، والتي تكتمل جدًا.
تخصيص الحانات ليس في أي مكان بالقرب من ذلك. دعنا نقول أنهم "فوريون" ، أشياء سلبية. إنهم لا يدعمون الرسوم المتحركة ، أي أنها ستنشئ دائمًا نفس التسليم بالنظر إلى نفس المعلمات. تذكر أن المغازل هي مولدات لا حصر لها ، قادرة على توليد تسلسلات طويلة ومعقدة.
حسنًا ، تحتوي القضبان أيضًا على مصنع للوصول ، وتستخدم عمليات الإغلاق لتخزين معلمات التصميم ، وتلقي معلمات تشغيل إضافية ، ولكن بعد ذلك لا يمكن للمصنع الفعلي إنشاء أي محتوى بمفرده. لا يزال يحتاج إلى معلمة إضافية ، رقم نقطة عائمة بين 0 و 1 ، وهي النسبة المئوية لتقديم نفسها.
يقوم
alive_bar
بحساب هذه النسبة تلقائيًا بناءً على العداد والإجمالي ، ولكن يمكنك إرسالها بنفسك عندما تكون في الوضعmanual
!
القضبان أيضا لا تحتوي على مترجم شريط ، لكنها توفر أداة التحقق !! ؟
يمكنك حتى خلط وتطابق مع شورس واسعة وتشيرات عادية كما هو الحال في المغازل! (وكل شيء يظل محاذاة تمامًا؟)
استخدم أدوات الاختيار لمحتوى قلبك !! لديهم المزيد من الأشياء الجيدة في انتظارك ، حتى الرسوم المتحركة في الوقت الفعلي!
قم بإنشاء أجمل وأروع الرسوم المتحركة التي يمكنك إرسالها إلي!
أفكر في إنشاء نوع من حزمةcontrib
، مع المغازل والبارات التي يتم توزيعها على المستخدم!
واو ، إذا كنت قد قرأت كل شيء حتى هنا ، فيجب أن يكون لديك الآن معرفة سليمة حول استخدام alive-progress
! ؟
لكن تستعيد نفسك لأن هناك المزيد من الأشياء المثيرة للانتظار!
الحفاظ على مشروع مفتوح المصدر صعب ويستغرق وقتًا طويلاً ، وقد بذلت الكثير من الجهد في هذا.
إذا كنت تقدر عملي ، فيمكنك دعمًا لي بالتبرع! شكرًا لك ؟
أوه ، هل تريد إيقافها تمامًا ، أسمع؟ هذا مفهوم رواية مذهل ، لم يتم العثور عليه في أي مكان afaik.
مع هذا ، يمكنك التصرف على بعض العناصر يدويًا ، حسب الرغبة ، في منتصف المعالجة المستمرة !!
نعم ، يمكنك العودة إلى المطالبة وإصلاحها ، وتغيير ، وإرسال الأشياء ، وسوف "تذكر" الشريط فقط حيث كان ...
لنفترض أنك بحاجة إلى التوفيق بين معاملات الدفع (كنت هناك ، القيام بذلك). تحتاج إلى التكرار أكثر من الآلاف منهم ، واكتشف بطريقة أو بأخرى المعيبة ، وإصلاحها. هذا الإصلاح ليس بسيطًا ولا حتميًا ، فأنت بحاجة إلى دراسة كل واحدة لفهم ما يجب القيام به. يمكن أن يفقدوا المستلم ، أو لديهم مبلغ خاطئ ، أو لا يتم مزامنتهم مع الخادم ، وما إلى ذلك ، من الصعب حتى تخيل كل الاحتمالات.
عادة ، يجب أن تترك عملية الكشف تعمل حتى الانتهاء ، وإلحاق قائمة كل تناقض يجدها وانتظرها ، وربما لفترة طويلة ، حتى تتمكن من البدء أخيرًا في إصلاحها ... يمكنك بالطبع تخفيف ذلك عن طريق المعالجة في القطع أو طباعتهم والتمثيل عبر قذيفة أخرى ، وما إلى ذلك ، ولكن هؤلاء لديهم أوجه القصور الخاصة بهم ...؟
الآن ، هناك طريقة أفضل! ببساطة توقف عملية الكشف الفعلي لفترة من الوقت! ثم عليك فقط الانتظار حتى يتم العثور على الخطأ التالي ، والتصرف في الوقت الفعلي!
لاستخدام آلية الإيقاف المؤقت ، يجب عليك فقط كتابة وظيفة ، بحيث يمكن للرمز 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`
إنه ساذج لأنه يفترض أن جميع الخطوات تستغرق نفس الوقت ، ولكن في الواقع ، قد يستغرق كل واحدة وقتًا مختلفًا تمامًا لإكماله. قد يكون Think read_file
و tokenize
سريعًا للغاية ، مما يجعل النسبة المئوية SPACTOCKE إلى 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 في أوضاع محدودة ، أي أنها تستغرق مليون تكرار في الثانية حتى يتم تحديث الشريط في 60 إطارًا في الثانية. في الوضع اليدوي غير المحدود ، هو 1.0 (100 ٪). كلاهما يمكّن نطاق تشغيل واسع ويعمل بشكل عام بشكل جيد.
على سبيل المثال ، ألقِ نظرة على التأثير الذي تحدثه هذه المعايرة المختلفة للغاية ، مما يؤدي إلى تشغيل نفس الكود بنفس السرعة! لاحظ أن الإحساس يمر بالدوران إلى المستخدم ، هل تسير هذه المعالجة بطيئة أم تسير بسرعة؟ وتذكر أن هذا ليس مجرد انتعاش الدوار ولكن الخط بأكمله ، مع تسليم الشريط وجميع الأدوات المصغّرة ، لذلك يصبح كل شيء أكثر سلاسة أو بطيئة:
لذا ، إذا كانت المعالجات الخاصة بك بالكاد تصل إلى 20 عنصرًا في الثانية ، وتعتقد أن
alive-progress
يبرز بطيئًا ، فيمكنك زيادة هذا الإحساس بالسرعة عن طريق معايرة ذلك لدعنا نقول40
، وسيتم تشغيل waaaay بشكل أسرع ... إنه من الأفضل أن تترك دائمًا بعض مساحة الرأس ومعايرةها إلى شيء ما بين 50 ٪ و 100 ٪ أكثر ، ثم قم بتعديله من هناك للعثور على أكثر ما تحب! :)
هل ترفض هذه الرسوم المتحركة المذهلة alive-progress
عرضها؟
Pycharm رائع ، أنا أحب ذلك! لكنني لن أفهم أبدًا سبب تعطيل محاكاة محطة افتراضيًا ... إذا كنت تستخدم وحدة التحكم في إخراج Pycharm ، فيرجى تمكين ذلك على جميع تكوينات التشغيل:
حتى أوصي بالانتقال إلى
File
>New Projects Setup
>Run Configuration Templates
، وتحديدPython
، وكذلك تمكينها هناك ، لذلك سيكون لدى أي مجموعة جديدة تنشئها هذه المجموعة بالفعل.
بالإضافة إلى ذلك ، تبلغ بعض المحطات أنفسهم "غير تفاعلية" ، مثل نفاد محطة حقيقية (pycharm و jupyter على سبيل المثال) ، في خطوط أنابيب shell ( 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
-> دائمًا ما يمكّن الرسوم المتحركة ، والكتابات التلقائية على جوبتر!force_tty=False
-> يعطل الرسوم المتحركة دائمًا ، مع الحفاظ على الإيصال النهائي فقطforce_tty=None
(افتراضي) -> اكتشاف تلقائي ، وفقًا لحالة المحطة المحطة يمكنك أيضًا تعيينه على مستوى النظام باستخدام config_handler
، لذلك لا تحتاج إلى تمريره يدويًا بعد الآن.
لاحظ أن وحدة التحكم في Pycharm و Jupyter Notebooks تُعرف بشكل كبير ، وبالتالي تحتوي على المزيد من النفقات العامة ، وبالتالي قد لا تكون النتيجة سائلة كما تتوقع. علاوة على ذلك ، لا تدعم أجهزة الكمبيوتر المحمولة jupyter رموز ANSI Escape ، لذلك اضطررت إلى تطوير بعض الحلول لمحاكاة وظائف مثل "Clear the Line" و "Clear From Cursor" ... لرؤية الرسوم المتحركة
alive_bar
على نحو سلس كما كنت أقصد ، تفضل دائمًا محطة كاملة.
alive-progress
أي تبعية. الآن لديه اثنان: واحد هو الوقت حول الوقت (مشروع آخر مثير للاهتمام لي ، إذا قلت ذلك بنفسي) ، والتي تستخدم لتتبع الوقت الذي يستغرقه لتجميع الدوار ، وتوليد عمليات الترحيل الصديقة للإنسان. والآخر هو Grapheme ، للكشف عن فواصل مجموعة Grapheme (لقد فتحت مشكلة هناك تسأل عن المستقبل وصحته ، ويضمن المؤلف أنه يعتزم تحديث المشروع على كل إصدار Unicode جديد) ؛alive-progress
فئة Python واحدة! الآن لديها عدد قليل من الأسباب الصغيرة لأسباب محددة للغاية (تغيير Callables ، محولات Iterator ، وبعض الواصفات لمقاذفات alive_bar
).alive_bar
نفسها هي مجرد وظيفة! على الرغم من أن نكون منصفين ، فهي "مجرد" وظيفة حيث أقوم بتوصيل العديد من عمليات الإغلاق من الداخل بشكل ديناميكي من الداخل (تذكر أن وظائف Python لها __dict__
تمامًا كما تفعل الفصول؟). alive_bar
تغيير حجم الطرف ، ولكنه يقتصر على الخط وفقًا لذلك).contrib
بطريقة أو بأخرى ، للسماح لطريقة بسيطة لمشاركة المغازل والبارات الرائعة من المستخدمين.skipped
stderr
والملفات الأخرى بدلاً من stdout
monitor
، elapsed
، stats
أكمل هنا.
alive_it
، واكتشف الاستخدامات المتداخلة لـ Alive_Progress ورمي رسالة خطأ أوضحalive_it
skipped
، إعداد تكوين max_cols
الجديد لـ Jupyter ، إصلاح جلب حجم المحطة عند استخدام STDERR ، يدعم رسميًا Python 3.11sys.stderr
والملفات الأخرى بدلاً من sys.stdout
، وتنعيم تقدير المعدل ، والمزيد من الاستعلامات في الحاجيات التي تعمل حاليًا " البيانات ، مساعدة نظام في أخطاء التكوينmonitor
قابلة للتخصيص ، elapsed
، و stats
Core Widgets و New monitor_end
و elapsed_end
و stats_end
Core Widgets ، ودعم أفضل لـ Ctrl+C ، مما يجعل alive_bar
توقفًا قبل الأوان قبل الأوانclick.echo()
دعم ؛ أداء أسرع الكشف الأكثر أمانًا للأعمدة الطرفية ؛ bar.current
يتصرف مثل الممتلكات ؛ إزالة بيثون 3.6.check()
أدوات في كل من المغازل والبارات ؛ حانات ومحركات المغازل. أوضاع الرسوم المتحركة الجديدة جنبا إلى جنب وتتابع المغازل. المغازل الجديدة المبنية ، الحانات ، والمواضيع ؛ Showtime الديناميكي مع الموضوعات ، حماية التمرير وأنماط المرشح ؛ تحسين التسجيل للملفات ؛ العديد من خيارات التكوين الجديدة لتخصيص المظهر ؛ محول التكرار الجديد 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
الأقدم في ملف متطلبات. txt مع التنسيقات التالية. ستجلب هذه دائمًا أحدث إصدارات البناء السابقة لإصدار معين ، لذلك ، إذا قمت بإصدار إصلاحات الأخطاء ، فستحصل عليها أيضًا.
❯ pip install -U " alive_progress<2 "
❯ pip install -U " alive_progress<2.2 "
❯ pip install -U " alive_progress<3.2 "
هذا البرنامج مرخص بموجب ترخيص معهد ماساتشوستس للتكنولوجيا. راجع ملف الترخيص الموجود في دليل التوزيع العلوي للحصول على نص الترخيص الكامل.
الحفاظ على مشروع مفتوح المصدر صعب ويستغرق وقتًا طويلاً ، وقد بذلت الكثير من الجهد في هذا.
إذا كنت تقدر عملي ، فيمكنك دعمًا لي بالتبرع! شكرًا لك ؟