Ich bearbeite in der Konsole nacheinander viele Dateien. Wenn ich während dieser Zeit nix ausgebe, könnte man (bei einer leisen Festplatte) auch meinen, das Programm sei abgestürzt.
Ich will dem Anwender also verdeutlichen, welche Datei gerade bearbeitet wird. Eine Ausgabe mit print erzeugt eine unübersichtlich lange Ausgabe. Ich hätte es gern, dass nur auf einer Zeile der aktuelle Dateiname ausgegeben wird. Die nächste Datei wird dann also über den Platz der ersten geschrieben. Somit wird immer nur eine Zeile "verschwendet" und man weiß aber, das das Programm beschäftigt ist.
Wie realisiert man das? Mit print komme ich nicht weiter. Hab mir sys.stdout.write() angesehen, aber da hab ich auch nix zum "überschreiben" entdeckt. Geht das überhaupt?
Konsole: Busy-Anzeige
Code: Alles auswählen
sys.stdout.write('Working on ... %s \r' % fname)
sys.stdout.flush()
Dich interessiert vielleicht noch eine Liste von Escape-Charaktären:
\e Write an <escape> character.
\a Write a <bell> character.
\b Write a <backspace> character.
\f Write a <form-feed> character.
\n Write a <new-line> character.
\r Write a <carriage return> character.
\t Write a <tab> character.
\v Write a <vertical tab> character.
\' Write a <single quote> character.
\\ Write a backslash character.
\num Write an 8-bit character whose ASCII value is the 1-, 2-, or 3-digit octal number num.
Solche Listen sind für jede Shell / Konsole leicht zu "ergoogeln" und - von leichten Variationen - stets recht ähnlich.
Gruß,
Christian
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
Carriage return (\r) setzt den Cursor an den Anfang der Zeile:
EDIT: Da war wer schneller!
Code: Alles auswählen
#!/usr/bin/env python
import sys
import time
sys.stdout.write("Hallo Welt!")
sys.stdout.flush()
time.sleep(1)
sys.stdout.write("\rWas anderes...")
sys.stdout.flush()
time.sleep(1)
sys.stdout.write("\n")
Hmmm. Das funzt bei mir, aber meine Version geht nicht... Ich versuch das mal auf ein paar Zeilen runter zu brechen... kommt gleich.Rebecca hat geschrieben:Carriage return (\r) setzt den Cursor an den Anfang der Zeile:Code: Alles auswählen
import sys import time sys.stdout.write("Hallo Welt!") sys.stdout.flush() time.sleep(1) sys.stdout.write("\rWas anderes...") sys.stdout.flush() time.sleep(1) sys.stdout.write("\n")
P.S. Was macht das 'flush()'?
Hmm, das is ja seltsam. Wenn ich immer nur einen konstanten Wert mit write() schreibe, also z.B. write("\r%s" % "..."), dann geht's. Aber wenn ich meinen Dateinamen reinschreibe, also write("\r%s" % filePath), dann erscheinen weiterhin alle untereinander, so als würde ich print benutzen...
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
stdout ist gepuffert (Filedescriptor!), ohne flush kriegt man die Ausgabe nicht sofort auf den Bildschrim geschrieben, sondern wenn der Buffer voll ist.droptix hat geschrieben: P.S. Was macht das 'flush()'?
Vielleicht hat der Inhalt von filePath noch ein \n am Ende? Mach mal repr(filePath)...droptix hat geschrieben:Hmm, das is ja seltsam. Wenn ich immer nur einen konstanten Wert mit write() schreibe, also z.B. write("\r%s" % "..."), dann geht's. Aber wenn ich meinen Dateinamen reinschreibe, also write("\r%s" % filePath), dann erscheinen weiterhin alle untereinander, so als würde ich print benutzen...
Das geht nicht: Ich übergebe an das Script einen Pfad im Dateisystem. Den hab ich jetzt mal künstlich festgelegt:
So bekomme ich alle Dateinamen untereinander. Das mit dem "\n" am Anfang oder Ende hatte ich auch schon überlegt und überprüft per:
Aber "shit" kam nie. Also hab ich mal nicht den Dateinamen, sondern eine Konstante ausgegeben. Komischweise kommt das nicht untereinander:
Also muss es am Dateiname uri liegen...
Code: Alles auswählen
import sys, os, time
sys.argv.append(r"C:\Dokumente und Einstellungen\All Users\Dokumente")
if sys.argv[1]:
for path, dirs, files in os.walk(sys.argv[1]):
for file in files:
uri = os.path.join(path, file)
# busy...
sys.stdout.write("\r%s" % uri)
sys.stdout.flush()
time.sleep(0.01)
Code: Alles auswählen
if uri.startswith("\n") or uri.endswith("\n"):
print "shit"
Code: Alles auswählen
import sys, os, time
sys.argv.append(r"C:\Dokumente und Einstellungen\All Users\Dokumente")
if sys.argv[1]:
for path, dirs, files in os.walk(sys.argv[1]):
for file in files:
uri = os.path.join(path, file)
# busy...
sys.stdout.write("\r%s" % "...")
sys.stdout.flush()
time.sleep(0.01)
repr(uri) ergibt gar nichts. Ich hab mal den Sleep-Timer erhöht und konnte feststellen, dass doch in einigen Zeilen der Dateiname überschrieben wird. Bei anderen wiederum wird mit einer neuen Zeile begonnen. Seltsam.
[edit] Aaaaaaaaaaaah. Wenn der Dateiname sooo lang ist, dass er nciht auf eine Zeile in der Konsole passt, dann wird natürlich ein automatischer Umbruch erzeugt. Dummerweise wird dann nur der Bereich der zweiten (bzw. letzten) Zeile mittels "\r" überschrieben. Also muss ich die Ausgabe auf z.B. 79 Zeichen begrenzen...
Kann ich die Breite der Konsole auslesen, damit ich diese statische Zahl 79 umgehen kann? Eigentlich ist die Standard-Windows-Konsole 80 Zeichen breit, aber die kann man ja verbreitern (wie unter Unixen auch).
[edit] Aaaaaaaaaaaah. Wenn der Dateiname sooo lang ist, dass er nciht auf eine Zeile in der Konsole passt, dann wird natürlich ein automatischer Umbruch erzeugt. Dummerweise wird dann nur der Bereich der zweiten (bzw. letzten) Zeile mittels "\r" überschrieben. Also muss ich die Ausgabe auf z.B. 79 Zeichen begrenzen...
Kann ich die Breite der Konsole auslesen, damit ich diese statische Zahl 79 umgehen kann? Eigentlich ist die Standard-Windows-Konsole 80 Zeichen breit, aber die kann man ja verbreitern (wie unter Unixen auch).
Womöglich schon - kenne mich mit Windows nicht so aus - aber glaube mir: Das willst Du nicht!
Es ist - meiner bescheidenen Erfahrung und meiner unmaßgeblichen Meinung nach - besser derartige Pfadangaben einzukürzen (z. B. nur den eigentlichen Dateinahmen zu nehmen oder best. Ordner durch ... zu ersetzen). Auf diese Weise ist eine solche Ausgabe lesbarer und nachvollziebar. Wenn ewig lange Zeilen über den Schirm huschen sieht das zwar für Deine Kollegen so aus, als würdest Du ganz doll und viel arbeiten, aber hilft doch eigentlich nicht weiter
.
Gruß,
Christian
Es ist - meiner bescheidenen Erfahrung und meiner unmaßgeblichen Meinung nach - besser derartige Pfadangaben einzukürzen (z. B. nur den eigentlichen Dateinahmen zu nehmen oder best. Ordner durch ... zu ersetzen). Auf diese Weise ist eine solche Ausgabe lesbarer und nachvollziebar. Wenn ewig lange Zeilen über den Schirm huschen sieht das zwar für Deine Kollegen so aus, als würdest Du ganz doll und viel arbeiten, aber hilft doch eigentlich nicht weiter

