পাইথন স্থিতি বার এবং শতাংশ মুদ্রণ করতে


160

নীচের মতো একটি স্ট্যাটাস বার বাস্তবায়ন করতে:

[==========                ]  45%
[================          ]  60%
[==========================] 100%

আমি এটিকে প্রিন্ট করে স্টডআউটে রাখতে চাই এবং এটিকে সতেজ রাখি, অন্য লাইনে মুদ্রণ না করে। কিভাবে এই কাজ করতে?


আমি একটি নতুন ধরণের অগ্রগতি বার প্রকাশ করেছি, যা আপনি প্রিন্ট করতে পারেন, থ্রুপুট এবং এটা দেখতে পারেন, এমনকি এটি থামিয়ে দিতে পারেন, খুব শীতল অ্যানিমেশন ছাড়াও! দয়া করে একবার দেখুন: github.com/rsalmei/alive-progress ! জীবিত-অগ্রগতি
রসলমেই

উত্তর:


146

পাইথন মডিউল রয়েছে যা আপনি পাইপিআই থেকে পেতে পারেন যা progressbarএই জাতীয় কার্যকারিতা কার্যকর করে। আপনি যদি নির্ভরতা যুক্ত করতে কিছু মনে করেন না তবে এটি একটি ভাল সমাধান। অন্যথায়, অন্য উত্তরগুলির সাথে একটিতে যান।

এটি কীভাবে ব্যবহার করবেন তার একটি সাধারণ উদাহরণ:

import progressbar
from time import sleep
bar = progressbar.ProgressBar(maxval=20, \
    widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])
bar.start()
for i in xrange(20):
    bar.update(i+1)
    sleep(0.1)
bar.finish()

এটি ইনস্টল করতে, আপনি ব্যবহার করতে পারেন easy_install progressbar, বা pip install progressbarযদি আপনি পাইপ পছন্দ করেন।


সমস্ত উত্তর দুর্দান্ত, তবে আমি মডিউলটি সবচেয়ে পছন্দ করি। সবাইকে ধন্যবাদ.
স্টান

8
সম্ভবত এই উদাহরণের মতো কিছু দরকার bar.start()?
জিম রায়নোর

2
আমার মেশিনে কাজ করে নাbar.start()
Zach

1
এই মডিউলটি 2 বছরেরও বেশি সময় আপডেট হয়নি। নতুন সফ্টওয়্যার জন্য এটি ব্যবহার করবেন না!
নবীন

4
ইনস্টলেশন: sudo -H pip install progressbar2
মার্টিন থোমা

254

'\r'অক্ষর (গাড়ি ফেরত) লাইনের শুরুতে কার্সার রিসেট ও তোমাদের উপর লিখতে কি লাইনে পূর্বে ছিল পারেন।

from time import sleep
import sys

for i in range(21):
    sys.stdout.write('\r')
    # the exact output you're looking for:
    sys.stdout.write("[%-20s] %d%%" % ('='*i, 5*i))
    sys.stdout.flush()
    sleep(0.25)

এটি যদি সমস্ত সিস্টেমে সম্পূর্ণরূপে পোর্টেবল হয় তবে আমি 100% নিশ্চিত নই তবে এটি লিনাক্স এবং ওএসএক্সে কমপক্ষে কাজ করে।


7
এটি চিহ্নিত উত্তরের চেয়ে ভাল, কারণ এটি পাইথন 3 নিয়েও কাজ করে works
জেরহার্ড হ্যাজারার

কোনও ধারনা কেন আমি মাঝে মাঝে একটি লাইনের শেষে অদ্ভুত চরিত্রগুলি পাই, এমনকি যদি আমি লেখা হচ্ছে যে স্ট্রিংটি বাতিল করে দিই?
জলাধার

