Fortschrittsbalken in Python

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Benutzeravatar
snafu
User
Beiträge: 6830
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich kenne das Projekt ProgressBar auf PyPi und habe auch einige Ideen davon übernommen. Trotzdem möchte ich den Code neu schreiben und einige Verbesserungen hinzufügen, da das Projekt ja irgendwie tot zu sein scheint. Bis alle Features implementiert sind, wird es noch ein Weilchen dauern, aber hier ein Vorgeschmack. Ich arbeite sehr viel mit Vererbung, weil ich glaube, dass das in dem Fall angebracht ist. Dokumentation habe ich bisher noch gar nicht geschrieben, wohl auch, weil ich den größten Teil erst heute Nachmittag zu Bildschirm gebracht habe. Hier mal ein Verwendungsbeispiel, wie gesagt: Pre-Alpha oder so ;P :

Code: Alles auswählen

In [1]: from progress import ProgressBar, FormattedPercentValue, write_string

In [2]: bar = ProgressBar(0,180, width=70)

In [3]: percentage = FormattedPercentValue(0,180)

In [4]: from time import sleep

In [5]: for i in xrange(1,181):
   ...:     bar.curval = percentage.curval = i
   ...:     s = '{0} {1}'.format(percentage, bar)
   ...:     write_string(s)
   ...:     sleep(.1)
   ...:     
   ...:     
100.0% [===================================================================>]
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Eine Klasse, die die beiden Elemente vereint, würde die Redundanz von deinem Code-Beispiel nehmen und deutlicher eleganter wirken.
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
Benutzeravatar
snafu
User
Beiträge: 6830
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ja, ist mir bewusst. Eine Klasse RendererContainer ist in Arbeit. Bei dem nächsten Code, den ich zeigen werde, wird wahrscheinlich auch ein Dekorator @progress_string dabei sein, der von "seiner" Funktion (beispielhaft sei der Callback von urllib.urlretrieve genannt) nur noch den aktuellen Wert und den Endwert erwartet. Für diejenigen, die das weiterhin händisch machen möchten, werde ich zudem auf die __add__-Methode eines Renderers einen Alias für curval setzen. Und die __add__-Methode des Containers führt dann entsprechend die __add__-Methoden ihrer Renderer aus.

Um ehrlich zu sein, wollte ich erstmal eine Prozentzahl samt animierten Balken haben. Ich bin eher jemand, der lieber ein Ergebnis sieht und sich anschließend um die Feinheiten in der Struktur kümmert. Zuviel Nachdenken über theoretische Details verdirbt mir nämlich auf Dauer die Lust an einem Projekt. Wobei das Design IMHO sooo schlecht gar nicht ist. Es fehlt quasi noch etwas an den gewissen Shortcuts, die eine API wirklich komfortabel machen.
Benutzeravatar
snafu
User
Beiträge: 6830
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich hab nochmal etwas umgebaut:

Code: Alles auswählen

In [1]: from time import sleep

In [2]: from callisto import ProgressValue, write_string

In [3]: progress = ProgressValue()

In [4]: progress.end = 180

In [5]: progress.renderers['pbar'].width = 70

In [6]: for i in xrange(1, 181):
   ...:     progress.current = i
   ...:     write_string(progress.render('{percent} {pbar}'))
   ...:     sleep(.1)
   ...:     
   ...:     
100.0% [===================================================================>]
Den Code dazu gibt's hier. Die Verrenkung mit der Breite wird man später nicht mehr machen müssen, da ich Funktionalität einbauen werde, die automatisch erkennen soll, wieviel Platz noch für den Fortschrittsbalken übrig ist. Mit dem angekündigten Dekorator wird dann alles auch nochmal etwas schöner. Zusätzlich baue ich Hilfen zum Testen ein, so dass man bereits eine Ausgabe erhalten kann, wenn man nur xrange() übergibt. Übrigens hoffe ich, das mit den automatischen Zuweisungen der Formatier-Argumente ist nicht zu magisch geworden.
Benutzeravatar
snafu
User
Beiträge: 6830
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich mal wieder. Das versprochene Feature, bei dem sich der Prozentbalken anpasst, ist enthalten. Zudem gibt es nun ".done()" für den ProgressValue, welches bei Bedarf von einem entsprechenden Renderer implementiert werden kann - mein Rotator macht das z.B.

