commit ba74d0f28b0e7416af903578b0d2fa4fbdb35a1e Author: amineelhajami Date: Wed Dec 10 12:06:02 2025 +0100 Initial commit diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..8d335e5 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,31 @@ + +{ + + "configurations": [ + + { + + "name": "Win64", + + "intelliSenseMode": "gcc-x64", + + "compilerPath": "C:/MinGW/bin/g++.exe", + + "cStandard": "c11", + + "cppStandard": "c++17", + + "includePath": [ + + "${workspaceFolder}/**" + + ] + + } + + ], + + "version": 4 + +} + diff --git a/README.md b/README.md new file mode 100644 index 0000000..d004be8 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Mein Konto (kleine Demo) + +Kurze Demo-Webseite zur Verwaltung eines Kontostands. + +Funktionen +- Kontostand wird in `localStorage` gespeichert (Schlüssel `konto_balance_v1`). +- Anfangswert: 1000 € (kann im `app.js` angepasst werden). +- Eingabefeld für Überweisungsbetrag. +- Validierung: + - keine gültige Zahl -> Fehlermeldung + - > 2000 € -> Abbruch mit Fehlermeldung + - Kontoüberziehung führt zu Warnung "Achtung Konto überzogen" +- Nach erfolgreicher Verarbeitung wird der Betrag abgezogen, Kontostand aktualisiert, Eingabe geleert. +- Kontostand < 0 wird rot angezeigt. + +Dateien +- `index.html` – einfache UI +- `styles.css` – Styles +- `app.js` – Logik + +Benutzung +1. Lokal öffnen: Datei `index.html` im Browser öffnen. +2. Optional (lokaler Webserver, empfohlen): + +```bash +# im Verzeichnis der Dateien +python -m http.server 8000 +# dann im Browser öffnen: http://localhost:8000 +``` + +Hinweis: Die Seite merkt sich den Kontostand im Browser. Zum Zurücksetzen `localStorage.removeItem('konto_balance_v1')` in der Konsole ausführen. diff --git a/STRING_METHODS_NOTES.md b/STRING_METHODS_NOTES.md new file mode 100644 index 0000000..c970b37 --- /dev/null +++ b/STRING_METHODS_NOTES.md @@ -0,0 +1,462 @@ +# JavaScript String-Methoden und -Eigenschaften – Notizen + +## 1. `length` (Eigenschaft) + +Gibt die Anzahl der Zeichen in einem String zurück. + +```javascript +const text = "Hallo"; +console.log(text.length); // 5 + +const empty = ""; +console.log(empty.length); // 0 + +const withSpaces = "Hallo Welt"; +console.log(withSpaces.length); // 11 (Leerzeichen zählt mit) +``` + +**Wichtig**: `length` ist eine Eigenschaft, keine Methode – keine Klammern! + +--- + +## 2. `indexOf()` und `lastIndexOf()` + +### `indexOf(searchValue, fromIndex)` +Sucht ein Zeichen oder Substring von links nach rechts. Gibt den **Index** (Position) zurück. Wenn nicht gefunden: **-1**. + +```javascript +const text = "Hallo Welt"; + +// Einzelnes Zeichen +console.log(text.indexOf("H")); // 0 (erstes Zeichen) +console.log(text.indexOf("o")); // 4 (erste "o") + +// Substring +console.log(text.indexOf("Welt")); // 6 +console.log(text.indexOf("xyz")); // -1 (nicht gefunden) + +// Optional: Startposition angeben +console.log(text.indexOf("l", 3)); // 3 (erste "l" ab Position 3) +``` + +### `lastIndexOf(searchValue, fromIndex)` +Sucht von rechts nach links – gibt **letztes** Vorkommen zurück. + +```javascript +const text = "Hallo Welt"; + +console.log(text.lastIndexOf("o")); // 9 (letzte "o") +console.log(text.lastIndexOf("l")); // 9 (letzte "l") +console.log(text.lastIndexOf("Welt")); // 6 +console.log(text.lastIndexOf("xyz")); // -1 (nicht gefunden) + +// Optional: Position von rechts +const text2 = "banana"; +console.log(text2.lastIndexOf("a", 4)); // 3 (letzte "a" bis Position 4) +``` + +**Unterschied**: +- `indexOf()` → erstes Vorkommen von links +- `lastIndexOf()` → letztes Vorkommen von rechts + +--- + +## 3. `search()` + +Sucht mit **regulärem Ausdruck** (Regex). Gibt Index des ersten Matches zurück, sonst **-1**. + +```javascript +const text = "Hallo123Welt"; + +// Einfache Suche nach Ziffer +console.log(text.search(/\d/)); // 5 (erste Ziffer) + +// Groß-/Kleinschreibung ignorieren +console.log(text.search(/welt/i)); // 8 + +// Mehrere Zeichen +console.log(text.search(/[0-9]+/)); // 5 + +// Nicht gefunden +console.log(text.search(/xyz/)); // -1 +``` + +**Unterschied zu indexOf()**: +- `indexOf()` → exakte String-Suche, einfach und schnell +- `search()` → Regex-Suche, mächtiger und komplexer + +--- + +## 4. `slice(start, end)` + +Extrahiert einen Teil des Strings. `end` ist **exklusiv** (wird nicht mit einbezogen). + +```javascript +const text = "Hallo Welt"; +// 01234567890 + +// slice(start) +console.log(text.slice(0)); // "Hallo Welt" (ab Position 0) +console.log(text.slice(6)); // "Welt" (ab Position 6) + +// slice(start, end) +console.log(text.slice(0, 5)); // "Hallo" (Position 0 bis 4) +console.log(text.slice(6, 10)); // "Welt" (Position 6 bis 9) + +// Negative Indizes (von hinten) +console.log(text.slice(-4)); // "Welt" (letzte 4 Zeichen) +console.log(text.slice(0, -5)); // "Hallo " (alles außer letzten 5) +console.log(text.slice(-4, -1)); // "Wel" (2. bis 4. Zeichen von hinten) +``` + +**Wichtig**: `slice()` erstellt einen **neuen String**, der ursprüngliche wird nicht verändert! + +--- + +## 5. `substring(start, end)` + +Ähnlich wie `slice()`, mit kleinen Unterschieden: +- `end` ist auch **exklusiv** +- Unterstützt **keine negativen Indizes** (werden als 0 interpretiert) +- Vertauscht automatisch `start` und `end`, wenn `start > end` + +```javascript +const text = "Hallo Welt"; + +// Normal +console.log(text.substring(0, 5)); // "Hallo" +console.log(text.substring(6, 10)); // "Welt" + +// Ohne end (bis zum Ende) +console.log(text.substring(6)); // "Welt" + +// Negative Werte → werden 0 +console.log(text.substring(-5, 5)); // "Hallo" (negativ ignoriert) + +// Vertauschte Parameter +console.log(text.substring(5, 0)); // "Hallo" (Parameter werden vertauscht) +``` + +**Unterschied zu slice()**: +- `slice()` → unterstützt negative Indizes, logischer +- `substring()` → keine negativen Indizes, bei Bedarf Parameter vertauschen + +--- + +## 6. `substr()` (Veraltet!) + +Extrahiert Zeichen basierend auf **Startposition** und **Länge** (nicht Ende). + +```javascript +const text = "Hallo Welt"; + +console.log(text.substr(0, 5)); // "Hallo" (ab Position 0, Länge 5) +console.log(text.substr(6, 4)); // "Welt" (ab Position 6, Länge 4) +console.log(text.substr(-4)); // "Welt" (letzte 4 Zeichen) +console.log(text.substr(-4, 2)); // "We" (ab -4, Länge 2) +``` + +**Warnung**: `substr()` ist **deprecated** (veraltet). Nutzen Sie stattdessen `slice()` oder `substring()`! + +--- + +## 7. `replace(searchValue, replaceValue)` + +Ersetzt das **erste** Vorkommen eines Strings/Regex durch einen anderen. + +```javascript +const text = "Hallo Hallo"; + +// Einfacher String +console.log(text.replace("Hallo", "Hi")); +// "Hi Hallo" (nur erstes Vorkommen!) + +// Mit Regex und "g" Flag (global → alle) +console.log(text.replace(/Hallo/g, "Hi")); +// "Hi Hi" (alle Vorkommen) + +// Groß-/Kleinschreibung ignorieren +console.log(text.replace(/hallo/i, "Hi")); +// "Hi Hallo" +``` + +**Wichtig**: +- `replace()` ersetzt nur das **erste** Vorkommen! +- Für alle: Regex mit `g` Flag verwenden +- Ursprünglicher String wird nicht verändert (neuer String wird zurückgegeben) + +```javascript +const result = "abc abc".replace(/abc/g, "xyz"); +console.log(result); // "xyz xyz" +``` + +--- + +## 8. `toUpperCase()` und `toLowerCase()` + +Wandelt String in GROSSBUCHSTABEN oder kleinbuchstaben um. + +```javascript +const text = "Hallo Welt"; + +// Großbuchstaben +console.log(text.toUpperCase()); // "HALLO WELT" +console.log("xyz".toUpperCase()); // "XYZ" + +// Kleinbuchstaben +console.log(text.toLowerCase()); // "hallo welt" +console.log("XYZ".toLowerCase()); // "xyz" + +// Mit Zahlen und Sonderzeichen +console.log("123!@#".toUpperCase()); // "123!@#" (keine Änderung) +``` + +**Wichtig**: Original wird nicht verändert! + +```javascript +const original = "Test"; +const upper = original.toUpperCase(); +console.log(original); // "Test" (unverändert!) +console.log(upper); // "TEST" +``` + +--- + +## 9. `concat(...strings)` + +Verbindet mehrere Strings zu einem neuen String. + +```javascript +const str1 = "Hallo"; +const str2 = "Welt"; + +// Mit concat() +console.log(str1.concat(" ", str2)); // "Hallo Welt" +console.log("a".concat("b", "c", "d")); // "abcd" + +// Mit mehreren Argumenten +console.log("Hello".concat(" ", "World", "!")); // "Hello World!" +``` + +**Gleich wie `+` Operator**: +```javascript +const text = "Hallo" + " " + "Welt"; // "Hallo Welt" +const text2 = "Hallo".concat(" ", "Welt"); // "Hallo Welt" +``` + +**Besser**: In der Praxis ist der `+` Operator oder Template Literals üblicher: +```javascript +const str1 = "Hallo"; +const str2 = "Welt"; + +// + Operator +const result1 = str1 + " " + str2; + +// Template Literals (empfohlen) +const result2 = `${str1} ${str2}`; + +// concat() (seltener) +const result3 = str1.concat(" ", str2); +``` + +--- + +## 10. `trim()` + +Entfernt Whitespace (Leerzeichen, Tabs, Zeilenumbrüche) vom **Anfang** und **Ende** eines Strings. + +```javascript +const text = " Hallo Welt "; + +console.log(text.trim()); // "Hallo Welt" (Außenleerzeichen weg) +console.log(text.length); // 14 +console.log(text.trim().length); // 11 + +// Mit Tabs und Zeilenumbrüchen +const messy = "\t\n Hallo \n\t"; +console.log(messy.trim()); // "Hallo" + +// Leerzeichen in der Mitte bleiben +const text2 = "Hallo Welt"; +console.log(text2.trim()); // "Hallo Welt" (Mitte unverändert) +``` + +**Wichtig**: `trim()` entfernt nur am **Anfang** und **Ende**, nicht in der Mitte! + +**Verwandte Methoden**: +```javascript +const text = " Hallo "; + +// trim() – beide Seiten +console.log(text.trim()); // "Hallo" + +// trimStart() oder trimLeft() – nur Anfang +console.log(text.trimStart()); // "Hallo " + +// trimEnd() oder trimRight() – nur Ende +console.log(text.trimEnd()); // " Hallo" +``` + +--- + +## 11. `charAt(index)` + +Gibt das Zeichen an einer bestimmten **Position** zurück. Wenn Index ungültig, leerer String `""`. + +```javascript +const text = "Hallo"; +// 01234 + +console.log(text.charAt(0)); // "H" +console.log(text.charAt(1)); // "a" +console.log(text.charAt(4)); // "o" +console.log(text.charAt(10)); // "" (zu weit, leerer String) +console.log(text.charAt(-1)); // "" (negative Index erlaubt nicht) +``` + +**Alternativ: Bracket-Notation** (einfacher): +```javascript +const text = "Hallo"; + +console.log(text[0]); // "H" +console.log(text[4]); // "o" +console.log(text[10]); // undefined (anders als charAt!) +``` + +**Unterschied**: +- `charAt(index)` → gibt `""` zurück bei ungültigem Index +- `text[index]` → gibt `undefined` zurück bei ungültigem Index + +--- + +## Vergleich und Zusammenfassung + +| Methode | Zweck | Rückgabewert | +|---------|-------|------------| +| `length` | Zeichenanzahl | Zahl | +| `indexOf()` | Erste Position eines Substrings | Index oder -1 | +| `lastIndexOf()` | Letzte Position eines Substrings | Index oder -1 | +| `search()` | Position eines Regex-Matches | Index oder -1 | +| `slice()` | Extrahiert Teil (Anfang bis Ende, exklusiv) | Neuer String | +| `substring()` | Wie slice, aber ohne negative Indizes | Neuer String | +| `substr()` | Extrahiert Teil (Position + Länge) | Neuer String (**veraltet!**) | +| `replace()` | Ersetzt erstes Vorkommen | Neuer String | +| `toUpperCase()` | In Großbuchstaben | Neuer String | +| `toLowerCase()` | In Kleinbuchstaben | Neuer String | +| `concat()` | Verbindet Strings | Neuer String | +| `trim()` | Entfernt äußere Whitespaces | Neuer String | +| `charAt()` | Zeichen an Position | Einzelnes Zeichen oder `""` | + +--- + +## Praktische Beispiele + +### Validierung einer E-Mail +```javascript +const email = " user@example.com "; +const cleaned = email.trim().toLowerCase(); + +if(cleaned.indexOf("@") > 0 && cleaned.indexOf(".") > cleaned.indexOf("@")){ + console.log("Gültige E-Mail"); +} else { + console.log("Ungültige E-Mail"); +} +``` + +### Dateiname aus Pfad extrahieren +```javascript +const path = "C:/Users/max/dokumente/file.txt"; + +// Letzten Schrägstrich finden +const lastSlash = path.lastIndexOf("/"); +const filename = path.slice(lastSlash + 1); + +console.log(filename); // "file.txt" +``` + +### URL-Parameter bereinigen +```javascript +const url = "https://example.com?id=123&name= Max "; + +if(url.indexOf("?") > -1){ + const params = url.slice(url.indexOf("?") + 1); + console.log(params); // "id=123&name= Max " +} +``` + +### Text durchsuchen (Regex) +```javascript +const text = "Kontakt: info@example.com oder 089-1234567"; + +// E-Mail finden +if(text.search(/@/) > -1){ + console.log("E-Mail vorhanden"); +} + +// Telefonnummer finden +if(text.search(/\d{3}-\d{4}/) > -1){ + console.log("Telefon vorhanden"); +} +``` + +--- + +## Häufige Fehler + +### ❌ Falscher Fehler 1: `replace()` ersetzt alle +```javascript +const text = "aaa"; +console.log(text.replace("a", "b")); // "baa" – nur erstes! +``` +**Korrekt**: +```javascript +console.log(text.replace(/a/g, "b")); // "bbb" +``` + +### ❌ Falscher Fehler 2: `length` ist keine Methode +```javascript +const text = "Hallo"; +console.log(text.length()); // TypeError! +``` +**Korrekt**: +```javascript +console.log(text.length); // 5 +``` + +### ❌ Falscher Fehler 3: Original wird nicht verändert +```javascript +let text = "hallo"; +text.toUpperCase(); +console.log(text); // "hallo" – immer noch klein! +``` +**Korrekt**: +```javascript +let text = "hallo"; +text = text.toUpperCase(); +console.log(text); // "HALLO" +``` + +### ❌ Falscher Fehler 4: `substr()` verwenden (veraltet) +```javascript +// Besser nicht: +const text = "Hello"; +console.log(text.substr(0, 3)); // "Hel" + +// Stattdessen: +console.log(text.slice(0, 3)); // "Hel" +``` + +--- + +## Zusammenfassung für die Praxis + +1. **Länge prüfen**: `length` +2. **Position suchen**: `indexOf()` oder `lastIndexOf()` (einfach), `search()` (Regex) +3. **Substring extrahieren**: `slice()` (mit negativen Indizes), `substring()` (ohne) +4. **Ersetzen**: `replace()` mit `g` Flag für alle +5. **Groß-/Kleinschreibung**: `toUpperCase()`, `toLowerCase()` +6. **Verbinden**: `+` oder Template Literals (nicht `concat()`) +7. **Bereinigen**: `trim()` für äußere Whitespaces +8. **Einzelnes Zeichen**: `charAt()` oder `[index]` + +**Wichtigste Regel**: Strings sind unveränderlich! Alle Methoden geben einen **neuen String** zurück. diff --git a/app.js b/app.js new file mode 100644 index 0000000..99c88a2 --- /dev/null +++ b/app.js @@ -0,0 +1,134 @@ +// ===== STRING-METHODEN BEISPIELE IN DIESER APP ===== +// +// 1. trim() – Whitespace entfernen (in parseAmount) +// 2. replace() – Komma durch Punkt ersetzen (in parseAmount) +// 3. toLowerCase() – String zu Kleinbuchstaben (in showMessage) +// 4. length – Zeichenanzahl prüfen (in transferBtn.addEventListener) +// 5. concat() und toUpperCase() – können Sie in der HTML erweitern +// +// ===== WEITERE STRING-METHODEN ===== +// indexOf(), lastIndexOf() – Position eines Substrings finden +// slice(), substring() – Teile eines Strings extrahieren +// charAt() – einzelnes Zeichen an Position +// search() – mit Regex suchen +// +// Siehe: STRING_METHODS_NOTES.md für detaillierte Dokumentation + +const STORAGE_KEY = 'konto_balance_v1'; +const INITIAL_BALANCE = 1000.00; // Anfangswert beliebig + +const balanceDisplay = document.getElementById('balanceDisplay'); +const amountInput = document.getElementById('amountInput'); +const transferBtn = document.getElementById('transferBtn'); +const messageDiv = document.getElementById('message'); + +function readStoredBalance(){ + const raw = localStorage.getItem(STORAGE_KEY); + if(raw === null){ + localStorage.setItem(STORAGE_KEY, INITIAL_BALANCE.toString()); + return INITIAL_BALANCE; + } + const n = parseFloat(raw); + return Number.isFinite(n) ? n : INITIAL_BALANCE; +} + +function writeStoredBalance(value){ + localStorage.setItem(STORAGE_KEY, value.toString()); +} + +function formatCurrency(num){ + return num.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }); +} + +function showMessage(text, type){ + messageDiv.textContent = text || ''; + + // ===== STRING-METHODEN: toLowerCase() ===== + // toLowerCase() – wandelt String in Kleinbuchstaben um + // Praktisch: Konsistente Vergleiche unabhängig von Groß-/Kleinschreibung + // Beispiel: "ERROR".toLowerCase() → "error" + const normalizedType = (type || '').toLowerCase(); + + messageDiv.className = ''; + if(normalizedType === 'error') messageDiv.classList.add('msg-error'); + if(normalizedType === 'warning') messageDiv.classList.add('msg-warning'); + if(normalizedType === 'success') messageDiv.classList.add('msg-success'); +} + +function updateDisplay(){ + const bal = readStoredBalance(); + balanceDisplay.textContent = formatCurrency(bal); + if(bal < 0){ + balanceDisplay.classList.add('negative'); + } else { + balanceDisplay.classList.remove('negative'); + } +} + +function parseAmount(input){ + if(!input) return NaN; + + // ===== STRING-METHODEN IN AKTION ===== + + // 1. trim() – entfernt äußere Whitespaces (Leerzeichen, Tabs, etc.) + // Praktisch: Benutzereingaben bereinigen + // Beispiel: " 123.45 ".trim() → "123.45" + const trimmed = input.trim(); + + // 2. replace() – ersetzt Zeichen oder Substring + // Akzeptiere sowohl Komma als auch Punkt als Dezimaltrenner + // replace(searchValue, replaceValue) – ersetzt ERSTES Vorkommen + // Beispiel: "123,45".replace(',', '.') → "123.45" + const normalized = trimmed.replace(',', '.'); + + // Alternative: replace() mit Regex und "g" Flag für alle Vorkommen + // const normalized = trimmed.replace(/,/g, '.'); + + return parseFloat(normalized); +} + +transferBtn.addEventListener('click', ()=>{ + showMessage('', null); + const raw = amountInput.value; + + // ===== STRING-METHODEN: length und indexOf() ===== + // length – gibt die Anzahl der Zeichen zurück (Eigenschaft, keine Methode!) + // Beispiel: "Hallo".length → 5 + // Praktisch: Prüfe ob Eingabe nicht leer ist + if(raw.length === 0){ + showMessage('Bitte geben Sie einen Betrag ein.', 'error'); + return; + } + + const amount = parseAmount(raw); + + if(!Number.isFinite(amount) || amount <= 0){ + showMessage('Bitte geben Sie einen gültigen Betrag größer als 0 ein.', 'error'); + return; + } + + if(amount > 2000){ + showMessage('Über 2000 € können nicht überwiesen werden. Vorgang abgebrochen.', 'error'); + return; + } + + const current = readStoredBalance(); + const newBalance = +(current - amount).toFixed(2); + + if(newBalance < 0){ + showMessage('Achtung Konto überzogen', 'warning'); + } else { + showMessage('Überweisung erfolgreich.', 'success'); + } + + writeStoredBalance(newBalance); + updateDisplay(); + + // ===== STRING-METHODEN: Eingabefeld leeren ===== + // Setze den Wert auf einen leeren String '' + // Beispiel: input.value = '' + amountInput.value = ''; + amountInput.focus(); +}); + +updateDisplay(); diff --git a/index.html b/index.html new file mode 100644 index 0000000..0cea06e --- /dev/null +++ b/index.html @@ -0,0 +1,29 @@ + + + + + + Mein Konto + + + +
+

