first commit

master
Thomas Smits 2024-03-11 10:32:49 +01:00
commit ff95f820c4
36 changed files with 378 additions and 0 deletions

View File

@ -0,0 +1,3 @@
## Prefix-Notation
Bitte wandeln Sie den folgenden mathematischen Ausdruck in einen gültigen Clojure-Ausdruck in _Prefix-Notation_ um: `42 / (3 + 3 * 3) * 4 - 11`.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)

View File

@ -0,0 +1,6 @@
# Lösung: 01_basics/01_prefix.md
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
```clojure
(- (* (/ 42 (+ (* 3 3) 3)) 4) 11)
```

View File

@ -0,0 +1,22 @@
## Erste Schritte
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Sie haben einen Nebenjob als Programmierer*in bei der _Abzock GmbH_, einem bekannten PlayStation 5-Scalper. Sie sollen ein kleines Clojure-Programm für die Preisgestaltung auf der Webseite der Firma schreiben.
* Legen Sie ein Clojure-Skript `scalper.clj` an
* Das Skript fragt (`read-line`) nach einem Produktnamen und nach einem Einkaufs-Preis p_E
* Es gibt den Produktnamen mit Verkaufspreis (p_V) aus (`print` und `println`)
* Es gilt p_V = max(2.5 x p_E, 995)
Hinweis: Verwenden Sie `Integer/parseInt` für die Umwandlung des Einkaufspreises und `max` für die Berechnung des Maximums.
```console
$ ./scalper.clj
Produktname:
PS5 digital edition
Einkauspreis:
440
Sonderangebot: PS5 digital edition für nur 1100.0 EUR
```

View File

@ -0,0 +1,3 @@
# Lösung: 01_basics/02_first_steps.md
!INCLUDESRC "../src/clojure/scalper.clj" clojure

View File

@ -0,0 +1,23 @@
## Maps: Lagerverwaltung
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Die Abzock GmbH ist sehr zufrieden mit Ihnen, sodass Sie jetzt die Lagerverwaltung optimieren sollen. Aktuell hat die Firma nur drei Artikel auf Lager: PlayStation 5 (10 Stück), Grafikkarten vom Typ GTX1090 (20 Stück) und Sonnenblumenöl (300 Flaschen). Verwenden Sie als Schlüssel die Keywords `:PS5`, `:GTX1090` und `:OEL`.
* Legen Sie ein Clojure-Skript `abzock-lager.clj` an
* Implementieren Sie das Lager als Map im Programm mit den Keywords als Key und dem Bestand als Wert
* Fragen Sie auf der Kommandozeile nach Warenabgängen
* Ziehen Sie den Warenabgang vom Lager ab und geben Sie die neuen Bestände aus
* Hinweis: Obwohl nicht sauber, dürfen Sie hier dasselbe Symbol mehrfach mit einem `def` überschreiben. Versuchen Sie nicht die Map mit `update` zu verändern, sondern entfernen Sie den Schlüssel und fügen Sie ihn danach mit dem neuen Bestand wieder ein.
```console
$ clj -M abzock-lager.clj
Lagerverwaltung Abzock GmbH
Welcher Artikel wurde geliefert:
PS5
Wieviel wurde ausgeliefert?
5
Neuer Lagerbestand
{:GTX1090 20, :OEL 300, :PS5 5}
```

View File

@ -0,0 +1,3 @@
# Lösung: 01_basics/03_maps.md
!INCLUDESRC "../src/clojure/abzock-lager.clj" clojure

View File

@ -0,0 +1,32 @@
## Kontrolltrukturen: Lagerverwaltung, Teil 2
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Die Lagerverwaltung aus der letzten Übung funktioniert gut, allerdings können die Bestände hier unter 0 fallen. Dies wollen Sie in einer nächsten Version korrigieren:
* Kopieren Sie das Clojure-Skript der letzten Übung und nennen Sie die Kopie `abzock-lager-2.clj`
* Ändern Sie es so ab, dass Abgänge nur verbucht werden, wenn noch ausreichend Lagerbestand vorhanden ist
* Reicht der Lagerbestand nicht aus, beleidigen Sie den Benutzer und buchen den Abgang nicht
```console
Lagerverwaltung Abzock GmbH
Welcher Artikel wurde geliefert:
PS5
Wie viel wurde ausgeliefert?
30
Nicht genug Artikel vorhanden, du unwissendes Frischfleisch
Neuer Lagerbestand
{:PS5 10, :GTX1090 20, :OEL 300}
```
```console
Lagerverwaltung Abzock GmbH
Welcher Artikel wurde geliefert:
PS5
Wie viel wurde ausgeliefert?
10
Neuer Lagerbestand
{:GTX1090 20, :OEL 300, :PS5 0}
```