Naja, vielleicht kommt ja in nächster Zeit noch Rückmeldung. Mir jedenfalls macht das Projekt Spaß. Achso, die API wurde auch nochmal ein bißchen verbessert. Ein simpler Test kann so ausgeführt werden:

Code: Alles auswählen

callisto.test('{percent} {pbar} {rotator}')
TODO u.a.:
- Rausfinden, wieso der Rotator plötzlich bei sehr kurzen Intervallen nicht mehr die Bremse zieht, so wie es eigentlich durch den Ticker bereitgestellt werden sollte und IMHO auch in vorherigen Versionen wurde.
- Implementieren von Zeit und Datenübertragungsraten mit einigermaßen intelligenter Nutzung der Maßeinheiten
- Hilfsfunktion, um die Ausgabe eines laufenden Prozesses verarbeiten zu können
usw...

http://paste.pocoo.org/show/208849/

Huch, Zeile 58 ist ein Übrigbleibsel, das da eigentlich nicht mehr stehen sollte. :lol:
Twilo
User
Beiträge: 109
Registriert: Mittwoch 10. Januar 2007, 19:17
Wohnort: Berlin
Kontaktdaten:

Hallo,

gibt es etwas vergleichbares für Windows, was auch unter Linux funktioniert?

mfg
Twilo

