Anfängergedanken Nr. 1

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.
epicpython
User
Beiträge: 20
Registriert: Montag 1. Oktober 2018, 12:35

Guten Tag liebe Community,

ich habe kürzlich auf der Webseite "w3schools" damit begonnen Python zu lernen. Diese Internetseite bietet zwar viele grundlegende Informationen, aber leider kaum Anwendungsbeispiele und auch keine Aufgaben, welche mir die Anwendung der Sprache näher bringen Aus diesem Grund möchte ich fragen, ob mir jemand Webseiten mit Aufgaben nennen kann, die für Einsteiger geeignet sind und das Wissen für die sinnvolle zukünftige Verwendung festigen. Außerdem frage ich mich, ob in einer "if-Abfrage" Bedingungen festgelegt werden können, welche die vorherige Ausführung einer anderen "if-Abfrage" erfordern. Es wäre mir so bspw. möglich einen Befehl nur unter der Bedingung auszuführen, wenn ein bestimmter Teil des Codes vorher ausgeführt wurde. Möglicherweise regelt sich dies bereits durch die Reihenfolge des geschriebenen Codes selbst dann, wenn die Bedingung erst zu einem späteren Zeitpunkt wahr wird. Ich könnte mich jedoch irren und brauche diesbezüglich dringend Hilfe.

MfG
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Zum ersten Teil deiner Frage: Hängt sehr stark von deinem Interessengebiet ab. Zunächst einmal solltest du das offzielle Tutorial durcharbeiten, um die Grundlagen zu lernen, falls noch nicht geschehen. Und dann kommt es halt drauf an, was du später vorwiegend programmieren willst. Typische Einsatzgebiete sind Web-Programmierung, Data Mining (z.B. im naturwissenschaftlichen Bereich), künstliche Intelligenz, Rasberry PI, Spiele, usw.

Und zur Sache mit dem if-Statement: Der Block wird nur dann vom Programmfluss betreten, wenn die Bedingung zutrifft. Innerhalb des Blocks kannst du dann weiter verschachteln, also im Falle von if eine weitere "Abzweigung" bauen. Insofern lagst du schon richtig mit deiner Vermutung. ;-)
epicpython
User
Beiträge: 20
Registriert: Montag 1. Oktober 2018, 12:35

Vielen Dank für die ausführliche Antwort,

ich habe im Laufe des Tages ein Video auf Youtube durchgearbeitet. Die Erklärung der "while"-Schleife hat es mir dann erlaubt, ein kleines Programm zu schreiben. Dieses Programm limitiert die Anzahl der Versuche für die Eingabe eines korrekten Strings. Wenn nun die Anzahl der Versuche hierfür gespeichert wird, frage ich mich, wie ich die Anzahl der vergangenen Versuche ausgebe. Ich habe versucht ein if-Statement in den Code zu integrieren. Allerdings ruft das bisher nur Fehler hervor.
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

@epicpython: Code sagt mehr als tausend Worte :-)

Es hat sich auch in diesem Forum bewährt, einfach seinen code zu zeigen, sich vorzustellen was jemand programmiert hat, und das nur anhand seiner Beschreibung, ist immer etwas anstrengend.

Prinzipiell kannst du aber eine einfache Auswertung innerhalb des Schleifenkörpers durchführen, if-elif/else bietet dafür alles was du brauchst. Eine einfache Variable "versuche" o.ä. wird dann entsprechend um 1 erhöht.
When we say computer, we mean the electronic computer.
epicpython
User
Beiträge: 20
Registriert: Montag 1. Oktober 2018, 12:35

wort = "12345"
eingabe = ""
eingabe_anzahl = 0
eingabe_limit = 3
eingabelimit_erreicht = False

while eingabe != wort and not(eingabelimit_erreicht):
if eingabe_limit > eingabe_anzahl:
eingabe = input("Gebe das richtige Wort ein: ")
eingabe_anzahl += 1
else:
eingabelimit_erreicht = True

if eingabelimit_erreicht:
print("Falsch!")
else:
print("Richtig!")
#Wenn ich nun versuche "eingabe_anzahl" mit dem print-Befehl bei jedem Versuch auszugeben erkennt VS Syntaxfehler
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das lässt sich ganz grob so lösen:

Code: Alles auswählen

for i in range(3):
    if versuch_ok:
        break
print('Anzahl Versuche:', i + 1)
while würde ich hierbei gar nicht nehmen. Wahrscheinlich hätte man dann sowas:

Code: Alles auswählen

versuch_ok = False
anzahl_versuche = 0
while not versuch_ok:
    anzahl_versuche += 1
    if versuch_richtig:
        versuch_ok = True
print('Du hast', anzahl_versuche, 'Versuche gebraucht')
Wie man sieht, wird beim for deutlich weniger Hirnschmalz verbraucht. Will man bei Variante 2 ebenfalls ein Maximum für die Versuche haben, dann wird es noch komplexer. Besonders wenn man break umgehen will, weil das angeblich nicht anfängerfreundlich sei.

EDIT:
Oh, habe gar nicht gesehen, dass da noch ein Beitrag kam.
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

@epicpython: beim einfügen von code bitte das nächste Mal die Funktion "code anzeigen" im Editor verwenden, sonst gehen wichtige Elemente für die korrekte Syntax verloren (z.B. Einrückungen, die in Python unabdingbar sind)

Um eine ähnliche Lösung für dein Beispiel zu zeigen:

Code: Alles auswählen

wort = "1234"
eingabe_limit = 3
eingabe_versuche = 1

while True:
    eingabe = input("Gebe das richtige Wort ein: ")
    if eingabe == wort:
        print("Richtig!")
        print("Anzahl der Versuche: ", eingabe_versuche)
        break
    else:
        print("Falsch!")
        eingabe_versuche += 1

    if eingabe_versuche > eingabe_limit:
        print("Maximale Anzahl an Versuchen erreicht. Limit:", eingabe_limit)
        print("Programmende.")
        break
In Python gehört es zum guten Ton die Bedingung nicht in den Schleifen Kopf zu stecken, sondern break im Schleifenkörper zu verwenden. Wenn die Anzahl der maximalen Versuche und damit die Anzahl der Schleifen-Wiederholungen/Durchläufe bereits im Vorfeld bekannt ist, verwendet man eine For-Schleife.

Ich würde also an deiner Stelle eine For-Schleife nutzen und mir dazu die range()-Funktion ansehen. Die Lösung lässt sich natürlich auf deutlich weniger Zeilen reduzieren, für den Einstieg sollte das obige Beispiel aber zugänglicher sein.
When we say computer, we mean the electronic computer.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Bei Deinem Code

Code: Alles auswählen

wort = "12345"
eingabe = ""
eingabe_anzahl = 0
eingabe_limit = 3
eingabelimit_erreicht = False
	
while eingabe != wort and not(eingabelimit_erreicht):
	if eingabe_limit > eingabe_anzahl:
		eingabe = input("Gebe das richtige Wort ein: ")
		eingabe_anzahl += 1
	else:
		eingabelimit_erreicht = True

if eingabelimit_erreicht:
    print("Falsch!")
else:
    print("Richtig!")
mußt Du ›eingabe‹ mit einem Dummy-Wert belegen, damit die Schleife überhaupt starten kann. In solchen Fällen prüft man die Bedingung erst innerhalb der Schleife. `not` ist keine Funktion, die Klammern sind daher verwirrend. ›eingabelimit_erreicht‹ ist überflüssig, da es identisch ist mit der Bedingung »eingabe_anzahl >= eingabe_limit«. Die if-Abfrage nach der while-Schleife kann man z.B. mit einem else-Block abdecken. Eingerückt wird immer mit 4 Leerzeichen und nicht mit Tab.

Code: Alles auswählen

wort = "12345"
eingabe_anzahl = 0
eingabe_limit = 3

while eingabe_anzahl < eingabe_limit:
    eingabe_anzahl += 1
    eingabe = input("Gebe das richtige Wort ein: ")
    if eingabe == wort:
        print("Richtig!")
        break
else:
    print("Falsch!")
Da aber die Anzahl der Durchgänge von vornherein feststeht, kann man die while-Schleife einfacher durch for ausdrücken:

