Erste Versuche mit Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
miwue45
User
Beiträge: 2
Registriert: Freitag 16. Dezember 2022, 17:13

Meine Konsole sieht so aus:

Python 3.10.7 (main, Nov 24 2022, 19:45:47) [GCC 12.2.0]
Type "copyright", "credits" or "license" for more information.

IPython 7.31.1 -- An enhanced Interactive Python.

[SpyderKernelApp] WARNING | debugpy_stream undefined, debugging will not be enabled


Wollte testen, wie man einen Programmablauf unterbrechen und wieder starten kann:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 14 17:19:22 2022

@author: michael
"""

durchgang = 1
while durchgang < 50:
print(durchgang)
durchgang = durchgang + 1
input("Press Enter to continue")


Ergebnis:

1
Press Enter to continue
2Press Enter to continue

3Press Enter to continue

4
Press Enter to continue
5Press Enter to continue

Gewünschtes Ergebnis:
1
Press Enter to continue
2
Press Enter to continue
3
Press Enter to continue
4
Press Enter to continue
5
Press Enter to continue

usw.

Was mache ich falsch?
Benutzeravatar
Axel-WAK
User
Beiträge: 62
Registriert: Dienstag 29. November 2022, 11:52

Macht doch das was Du programmiert hast.
OS: LMDE5 *** Homepage *** Github Seite
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Es mag daran liegen, dass der Ausgabestrom, welcher von print bedient wird, an den jeweiligen Stellen noch nicht "durchgespült" (flushed) wurde. Das ist abhängig von der verwendeten Konsole und ihrer Umgebung. Diese kann man mit einem zusätzlichen Argument der print-Funktion erzwingen:

Code: Alles auswählen

def main():
    durchgang = 1
    while durchgang < 50:
        print(durchgang, flush=True)
        durchgang = durchgang + 1
        input("Press Enter to continue")

if __name__ == '__main__':
    main()
Kompakter und lesbarer lässt sich das ganze mit einer for-Schleife formulieren:

Code: Alles auswählen

def main():
    for i in range(1, 50):
        print(i, flush=True)
        input("Press Enter to continue")

if __name__ == '__main__':
    main()
Disclaimer: Testen konnte ich das allerdings nicht, da in meinen Konsolen (Windows-CMD und GitBash) die Ausgaben auch ohne flush "der Reihe nach" erfolgten.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Benutzeravatar
__blackjack__
User
Beiträge: 13123
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das sollte überall der Reihe nach erfolgen, denn `print()` und `input()` geben ja ihre Ausgaben beide über `sys.stdout` aus. Das kann nur komische Ausgaben produzieren falls die Umgebung da irgendwas sehr komisches macht, und das ist dann ein Fehler den man nicht versuchen sollte im eigenen Programm zu beheben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
miwue45
User
Beiträge: 2
Registriert: Freitag 16. Dezember 2022, 17:13

Beide Codes funktionieren korrekt. Danke!
Was genau machen

def main():

if __name__ == '__main__':
main()
??
juwido
User
Beiträge: 20
Registriert: Donnerstag 15. Dezember 2022, 13:41

if __name__ == '__main__':" main() - startet das "Hauptprogramm", das in der "Hauptfunktion" - def main(): - steht. - Aber nur, wenn die Datei als erstes vom Interpreter geladen und gestartet wird. Mann kann die Datei auch als Modul mit - import ..- laden, dann ist - if ... - aber 'false' und der Interpreter startet - main() - nicht.
Benutzeravatar
Dennis89
User
Beiträge: 1158
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

zu deiner ersten Frage, mit dieser Zeile wird eine Funktion mit dem Namen „main“ definiert. Auf python.org gibt es ein Starter-Tutorial, da werden solche Sachen erklärt. Es empfiehlt sich das mal durch zu arbeiten 🙂

Deine zweite Frage, diese if-Abfrage ruft die main-Funktion bei Programmstart auf. Es sei denn dieses Programm wurde in ein anderes importiert, dann wird main nicht ausgeführt. Auch dazu findet man verständlichere Erklärungen mit Beispielen im Netz.
Sorry das ich keine Links dazu poste, das ist mir am Handy etwas zu fummelig.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

__blackjack__ hat geschrieben: Freitag 16. Dezember 2022, 18:34 Das sollte überall der Reihe nach erfolgen, denn `print()` und `input()` geben ja ihre Ausgaben beide über `sys.stdout` aus. Das kann nur komische Ausgaben produzieren falls die Umgebung da irgendwas sehr komisches macht, und das ist dann ein Fehler den man nicht versuchen sollte im eigenen Programm zu beheben.
@__blackjack__: So komisch sah mir das gar nicht aus. Ich habe mich an damals(tm) erinnert gefühlt, als ich meine ersten Schritte mit C++ machte. Ausgaben über std::cout wurden dort regelmäßig mit std::endl abgeschlossen, welches eben ein flush mit ausführten. Der Hinweis aus der Dokumentation "Whether the output is buffered is usually determined by file, but if the flush keyword argument is true, the stream is forcibly flushed" [1] und der Hinweis auf das verwendete Spyder brachte bei mir den Verdacht auf, dass die Ein-/Ausgabeströme hier gepuffert sein könnten.

@miwue45: Insofern hat __blackjack__ recht, als dass du deine Programme in einer "gebräuchlichen" Konsole ausführen lassen solltest und nicht direkt in der Konsole einer IDE, welche für die ersten Schritte [2] m. E. ohnehin mehr Komplexität als nötig reinbringt. Ein einfacher Texteditor mit Syntax-Highlighting und der interaktive Python-Interpreter reichten da aus.

[1]: https://docs.python.org/3/library/functions.html#print
[2]: https://docs.python.org/3/tutorial/index.html
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Benutzeravatar
__blackjack__
User
Beiträge: 13123
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@bwbg: In C++ werden die Daten auch ohne `std::endl` oder explizitem `flush()`-Aufruf in der Reihenfolge ausgegeben in der sie geschrieben wurden. In der Beispielausgabe sieht es ja so aus, als würde sich der Ausgabeprompt zwischen die Zahl und deren Zeilenendezeichen drängeln. Zudem lösen bei C++ Lesevorgänge auf `std::cin` einen vorherigen `flush()` auf `std::cout` aus, so das selbst mit "\n" ausgegebener Text über `std::cout` komplett ausgegeben wird bevor der Benutzer dann etwas eingeben kann/muss.

Ich sehe bei beiden Sprachen nicht wie das beschriebene Verhalten ohne Fehler in der IDE zustande kommen sollte. Ich vermute hier das die IDE die Daten nicht einfach über die Standardein- und ausgaben abgreift, sondern `print()` und/oder `input()` durch was eigenes ersetzt hat, zum Beispiel um Numpy-Arrays, Pandas-DataFrames, und Matplotlib-Plots, und ähnliches, in der Konsole als Tabellen und Grafiken ausgeben zu können. Da muss man ja vor der Ausgabe als Text ansetzen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

miwue45 hat geschrieben: Freitag 16. Dezember 2022, 17:30 Meine Konsole sieht so aus:

Python 3.10.7 (main, Nov 24 2022, 19:45:47) [GCC 12.2.0]
Type "copyright", "credits" or "license" for more information.

IPython 7.31.1 -- An enhanced Interactive Python.

[SpyderKernelApp] WARNING | debugpy_stream undefined, debugging will not be enabled
Das sollte nicht sein. Vielleicht ist da noch mehr kaputt als nur das Debugging.

Wenn ich das Programm in Spyder 5.4.0 (Windows) laufen lasse, kommen alle Ausgaben in der erwarteten Reihenfolge.
juwido
User
Beiträge: 20
Registriert: Donnerstag 15. Dezember 2022, 13:41

Ja, die "WARNING ... ... _stream undefined" passt auch für die Daten-Ausgabe im Eingangspost von miwue45...

Nun soll I Python ja durch Parallelverarbeitung die Laufzeit großer Programme reduzieren. Sieht fast so aus, als würde "print..." nur weitergegeben und dann schon "input..." verarbeitet. Jedenfalls sieht es so aus, als wenn der String von "input" sich zwischen "print" und das von "print" nachgeschobene "new line" drängen kann.
Solche Effekte sind u.U. schwer nachzubilden, da die anderen auf dem Rechner aktiven Prozesse das Timing ja mit beeinflussen...
Benutzeravatar
__blackjack__
User
Beiträge: 13123
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@juwido: IPython soll nix mit Parallelverarbeitung reduzieren. Das ist einfach eine gute, interaktive Python-Shell. Es gibt ein Projekt was eigenständig ist (ipyparallel) und das parallele IPython-Engines verwalten kann, aber darum geht es ja in der Frage gar nicht. Da wird ja nicht einmal IPython selbst interaktiv verwendet, sondern ein Programm gestartet.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
juwido
User
Beiträge: 20
Registriert: Donnerstag 15. Dezember 2022, 13:41

Oh, da habe ich den Wikipedia-Eintrag zu IPython wohl zu flüchtig gelesen ... Entschuldigung!
Die Ursache liegt dann wohl doch wo anders ...
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Trotzdem - wenn ein Problem nur in einer IDE auftritt, und mit der (Installation der) IDE etwas nicht in Ordnung ist, dann sollte man das als Fehlerquelle ausschließen.
Antworten