Python-voortgangsbalk

Hoe gebruik ik een voortgangsbalk wanneer mijn script een taak uitvoert die waarschijnlijk tijd kost?

Bijvoorbeeld een functie die enige tijd nodig heeft om te voltooien en Trueretourneert wanneer deze is voltooid. Hoe kan ik een voortgangsbalk weergeven gedurende de tijd dat de functie wordt uitgevoerd?

Houd er rekening mee dat ik dit in realtime moet doen, dus ik weet niet wat ik eraan moet doen. Heb ik hiervoor een threadnodig? Ik heb geen idee.

Op dit moment druk ik niets af terwijl de functie wordt uitgevoerd, maar een voortgangsbalk zou fijn zijn. Ik ben ook meer geïnteresseerd in hoe dit kan worden gedaan vanuit een code-oogpunt.


Antwoord 1, autoriteit 100%

Er zijn specifieke bibliotheken (zoals deze hier), maar misschien zou iets heel eenvoudigs kunnen doen:

import time
import sys
toolbar_width = 40
# setup toolbar
sys.stdout.write("[%s]" % (" " * toolbar_width))
sys.stdout.flush()
sys.stdout.write("\b" * (toolbar_width+1)) # return to start of line, after '['
for i in xrange(toolbar_width):
    time.sleep(0.1) # do real work here
    # update the bar
    sys.stdout.write("-")
    sys.stdout.flush()
sys.stdout.write("]\n") # this ends the progress bar

Opmerking: progressbar2is een afsplitsing van voortgangsbalkdie al jaren niet is onderhouden.


Antwoord 2, autoriteit 91%

Met tqdm(conda install tqdmof pip install tqdm) je kunt binnen een seconde een voortgangsmeter aan je loops toevoegen:

from time import sleep
from tqdm import tqdm
for i in tqdm(range(10)):
    sleep(3)
 60%|██████    | 6/10 [00:18<00:12,  0.33 it/s]

Er is ook een notebookversie:

from tqdm.notebook import tqdm
for i in tqdm(range(100)):
    sleep(3)

U kunt tqdm.autogebruiken in plaats van tqdm.notebookom zowel in een terminal als in notebooks te werken.

tqdm.contribbevat enkele hulpfuncties om dingen te doen zoals enumerate, mapen zip. Er zijn gelijktijdige kaarten in tqdm.contrib.concurrent.

Je kunt zelfs voortgang naar je telefoon laten sturen nadat je de verbinding met een jupyter-notebook hebt verbroken met tqdm.contrib.telegramof tqdm.contrib.discord.


Antwoord 3, autoriteit 44%

De bovenstaande suggesties zijn redelijk goed, maar ik denk dat de meeste mensen gewoon een kant-en-klare oplossing willen, zonder afhankelijkheden van externe pakketten, maar die ook herbruikbaar is.

Ik heb de beste punten van al het bovenstaande en heb er een functie van gemaakt, samen met een testcase.

Om het te gebruiken, kopieert u gewoon de regels onder “Def update_progress (vooruitgang)” maar niet het testscript. Vergeet niet om SYS te importeren. Bel dit wanneer u de voortgangsbalk moet weergeven of bijwerken.

Dit werkt door het symbool van de “\ R” naar de console rechtstreeks te verzenden om de cursor terug te zetten naar het begin. “Print” in Python reconstraat het bovenstaande symbool niet voor dit doel, vandaar dat we ‘SYS’

nodig hebben

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 = 10 # 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()
# update_progress test script
print "progress : 'hello'"
update_progress("hello")
time.sleep(1)
print "progress : 3"
update_progress(3)
time.sleep(1)
print "progress : [23]"
update_progress([23])
time.sleep(1)
print ""
print "progress : -10"
update_progress(-10)
time.sleep(2)
print ""
print "progress : 10"
update_progress(10)
time.sleep(2)
print ""
print "progress : 0->1"
for i in range(101):
    time.sleep(0.1)
    update_progress(i/100.0)