Code: Alles auswählen

wort = "12345"
eingabe_limit = 3

for eingabe_anzahl in range(1, eingabe_limit + 1):
    eingabe = input("Gebe das richtige Wort ein: ")
    if eingabe == wort:
        print("Richtig!")
        break
else:
    print("Falsch!")
PS: Du hast nicht gezeigt, wie Du versucht hast, eingabe_anzahl auszugeben, daher kann man auch nicht sagen, was Du dabei falsch gemacht hast.
epicpython
User
Beiträge: 20
Registriert: Montag 1. Oktober 2018, 12:35

Diesen Beitrag habe ich nachträglich verändert, da ich nicht gesehen habe, dass bereits alles ausführlichst erklärt wurde.

Ich möchte mich bei euch allen für die schnellen und verständlich formulierten Hilfestellungen und Lösungswege bedanken. Ihr entfacht in mir eine wahre Begeisterung für das Programmieren und für dieses Forum.

Danke
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier ist übrigens die Übersetzung vom offiziellen Python-Tutorial:
https://py-tutorial-de.readthedocs.io/de/python-3.3/

Da werden die verschiedenen Container-Typen für das Umgehen mit mehreren Elementen erklärt, sowie alles zur Bildschirmausgabe, Einlesen von Benutzereingaben, Lesen und Schreiben von Dateien, usw.
epicpython
User
Beiträge: 20
Registriert: Montag 1. Oktober 2018, 12:35

Ich habe es geschafft. Hier nochmal die funktionierende Lösung meinerseits:

Code: Alles auswählen

wort = "abc"
eingabe_anzahl = 0
eingabe_limit = 3

for eingabe_anzahl in range (0, eingabe_limit, 1):
    eingabe = input("Gebe das richtige Wort ein: ")
    if eingabe_anzahl > eingabe_limit:
        print("Eingabelimit erreicht")
        break
    if eingabe == wort:
        print("Richtig!")
        break
    elif eingabe != wort:
        print("Versuche es noch einmal!\nVersuchsnummer: " + str(eingabe_anzahl))
Ich versuche nun das Programm um eine Funktion zu erweitern, welche nach jedem Versuch einen weiteren Hinweis auf das Wort ausgibt. Hierzu war es meine Idee eine Liste zu verwenden, dessen Indexzugriff sich nach einem Durchlauf um 1 erhöht, sodass jedes Mal auf ein weiteres Item zugegriffen wird. Ein weiterer Lösungsansatz war für mich, einen bestimmten Hinweis auszugeben, wenn ein bestimmter "eingabe_anzahl"-Wert erreicht wurde. Gibt es zu dem ersten Gedanken eine Lösung oder ist es nicht üblich das so zu machen?
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@epicpython: Deine Lösung funktioniert nicht. Wann ist denn Deiner Meinung nach `eingabe_anzahl` jemals grösser als `eingabe_limit`? Die Ausgabe „Eingabelimit erreicht” wird niemals ausgegeben, also ist der Code an der Stelle überflüssig oder falsch.

Die 0 und die 1 bei `range()` sind die Defaultwerte, die würde man weglassen. Und `eingabe_anzahl` vor der Schleife mit 0 zu initialisieren ist überflüssig.

Wenn bei jedem Versuch ein Hinweis kommen soll, dann würde man `range()` und Indexzugriffe ganz weglassen und über eine Liste mit Hinweisen iterieren. Falls man *zusätzlich* eine laufende Zahl benötigt, gibt es dafür die `enumerate()`-Funktion.

Nachtrag: Wenn man in einem ``elif`` genau das Gegenteil prüft was man davor im ``if`` hatte, dann ist das überflüssig, weil man dann einfach ``else`` verwenden kann. Auf ein ``elif`` lasse ich so etwas übrigens sehr selten enden, denn das bedeutet ja in der Regel das irgendwelche Fälle nicht berücksichtigt wurden. Das ist manchmal so gewollt, aber oft eben auch nicht, also überlege ich an der Stelle immer ob ein ``else`` mit einem ``assert False`` an der Stelle sinnvoll ist. Damit bekommt man dann die Fälle mit, die eigentlich niemals auftreten dürften. Sofern man alles richtig gemacht hat. Was man ja leider nicht immer macht. :-)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
epicpython
User
Beiträge: 20
Registriert: Montag 1. Oktober 2018, 12:35

