Seite 1 von 1
Probleme mit Wagenrücklauf beim erstellen eines Countdowns
Verfasst: Sonntag 19. Mai 2013, 15:46
von Avantasia1975
Hallo liebe Gemeinde,
ich bin grade dabei einen Countdown zu basteln und möchte das mir die Zeit in der Konsole angezeigt wird.
Hierbei möchte ich, das es immer in der selben Zeile geschieht. Hierbei benutze ich nun die Escapesequenze "\r".
So wie ich das verstanden habe setzt dies den Cursor ja an den Anfang der Zeile zurück. Leider wird bei mir aber nichts angezeigt.
Nur die letzte Zeile bekomme ich zu Gesicht. Zuerst dachte ich, das "\r" nicht nur zum Anfang springt, sondern die Zeile auch löscht.
Dann verstehe ich aber nicht, wieso ich die letzte Zahl zu Gesicht bekomme.
Tut mir leid wenn ich euch mit so einer banalen Frage belästige.
Hier einfach mal mein Anfang
Code: Alles auswählen
#!/usr/bin/env python
from time import sleep
ms = 60
while True:
sleep(0.05)
ms = ms - 1
print "00:00:{}\r".format(ms),
if ms == 0:
break
[/code]
Gruß
Andi
Re: Probleme mit Wagenrücklauf beim erstellen eines Countdow
Verfasst: Sonntag 19. Mai 2013, 16:01
von Sirius3
@Avantasia1975: Zeilen werden normalerweise erst angezeigt, wenn sie mit einem Zeilenumbruch '\n' abgeschlossen werden. »flush« hilft.
Code: Alles auswählen
#!/usr/bin/env python
import sys
import time
for ms in xrange(60,-1,-1):
time.sleep(0.05)
sys.stdout.write("00:00:{}\r".format(ms))
sys.stdout.flush()
Re: Probleme mit Wagenrücklauf beim erstellen eines Countdow
Verfasst: Sonntag 19. Mai 2013, 16:03
von Avantasia1975
Ahh ok.
Vielen Dank.
Re: Probleme mit Wagenrücklauf beim erstellen eines Countdow
Verfasst: Dienstag 24. September 2013, 19:22
von Avantasia1975
Sorry wenn ich das hier nochmal aufwärme.
Beim letzten mal habe ich das so hingenommen und mich gefreut, dass es geklappt hat.
Nun möchte ich es aber verstehen
Kann das mal einer für Dummie's erklären?
So wie ich das verstehe wird erstmal alles in einen Buffer aufgenommen und erst bei einem \n bzw "enter" gesendet wird.
Was bewirkt flush nun an der Stelle?
Wenn ich eine Zeile
print "Bla",
habe sende ich doch auch kein \n aber dennoch wird die Zeile angezeigt.
So wie Sirius3 es geschrieben hat, hat es ja dann geklappt und ich kann die Zeit sehen.
Wenn ich allerdings ein
python -c "import sys,time;sys.stdout.write('Hallo\r');sys.stdout.flush()"
ausführe kann ich das "Hallo" nicht sehen. Wieso kann ich aber die Zahl in dem Script sehen? Sollte die Ausgabe nicht von flush gelöscht werden?
Fragen über Fragen.
Ich hoffe mir kann das jemand halbwegs verständlich erklären.
Gruß Andi
€
Ok ich glaube ich habe es langsam.
Flush leer den buffer und schreibt den inhalt nach stdout.
Das hier kein \n Zeichen kommt, kann \r greifen.
Soweit richtig?
Re: Probleme mit Wagenrücklauf beim erstellen eines Countdow
Verfasst: Dienstag 24. September 2013, 19:51
von mutetella
Avantasia1975 hat geschrieben:Wenn ich allerdings ein
python -c "import sys,time;sys.stdout.write('Hallo\r');sys.stdout.flush()"
ausführe kann ich das "Hallo" nicht sehen.
Du kannst das "Hallo" nicht sehen, weil alles zu schnell geht...

Zuerst wird "Hallo" geschrieben, danach wird auf den Zeilenanfang gesprungen, danach wiederum übernimmt das Terminal und überschreibt das "Hallo".
Versuche mal folgendes, dann siehst Du es (zudem hat das importierte `time` dann auch einen Sinn

):
Code: Alles auswählen
python -c "import sys,time;sys.stdout.write('Hallo\r');sys.stdout.flush();time.sleep(1)"
mutetella
Re: Probleme mit Wagenrücklauf beim erstellen eines Countdow
Verfasst: Dienstag 24. September 2013, 19:53
von BlackJack
@Avantasia1975: Die Ausgabe wird in einen Pufferspeicher geschrieben und erst rausgeschrieben wenn entweder ein '\n' in dem Puffer landet, oder der Puffer voll ist, oder `flush()` ausgeführt wird (, oder `close()` was ein `flush()` impliziert).
Bei ``print 'Blah',`` siehst Du das Blah normalerweise nicht. Nur wenn das Programm zuende ist, denn dann wird natürlich auch der Puffer gelehrt weil am Ende auf allen offenen Dateien `close()` aufgerufen wird (zumindest auf Systemebene, nicht unbedingt die `close()`-Methode). Wenn die letzte Ausgabe auf `sys.stdout` ein ``print`` mit einem Komma am Ende war greift noch die besonderheit, dass der Pythoninterpreter beim beenden dann noch ein '\n' ausgibt. Aber nur wenn man ``print`` verwendet hat, nicht wenn man direkt mit `sys.stdout.write()` geschrieben hat.
Bei dem ``python -c …``-Beispiel wird also sehr wohl 'Hallo' ausgegeben und dann wird der Cursor auf den Anfang der Zeile gesetzt und das Programm endet. Und der Prompt vom Betriebssystem überschreibt dann das 'Hallo'. Gib da mal was aus was länger als der Prompt ist, und Du wirst nach dem Prompt den Rest davon sehen.
Re: Probleme mit Wagenrücklauf beim erstellen eines Countdow
Verfasst: Mittwoch 25. September 2013, 18:08
von Avantasia1975
Super vielen Dank.
Ich hatte dann selber mal ein sleep ans Ende gesetzt und dann eben das "Hallo" gesehen.
Das beim schliessen bzw, beenden eines Programms quasi automatisch ein \n gesetzt wird erklärt das also.
Nu ist das alles klar.
Vielen Dank für die schnellen Antworten und einen schönen Abend noch.
Gruß
Andi
Re: Probleme mit Wagenrücklauf beim erstellen eines Countdow
Verfasst: Mittwoch 25. September 2013, 18:49
von mutetella
Avantasia1975 hat geschrieben:Das beim schliessen bzw, beenden eines Programms quasi automatisch ein \n gesetzt wird erklärt das also.
[korinthenkackerei]Stimmt so nicht ganz. Du gibst 'Hallo' aus und setzt den Cursor an den Anfang der Zeile zurück. Beim Beenden des Programms steht der Cursor weiterhin dort. Nun schreibt Deine Shell den prompt-Text ab der aktuellen Cursorposition. Ein automatisches '\n' wird weder vom Programmende noch von der Shell initiiert.[/korinthenkackerei]
Das alles gilt, solange Du, wie in Deinem Beispiel, nicht `print` verwendest sondern Deine Ausgabe direkt an `sys.stdout` schickst. Wie `print` arbeitet hat Dir ja BlackJack schon erklärt.
mutetella