print ""
print "Test completed"
time.sleep(10)

Dit is wat het resultaat van het testscript laat zien (de laatste voortgangsbalk wordt geanimeerd):

progress : 'hello'
Percent: [----------] 0% error: progress var must be float
progress : 3
Percent: [##########] 100% Done...
progress : [23]
Percent: [----------] 0% error: progress var must be float
progress : -10
Percent: [----------] 0% Halt...
progress : 10
Percent: [##########] 100% Done...
progress : 0->1
Percent: [##########] 100% Done...
Test completed

Antwoord 4, autoriteit 33%

Om een voortgangsbalkraamwerk op een nuttige manier te gebruiken, d.w.z. om een voltooiingspercentage en een geschatte verwachte aankomsttijd te krijgen, moet u kunnen aangeven hoeveel stappen het zal hebben.

Dus, kun je zien hoeveel stappen je rekenfunctie heeft? Kun je de code wijzigen?

Je hoeft het op geen enkele manier te refactoren of te splitsen, je kunt gewoon wat strategische yields invoegen om de stappen te markeren, of als het een for-lus, slechts één!

Uw functie zou er nu ongeveer zo uit moeten zien:

def compute():
    for i in range(1000):
        ... # process an item
        yield  # insert this and you're done!

Installeer dan gewoon:

pip install alive-progress

En gebruik het als:

from alive_progress import alive_bar
with alive_bar(1000) as bar:
    for i in compute():
        bar()

Om een coole voortgangsbalk te krijgen!

|█████████████▎                      | ▅▃▁ 321/1000 [32%] in 8s (40.1/s, eta: 16s)

DISCLAIMER: Ik ben de auteur van alive-progress, maar het zou je probleem mooi moeten oplossen! Lees de documentatie op https://github.com/rsalmei/alive-progress om meer te weten. Hier enkele voorbeelden van wat het kan doen:


5, Autoriteit 12%

Voor een vergelijkbare toepassing (het bijhouden van de voortgang in een lus) Ik heb eenvoudig de python-progressbar :

Hun voorbeeld gaat zoiets,

from progressbar import *               # just a simple progress bar
widgets = ['Test: ', Percentage(), ' ', Bar(marker='0',left='[',right=']'),
           ' ', ETA(), ' ', FileTransferSpeed()] #see docs for other options
pbar = ProgressBar(widgets=widgets, maxval=500)
pbar.start()
for i in range(100,500+1,50):
    # here do something long at each iteration
    pbar.update(i) #this adds a little symbol at each iteration
pbar.finish()
print

6, Autoriteit 12%

Probeer vooruitgang van https://pypi.python.org/pypi/progress .

from progress.bar import Bar
bar = Bar('Processing', max=20)
for i in range(20):
    # Do some work
    bar.next()
bar.finish()

Het resultaat is een balk zoals het volgende:

Processing |#############                   | 42/100

Antwoord 7, autoriteit 10%

Ik heb zojuist een eenvoudige voortgangscursus gemaakt voor mijn behoeften nadat ik hier naar een gelijkwaardige oplossing had gezocht. Ik dacht dat ik het misschien wel zou posten.

from __future__ import print_function
import sys
import re
class ProgressBar(object):
    DEFAULT = 'Progress: %(bar)s %(percent)3d%%'
    FULL = '%(bar)s %(current)d/%(total)d (%(percent)3d%%) %(remaining)d to go'
    def __init__(self, total, width=40, fmt=DEFAULT, symbol='=',
                 output=sys.stderr):
        assert len(symbol) == 1
        self.total = total
        self.width = width
        self.symbol = symbol
        self.output = output
        self.fmt = re.sub(r'(?P<name>%\(.+?\))d',
            r'\g<name>%dd' % len(str(total)), fmt)
        self.current = 0
    def __call__(self):
        percent = self.current / float(self.total)
        size = int(self.width * percent)
        remaining = self.total - self.current
        bar = '[' + self.symbol * size + ' ' * (self.width - size) + ']'
        args = {
            'total': self.total,
            'bar': bar,
            'current': self.current,
            'percent': percent * 100,
            'remaining': remaining
        }
        print('\r' + self.fmt % args, file=self.output, end='')
    def done(self):
        self.current = self.total
        self()
        print('', file=self.output)

Voorbeeld:

from time import sleep
progress = ProgressBar(80, fmt=ProgressBar.FULL)
for x in xrange(progress.total):
    progress.current += 1
    progress()
    sleep(0.1)
progress.done()

Zal het volgende afdrukken:

[======== ] 17/80 ( 21%) 63 to go


Antwoord 8, autoriteit 8%

Ik hou van Brian Khuu’s antwoordvanwege zijn eenvoud en omdat ik geen externe pakketten nodig heb. Ik heb het een beetje veranderd, dus ik voeg mijn versie hier toe:

import sys
import time
def updt(total, progress):
    """
    Displays or updates a console progress bar.
    Original source: https://stackoverflow.com/a/15860757/1391441
    """
    barLength, status = 20, ""
    progress = float(progress) / float(total)
    if progress >= 1.:
        progress, status = 1, "\r\n"
    block = int(round(barLength * progress))
    text = "\r[{}] {:.0f}% {}".format(
        "#" * block + "-" * (barLength - block), round(progress * 100, 0),
        status)
    sys.stdout.write(text)
    sys.stdout.flush()
runs = 300
for run_num in range(runs):
    time.sleep(.1)
    updt(runs, run_num + 1)

Het duurt het totale aantal runs (total) en het aantal tot nu toe verwerkte runs (progress) uitgaande van total >= progress. Het resultaat ziet er als volgt uit:

[#####---------------] 27%

Antwoord 9, autoriteit 8%

Je kunt tqdm:

gebruiken

from tqdm import tqdm
with tqdm(total=100, desc="Adding Users", bar_format="{l_bar}{bar} [ time left: {remaining} ]") as pbar:
    for i in range(100):
        time.sleep(3)
        pbar.update(1)

In dit voorbeeld loopt de voortgangsbalk 5 minuten
en het wordt zo weergegeven:

Adding Users:   3%|█████▊                                     [ time left: 04:51 ]                                                                                                        

U kunt het wijzigen en deze aanpassen zoals u wilt.


10, Autoriteit 4%

Ik hou echt van de python-progressbar , want het is heel eenvoudig te gebruiken.

Voor de meest eenvoudige behuizing is het alleen:

import progressbar
import time
progress = progressbar.ProgressBar()
for i in progress(range(80)):
    time.sleep(0.01)

Het uiterlijk kan worden aangepast en het kan de geschatte resterende tijd weergeven. Gebruik voor een voorbeeld dezelfde code als hierboven, maar met:

progress = progressbar.ProgressBar(widgets=[progressbar.Bar('=', '[', ']'), ' ',
                                            progressbar.Percentage(), ' ',
                                            progressbar.ETA()])

11, Autoriteit 3%

Gebruik deze bibliotheek: fish(Github ).

Gebruik:

>>> import fish
>>> while churning:
...     churn_churn()
...     fish.animate()

Veel plezier!


12, Autoriteit 3%

Als het een grote lus is met een vast bedrag van iteraties dat veel tijd kost, kunt u deze functie gebruiken die ik heb gemaakt. Elke iteratie van de lus voegt de voortgang toe. Waar tellen de huidige iteratie van de lus is, is het totaal de waarde die u loopt naar en-formaat (INT) is hoe groot u wilt dat de balk in stappen van 10 IE (maat 1 = 10 tekens, maat 2 = 20 tekens)

import sys
def loadingBar(count,total,size):
    percent = float(count)/float(total)*100
    sys.stdout.write("\r" + str(int(count)).rjust(3,'0')+"/"+str(int(total)).rjust(3,'0') + ' [' + '='*int(percent/10)*size + ' '*(10-int(percent/10))*size + ']')

Voorbeeld:

for i in range(0,100):
     loadingBar(i,100,2)
     #do some code 

Uitgang:

i = 50
>> 050/100 [==========          ]

13, Autoriteit 2%

De onderstaande code is een vrij algemene oplossing en heeft ook een tijd verstreken en de resterende schatting van de tijd. Je kunt er acteur met gebruiken. De voortgangsbalk heeft een vaste grootte van 25 tekens, maar het kan updates in 1% stappen tonen met behulp van volledige, de helft en kwartaalblokkarakters. De uitvoer ziet er als volgt uit:

18% |████▌                    | \ [0:00:01, 0:00:06]

code met voorbeeld:

import sys, time
from numpy import linspace
def ProgressBar(iterObj):
  def SecToStr(sec):
    m, s = divmod(sec, 60)
    h, m = divmod(m, 60)
    return u'%d:%02d:%02d'%(h, m, s)
  L = len(iterObj)
  steps = {int(x):y for x,y in zip(linspace(0, L, min(100,L), endpoint=False),
                                   linspace(0, 100, min(100,L), endpoint=False))}
  qSteps = ['', u'\u258E', u'\u258C', u'\u258A'] # quarter and half block chars
  startT = time.time()
  timeStr = '   [0:00:00, -:--:--]'
  activity = [' -',' \\',' |',' /']
  for nn,item in enumerate(iterObj):
    if nn in steps:
      done = u'\u2588'*int(steps[nn]/4.0)+qSteps[int(steps[nn]%4)]
      todo = ' '*(25-len(done))
      barStr = u'%4d%% |%s%s|'%(steps[nn], done, todo)
    if nn>0:
      endT = time.time()
      timeStr = ' [%s, %s]'%(SecToStr(endT-startT),
                             SecToStr((endT-startT)*(L/float(nn)-1)))
    sys.stdout.write('\r'+barStr+activity[nn%4]+timeStr); sys.stdout.flush()
    yield item
  barStr = u'%4d%% |%s|'%(100, u'\u2588'*25)
  timeStr = '   [%s, 0:00:00]\n'%(SecToStr(time.time()-startT))
  sys.stdout.write('\r'+barStr+timeStr); sys.stdout.flush()
# Example
s = ''
for c in ProgressBar(list('Disassemble and reassemble this string')):
  time.sleep(0.2)
  s += c
print(s)

Suggesties voor verbeteringen of andere opmerkingen worden op prijs gesteld. Proost!


Antwoord 14, autoriteit 2%

Het is vrij eenvoudig in Python3:

  import time
   import math
    def show_progress_bar(bar_length, completed, total):
        bar_length_unit_value = (total / bar_length)
        completed_bar_part = math.ceil(completed / bar_length_unit_value)
        progress = "*" * completed_bar_part
        remaining = " " * (bar_length - completed_bar_part)
        percent_done = "%.2f" % ((completed / total) * 100)
        print(f'[{progress}{remaining}] {percent_done}%', end='\r')
    bar_length = 30
    total = 100
    for i in range(0, total + 1):
        show_progress_bar(bar_length, i, total)
        time.sleep(0.1)
    print('\n')

Antwoord 15, autoriteit 2%

Bij gebruik in jupyter-notebooks werkt het gebruik van normale tqdm niet, omdat de uitvoer op meerdere regels wordt geschreven. Gebruik in plaats daarvan dit:

import time
from tqdm import tqdm_notebook as tqdm
for i in tqdm(range(100))
    time.sleep(0.5)

Antwoord 16

Ik vind deze paginaleuk.

Begint met een eenvoudig voorbeeld en gaat over naar een versie met meerdere threads. Werkt uit de doos. Geen pakketten van derden vereist.

De code ziet er ongeveer zo uit:

import time
import sys
def do_task():
    time.sleep(1)
def example_1(n):
    for i in range(n):
        do_task()
        print '\b.',
        sys.stdout.flush()
    print ' Done!'
print 'Starting ',
example_1(10)

Of hier is een voorbeeld om threads te gebruiken om de draaiende laadbalk te laten draaien terwijl het programma draait:

import sys
import time
import threading
class progress_bar_loading(threading.Thread):
    def run(self):
            global stop
            global kill
            print 'Loading....  ',
            sys.stdout.flush()
            i = 0
            while stop != True:
                    if (i%4) == 0: 
                        sys.stdout.write('\b/')
                    elif (i%4) == 1: 
                        sys.stdout.write('\b-')
                    elif (i%4) == 2: 
                        sys.stdout.write('\b\\')
                    elif (i%4) == 3: 
                        sys.stdout.write('\b|')
                    sys.stdout.flush()
                    time.sleep(0.2)
                    i+=1
            if kill == True: 
                print '\b\b\b\b ABORT!',
            else: 
                print '\b\b done!',
kill = False      
stop = False
p = progress_bar_loading()
p.start()
try:
    #anything you want to run. 
    time.sleep(1)
    stop = True
except KeyboardInterrupt or EOFError:
         kill = True
         stop = True

17

Als uw werk niet in meetbare brokken kan worden afgebroken, kunt u uw functie bellen in een nieuwe thread en de tijd hoe lang het duurt:

import thread
import time
import sys
def work():
    time.sleep( 5 )
def locked_call( func, lock ):
    lock.acquire()
    func()
    lock.release()
lock = thread.allocate_lock()
thread.start_new_thread( locked_call, ( work, lock, ) )
# This part is icky...
while( not lock.locked() ):
    time.sleep( 0.1 )
while( lock.locked() ):
    sys.stdout.write( "*" )
    sys.stdout.flush()
    time.sleep( 1 )
print "\nWork Done"

U kunt de timingprecisie duidelijk verhogen zoals vereist.


18

Ik hou van Gabriel antwoord, maar ik heb het veranderd om flexibel te zijn. U kunt bundellengte naar de functie verzenden en uw voortgangsbalk krijgen met elke gewenste lengte. En je kunt geen voortgangsbalk hebben met nul of negatieve lengte. Ook kunt u deze functie gebruiken zoals gabriel antwoord (kijk naar het voorbeeld # 2).

import sys
import time
def ProgressBar(Total, Progress, BarLength=20, ProgressIcon="#", BarIcon="-"):
    try:
        # You can't have a progress bar with zero or negative length.
        if BarLength <1:
            BarLength = 20
        # Use status variable for going to the next line after progress completion.
        Status = ""
        # Calcuting progress between 0 and 1 for percentage.
        Progress = float(Progress) / float(Total)
        # Doing this conditions at final progressing.
        if Progress >= 1.:
            Progress = 1
            Status = "\r\n"    # Going to the next line
        # Calculating how many places should be filled
        Block = int(round(BarLength * Progress))
        # Show this
        Bar = "[{}] {:.0f}% {}".format(ProgressIcon * Block + BarIcon * (BarLength - Block), round(Progress * 100, 0), Status)
        return Bar
    except:
        return "ERROR"
def ShowBar(Bar):
    sys.stdout.write(Bar)
    sys.stdout.flush()
if __name__ == '__main__':
    print("This is a simple progress bar.\n")
    # Example #1:
    print('Example #1')
    Runs = 10
    for i in range(Runs + 1):
        progressBar = "\rProgress: " + ProgressBar(10, i, Runs)
        ShowBar(progressBar)
        time.sleep(1)
    # Example #2:
    print('\nExample #2')
    Runs = 10
    for i in range(Runs + 1):
        progressBar = "\rProgress: " + ProgressBar(10, i, 20, '|', '.')
        ShowBar(progressBar)
        time.sleep(1)
    print('\nDone.')
# Example #2:
Runs = 10
for i in range(Runs + 1):
    ProgressBar(10, i)
    time.sleep(1)

Resultaat:

Dit is een eenvoudige voortgangsbalk.

Voorbeeld # 1

Voortgang: [### ——-] 30%

Voorbeeld # 2

Voortgang: [|||||||||||| ……..] 60%

Gereed.


19

Ik denk dat ik een beetje laat ben, maar dit zou moeten werken voor mensen die werken met de huidige versies van python 3, aangezien dit “f-strings”gebruikt, zoals geïntroduceerd in Python 3.6 PEP 498:

Code

from numpy import interp
class Progress:
    def __init__(self, value, end, title='Downloading',buffer=20):
        self.title = title
        #when calling in a for loop it doesn't include the last number
        self.end = end -1
        self.buffer = buffer
        self.value = value
        self.progress()
    def progress(self):
        maped = int(interp(self.value, [0, self.end], [0, self.buffer]))
        print(f'{self.title}: [{"#"*maped}{"-"*(self.buffer - maped)}]{self.value}/{self.end} {((self.value/self.end)*100):.2f}%', end='\r')

Voorbeeld

#some loop that does perfroms a task
for x in range(21)  #set to 21 to include until 20
    Progress(x, 21)

Uitvoer

Downloading: [########------------] 8/20 40.00%

Antwoord 20

Ik heb de methode format()gebruikt om een laadbalk te maken. Hier is mijn oplossing:

import time
loadbarwidth = 23
for i in range(1, loadbarwidth + 1):
    time.sleep(0.1) 
    strbarwidth = '[{}{}] - {}\r'.format(
        (i * '#'),
        ((loadbarwidth - i) * '-'),
        (('{:0.2f}'.format(((i) * (100/loadbarwidth))) + '%'))
    )
    print(strbarwidth ,end = '')
print()

Uitvoer:

[#######################] - 100.00%

Antwoord 21

Dit is mijn eenvoudige oplossing:

import time
def progress(_cur, _max):
    p = round(100*_cur/_max)
    b = f"Progress: {p}% - ["+"."*int(p/5)+" "*(20-int(p/5))+"]"
    print(b, end="\r")
# USAGE:
for i in range(0,101):
    time.sleep(0.1) 
    progress(i,100)
print("..."*5, end="\r")
print("Done")

Antwoord 22

Een heel eenvoudige aanpak:

def progbar(count: int) -> None:
    for i in range(count):
        print(f"[{i*'#'}{(count-1-i)*' '}] - {i+1}/{count}", end="\r")
        yield i
    print('\n')

En het gebruik:

from time import sleep
for i in progbar(10):
    sleep(0.2) #whatever task you need to do

Antwoord 23

Hier is een korte oplossing die de laadbalk programmatisch opbouwt (u moet beslissen hoe lang u deze wilt).

import time
n = 33  # or however many loading slots you want to have
load = 0.01  # artificial loading time!
loading = '.' * n  # for strings, * is the repeat operator
for i in range(n+1):
    # this loop replaces each dot with a hash!
    print('\r%s Loading at %3d percent!' % (loading, i*100/n), end='')
    loading = loading[:i] + '#' + loading[i+1:]
    time.sleep(load)

Antwoord 24

Probeer PyProg. PyProg is een open-source bibliotheek voor Python om super aanpasbare voortgangsindicatoren te maken & balken.

Het is momenteel op versie 1.0.2; Het wordt gehost op GitHub en beschikbaar op PYPI (links hieronder). Het is compatibel met Python 3 & AMP; 2 En het kan ook worden gebruikt met QT-console.

Het is echt gemakkelijk te gebruiken. De volgende code:

import pyprog
from time import sleep
# Create Object
prog = pyprog.ProgressBar(" ", "", 34)
# 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()

produceert:

Initial State:
Progress: 0% --------------------------------------------------
When half done:
Progress: 50% #########################-------------------------
Final State:
Progress: 100% ##################################################

Ik heb daadwerkelijk pyprog gemaakt omdat ik een eenvoudige maar super aanpasbare voortgangsbalkbibliotheek nodig had. U kunt het eenvoudig installeren met: pip install pyprog.

Pyprog Github: https://github.com/bill13579/pyprog
PYPI: https://pypi.python.org/pypi/pyprog/


25

U kunt ook verlichten gebruiken. Het belangrijkste voordeel dat u kunt inloggen op hetzelfde moment zonder uw voortgangsbalk te overschrijven.

import time
import enlighten
manager = enlighten.Manager()
pbar = manager.counter(total=100)
for num in range(1, 101):
    time.sleep(0.05)
    print('Step %d complete' % num)
    pbar.update()

Het behandelt ook meerdere voortgangsbars.

import time
import enlighten
manager = enlighten.Manager()
odds = manager.counter(total=50)
evens = manager.counter(total=50)
for num in range(1, 101):
    time.sleep(0.05)
    if num % 2:
        odds.update()
    else:
        evens.update()

26

Een beetje meer generiek antwoord van JELDE015 (krediet voor hem natuurlijk)

Voor het bijwerken van de laadbalk handmatig is:

import sys
from math import *
def loadingBar(i, N, size):
    percent = float(i) / float(N)
    sys.stdout.write("\r"
                     + str(int(i)).rjust(3, '0')
                     +"/"
                     +str(int(N)).rjust(3, '0')
                     + ' ['
                     + '='*ceil(percent*size)
                     + ' '*floor((1-percent)*size)
                     + ']')

en belt het door:

loadingBar(7, 220, 40)

resulteert:

007/220 [=                                       ]  

noem het wanneer u maar wilt met de huidige iwaarde.

Stel de sizein als het aantal tekens de balk

moet zijn


27

Gebruik de Progress Library !

pip install progress

Hier is een aangepaste subklasse die ik heb geschreven om de ETA/Verstreken tijden op te maken in een beter leesbaar formaat:

import datetime
from progress.bar import IncrementalBar
class ProgressBar(IncrementalBar):
    '''
    My custom progress bar that:
       - Show %, count, elapsed, eta
       - Time is shown in H:M:S format
    '''
    message = 'Progress'
    suffix  = '%(percent).1f%% (%(index)d/%(max)d) -- %(elapsed_min)s (eta: %(eta_min)s)'
    def formatTime(self, seconds):
        return str(datetime.timedelta(seconds=seconds))
    @property
    def elapsed_min(self):
        return self.formatTime(self.elapsed)
    @property
    def eta_min(self):
        return self.formatTime(self.eta)
if __name__=='__main__':
    counter = 120
    bar     = ProgressBar('Processing', max=counter)
    for i in range(counter):
        bar.next()
        time.sleep(1)
    bar.finish()

Antwoord 28

Je moet de voortgangsbalk koppelen aan de taak die voorhanden is (zodat deze de voortgang meet :D). Als u bijvoorbeeld een bestand FTP-t, kunt u ftplib vertellen om een buffer van een bepaalde grootte te pakken, laten we zeggen 128K, en dan voeg je aan je voortgangsbalk toe welk percentage van de bestandsgrootte 128k vertegenwoordigt. Als u de CLI gebruikt en uw voortgangsmeter 20 tekens lang is, zou u één teken toevoegen wanneer 1/20e van het bestand is overgedragen.


Antwoord 29

@Massagran: Het werkt goed in mijn programma’s. Verder moeten we een teller toevoegen om de lustijden aan te geven. Deze teller speelt als het argument van de methode update.
Bijvoorbeeld: lees alle regels van een testbestand en behandel ze ergens op. Stel dat de functie dosth()geen betrekking heeft in de variabele i.

lines = open(sys.argv[1]).readlines()
i = 0
widgets=[Percentage(), Bar()]
pbar = ProgressBar(widgets=widgets,maxval=len(lines)).start()
pbar.start()
for line in lines:<pre>
    dosth();
    i += 1
    pbar.update(i)</pre>
pbar.finish()

De variabele iregelt de status van pbarvia de methode update

Other episodes