Ich habe nun den Sinn der Schreibweise der "range()"-Funktion mit einem Additionszeichen hinter dem zweiten Parameter verstanden. Zuvor dachte ich, dass es lediglich eine andere Schreibweise des dritten Parameters wäre.

Code: Alles auswählen

wort = "abc"
eingabe_limit = 3
eingabe_anzahl = 1


for eingabe_anzahl in range (1, eingabe_limit + 1):
    eingabe = input("Gebe das richtige Wort ein: ")
    if eingabe_anzahl == eingabe_limit:
        print("Eingabelimit erreicht\nVersuchsnummer: " + str(eingabe_anzahl))
        break
    if eingabe == wort:
        print("Richtig!")
        break
    else:
        print("Versuche es noch einmal!\nVersuchsnummer: " + str(eingabe_anzahl))
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@epicpython: `eingabe_anzahl` vor der Schleife an einen Wert zu binden macht hier immer noch keinen Sinn. Der Wert wird ja nie irgendwo verwendet.

Und ich würde das überschreiten des Eingabelimits auch nicht in der Schleife behandeln, sondern in einem ``else`` zu der Schleife. Genau für so etwas ist das ja da.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
epicpython
User
Beiträge: 20
Registriert: Montag 1. Oktober 2018, 12:35

Wie genau kann ich mir ein "else"" zu der Schleife vorstellen? Ich habe jetzt auch verstanden, wieso es keinen Sinn macht eine Variable mit einem Wert zu belegen. Für einen Beginner ist es sicher nicht ungewöhnlich Variablen vorab zu definieren. Die Variable kann aber auch am Eingang der "for"-Schleife kreiert werden und hat nachfolgend einen Defaultwert. Das war sehr hilfreich. Danke
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das else eine Schleife kommt zum tragen, wenn diese nicht abgebrochen wurde.

Code: Alles auswählen

for i in range(100):
      if == 10: # hier gegen zB 200 austauschen, dann aendert sich was.
          break
else:
     print("no break")
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

epicpython hat geschrieben: Dienstag 2. Oktober 2018, 14:39 Wie genau kann ich mir ein "else"" zu der Schleife vorstellen?
Es gibt in Python ein "for-break-else" Konstrukt. Das passt auf Deine Anwendung genau und Sirius3 hatte Dir die fertige Lösung auch schon geliefert.
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Naja einfach ein ``else:`` passsend zum ``for:`` eingerückt. Der Code der dort drin steht wird ausgeführt wenn die Schleife *nicht* durch ``break`` verlassen wurde.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
epicpython
User
Beiträge: 20
Registriert: Montag 1. Oktober 2018, 12:35

Das Problem am Code von Sirius3 ist, dass ich nicht bei jeder falschen Eingabe die Meldung erhalte, dass diese falsch war. Erst am Ende der "for"-Schleife erhalte ich die Meldung, dass ich einen (eigentlich mehrere) Fehler gemacht habe. Meine Lösung müsste dementsprechend im Hinblick auf die gewünschte Funktionsweise vollkommen richtig sein. Zumindest hatte ich gehofft, dass es so ist. Funktionieren tut es.
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

@epicpython:

das `else` nach der For-Schleife ist trotzdem optional. Selbst wenn im Schleifen-Körper bereits ein `else` definiert wurde.

Code: Alles auswählen

wort = "abc"
eingabe_limit = 3

for i in range(1, eingabe_limit + 1):
    eingabe = input("Gebe das richtige Wort ein: ")
    if eingabe == wort:
        print("Richtig!")
        print("Versuche: ", i)
        break
    else:
        print("Falsch.")
        print("Versuche: ", i)
else:
    print("Programmende.")

`eingabe_anzahl` entfällt hierbei wie __blackjack__ erwähnt hat, da es schlicht nicht benötigt wird.
When we say computer, we mean the electronic computer.
Antworten