View File

@ -0,0 +1,3 @@
# Lösung: 01_basics/04_control_structures.md
!INCLUDESRC "../src/clojure/abzock-lager-2.clj" clojure

View File

@ -0,0 +1,35 @@
## Map und Reduce: Gewinnermittlung für die Abzock GmbH
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Nachdem die Abzock GmbH wirklich goldene Zeiten gesehen hat, möchte die Firma einen besseren Überblick über die Einnahmen haben. Die Geschäftsführer möchten sich nämlich von dem Gewinn Teslas kaufen und damit vollkommen sinnlos in der Gegend herumfahren und dabei rufen "Eure Armut kotzt uns an".
Dank Ihrer unermüdlichen Arbeit, liegen die Verkaufsdaten der Firma bereits in Clojure Datenstrukturen vor.
```clojure{Verkaufte Stückzahlen}
(def verkaeufe-stueckzahlen {
:PS5 [ 10, 5, 8, 13, 22, 42, 110 ],
:GTX1090 [ 5, 7, 11, 54, 90 ],
:OEL [ 10, 44, 100, 343, 66, 52, 23 ]})
```
```clojure{Verkaufspreise}
(def verkaufspreise {
:PS5 1239,
:GTX1090 1699,
:OEL 9 })
```
Schreiben Sie ein Clojure-Skript `abzock-gewinn.clj`:
* Berechnen Sie die Einnahmen jedes einzelnen Verkaufs
* Berechnen Sie die Summer der Einnahmen pro Produkt
* Geben Sie das Ergebnis mit `println` aus
* Verwenden Sie `doseq`, `map` und `reduce`
```console{Ausgabe des Programms}
Gewinnermittlung Abzock GmbH
:PS5 260190 EUR
:GTX1090 283733 EUR
:OEL 5742 EUR
```

View File

@ -0,0 +1,3 @@
# Lösung: 01_basics/05_map_reduce.md
!INCLUDESRC "../src/clojure/abzock-gewinn.clj" clojure

View File

@ -0,0 +1,10 @@
## Multi-Arity-Funktion
Schreiben Sie eine Funktion `my-average`, welche das arithmetische Mittel von 2, 4 oder 6 Zahlen bestimmen kann. Verwenden Sie __keine__ Varag-Funktion, sondern programmieren Sie eine _Multi-Arity-Funktion_.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn my-average
; ----> hier Ihr Code <----
)
```

View File

@ -0,0 +1,3 @@
# Lösung: 02_funktionen/01_my-average.md
!INCLUDESRC "../src/clojure/my-average.clj" clojure

View File

@ -0,0 +1,15 @@
## Funktion als Rückgabewert
Schreiben Sie eine Funktion `plus-n-fn`, welche einen Parameter `n` nimmt und eine neue Funktion zurückliefert, die ebenfalls einen Parameter akzeptiert. Diese neue Funktion addiert den Übergabewert zu `n`.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn plus-n-fn
"Liefert eine Funktion zurück, die genau ein
Argument nimmt und dieses Argument zu
`n` addiert."
[n]
; ---- hier Ihr Code ----
)
```

View File

@ -0,0 +1,3 @@
# Lösung: 02_funktionen/02_plus-n-fn.md
!INCLUDESRC "../src/clojure/plus-n-fn.clj" clojure

View File

