Seite 1 von 1

Print printet nichts

Verfasst: Dienstag 18. September 2007, 09:59
von stefan3003
Hallo,

ich habe ein Programm was für eine unbestimmte Zeit läuft, nun dachte ich mir es sei doch nett wenn auf dem Bildschirm irgendwas kleines passiert. Leichter gesagt als getan ;-| Bei folgendem Code wird leider nichts in der Konsole ausgegeben:

Code: Alles auswählen

#!/usr/bin/env python

import time

spinchars="|/-\\"
spinlen = len(spinchars)
x = 0
for i in range(600):
    if x >= spinlen:
        x = 0
    print spinchars[x],
    x=x+1
    time.sleep(0.1)
Es scheint an dem

Code: Alles auswählen

print spinchars[x],
zu liegen, wenn ich das "," entferne wird mit Newline geprintet, sieht aber nicht so toll aus. Meine eigentliche Idee war

Code: Alles auswählen

print "\r", spinchars[x],
(also ein Zeichen ohne Newline ausgeben und beim nächsten Aufruf wird es einfach gelöscht und dann überschrieben) aber wieso wird absolut garnichts ausgegeben bzw. wie mache ich es riichtig ? ;)

Vielen Dank für eure Hilfe im Vorraus,
Stefan

Verfasst: Dienstag 18. September 2007, 10:14
von CM
Hoi,

habe gerade nicht viel Zeit, also:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import time
import sys

spinchars="|/-\\"
spinlen = len(spinchars)
x = 0
for i in range(50):
    if not (x % spinlen):
        x = 0
    sys.stdout.write("%s\r" % spinchars[x])
    sys.stdout.flush()
    x += 1
    time.sleep(0.1)
oder aus einer aktuellen Anwendung von mir:

Code: Alles auswählen

def _progress_write(fraction):
    """
        writes out progress bar on the command line,
        requires fraction of the completed total

        invoke like:
        _progress_write(fraction), where fraction is a float
    """
    sys.stdout.write('    completed [')
    index = 0
    for i in xrange(20):
        if (fraction * 20) > index:
            sys.stdout.write('-')
        else:
            sys.stdout.write(' ')
        index += 1
    sys.stdout.write('] %.1f %s\r' % (fraction*100, chr(37)))
    sys.stdout.flush()
Damit solltest Du weiterbasteln können.
Viel Erfolg!

Gruß,
Christian

Verfasst: Dienstag 18. September 2007, 10:20
von stefan3003

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import time
import sys

spinchars="|/-\\"
spinlen = len(spinchars)
x = 0
for i in range(50):
    if not (x % spinlen):
        x = 0
    sys.stdout.write("%s\r" % spinchars[x])
    sys.stdout.flush()
    x += 1
    time.sleep(0.1)
Super! Vielen Dank! :-) Hast du noch eine Idee warum das mit 'print' nicht geht ?

Gruß,
Stefan

Verfasst: Dienstag 18. September 2007, 10:23
von CM
Mach mal

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import time
import sys

spinchars="|/-\\"
spinlen = len(spinchars)
x = 0
for i in range(50):
    if not (x % spinlen):
        x = 0
    time.sleep(0.1)
    print '\r',spinchars[x],
    sys.stdout.flush()
    x += 1
Na, fällt Dir was auf?

Gruß,
Christian

edit: irritierenden Nonsens entfernt

Verfasst: Dienstag 18. September 2007, 10:57
von BlackJack
Etwas kürzere Variante bei der man sich nicht mit der Indexierung herumschlagen muss:

Code: Alles auswählen

import sys
import time
from itertools import cycle

def main():
    spinchars_iterator = cycle('|/-\\')
    for i in xrange(50):
        time.sleep(0.1)
        print '\r', spinchars_iterator.next(),
        sys.stdout.flush()

Verfasst: Dienstag 18. September 2007, 11:27
von Y0Gi
Verdammt, da war BlackJack mit `cycle` schneller da ;)

Sowas ähnliches habe ich auch mal geschrieben und immer mal wieder überarbeitet. U.a. verwende ich nur soviele Rückschritte (mittels `\b`) wie erforderlich und stelle dabei auch einen Fortschrittsbalken dar. Letztlich bin ich doch überrascht, in wie wenig Code das mittlerweile zu machen ist.[/list]

Verfasst: Mittwoch 19. September 2007, 11:59
von stefan3003
Oh! Natürlich. Immer artig flushen nicht vergessen ;)
Vielen Dank an alle! :)

Verfasst: Mittwoch 19. September 2007, 12:33
von HWK
@BlackJack: Zeile 10 ist ja wohl nur nötig, wenn man in Zeile 9 in sys.stdout schreibt? Mit print statt sys.stdout.write klappt es aber in der Konsole durchaus auch.
MfG
HWK

Verfasst: Mittwoch 19. September 2007, 12:37
von gerold
HWK hat geschrieben:Zeile 10 ist ja wohl nur nötig, wenn man in Zeile 9 in sys.stdout schreibt?
Hallo HWK!

Ich glaube (will es jetzt nicht nachprüfen), dass da kein Unterschied bezüglich flush(), zwischen ``sys.stdout.write()`` und ``print``, existiert.

mfg
Gerold
:-)

Verfasst: Mittwoch 19. September 2007, 12:49
von HWK
@Gerold: Mag sein. Bei mir funktionieren beide Varianten (print bzw. sys.stdout.write) ohne flush in der Konsole. In Idle wird natürlich nur Unsinn angezeigt.

Verfasst: Mittwoch 19. September 2007, 12:49
von CM
Gerold, das ist korrekt. Das flush() ist nicht immer notwendig, aber u. U. schon. Und man will ja keine längere Rechnung ausführen, schreibt sich eine progress bar (oder so) und sieht dann bloß einen erratischen Update. Daher mag es hier überflüssig sein, allgemein aber wohl eher nicht.

Gruß,
Christian

PS Danke BJ für die Klarstellung.

Verfasst: Mittwoch 19. September 2007, 14:13
von gerold
Ups :lol:

Mir ging es nicht darum, herauszustellen ob flush in den Beispielen verwendet werden soll oder nicht. Mir ging es einzig darum, dass ich nicht glaube, dass ``print`` automatisch ein flush nachschiebt und sys.stdout.write nicht.

print ist für mich bis jetzt nie etwas anderes gewesen als ein Synonym für

Code: Alles auswählen

def print(*args):
    sys.stdout.write("%s\n" % (" ".join(args)))
Ohne an die Spezialfälle, wie z.B. die Umleitung in eine Datei, zu denken.

lg
Gerold
:-)

Verfasst: Mittwoch 19. September 2007, 20:57
von birkenfeld
Oh, das sind nicht die einzigen Unterschiede. Man denke an die trailing-comma-Regel und an softspace. Außerdem gibt es für C-Objekte einen eigenen tp_print-Slot. Theoretisch kann also "print x" und "write(str(x))" etwas völlig anderes ausgeben.