23
লিখিত হিসাবে, কোডটি পরিষ্কার করে দেয় না যে আপনি যে আকারের উপরে পুনরাবৃত্তি করছেন (21 নয়) এটি কীভাবে মানিয়ে নেবেন। আমি চাই n=21, প্রতিস্থাপন range(21)সঙ্গে range(n), তারপর যোগ j = (i + 1) / nলুপ ভিতরে, এবং প্রতিস্থাপন writeএই সামান্য সংশোধন সহ বিবৃতি: sys.stdout.write("[%-20s] %d%%" % ('='*int(20*j), 100*j))। এখন আপনার কেবলমাত্র পরিবর্তনটি করা দরকার তা হল n=21লুপের আগে (আরও বেশি সম্ভাবনা n=len(iterable)), তারপরে পুনরাবৃত্তিযোগ্য বস্তুর উপর অঙ্ক করা উচিত। আমি এই সম্পাদনার প্রস্তাব দিয়েছিলাম তবে তা প্রত্যাখ্যান করা হয়েছিল; দৃশ্যত কার্যকারিতা "পোস্টের মূল উদ্দেশ্য থেকে বিচ্যুত হয়"।
স্টিভেন সি হাওয়েল

1
এন এর নির্বিচার আকারের সাথে অভিযোজিত sys.stdout.write("[{:{}}] {:.1f}%".format("="*i, n-1, (100/(n-1)*i))), পাইথন 3 কেবল
গ্যাব্রিয়েলচু

3
@ স্টিভেনসি.হোয়েল আপনি কেন এটি চিহ্ন হিসাবে উদ্ধৃত করে উত্তর পোস্ট করেন না? এটি অন্য সংস্করণ এবং এটি প্রস্তুত করতে এটি বেশ সহায়ক
জিএম

91

আমি দরকারী লাইব্রেরি পেয়েছি tqdm ( https://github.com/tqdm/tqdm/ , এর আগে: https://github.com/noamraph/tqdm )। এটি স্বয়ংক্রিয়ভাবে সমাপ্তির সময় অনুমান করে এবং পুনরুক্তি হিসাবে ব্যবহার করা যেতে পারে।

ব্যবহার:

import tqdm
import time

for i in tqdm.tqdm(range(1000)):
    time.sleep(0.01)
    # or other long operations

ফলাফল স্বরূপ:

|####------| 450/1000  45% [elapsed: 00:04 left: 00:05, 99.15 iters/sec]

tqdm যে কোনও পুনরাবৃত্তযোগ্য মোড়ানো করতে পারেন।


4
Tqdm প্রকল্পের এখন এখানে রক্ষা করা হয় ডেভেলপাররা যাতে একটি নতুন দল দ্বারা।
চমত্কার

1
বাহ, এই tqdm ঠিক আশ্চর্যজনক, এবং ব্যবহার করা এত সহজ :)।
সিডাহেমে

6
এটি সহজেই সবচেয়ে সহজ সমাধান
kd88

2
এটি আনাকোন্ডা বিতরণের সাথেও বান্ডিল হয়ে এসেছে! (অজগর 3.5 এবং কমপক্ষে উপরের হিসাবে)
জ্যাককোট

ধন্যবাদ, আশ্চর্যজনক, সহজ এবং কার্যকর
ডেভিডেল

23

আপনি \r( গাড়ী চালনা ) ব্যবহার করতে পারেন । ডেমো:

import sys
total = 10000000
point = total / 100
increment = total / 20
for i in xrange(total):
    if(i % (5 * point) == 0):
        sys.stdout.write("\r[" + "=" * (i / increment) +  " " * ((total - i)/ increment) + "]" +  str(i / point) + "%")
        sys.stdout.flush()

totalহিসাবে চেষ্টা করুন 10, তারপরে আপনি ত্রুটি বার্তাটি পাবেনZeroDivisionError: long division or modulo by zero
unseen_rider

19

এখানে আপনি নিম্নলিখিত ক্রিয়াকলাপ হিসাবে কোড ব্যবহার করতে পারেন:

def drawProgressBar(percent, barLen = 20):
    sys.stdout.write("\r")
    progress = ""
    for i in range(barLen):
        if i < int(barLen * percent):
            progress += "="
        else:
            progress += " "
    sys.stdout.write("[ %s ] %.2f%%" % (progress, percent * 100))
    sys.stdout.flush()

। ফর্ম্যাট ব্যবহারের সাথে:

def drawProgressBar(percent, barLen = 20):
    # percent float from 0 to 1. 
    sys.stdout.write("\r")
    sys.stdout.write("[{:<{}}] {:.0f}%".format("=" * int(barLen * percent), barLen, percent * 100))
    sys.stdout.flush()

আমার জন্য প্রথম লাইনটি কার্সার দ্বারা সংশোধন করে না - কেবল দ্বিতীয় লাইনটি করে। সুতরাং অগ্রগতি বারের জন্য একাধিক লাইন এবং উদাহরণস্বরূপ একটির জন্য পাওয়া গেছে] percent * 100 %
unseen_rider

6

উপরের উত্তরগুলি এবং সিএলআই অগ্রগতি বার সম্পর্কে অন্যান্য অনুরূপ প্রশ্নের ভিত্তিতে, আমি মনে করি তাদের সকলের একটি সাধারণ সাধারণ উত্তর পেয়েছি think এটি https://stackoverflow.com/a/15860757/2254146 এ দেখুন

এখানে ফাংশনের একটি অনুলিপি দেওয়া হয়েছে, তবে আপনার শৈলীতে ফিট করার জন্য এটি পরিবর্তিত হয়েছে:

import time, sys

# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
    barLength = 20 # Modify this to change the length of the progress bar
    status = ""
    if isinstance(progress, int):
        progress = float(progress)
    if not isinstance(progress, float):
        progress = 0
        status = "error: progress var must be float\r\n"
    if progress < 0:
        progress = 0
        status = "Halt...\r\n"
    if progress >= 1:
        progress = 1
        status = "Done...\r\n"
    block = int(round(barLength*progress))
    text = "\rPercent: [{0}] {1}% {2}".format( "="*block + " "*(barLength-block), progress*100, status)
    sys.stdout.write(text)
    sys.stdout.flush()

দেখতে

শতাংশ: [=====================] 99.0%


অগ্রগতি বারটি আমার কাছে উপস্থিত হবে না
unseen_rider

আমি মনে করি যে এটির দশমিক জায়গাগুলির প্রয়োজন নেই যেমন গোল (অগ্রগতি * 100,2)
আন্দ্রেস সানচেজ

4

যদি আপনি একটি কমান্ড লাইন ইন্টারফেস বিকাশ করে থাকেন তবে আমি আপনাকে পরামর্শ দিন clickযা খুব সুন্দর:

import click
import time

for filename in range(3):
    with click.progressbar(range(100), fill_char='=', empty_char=' ') as bar:
        for user in bar:
            time.sleep(0.01)

আপনি যে আউটপুট পাবেন তা এখানে:

$ python test.py
  [====================================]  100%
  [====================================]  100%
  [=========                           ]   27%

4

আরও উন্নত করা, একটি ফাংশন ব্যবহার করে:

import sys

def printProgressBar(i,max,postText):
    n_bar =10 #size of progress bar
    j= i/max
    sys.stdout.write('\r')
    sys.stdout.write(f"[{'=' * int(n_bar * j):{n_bar}s}] {int(100 * j)}%  {postText}")
    sys.stdout.flush()

কলিং উদাহরণ:

total=33
for i in range(total):
    printProgressBar(i,total,"blah")
    sleep(0.05)  

আউটপুট:

[================================================  ] 96%  blah  

পারফেক্ট! এবং কোনও মডিউলগুলির প্রয়োজন নেই
ইয়ার্ভেডিয়াল

3

আমি আজ এই থ্রেডে এসেছি এবং মার্ক রুশাকফের কাছ থেকে এই সমাধানটি চেষ্টা করার পরে

from time import sleep
import sys

for i in range(21):
sys.stdout.write('\r')
# the exact output you're looking for:
sys.stdout.write("[%-20s] %d%%" % ('='*i, 5*i))
sys.stdout.flush()
sleep(0.25)

