Update of exercises

main
Thomas Smits 2026-06-10 14:22:56 +02:00
parent 20a7fcc149
commit 899ee1ea64
11 changed files with 343 additions and 13 deletions

View File

@ -0,0 +1,180 @@
# IP-Adressen
**🎓 Benotetes Assignment 🎓**
📆 **Fällig: 23.06.2026** 📆
Mittlerweile haben Sie sich mit den Aliens angefreundet. Allerdings müssen sie demnächst zurück nach Hause.
"Es tut uns leid, aber mir müssen gehen"
Sie wollen aber weiterhin mit Ihren neuen Freunden im Kontakt bleiben.
"Müsst ihr wirklich gehen?"
Dann schlugen die Aliens etwas vor:
"Ja, aber wir können unsere Computer in einem Netzwerk verbinden, um weiterhin zu kommunizieren".
Diese Idee klang super, bis Sie feststellten, dass sie nicht wissen, wie man
Computer in einem Netzwerk verbindet.
"Aber wie soll das gehen?"
"Wir brauchen dafür nur IP-Adressen im selben Netzwerk"
Dafür brauchen Sie aber ein Tool, mit dem Sie IP-Adressen in einem Netzwerk
berechnen können.
## Paket
Gehen Sie in das Paket [pr2.collections.ip](../sources/src/main/java/pr2/collections/ip/).
## Implementierung
Im Paket
[pr2.collections.ip.iputils](../sources/src/main/java/pr2/collections/ip/iputils/) befinden sich folgende Inhalte:
* `IPAdress` -> Eine Klasse
* `IPFormatter` -> Ein Interface
* `IPParser` -> Ein Interface
* `IPInformation` -> Ein Enum
* `IPParseException` -> Eine Ausnahme
Und noch eine `Main` im darüberliegendem Paket.
Zur Information über IP-Adressen:
* Eine IP-Adresse besteht aus 2 Teilen: die Adresse selbst sowie die Subnetzmaske
* Die Subnetzmaske beginnt immer links, und eine Folge von 1 und danach nur noch 0. Zum Beispiel `11110000` wäre eine Subnetzmaske (nicht vollständig, geht um das Konzept), `10100001` aber nicht.
* Die Subnetzmaske wird üblicherweise mit `/X` angegeben, wo `X` die Anzahl an Bits ist, die auf 1 sind.
* Die Subnetzmaske ist immer genauso lang wie die IP-Adresse (in bytes)
* Die Netzwerkadresse wird berechnet, indem alle Host-Bits auf 0 gesetzt werden, bsp: `10101010` als IP und `11110000` als Subnetzmaske ergeben `10100000` als Netzwerkadresse.
* Die Broadcastadresse wird berechnet, indem alle Host-Bits auf 1 gesetzt werden, bsp: `10101010` als IP und `11110000` als Subnetzmaske ergeben `10101111` als Broadcastadresse.
### `Main`
Diese Klasse hat eine `main`-Methode, welche den Nutzer auf der Konsole nach einer IP-Adresse frägt, diese einliest, verarbeitet und dann das Ergebnis auf der Konsole ausgibt. Ein Beispiel könnte wie folgt aussehen:
```
Bitte gib eine IP-Adresse ein: 192.168.0.1/30
```
```
IP-Adresse: 192.168.0.1/30
Network: 192.168.0.0/30
Broadcast: 192.168.0.3/30
Range: 192.168.0.1/30 - 192.168.0.2/30
Verfügbare Adressen:
192.168.0.1/30
192.168.0.2/30
```
Sie dürfen gerne beliebig rumspielen, aber eine simple Ausgabe wie im obigen Beispiel genügt.
### `IPAddress`
Dieser Klasse fehlt einiges:
* `getNetworkAddress` Implementierung
* `getBroadcastAddress` Implementierung
* `addHostByte` Implementierung
* `prettyFormat` Implementierung
* `iterator` Implementierung
* Konstruktoren
In den Javadocs können Sie sehen, was die Methoden jeweils tun sollen. Es soll neben dem Copy-Konstruktor auch einen Konstruktor geben, der eine **verarbeitbare Darstellung einer IP-Adresse** sowie einen passenden `IPFormatter` bekommt.
Überlegen Sie sich gut, wie eine **verarbeitbare Darstellung einer IP-Adresse** aussehen sollte.
Dann zum Iterator: dieser soll über die IP-Adressen im Range iterieren, sprich die _Netzwerkadresse_ sowie die _Broadcastadresse_ **nicht** mit einbegriffen. Sie dürfen eine Innere-Klasse oder seperate Klasse verwenden, beide sollen allerdings von außen nicht sichtbar sein!
Dann noch ein Beispiel-Output für die `prettyFormat`-Methode:
```
IP-Adresse: 192.168.0.1/30
Network: 192.168.0.0/30
Broadcast: 192.168.0.3/30
Range: 192.168.0.1/30 - 192.168.0.2/30
Verfügbare Adressen:
192.168.0.1/30
192.168.0.2/30
```
### `IPFormatter`
Diesem Interface fehlt noch eine Methode `format`. Diese Methode soll einen String als Rückgabewert zurückgeben. Überlegen Sie sich geeignete Parameter.
### `IPParser`
Diesem Interface fehlt noch eine Methode `parse`. Diese Methode soll einen String übergeben bekommen und eine für die `IPAddress` **verarbeitbare Darstellung der IP-Adresse** zurückgeben. Überlegen Sie sich einen geeigneten Rückgabewert.
### `IPInformation`
Dieses Enum soll Optionen für das `prettyFormat` der `IPAddress` angeben. Sie dürfen hier auch gerne Methoden hinzufügen, es dürfen aber **keine** Konsolen-Ausgaben getätig werden.
Es sollte für folgendes Optionen geben:
* Die IP-Adresse
* Die Netzwerkadresse der IP-Adresse
* Die Broadcast-Adresse der IP-Adresse
* Den Range der IP-Adresse (**Netzwerkadresse+1** - **Broadcastadresse-1**)
* Alle IP-Adressen im Range ausgeben
### `IPParseException`
Diese Klasse ist bereits implementiert. Sie dürfen diese gerne ändern, müssen dies aber nicht.
### Weiteres
Ebenfalls fehlt jeweils eine Klasse, die `IPFormatter` bzw. `IPParser` implementieren. Erstellen Sie dafür entsprechend eine `IPv4Formatter` und `IPv4Parser` Klasse und implementieren Sie diese. Es sollen gängige IPv4-Adressen verarbeitbar / ausgegeben werden können, zum Beispiel `192.168.0.1/24`.
### Bonus [+25 Punkte]
Wer Bonus-Punkte möchte, darf zusätzlich einen `IPv6Formatter` und `IPv6Parser` erstellen und implementieren. Die Punkte gibt es allerdings **nur**, wenn alle folgende Formate sowohl eingegeben als auch ausgegeben werden können:
* `::/24`
* `::1/24`
* `1::1/24`
* `1:1::1/24`
* `1111:1111:1111:1111:1111:1111:1111:1111/24`
**Informationen**
* Das sind nur Beispiele für die Formate, natürlich sollten alle möglichen IPv6-Adressen in diesen Formaten funktionieren.
* Es sollte **keine** andere Klasse angepasst werden, dass IPv6 funktioniert, mit Ausnahme der `Main`
Und natürlich soll das ganze dann auch in der `Main` funktionieren, zum Beispiel:
```
Bitte gebe eine IP-Adresse ein: ::1/126
IP-Adresse: ::1/126
Network: ::/126
Broadcast: ::3/126
Range: ::1/126 - ::2/126
Verfügbare Adressen:
::1/126
::2/126
```
## Tests
Überprüfen Sie die Funktionalität Ihrer Implementierung mit entsprechenden JUnit-Tests und weisen Sie mit diesen Tests nach, dass die implementierten Operationen richtig funktionieren. Testen Sie alle Methoden und Konstruktoren (die `prettyFormat`-Methode müssen Sie nicht testen).
**Abgabe**: Source-Code der Tests als `IPTest`.
## Abgabe
Alle Abgaben für die Vorlesung erfolgen über `git` und das Ihnen zugeordnete Repository.
Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Rufen Sie mit `bin/submit.sh` das Skript auf, das die Lösungen testet und kompiliert. Wenn Maven eine Fehlermeldung zeigt, beheben Sie diese zuerst, bevor Sie mit dem nächsten Schritt fortfahren.
4. Wenn Sie Meldung "✅ Projekt gebaut" bekommen, checken Sie Ihre Änderungen in `git` **auf der Kommandozeile** ein (comitten), d.h. mit `git add` und `git commit`. Verwenden Sie **nicht** Eclipse für diesen Schritt.
5. Rufen Sie mit `bin/submit.sh` erneut das Skript auf. Wenn alles klappt, bekommen Sie die Anzeige "✅ Aktuelle Lösungen eingereicht" und Ihre Lösung ist im System angekommen.
6. Überprüfen Sie über das Web-Frontend, ob alles so im Repository liegt, wie Sie es erwarten.
**Erinnerung**: Denken Sie daran, dass Sie alle **öffentlichen Methoden** mit entsprechender **Javadoc** versehen müssen. **Ausgaben** auf und **Eingaben** von der Konsole sind nur dann erlaubt, wenn der Aufgabentext es explizit verlangt.