Gruß,
Christian
Sehr lustig... denn genau das hatte ich heute Nachmittag bereits gemacht
Also die Dateinamen für die Ausgabe eingestampft. Schon erledigt quasi.
Was mir auch noch aufgefallen ist: ein carriage return setzt ja wirklich nur den Cursor auf die Anfangszeile, löscht diese aber nicht. Also muss ich "alte Reste" der vorherigen Ausgabe fein mit Leerzeichen überschreiben. Oder kann man die Zeile auch komplett leeren?


Was mir auch noch aufgefallen ist: ein carriage return setzt ja wirklich nur den Cursor auf die Anfangszeile, löscht diese aber nicht. Also muss ich "alte Reste" der vorherigen Ausgabe fein mit Leerzeichen überschreiben. Oder kann man die Zeile auch komplett leeren?
Was meinst du damit? Das ist bei Unixen mit langen Pfaden doch genau dasselbe... Das Python-Tool ist eh ein Multiplattform-ToolCM hat geschrieben:Womöglich schon - kenne mich mit Windows nicht so aus - aber glaube mir: Das willst Du nicht!

Moin,
Bzgl. \r: Du kannst entweder Leerzeichen nehmen oder 'x * \b' einsetzen. Beides dirty hacks, aber ich weiß nichts besseres - jemand mit einer besseren Idee? (Ich gebe frei zu meist einfach ein paar Leerzeichen an die Ausgabe, s.o., zu hängen ...)
Gruß,
Christian
damit meine ich, daß der Aufwand nicht das Ergebnis rechtfertigt und Du nicht glücklich mit den vergrößerten Konsolenfenstern sein wird. Na gut, da kann ich mich irren und das Ausrufezeichen war sicher überflüssig ...droptix hat geschrieben:Was meinst du damit?
Bzgl. \r: Du kannst entweder Leerzeichen nehmen oder 'x * \b' einsetzen. Beides dirty hacks, aber ich weiß nichts besseres - jemand mit einer besseren Idee? (Ich gebe frei zu meist einfach ein paar Leerzeichen an die Ausgabe, s.o., zu hängen ...)
Gruß,
Christian
Und ich gestehe, dass ich das ganz clever auch mit Leerzeichen löse, nämlich so

