452 lines
22 KiB
Python
452 lines
22 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Java Modules Generator for Courses: Lehrpfad 1 & 2 (Module 01 bis 08)
|
|
Erstellt alle 8 Module mit:
|
|
- index.html
|
|
- README.md
|
|
- Aufgabe.java
|
|
- TestAufgabe.java
|
|
- Musterloesung.java
|
|
"""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
BASE_DIR = Path("/root/uebungen_python/courses/java")
|
|
|
|
# ==============================================================================
|
|
# MODUL 01: Java Syntax & Primitive Datentypen
|
|
# ==============================================================================
|
|
MOD_01_INDEX = """<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Java 01: Java Syntax & Primitive Datentypen</title>
|
|
<link rel="stylesheet" href="../../../assets/style.css">
|
|
</head>
|
|
<body>
|
|
<div class="app-layout">
|
|
<div class="app-main">
|
|
<header>
|
|
<div class="header-container">
|
|
<div class="header-badge">☕ Java 21+ Enterprise & IHK/Uni Standard</div>
|
|
<h1>Java 01: Syntax, Primitive Datentypen & Type Casting</h1>
|
|
<p>Tauche ein in das strenge, statische Typensystem von Java: Lerne die 8 primitiven Datentypen, den JVM Entry-Point <code>public static void main</code> und sicheres Type Casting.</p>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="container">
|
|
<!-- 1. THEORIE: STRUKTUR & MAIN -->
|
|
<section class="card">
|
|
<h2>🏛️ 1. Grundstruktur eines Java-Programms</h2>
|
|
<p>In Java ist alles in <strong>Klassen</strong> organisiert. Der Dateiname muss exakt dem Namen der <code>public class</code> entsprechen (inklusive Groß-/Kleinschreibung):</p>
|
|
|
|
<pre><code>public class Aufgabe {
|
|
// Der Einstiegspunkt für die Java Virtual Machine (JVM)
|
|
public static void main(String[] args) {
|
|
System.out.println("Willkommen in Java 21 Enterprise!");
|
|
}
|
|
}</code></pre>
|
|
|
|
<div class="box box-analogie">
|
|
<div class="box-title">🏢 Didaktische Analogie: Der Schlüssel zum Haupttor</div>
|
|
<p>Die <code>main</code>-Methode ist der Generalschlüssel der JVM: <code>public</code> (jeder darf rein), <code>static</code> (das Gebäude muss nicht erst instanziiert werden), <code>void</code> (keine Rückgabe an das Betriebssystem nötig) und <code>String[] args</code> (die Übergabeparameter beim Starten).</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- 2. THEORIE: PRIMITIVE DATENTYPEN -->
|
|
<section class="card">
|
|
<h2>🔢 2. Die 8 primitiven Datentypen</h2>
|
|
<p>Java unterscheidet strikt zwischen <strong>primitiven Typen</strong> (direkt auf dem Stack gespeichert) und <strong>Referenztypen</strong> (Objekte auf dem Heap):</p>
|
|
|
|
<div style="overflow-x: auto;">
|
|
<table style="width: 100%; border-collapse: collapse; font-size: 0.9rem; margin-bottom: 16px;">
|
|
<thead>
|
|
<tr style="border-bottom: 2px solid var(--border-color); background: var(--bg-subtle);">
|
|
<th style="padding: 8px 12px;">Typ</th>
|
|
<th style="padding: 8px 12px;">Größe</th>
|
|
<th style="padding: 8px 12px;">Wertebereich</th>
|
|
<th style="padding: 8px 12px;">Standardwert</th>
|
|
<th style="padding: 8px 12px;">Beispiel</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
|
<td style="padding: 8px 12px;"><code>byte</code></td>
|
|
<td style="padding: 8px 12px;">8 Bit (1 Byte)</td>
|
|
<td style="padding: 8px 12px;">-128 bis 127</td>
|
|
<td style="padding: 8px 12px;"><code>0</code></td>
|
|
<td style="padding: 8px 12px;"><code>byte b = 42;</code></td>
|
|
</tr>
|
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
|
<td style="padding: 8px 12px;"><code>short</code></td>
|
|
<td style="padding: 8px 12px;">16 Bit (2 Byte)</td>
|
|
<td style="padding: 8px 12px;">-32.768 bis 32.767</td>
|
|
<td style="padding: 8px 12px;"><code>0</code></td>
|
|
<td style="padding: 8px 12px;"><code>short s = 1024;</code></td>
|
|
</tr>
|
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
|
<td style="padding: 8px 12px;"><code>int</code></td>
|
|
<td style="padding: 8px 12px;">32 Bit (4 Byte)</td>
|
|
<td style="padding: 8px 12px;">-2.147.483.648 bis 2.147.483.647</td>
|
|
<td style="padding: 8px 12px;"><code>0</code></td>
|
|
<td style="padding: 8px 12px;"><code>int port = 8080;</code></td>
|
|
</tr>
|
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
|
<td style="padding: 8px 12px;"><code>long</code></td>
|
|
<td style="padding: 8px 12px;">64 Bit (8 Byte)</td>
|
|
<td style="padding: 8px 12px;">-9 Trillionen bis +9 Trillionen</td>
|
|
<td style="padding: 8px 12px;"><code>0L</code></td>
|
|
<td style="padding: 8px 12px;"><code>long timestamp = 1700000000000L;</code></td>
|
|
</tr>
|
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
|
<td style="padding: 8px 12px;"><code>float</code></td>
|
|
<td style="padding: 8px 12px;">32 Bit (4 Byte)</td>
|
|
<td style="padding: 8px 12px;">~6-7 Dezimalstellen</td>
|
|
<td style="padding: 8px 12px;"><code>0.0f</code></td>
|
|
<td style="padding: 8px 12px;"><code>float pi = 3.14159f;</code></td>
|
|
</tr>
|
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
|
<td style="padding: 8px 12px;"><code>double</code></td>
|
|
<td style="padding: 8px 12px;">64 Bit (8 Byte)</td>
|
|
<td style="padding: 8px 12px;">~15-16 Dezimalstellen (Standard)</td>
|
|
<td style="padding: 8px 12px;"><code>0.0d</code></td>
|
|
<td style="padding: 8px 12px;"><code>double saldo = 1250.75;</code></td>
|
|
</tr>
|
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
|
<td style="padding: 8px 12px;"><code>boolean</code></td>
|
|
<td style="padding: 8px 12px;">1 Bit / JVM</td>
|
|
<td style="padding: 8px 12px;"><code>true</code> oder <code>false</code></td>
|
|
<td style="padding: 8px 12px;"><code>false</code></td>
|
|
<td style="padding: 8px 12px;"><code>boolean isProd = true;</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding: 8px 12px;"><code>char</code></td>
|
|
<td style="padding: 8px 12px;">16 Bit (2 Byte)</td>
|
|
<td style="padding: 8px 12px;">Unicode (0 bis 65.535)</td>
|
|
<td style="padding: 8px 12px;"><code>'\\u0000'</code></td>
|
|
<td style="padding: 8px 12px;"><code>char grade = 'A';</code></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- 3. THEORIE: TYPE CASTING -->
|
|
<section class="card">
|
|
<h2>🔄 3. Type Casting: Widening vs. Narrowing</h2>
|
|
<p>Wenn Werte zwischen Datentypen übergeben werden, unterscheidet Java zwei Fälle:</p>
|
|
|
|
<pre><code>// 1. Widening Casting (Automatisch/Implizit - kein Datenverlust):
|
|
// byte -> short -> char -> int -> long -> float -> double
|
|
int kleineZahl = 100;
|
|
double kommazahl = kleineZahl; // 100.0 (Automatisch erweitert)
|
|
|
|
// 2. Narrowing Casting (Manuell/Explizit - möglicher Datenverlust/Überlauf):
|
|
// double -> float -> long -> int -> char -> short -> byte
|
|
double preis = 99.99;
|
|
int gerundet = (int) preis; // 99 (Nachkommastellen werden abgeschnitten!)
|
|
|
|
// ⚠️ Vorsicht bei Ganzzahl-Division:
|
|
int summe = 10;
|
|
int anzahl = 4;
|
|
double falsch = summe / anzahl; // Ergibt 2.0 (Ganzzahldivision 10/4 = 2!)
|
|
double richtig = (double) summe / anzahl; // Ergibt 2.5 (10.0 / 4 = 2.5)</code></pre>
|
|
</section>
|
|
|
|
<!-- 4. AUFGABEN CHECKLISTE -->
|
|
<section class="card">
|
|
<h2>🎯 Aufgaben & Checkliste in <code>Aufgabe.java</code></h2>
|
|
<div class="task-item">
|
|
<input type="checkbox" class="task-checkbox" id="t1">
|
|
<label class="task-label" for="t1"><strong>TODO 1:</strong> <code>getServerInfo(serverName, port, cpuUsage, isProduction, status)</code> formatieren.</label>
|
|
</div>
|
|
<div class="task-item">
|
|
<input type="checkbox" class="task-checkbox" id="t2">
|
|
<label class="task-label" for="t2"><strong>TODO 2:</strong> <code>berechneNotendurchschnitt(summePunkte, anzahlPruefungen)</code> mit explizitem Cast zu <code>double</code> fehlerfrei berechnen.</label>
|
|
</div>
|
|
<div class="task-item">
|
|
<input type="checkbox" class="task-checkbox" id="t3">
|
|
<label class="task-label" for="t3"><strong>TODO 3:</strong> <code>verschiebeZeichen(c, offset)</code> und <code>istGrossbuchstabe(c)</code> mit Unicode/char-Arithmetik umsetzen.</label>
|
|
</div>
|
|
<div class="task-item">
|
|
<input type="checkbox" class="task-checkbox" id="t4">
|
|
<label class="task-label" for="t4"><strong>TODO 4:</strong> <code>konvertiereZuByte(wert)</code> mit Bereichsprüfung (-128 bis 127) und Narrowing Cast programmieren.</label>
|
|
</div>
|
|
|
|
<div class="box box-tipp" style="margin-top: 20px;">
|
|
<div class="box-title">💡 Java Pro-Tipp: String.format & Locale</div>
|
|
<p>Nutze <code>String.format(java.util.Locale.US, "%.1f%%", cpuUsage * 100)</code> für international standardisierte Punktdarstellung bei Fließkommazahlen.</p>
|
|
</div>
|
|
|
|
<div style="margin-top: 25px; display: flex; gap: 12px; flex-wrap: wrap;">
|
|
<a href="../../../workspace.html?course=java&track=track_1_java_basics&chapter=01_java_syntax_und_primitive_typen" class="btn" style="background: #e11d48; color: #fff; font-weight: 700;">💻 In Web-IDE öffnen →</a>
|
|
<a href="../02_kontrollfluss_und_verzweigungen/index.html" class="btn btn-secondary">Weiter zu Java 02 →</a>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
MOD_01_README = """# ☕ Java 01: Syntax, Primitive Datentypen & Type Casting
|
|
|
|
Willkommen zum ersten Modul des Java Enterprise Kurses! In dieser Einheit lernst du die fundamentale Struktur von Java-Programmen, das strenge statische Typensystem und den sicheren Umgang mit Typkonvertierungen kennen.
|
|
|
|
---
|
|
|
|
## 🎯 Lernziele
|
|
|
|
Nach Bearbeitung dieses Moduls kannst du:
|
|
1. Den Aufbau einer Java-Klasse und die Signatur der `public static void main(String[] args)` Methode fehlerfrei erklären.
|
|
2. Alle **8 primitiven Datentypen** (`byte`, `short`, `int`, `long`, `float`, `double`, `boolean`, `char`) zielgerichtet auswählen und Speichergrößen abschätzen.
|
|
3. Den Unterschied zwischen **Stack-Speicher** (primitive Typen) und **Heap-Speicher** (Objekte) verstehen.
|
|
4. **Widening** (implizit) und **Narrowing** (explizit) Type Casting anwenden und Ganzzahldivisions-Fallen vermeiden.
|
|
5. Zeichenarithmetik mit `char` und Unicode durchführen.
|
|
|
|
---
|
|
|
|
## 💡 Theoretische Grundlagen
|
|
|
|
### 1. Das statische Typensystem von Java
|
|
Java ist streng und statisch typisiert. Das bedeutet: Jede Variable besitzt bereits zur **Compile-Zeit** einen unveränderlichen Typ.
|
|
|
|
```java
|
|
int port = 8080;
|
|
// port = "achtzig"; // COMPILE-FEHLER: Incompatible types!
|
|
```
|
|
|
|
### 2. Primitive Datentypen im Überblick
|
|
|
|
| Typ | Bit-Breite | Wertebereich | Standardwert |
|
|
| :--- | :--- | :--- | :--- |
|
|
| `byte` | 8 Bit | -128 bis 127 | `0` |
|
|
| `short` | 16 Bit | -32.768 bis 32.767 | `0` |
|
|
| `int` | 32 Bit | -2.147.483.648 bis 2.147.483.647 | `0` |
|
|
| `long` | 64 Bit | -9 Trillionen bis +9 Trillionen | `0L` |
|
|
| `float` | 32 Bit | IEEE 754 Fließkomma (~7 Dezimalstellen) | `0.0f` |
|
|
| `double` | 64 Bit | IEEE 754 Fließkomma (~16 Dezimalstellen) | `0.0d` |
|
|
| `boolean` | 1 Bit / JVM | `true` oder `false` | `false` |
|
|
| `char` | 16 Bit | Unicode `\\u0000` bis `\\uffff` (0 bis 65.535) | `'\\u0000'` |
|
|
|
|
### 3. Type Casting (Typumwandlung)
|
|
|
|
```java
|
|
// Widening (Automatisch ohne Informationsverlust):
|
|
int count = 42;
|
|
double countDouble = count; // 42.0
|
|
|
|
// Narrowing (Expliziter Cast erforderlich, da Daten verloren gehen können):
|
|
double preis = 19.99;
|
|
int euro = (int) preis; // 19 (Nachkommastelle wird abgeschnitten!)
|
|
|
|
// ⚠️ Typische Falle: Ganzzahldivision
|
|
int a = 7;
|
|
int b = 2;
|
|
double res1 = a / b; // 3.0 (weil 7/2 als int gerechnet wird!)
|
|
double res2 = (double) a / b; // 3.5 (7.0 / 2 wird als double gerechnet)
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Aufgabenübersicht in `Aufgabe.java`
|
|
|
|
1. **TODO 1: `getServerInfo(...)`**:
|
|
Erzeuge einen formatierten String aus Servername, Port, CPU-Last in Prozent, Produktionsstatus und Status-Zeichen.
|
|
2. **TODO 2: `berechneNotendurchschnitt(...)`**:
|
|
Berechne den exakten Notendurchschnitt mit `(double) summe / anzahl`. Gib `0.0` zurück bei `anzahl <= 0`.
|
|
3. **TODO 3: `verschiebeZeichen(...)` & `istGrossbuchstabe(...)`**:
|
|
Führe Unicode-Verschiebung durch und prüfe auf Großbuchstaben (`'A'` bis `'Z'`).
|
|
4. **TODO 4: `konvertiereZuByte(...)`**:
|
|
Überprüfe, ob der Wert im Bereich `-128` bis `127` liegt. Falls nicht, wirf eine `IllegalArgumentException`. Führe ansonsten den Narrowing Cast `(byte) wert` durch.
|
|
|
|
---
|
|
|
|
## 🧪 Tests ausführen
|
|
|
|
In der Web-IDE: Klicke auf **"Code ausführen & testen"**.
|
|
Lokal mit Standard-Java:
|
|
```bash
|
|
javac Aufgabe.java TestAufgabe.java
|
|
java TestAufgabe
|
|
```
|
|
"""
|
|
|
|
MOD_01_AUFGABE = """public class Aufgabe {
|
|
|
|
// 🎯 TEILZIEL 1 (TODO 1): Server-Konfigurationsdaten als String formatieren
|
|
// Format: "Server: [serverName] | Port: [port] | CPU: [cpuUsage in %] | Status: [status] | Prod: [isProduction]"
|
|
// Beispiel: getServerInfo("PROD-1", 8080, 0.755, true, 'A')
|
|
// Rückgabe: "Server: PROD-1 | Port: 8080 | CPU: 75.5% | Status: A | Prod: true"
|
|
// Hinweis: Nutze java.util.Locale.US für Punkt-Notation bei Prozentangaben (%.1f%%).
|
|
public static String getServerInfo(String serverName, int port, double cpuUsage, boolean isProduction, char status) {
|
|
// TODO: Implementiere die Formatierung
|
|
return "";
|
|
}
|
|
|
|
// 🎯 TEILZIEL 2 (TODO 2): Genauen Notendurchschnitt mit Typkonvertierung berechnen
|
|
// Berechne den Durchschnitt als double.
|
|
// Falls anzahlPruefungen <= 0 ist, gib 0.0 zurück.
|
|
// Achte darauf, dass KEINE Ganzzahldivision stattfindet!
|
|
public static double berechneNotendurchschnitt(int summePunkte, int anzahlPruefungen) {
|
|
// TODO: Prüfe auf <= 0 und führe expliziten Type Cast durch
|
|
return 0.0;
|
|
}
|
|
|
|
// 🎯 TEILZIEL 3 (TODO 3): Char-Transformation & Unicode-Arithmetik
|
|
// Verschiebt das gegebene Zeichen c um 'offset' Positionen im Zeichensatz.
|
|
// Beispiel: verschiebeZeichen('A', 3) -> 'D'
|
|
// Beispiel: verschiebeZeichen('a', 1) -> 'b'
|
|
public static char verschiebeZeichen(char c, int offset) {
|
|
// TODO: Führe char-Arithmetik mit explizitem Cast (char)(...) durch
|
|
return ' ';
|
|
}
|
|
|
|
// Prüft, ob das gegebene Zeichen ein lateinischer Großbuchstabe ('A' bis 'Z') ist.
|
|
public static boolean istGrossbuchstabe(char c) {
|
|
// TODO: Prüfe den Bereich 'A' <= c <= 'Z'
|
|
return false;
|
|
}
|
|
|
|
// 🎯 TEILZIEL 4 (TODO 4): Narrowing Casting mit Wertebereichs-Prüfung
|
|
// Konvertiert einen int-Wert sicher in einen byte (-128 bis 127).
|
|
// Falls der Wert < -128 oder > 127 ist, soll eine IllegalArgumentException mit der Nachricht
|
|
// "Wert außerhalb des Byte-Bereichs: " + wert geworfen werden.
|
|
public static byte konvertiereZuByte(int wert) {
|
|
// TODO: Validiere Wertebereich und caste zu byte
|
|
return 0;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
System.out.println(getServerInfo("PROD-1", 8080, 0.755, true, 'A'));
|
|
System.out.println("Schnitt (15 Punkte / 4): " + berechneNotendurchschnitt(15, 4));
|
|
System.out.println("Verschiebe 'A' um 3: " + verschiebeZeichen('A', 3));
|
|
System.out.println("Ist 'G' groß? " + istGrossbuchstabe('G'));
|
|
System.out.println("Byte-Cast (42): " + konvertiereZuByte(42));
|
|
}
|
|
}
|
|
"""
|
|
|
|
MOD_01_TEST = """import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.api.DisplayName;
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
|
|
public class TestAufgabe {
|
|
|
|
@Test
|
|
@DisplayName("TODO 1: getServerInfo formatiert alle primitiven Typen korrekt")
|
|
void testGetServerInfo() {
|
|
String info1 = Aufgabe.getServerInfo("PROD-1", 8080, 0.755, true, 'A');
|
|
assertEquals("Server: PROD-1 | Port: 8080 | CPU: 75.5% | Status: A | Prod: true", info1);
|
|
|
|
String info2 = Aufgabe.getServerInfo("DEV-NODE", 3000, 0.12, false, 'I');
|
|
assertEquals("Server: DEV-NODE | Port: 3000 | CPU: 12.0% | Status: I | Prod: false", info2);
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("TODO 2: berechneNotendurchschnitt verhindert Ganzzahldivision & Division durch 0")
|
|
void testBerechneNotendurchschnitt() {
|
|
assertEquals(3.75, Aufgabe.berechneNotendurchschnitt(15, 4), 0.0001);
|
|
assertEquals(2.3333, Aufgabe.berechneNotendurchschnitt(7, 3), 0.001);
|
|
assertEquals(0.0, Aufgabe.berechneNotendurchschnitt(100, 0), 0.0001);
|
|
assertEquals(0.0, Aufgabe.berechneNotendurchschnitt(50, -2), 0.0001);
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("TODO 3: verschiebeZeichen und istGrossbuchstabe arbeiten mit Unicode/ASCII")
|
|
void testCharOperationen() {
|
|
assertEquals('D', Aufgabe.verschiebeZeichen('A', 3));
|
|
assertEquals('z', Aufgabe.verschiebeZeichen('a', 25));
|
|
assertEquals('A', Aufgabe.verschiebeZeichen('C', -2));
|
|
|
|
assertTrue(Aufgabe.istGrossbuchstabe('A'));
|
|
assertTrue(Aufgabe.istGrossbuchstabe('M'));
|
|
assertTrue(Aufgabe.istGrossbuchstabe('Z'));
|
|
assertFalse(Aufgabe.istGrossbuchstabe('a'));
|
|
assertFalse(Aufgabe.istGrossbuchstabe('1'));
|
|
assertFalse(Aufgabe.istGrossbuchstabe('!'));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("TODO 4: konvertiereZuByte wirft Exception bei Überlauf und castet gültige Werte")
|
|
void testKonvertiereZuByte() {
|
|
assertEquals((byte) 42, Aufgabe.konvertiereZuByte(42));
|
|
assertEquals((byte) -128, Aufgabe.konvertiereZuByte(-128));
|
|
assertEquals((byte) 127, Aufgabe.konvertiereZuByte(127));
|
|
|
|
assertThrows(IllegalArgumentException.class, () -> Aufgabe.konvertiereZuByte(128));
|
|
assertThrows(IllegalArgumentException.class, () -> Aufgabe.konvertiereZuByte(-129));
|
|
assertThrows(IllegalArgumentException.class, () -> Aufgabe.konvertiereZuByte(1000));
|
|
}
|
|
|
|
// Standalone Runner für direkte Ausführung ohne externes Framework
|
|
public static void main(String[] args) {
|
|
System.out.println("🧪 Starte Tests für Java 01: Syntax & Primitive Typen...");
|
|
TestAufgabe t = new TestAufgabe();
|
|
int passed = 0;
|
|
int total = 4;
|
|
|
|
try { t.testGetServerInfo(); passed++; System.out.println(" [✔] Test 1: getServerInfo PASSED"); } catch (Throwable e) { System.out.println(" [✘] Test 1 FAILED: " + e.getMessage()); }
|
|
try { t.testBerechneNotendurchschnitt(); passed++; System.out.println(" [✔] Test 2: berechneNotendurchschnitt PASSED"); } catch (Throwable e) { System.out.println(" [✘] Test 2 FAILED: " + e.getMessage()); }
|
|
try { t.testCharOperationen(); passed++; System.out.println(" [✔] Test 3: Char-Operationen PASSED"); } catch (Throwable e) { System.out.println(" [✘] Test 3 FAILED: " + e.getMessage()); }
|
|
try { t.testKonvertiereZuByte(); passed++; System.out.println(" [✔] Test 4: konvertiereZuByte PASSED"); } catch (Throwable e) { System.out.println(" [✘] Test 4 FAILED: " + e.getMessage()); }
|
|
|
|
System.out.printf("\\nErgebnis: %d/%d Tests bestanden.\\n", passed, total);
|
|
if (passed == total) {
|
|
System.out.println("🎉 Alle Tests erfolgreich!");
|
|
} else {
|
|
System.exit(1);
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
MOD_01_LOESUNG = """import java.util.Locale;
|
|
|
|
public class Musterloesung {
|
|
|
|
// 🎯 TEILZIEL 1: Server-Konfigurationsdaten als String formatieren
|
|
public static String getServerInfo(String serverName, int port, double cpuUsage, boolean isProduction, char status) {
|
|
return String.format(Locale.US, "Server: %s | Port: %d | CPU: %.1f%% | Status: %c | Prod: %b",
|
|
serverName, port, cpuUsage * 100.0, status, isProduction);
|
|
}
|
|
|
|
// 🎯 TEILZIEL 2: Genauen Notendurchschnitt mit Typkonvertierung berechnen
|
|
public static double berechneNotendurchschnitt(int summePunkte, int anzahlPruefungen) {
|
|
if (anzahlPruefungen <= 0) {
|
|
return 0.0;
|
|
}
|
|
return (double) summePunkte / anzahlPruefungen;
|
|
}
|
|
|
|
// 🎯 TEILZIEL 3: Char-Transformation & Unicode-Arithmetik
|
|
public static char verschiebeZeichen(char c, int offset) {
|
|
return (char) (c + offset);
|
|
}
|
|
|
|
public static boolean istGrossbuchstabe(char c) {
|
|
return c >= 'A' && c <= 'Z';
|
|
}
|
|
|
|
// 🎯 TEILZIEL 4: Narrowing Casting mit Wertebereichs-Prüfung
|
|
public static byte konvertiereZuByte(int wert) {
|
|
if (wert < -128 || wert > 127) {
|
|
throw new IllegalArgumentException("Wert außerhalb des Byte-Bereichs: " + wert);
|
|
}
|
|
return (byte) wert;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
System.out.println(getServerInfo("PROD-1", 8080, 0.755, true, 'A'));
|
|
System.out.println("Schnitt: " + berechneNotendurchschnitt(15, 4));
|
|
System.out.println("Char: " + verschiebeZeichen('A', 3));
|
|
System.out.println("Großbuchstabe: " + istGrossbuchstabe('X'));
|
|
System.out.println("Byte: " + konvertiereZuByte(100));
|
|
}
|
|
}
|
|
"""
|
|
|
|
print("Modul 01 Data ready.")
|