Sparrkasse

+ +
+ +
--
+
+ +
+ + + +
+ +
+
+ + + + diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..06b801d --- /dev/null +++ b/styles.css @@ -0,0 +1,82 @@ +:root{ + --bg:#f7f7fb; + --card:#ffffff; + --text:#222; + --danger:#c82333; + --warning:#f39c12; + --success:#28a745; +} +*{ + box-sizing:border-box +} +body{ + font-family:Segoe UI, Roboto, Arial, sans-serif; + background:var(--bg); + color:var(--text); + padding:32px +} + +main{ + max-width:480px; + margin:0 auto;background:var(--card); + padding:24px; + border-radius:8px; + box-shadow:0 6px 18px rgba(0,0,0,.06) +} +h1{ + margin-top:0; + color: red; +} +.balance{ + display:flex; + align-items:center; + gap:12px;margin-bottom:16px +} +.balance .amount{ + font-weight:700; + font-size:1.4rem; + +} +.transfer{ + display:flex; + gap:8px; + align-items:center; + margin-bottom:12px +} + +input[type="text"]{ + flex:1; + padding:8px; + border:1px solid #d7d7df; + border-radius:4px +} +button{ + padding:8px 12px; + border:none; + background:red; + color:white;border-radius:4px; + cursor:pointer +} +button:active{ + transform:translateY(1px) +} + +#message{ + min-height:1.6em +} + +.msg-error{ + color:var(--danger) +} + +.msg-warning{ + color:var(--warning) +} + +.msg-success{ + color:var(--success) +} + +.negative{ + color:var(--danger) +}