पायथन स्थिति पट्टी और प्रतिशत का प्रिंट आउट करने के लिए


160

नीचे की तरह स्थिति पट्टी लागू करने के लिए:

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

मैं चाहता हूं कि इसे प्रिंटआउट के रूप में मुद्रित किया जाए, और इसे ताज़ा करते रहें, किसी अन्य पंक्ति में प्रिंट न करें। यह कैसे करना है?


मैंने एक नई तरह की प्रगति पट्टी प्रकाशित की है, जिसे आप प्रिंट कर सकते हैं, थ्रूपुट और एटा को देख सकते हैं, यहां तक ​​कि बहुत शांत एनिमेशन के अलावा, इसे रोक सकते हैं! कृपया देखें: github.com/rsalmei/alive-progress ! जीवित-प्रगति
rsalmei

जवाबों:


146

एक पायथन मॉड्यूल है जिसे आप PyPI से प्राप्त कर सकते हैं जिसे 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 के साथ भी काम करता है।
गेरहार्ड हैगर

किसी भी विचार क्यों मैं कई बार एक पंक्ति के अंत में अजीब अक्षर प्राप्त करता हूं, भले ही मैं उस स्ट्रिंग को शून्य-समाप्त करता हूं जो लिखा जा रहा है?
जलाशय

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
@ StevenC.Howell आप मार्क का हवाला देते हुए इसका जवाब क्यों नहीं देते? यह एक और संस्करण है और इसे तैयार करने में बहुत मददगार है
GM

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 परियोजना अब यहाँ बनाए रखा है developpers की एक नई टीम द्वारा।
21

1
waw, यह tqdm सिर्फ आश्चर्यजनक है, और इतना आसान उपयोग :)।
सिद्धाहम

6
यह आसानी से सबसे सरल समाधान है
kd88

2
यह एनाकोंडा डिस्ट्रीब्यूट के साथ भी आया है! (जैसा कि अजगर 3.5 और उससे कम के लिए)
जैक्कोट

धन्यवाद, अद्भुत, सरल और प्रभावी
DavideL

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
अनदेखी 27

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()

.Format के उपयोग के साथ:

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

उपरोक्त उत्तर और CLI प्रगति बार के बारे में इसी तरह के अन्य प्रश्नों के आधार पर, मुझे लगता है कि मुझे उन सभी के लिए एक सामान्य सामान्य उत्तर मिला। इसे 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%


प्रगति बार मेरे लिए प्रकट नहीं होता है
अनदेखी 23

मुझे लगता है कि इसकी आवश्यकता नहीं है कि कई दशमलव स्थान यानी राउंड (प्रगति * 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  

उत्तम! और कोई मॉड्यूल की जरूरत है
yurividal

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)

मैं कह सकता हूँ कि यह W7-64 पर अजगर 3.4.3 64-बिट के साथ ठीक काम करता है, लेकिन केवल देशी कंसोल में। हालाँकि जब स्पाईडर 3.0.0dev के बिल्ट-इन कंसोल का उपयोग करते हैं, तो लाइन ब्रेक अभी भी / फिर से मौजूद होते हैं। जैसा कि मुझे यह पता लगाने में कुछ समय लगा, मैं इस अवलोकन को यहां रिपोर्ट करना चाहता हूं।


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),

'# ’क्या करता है?
14

@unseen_rider यहां '#' सिर्फ एक प्रतीक है जिसे लूप पुनरावृत्ति बढ़ने पर दोहराया जाएगा।
NILESH कुमार

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

PyProg का प्रयास करें। PyProg सुपर अनुकूलन प्रगति संकेतक और बार बनाने के लिए पायथन के लिए एक ओपन-सोर्स लाइब्रेरी है।

यह वर्तमान में संस्करण 1.0.2 पर है; यह Github पर होस्ट किया गया है और PyPI (नीचे लिंक नीचे) पर उपलब्ध है। यह पायथन 3 और 2 के साथ संगत है और इसे क्यूटी कंसोल के साथ भी इस्तेमाल किया जा सकता है।

यह उपयोग करने के लिए वास्तव में आसान है। निम्नलिखित कोड:

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%

प्रगति बार को अनुकूलित करने के लिए अधिक विकल्पों के लिए, इस वेबसाइट के जीथब पृष्ठ पर जाएं।

मैंने वास्तव में PyProg बनाया क्योंकि मुझे एक सरल लेकिन सुपर अनुकूलन योग्य प्रगति बार लाइब्रेरी की आवश्यकता थी। आप आसानी से के साथ स्थापित कर सकते हैं: pip install pyprog

PyProg Github: https://github.com/Bill13579/pyprog
PyPI: https://pypi.python.org/pypi/pyprog/


1

@ मार्क-रूसकॉफ उत्तर का उपयोग करते हुए, मैंने एक सरल दृष्टिकोण पर काम किया, एसईएस लाइब्रेरी को कॉल करने की आवश्यकता नहीं है। यह पायथन के साथ काम करता है 3. विंडोज में परीक्षण किया गया:

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("")
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.