View File

@ -28,6 +28,7 @@ Wichtige Einstellungen für Eclipse sind [hier](help/eclipse.md) beschrieben.
| 9. | 06.05.2026 | [Was hoppelt den da?](Assignment_009/readme.md) | **19.05.2026** | | 9. | 06.05.2026 | [Was hoppelt den da?](Assignment_009/readme.md) | **19.05.2026** |
| 10. | 13.05.2026 | [Live-Testat](Assignment_010/readme.md) | **13.05.2026** | | 10. | 13.05.2026 | [Live-Testat](Assignment_010/readme.md) | **13.05.2026** |
| 11. | 20.05.2026 | [Mist die Festplatte ist schon wieder voll](Assignment_011/readme.md) | **09.06.2026** | | 11. | 20.05.2026 | [Mist die Festplatte ist schon wieder voll](Assignment_011/readme.md) | **09.06.2026** |
| 12. | 10.06.2026 | [IP-Adressen](Assignment_012/readme.md) | **23.06.2026** |
## 🏛️ Aufbau der Veranstaltung ## 🏛️ Aufbau der Veranstaltung
@ -45,8 +46,8 @@ Die folgende Tabelle zeigt Ihnen die Themen der Woche und welche Kapitel Sie bis
| 8 | Wenn es mal schief geht, Ausnahmen | Exceptions, try, catch | [9][9] | [1][as_001], [2][as_002], [3][as_003], [4][as_004], [5][as_005] | **04.05** | | 8 | Wenn es mal schief geht, Ausnahmen | Exceptions, try, catch | [9][9] | [1][as_001], [2][as_002], [3][as_003], [4][as_004], [5][as_005] | **04.05** |
| 9 | Rein oder raus, die Daten müssen fließen | Input/Output mit Streams und Reader/Writer | [10][10] | [1][io_001], [2][io_002], [3][io_003], [4][io_004], [5][io_005], [6][io_006], [7][io_007], [8][io_008], [9][io_009], [10][io_010], [11][io_011], [12][io_012], [13][io_013], [14][io_014], [15][io_015], [16][io_016] | **11.05** | | 9 | Rein oder raus, die Daten müssen fließen | Input/Output mit Streams und Reader/Writer | [10][10] | [1][io_001], [2][io_002], [3][io_003], [4][io_004], [5][io_005], [6][io_006], [7][io_007], [8][io_008], [9][io_009], [10][io_010], [11][io_011], [12][io_012], [13][io_013], [14][io_014], [15][io_015], [16][io_016] | **11.05** |
| 10 | One size fits all, mit generischen Typen | Generische Typen, Wildcards | [11][11] | [1][ge_001], [2][ge_002], [3][ge_003], [4][ge_004], [5][ge_005], [6][ge_006], [7][ge_007], [8][ge_008], [9][ge_009] | **18.05** | | 10 | One size fits all, mit generischen Typen | Generische Typen, Wildcards | [11][11] | [1][ge_001], [2][ge_002], [3][ge_003], [4][ge_004], [5][ge_005], [6][ge_006], [7][ge_007], [8][ge_008], [9][ge_009] | **18.05** |
| 11 | Matroschka-Klassen | Geschachtelte Klassen, Lambdas | [12][12] | [1][gk_001], [2][gk_002], [3][gk_003], [4][la_001], [5][la_002] | **01.06** | | 11 | Daten brauchen Struktur | Abstrakte Datentypen | [13][13] | | **01.06** |
| 12 | Daten brauchen Struktur | Abstrakte Datentypen | [13][13] | | **08.06** | | 11 | Matroschka-Klassen | Geschachtelte Klassen, Lambdas | [12][12] | [1][gk_001], [2][gk_002], [3][gk_003], [4][la_001], [5][la_002] | **08.06** |
| 13 | Objekte sammeln | Collections und Streams | [14][14], [15][15] | [1][co_001], [2][co_002], [3][co_003], [4][co_004], [5][co_005], [6][co_006], [7][co_007], [8][co_008], [9][co_009], [10][co_010], [11][co_011], [12][sr_001], [13][sr_002], [14][sr_003], [15][sr_004], [16][sr_005], [17][sr_006], [18][sr_007], [19][sr_008], [20][sr_009], [21][sr_010] | **15.06** | | 13 | Objekte sammeln | Collections und Streams | [14][14], [15][15] | [1][co_001], [2][co_002], [3][co_003], [4][co_004], [5][co_005], [6][co_006], [7][co_007], [8][co_008], [9][co_009], [10][co_010], [11][co_011], [12][sr_001], [13][sr_002], [14][sr_003], [15][sr_004], [16][sr_005], [17][sr_006], [18][sr_007], [19][sr_008], [20][sr_009], [21][sr_010] | **15.06** |
| 14 | Parallel läuft es schneller | Threads, Probleme der Thread-Programmierung | [16][16] | [1][th_001], [2][th_002], [3][th_003], [4][th_004], [5][th_005], [6][th_006], [7][th_007], [8][th_008] | **22.06** | | 14 | Parallel läuft es schneller | Threads, Probleme der Thread-Programmierung | [16][16] | [1][th_001], [2][th_002], [3][th_003], [4][th_004], [5][th_005], [6][th_006], [7][th_007], [8][th_008] | **22.06** |

