طراحی نوارهای پیشروی در پایتون با Tqdm – راهنمای کاربردی
در این مقاله با روش استفاده از نوارهای پیشروی در پایتون با Tqdm آشنا میشویم. «نوار پیشروی» (Progress bar)، مدت انتظار کاربر را تعیین میکند، درکی از میزان فعالیت برنامه به دست میدهد و به همین جهت موجب کاهش تنش عصبی میشود. نوارهای پیشروی سالها است که در صنعت نرمافزار مورد استفاده قرار میگیرند، برخی از آنها هیجانانگیز و برخی دیگر نیز خستهکننده هستند. برخی از نوارهای پیشروی نیز به خوبی مستندسازی نشدهاند.


نوار پیشروی در اساس خود نواری است که برحسب درصد پیشرفت در انجام یک وظیفه پر میشود. پیشروی نوار بر اساس نشانههای مشخصی در انجام وظیفه اندازهگیری میشود. این کار عموماً از طریق طراحی قبلی برخی آیتمهای ورودی و سپس محاسبه پیشرفت با تقسیم تعداد آیتمهای تکمیلشده بر مجموع آیتمهای ورودی صورت میگیرد. البته این حالت بسیار ساده شدهای از مسئله است. عوامل دیگری نیز مانند سرعت شبکه، تأخیر شبکه و لزوم ذخیره دائمی دادهها روی دستگاه کاربر جهت به دست آوردن تخمین دقیقتری از ETA (زمان تقریبی رسیدن | Estimated Time of Arrival) و همچنین سرعت نوشتن وجود دارند که باید در نظر داشت.
شما که این مقاله را برای مطالعه انتخاب کردهاید، به احتمال زیاد از وجود مثالهای کم آنلاین در مورد Tqdm و عدم روشنسازی مناسب طرز کار این کتابخانه در حالتهای گوناگون به ستوه آمدهاید. در مثالهایی که در این مقاله ارائه میشوند، فرض شده است که شما از قبل با طرز کار پکیجهای پایتون آشنایی دارید. اگر با کندوکاو در issue-های گیت آشنایی زیادی نداشته باشید، ممکن است در یافتن مثالهای کد در میان مکالمههای بین جامعه و توسعهدهندگان با دشواری مواجه شوید.
پیش از آن که به ارائه مثالها بپردازیم، ابتدا معنای Tqdm را به صورت دقیق توضیح میدهیم. شاید در نخستین مواجهه نام آن موجب شگفتی شما شود. معنای آن چندان واضح نیست و به نظرمی رسد هیچ ربطی به کاراییاش ندارد. دلیل این مسئله آن است که نام این پکیج به زبان عربی است. Tqdm اختصاری برای عبارت تقدّم است که در زبان عربی به معنای پیشروی است.
پکیج Tqdm یکی از جامعترین پکیجها برای طراحی نوارهای پیشروی است و در مواردی که بخواهید اسکریپتهایی طراحی کنید که کاربران را در مورد وضعیت اپلیکیشن آگاه نگه دارند، کاملاً مفید است. Tqdm روی هر پلتفرمی (لینوکس، ویندوز مک، فریبیاسدی، نتبیاسدی، سولاریس/ ساناواس) در هر کنسول یا GUI کار میکند و کاربرد آن در نتبوکهای IPython و Jupyter نیز آسان است. در ادامه مثالی از آن را در pandas بررسی میکنیم.
توجه داشته باشید که Tqdm با کتابخانه لاگ اصلی پایتون به خوبی کار نمیکند. در این حالت برای به دست آوردن یک نوار پیشروی بیعیب و نقص ممکن است برخی تدابیر ویژه لازم باشد. از آنجا که نوارهای پیشروی که از سوی پکیج Tqdm ایجاد میشوند، برای کنترل کاراکترها از ورودیهای «بازگشت کارتریج» (r\) و «ابتدای خط» (n\) استفاده میکنند، درک زمان استفاده از آن در محیطی که پشتیبانی نمیکنند بسیار مهم است. برای نمونه در ترمینال لاگ Jenkins یا در فریمورکهای لاگ شخص ثالث مانند splunk ،cloudwatch و Loggly، خروجی مطلوب ممکن است آن چیزی که انتظار دارید، نباشد. برای نمونه خروجی مانند تصویر زیر در هر خط جریان مییابد:

در این راهنمای فشرده، برخی مثالها ارائه میشوند تا بتوانید بدون زحمت زیاد، پیشرفت سریعی در بهرهگیری از این پکیج به دست آورید. این مثالها با آن چه Tqdm هم اینک در ریپازیتوری گیت خود نمایش میدهد مطابقت دارند و توضیحاتی نیز در مورد طرز کار کد ارائه شده است. ابتدا کار خود را با راهاندازی Tqdm روی رایانه لوکال آغاز میکنیم.
پیشنیازها
پایتون 3 باید روی رایانه نصب باشد، اگر از مک استفاده میکنید، میتوانید از Brew به این منظور بهره بگرید و یا دستورالعملهای ارائه شده در وبسایت پایتون (+) را طی کنید. اگر از ویندوز استفاده میکنید، Python MSI میتواند به شما کمک کند تا دستکم مطمئن باشید که متغیرهای محیطی به درستی تنظیم شده و پایتون نصب میشود.
$ brew install python3
توجه کنید که Pip3 به همراه پایتون 3 بستهبندی شده است. برای نصب virtualenv از طریق pip دستور زیر را اجرا نمایید:
$ pip3 install virtualenv
آن دایرکتوری که میخواهید کد را در آن بنویسید پیدا کرده و یک محیط مجازی ایجاد کنید:
$ virtualenv -p python3 <your-desired-path>
این «محیط مجازی» (virtualenv) را فعال کنید:
$ source <desired-path>/bin/activate
در حالتی که بخواهید virtualenv را غیرفعال کنید، میتوانید دستور زیر را اجرا نمایید:
$ deactivate
در ادامه دستورهای زیر را اجرا کنید:
$ pip install tqdm $ pip freeze > requirements.txt
بدین ترتیب یک محیط مجازی ایجاد میشود که میتوانید کد پایتون را در آن اجرا نمایید. این رویه مناسبی است و پیشنهاد میشود که همواره از آن پیروی کنید. محیطهای مجازی پایتون، محیطهای ایزولهای برای پروژههای پایتون فراهم میسازند این بدان معنی است که هر پروژه میتواند وابستگیهای خاص خود را صرفنظر از وابستگیهای پروژههای دیگر داشته باشد. پس از فعالسازی pip پکیجهایی که لازم است را در پوشه محیط مجازی نصب میکند. غیرفعالسازی محیط مجازی موجب قطع لینک به محیط مجازی درون نشست ترمینال میشود. اجرای دستور pip freeze یک اسنپشات از نسخه کنونی پکیجهایی که با اپلیکیشن کار میکنند ذخیره میکند. در ادامه برخی کاربردهای tqdm را مورد بررسی قرار میدهیم.
افزودن نوار پیشروی به حلقههای for
به جای پرینت کردن اندیسها یا دیگر اطلاعات در هر بار تکرار حلقههای for جهت نمایش میزان پیشرفت، میتوان به سادگی نوار پیشروی را چنان که در مثالهای بعدی خواهید دید به پروژه اضافه کرد. افزودن نوار پیشروی موجب میشود که در زمان اجرای اسکریپتهای طولانی از روند انجام کار آگاه بمانید. اگر پروژه را روی رایانه ویندوزی اجرا میکنید، ممکن است لازم باشد پکیج colorama pip را اضافه کنید.
بدین ترتیب یک نوار پیشروی زیبا و تودرتو به دست میآید. هر کدام از حلقههای بیرونی، ده بار تکرار میشود. به صورت پیشفرض tqdm در استریم خروجی sys.stderr پرینت میشود. برای تغییر کانال آن به استریم خروجی استاندارد باید از آرگومانهای دیگر استفاده کنید:
file=sys.stdout

بهروزرسانیهای دستی نوار پیشروی
موردی وجود دارند که لازم است کنترل را به دست بگیرید و بهروزرسانیهای نوار پیشروی را در بازههای خاصی به صورت دستی اجرا کنید. برای نمونه هنگامی که یک فایل چندبخشی را به صورت تکهتکه دانلود میکنید یا دادهها را استریم میکنید، چنین حالتی پیش میآید. این وضعیت را میتوان به صورت یک بهروزرسانی بازهای دورهای یا در بازههای خاص تصور کرد. پکیج tqdm امکان اجرای دستی تابع بهروزرسانی نوار پیشروی را چنان که در مثال زیر میبینید، فراهم ساخته است:
خصوصیت total کلاس tqdm فوق تعداد مورد انتظار تکرارها است که در کد فوق برابر با 100 تعیین شده است. فراخوانی تابع بهروزرسانی به صورت نموی موجب اضافه شدن 10 مورد به تکرارها میشود تا این که به 100% مورد نظر برسد.
اگر total تعیین نشده باشد، از len(iterable) در صورت امکان استفاده میشود. اگر این مورد حذف شود، تنها آمار پیشروی مقدماتی نمایش مییابد و دیگر خبری از ETA و نوار پیشروی نخواهد بود. چنین حالتی مفید نیست، اما با این حال همچنان میتوان کار در حال اجرا در پسزمینه را نمایش داد.
دانلود فایلهای بزرگ با نوار پیشروی tqdm
در این مثال، باید پکیج requests (+) و validator-ها (+) را از طریق pip به site-packages پایتون اضافه کنیم.
نوارهای پیشروی بر پایه نخ
در این مثال میتوانیم شیوه قرار دادن پکیج tqdm درون نخهای پایتون را ببینیم. در این جا نباید نخها را با پردازشها اشتباه بگیرید. اگر میخواهید از مزیت استفاده از همه هستههای رایانهتان بهرهمند شوید، در این صورت باید از روش چندپردازشی استفاده کنید. آرگومان position در tqdm امکان تعیین آفست خط برای پرینت این نوار را فراهم ساخته است. اگر این آرگومان تعیین نشده باشد، به صورت پیشفرض روی automatic است. در این مثال تعیین این مقدار برای مدیریت چند نوار به طور همزمان حائز اهمیت است. اگر این آرگومان را نادیده بگیرید، نوارهای شما از سوی نخهای مختلف بازنویسی میشوند.
اعمال tqdm روی دیتافریمهای pandas
Tqdm را میتوان روی دیتافریمهای pandas نیز اعمال کرد و یک نوار پیشروی tqdm را روی آن ساخت. بدین منظور باید از progress_apply به جای apply و از progress_map به جای map استفاده کنید. به مثال زیر توجه کنید. روی هر ردیف Pandas، قلاب بهروزرسانی tqdm تکرار میشود و بر مبنای دادههای کل درون دیتافریم فراخوانی میشود. بین ترتیب میتوان یک ETA به دست آورد.

