Wie kann man ein weitverzweigtes Geflecht aus if/else-Anweisungen in Python (oder in anderen Programmiersprachen) programmieren?
Wenn man als absoluter Laie in Programmierung im Internet zur if/else-Anweisung (egal, in welcher Programmiersprache) recherchiert, wird man schnell feststellen, dass die Infos, die man hier findet, nicht allzu reichhaltig sind.
Das höchste der Gefühle, was einem beigebracht wird, ist folgenden Dialog zu programmieren: "Welche Sprache sprechen Sie?" - "Französisch." - "Wollen Sie sich auf Französisch weiter unterhalten?" Ende.
Man lernt nicht, wie man mit dem Programm weitermachen kann, falls die Antwort des Benutzers "Ja" sein sollte. Man erfährt gar nichts. Was zu finden ist, ist, wie man EINE FRAGE STELLT und dann auf EINE ANTWORT zu dieser Frage reagieren kann. Das war's.
Ich wüsste gern, wie man das weiterspinnen kann. Wie man eine ganz lange Unterhaltung mit allen möglichen Antwortmöglichkeiten programmieren kann. So wie bei einem Windows-Installationassistenten, der dafür sorgt, dass Windows unter hundert verschiedenen Arten auf die Art installiert wird, wie der Benutzer es will.
Wenn die Benutzer dieser Seite keine Antwort auf die Frage haben, weil sie es selbst nicht wissen, ist das überhaupt kein Problem. Man trifft immer wieder einen It-Profi, der es vielleicht weiß.
Allerdings lässt sich extrem leicht feststellen, dass irgendwelche Teenies oder Leute, die auf dem geistigen Niveau von (nicht sehr gut erzogenen) Teenies stehengeblieben sind, es sich zum Hobby machen, auf dieser Seite unvorstellbar bösartig und beleidigend zu antworten. Es ist völlig egal, was man fragt, egal ob "Wie heißt das weiße Zeug, das früher auf den Donuts war?" oder "In welchen Läden kann man viele naturfreundliche Reinigungsmittel kaufen?" Es wird immer geantwortet von irgendwelchen Leuten, die zu wenig zu tun haben und sich ihre Zeit vertreiben, Leute im Internet mit Sprüchen wie "Boah, Alta, wie dumm BIIISSSSST Du eigentlich?" zu beleidigen.
Ich werde auf so einen Schwachsinn nicht antworten, auch nicht auf "gut gemeinte Rückfragen" und schon gar nicht auf "Also, mit SO EINER NEGATIVEN EINSTELLUNG MENSCHEN GEGENÜBER würde ich hier aber KEINE Frage stellen".
Die Frage ist klar formuliert, so klar wie sie klarer nicht formuliert werden kann. So wie "Was ist 2 + 2?" Wenn jemand die Antwort wüsste, würde mich das sehr freuen. Wenn nicht, dann nicht.
Danke, Ende.
6 Antworten
Idealerweise zieht man undurchsichtigen Code auseinander, indem man Teile zum Beispiel in Funktionen auslagert. In deinem Fall würde man im Rumpf einer If-Else Abfrage eine Funktion aufrufen, die wiederum eine weitere If-Else Anweisung beinhaltet.
Falls möglich wandelt man ein If-Else auch in ein Switch-Case um. Ist im Endeffekt eine leserlichere Struktur eines sehr langen If-Else Statements auf gleicher Ebene.
Allerdings ist das natürlich von Fall zu Fall unterschiedlich.
Am wichtigsten sind gut lesbare Kommentare, durch welche man komplexen Code leserlicher gestalten kann.
LG Knom
Ja, wenn die Frage hier auf die Lesbarkeit von Code abzielen sollte, dann gibt es eine dritte Möglichkeit, neben den beiden oben bereits geschilderten
- verschachtetes If-Else
- Switch
Wenn man beispielsweise mit einer Programmiersprache arbeitet, die Maps (z.B. Hashmaps) zur Verfügung stellt, kann man z.B. Verhalten (z.B. Objekten mit entsprechenden Methoden) mit den dort verwendeten Schlüsseln verknüpfen.
In der Programmiersprache Java würde man z.B. ein sogenanntes Interface mit ein oder mehreren Mehtoden-Signaturen definieren und Klassen entwickeln, die dieses Interface implementieren, um dann die in der Map gespeicherten Objekte mit dem gewünschten Verhalten (Implementation des definierten Interface) gegen den gemappten Schlüssel zu erhalten. Dies ist aber wirklich im Wesentlichen nur bei sehr komplexen Fällen sinnvoll, da natürlich das Auffinden des gewählten Objekts gegen den gegebenen Schlüssel ein wenig langsamer ist im Laufzeitverhalten, als eine hartkodierte Entscheidungskaskade.
Der Punkt einer Verzweigung ist eben, daß sie nur zwei Möglichkeiten kennt. Von daher gibt es dazu offensichtlich nicht mehr zu sagen.
Die Frage, wie man eine geführte Installation umgesetzt bekommt, ist ein völlig anderer Themenbereich - da geht es um die Befähigung der Abstraktion und die Aufgabe auf die vorhandenen Mitteln abbilden zu können.
Heißt für eine geführte Installation die Erkenntnis: Ich konfrotiere den Benutzer wiederholt mit Fragen und Wahlmöglichkeiten, wobei jede Entscheidungsfindung im Kern identisch ist. Ich muß also wiederholt die gleiche Aufgabe erledigen, wobei sich die Daten in gewissem Rahmen ändern (Anzahl und/oder Art der Optionen, Fragetexte, ...).
Also werde ich das auch genau so lösen:
Ich habe einen Datenbestand mit den jeweiligen Entscheidungen und eine abstrakte Beschreibung, wie die Optionen präsentiert werden sollen und generiere daraus die Dialogerie. Ich gehe nicht hin und schreieb eien Tirade von if/else-Blöcken da hin.
Gibt es mehr als 2 Optionen gibt es oft ein Konstrukt, das mich dies vereinfacht beschreiben lässt:
opt=int(input("Option wählen:"))
match opt :
case 0:
#branch 1
case 2:
#branch 2
,,,,
case _:
#everything else
Python nennt das structural matching (das kann noch so manches mehr) und im Kern werden die notwendigen if/else daraus generiert. In Sprachen wie C wird das technisch als "Sprungtabelle" realisiert, weswegen dann auch sowas wie ein impliziter fallthrough existiert, wenn ich den Zweig nicht forciert unterbreche.
Vergleiche folgendes:
def calc(op,x,y):
if op=='+':
return x+y
if op=='-':
return x-y
#usw. usf.
def calc(op,x,y):
match op:
case '+':
return x+y
case '-':
return x-y
#usw usf.
Da hier im Kern keine Else-Zweige benötigt werden, sind beide Varianten recht nahe beieinander, wobei die cases hier noch Nebenbedingungen haben könnten.
Man kann das aber auch so machen:
def calc(op,x,y,):
ops={'+':lambda x,y:x+y, '-' : lambda x,y:x-y, ....}
if op in ops:
return ops[op](x,y)
Genau das hier verschiebt die Abfrage der verschiedenen Optionen in Daten, indem ich eben nur noch schaue ob der Operator (Auswahlkriterium) als Schlüssel existiert und dann die assoziierten Daten nutze.
Man lernt nicht, wie man mit dem Programm weitermachen kann, falls die Antwort des Benutzers "Ja" sein sollte. Man erfährt gar nichts. Was zu finden ist, ist, wie man EINE FRAGE STELLT und dann auf EINE ANTWORT zu dieser Frage reagieren kann. Das war's.
Mehr brauchst du auch nicht über eine If-Then-Else-Struktur zu wissen.
Den Rest lernt man mit den Grundlagen der Programmierung - mit denen man anstelle einer Programmiersprache zuerst beginnt. Dann kennt man Programmablaufplan, Struktogramm, Pseudocode, OOP etc. und kann sich eine Programmstruktur bereits ohne Programmiersprache auf Papier so darstellen, dass man diese Aufzeichnung nur noch in eine Programmiersprache "übersetzen" muss.
IF hat nur zwei mögliche Ergebnisse -> a) Bedingung ist zutreffend, also wahr, b) Bedingung ist nicht zutreffend, also falsch.
Und genau auf diese beiden Ergebnisse werden genutzt, um die weiteren Aktionen auszuführen, die von der Bedingung abhängig sind.
a) wird im Then-Teil ausgeführt, b) hingegen im Else-Teil.
Man lernt nicht, wie man mit dem Programm weitermachen kann,
Ganz normal NACH dem Ende der If-Then-Else-Struktur.
Willst du, dass eine Bedingung erfüllt wird, damit der weitere Programmcode ausgeführt wird, dann muss im Else dafür gesorgt werden, dass das Programm dort endet.
Willst du, dass eine Bedingung NICHT erfüllt wird, damit der weitere Programmcode ausgeführt wird, dann muss im If-Teil dafür gesorgt werden, dass das Programm dort endet. (Den Else-Teil kann man sich dann schenken.)
Nach dem Else-Teil kommt dann einfach die nächste Anweisung, mit der das Programm fortgesetzt werden soll.
Die Alternative zu if else if else if else ... ist switch / case
Da stehen beliebig viele Abfragen übersichtlich untereinander. Praktisches Beispiel in PHP: Ein Datensatz in der Datenbank soll geändert werden. Der rückgemeldete Status kann -1, 0 oder 1 sein.
switch ( @mysql_affected_rows( $conn_id ) ) {
case (-1):
echo "Fehler: Satz konnte nicht geändert werden";
break;
case (0):
// neue Daten sind wie die alten
echo "Hinweis: Nichts zu ändern";
break;
case (1):
echo "Satz wurde geändert";
break;
}