আমি বলতে পারি যে এটি ডায়াগন 3.4.3 64৪-বিট দিয়ে ডাব্লু 7-64 এ ঠিক কাজ করে তবে কেবল দেশীয় কনসোলে in তবে স্পাইডার 3.0.০.০.দেবের অন্তর্নির্মিত কনসোলটি ব্যবহার করার সময়, লাইন ব্রেকগুলি এখনও / আবার উপস্থিত রয়েছে। যেহেতু এটি আমাকে কিছুটা সময় নিয়েছিল, আমি এখানে এই পর্যবেক্ষণটি রিপোর্ট করতে চাই।


2

এখানে এবং অন্য কোথাও কয়েকটি উত্তরের উপর ভিত্তি করে, আমি এই সাধারণ ফাংশনটি লিখেছি যা একটি অগ্রগতি বারটি প্রদর্শন করে এবং সময় ব্যয় করে / अनुमानিত অবশিষ্ট সময়টি প্রদর্শন করে। বেশিরভাগ ইউনিক্স-ভিত্তিক মেশিনে কাজ করা উচিত।

import time
import sys

percent = 50.0
start = time.time()
draw_progress_bar(percent, start)


def draw_progress_bar(percent, start, barLen=20):
sys.stdout.write("\r")
progress = ""
for i in range(barLen):
    if i < int(barLen * percent):
        progress += "="
    else:
        progress += " "

elapsedTime = time.time() - start;
estimatedRemaining = int(elapsedTime * (1.0/percent) - elapsedTime)

if (percent == 1.0):
    sys.stdout.write("[ %s ] %.1f%% Elapsed: %im %02is ETA: Done!\n" % 
        (progress, percent * 100, int(elapsedTime)/60, int(elapsedTime)%60))
    sys.stdout.flush()
    return
else:
    sys.stdout.write("[ %s ] %.1f%% Elapsed: %im %02is ETA: %im%02is " % 
        (progress, percent * 100, int(elapsedTime)/60, int(elapsedTime)%60,
         estimatedRemaining/60, estimatedRemaining%60))
    sys.stdout.flush()
    return

2

এটি বেশ সরল পদ্ধতির কোনও লুপের সাথে ব্যবহার করা যেতে পারে।

#!/usr/bin/python
for i in range(100001):
    s =  ((i/5000)*'#')+str(i)+(' %')
    print ('\r'+s),

'#' কি করে?
unseen_rider

@ ইউনসেন_াইডার এখানে '#' কেবল একটি প্রতীক যা লুপ পুনরাবৃত্তির পরিমাণ বাড়ার সাথে সাথে পুনরাবৃত্তি হবে।
নীলেশ কুমার

2

সবচেয়ে সহজ এখনও

import sys
total_records = 1000
for i in range (total_records):
    sys.stdout.write('\rUpdated record: ' + str(i) + ' of ' + str(total_records))
    sys.stdout.flush()

কীটি হল পূর্ণসংখ্যার প্রকারকে স্ট্রিংয়ে রূপান্তর করা।


2

মার্ক রুশাকফের সমাধানে বর্ণিত হিসাবে , আপনি sys.stdout.write('\r')কার্সারটির পুনরায় অক্ষরটি আউটপুট করতে পারেন, কার্সারটিকে লাইনের শুরুতে পুনরায় সেট করতে। সেই সমাধানটি সাধারণ করতে, পাইথন 3 এর এফ স্ট্রিংগুলি প্রয়োগ করার সময় আপনি ব্যবহার করতে পারেন

from time import sleep
import sys

n_bar = 50
iterable = range(33)  # for demo purposes
n_iter = len(iterable)
for i, item in enumerate(iterable):
    j = (i + 1) / n_iter

    sys.stdout.write('\r')
    sys.stdout.write(f"[{'=' * int(n_bar * j):{n_bar}s}] {int(100 * j)}%")
    sys.stdout.flush()

    sleep(0.05)  
    # do something with <item> here

