Okay, dann muss ich, ich glaube es einmal in den Hintergrund schieben.
Genau, also ich wurde gewählt, mehrere Ansagen zu machen.
Wir brauchen euch Betreuerinnen für SE1 gesucht. Also für das
nächste Semester. Es soll ja irgendwie weitergehen. Momentaner Stand ist,
dass die Veranstaltung übernommen wird von einem anderen Professor,
aber der braucht natürlich genauso Betreuer.
Also das Konzept der Übung, das soll alles beibehalten werden.
Also hauptsächlich die Motivation, die wir immer euch geben,
das zu machen, ist, man lernt den Stoff nochmal ein bisschen intensiver.
Also wenn man anderen Leuten beibringt, was ihr jetzt gerade lernt,
dann verfestigt man nochmal so die ganzen,
das ganze Wissen
Aber es gibt natürlich auch Geld. Also wenn ihr irgendwie vielleicht nicht mehr
zu Hause wohnt und ein bisschen Geld selber verdienen müsst,
seht ihr hier, was man da bekommt.
Diese fünf Stunden, die ihr pro Woche arbeiten sollt,
die teilen sich auf in die drei Stunden Präsenz,
die ihr ja auch als Teilnehmer kennt.
Man muss ja drei Stunden fort sein und da irgendwie Leute betreuen.
Oder ihr werdet momentan betreut, irgendwann seid ihr dann die Betreuer.
Dann gibt es einmal pro Woche eine Betreuerrunde,
wo ihr quasi das aktuelle Blatt vorgestellt bekommt von meinem Nachfolger.
Die habe ich dann ein bisschen erklärt, worauf man so
achten muss und wo so die Fallstrecke sind und so.
Und eine Stunde sollt ihr euch selber noch irgendwie zu Hause vorbereiten.
Wie war das nochmal mit Iquels und was ist nochmal
eine Referenzvariable? Ich schaue mir das nochmal alles an.
So berechnen sich also
diese fünf Stunden
Und das Tolle ist, wenn ihr zwei Übungsgruppen übernehmt,
dann kriegt ihr zehn Stunden und wir erwarten dann eigentlich ja auch,
ja, dann müsstet ihr euch ja theoretisch drei Stunden dann,
glaube ich, so vorbereiten, damit das alles hinkommt.
Also das wird wahrscheinlich niemand tun. Also der Stundenlohn ist effektiv besser,
wenn ihr zwei Übungsgruppen übernehmt, kann ich einfach mal so sagen.
Tja, okay, kleines Stimmungsbild,
wer hätte denn so tendenziell grundsätzlich Interesse, das zu machen?
Ja, ja, so vielleicht 15, 15, 20 Leute,
okay. Genau, also wenn ihr daran Interesse habt,
dann schreibt eine Mail an die bekannte E-Mail-Adresse,
Ich lasse sie nochmal ein bisschen hier stehen.
Genau. Erfahrungsgemäß kriegen wir mal ungefähr doppelt so viel Bewerbung,
wie wir brauchen. Also seid bitte da nicht enttäuscht,
falls wir euch nicht nehmen können.
Okay, dann habe ich heute mal geguckt.
SE2-Klausur ist ja schon in zwölf Tagen, glaube ich.
Da sind unheimlich viele Leute für angemeldet. Das kann eigentlich
fast gar nicht sein. Also es ist ja so,
je nachdem, was ihr studiert, ist es meistens so,
wenn ihr euch für diese Veranstaltung anmeldet.
Wenn ihr sagt, ich will an der Übung und an
der Vorlesung teilnehmen. Oft ist es dann schon so,
dass ihr in Stina automatisch für die erste Klausur angemeldet seid,
auch wenn ihr das vielleicht gar nicht wollt oder wisst
oder so
Also prüfte einmal nach der Vorlesung oder so oder von mir aus
auch jetzt. Nach dem Motto, hey,
ich will eigentlich erst zum zweiten Termin schreiben, dann schaue ich mal,
ob ich auch wirklich abgemeldet bin vom ersten Termin.
Sonst verschenkt ihr ja einen Versuch. Ich hoffe,
das ist euch bewusst und ihr habt drei Versuche.
Wenn ihr automatisch zum ersten angemeldet seid,
aber nicht hingeht, dann ist ein Versuch weg.
Das wäre irgendwie schade. Und das betrifft jedes Mal
immer so 10 bis 20 Prozent der Studierenden tatsächlich.
Also letztes Jahr haben ungefähr 60 Studenten einen Versuch verschenkt,
einfach weil sie nicht gekommen sind.
Ich vermute mal, dass viele einfach gar nicht wussten,
dass sie angemeldet waren.
Also bitte prüft das
Gut, und auch andersrum. Also wenn ihr teilnehmen wollt,
prüft, dass ihr auch wirklich angemeldet seid.
Früher war das alles immer noch so ein bisschen lachs und
die Leute einfach mitschreiben lassen und dann war das irgendwie okay.
Das ist seit ein paar Jahren nicht mehr so. Also
wenn ihr nicht in Stine angemeldet seid und ihr schreibt die Klausur mit,
dann muss euer Prüfungsamt entscheiden, ob die Klausur gewertet wird oder nicht.
Und meistens geht das nicht durch. Okay. So,
muss ich dazu noch irgendwas sagen. Nee, also ich
werde über die Klausur auch nächste Woche nochmal was sagen.
Wir können nochmal die Probeklausur zusammen durchgehen vielleicht hier.
Das ist, glaube ich, ein ganz netter Abschluss.
Vielleicht als keine Motivation, dass ihr auch noch am
letzten Termin kommt
Ja, gibt es noch Fragen zu dem, was ihr
hier seht? Keiner meldet sich, okay. Ja,
dann würde ich sagen, machen wir mal weiter.
Vielleicht wundert ihr euch, dass ich heute ganz alleine hier stehe.
Ich habe meine Mitstrater gebeten, dass ich heute so einen kleinen Nachholtermin bekomme.
Also ich habe so viele Sachen nicht machen können, dadurch,
dass ich einmal gar nicht da war und dass die Zeit immer so hektisch war,
dass ich heute mal so ein kleines Nachholprogramm mit euch machen wollte.
Okay, ihr seht nicht, was hier steht,
das ist gut, dann bleibt so eine kleine Überraschung.
Also ich wollte mal zuerst nochmal mit euch mal wieder
den Klassiker Equiels ausgraben
Wo ist denn unser Equiels 4? Genau. Also,
das ist ja so das klassische Muster.
Man muss daran denken, dass man einen Object übergibt,
sonst wird die Methode nicht gefunden vom Java-Framework-Code.
Dann muss man gucken, dass der dynamische Typ des Objekts,
was da übergeben wurde, tatsächlich ein Bruch ist.
Ansonsten kann man gleich False zurückgeben. Also, wenn ihr versucht,
einen Baruch mit einem Konto zu vergleichen, sollte False zurückkommen.
Okay, wenn man dann festgestellt hat, dass es tatsächlich
ein Bruch ist, dann braucht man diese Typzusicherung.
Und nachdem man das gemacht hat,
kann man dann die jeweiligen Komponenten ein paar Weise miteinander vergleichen.
Die Zähler miteinander vergleichen, mein eigener mit dem anderen und
die Nenner miteinander vergleichen,
mein eigener mit dem anderen
Vielleicht alle die Tür da hinten zumachen, das irritiert mich immer so,
wenn da so Leute reingucken und nicht reinkommen, vielleicht,
weil sie mich hier vorne stehen sehen oder so.
Okay, und ich habe irgendwann mal ein interessantes Paper gelesen
von Kevin Henny, der schreibt immer ganz interessante Sachen.
Und da hatte ich gesehen, wie man diese Equiels-Methode in
zwei Equiels-Methoden aufteilen kann. Also die Argumentation war da so,
hm, hier passiert ja eigentlich relativ viel.
Also wir haben hier irgendwie so ein paar Zeilen,
die sich so ein bisschen um das Typsystem kümmern,
dass da auch wirklich das reinkommt,
was man eigentlich braucht und wenn da Quatsch rauskommt,
muss ich Falls zurückgeben und so
Und der eigentliche fachliche Vergleich ist ja der hier.
Und er hatte versucht, kann man nicht diese beiden Teile
irgendwie trennen? Er hatte sich also überlegt,
kann man nicht erstmal diesen Anfängerfehler machen und sagen,
ich mache diese Equiels-Methode mit dem eigentlich falschen Parameter-Typ,
also dass ich quasi direkten Bauch übergebe.
So, was müsste dann da rein, diese Zeile?
Das ist ja die Zeile, die sich darum kümmert,
tatsächliche Zähler miteinander zu vergleichen.
Und vielleicht kommt gerade so ein kleiner Flashback von letzter Woche.
Ich will im Prinzip diesen Code auslagern in diese Methode.
Ich habe jetzt auch hier diesen implementierten Code hier reingenommen,
dann kann ich das jetzt ja ersetzen, einfach durch den Aufruf.
Was muss ich denn jetzt hier hinschreiben,
um diese Methode aufzurufen
Ja. Genau. Sehr schön. Das sieht irgendwie lustig
aus. Also eine Equels-Methode ruft jetzt, ruft jetzt
eine andere Equels-Methode auf. Woher weiß denn jetzt Java,
welche Equels-Methode das ist, die hier aufgerufen wird?
Also es gibt jetzt ja hier zwei Equels-Methoden.
Es gibt ja einmal die und es gibt einmal die,
könnte das jetzt irgendwie eine Endlosrekursion werden oder so
Also es hat auf jeden Fall was mit Polymorphie zu tun,
aber es ist nicht die Polymorphie, die man meistens in Java meint.
Es ist tatsächlich so, dass der Compiler guckt sich an,
was steht denn hier in den Klammern? Der Compiler weiß,
oh ich glaube, dass die Fehler, die Fehlermeldung,
das ist schön, dass der Poper möglicherweise falsch ist.
Also der Compiler guckt sich einfach an,
was ist denn hier der aktuelle Parameter?
Aha, that, wo ist der denn definiert? Ach,
der ist ja hier definiert, was ist der statische Typ?
Boah, aha. Der Mensch will also eine Equals-Methode aufrufen,
die einen Bruch entgegennimmt statisch. Und schaue ich mal,
gibt es denn so eine Methode? Ah ja, hier ist sie.
Ja, das heißt, das passiert schon zur Übersetzungszeit.
Also wenn ich hier mal raufklicke und sage, F3,
also geh in die Methode,
die irgendwann später mal aufgerufen wird,
dann weiß der Compiler,
das kann
nur diese Equals-Methode sein
Das weiß der schon statisch. Der guckt sich einfach an,
was steht statisch in den runden Klammern, was ist der statische Typ davon?
Ah ja, alles klar. Das kann hier also niemals
passieren, dass hier irgendwie eine Etwas-Rekordion passiert oder so.
Okay, hat man jetzt dadurch so viel gewonnen?
Mal gucken. Also, wir haben jetzt das interessante Phänomen,
dass wir dieses Thead nur noch an einer Stelle brauchen,
nämlich genau hier, wo ich das gerade markiert habe.
Das heißt, man könnte das im Prinzip auch ersetzen durch
die Initialisierung von Thead und da brauchen wir die Variablen nicht mehr.
Gut, das macht exakt dasselbe. Zack, zack.
Hoffentlich bis hierhin
, klar
Und jetzt einfach ein interessantes Muster. Ich sage,
wenn eine bestimmte Bedingung gilt, dann will ich das hier returnen.
Ansonsten will ich Falls returnen. Ich weiß nicht,
ob wir sowas schon mal in Kerl hatten, wahrscheinlich nicht,
der hat ja keinen Return. Aber man kann das,
man kann tatsächlich diese Zeilen ohne eine If-Anweisung hinkriegen mit einem einzigen Return.
Vielleicht wäre das mal so eine Aufgabe für die Klausur,
wenn ich das jetzt nicht verraten hätte.
Das ist so ein kleiner Brainteaser. Also sieht jemand,
wie ich das ersetzen kann durch Return und dann irgendein,
ich sag mal, relativ komplizierter Ausdruck,
wo natürlich das alles irgendwie drin vorkommen muss,
möglicherweise noch mit mehreren Operatoren oder hinten
meldet sich jemand
Ich kann das ja immer hinschreiben, was du meinst und
alle verstehen, worüber du redest, dann das Equals.
Okay. So. Oh, Entschuldigung. Okay, das ist
schon mal ein erster guter Zwischentritt. Das Problem ist,
dass wir natürlich in SE1 und SE2 euch nie diesen Operator beigebracht haben.
Deswegen bin ich da immer so ein bisschen vorsichtig.
Also darauf hätte jetzt eigentlich keiner kommen können.
Aber schön, dass du den Operator kennst.
Wann kommt denn hier True zurück? Wann wird dieser Ausdruck
True zurückgeben? Welche Bedingungen müssen dafür gelten? Kann man
das irgendwie anders formulieren? Ihr Darm meldet sich jemand,
ja? True liefert, genau. Das heißt also,
diese Bedingungen muss True sein. Und diese Bedingung muss
True sein. Kennt ihr einen Operator und Java,
mit dem ich sagen kann,
zwei Bedingungen müssen wahr sein,
damit wahr zurückkommt
Vielleicht irgendjemand anderes mal. Hatten wir, glaube ich,
in Caro Woche eins oder zwei. Ich weiß es nicht mehr
genau. Ja. Der Hundeoperator, genau, ne?
Zack, zack. Zack. Ja, dann brauchen wir
diesen komischen Operator, nicht den wir nicht kennen.
Ich sage also, ein Bruch ist dann gleich mit einem beliebigen Objekt,
wenn es sich bei dem beliebigen Objekt um einen Bruch handelt.
Und wenn ich dann gleich bin mit diesem statisch als Bruchbekanntenbruch.
Ja. Und bis zum ersten Mal die ersten Anzeste
Das ist korrekt. Also, wenn dieser Ausdruck false ist,
wird sofort false zurückgegeben. Richtig. Das heißt also,
diese Typzusicherung wird nur vorgenommen, wenn dieser Ausdruck wahr ist.
Ja, das heißt, das macht genau das,
was wir wollen. Und das Witzige finde ich jetzt,
ich weiß nicht, ob ihr euch noch erinnert,
wie viel Kot das vorher war.
Wir haben jetzt hier eine Zeile Code,
die sich um diesen Typ Mist kümmert.
Und eine Zeile Code, die sich um die fachliche Logik kümmert.
Wir haben kein Ist mehr, keine,
nicht mal eine Variable und mal zwei.
Also wir haben hier genau eine Variable und die Variable Optch,
die vom statischen Typ Object ist.
Und in diesem Scope haben wir nur die Variable Wet,
die vom Typ
Bruch ist
Also ich persönlich finde das ganz nett. Ja,
und ich würde euch empfehlen, kleiner Hinweis für euch,
so die Leute, die sich das angucken und fragen,
was könnte denn so alles in der Klausur drankommen,
dass dieses, ich sage jetzt einfach mal,
Muster schadet sicherlich nicht,
wenn man das schon mal gesehen hat.
Gut. Deswegen damit ist es auch so wichtig, das heute zu wiederholen.
Wollen wir mal schauen, dass die Tests noch durchlaufen?
Dass wir hier nichts kaputt geequels haben. Jo, Tests
laufen noch durch. Okay, habt ihr zu diesen Muster
noch Fragen?
Eine Frage
Ah, das ist eine sehr gute Frage.
Die kommt jedes Jahr von irgendjemandem mutigen, der sich traut.
Also die Frage ist, brauchen wir diese Methode denn überhaupt noch? Ja,
so nach dem Motto, also wenn es eine Methode gibt,
die sich um Brüche kümmert und die Object-Methode,
die wir aus Eakles erben, die wird ja wahrscheinlich fort zurückgehen,
wenn ich da irgendwie Schwachsinn übergebe.
Das Problem ist aber, diese Auflösung,
welche dieser beiden Eakles-Operationen ich nehme,
passiert schon zur Übersetzungszeit
Das ist also zu früh oder keine Ahnung. Also es kann durchaus passieren,
das zur Laufzeit, ja, der Compiler weiß,
ich habe hier irgendein Objekt, ich entschuldige Compiler, Schwachsinn, die JWM,
dass die JWM sagt, ich habe hier irgendein Objekt,
ich weiß nicht genau, was das für ein Objekt ist,
das muss erstmal irgendwie getestet werden, was es für ein Objekt ist.
Ja, und tatsächlich ist es auch so,
du kannst dir überlegen, diese Operation, wir wollen ja letzten Endes,
dass die aus dem JUnit irgendwie aufgerufen wird, ne,
wir haben doch dieses Assurd Equals irgendwo,
lass mich noch mal ganz kurz gucken,
wo haben wir es denn, muss meine Testklasse,
zum Beispiel hier, ne, also du kannst dir ja vorstellen,
in diesem Assurd
Equals muss dieses Equals ja
irgendwie aufgerufen werden
Ja. Und jetzt kannst du dir überlegen, wie müsste
dieses Assert Equals programmiert sein, damit diese Operation aufgerufen wird.
Dann müsste in dem Assert Eagles, was in dem J. Unit-Test-Framework
drin ist, müsste eine Variable sein vom statischen Typ Bruch.
Und Share Unit ist ja, keine Ahnung,
15 Jahre alt, 20 Jahre alt.
Da gab es diese Klasse noch gar nicht. Also es
kann unmöglich einen Aufruf dieser Operation in der Klasse J. Unit irgendwie drinstehen.
Das ist dieser Unterschied zwischen statischer Typ und dynamischer Typ.
Das ist ja ein bisschen schwierig zu erklären
Okay, das heißt also, jeglicher Framework-Code wird immer diese Equels-Methode aufrufen.
Und ich müsste eigentlich genauer sagen, diese Equels-Operation,
weil die gibt es eben schon seit 20 Jahren.
Und nur die können wir auch tatsächlich überschreiben.
Gut. Okay, ja, sonst noch Fragen,
das war eine sehr gute Frage, ja.
Das ist eine Darstellung von deutschen Welten. Dieser Steak hört
sich an, die Armee ist das Leben, der ist
ein 302. Wir haben ja, glaube ich, den,
wir haben uns doch, glaube ich,
so darauf geeinigt, dass wir gesagt haben,
bei der Erzeugung
Genau, man kann keine ungekürzten Brüche erzeugen, genau,
genau, sehr schön. Okay, sehr schön,
das war so das mit den Equals, dann schaue ich mal
ganz kurz, was ich noch mit euch machen wollte.
Also ich habe das hier mal betitelt unter Equals überladen.
Man muss da auch unheimlich vorsichtig sein, was damit genau gemeint ist.
Wo ist mein Equals? Hier. Also diese Methode,
haben wir überschrieben, es gibt dieses Equals Object seit 20 Jahren
in der Klasse Object und an der Stelle habe ich gesagt,
ich will mein eigenes Equals Object haben,
das nennt man überschreiben.
Und an dieser Stelle haben wir die Methode Equals überladen.
Wir haben jetzt in derselben Klasse zwei Equals-Methoden.
Das ist was anderes. Macht euch nochmal klar,
was der Unterschied ist zwischen Überschreiben und Überladen.
Das ist ja auch SE1 Grundwissen im Prinzip
Hm? Ich möchte meinen Bruch auch mit einem Intager vergleichen können.
Das würde ich nicht machen wollen. Dann hast du das interessante Problem,
ich kann einen Bruch dann mit einem Intager vergleichen,
aber ich kann nicht einen Intager mit einem Bruch vergleichen.
Ja, hast du so eine blöde Asymmetrie da drin.
Also Equals vernünftig hinzukriegen, ist gar nicht so einfach.
Okay, also das war das Equals überladen.
Was wollte ich noch mit euch machen?
Genau. Wir haben ja hier in unseren Tests,
ich glaube, die haben völlig blöde Namen.
Ich glaube, ich wollte den Namen mal erinnern.
Nee, ich habe die Namen geändert.
Die hießen vorher Kukuku und Kukuku
Was haben wir in diesen Tests gemacht?
Wir haben ein Hash-Set erzeugt oder hier haben wir es erzeugt
und haben einfach mal einen Bruch reingetan und haben geguckt,
ob der Bruch drin ist.
Nun gibt es ja nicht nur Hash-Sets.
Ja, es gibt auch noch andere Sets.
Also wenn ich mal hier irgendwie in die Typ-Hierarchie reingucke,
Appstract-Set, Appstract-Collection. Schade, ich hatte gehofft,
dass ich ganz schnell einfach nur das Interface-Set finde.
Wie finde ich das denn mal schnell? Ich gehe mal mit F3
hier rein. Und dann steht hier sicherlich irgendwo Implements-Set,
genau. Was gibt es denn noch so für Sets?
Also wenn ich jetzt hier einfach mal mit F4,
kann ich dann sehen, welche Sets es so gibt.
Also es gibt Hashtag
Wo ist das Set, was ich euch eigentlich zeigen wollte?
Ich glaube, heißt es nicht Treeset?
Wieso finde ich das Treeset hier nicht? Der Compiler wird
es oder die IDE wird es gleich für mich finden.
Also es gibt eben nicht nur Hashsets oder auch ein
anderes Set und das wollte ich auch mal mit euch.
Dafür wollte ich auch nochmal einen eigenen Testfall machen.
Nehmen wir nochmal diesen leicht verständlichen Testfall.
Den klebe ich mal hier nach unten. Und dann nehmen
wir den mal nicht Hashset enthält, sondern Treeset enthält.
Und dann nehme ich hier entsprechend ein Treeset und muss ich
das bei der Erzeugung natürlich auch machen.
Und ich hoffe, ich habe mich jetzt nicht völlig vertan,
wenn ich jetzt einmal sage Import,
ob er das dann findet
Oh mein Gott, ist er zufrieden?
Warum hat er das denn vorher nicht gefunden?
Wenn ich jetzt nochmal F4 sage, kommt dann irgendwas,
was mir weiterhilft, erbt auch von Apps durch jetzt.
Ich weiß es nicht. Also ich muss... Ah.
Ah, deswegen hast du beim Interface-Set nicht gefunden.
Dankeschön. Genau. Das würde ich gerne mal gucken,
ob das auch geht. Es ist einfach eine andere Implementation.
Nicht mit Hashing, sondern mit binären Suchbäumen. Ja,
da kann ich dir doch einfach ausführen, oder?
Oh, was haben wir denn da jetzt?
Tree-Set enthält eingeführten Boris Fee geschlagen. Aha. Und schauen
wir noch, was passiert ist. Javalang, Class,
Cast Acception
Brüche, Bruch, Cannot Becast to Java, lang comparable.
Haben wir euch schon mal was über dieses Javalon Comparable erzählt?
Ich bin mir da gar nicht so sicher.
Eher nicht, ne? Okay, kann man sich mal
den Code angucken, wo das tatsächlich geknallt ist?
Hier irgendwie? Ja, okay, Java-Framework-Code.
Ist immer nicht besonders wahnsinnig lesbar. Okay, ein Treeset
. Wie funktioniert eigentlich ein Treeset? Wir hatten euch
ein SE1 mal was beigebracht über so Baumstrukturen.
Könnt ihr euch noch erinnern? Vielleicht mache ich das mal
ganz kurz als kleine Grafik
Ich war mal ein neues, neuen Tab.
Nehmen wir mal an, ich will ein Set haben,
wo die Zahlen eins, zwei, drei,
vier, fünf, sechs und sieben drin sind.
In einem Hashtag wären die irgendwie in diesen Überlaufbehältern drin,
je nachdem, wie man das hasht.
Und in einem Treeset tue ich mal jetzt die vier irgendwie
nach oben und dann tue ich mal die zwei und die sechs irgendwie hier hin.
Ich muss das gleich noch ein bisschen schöner formatieren.
Vielleicht seht ihr dann ungefähr die Struktur so. Okay,
es sieht noch nicht wirklich wie ein Baum aus, oder?
Kriege ich das irgendwie hin, dass es aussieht wie ein Baum?
Also wenn ich hier irgendwie mal so ein bisschen slash
hin mache und hier irgendwie vielleicht ein Backslash.
So, und dann, ja, ich sehe,
ich bin nicht unbedingt ein Asgard-Künstler,
aber irgendwie kriegen wir das hin
Das sieht doch schon eher aus wie ein Baum, oder?
Und dann vielleicht noch irgendwie, ja, ich glaube,
hier spare ich mir das jetzt mal,
weil ich kriege die Striche nicht weniger gebogen oder mehr gebogen.
So ist ein Treeset intern aufgebaut. Also das kleinste Element steht
quasi unten ganz links und das Größte steht irgendwie unten ganz rechts.
Und wenn man jetzt ein Element sucht,
dann fängt man einfach oben an und überlegt sich,
wo müsste denn das Element stehen, was ich suche?
Nehmen wir mal an, ich suche die sechs.
Dann sehe ich jetzt hier, oh, hier ist die vier,
dann muss ich jetzt nach rechts gehen in den Baum.
In dem linken Teil, warum kann das Element nicht drin sein,
denn da sind ja alle Elemente kleiner.
Seht ihr das hier alle Elemente kleiner sind als die Firmen?
Okay, dann geht es hier weiter. Oh,
ich habe die sechs gefunden, das war ja ein blöder langweiliger Fall.
Nehmen wir mal an, ich suche die drei.
Okay, ich fange wieder ganz oben an.
Ich suche die drei und hier steht die vier,
muss ich jetzt in den linken oder in den rechten Teil bauen?
Einfach sagen, Ich habe einfach mal links gehört,
also ich muss jetzt hier in den linken Teilbaum gehen.
Jetzt sehe ich hier die zwei und ich suche nach der drei.
Muss ich jetzt, ich markiere das mal, ich bin gerade hier.
Muss ich jetzt nach links oder nach rechts?
Ich habe rechts gehört, denn die drei ist ja größer.
Also wenn, kann sie nur hier stehen. Und ich habe sie auch tatsächlich gefunden. Ja,
ich muss also immer die Frage beantworten können, das Element,
was ich gerade sehe und das Element, nachdem ich suche,
wie stehen die in einem Verhältnis, sondern da sind die gleich,
dann habe ich es gefunden, ist das,
was ich so kleiner, da muss ich im linken Teilbaum weitermachen,
ist es größer,
da muss ich im rechten Teilbaum weitermachen.
Ja, ich muss also die Frage beantworten können,
wenn ich zwei Elemente habe,
ja, sind die gleich, kleiner oder größer.
Und ich habe das bis jetzt nicht programmiert.
Also Java kann das nicht auf magische Art und Weise wissen,
wann ein Bruch kleiner ist als ein anderer
Okay. Und dafür gibt es dieses Interface Comparable.
Ich kann also sagen, die Klasse Bruch implementiert das Interface Comparable,
so hat man das früher in Java 1.4 geschrieben.
Und jetzt beschwert sich der Compiler, der Compiler will wissen,
womit kann man Brüche denn vergleichen? Oder womit kann ich
einen Bruch vergleichen? Das sieht so ein bisschen komisch aus.
Man muss das Bruch da nochmal reinschreiben. Das heißt,
so viel wie Einbruch kann verglichen werden mit einem anderen Bruch.
Warum ist dieses Interface einmal ganz kurz angucken, was da drin steht?
Oh Gott, ganz viel Text. Der ist aber wichtig,
der Text. Ich werde den aber gleich für euch zusammenfassen.
Es ist aber, wenn man mal durch den ganzen Text
durchgeht, ah, ihr könnt es gerade noch sehen.
Es gibt nur eine einzige Operation in diesem Interface, Comparto
, ganz viel Text. Ich will den nicht sehen,
dafür wird er euch erstmal nur
Ja, also ich könnte,
wenn mein Bruch dieses Interface implementiert und ich biete diese Operation an,
dann kann ich eben die Frage beantworten, bin ich selber kleiner,
gleich oder größer als dieser andere Bruch?
Ja, ich muss also diese Comperto-Methode implementieren, klar.
Das ist ja ein Grundwissen, jetzt kann ich das hier ihr Clips machen lassen.
Ad-un-Implemented Message, comparable comperto und das will ich haben.
Das ist ja natürlich erstmal nur Quatsch.
Jutten, haben wir sie? Und gemäß meiner Namenskonvention,
Konvention nenne ich das nicht O, sondern That.
So, jetzt haben wir genau diese beiden Brüche in der Hand. Jetzt,
jetzt sage ich das mal kurz auf Deutsch,
also wenn This, kleiner That, dann,
und das muss ich gleich erklären, Fantasys, ob's,
you user, they had to do do do do.
Ja, ansonsten sind sie halt gleich, dann so.
Jetzt ist die Frage, was muss ich denn da jetzt zurückgeben?
Ich muss ein Int zurückgeben, das klingt ja erstmal total komisch.
Ich hätte jetzt vielleicht erwartet, dass man da irgendeine Datentür zurückgibt,
der sagt, kleiner, gleich oder größer, irgendwas,
was drei Elemente hat, ja. Ich weiß nicht,
früher war man irgendwie nicht so weit in Java, man hat gesagt,
ich gebe ein Int zurück und dieser Int wird so gedeutet,
in diesem Fall, wenn ich selber kleiner bin,
als der Bruch, den ich übergebe,
dann irgendeine negative Zahl liefern, ja,
irgendeine,
man kann minus eins nehmen oder minus 42 oder minus
zwei Milliarden,
ist völlig egal
Was glaubt ihr, was ich zurückgeben muss, wenn der eigene,
also wenn ich selber größer bin als der übergebene Brauch?
Ja. Genau. Irgendeine positive Zone. Und was bleibt
jetzt noch übrig? Gibt es noch was anderes aus der
negativen und positiven Zahlen? Je nach Definition. Du hast
ja gerade schon so schön gesagt, größer als null.
Also was bleibt dann übrig, wenn hier gemeint ist,
größer als null. Und hier, kleiner als null,
was könnte dann noch übrig bleiben?
Ist zu leicht die Frage, oder?
Keiner will sich blamieren
Null, null muss man zurückliefern, genau, ja.
Gut. Ja, wie kann ich denn jetzt feststellen?
Also ich selber bestehe ja aus Zähler und Nenner,
diese Zahl besteht auch aus Zähler und NRW kann ich jetzt feststellen,
ob ich kleiner bin als die andere Zahl.
Das ist eine mögliche Antwort. Du wolltest in einer Zeile machen,
wow, dann machen wir erstmal die einfache Variante und dann gucken wir,
ob es auch in einer Zeile geht,
da meldet sich jemand.
Du willst subtrahieren, ah
Und dann gucken, ob es kleiner als nur A. Ich
glaube, die haben wir tatsächlich nicht.
Ich glaube, so eine Methode haben wir leider nicht.
Aber auch ein cooler Ansatz. Sonst jemand? Wahrscheinlich ist
nicht allen klar, was gemeint ist.
Deswegen machen wir nochmal kurz einen eigenen Chat. Also,
ich will wissen, ob A durch B, ja,
ich weiß nicht, größer, kleiner gleich, C durch D.
Und jetzt hast du gesagt, irgendwas überkreuzt.
Was muss ich jetzt ausrechnen?
Okay, ihr seid alle immer schon so trickreich mit dem Minus.
Ich will das Minus jetzt erstmal nicht benutzen,
aus gutem Grund. Also, aber nach dem Motto,
wenn diese Zahl kleiner ist als diese Zahl,
dann bedeutet das, dieser Bruch ist kleiner als dieser Bauch.
Habe ich das richtig interpretiert? Okay. Gut, das heißt,
wir können ja erstmal diese Überkreuzprodukte einmal ganz kurz bilden.
Ich kann das ruhig nennen, AD,
dann ist euch vielleicht klar, was wir hier gerade ausrechnen.
Also AD ist This Zähler, hallo,
mal seit Nenner
Oder ich schiebe das mal nach oben.
Das ist ja noch nichts mit dem Kommentar zu tun.
Und CB ist Thatzähler, mal this Nenner.
Habe ich das richtig gemacht? Gut. Okay,
und jetzt könnt ihr doch einfach sagen, wenn AD kleiner
ist als CB, so und jetzt kommt eine Herausforderung.
Ihr müsst mir jetzt irgendeine negative Zahl sagen.
Dann nehme ich einfach mal minus eins.
Das ist die einfachste
Wenn sonst nichts kommt, dann kann ich sagen,
wenn AD größer ist als CB, dann gebe ich plus eins zurück.
Und ach guck mal, das Retour 0 steht da schon,
das ist ja witziger Zufall. So könnte man das zum Beispiel machen.
Jetzt kann man da sicherlich noch irgendwelche Optimierungen machen,
man subtrahiert, statt zu vergleichen und so.
Das lasse ich euch mal als Hausaufgabe,
ich will das hier nicht zu kryptisch machen.
Ich wollte es hier nochmal ganz explizit machen,
wenn ihr also irgendwie feststellen könnt, hey,
ich bin irgendwie kleiner als das Übergebene, dann müssen wir was Negatives zurückliefern.
Wenn ich feststellen kann, ich bin größer als das Übergebene
, dann muss ich was Positives zurückliefern.
Und ansonsten gebe ich null zurück. Ach Mist,
jetzt habe ich das JGK9 gar nicht mehr inszeniert.
Ich wollte euch hier noch einmal Das zeigen,
dass es auch für ganz normale Strings geht.
Vielleicht machen wir da auf einmal ganz kurz hier irgendeine Hilfsklasse,
wie kriege ich dieses Fenster zu?
Nee, jetzt hat das andere Fenster geschlossen.
Ich mache hier mal ganz kurz eine kleine Klasse,
die ich jetzt nur deswegen habe, weil ich diese Jay-Schäne nicht da habe,
so eine kleine Spielklasse, so immer Spielzimmer.
So, ich wollte euch einfach mal zeigen,
dass es in Java schon viele Klassen gibt,
die dieses Comparable Interface implementieren, zum Beispiel Strings,
also ich kann zum Beispiel sagen, ja,
was nehmen wir da mal?
Competial World. Was würdet ihr erwarten? Kommt da
eine negative Zahl raus, eine positive oder null?
Und das ist ja so eine wunderbare Abstimmungsfrage eigentlich, oder?
Also, wer glaubt, dass Hello kleiner ist als World
und deswegen eine negative Zahl rauskommen muss?
Das sind so ungefähr, sag ich mal, Dutzend.
Wer glaubt, dass Hello und heute das gleiche Wort sind
und deswegen müsste null rauskommen. Einer. Wer glaubt,
dass Hello größer ist als World und deswegen müsste was Positives rauskommen.
Okay, einer. Dann schauen wir kurz
Es kommt tatsächlich was Negatives raus. Weil wenn ihr
in einem Wörterbuch nachgucken würdet in einem englischen Wörterbuch,
dann wurde Hello auf einer früheren Seite kommen als World.
Okay, jetzt kann man sich überlegen, warum da minus 15 rauskommt,
hat irgendwelche technischen Gründe, ist eigentlich nicht besonders spannend.
Wer will wissen, warum da minus 15 rauskommt,
dann erkläre ich es. Aber doch einiger einigermaßen viele Leute.
Also der Algorithmus ist eigentlich ganz einfach. Es werden sich erstmal
die ersten beiden Zeichen angeguckt und dann sieht man sofort,
oh, die sind verschieden, ich kann jetzt schon entscheiden,
wie die Wörter in einer Reihenfolge im Wörterbuch sind.
Das kann ich schon am ersten Buchstaben entscheiden, dadurch,
dass sie verschieden sind. Und dann nimmt man diesen Trick,
den du, glaube ich, gerade machen wolltest,
man subtrachiert die beiden Buchstaben einfach voneinander
Ich subtrahiere, also ich rechne aus, ha-w-w.
Was ist denn ha-w-w? Ja. Minus 15. Das liegt einfach daran,
dass das W im Alphabet 15 Stellen weiter ist als das Haar.
Ja, also ihr könnt mit Buchstaben,
wenn ihr auf Buchstaben Subtraktionen macht, dann wird einfach nur geguckt,
wie weit sind die im Alphabet.
Und wenn der erste Buchstabe eben vorher ist,
dann kommt was Negatives raus und andersrum wurde was Positives rauskommen.
Wenn ich jetzt hier zum Beispiel mal hinschreibe,
Xello,
was müsste dann rauskommen
Richtig, eins, weil das X ist ja ein weiter als das W. Die Eins war eben ganz kurz sichtbar, hier ist sie, ne? Okay. Und wenn man jetzt irgendwie,
keine Ahnung, ABC jeweils davor schreibt,
dann wird dieser Algorithmus sich diese beiden As angucken und sagen,
das sind ja beides As,
dann weiß ich nicht so genau, was ich machen soll,
dann gucke ich mir mal den nächsten an,
das sind beides Bass, ich weiß immer noch nicht,
was los ist, beides Ziels, ich weiß immer noch nicht,
oh, jetzt habe ich endlich mal zwei gefunden,
die verschieden sind, dann weiß ich,
welches woher kommt und welches später kommt.
Das ist eigentlich ganz einfach. Okay, also Strings implementieren eben
auch dieses Comparable. Warum haben wir das jetzt gemacht?
Wir hatten ja in der Bruchklasse, hatten wir ja dieses Phänomen,
dass dieser Testfall Ja, dass da halt eine Acception kam.
Also irgendwie konnten wir das nicht wirklich einfügen in dieses Tree-Set.
Mal gucken, ob das jetzt geht. Wo ist mein Test?
Hier ist er. Schaut mal, das funktioniert jetzt. Ja,
also immer, wenn ihr, also ich würde sagen,
eigentlich für fast jeden Fachwert macht es Sinn, dieses Comparable zu implementieren.
Denn wenn ihr sagt, okay,
ich implementiere das equals und das Hashcode, was man hier sieht,
Equals und Hashcode, dann kann man leider nur Hash-Sets benutzen.
Vielleicht gibt es aber auch Benutzer, die sagen,
nö, ich würde kein Hash-Set, ich will ein Tree-Set,
dann müsst ihr dieses Comperator implementieren.
Und einer der Vorteile zum Beispiel von diesem, Tre-Set ist folgender.
Wenn ihr euch diese Struktur anguckt, das sieht ja sehr geordnet aus.
Also egal, in welcher Reihenfolge ihr die Elemente in dieses Tre-Set reinstopft.
Es wird immer so intern umstrukturiert, dass die Elemente,
wenn ihr darüber iteriert, immer in der Reihenfolge sind eins,
zwei, drei, vier, fünf, sechs, sieben.
Also wenn ihr da einfach mal so horizontal durchgeht quasi. Ja,
also wenn ihr tatsächlich mit einer VI-Schlaf über ein Tre-Set rübergeht,
dann kommen die Elemente in aufsteigender Reihenfolge daraus.
Das will man vielleicht manchmal haben. Gut. Also deswegen
nochmal gesagt, ihr müsst versprechen, dass euer Fachwert comparable
mit eurem eigenen Typen in Spitzenklammern implementiert
Und dann, ja, in dem Interface gibt es
nur die eine Operation, das ist eben diese hier.
Und vielleicht gucken wir uns noch mal ganz kurz an,
was sind der Kommentar sagt, den ich eben so übersprungen hatte,
so in dem Interface. Da steht alles drin,
was ich euch eben so lachs daher gesagt habe, ja.
Das ist hier jetzt leider überhaupt nicht gut formatiert.
Kann ich nicht hier hingehen und irgendwie sagen,
ich will ein Java-Doc-View haben, gibt es nicht irgendwelche Clips-Experten,
die mir jetzt sagen können, show view Java-Doc, ach guck mal.
Wieso sehe ich jetzt nichts? Ich gehe noch mal neu
raus, hier. Ja,
wenn ich das jetzt noch mal ganz kurz hochziehe,
dann müsste diese Information,
die ich euch gerade gesagt habe,
hier irgendwo eigentlich stehen
Transitivität, bla, bla, bla. Ach hier,
das ist eigentlich der spannende Satz, ja.
Gibt eine negative Zahl, null oder eine positive Zahl zurück,
diese drei Fälle gibt. Je nachdem, ob dieses Objekt
kleiner als gleich oder größer ist als das übergebene Objekt.
Den ganzen anderen Kram mösst ihr euch nicht angucken,
das ist die tiefere Mathematik.
Ich weiß nicht. Ich glaube, das verwirrt jetzt eher
. Diese drei Fälle müssen euch davon noch klar sein.
Negativ heißt kleiner, null heißt gleich, positiv heißt größer.
Ja, okay. Ja, gibt es dazu noch Fragen?
Ich lege das mal kurz auf Bruch und ein bisschen Vollbild
machen und wo ist die Implementation
Zack. Zu dem Competor noch fragen. Ah, gute Frage
. Wie ist das denn mit kleinen und großen Buchstaben?
Wo ist mein Spielzimmer? Habe ich das geschlossen? Hier.
Vielleicht, nochmal als kleiner Hitbus, als kleiner Hinweis.
Man kann einen Buchstaben nehmen, uns zum Beispiel in ein Intcasten.
Ja, das mache ich jetzt einfach mal.
Einmal mit dem kleinen A und aber mit dem großen A,
dann könnt ihr wissen, was da tatsächlich gerechnet wird.
Also jeder Buchstabe hat ja so ein Unicor,
das ist einfach nur eine Zahl und du siehst,
wenn ich das mal ein bisschen hose scrolle, nein, hier.
Du siehst, das kleine A hat den Unicor 97
und als große Art,
den Unicord
Das heißt also, die Großbuchstaben kommen im Wörterbuch vor den Kleinen.
Das ist jetzt vielleicht ein bisschen an den Haaren herbeigeflogen,
aber so ist es in Schafa. Ja. Ja,
also die ersten 128 Zeichen von Hühnerkurt sind der Asky-Code.
Genau. Da war noch eine Frage. Das war die
Frage, genau. Ja. Die ersten 128 sind genau
gleich. Gut. Okay, dann schaue ich mal,
was ich noch für euch habe.
Jetzt haben wir hier schon Halbzeit durch den technischen Staum anfangen.
Na gut. Man kann es nicht ändern.
Das war das Comparable. Genau. Was habe ich noch
? Ach ja, jetzt kommt ein riesiges Thema.
Wir haben ja in der Klasse Bruch
eine Methode geschrieben
Die aus einem Bruch einen String macht. Hier ist sie.
Das war ja eigentlich relativ einfach. Wir haben ja diese
beiden Komponenten und wir kleben da einfach diesen Slash dazwischen.
Und dann wird das hier automatisch von innen nach String
gewandelt und so, das kann alles Java automatisch.
Jetzt wäre es ja irgendwie auch ganz nett, wenn das irgendwie rückwärts gehen würde.
Ich habe einen String, wo drin steht, drei Leertaste,
slash Leertaste 4. Und ich will daraus einen Bruch machen.
Dazu schreibe ich vielleicht einmal ganz kurz den Test,
dass euch klar ist, was ich meine.
Also haben wir hier irgendeinen Test, der to string testet
und dann schreibe ich mal, guck mal hier.
Ich mache jetzt mal quasi genau den umgekehrten Test dazu.
Also Public Void, Test, vielleicht From String.
Mir fällt gerade nichts Besseres an
Also, ich will sagen, es soll drei Viertel rauskommen.
Ja, und jetzt muss ich mit,
das muss wahrscheinlich nur eine Fabrikmethode sein.
Da sage ich, also mal Bruchpunkt from String 3 durch 4.
Und vielleicht erstmal mit den Leertasten. Vielleicht ignoriere ich erstmal
die Leertasten, die machen es erstmal nur kompliziert.
Ja, das ist erstmal die Anforderung, wie es haben will.
Ich will also in der Klasse Bruch eine statische Methode from String haben,
der übergebe ich einen Bruch in Stringform.
Das ist ja eine String der Länge 3. Und daraus soll dann
ein Bruch gemacht werden und da soll eben drei Viertel bei rauskommen.
Seht ihr, das ist genau das Gegenteil zu dem hier ist quasi.
Hier mache ich aus einem String einen Bruch und hier mache ich aus einem,
Entschuldigung,
hier mache ich aus einem Bruch einen String und hier aus
einem String
einen Bruch
Ja, wie könnte man das denn jetzt angehen?
Also, die Lösung lautet reguläre Ausdrücke.
Ich weiß nicht, wer von euch reguläre Ausdrücke kennt.
Einmal Handwurf für reguläre Ausdrücke kennen. So vielleicht die Hälfte
des Publikums, okay. Hattet ihr schon den FG,
genau. Aber hier sitzen ja auch teilweise Nebenfächler,
die wir jetzt vielleicht gar nicht wissen, wovon ich hier rede.
Deswegen versuche ich mal, für unseren Anwendungsfall die Basics von regulären Ausdrücken euch klarzumachen.
Weil die sind sehr nützlich für das aktuelle Aufgabenblatt.
So, jetzt habe ich hier unglaublich viel Kram.
Das lasse ich mal lieber alles da, manchmal schließe ich zu viel.
Also mache ich mir hier mal ein neues Bild.
Ja, okay
So. Die Grundidee ist es bei regulären Ausdrücken zu sagen,
ich baue mir einen Automaten und diesen Automaten füttere ich
nach und nach mit einzelnen Zeichen aus dem String.
Also ich würde in diesen Automaten erstmal die drei reinwerfen,
dann den Slash und dann die vier und dann würde ich mal gucken,
ob da was Vernünftiges bei rauskommt.
Und wie wird so ein Automat intern modelliert?
Jetzt könnte ich hier meine Zeichenkünste, ja,
hohe Schwarze ist schon okay, vielleicht nicht ganz so dick.
Meine Zeichenkünste bewundern. Also man macht diese Zustände dieses Automaten
. Das soll ein Kreis sein, ja.
Das soll ein Kreis sein und man macht hier gerne so
einen schwarzen Strich noch daneben irgendwie.
Das heißt,
hier fängt Automat an
So, das ist der Zustand, es kann losgehen.
Ich habe noch kein Zeichen gesehen. Und jetzt konzentrieren wir
uns mal darauf, dass wir tatsächlich nur Brüche verarbeiten wollen,
die nur aus jeweils einer Ziffer bestehen.
Um es erstmal einfach zu haben. Also ich sage,
ich kann in den nächsten Zustand kommen,
dieser Zustand steht dafür, ich habe den Zähler quasi verarbeitet.
Und wie komme ich jetzt in diesen Zustand?
Mach ich mal hier, vielleicht mache ich da mal tatsächlich,
das sieht aus wie ein Auto sonst, ich mache mal eine andere Farbe.
Flamme mal blau für die Pfeile. Also ich kann in
diesen anderen Zustand kommen, indem ich irgendeine Ziffer übergebe.
Ja, und ich schreibe jetzt hier einfach mal hin,
Ja, soll ich jetzt hier tatsächlich alle ziffern,
die das Gipfel schreiben? Ich sage einfach mal null,
das soll eine null sein, oh Gott, Punkt,
Punkt, 9. Also glaubt mir einfach mal,
das soll eine 9 sein, ja?
Also irgendeine der Ziffern von 0 bis 9 wird akzeptiert.
Und dann bin ich in dem nächsten Zustand.
Was würde ich denn jetzt erwarten, welches Zeichen als nächstes?
Wenn wir sagen, wir beschränken uns doch auf das Zele
und Ende nur aus einer Ziffer bestehen.
Also ich habe jetzt ein Zeichen reingeworfen,
in unserem Fall die 3. Was darf als nächstes reingeworfen werden?
Ja. Der Slash, genau. Also machen wir hier
einen weiteren Übergang. Ein Slash darf reingeworfen werden.
So, dann muss ich jetzt wieder auf Schwarz wechseln
Jetzt bin ich also in dem Zustand. Nehmen wir mal an,
der Automat hat jetzt gerade Mittagspause,
dann kommt eine halbe Stunde zurück und er weiß,
ah, ich bin gerade in dem Zustand,
ich weiß, ich habe schon eine Ziffer gelesen,
ich weiß, ich habe schon in Slash gelesen,
bin ich jetzt schon fertig?
Nee, bin ich noch nicht. Irgendwas fehlt doch noch
, oder? Was muss ich denn jetzt noch einlesen,
damit der Bruch komplett eingelesen wurde?
Was fehlt noch, ja? Genau. Ah,
eine Zahl von 1 bis 9, sagst du?
Das ist spannend. Schön, dass ihr mal gleich an
diese ganzen Sonderfälle denkt. Weil wir ja nicht
durch null dividieren wollen
Zack, zack, zack. Eins, Punkt, Punkt.9. So. Also dieses Kunstwerk,
speichere ich einmal ganz kurz nicht, dass das irgendwie verloren geht.
Bam, bam, bam, bam, bam.
So. Ach so. Und was auch noch toll ist,
wir sind jetzt, wenn wir dann in dem letzten Zustand sind,
wenn wir also dann auch eine Ziffer zwischen 1 und 9 eingelesen haben,
dann sind wir fertig.
Dann mache ich das hier mal so, so einen schwarzen Strich.
Das heißt, das ist der Endzustand. Wir haben gewonnen
quasi, ja. Game Over aber gewonnen. Wenn ihr
jetzt in irgendeinem Zustand seid und es steht ein Zeichen in dem String,
was hier nicht angeboten wird, was nicht in Blau hier quasi steht.
Also nehmen wir an, okay,
wir finden eine Ziffer und dann steht da irgendwie ein Fragezeichen
oder ein Punkt oder ein A. Dann sagt dieser Automat,
hm, A, kann ich hier nicht verarbeiten,
dann knallt es einfach.
Das male ich jetzt hier nicht hin. Ich schreibe mal
jetzt nicht hier alle anderen Tausenden von Zeichen hin.
Also nur die Zeichen, die ja an solchen Kanten stehen,
werden dann akzeptiert, ansonsten gibt es halt einen Fehler.
Okay, jetzt kann man in Java nicht solche Automaten malen.
Ja, Java ist ja eine textbasierte Sprache,
aber man kann solche Automaten zusammenbauen lassen von Java.
Das will ich euch einmal zeigen, wie das geht.
Kann ich das irgendwie, ja, ich glaube,
das könnt ihr euch ungefähr im Hintergrund merken, oder?
So eine Ziffer, dann einen Slash und dann
irgendeine Ziffer von 1 bis
So, wie macht man das? Ich gehe jetzt mal in die Klasse Bruch.
Ich kann ja eigentlich das mal hier erzeugen lassen,
Steuerung 1, erzeugt mir noch mal bitte die Methode.
Wo hat es ihn hin erzeugt? Da ist sie,
da soll ein Bruch zurückkommen. Und das nennen wir mal Text.
So, es gibt jetzt im Prinzip zwei Dinge, die ich brauche.
Einmal brauche ich diesen Automaten mit diesen vier Zuständen.
Diesen Automaten muss ich mir im Prinzip nur einmal erzeugen.
Ich kann beliebig oft diesen Automaten benutzen, aber einfach,
dass es diese vier Zustände gibt mit diesen blauen Kanten jeweils.
Das kann ich mir einfach hier mal als private statische Variable machen,
Private Static, Final Pattern heißt das,
glaube ich
So. Das sieht ja zuletzt mal ein bisschen komisch aus,
keine Angst, ich erkläre gleich alles.
Also, wenn ihr hier Pattern seht,
dann heißt das so viel wie Automat, okay?
So, und jetzt muss ich den Automat in Textform schreiben,
ich mache ja mal hier noch einen Import, Java-Uto-Rack-Expertin, genau.
Jetzt muss ich das in Textform beschreiben, ich muss also sagen,
als erstes irgendeine der Ziffern von 0 bis 9.
Und da gibt es ganz viele Möglichkeiten, das hinzuschreiben.
Ich zeige euch mal ganz kurz, vielleicht hier die Möglichkeiten,
die es dafür gibt. Also, ich kann entweder sagen,
01 von 3, 4, 5, 6,
7, 8, 9, in so eckigen Klammern.
Ja, wenn ihr was in eckige Klammern reinschreibt, heißt das immer,
hey, du hast die freie Wahl zwischen diesen folgenden Dingen.
Dann ist den Leuten irgendwann mal aufgefallen,
meistens stehen da so Abfolgen von hintereinander folgenden Elementen drin.
Ja, also das sind nicht irgendwelche zufälligen Ziffern,
sondern genau die jeweiligen, die zusammengehören.
Das kann man auch abkürzen, man kann einfach schreiben,
0 bis 9. Dann ist den Leuten irgendwann aufgefallen,
das brauche ich so oft, irgendeine der Ziffern von 0 bis 9.
Dann kann ich auch schreiben, backslash d. Ja, extrem offensichtlich.
D steht einfach für Digit. Und ich glaube,
das war's. Es gibt noch eine weitere Möglichkeit.
Ich glaube nicht. Welche wollen wir denn
da mal nehmen
Vielleicht die hier, die finde ich irgendwie am intuitivsten.
Nehmen wir vielleicht mal die hier. Also die klebe ich
jetzt hier einfach mal rein. Ja. Und
jetzt kann es einfach weitergehen. Was erwarte ich denn,
nachdem ich eine Ziffer von 0 bis 9 da eingetan habe?
Sollen wir nochmal auf die Grafik oder wisst ihr es noch?
Einen Slash. Den kann ich ja einfach so hinschreiben.
Das Slash hat keine besondere Bedeutung in regulären Ausdrücken.
Oder ich bin nicht 100 Prozent sicher.
Müssen wir gleich mal gucken, wenn das gleich knallt,
dann muss ich den vielleicht auch speziell behandeln.
Okay, und was soll dahinter kommen? 1 bis 9.
Ach, dann ist es auch hier sehr schön symmetrisch.
Das sieht doch irgendwie toll aus.
Okay. Gut
Wir haben jetzt also in dieser Variable Pattern, wenn man so will,
eine Referenz auf diesen Automaten und der Automat bleibt immer gleich.
Diese vier Zustände mit den jeweiligen Übergängen. Was ich
jetzt machen will, ist so eine Art, ja,
ich will quasi jetzt einmal durch den Automaten durchgehen mit einem konkreten String.
Ich will mir jetzt den String nehmen, 3 Slash 4
und will hier einmal so dieses Spiel spielen, hier so durchzugehen.
Dafür brauche ich eine weitere Klasse in Java.
Und das mache ich nicht eine weitere Klasse.
Ein weiteres Objekt. Und zwar mache ich das folgendermaßen.
Ich sage, liebes Pattern, gib mir doch mal einen Matcher.
Und zwar soll dieser Matcher den Text verarbeiten,
der hier übergeben wurde vom Benutzer.
Okay, das tun wir uns mal eine eigene Variable
Okay. Gut. Also, wenn ihr vielleicht das,
wie ein Brettspiel versteht, ja, nehmen wir Monopoly zum Beispiel,
ja, dann ist das Pattern, das Monopoly-Brettspiel,
das ist ja immer gleich seit 50 Jahren oder so, weiß ich nicht.
Aber jedes Mal, wenn ihr spielt,
also das Monopoly-Spiel, nennt man es dann auch,
ne, also nicht das Spielbrett, sondern die Partie,
sagen wir mal so, die Monopoly-Partie ist dann,
wenn man so will, der Matcher,
das muss ich dann jedes Mal neu machen bei jeder neuen Anfrage.
Ich will immer wieder von vorne anfangen sozusagen, ja.
So, genau. Und jetzt kann ich fragen,
hey, lieber Matcher,
matchst du denn überhaupt auf diesen String
Ja, hier racht halt jetzt also die Maschine los.
Hier sind jetzt alle Informationen da, die sagen,
okay, so sieht der Automat aus,
das ist der Eingabetext, dann versuche ich jetzt mal,
die Zeichen alle in diesen Automaten reinzustecken, zu schauen,
ob ich mal im Endzustand ankomme.
Dann wären wir quasi hier. Dann wüssten wir, okay,
irgendwie ist die Eingabe wohl geformt und ansonsten müssten wir da irgendwie eine Fehlermeldung ausgeben.
Vielleicht kann ich ja hier einfach mal kurz sagen,
dass euch das irgendwie klar ist, Eingabe wohl geformt.
Was ist das Gegenteil von wohl geformt?
Ich sage einfach mal fehlerhaft. Das Blöde ist jetzt aber,
Das reicht uns ja eigentlich gar nicht.
Also wenn dieser Automat mir nur sagt, ja,
du hast die Zeichen in mich reingesteckt, das sieht aus wie ein Bruch.
Aber ich will ja eigentlich jetzt auch an diese Informationen rankommen.
Also wenn ich jetzt hier nochmal in den Bruchtest ganz kurz reingehe,
also er muss ja tatsächlich erkennen, dass das hier die Zahl,
die Zahl 3 ist und nicht nur einfach ein String,
der so aussieht wie eine 3 und dass das hier die Zahl 4 ist.
Ich muss irgendwie in diese Bestandteile rankommen können. Und auch
das ist mit regulären Ausdrücken machbar und ich zeige euch immer,
wie das geht. Dazu muss ich die Bestandteile,
an die ich rankommen will, mit runden Klammern umklammern.
Was man damit macht, ist zu sagen,
Dieser Teil des Automaten ist eine Gruppe,
man sagt den regulären aus so einer Gruppe dazu.
Das gehört irgendwie zusammen, das ist ein interessantes Ding,
mit dem will ich später mal was machen.
Und das ist auch ein interessantes Ding,
mit dem will ich später mal was machen.
Ist klar, weil das ist ja der Zähler.
Und das ist ja der Nenner. Ansonsten ist es
nur eine Riesengruppe. Jetzt kann ich sagen,
das sind die beiden Gruppen, die mich tatsächlich interessieren.
Und jetzt kann ich an diese Gruppen rankommen. Ich kann also
dem Matcher sagen, gib mir doch mal die erste Gruppe.
Gruppe Nummer eins, kann ich mal in eine Variable reintun,
nennen wir die doch mal vor dem Slash.
Und ich kann an die zweite Gruppe rankommen,
das nennen wir mal nach dem Slash
Oh Gott, das heißt jetzt für unser konkretes Beispiel mache ich
das mal als Kommentar. In vor dem Slash haben wir
jetzt quasi diesen String und nach dem Slash haben wir diesen String.
Wir haben also dieses String jetzt rausextrahiert aus dem regulären Ausdruck.
Das reicht jetzt leider noch nicht,
denn wenn wir einen Bruch zurückliefern wollen,
wie sieht nochmal das Selekt von dem Bruch aus,
wo ist unser Selekt, das müsste relativ weit oben sein,
genau.
Hier kann ich ja keine Strings reintun, ich muss ja ins Eintun.
Wie kann ich denn aus einem String in Java
ein Int machen?
Weiß das zufällig jemand?
Genau. Zustande Methode, da gebe ich einen String rein,
in diesem Fall vor dem Slash. Und da kommt ein Int
zurück. Das können wir doch dann mal nennen, Zähler.
Ja, das habe ich mich hier vertippt, Zähler.
Okay, und dasselbe machen wir mal mit nach dem Slash.
Und das nennen wir dann Nenner. Das sind also
zwei interessante Schritte. Erstmal die Strings extra hin und dann
aus den Strings ins machen. Was mache ich jetzt?
Jetzt habe ich die beiden ins,
Genau, Return und so weiter, sehr schön.
Ach guck mal, das hat er schon automatisch erkannt,
dass das sinnvoll ist, da reinzustecken.
Genau. Ansonsten schmeißen wir eine Acception, oder?
Throne, New Eligal Argument Acception. Ah, die Moment Acception
. Fehler, hafter Bruch oder irgendwie sowas, ja.
Vielleicht den Bruch noch dazu. So. Zack. Okay.
Vielleicht mache ich es tatsächlich mal andersrum. Das ist schon
eine kleine Stilfrage. Ich könnte ja auch im Prinzip
diese Bedingungen negieren. Jetzt gefühlt euch halt wieder ein bisschen
wie bei Kerl, dann kann ich
diese Bedingungen hochziehen
Dann kann ich dieses Elzo, ich vertausche jetzt quasi einfach diese beiden Blöcke.
Und dann, was man gerne macht, ist,
dass Throw nicht in den eigenen Block zu packen,
sondern das quasi direkt dahinter zu packen.
Und dann kann ich mir das hier sparen. Ich weiß nicht,
ob diese Umwandlung allen klar ist, macht exakt das selber.
Man ist das generell Early Exit. Also ich gucke erst mal,
ob die Eingaben korrekt sind, wenn nicht,
springe ich sofort raus aus der Methode mit einer Acception.
Und das ist der sogenannte Happy Path, wo alles in Ordnung ist.
Und ich muss mich nicht mehr um Fehler kümmern.
Ich finde das übersichtlich als den EFLs. Ich weiß nicht
, wie es euch geht. Ist persönlicher Geschmack.
Gut. Dann kommen wir noch einmal ganz kurz hin,
bevor es Fragen dazu gibt, ob der Test durchläuft.
Prochtest. Guck mal, alle Tests laufen durch.
Insbesondere Ich kann ja auch mal ruhig nur diesen Test,
Test from Strength, ich kann den mal ausführen.
Ich will nur diesen einen Test ausführen, geht das?
Genau. Test from String hat wunderbar funktioniert. Ich kann jetzt
also drei durch vier reinstecken und es kommt ein Bruch raus,
der genau dieses Dreiviertel ist, was wir uns ja hier oben als Konstante quasi hingeschrieben hatten.
So, das war, glaube ich, jetzt ganz schön viel Zeug.
Aber ihr seht, das ist gar nicht so viel Code,
das ist eine halbe Bildschirmseite.
Ja. Gibt es dazu noch Fragen? Frage? Jetzt
längst. Das ist der nächste Schritt. Das machen wir
, wenn keine Fragen mehr sind. Genau. Gibt es
noch Fragen zum aktuellen Stand,
Sehr gut. Also wir müssen uns um mehrere Ziffern kümmern
und wir müssen uns um Leerzeichen kümmern.
Das sind zwei weitere Anforderungen. Das stimmt, ja.
Ah, warum fängt die Group bei 1 an zu zählen?
Das ist eine sehr gute Frage, weil Informatiker ja
eigentlich immer bei null anfangen zu zählen.
Wir können ja mal gucken, ich kann ja einfach mal
ganz blöd die Gruppe Nummer 0 auf die Konsole schreiben.
Man schreibt ja einen Test normalerweise nichts auf die Konsole.
Das ist nur, weil wir so ein bisschen im Zeitdruck sind.
Und dann werden wir mal sehen, was ist denn
die Gruppe Nummer 0? Siehst du, was die Gruppe
Nummer 0 ist
Alles. Die Gruppe Nummer 0 ist immer der ganze String.
Warum man das wissen wollen würde,
ist, wir ehrlich gesagt ein bisschen schleierhaft,
weil ich als Benutzer stecke ja den String rein, der verarbeitet werden soll.
Also wenn ich ihn aus irgendeinem Grund mal vergessen sollte,
kann ich den mit Gruppe 0 wieder rausholen.
Aber ich sehe da persönlich keinen Anwendungsfall für.
Okay, wo hatte ich das jetzt gemacht?
Hier. Weg damit. Okay. Ja,
noch weitere Fragen zu dem Code, der jetzt hier steht.
Nee, vielleicht machen wir uns mal so ein bisschen,
also hier, das ist das mit den Strings,
das ist das Paarsen und hier wird der Paar.
Ich glaube, so kann man das ganz gut verstehen.
Okay. Ja, ich glaube, das mit den Leerzeichen
ist einfacher
Also, wir können ja mal wieder zu unserem Kunstwerk gehen und uns überlegen,
wie würde das denn in diesem Zustandsautomaten aussehen?
Ich sage also, ich gehe noch einen weiteren Schritt zurück.
Vielleicht ist nicht allen klar, worum es gerade geht.
Ich mache jetzt einen weiteren Test an dieser Stelle.
Und der Herr hatte ja eben gesagt, ich will auch Leerzeichen erlauben.
Ja, ich will also, dass hier auch Leerzeichen stehen dürfen.
Das würde momentan nicht funktionieren, denn der Automat sagt ja,
nachdem man die erste Ziffer verarbeitet hat, muss hier ein Slash stehen.
Ja, also wenn ich jetzt mal versuche,
diesen Test durchlaufen zu lassen, der mit dem Leerzeichen,
der steht ja weiter unten hier,
ist so,
dann müsste das eigentlich knallen
Genau. Nun, was ist die Exception illegal Argument Acception,
fehlerhafter Bruchdreiviertel? Ja, das ist genau die Exception,
die wir da eben rausgeschmissen haben. Okay, weil warum?
Weil diese Methode gesagt hat, es tut mir leid,
ich konnte diese Zeichen nicht vernünftig in den Automaten reinschmeißen.
Irgendwann gab es ein Problem. Wo genau das Problem ist,
sieht man jetzt hier leider gar nicht.
Gut. Okay, also das ist hoffentlich allen klar.
Wir wollen, dass diese Leerzeichen auch erlaubt sind.
Wie können wir das denn jetzt in diesen Automaten einbauen,
dass auch Leerzeichen erlaubt sind
Würdet ihr das machen? Weitere Zustände oder
weitere Kanten oder beides oder nur eins von beiden?
Group ist ja schon sehr oft Java jetzt gemünzt.
Also wenn das die Zustände von eins bis vier sind,
an welchen dieser vier Zustände muss ich jetzt was machen?
Das ist eine spannende Frage. Wollen wir auch Leerzeichen erlauben,
vor und nach dem jeweiligen Bruch? Wir können ja der Einfachkeit
erstmal sagen, nur hier und hier dürfen Leerzeichen sein.
Also hier quasi nicht und da quasi auch nicht.
Und da hattest du ja schon die Lösung jetzt verraten.
Also wir brauchen einen blauen Kringel an allen Stellen,
wo wir Leerzeichen erlauben wollen.
Also einmal hier
Das soll also ein Pfeil sein,
der zu sich selber hier und hier nochmal. Ja,
und wie, ja, jetzt muss ich ein Leerzeichen hinmalen.
Wie mache ich das denn? Vielleicht nehme ich mal,
so wie in Java man das machen würde, ja,
seht ihr, dass hier ein Leerzeichen ist zwischen den beiden Hochkommatons?
Das sieht jetzt irgendwie aus wie Hasenaugen oder irgendwas, egal.
Also ein Leerzeichen, ja, hier werden Leerzeichen akzeptiert.
Am Moment, jetzt akzeptieren wir ja beliebig viele Leerzeichen.
Das wollte ich eigentlich gar nicht. Das ist ja doof.
Dann brauchen wir irgendwie doch einen neuen Zustand, ne?
Sollte das nochmal rückgängig machen? Also, wir brauchen einen
neuen Zustand
Ich wurde mal intuitiv sagen, hier brauchen wir einen.
Und hier brauchen wir einen. Dann brauchen wir einen Fall, der hier sagt,
wenn du eine Leertaste einliest, dann gehe hier hin.
Genauso hier. Und die Leertaste mache ich jetzt hier wieder
mit diesen Hasenaugen. So. Und welche Übergänge fehlen jetzt noch
? Also wenn ich ein Zeichen einlese und ein Leer,
Entschuldigung, wenn ich eine Ziffer einlese und ein Leerzeichen,
was muss dann als nächstes kommen
Ja. So, ne? Sehr schön. Und fehlt
von hier aus noch irgendwas? Genau. Ihr seht,
hier ist jetzt ein bisschen Code-Duplizierung oder Automaten-Duplizierung oder was auch immer.
Das kann man mit formalen Hilfsmitteln auch noch alles irgendwie wegkriegen.
Dann gibt es irgendwelche leeren Übergänge und so. Das will ich
euch jetzt alles gar nicht zeigen. Das Tolle ist,
so kompliziert wie dieses Diagramm jetzt geworden ist, in Java ist es deutlich einfacher.
Ich kann in Java sagen, in meiner textuellen Beschreibung des Automaten.
Ich will an dieser Stelle ein Lehrzeichen haben,
was da aber nicht unbedingt stehen muss.
Ja, und an dieser Stelle würde ich ein Lehrzeichen haben,
was da nicht unbedingt stehen muss. Also ein Lehrzeichen in regulären Aus,
Entschuldigung, ein Fragezeichen in regulären Ausdrücken bedeutet, das,
was unmittelbar vor dem Fragezeichen steht, kann vorkommen,
muss aber nicht.
Ja. Eine Schraube. In diesem Fall ist es tatsächlich
nur ein Char. Also wenn du sagen würdest,
Hello-Fragezeichen, dann würdest du hell oder Hello akzeptieren
Okay, wollen wir testen, ob das noch funktioniert?
Das sieht irgendwie komisch aus, ne?
Das haben reguläre Ausdrücke so an sich. Am Anfang sind
sie total übersichtig und dann sehen sie immer komischer aus.
Okay, seht ihr, das funktioniert jetzt.
Tests laufen durch. Das ist doch nicht schlecht.
Okay, das war also die Anforderung mit den Lehrzeichen.
Ich hoffe, der Herr ist zufrieden.
Dann war die nächste Anforderung, wir wollen mehrere Ziffern akzeptieren.
Ich glaube, ich erspare mir das jetzt mal,
das hier einzubauen, oder? Obwohl, nee,
ich glaube, auf dieser Ebene ist es tatsächlich relativ einfach.
Ich könnte ja hier einfach sagen, an den Blau
war schon okay.
Ich mache hier einfach
einen Übergang
Zack. 0 bis 9. Tack, tack, tack.
Ja. Und an dieser Stelle... Achso, ich bin
schon ganz rechts. Es wird hier ein bisschen unübersichtlich.
Es tut mir leid. So. Auch von 0 bis 9. Zack,
zack, zack. Ja. Ja, ich hoffe,
ihr glaubt mir, dass das dann 0 bis 9 steht.
Also nach dem Motto, ich brauche auf jeden Fall erstmal
die erste Ziffer, die muss auf jeden Fall kommen.
Also wenn ich in diesem Zustand bin, weiß ich,
ich habe mindestens eine Ziffer angelesen und da können auch weiterkommen.
Ich werde mich ja immer im Kreis drehen, solange
weitere Ziffern kommen. Irgendwann wird keine Ziffer mehr kommen,
dann kommt entweder ein Slash oder eine Leertaste und genauso ähnlich hier
Wenn ich also für den Nenner eine Ziffer gelesen habe,
bin ich zufrieden,
egal ob ich von hier komme oder ob ich von hier komme.
Dann können aber noch beliebig viele weitere Ziffern kommen,
das ist mir egal. Ja, die werden eben
auch akzeptiert. Ja, ich bleibe in dem Zustand.
Das ist nachvollziehbar. Okay. Ja, wie macht man
das jetzt in Java? Man kann in Java,
also das Fragezeichen sagt ja einmal oder gar nicht.
Ja, und es gibt eben auch die Möglichkeit zu sagen
, kann ruhig öfter als einmal vorkommen.
Ja, also ich könnte jetzt zum Beispiel sagen,
dieses 0 bis 9 will ich
mindestens einmal haben
Richtig, mit dem Plus. Man schreibt einen Plus dahinter.
Plus heißt einen regulären Ausdrücken, mindestens einmal. Wie ist
das jetzt? Könnte ich das hier hinten auch hinschreiben?
Nee, richtig, warum nicht? Ja. Genau,
wir wollen ja, dass alle weiteren Ziffern hinter der ersten auch die Null erlauben.
Wie könnte man dieses Problem denn lösen? Also das,
ja, das ist ja interessant. Also erst 1 bis
9, das werde ich sicherlich stehen lassen müssen,
ja.
Das ist interessant. Da meldet sich jemand. Genau,
also ich erkläre jetzt mal, was hier im momentanen Zustand steht.
Also ich erwarte eine führende Ziffer von 1 bis 9
und dann mindestens eine weitere Ziffer.
Ich könnte also keine einstelligen Nenner mehr produzieren. Das wäre
irgendwie nicht so gut. Und jetzt war die Lösung schon
zu sagen, hey, der Herr kannte offenbar reguläre Ausdrücke.
Wenn man statt dem Plus ein Sternchen nimmt,
dann heißt es nicht mindestens eins,
sondern mindestens null
Oder mindestens keins. Je nachdem, was euch besser gefällt.
Das heißt also, hey, da können noch beliebig viele weitere kommen,
muss aber auch nicht unbedingt. Jetzt könnt ihr mich,
nee, ich will es nicht zu kompliziert machen,
ja, also das, so müsste das funktionieren.
Wir sind gar nicht Test-Driven-Development-mäßig vorgenommen, wir haben noch gar
keinen Test dafür, das können wir einmal ganz kurz machen.
Kupiere ich mir mal wieder diesen Test hier vielleicht.
Und dann nennen wir das mal Test from String mehr stellt,
mehr stellig. Was wollen wir denn mal nehmen?
Zehntel. Dass wir auch mal diesen Fall haben,
dass hinten eine Null steht zum Beispiel.
Und jetzt dafür haben wir noch keinen Bruch,
dann machen wir uns mal ganz kurz ein 42.10.
Das wird ja intern beides kürzen, das ist ja egal.
Müsste das funktionieren? Ich glaube ja. Es werden beide
gekürzt. Intern wird ja immer der Konstruktor kürzt ja immer.
Das heißt, er wird sowohl diese 42 Zehntel kürzen als
auch das, was dann hier gepasst wird.
Das wird ja dann genauso kürzen. Das ist dann 21
Fünftel. Ja, okay. Dann schauen wir mal,
ich mache sie wieder konkret auf diesen einen.
Irgendwie beruhigt mich das, wenn ich diesen einen ausführe statt alles.
Ich weiß auch nicht warum
Das funktioniert jetzt auch. Gut. Genau. Jetzt ist es ja so,
dass diese Brüche, also so wie ich das jetzt hier hingeschrieben habe,
mit dem Plus und dem Stern,
da könnte ich jetzt beliebig viele Ziffern reinschreiben, ja,
20, 100.000.
Das ist wahrscheinlich nicht so wahnsinnig sinnvoll. Wir sollten uns
wahrscheinlich irgendwie beschränken. Denn Int oder haben wir Intro,
haben wir Long genommen? Ich weiß es schon. Ich
glaube, wir haben Int genommen. Wie lang kann denn so
ein Int werden, wie viel Ziffern so ganz grob?
Ja, also genau, und wie viel Ziffern hat
die Zahl zwei Milliarden
Ich glaube, sie hat zehn, aber tatsächlich,
wir können nicht alle zehnstelligen Zahlen reinpacken. Also es geht ja
nur bis zwei Milliarden, drei Milliarden würde schon nicht mehr gehen.
Also vielleicht sollten wir uns mal auf einen neuen Ziffern beschränken.
Wie machen wir das denn? Also vielleicht wäre es ganz gut. Immer dann,
wenn ihr folgendes Szenario habt, ihr schreibt eine Funktion,
die einen Parameter entgegennimmt und ihr sagt dem Klienten,
ich kann aber nicht alle Strings akzeptieren.
Also laut Typ-Systemen könntest du mir jetzt hier beliebig lange Brüche reinstecken.
Dann ist es eigentlich meistens ganz gut,
wenn man da irgendwie eine Vorbedingung von, ihr kennt ja Vorbedingungen,
ich mache das jetzt mal hier ganz salopp,
ich könnte hier sowas hinschreiben
wie Require
Programmieren wir gerade Deutsch oder Englisch. From String ist,
ich glaube, ich mische das hier gerade so ein bisschen, ist ja egal.
Ich nenne die Methode einfach mal East Valled. Ja,
ich sage also den Benutzer, der String,
den du mir hier reinsteckst, das darf nicht ein beliebig langer Bruch sein,
sondern der muss irgendwie valide sein.
Und was dieses valide ist, dafür bauen wir uns mal
eine Hilfsfunktion. So, wo ich, genau,
wo ich im Prinzip sowas ähnliches mache wie hier,
ich kopiere das einmal ganz kurz hier hoch.
Nur, dass ich statt eine Exception zu schmeißen,
einfach nur den Benutzer darüber informiere, ob es matcht oder nicht.
Das macht bis jetzt noch keinen Unterschied,
weil der Rack ist ja immer noch beliebig lange Zahlen entgegennimmt
Aber ich will jetzt Folgendes machen. Ich will,
dass diese Funktion Falts zurückliefert, falls die Brüche zu groß werden.
Ja, das könnte ich jetzt direkt hier in dem Rack-Ex implementieren.
Ich will aber erstmal den Test dazu schreiben. Also ich will
irgendwie sagen, ja, welchen nehmen wir da mal irgendeinen?
Was ist der Letzte, den wir hier genommen hatten?
Mit Lena Zeichen, bla bla bla, oder macht den hier?
Also ich sage, nehmen wir den nochmal, ja,
Milliardenbruch ist ungültig oder so, ja. Und dann sage ich,
ich erwarte, dass Falts zurückkommt, wenn ich teste,
ob Das sind doch jetzt zehn Ziffern ziemlich sicher.
Ja, ne? Genau, was ist jetzt das Problem?
Was habe ich hier falsch gemacht? Ach, ich habe
das nicht importiert. Muss ich das irgendwie importieren? Guck mal,
Sir True habe ich importiert, aber nicht A Third Fouls.
Ich weiß nicht, vielleicht hätte das Air Camps auch für mich machen können.
Das habe ich jetzt so schnell nicht probiert.
Das ist mal groß der Test. Genau. Dieser Test
wird momentan fehlschlagen. Ach so, warte mal,
weil es ja auch kein Bruch ist.
Viertel. Oder Siebtel. Es ist ja völlig egal.
Es geht ja nur darum, dass diese Zahl zu groß
Dieser Test wird momentan fehlschlagen, weil wir gesagt haben,
Brüche können beliebig groß sein, in unserem regulären Ausdruck.
Wenn ich das einmal kurz ausführe, dann ist J.Unit Test.
Genau, also da momentan sagt er, nö,
das sieht aus wie ein Bruch, das akzeptiere ich.
Was passiert dann eigentlich? Wollen wir mal ganz kurz gucken,
wenn ich tatsächlich sage, Bruchpunkt from String.
Ja, ich mache gar nichts mit dem String.
Ich will einfach nochmal gucken, was passiert.
Achso. Ja
Habt ihr eine Idee, was passieren könnte an dieser Stelle?
Also wir nehmen mal diesen String auseinander, schauen uns zehn
und Nenner an, machen aus dem String ein Int.
Oh, wisst ihr was, wir haben, glaube ich,
gerade einen witzigen Randfall. Eine Milliarde geht ja noch.
Ich habe ja gesagt, drei Milliarden geht nicht mehr.
Entschuldigung, ich hätte drei Milliarden nehmen müssen.
Entschuldigung. Was glaubt ihr, was jetzt passiert,
wenn ich das hier einfach mal durchaus will?
Also hier steht ja noch nicht mal, Asserd Equips oder irgendwas.
Also dieser Test wird jetzt durchlaufen, es sei denn,
es kommt eine Acception. Mal gucken, ob eine Acception kommt.
Habe ich daran aufgeklickt. Run as Tree Union Test.
Schaut mal. Number formated Acception 4 Inputstring.
Wo ist die denn hergekommen
Pass Int. Ja, okay. Ja, irgendwelche Java-Interne.
Hier. Also ich habe hier versucht, diesen String,
wo dieses 3 Milliarden drin stand, in den Into umzuwandeln.
Und das geht natürlich nicht, weil das die Grenzen von dem Into überschreitet.
Ja, und bei noch längeren Strings natürlich erst recht.
Also ich würde eigentlich ganz gerne sagen, da dürfen höchstens neun Ziffern stehen.
Ja, das ist irgendwie mein Ziel. Das heißt,
ich nehme jetzt mal diesen Quatschtest wieder weg. Also ich will tatsächlich,
dass Isvallet sagt, dieser String ist schon zu lang.
Ja, wie mache ich das?
Also ich will jetzt nicht an einem Automaten rumhüllen,
das würde nicht auf einen Bildschirm passen.
Wir gehen wieder zu einem regulären Ausdruck.
Und ich mache hier wieder Vollbild,
das vergesse ich immer
Also, dieses Plus sagt, eins bis unendlich, so viel du willst.
Und dieses Mal sagt, null bis unendlich, so viel
du willst. Das ist ja sicherlich nicht so sinnvoll.
Gibt es irgendwelche regulären Ausdrucksexperten, die mir sagen können,
ich kann ja auch hinschreiben, eins bis neun.
Weißt du das zufällig, aber einer hat eine Idee da hinten.
Du hattest, glaube ich, lange nichts, ja.
Ja. Ja. Sehr schön. Also dieses Monstrum in
regulären Ausdrücken bedeutet, was auch immer davor steht,
darf ein bis neun
Mal vorkommen
Gut. Soll ich mir das einfach mal hier hinten hin kopieren?
So. Du sagst 1 bis 8. Gibt es noch weitere Vorschläge?
Das ist schon mal besser als das, was hier momentan steht.
1 bis 8. Soll ich mal hinschreiben? Zieht jemand
das Problem? 0 bis 8. Denn das Sternchen hat ja
auch null erlaubt. Und dadurch, dass wir hier ja
schon den ersten haben, muss ich beide Grenzen anpassen.
Ich muss auch null erlauben. Genau. Ach ja,
dann schauen wir mal,
ich führe das jetzt hier nochmal aus
Ach so, den Test gibt es gar nicht mehr.
Ich führe mal wieder den kompletten Test aus. Kann ich
das auch machen? Ich will den ganzen Bauchtest ausführen.
Ja, jetzt geht wieder alles.
Ja, also ich gehe noch mal ganz kurz zurück.
Ich kann das noch mal ein bisschen erweitern.
Also ich kann zum Beispiel sagen,
wenn ich jetzt die erste Ziffer zum Beispiel mal entferne,
dann ist es kurz genug, dann sind es neun.
Hier sind es schon zehn, das soll nicht mehr als
gültig akzeptiert werden. Ja, ist das nachvollziehbar?
So. Okay. Ja
Wenn man das so sieht? Also reguläre Ausdrücke sollten nicht
viel komplizierter werden als das. Es gibt auch reguläre Ausdrücke,
die prüfen Validität von E-Mail-Adressen, die gehen dann über mehrere Seiten.
Also man muss vorsichtig sein mit regulären Ausdrücken.
Ja, folgen ist der alte Nazi-Bild. Beim Fass,
die Geschneide ist sehr sofort eingerettet. Könnte man sich wahrscheinlich
pragmatisch überlegen, dass das vielleicht möglicherweise auch sinnvoll ist.
Das Blöde ist, du wirst dann wahrscheinlich,
wahrscheinlich wird diese Methode dann nicht mehr so hübsch elegant in zwei Zeilen hinzumachen sein.
Da muss man halt einen Kompromiss finden, zu sagen,
ich will einfach einen Code, dafür habe ich die Limitierung,
dass es nur bis 999 Millionen geht.
Oder ich sage, nein,
es muss unbedingt bis zwei Milliarden geben,
ich brauche diesen Wertebereich,
dann wird möglicherweise
die Implementation ein bisschen hässlicher
Okay. Genau. Also, merkt euch, eine Sache sollte ich vielleicht noch machen.
Also, dieses 0 bis 9. Da hatten wir ja gesagt,
da kann man auch sagen, Backslash T. oder hatte ich das nicht hier überhaupt genommen?
Man kann auch einfach sagen, Backslash T., da haben wir es. Ich glaube,
ich versuche einmal ganz kurz im Hintergrund, dass J.J.K. 9 runterzuladen,
weil ich werde jetzt nochmal so ein bisschen interaktiv mit euch rumspielen wollen und der Effekt ist immer nicht so schön,
wenn man diese Konsole, was, ich will eigentlich nur,
wieso ist der denn jetzt hier,
ich will doch nur auf Google,
kann ich nicht auf Google, ist das nicht meine Startseite,
doch,
J.J.K. Nown
Das ist nicht schlimm, weil das nächste Thema, was danach kommt,
werde ich sowieso nicht mehr anfangen können in den zehn Minuten,
dann ist es nicht schlimm, wenn wir jetzt eine Minute euch,
wenn ich euch eine Minute lang zeige,
wie man sich das JDK 9 runterlädt.
Also man muss erstmal das Lizenzregreement akzeptieren, das kennt ihr ja,
das hat sich wahrscheinlich noch nie jemand angeguckt,
dann brauche ich Linux, Tradedig, das brauche ich.
So, was passiert jetzt als nächstes? Es wird runtergeladen
. Okay, liegt da jetzt im Hintergrund runter.
Gut. Wo war ich jetzt eigentlich stehen geblieben?
Genau, also 0 bis 9. Ich hatte ja gesagt,
man kann ja auch stattdessen hinschreiben,
Backslash D. Jetzt kommt aber so eine ganz merkwürdige Fehlermeldung,
die ihr blöderweise nicht sehen könnt.
Ich muss jetzt mal ausnahmsweise das Fenster von Eclipse
ein bisschen kleiner machen
Und das ist mir hier so ein bisschen hochziehen,
kann man jetzt sehen, dass da unten eine Fehlermeldung ist.
Genau. In-Value-Escape-Sequence Value once up wechseless Steh,
wechseless T-Bexeless N und so weiter. Kennt ihr irgendeine,
zum Beispiel dieses Backslash N, habt ihr das schon mal gesehen?
Neue Zeile. Es gibt also so ein paar Sonderzeichen. Ihr könnt jetzt nicht,
wenn ihr in Java in einem String-Gitteral eine neue Zeile haben wollt,
könnt ihr nicht einfach auf die Enter-Taste drücken und dann geht
das String-Gitterer in der nächsten Zeile weiter.
Also so was Besonderes wie neue Zeile oder Tabulator oder ich brauche zum Beispiel ein Gänsefüßchen.
Dafür braucht man dann in dem String-Gitteral zwei Zeichen,
einmal ein Backslash und dann eben irgendwas,
was sagt, worum es jetzt geht.
Das N heißt dann Zeilenumbruch und das Gänsefüßen heißt dann,
ich brauche Gänsefüße
Okay. Was in der Dokumentation von den Java-regulären Ausdrücken
steht, ist, ihr braucht einen Wechsel-Stee.
Also die Reg-Ex-Engine will einen Backslash in dem String sehen.
Und hinter dem Backstlash will sie einen D sehen.
In dem String. Was ihr aber hier seht,
ist kein String, sondern ein String-Literal.
String-Literale seht ihr an diesen Gänsefüßchen. Wenn ich diese String-Literale,
so wie es ist, einfach mal in System Out Printline reinschreiben würde,
dann würden diese Gänsefüßchen ja nicht auf der Konsole erscheinen.
Das ist euch hoffentlich klar, oder? Wenn ihr einen
String auf die Konsole schreibt, sind da keine Gänsefüßchen.
Gut, das heißt also, der String,
so wie er schon im Speicher steht,
wenn ihr zum Beispiel in euer Stringliterath Backslash N reinschreibt,
dann ist da nicht ein Backslash und ein N im Speicher zur Laufzeit,
sondern wirklich ein Zeilenumbruch.
Also irgendwie Asky Code. 13 oder so oder 10,
ich weiß es nicht genau. Jedenfalls nur ein Zeichen.
Und das wollte ich euch einmal ganz kurz demonstrieren.
Seht ihr, der Downward ist abgeschlossen,
jetzt gehe ich ja einmal in meine Downloads.
Dann haben wir hier das JDK 9. Ja. Ja,
genau, da haben wir es. Dann mache ich das
nochmal hier, vielleicht irgendwie in mein Hauptverzeichnis rein, einmal in Packen.
400 Megabyte, ja, kann ich ja hier
schon mal optimistisch in die Konsole reingehen
Wieso hören man da immer Leute klatschen? So, dann können wir
da jetzt mal reingehen. Genau, nur das Programm,
was ich eben gerne benutze, um solche Sachen zu demozieren,
ist diese, oh, ist das schlimm?
Ich hoffe nicht. Sieht nicht schlimm aus. Genau. Also,
ich weiß gar nicht, wenn ich zum Beispiel sowas mache,
wie wird das eigentlich dann dargestellt von der JSHL?
Wo seht ihr das? Das ist ja wirklich,
das Backstage-N wird von der JSHL so,
dass er tatsächlich einen Zeilenumbruch hier hinschreibt,
aber die Gänsefüßchen schreibt er trotzdem.
Das ist so ein bisschen inkonsequent. Also,
wenn ich jetzt tatsächlich mal sage, System out,
Printline,
Hello Backstle.
Was? Was war das denn? Aha, pake slash
and world. World. So, dann seht ihr
die Gänsefüßchen gehören nicht wirklich zu dem String. Ja,
das ist nur, damit man in Java sieht,
wo fängt er denn an und wo er hört er auf.
Und das ist auch kein Backslash in dem String. Ja,
und das ist auch kein N in dem String,
sondern dieses Backstage-In wurde verschmolzen zu einem Zeilenumbruch.
Ich muss euch so immer fragen, zur Übersetzungszeit gibt es
Stringliterale mit den Gänsefüßchen und zur Lautzeit gibt es Strings.
Und da sind eben diese Gänsefüßchen und diese Spezial-Dinge nicht drin.
Ich will jetzt also Folgendes, ich will schreiben, System out,
Printline und dann bin ich mir nicht so ganz sicher,
was da jetzt rein muss.
Und ich will das jetzt auf der Konsole steht, Backslash D.
Ich will also das zwei Zeichen in dem Strings sind,
ein Backslash und ein D. Richtig. Ich muss also Java sagen,
pass auf, das erste Zeichen ist ein Backslash und das
zweite Zeichen ist ein D. Seht ihr das?
Ich kann also auch zum Beispiel fragen, hey,
wie lang ist dieser String eigentlich? Oder sagen,
da sind zwei Zeichen drin, nämlich der Backslash und das D.
Es sind nicht fünf Zeichen, es ist nicht Gänsefüßchen,
Backslash, Speckslash, D, Gänsefüßchen.
Es ist zur Laufzeit, es ist wirklich nur zwei Zeichen.
Okay, das ist als kleiner Hinweis,
warum man manchmal zwei Backslashes in Strings braucht
Von wo kam ich? Ich muss mal kurz jemandem meinen Stack wieder zurückrollen.
Genau, ich kam von hier. Also, der Java-Combatter sagt,
es gibt kein Spezialzeichenwechselstil, will ich auch gar nicht.
Ich will ja eigentlich einen Backslash haben. Deswegen müsste da
zwei Backslashes reinschreiben. Okay, mach das nicht unbedingt übersichtig.
Und das könnte ich hier genauso machen. Wollen wir mal
kurz hier, ne? Backslash Backslash stehen.
Genau. Okay, wollen wir nochmal unsere Tests durchführen,
dass immer noch alles geht, genau.
Okay, ich glaube, eine Sache will ich
noch mit euch machen
Ich gehe wieder in meinen Test zurück. Und ihr könnt mir glauben,
alles, was ich heute mit euch mache, ist nicht,
weil ich reguläre Ausdrücke so toll oder so furchtbar finde,
sondern weil er sie auf dem aktuellen Aufgabenblatt wunderbar gebrauchen könnt.
Warum? Ihr müsst ja so einen Geldbetrag, der auf der Tastatur eingegeben wird,
irgendwie umwandeln von String nach Geldbetrag. Also alles,
was wir jetzt hier machen mit Umwandlung von String nach Bruch,
müsst ihr dann ähnlich machen von String nach Geld betrachten,
euch nur überlegen, was ist denn ein sinnvoller reguläre Ausdruck dafür?
So, und was ich jetzt noch einmal mit euch machen wollte,
ist, einen weiteren Testfallschreiben, der sagt,
Test from String ohne Nenner.
Ich will zum Beispiel auch solche Brüche Brüche erlauben.
Ich will, dass der Benutzer nicht unbedingt einen Zähler angeben muss.
Es soll auch okay sein, das soll natürlich nicht dreiviertel rauskommen.
Dann soll er natürlich rauskommen, bruch.delekt, 123,1. Ist diese
Anforderung erstmal nachvollziehbar. Also wenn da nicht steht,
was der Nenner ist, soll der Nenner eins sein.
Gut. Was bedeutet das für unseren regulären Ausdruck?
Gehen wir wieder zurück zum regulären Ausdruck.
Ich habe jetzt hier irgendwo einen Bereich,
den ich
optional halten will
Ich glaube, es ist dieser Bereich, oder?
Das will ich optional haben. Wie kann ich denn das jetzt alles optional machen?
Also wenn ich jetzt einfach nur ein Fragezeichen dahinter klebe,
dann wird er nur das nehmen, was direkt,
das ist, dann würde er quasi nur das nehmen.
Ich muss also jetzt irgendwie das alles nochmal irgendwie zusammenfassen und
sagen, das soll eine Einheit sein.
Ja. Richtig, neue Runde klammern. Und ein Fragezeichen
dahinter. Und jetzt haben dann meistens den Effekt,
ich bin auch nicht ganz so fit in Regularien,
dass jetzt irgendwie ganz viel auf einmal schief geht.
Ja, also jetzt sind hier mehrere bzw. das mehrstellig funktioniert jetzt nicht mehr,
dass natürlich so wenig Test from String,
das Normale funktioniert jetzt auch nicht mehr.
Das hat damit zu tun,
dass wir ja vorher runde Klammern verwendet hatten und zu sagen,
wir haben hier eine Gruppe und diese Gruppe will ich extrahieren können.
Wir hatten die erste Gruppe war der Zähler,
die zweite Gruppe war der Nenner. Und dadurch,
dass wir jetzt hier noch eine weitere Klammer eingebaut haben,
haben wir jetzt auch eine weitere Gruppe.
Das heißt also, das hier wäre jetzt die Gruppe 2
und das hier wäre jetzt die Gruppe 3.
Das ist so halbwegs nachvollziehbar. Ich muss jetzt also an
dieser Stelle sagen, Ich möchte die Gruppe 3 nehmen.
Die Gruppe 2 wäre slash 4. Das kann ich nicht parsen.
So, wenn ich das jetzt mache, dann müssten zumindest
die Fehler von eben verschwinden, die in mehreren Testfällen waren.
Seht ihr das normale Test from String?
Geht jetzt wieder. Das Einzige, was noch nicht geht,
ist, Test from String ohne Nenner.
Also wir müssen uns die Frage stellen, was passiert denn eigentlich,
wenn jetzt diese optionale Gruppe 2 sozusagen ist es dann ja, oder?
Ich bin gar nicht ganz sicher. Wenn die jetzt ja dann quasi nicht da ist,
wir können das ja vielleicht mal folgendermaßen machen,
wir können ja einfach mal alle Gruppen einmal auf die Konsole schreiben.
Wir finden das jetzt einfach mal raus. Ihr müsst ja
nicht immer alles glauben, was ich euch erzähle.
Wir versuchen das einfach
mal interaktiv rauszufinden
Und ich mache das jetzt mal nur für den Testfall, für den einen neuen.
Ich schreibe einfach mal alle drei Gruppen auf die Konsole.
Mal sehen, ob wir da ein Muster erkennen.
Also, hier ist unser Testfall, Ron Astra Unit Test.
Jetzt gucken wir mal auf die Konsole, was in den drei Gruppen drinsteht.
Aha. Also, die erste Gruppe ist, klar,
der Zehner hat sich nichts geändert. Und sowohl die zweite Gruppe,
die komplette mit dem Slash, die es nicht gab,
als auch das, was hinter dem Slash steht,
was es ja auch nicht gab,
das ist jetzt beides ein Null.
Ja, ich kann jetzt also einfach eine Überprüfung machen.
Ob das, was ich als Nenner interpretiere,
ob das überhaupt gegeben ist,
indem ich das mit Nai vergleiche
Ja, also ich kann jetzt hier einfach eine Fallunterscheidung machen.
Wenn nach dem slash null ist. Oder vielleicht,
vielleicht sagen wir ungleich mal, dann ist es der Fall von vorher.
Dann kann ich im Prinzip dasselbe machen wie vorher.
So. Ich scrolle es mal ein bisschen hoch,
dass ihr alles seht. Ansonsten, was muss ich denn
ansonsten machen? Jemanden Vorschlag, ja. Genau,
also ich müsste quasi den Zähler mir hier runterkopieren.
Weißt du was, ich ziehe das einmal nach oben,
weil das muss ich ja
in beiden Fällen machen
Und dann kann ich hier einfach sagen, der Nenner soll eins sein.
Habe ich das so jetzt in der Geschwinde, in der Hektik richtig gemacht?
Also nochmal kurz nachvollzogen. Also wenn nach dem Slash tatsächlich was war,
wenn dann nicht nahe drin ist, dann muss ich
den Nenner normal parsen und mache aus Zähne und Nenner einen Bruch.
Ansonsten übergebe ich eins für einen Nenner und den Zähler
hatte ich immer hier oben schon rausgepastet.
Das sieht doch eigentlich vernünftig aus, oder?
Wollen wir das mal austesten? Genau. Okay,
das heißt, wir haben jetzt noch eine Minute Zeit,
ja, dann würde ich sagen, bleiben einfach mal hier,
das ist ja völlig okay.
Muss der reguläre Ausdruck, ich kann den regulären Auftrag mal
so ein bisschen runterholen, dass ihr alles gleichzeitig seht.
Vielleicht tue ich immer ganz nach unten
Ich mache das immer ganz gerne, weil reguläre Ausdrucke sind so hässlich.
Ich will immer, dass Wartungsprogrammierer die möglichst spät sehen.
Deswegen tue ich immer nach ganz unten. So. Genau. Also
ich versuche noch mal zusammenzufassen, was wir hier gemacht haben.
Also, man kann sich erst mal ungefähr orientieren,
dass hier die Mitte ist, so als erste Orientierung.
Also, wir haben gesagt,
ein Bruch fängt immer mit einer Ziffer an und ich kann mich entscheiden,
wie viel dazu verändert haben will, zwischen 1 und 9,
also mindestens eine Ziffer höchstens 9 Ziffern.
Diese geschweiften Klammern in regulären Ausdrücken und sagen also,
wie viele ich haben will von 1 bis 9. Okay,
das muss ich auf jeden Fall haben.
Und ich habe so eine runde Klammern genommen,
damit ich über diese Group-Methode rankomme an den Teilstring.
Okay, dann habe ich gesagt,
Kann dieses Monstrum kommen. Optional, weil hier das Fragezeichen
steht und da habe ich eben diese zusätzlichen Klammern.
Und was ist es, was optional sein kann?
Eine optionale Lehrtaste, gefolgt von einem Slash,
der da auf jeden Fall stehen muss,
gefolgt von einer optionalen Lehrtaste und dann eine weitere Gruppe.
Das ist unsere Gruppe Nummer drei mittlerweile, die den kompletten Nenner darstellt.
Wie sieht ein Nenner aus? Irgendeine Ziffer zwischen 1 und 9,
die 0 will ich nicht erlauben. Und dann, ja,
können noch weitere Ziffern folgen, nämlich mindestens 0 und höchstens 8.
Dann haben wir insgesamt mindestens eine und höchstens 9.
Und wir haben diese runden Klammern verwendet,
habe ich eben gesagt, um da ranzukommen.
Wie kommt man jetzt da ran
Also, wenn ihr dieses Pattern habt,
könnt ihr dem Pattern sagen, hey,
ich muss so einen Matcher haben, der quasi das Monopoly-Spiel spielt.
Ich will jetzt wirklich was reinwerfen in diesen Automaten.
Wenn das nicht funktioniert, schmeiße ich eine Acception und erkläre
es sich nicht an die Vorbedingungen gehalten.
Dann kann ich hier mit dieser Group-Operation rankommen, an die Gruppen.
Leider ist die Gruppe zwei jetzt diese Schwachsinnsgruppe irgendwie hier,
die uns nicht viel bringen würde, die mit dem Slash.
Deswegen mussten wir die jetzt hier überspringen. Dann haben wir mit dem Pass Int,
haben wir uns jetzt hier den Zähler rausgepasst und wir sind auch sicher,
dass es funktioniert, weil neuen Ziffern kann man immer als Int passen.
Da kann kein Problem auftreten. Ich muss hier nichts irgendwie catchen oder so.
Und hier mussten wir jetzt noch schauen, kann ich Wie soll ich sagen?
Gab es diese weitere Gruppe, diese dritte hier hinten?
Also hat der Benutzer diesen Slash eingegeben oder nicht?
Wenn es nach dem Slash was gab, dann mache ich eben,
muss ich auch noch den Nenner passen.
Ansonsten kann ich als Nenner eins übergeben. Ja,
und ihr werdet jetzt ziemlich viel von dem Code ähnlich schreiben können in eurem Projekt,
wo es um Geldbeträge geht, weil das Komma ist das,
was also in einem Geldbetrag, was hier ungefähr so der Slash war,
sage ich mal so ganz grob,
ihr sollt ja auch Geldbeträge ohne Komma eingeben können.
Also ich glaube, 95 Prozent von dem, was ich
euch heute erzählt habe, werdet ihr wirklich einsetzen können.
Dann sehen wir uns nächste Woche zum letzten Mal.
Vielen Dank