@ -0,0 +1,13 @@
## apply und Funktionen als Übergabewerte
Schreiben Sie eine Funktion `triple-apply`, der man eine Funktion und beliebig viele weitere Argumente übergeben kann. Die Funktion wird dreimal mit den Argumenten ausgeführt und die Ergebnisse werden addiert, bevor sie zurückgegeben werden.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn triple-apply
"Wendet die Funktion `f` dreimal hintereinander auf die Argumente
`args` an und gibt die Summe der Ergebnisse zurück."
[f & args]
; ---- hier Ihr Code ----
)
```

View File

@ -0,0 +1,3 @@
# Lösung: 02_funktionen/03_triple-apply.md
!INCLUDESRC "../src/clojure/triple-apply.clj" clojure

View File

@ -0,0 +1,10 @@
## Vor- und Nachbedingung
Gegeben Sie die folgende Funktion `sqrt`. Versehen Sie die Funktion mit einer Vor- und Nachbedingung, um den Aufruf mit ungültigen Werten (`n <= 0`) und auf einen positiven Rückgabewert (`> 0`) zu testen.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn sqrt [n]
; ---- hier Ihr Code ----
(Math/sqrt n))
```

View File

@ -0,0 +1,3 @@
# Lösung: 02_funktionen/04_sqrt.md
!INCLUDESRC "../src/clojure/sqrt.clj" clojure

View File

@ -0,0 +1,13 @@
## Tail-Recursion
Schreiben Sie eine Funktion `prod-recur`, die eine beliebige Zahl von Werten multipliziert, die ihr als Vektor oder Sequenz übergeben werden. Verwenden Sie für die Implementierung `loop` und `recur` und __nicht__ `reduce` oder eine andere Funktion außer `*`.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn prod-recur
"Berechnet das Produkt einer Reihe von Zahlen `zahlen` unter
Verwendung von loop und recur."
[zahlen]
; ---- hier Ihr Code ----
)
```

View File

@ -0,0 +1,3 @@
# Lösung: 03_rekursion/01_prod-recur.md
!INCLUDESRC "../src/clojure/prod-recur.clj" clojure

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

@ -0,0 +1,40 @@
## Was hoppelt den da?
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Nach Ihrer umfassenden Tätigkeit im Scalper-Sektor sind Sie komplett erschöpft und brauchen etwas Urlaub. Also buchen Sie von dem Geld, das Sie in den letzten Monaten verdient haben, einen schönen Urlaub in den Alpen. Von Ihrem Zimmer haben Sie einen wunderbaren Blick auf die Wiesen und natürlich die Berge. Das einzige Problem: Es gibt kein Internet und damit entfallen die ganzen schönen Online-Spiele und das Netflixen komplett. Sie tun also das, was man in solch einer Situation macht und schauen aus dem Fenster.
<img src="rabbit.jpg" width="300">
Sie sehen ein Kaninchen, das freudig über die Wiese hoppelt. "Ach, wie schön die Natur ist" denken Sie und seufzen entspannt.
Während Sie so den Kaninchen zuschauen, denken Sie an Fibonacci und den Biologieunterricht in der Schule. Dort haben Sie gelernt, dass die Größe einer Kaninchenpopulation - solange man keine davon erlegt und isst - der Folge der Fibonacci-Zahlen folgt. Da sowieso nichts zu tun ist, setzen Sie sich in und programmieren in Clojure ein entsprechendes, kleines Skript.
Die Fibonacci-Zahlen sind rekursiv definiert als:
1. F_0 = 0
2. F_1 = 1
3. F_n = F_{n-1} + F_{n-2}
Damit ist der Anfang der Fibonacci-Folge:
| n | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|-----|---|---|---|---|---|---|---|----|----|----|
| F_n | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 |
Schreiben Sie ein Clojure-Programm (`kaninchen.clj`), das Fibonacci-Zahlen berechnet und ausgibt.
* Es soll eine Funktion `fibs` geben, die für den Parameter `n` die dazugehörige Fibonacci-Zahlen bis `n` liefert, also z.B. `(fibs 5)` liefert `(0 1 1 2 3 5)`.
* Es soll eine Funktion `fib` geben, die für den Parameter `n` die Fibonacci-Zahl an der Stelle `n` liefert, also z.B. `(fib 5)` liefert `5`.
* Schreiben Sie eine Funktion `karnickel` welche die Anzahl der Kaninchen nach 14 Generationen ausgibt und die Entwicklung der Population als Reihe von Zahlen.
```console
Nach 14 Generationen haben wir 377 Kaninchen
Die Population entwickelt sich so: (0 1 1 2 3 5 8 13 21 34 55 89 144 233 377)
```
* Verwenden Sie bitte auf jeden Fall eine _Tail-Recursion_ mit `loop` und `recur`.
* Speichern Sie die Anzahl der Generationen in einem Symbol.
* Sichern Sie die Funktionen `fib` und `fibs` durch eine Vorbedingung dagegen ab, mit negativen Werten aufgerufen zu werden.
* Stellen Sie durch eine Nachbedingung bei `fib` sicher, dass das Ergebnis nicht negativ ist.

View File

@ -0,0 +1,3 @@
# Lösung: 03_rekursion/02_karnickel.md
!INCLUDESRC "../src/clojure/kaninchen.clj" clojure

View File

@ -0,0 +1,14 @@
## cond
Schreiben Sie eine Funktion `test-positive`, der man eine Zahl übergibt und die dann einen String zurückgibt, der anzeigt, ob die zweite Zahl größer, kleiner oder gleich 0 ist.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn test-positive
"Vergleicht eine Zahl mit 0 gibt einen Hinweis-Text.
Der Hinweistext erklärt, ob die Zahl `number` größer, kleiner
oder gleich zur Zahl 0 ist."
[number]
; ---- hier Ihr Code ----
)
```

View File

@ -0,0 +1,3 @@
# Lösung: 04_variablen/01_test-positive.md
!INCLUDESRC "../src/clojure/test-positive.clj" clojure

View File

@ -0,0 +1,14 @@
## Ausnahmebehandlung
Schreiben Sie eine Funktion `number-formatter`, die unter Verwendung von der Java-Methode `Integer.parseInt` einen String in einen Zahlenwert umwandelt. Wenn die Umwandlung nicht funktioniert, gibt die Funktion -1 zurück.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn number-formatter
"Konvertiert den String `string` in einen Integer-Wert.
Wenn die Konvertierung fehlschlägt, wird -1 zurück
gegeben."
[string]
; ---- hier Ihr Code ----
)
```

View File

@ -0,0 +1,3 @@
# Lösung: 04_variablen/02_number-formatter.md
!INCLUDESRC "../src/clojure/number-formatter.clj" clojure

View File

@ -0,0 +1,13 @@
## reduce
Schreiben Sie eine Funktion `prod-reduce`, die eine beliebige Zahl von Werten multipliziert, die ihr als Vektor oder Sequenz übergeben werden. Verwenden Sie für die Implementierung die `reduce`-Funktion und __keine__ Rekursion.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn prod-reduce
"Berechnet das Produkt einer Reihe von Zahlen `zahlen` unter
Verwendung von reduce."
[zahlen]
; ---- hier Ihr Code ----
)
```

View File

@ -0,0 +1,3 @@
# Lösung: 05_collections/01_prod-reduce.md
!INCLUDESRC "../src/clojure/prod-reduce.clj" clojure

View File

@ -0,0 +1,15 @@
## mapping und cycle
Schreiben Sie eine Funktion `map-cycle`, welche durch eine übergebene Menge von Zahlen wiederholt läuft. Die Übergabe erfolgt als _Vararg-Argument_. Die Zahlen werden dann mal Zwei genommen und es wird jeweils 1 abgezogen (z.B. 5 -> 10 - 1 = 9). Aus dem Ergebnis werden dann n-Werte, gesteuert über den ersten Parameter, zurückgegeben.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn map-cycle
"Erzeugt eine unendliche Sequenz der Zahlen `zahlen`
und berechnet für jede Zahl deren Doppeltes und zieht
1 ab. Vom Ergebnis werden `n` Elemente zurück
gegeben."
[n & zahlen]
; ---- hier Ihr Code ----
)
```

View File

@ -0,0 +1,3 @@
# Lösung: 05_collections/02_map-cycle.md
!INCLUDESRC "../src/clojure/map-cycle.clj" clojure

View File

@ -0,0 +1,13 @@
## take-while
Schreiben Sie eine Funktion `below-zero`, welche einen Vektor oder eine Sequenz übergeben bekommt. Die Funktion soll einen neuen Vektor (oder Sequenz) mit denselben Elementen zurückgeben, diese endet aber vor dem ersten Element das `>= 0` ist.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn below-zero
"Läuft über `data` und gibt die Elemente bis zum ersten
Auftreten eines Wertes >= 0 zurück."
[data]
; ---- hier Ihr Code ----
)
```

