Wie kann man ein weitverzweigtes Geflecht aus if/else-Anweisungen in Python (oder in anderen Programmiersprachen) programmieren?

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

Woher ich das weiß:Studium / Ausbildung – Softwareentwickler mit 10 Jahren Berufserfahrung 💾

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.

Woher ich das weiß:Berufserfahrung

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;
}