برای اجرای این پروژه باید مطمئن شوید که پکیجهای requests ،tqdm و pandas نصب شدهاند:
برای اجرای این پروژه در نوتبوکهای ژوپیتر باید نوتبوک ژوپیتر را نیز با دستور زیر نصب کنید:
python3 -m pip install jupyter
برای اجرای نوتبوک، دستور زیر را در ترمینال اجرا کنید. بدین ترتیب مرورگری باز میشود که ژوپیتر روی پورت پیشفرض در آن اجرا شده است:
jupyter notebook
افزودن رنگ به نوار پیشروی tqdm
اگر جزو کسانی نیستید که فکر میکنند افزودن رنگ به نوار پیشروی موجب سردرگم شدن میشود، باید اعلام کنیم که امکان انجام این کار در مورد نوارهای پیشروی tqdm با بهرهگیری از colorama (+) وجود دارد. colorama یک پکیج رنگی کردن متن ترمینال ساده و چند پلتفرمی در پایتون است. نمایش متنهای رنگی به روش چند پلفترمی با استفاده از اختصار ثابت Colorama برای دنباله ANSI escape ممکن شده است. برای مشاهده مثالها سورس کد این پکیج به این صفحه (+) سر بزنید.

استفاده از Python Logger به همراه tqdm
در مثال زیر شیوه نوشتن لاگ درون فریمورک Python Logger را میبینید. ایده کار، ایجاد یک لاگر سفارشی است که دادههای لاگ شده را از StringIO و channel ارثبری کند. استفاده از ماژولهای بافر مانند StringIO به ما کمک میکند که دادهها را مانند یک فایل معمول دستکاری کنیم و سپس از آنها برای پردازشهای بعدی استفاده نماییم.
افزودن Tqdm به پردازشهای فرعی پایتون
«پردازشهای فرعی» (subproceses) پایتون برای دسترسی به دستورهای سیستم استفاده میشوند و توصیه شده حتماً مورد استفاده قرار گیرند. برای نمونه برای اجرای دستورهای ترمینال ویندوز یا دستورهای bash در ترمینال لینوکس از این پردازشهای فرعی استفاده میشود. ماژول subprocess امکان زایش پردازشهای جدید، اتصال به pipe-های ورودی/خروجی/خطای آنها و به دست آوردن کدهای بازگشتی را فراهم میسازد.
در مثال فوق، به صورت مکرر خروجی تولید شده از سوی دستور اجرایی را استریم میکنیم و از آن برای بهروزرسانی نوار پیشروی tqdm بهره میگیریم. از آنجا که صراحتاً یک تکرارکننده با طول از پیشتعریفشده نداریم، نمیتوانیم برای این فرایند تکرار، انتهایی تصور کنیم و از این رو tqdm به صورت پیشفرض زمان سپریشده را به عنوان خروجی ارائه میکند.

زمان سپریشده در مواردی که میخواهید ترمینال زیاد شلوغ نشود، میتواند مطلوب باشد. نکتهای که باید توجه داشت این است که مستندات پایتون در مورد استفاده از آرگومان shell=True هشداری به صورت زیر دادهاند:
فراخوانی شل سیستم به وسیله آرگومان shell=True، در صورتی که با ورودیهای غیر قابل اعتماد همراه باشد، میتواند موجب مخاطرات امنیتی شود.
امیدواریم این مقاله و مثالهای ارائه شده برای شما مفید بوده باشد.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی پایتون
- مجموعه آموزشهای برنامهنویسی
- گنجینه آموزشهای برنامهنویسی پایتون
- تاریخ و زمان کنونی در پایتون — به زبان ساده
- افزودن لاگ به اسکریپت پایتون — راهنمای کاربردی
- زبان برنامه نویسی پایتون (Python) — از صفر تا صد
==














توضیحات و مثال ها کامل و جامع بود، ممنونم.
اصلا خوب توضیح ندادین واسه کسی که با این ماژول آشنایی قبلی نداشته باشه بیشتر سردرگم میشه فقط یه سری مثال زدین بدون توضیح بخش های مهم این این ماژول