View File

@ -0,0 +1,3 @@
# Lösung: 05_collections/03_below-zero.md
!INCLUDESRC "../src/clojure/below-zero.clj" clojure

View File

@ -0,0 +1,12 @@
## filter
Schreiben Sie eine Funktion `filter-positive`, welche eine Liste oder Sequenz übergeben bekommt. Die Funktion soll eine neue Liste (oder Sequenz) mit denselben Elemente zurückgeben, aber alle Elemente `> 0` ausfiltern.
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
```clojure
(defn filter-positive
"Läuft über `data` und gibt die Elemente, deren Wert < 0 ist zurück."
[data]
; ---- hier Ihr Code ----
)
```

View File

@ -0,0 +1,3 @@
# Lösung: 05_collections/04_filter-zero.md
!INCLUDESRC "../src/clojure/filter-positive.clj" clojure

27
readme.md 100644
View File

@ -0,0 +1,27 @@
# Clojure-Programmierung
Hier finden Sie Übungsaufgaben für den Kurs Clojure-Programmierung.
Die **Abgabedaten** haben keine Bedeutung, da es sich um freiwillige Übungen handelt.
## Themenüberblick
| # | Thema | Fällig am 📆 | Musterlösung |
|----|------------------------------------------------------------------|----------------|----------------|
| 1. | [01_basics/01_prefix.md](Assignment_001/readme.md) | **----** | [](Assignment_001/solution/) |
| 2. | [01_basics/02_first_steps.md](Assignment_002/readme.md) | **----** | [](Assignment_002/solution/) |
| 3. | [01_basics/03_maps.md](Assignment_003/readme.md) | **----** | [](Assignment_003/solution/) |
| 4. | [01_basics/04_control_structures.md](Assignment_004/readme.md) | **----** | [](Assignment_004/solution/) |
| 5. | [01_basics/05_map_reduce.md](Assignment_005/readme.md) | **----** | [](Assignment_005/solution/) |
| 6. | [02_funktionen/01_my-average.md](Assignment_006/readme.md) | **----** | [](Assignment_006/solution/) |
| 7. | [02_funktionen/02_plus-n-fn.md](Assignment_007/readme.md) | **----** | [](Assignment_007/solution/) |
| 8. | [02_funktionen/03_triple-apply.md](Assignment_008/readme.md) | **----** | [](Assignment_008/solution/) |
| 9. | [02_funktionen/04_sqrt.md](Assignment_009/readme.md) | **----** | [](Assignment_009/solution/) |
| 10. | [03_rekursion/01_prod-recur.md](Assignment_010/readme.md) | **----** | [](Assignment_010/solution/) |
| 11. | [03_rekursion/02_karnickel.md](Assignment_011/readme.md) | **----** | [](Assignment_011/solution/) |
| 12. | [04_variablen/01_test-positive.md](Assignment_012/readme.md) | **----** | [](Assignment_012/solution/) |
| 13. | [04_variablen/02_number-formatter.md](Assignment_013/readme.md) | **----** | [](Assignment_013/solution/) |
| 14. | [05_collections/01_prod-reduce.md](Assignment_014/readme.md) | **----** | [](Assignment_014/solution/) |
| 15. | [05_collections/02_map-cycle.md](Assignment_015/readme.md) | **----** | [](Assignment_015/solution/) |
| 16. | [05_collections/03_below-zero.md](Assignment_016/readme.md) | **----** | [](Assignment_016/solution/) |
| 17. | [05_collections/04_filter-zero.md](Assignment_017/readme.md) | **----** | [](Assignment_017/solution/) |