Tracks
/
Julia
Julia
/
Übungen
/
Highschool-Liebe
Highschool-Liebe

Highschool-Liebe

Lernübung

Einführung

Julia ermutigt Programmierer, möglichst viel Code in Funktionen zu stecken, die JIT-kompiliert werden können. Viele kleine Funktionen anzulegen ist dabei bewusst performant.

Das führt oft dazu, dass viele kleine, einfache Funktionen übrig bleiben, die kombiniert werden müssen, um nicht-triviale Aufgaben zu erledigen.

Ein naheliegender Ansatz ist, Funktionsaufrufe zu verschachteln. Das folgende Beispiel ist ziemlich konstruiert, veranschaulicht aber den Punkt.

julia> first.(titlecase.(reverse.(["my", "test", "strings"])))
3-element Vector{Char}:
 'Y': ASCII/Unicode U+0059 (category Lu: Letter, uppercase)
 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase)
 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)

Der Nachteil dieses Ansatzes ist, dass die Lesbarkeit mit zunehmender Verschachtelungstiefe schnell sinkt.

Wir brauchen einen einfacheren und flexibleren Ansatz.

Komposition

Das ist die Technik, die Mathematiker lieben, und Julia übernimmt die mathematische Syntax.

Beliebig viele Funktionen lassen sich mit ∘-Operatoren zu einer composed-Funktion zusammensetzen (eingegeben als \circ und dann Tab). Das Ergebnis kannst du wie eine einzelne Funktion verwenden.

julia> compfunc = first ∘ titlecase ∘ reverse
first ∘ titlecase ∘ reverse
julia> compfunc.(["my", "test", "strings"])
3-element Vector{Char}:
 'Y': ASCII/Unicode U+0059 (category Lu: Letter, uppercase)
 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase)
 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)
# alternative syntax, giving the same result
julia> (first ∘ titlecase ∘ reverse).(["my", "test", "strings"])

Ein paar Punkte, die du beachten solltest:

  • Die Ausgangsfunktionen stehen in derselben Reihenfolge wie beim Verschachteln und werden von rechts nach links ausgeführt.
  • Broadcasting lässt sich beim Zusammensetzen nicht einfach verwenden, kann aber beim Aufruf der zusammengesetzten Funktion angewendet werden.

Pipelining

Eine Alternative lässt sich eher als der Ansatz der Programmierer verstehen, nicht als der der Mathematiker.

Pipelines werden schon lange in Unix-Shellskripten verwendet und wurden in jüngerer Zeit auch in gängigen Programmiersprachen populär (F# wird manchmal zugeschrieben, ihre Verbreitung vorangetrieben zu haben).

Das Grundkonzept: Du startest mit irgendwelchen Daten und leitest sie dann durch eine Reihe von Funktionen, um das Ergebnis zu erhalten.

Der Pipe-Operator ist |> (wie in F# und neueren Versionen von R), doch Julia hat auch eine Broadcast-Version .|>.

julia> ["my", "test", "strings"] .|> reverse .|> titlecase .|> first
3-element Vector{Char}:
 'Y': ASCII/Unicode U+0059 (category Lu: Letter, uppercase)
 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase)
 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)

Die Ausführung erfolgt jetzt streng von links nach rechts, wobei die Ausgabe jeder Funktion in Pfeilrichtung fließt und zum Eingabewert der nächsten Funktion wird.

Einschränkungen, Workarounds und andere Optionen

Es ist kein Zufall, dass die Funktionen, mit denen Komposition und Pipelining veranschaulicht werden, alle ein einziges Argument entgegennehmen.

Manche rein funktionalen Sprachen leiten das erste Argument in eine Funktion, erlauben aber, weitere anzugeben.

Julia dagegen erwartet in einer Pipeline nur Funktions-Namen (oder etwas Gleichwertiges), ohne zusätzliche Argumente.

Dafür gibt es wichtige technische Gründe (sie hängen damit zusammen, dass currying kein fester Bestandteil des Sprachdesigns ist). Die vielen Menschen, die von Currying nichts verstehen, sollten einfach akzeptieren, dass diese Einschränkung kein sorgloser Fehler ist und sich in künftigen Julia-Versionen wahrscheinlich nicht ändern wird.

Workarounds

Wir brauchen Funktionen mit genau einem Argument, die erledigen, was nötig ist. Zum Glück ist das Definieren neuer Funktionen in Julia einfach.

Am einfachsten verwenden wir eine anonymous function. Wenn wir beispielsweise einen einzelnen String als Eingabe haben und ihn an Unterstrichen aufteilen wollen:

julia> "my_test_strings" |> (s -> split(s, '_'))
3-element Vector{SubString{String}}:
 "my"
 "test"
 "strings"

Dieser Vektor könnte dann wie zuvor durch weitere Funktionen geleitet werden.

In diesem Fall ist es optional, die anonyme Funktion in Klammern zu setzen, aber allgemein ist das eine nützliche Möglichkeit, Mehrdeutigkeiten zu vermeiden.

Ebenso könnten wir weiter oben im Programm eine benannte Funktion anlegen und sie nach Bedarf wiederverwenden.

Anleitung

In dieser Übung hilfst du Highschool-Pärchen, ihre Liebe in den sozialen Medien zu bekunden, indem du ein Unicode-Herz mit ihren Initialen erzeugst:

❤ J.  +  M. ❤

1. Den Namen bereinigen

Implementiere die Methode cleanupname. Sie soll einen Namen entgegennehmen und darin alle - durch ein Leerzeichen ersetzen. Außerdem soll sie Leerzeichen am Anfang und am Ende des Namens entfernen.

julia> cleanupname("Jane-Ann")
"Jane Ann"

2. Den ersten Buchstaben des Namens ermitteln

Implementiere die Methode firstletter. Sie soll einen Namen entgegennehmen und seinen ersten Buchstaben als String zurückgeben. Achte darauf, cleanupname aus dem vorherigen Schritt wiederzuverwenden und mit anderen Funktionen zu kombinieren.

julia> firstletter("Jane")
"J"

3. Den ersten Buchstaben als Initiale formatieren

Implementiere die Methode initial. Sie soll einen Namen entgegennehmen und seinen ersten Buchstaben in Großbuchstaben zurückgeben, gefolgt von einem Punkt. Achte darauf, firstletter aus dem vorherigen Schritt wiederzuverwenden.

initial("Robert")
"R."

4. Die Initialen in das Herz setzen

Implementiere die Methode couple. Sie soll zwei Namen entgegennehmen und die Initialen mit Emoji-Herzen drumherum zurückgeben. Achte darauf, initial aus dem vorherigen Schritt wiederzuverwenden.

couple("Blake Miller", "Riley Lewis")
"❤ B.  +  R. ❤"
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Julia Exercism

Bereit, mit Highschool-Liebe zu starten?

Melde dich bei Exercism an, um Julia mit 35 Konzepte128 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.