Aufzählungen / Enums in Racket
Der Farberkenner
Die Studierenden Tara und Phoenix müssen für ihr Studium einige Versuche in einem Chemielabor mit den zwei pH-Indikatoren Bromthymolblau (BTB) und Methylrot (MR) durchführen. Da sie keine Lust haben die pH-Messungen ständig selbst abzulesen, beschließen sie die Bestimmung des pH-Bereiches zu automatisieren.
Um die Farbe der Lösungen zu erkennen baut Tara einen Farberkenner. Dieser besteht aus einer Kamera die drei Bits übertragen kann. Je ein Bit für die Farbanteile Rot, Grün und Blau.
Die beiden pH-Indikatoren können folgende Farben annehmen:
Entsprechend der möglichen Indikator-Farben beschließt Tara, dass nur die folgenden Binärcodes für sie relevant sind:
Erkannte Farbe | Übermittelter Binärcode |
---|---|
Blau | 001 |
Grün | 010 |
Rot | 100 |
Gelb | 110 |
Aufgabe 1: Binärcodes in Farben umwandeln
Um nicht weiter mit Binärcodes arbeiten zu müssen soll die Funktion binaer‑zu‑farbe
je nach Binärcode wieder die entsprechende Farbe als Zeichenkette zurückgeben. Bei allen nicht genauer definierten
Binärcodes soll "Uneindeutig" zurückgeben werden.
Die übertragenen Binärcodes werden ebenfalls als Zeichenkette übergeben.
(a) Übertrage den Code in deine Racket-Datei und
ergänze das Funktionsgerüst und den Funktionskörper für die Funktion binaer‑zu‑farbe
:
;Gibt für die erhaltenen Binärwerte die entsprechnede Farbe zurück
(: binaer-zu-farbe (string -> string))
(check-expect (binaer-zu-farbe "001") "Blau")
(check-expect (binaer-zu-farbe "010") "Grün")
(check-expect (binaer-zu-farbe "100") "Rot")
(check-expect (binaer-zu-farbe "110") "Gelb")
(check-expect (binaer-zu-farbe "101") "Uneindeutig")
...
Aufgabe 2: pH-Wert Bestimmung anhand der Farbe
Um den Farben geeigneten pH-Werten zuzuordnen hat Phoenix für den Indikator Methylrot (MR) die folgende Funktionen geschrieben:
;Bestimmt anhand der erhaltenen Farbe den ph-Wert für Methylrot
(: pH-Wert-MR (string -> string))
(check-expect (pH-Wert-MR "rot") "pH <= 5.1")
(check-expect (pH-Wert-MR "gelb") "5.1 <= pH")
(define pH-Wert-MR
(lambda (farbe)
(cond
([string=? "rot" farbe] "pH <= 5.1")
([string=? "gelb" farbe] "5.1 <= pH")
(else "unbekannte Farbe")
)
) )
Zusatzinfo: Mehtylrot im Detail
Genaugenommen weißt Mehtylrot drei verschiedene Farben auf:
- Rot - wenn der pH-Wert unter 4.4 ist
- Orange - im Umschlagsbereich zwischen 4.5 und 6.2
- Gelb - wenn der pH-Wert über 6.2 ist
Um unseren Racket-Code etwas kürzer zuhalten, wurde als Umschlagspunkt der pKs-Wert von Methylrot (pH=5.1) gewählt.
(a) Übertrage den Code in deine Racket-Datei und überprüfe die Implementierung mittels der Test-Fälle.
(b) Schreibe in der REPL einen Ausdruck, welcher die Funktionen pH-Wert-MR
und
binaer-zu-farbe
so verknüpfst, dass du den pH-Bereich für den Binärcode 110 erhältst.
Welche Rückgabe erhältst du?
(c) Erkläre warum der Ausdruck, obwohl er keinen Fehler wirft, dennoch die falsche Rückgabe produziert.
Aufgabe 3: pH-Wert Bestimmung anhand der Farbe
Um solche Probleme zu vermeiden, beschließen Tara und Phoenix, dass sie eine Möglichkeit brauchen
die möglichen Rückgabedaten und Übergabedaten von Funktionen direkt miteinander zu vergleichen.
Hierfür legen sie folgenden Wunsch-Signaturen fest:
(: binaer-zu-farbe (string -> pH-Indikator-Farbe))
(: pH-Wert-MR (pH-Indikator-Farbe -> string))
Da Racket natürlich keinen passenden Datentyp pH-Indikator-Farbe
hat,
müssen wir uns diesen selbst definieren. Eine Möglichkeit dies zu tun ist die folgende:
;Eine Indikatorfarbe ist eine der folgenden
; - "blau"
; - "grün"
; - "rot"
; - "gelb"
; - "ungültig"
(define indikator-farben
(signature (enum "blau" "grün" "rot" "gelb" "uneindeutig")))
(a) Übertrage das obige Code-Segment in deinen Racket-Code.
(b) Passe die Signaturen der Funktionen binaer-zu-farbe
und pH-Wert-MR
an und überprüfe die Funktionen erneut mittels der Test-Fälle.
(c) Passe die Funktionen Funktionen binaer-zu-farbe
und pH-Wert-MR
, wo notwendig, an um die Signaturverletzungen zu beheben.
pH-Indikator-Farbe
erstellt Phoenix noch
eine Funktion zur Bestimmung der pH-Werte für den Indikator Bromthymolblau (BTB):
;Bestimmt anhand der erhaltenen Farbe den ph-Wert für BTB
(: pH-Wert-BTB (pH-Indikator-Farbe -> string))
(check-expect (pH-Wert-BTB "gelb") "pH <= 5.8")
(check-expect (pH-Wert-BTB "türkis") "5.8 < pH < 7.6")
(check-expect (pH-Wert-BTB "blau") "7.6 <= pH")
(define pH-Wert-BTB
(lambda (farbe)
(cond
([string=? "gelb" farbe] "pH <= 5.8")
([string=? "türkis" farbe] "5.8 < pH < 7.6")
([string=? "blau" farbe] "7.6 <= pH")
(else "unbekannte Farbe")
)
) )
(d) Übertrage die Funktion pH-Wert-BTB
in dein Racket-Code,
überprüfe die Implementierung anhand der Tests und behebe mögliche Fehler.
Aufgabe 4: Eine gemeinsame Funktion für die beiden Indikatoren
Anstelle für jeden Indikator eine eigene Funktion zu haben, ist es auch möglich eine Funktion zu schreiben, die neben dem Farbwert auch den Indikator übergeben bekommt und dementsprechend den pH-Wert zurückliefert. Diese soll wie folgt funktionieren:
;Bestimmt anhand der erhaltenen Farbe den ph-Wert für einen Indikator
(: pH-Wert-Indikator (indikator pH-Indikator-Farbe -> string))
(check-expect (pH-Wert-Indikator "BTB" "gelb") "pH <= 5.8")
(check-expect (pH-Wert-Indikator "BTB" "grün") "5.8 < pH < 7.6")
(check-expect (pH-Wert-Indikator "BTB" "blau") "7.6 <= pH")
(check-expect (pH-Wert-Indikator "MR" "rot") "pH <= 5.1")
(check-expect (pH-Wert-Indikator "MR" "gelb") "5.1 <= pH")
(a) Entwerfe einen neuen Datentyp indikator
(b) Übertrage den obigen Code in deine Racket-Datei und ergänze das Funktionsgerüst und den Funktionskörper
für die Funktion pH-Wert-Indikator
Quellen
- [1]: Bromthymolblau - Urheber: DOJ - Lizenz: inf-schule.de
- [2]: Methylrot - Urheber: DOJ - Lizenz: inf-schule.de
- [3]: Color transition of Methyl red solution under different acid-base conditions(letzter Zugriff: 23.05.2025) - Urheber: LHcheM - Lizenz: Creative Commons BY-SA 3.0