View File

@ -0,0 +1,16 @@
package pr2.collections.ip;
/**
* Main-Klasse mit der main-Methode.
*/
public class Main {
/**
* Die main-Methode für ein Konsoleninterface.
*
* @param args die Konsolen-Argumente.
*/
public static void main(String[] args) {
}
}

View File

@ -0,0 +1,78 @@
package pr2.collections.ip.iputils;
import java.util.Set;
import java.util.Iterator;
/**
* Eine Klasse um eine IP-Adresse zu repräsentieren und Berechnung
* auszuführen.
*/
public class IPAddress implements Iterable<IPAddress> {
/**
* Ein Copy-Konstruktor.
*
* @param ip die IP, von der eine Kopie erstellt werden soll.
*/
public IPAddress(IPAddress ip) {
}
/**
* Berechnet die Netzwerkadresse und liefert diese als neues {@link IPAddress}
* Objekt zurück.
*
* @return die Netzwerkadresse.
*/
public IPAddress getNetworkAddress() {
return null;
}
/**
* Berechnet die Broadcast-Adresse und liefer diese als neues {@link IPAddress}
* Objekt zurück.
*
* @return die Broadcast-Adresse.
*/
public IPAddress getBroadcastAddress() {
return null;
}
/**
* Fügt den Host-Bits einen Wert hinzu und gibt die daraus folgende IP-Adresse
* als neues {@link IPAddress} Objekt zurück. Falls die neue Adresse über die
* Broadcast-Adresse geht, wird die Broadcast-Adresse zurückgegeben. Falls die
* neue Adresse unter die Netzwerkadresse geht, wird die Netzwerkadresse
* zurückgegeben.
*
* @param amount die Menge um wie viel sich die Host-Bits ändern sollen.
* @return die neue IP-Adresse.
*/
public IPAddress addHostByte(int amount) {
return null;
}
@Override
public String toString() {
return null;
}
/**
* Gibt die {@link IPAddress} in einem schön formatierten {@link String} zurück.
*
* @param information welche informationen in der Rückgabe enthalten sein
* sollen.
* @return ein schön formatierter {@link String}.
*/
public String prettyFormat(Set<IPInformation> information) {
return null;
}
@Override
public Iterator<IPAddress> iterator() {
return null;
}
}