Code: Alles auswählen
# quick 'n' dirty
import sys, string, time
maxlen = 30
abbrev = "..."
abslen = maxlen - len(abbrev)
def p(m):
global maxlen, abbrev, abslen
if len(m) > maxlen:
m = string.join([m[:abslen], abbrev], "")
sys.stdout.write("\r%s\r%s" % (maxlen * " ", m))
sys.stdout.flush()
p("Hello world it's python!")
time.sleep(1)
p("I'm really great!")
time.sleep(1)
p("Believe me!")
time.sleep(1)
Eindroptix hat geschrieben:Code: Alles auswählen
sys.stdout.write("\r%s\r%s" % (maxlen * " ", m))
Code: Alles auswählen
sys.stdout.write("\r%*s" % (-maxlen, m))
(Für konstante maxlen von 60 geht z.B. auch "\r%-60s" % m)
Noch ein Hinweis: Wenn die bearbeitung pro Datei nicht lange dauert, ist es besser, nicht jede Datei einzeln anzuzeigen. Ansonsten verbringt das Programm mehr mit dem Anzeigen der Dateinamen als mit der eigentlichen Aufgabe.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Ich weiß, dass es etwas spät ist, aber besser spät als nie: Ein Rezept, heute per DPU gefunden.droptix hat geschrieben:Kann ich die Breite der Konsole auslesen, damit ich diese statische Zahl 79 umgehen kann? Eigentlich ist die Standard-Windows-Konsole 80 Zeichen breit, aber die kann man ja verbreitern (wie unter Unixen auch).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Jup, genau. Damit hätten wir auch einen Post der erklärt was DPU ist. Die Suchfunktion wirds freuen, wenns mal jemanden interessiert. Nur die für die Suchfunktion interessiert sich kaum einer.Joghurt hat geschrieben:Edit: Ah! Daily Python URL
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice