i

Strukturierung: Fallunterscheidungen

Wenn wir Funktionen schreiben, welche sich in Abhängigkeit der Übergabedaten unterschiedlich verhalten sollen, benötigen wir Fallunterscheidungen, um dieses Verhalten umzusetzen.

Die allgemeine Fallunterscheidung

Eine allgemeine Fallunterscheidung wird in Racket mit einem (cond ...)-Ausdruck umgesetzt. Dieser enthält beliebig viele Fälle, die jeweils aus einer Bedingung (ein Ausdruck mit booleschem Rückgabewert) und einem zugehörigen Rückgabewert bestehen. Wenn die Bedingung #t ergibt, wird der zugehörige Rückgabewert als Ergebnis der Funktion zurückgegeben.
Wenn nicht sichergestellt werden kann, dass mindestens eine der Bedingungen zu #t ausgewertet wird, muss ein else-Fall hinzugefügt werden.

Faustregel: Die allgemeine Fallunterscheidung nutzen wir, wenn wir mehr als zwei Fälle haben, die wir unterscheiden müssen.

Beispielfunktion mit einer allgemeinen Fallunterscheidung:

;Bestimmt ob eine Zahl positiv oder negativ ist
(: positiv-oder-negativ (real -> string))
(check-expect (positiv-oder-negativ -0.2) "negativ")
(check-expect (positiv-oder-negativ 0) "weder positiv noch negativ")
(check-expect (positiv-oder-negativ 12.7) "positiv")
(define positiv-oder-negativ
  (lambda (zahl)
    (cond
      ([< zahl 0] "negativ")
      ([= zahl 0] "weder positiv noch negativ")
      ([> zahl 0] "positiv")
    ) 
) ) 

Aufgabe 1: Fälle in der allgemeinen Fallunterscheidung

Welche der folgenden Fallunterscheidungen sind korrekt? Begründe deine Entscheidung.

(a)

    (cond
      ([< zahl 0] 0)
      ([= zahl 0] 1)
      ([> zahl 0] 0)
    ) 
(b)
    (cond
      ([+ a 0] "zulässig")
      ([- a 0] "zulässig")
      ([* a 0] "zulässig")
      ([/ a 0] "unzulässig")
    ) 
(c)
    (cond
      ([= (string-length text) 0] "leerer String")
      ([<= 100 (string-length text)] "großer String")
      ([>= 10 (string-length text)] "kleiner String")
      ([string=? text text] (string-append text "!"))
    ) 
(d)
    (cond
      ([string=? "minus"] (- x 1))
      ([string=? "plus"] (+ x 1))
      ([string-append "plus" "minus"] x)
      (else 0)
    ) 

Aufgabe 2: Das Zählspiel FizzBuzz

Bestehende Datei - fallunterscheidungen.rkt

Wir wollen eine Funktion für das Zählspiel FizzBuzz implementieren. Dieses Spiel funktioniert wie folgt:

  • Die Spielenden zählen bei 1 beginnend reihum bis 100.
  • Jede Zahl, die durch 3 teilbar ist, wird nicht als Zahl gesagt, sondern durch "Fizz" ersetzt.
  • Jede Zahl, die durch 5 teilbar ist, wird durch "Buzz" ersetzt.
  • Jede Zahl, die durch 3 und 5 teilbar ist, wird durch "FizzBuzz" ersetzt.
  • Für alle anderen Zahlen wird die entsprechende Zahl gesagt.

(a) Wähle für die Zahlen 1 bis 6 jeweils die korrekte FizzBuzz-Ausgabe.

(b) Bei welcher Zahl muss man zum ersten Mal "FizzBuzz" sagen?

(c) Implementiere eine Funktion, die für eine übergebene Zahl von 1 bis 100 die korrekte FizzBuzz-Ausgabe angibt.
Hinweise:

  • Mit der Funktion number->string kannst du eine Zahl in einen String umwandeln.
  • Wenn du für einen Fall mehrere Bedingungen benötigst, kannst du diese beispielsweise wie folgt verknüpfen: [and (< x 12) (> x 5)]


Die binäre Fallunterscheidung

Eine binäre Fallunterscheidung wird in Racket mit einem (if ...)-Ausdruck umgesetzt. Dieser enthält eine Bedingung (ein Ausdruck mit booleschem Rückgabewert) und zwei mögliche Rückgabewerte. Wenn die Bedingung #t ergibt, wird der erste Rückgabewert als Ergebnis der Funktion zurückgegeben, wenn die Bedingung #f ergibt, der zweite.

Faustregel: Die binäre Fallunterscheidung nutzen wir, wenn wir genau zwei Fälle haben, die wir unterscheiden müssen.

Beispielfunktion mit einer binären Fallunterscheidung:

;Bestimmt ob eine Klassenarbeit mit der erreichten Anzahl an Notenpunkten bestanden wurde. 
(: bestanden? (natural -> boolean))
(check-expect (bestanden? 4) #f)
(check-expect (bestanden? 5) #t)
(define bestanden?
    (lambda (punkte)
        (if [< punkte 5] #f #t)
)   )

Aufgabe 3: Anwendung der Faustregeln

Welche der beiden Fallunterscheidungsarten eignet sich (nach unseren Faustregeln) für die folgenden Funktionen:

Eine Funktion, die je nach Ergebnis eines Münzwurfs unterschiedliches Verhalten aufweist.

Eine Funktion, die je nach Ergebnis eines Würfelwurfs unterschiedliches Verhalten aufweist.

Eine Funktion, die für alle natürlichen Zahlen, wenn zutreffend, "zweistellig" oder "dreistellig" zurückgibt.

Nach Abschluss des Abiturs wird eine Funktion veröffentlicht, mit welcher man prüfen kann, ob eine Abiturnote besser als der Durchschnitt ist.

Ein Online-Unternehmen verkauft Android- und iOS-Smartphones. Sie veröffentlichen eine Funktion, die für jedes zukaufende Smartphone einen Preis zurückgibt.


Aufgabe 4: Verkettung binärer Fallunterscheidung

Bestehende Datei - fallunterscheidungen.rkt

Wir haben nun zwei Arten von Fallunterscheidungen kennengelernt, die für unterschiedliche Zwecke geeignet sind. Auch haben wir bereits gezeigt, dass wir eine allgemeine Fallunterscheidung mit zwei Fällen ohne Probleme in eine binäre Fallunterscheidung überführen können. Doch wie sieht es aus, wenn wir für mehrere Fälle nur binäre Fallunterscheidungen verwenden dürfen?

(a) Ändere den Funktionskörper der Funktion btb-binaer so, dass nur noch binäre Fallunterscheidungen verwendet werden.

;Bestimmt den pH-Zustand anhand der Färbung des pH-Indikators Bromthymolblau (BTB)
(: btb-binaer (string -> string))
(check-expect (btb-binaer "gelb") "sauer")
(check-expect (btb-binaer "grün") "neutral")
(check-expect (btb-binaer "blau") "alkalisch")
(check-expect (btb-binaer "rot") "ungültiges Übergabedatum")
(define btb-binaer
  (lambda (farbe)
    (cond 
     ([string=? "gelb" farbe] "sauer")
     ([string=? "grün" farbe] "neutral")
     ([string=? "blau" farbe] "alkalisch")
     (else "ungültiges Übergabedatum")
    ) 
)  )

Suche

v
100.137.2.1.1.2 Strukturierung: Fallunterscheidungen
Kopieren durch Anklicken

Rückmeldung geben