View File

@ -0,0 +1,9 @@
package pr2.collections.ip.iputils;
/**
* Interface mit einer Methode um aus IP-Adress-Bytes einen String zu machen.
*/
public interface IPFormatter {
}

View File

@ -0,0 +1,20 @@
package pr2.collections.ip.iputils;
/**
* Enum mit pretty-print Optionen.
*/
public enum IPInformation {
REPLACEME;
/**
* Formatiert eine {@link IPAddress} zur gegebenen Option.
*
* @param ip die {@link IPAddress} zum Formatieren.
* @return der formatierte String.
*/
public String toString(IPAddress ip) {
return null;
}
}

View File

@ -0,0 +1,16 @@
package pr2.collections.ip.iputils;
/**
* Wird geworfen, wenn eine IP-Adresse nicht verarbeitet werden konnte.
*/
public class IPParseException extends Exception {
/**
* Konstruktor für die Ausnahme.
*
* @param version die IP-Version.
* @param text die Fehlermeldung.
*/
public IPParseException(int version, String text) {
super(String.format("Failed to parse IPv%d: %s.", version, text));
}
}

View File

@ -0,0 +1,8 @@
package pr2.collections.ip.iputils;
/**
* Interface mit einer Methode um aus einem String eine verarbeitbare
* Repräsentation für eine IP-Adresse zu generieren.
*/
public interface IPParser {
}

View File

@ -43,5 +43,6 @@ public class RuleFactory {
public static Rule createRule(int number) { public static Rule createRule(int number) {
// TODO: Hier sollten sich Ihre Änderungen abspielen // TODO: Hier sollten sich Ihre Änderungen abspielen
return null;
} }
} }

View File

@ -3,17 +3,7 @@ package pr2.vererbung.racewars.model;
/** /**
* Basisklasse für alle Wesen im Spiel. * Basisklasse für alle Wesen im Spiel.
*/ */
public abstract class Wesen implements Angreifer, Angegriffener { public abstract class Wesen {
/**
* Greife das andere Wesen an. Der Schaden wird berechnet und beim
* gegnerischen Wesen abgezogen.
*
* @param gegner Wesen, das angegriffen werden soll.
* @return Zugefügter Schaden.
*/
@Override
public abstract double attacke(Angegriffener gegner);
} }

View File

@ -0,0 +1,11 @@
package pr2.collections.ip;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import pr2.collections.ip.iputils.*;
import static org.junit.jupiter.api.Assertions.*;
public class IPTest {
}