1

পাইপ্রোগ চেষ্টা করুন। পাইপ্রাগ হ'ল পাইথনের একটি ওপেন সোর্স লাইব্রেরি সুপার কাস্টমাইজযোগ্য অগ্রগতি সূচক এবং বারগুলি তৈরি করতে।

এটি বর্তমানে 1.0.2 সংস্করণে রয়েছে; এটি গিথুবটিতে হোস্ট করা হয়েছে এবং পিপিআইতে উপলব্ধ রয়েছে (নীচে লিঙ্কগুলি)। এটি পাইথন 3 এবং 2 এর সাথে সামঞ্জস্যপূর্ণ এবং এটি Qt কনসোলের সাথেও ব্যবহার করা যেতে পারে।

এটি ব্যবহার করা সত্যই সহজ। নিম্নলিখিত কোড:

import pyprog
from time import sleep

# Create Object
prog = pyprog.ProgressBar(" ", " ", total=34, bar_length=26, complete_symbol="=", not_complete_symbol=" ", wrap_bar_prefix=" [", wrap_bar_suffix="] ", progress_explain="", progress_loc=pyprog.ProgressBar.PROGRESS_LOC_END)
# Update Progress Bar
prog.update()

for i in range(34):
    # Do something
    sleep(0.1)
    # Set current status
    prog.set_stat(i + 1)
    # Update Progress Bar again
    prog.update()

# Make the Progress Bar final
prog.end()

আপনি যা চান ঠিক তা উত্পাদন করবে (এমনকি বারের দৈর্ঘ্যও!):

[===========               ] 45%
[===============           ] 60%
[==========================] 100%

অগ্রগতি বারটি কাস্টমাইজ করার জন্য আরও বিকল্পগুলির জন্য, এই ওয়েবসাইটটির গিথুব পৃষ্ঠায় যান।

আমি আসলে পাইপ্রোগ তৈরি করেছি কারণ আমার একটি সাধারণ তবে সুপার কাস্টমাইজযোগ্য প্রগতি বার গ্রন্থাগার দরকার needed আপনি সহজেই সঙ্গে এটি ইনস্টল করতে পারেন: pip install pyprog

পাইপ্রোগ গিথুব: https://github.com/Bill13579/pyprog পাইপিআই
: https://pypi.python.org/pypi/pyprog/


1

@ মার্ক-রুশকফ উত্তরটি ব্যবহার করে, আমি একটি সহজ পদ্ধতির কাজ করেছি, সিস লাইব্রেরি কল করার দরকার নেই। এটি পাইথন ৩ এর সাথে কাজ করে Windows উইন্ডোজে পরীক্ষিত:

from time import sleep
for i in range(21):
    # the exact output you're looking for:
    print ("\r[%-20s] %d%%" % ('='*i, 5*i), end='')
    sleep(0.25)

ভিন্ন প্রশ্নের উত্তরে বর্ণিত হিসাবে printহ'ল একটি পাতলা মোড়ক যা ইনপুট ফর্ম্যাট করে এবং প্রদত্ত কোনও অবজেক্টের রাইটিং ফাংশনটিকে কল করে। ডিফল্টরূপে এই অবজেক্টটি sys.stdout
স্টিভেন সি। হাওয়েল

0

সমাধানটি @ মার্ক-রুশকফের সাহায্যে আমি এখানে তৈরি করেছি। অভিযোজিতভাবে টার্মিনাল প্রস্থের সাথে সামঞ্জস্য করতে।

from time import sleep
import os
import sys
from math import ceil

l = list(map(int,os.popen('stty size','r').read().split()))
col = l[1]
col = col - 6

for i in range(col):
    sys.stdout.write('\r')
    getStr = "[%s " % ('='*i)
    sys.stdout.write(getStr.ljust(col)+"]"+"%d%%" % (ceil((100/col)*i)))
    sys.stdout.flush()
    sleep(0.25)
print("")
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.