EDIT: was haltet Ihr von python-progressbar?
[url=http://www.farb-tabelle.de/][b]Farbtabelle[/b][/url]
Benutzeravatar
snafu
User
Beiträge: 6830
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Etwas für Windows, das auch unter Linux läuft, entspricht ja dem, was man landläufig als "plattformunabhängig" bezeichnen würde. Genau so etwas habe ich vor. Das von dir genannte Tool habe ich ja selbst im OP erwähnt und ich will meins als eine Art Nachfolger herausbringen. Es soll später im Großen und Ganzen die Funktionalität von `python-progressbar` unterstützen - nur eben anders strukturiert - sowie weitere Features.

Was übrigens die Abhängigkeit von Curses angeht, so könnte man sich unter Windows z.B. den Python 2.6 Port von `wcurses` installieren (http://www.lfd.uci.edu/~gohlke/pythonlibs/). Das mag nur zur Ermittlung der Terminalgröße noch etwas Overkill sein, aber ich will früher oder später auch "Inverse-Gimmicks" einbauen. Ein Beispiel wäre Schrift im Fortschrittsbalken, die im entsprechend durchlaufenen (weißen) Bereich die Gegenfarbe annimmt. Ich hoffe, `wcurses` hat das implementiert. Generell sollen wahrscheinlich auch Farben unterstützt werden.

Auch hatte ich ja schon das live-mäßige Auslesen von Prozess-Ausgaben erwähnt. Fernziel ist hier ein intelligenter Parser, der typische Fortschrittsangaben erkennt und in `ProgressValue`s umwandelt, so dass diese Angaben nicht nur isoliert, sondern auch in verändertem Design angezeigt werden können. Dazu würden dann natürlich auch GUI-Toolkits zählen, die den Prozess starten, Callisto die niederen Arbeiten erledigen lassen und nur noch die resultierenden Werte mit ihren grafischen Elementen verknüpfen. Dies ist aber wie gesagt noch Zukunftsmusik. Erstmal werden die häufig gebrauchten Prozess-Widgets zu Ende implementiert und dann auch mal released, sobald ich der Meinung bin, dass die API sich ausreichend gefestigt hat.
Twilo
User
Beiträge: 109
Registriert: Mittwoch 10. Januar 2007, 19:17
Wohnort: Berlin
Kontaktdaten:

Hallo,

gibt es wcurses auch für python2.5 oder mod_python für python2.6?
Immer diese Abhängigkeiten :?

mfg
Twilo
[url=http://www.farb-tabelle.de/][b]Farbtabelle[/b][/url]
lunar

Was genau hat mod_python nun mit diesem Thema zu tun?!
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

lunar hat geschrieben:Was genau hat mod_python nun mit diesem Thema zu tun?!
Außerdem sollte man sowieso WSGI verwenden...
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
Twilo
User
Beiträge: 109
Registriert: Mittwoch 10. Januar 2007, 19:17
Wohnort: Berlin
Kontaktdaten:

Hallo,
lunar hat geschrieben:Was genau hat mod_python nun mit diesem Thema zu tun?!
auf dem Rechner läuft ein Apache mit mod_python. Da es mod_python nicht für python2.6 gibt(?), wurde python2.5 installiert.

Auf dem gleichen Rechner wollte ich in der Konsole einen Fortschrittsbalken ausgeben.

mfg
Twilo
[url=http://www.farb-tabelle.de/][b]Farbtabelle[/b][/url]
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Twilo hat geschrieben:auf dem Rechner läuft ein Apache mit mod_python. Da es mod_python nicht für python2.6 gibt(?), wurde python2.5 installiert.
Du kannst/solltest trotzdem WSGI verwenden. Zum Deploy kannst du immer noch mod_python verwenden.

Siehe dazu auch in der Python-Dokumentation "HOWTO Use Python in the web", hier ein Ausschnitt.
These are the reasons why mod_python should be avoided when writing new programs. In some circumstances it might be still a good idea to use mod_python for deployment, but WSGI makes it possible to run WSGI programs under mod_python as well.
Eine ausführliche, deutsche Einführung in WSGI findest du außerdem hier:
http://docs.google.com/fileview?id=0Bxc ... MzAw&hl=en
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
Benutzeravatar
snafu
User
Beiträge: 6830
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Bitte tut mir den Gefallen und lasst das jetzt nicht ausufern...
Benutzeravatar
snafu
User
Beiträge: 6830
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Moin,

ich hatte mal wieder die Muße, ein bißchen was zu machen. Callisto unterstützt jetzt mehrzeilige Templates und erkennt bei Dateigrößen automatisch eine passende Einheit samt Umrechnung. Ob das genau so intelligent implementiert wurde, überlasse ich dem Leser... Hier dann mal ein erstes Beispiel, wie man es evtl später in-the-wild finden könnte:

Code: Alles auswählen

from contextlib import closing
from urllib import urlopen, urlretrieve
from callisto import ProgressValue

URL = 'http://python.org/ftp/python/2.6.5/Python-2.6.5.tar.bz2'

TEMPLATE = """
Downloading python 2.6.5 source-file... ({cursize} of {totsize})
{pbar} {percent}"""

def download_pysource(url=URL, template=TEMPLATE):
    with closing(urlopen(url)) as pysource:
        filesize = int(pysource.info()['Content-Length'])
    progress = ProgressValue(template=template, end=filesize)

    urlretrieve(url, reporthook=lambda blks,bsize,_: progress.render(blks*bsize))
    progress.done()
Das Ding funktioniert definitiv nur mit Unix - sorry dafür. Habe aber inzwischen Infos gefunden, wie man unter Windows mittels `ctypes.windll` die Terminalgröße rauskriegt und den Text einfärben kann. Das sieht im Großen und Ganzen alles etwas ordentlicher aus als das bekannte Beispiel mit `struct` und so (IMHO). Nach dem Ausprobieren von `wcurses` und etwas, das auf `PDCurses` aufbaut, bin ich doch etwas enttäuscht und werde mich halt selbst an die Sache machen. Wobei Windows-Support wohl eher zu den mittelfristigen Zielen gehören wird. Gibt vieles anderes, was mir momentan wichtiger erscheint.

Nochwas: Der "Progress" sollte grundsätzlich mit `.done()` abgeschlossen werden, damit die Klassen ein letztes Mal rendern und Abschlussarbeiten durchführen können. Ich hatte das ja schon vorher mal erwähnt. Wahrscheinlich werde ich den Nutzer letztlich mittels Contextmanager zu seinem Glück zwingen, aber das kommt ein ander Mal - wie auch die Doku. :)

Der Code: http://www.python-forum.de/pastebin.php?mode=view&s=9
Antworten