Compare commits

...

11 Commits

60 changed files with 2578 additions and 0 deletions

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset ="utf-8">
<title>Ungeordnete Liste</title>
</head>
<body>
<h1>Unnummerierte Liste</h1>
<ul>
<li>HTML lernen</li>
<ul>
<li>Tags</li>
<li>Listen</li>
<li>Formulare</li>
</ul>
<li>CSS entdecken</li>
<li>JavaScript üben</li>
</ul>
</body>
</html>

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Muffins</title>
</head>
<body>
<h1>Muffins backen</h1>
<ol type="I" start="IV" reversed>
<li>Backofen auf 180 °C vorheizen</li>
<li>Teig vorbereiten (Mehl, Zucker, Eier etc. verrühren)</li>
<li>Teig in Förmchen füllen</li>
<li>Muffins 20 Minuten backen</li>
<li>Abkühlen lassen und servieren</li>
</ol>
</body>
</html>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Stundenplan</title>
</head>
<body>
<table border="1">
<caption>Stundenplan - 8. Schuljahr</caption>
<thead>
<tr>
<th>Zeit</th>
<th>Montag</th>
<th>Dienstag</th>
<th>Mittwoch</th>
<th>Donnerstag</th>
<th>Freitag</th>
</tr>
</thead>
<tbody>
<tr>
<td>08-10 Uhr</td>
<td>Mathe</td>
<td>Englisch</td>
<td>Physik</td>
<td>Chemie</td>
<td>Sport</td>
</tr>
<tr>
<td>10-12 Uhr</td>
<td>Deutsch</td>
<td>Biologie</td>
<td>Musik</td>
<td>Mathe</td>
<td>Kunst</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="6">Stand: Juli 2025</td>
</tr>
</tfoot>
</table>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Sectioning</title>
</head>
<body>
<header>
<nav>
<a href="#main">Hauptinhalt</a>
<a href="#html">Design</a>
<a href =#css>Design</a>
<a href="#footer">Kontakt</a>
</nav>
</header>
<main id="main">
<section>
<article id="html">
<h2>HTML</h2>
<p>HTML ist eine Auszeichnungssprache</p>
</article>
<article id="css">
<h2>CSS</h2>
<p>CSS ist eine Stylesprache</p>
</article>
</section>
<section>
<h2>Tipp der Woche</h2>
<p>...selbst Tippen!</p>
</section>
</main>
<footer id="footer">
<p>&copy; 2025 WebWeekly Redaktion</p>
</footer>
</body>
</html>

View File

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Meine Lieblingsrezepte</title>
</head>
<body>
<header>
<nav>
<a href="rezepte/bolognese.html">Vegetarische Bolognese</a> |
<a href="rezepte/ramen.html">Ramen</a> |
<a href="rezepte/kimchi.html">Kimchi</a> |
<a href="rezepte/nudelpfanne.html">Nudelpfanne</a> |
<a href="rezepte/salat.html">Salat</a>
</nav>
</header>
<main>
<table border="1">
<thead>
<tr>
<th>Rezept</th>
<th>Bild</th>
<th>Arbeitsaufwand</th>
<th>Portionen</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="detailseiten/bolognese.html">Vegetarische Bolognese</a></td>
<td><img src="img/bolognese.jpeg" alt="Spaghetti Bolognese"width="300"></td>
<td>60 Minuten</td>
<td>4</td>
</tr>
<tr>
<td><a href="detailseiten/ramen.html">Ramen</a></td>
<td><img src="img/ramen.jpeg" alt="Vegetarische Ramen"width="300"></td>
<td>30 Minuten</td>
<td>2</td>
</tr>
<tr>
<td><a href="detailseiten/kimchi.html">Kimchi</a></td>
<td><img src="img/kimchi.jpeg" alt="Kimchi"width="300"></td>
<td>30 Minuten + 3 Wochen Wartezeit</td>
<td>30</td>
</tr>
<tr>
<td><a href="detailseiten/nudelpfanne.html">Nudelpfanne</a></td>
<td><img src="img/nudelpfanne.jpeg" alt="Nudelpfanne" width="300"></td>
<td>20 Minuten</td>
<td>2</td>
</tr>
<tr>
<td><a href="detailseiten/salat.html">Salat</a></td>
<td><img src="img/salat.jpeg" alt="Salat" width="300"></td>
<td>10 Minuten</td>
<td>2</td>
</tr>
</tbody>
</table>
</main>
<footer>
<p>Kontakt: <a href="mailto:meine.rezepte@example.com">meine.rezepte@example.com</a></p>
<p>Erstellt von: Francesca Bläse | © 2025 Meine Lieblingsrezepte</p>
</footer>
</body>
</html>

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Vegetarische Spaghetti Bolognese</title>
</head>
<body>
<header>
<h1>Vegetarische Spaghetti Bolognese</h1>
<nav>
<a href="../index.html">Zurück zur Übersicht</a>
</nav>
</header>
<main>
<img src="../img/bolognese.jpeg" alt="Vegetarische Spaghetti Bolognese" width="400">
<h2>Beschreibung</h2>
<p>Eine herzhafte, vegetarische Variante der klassischen Bolognese mit Tofu statt Hackfleisch.
Perfekt für alle, die bewusst genießen wollen, ohne auf Geschmack zu verzichten.</p>
<h2>Zutaten (für 4 Personen)</h2>
<ul>
<li>400 g Spaghetti</li>
<li>300 g fester Tofu</li>
<li>1 Zwiebel, 2 Knoblauchzehen</li>
<li>1 Dose stückige Tomaten (400 g)</li>
<li>2 EL Tomatenmark</li>
<li>2 EL Olivenöl</li>
<li>1 TL Sojasauce</li>
<li>Salz, Pfeffer, Oregano, Basilikum</li>
</ul>
<h2>Zubereitung</h2>
<ol>
<li>Zwiebel und Knoblauch fein hacken und in Olivenöl glasig anbraten.</li>
<li>Tofu mit einer Gabel zerbröseln oder fein zerdrücken, dann mit Sojasauce goldbraun anbraten.</li>
<li>Tomaten und Tomatenmark hinzufügen, würzen und etwa 2030 Minuten köcheln lassen.</li>
<li>Spaghetti nach Packungsanweisung kochen, abgießen und mit d

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Kimchi</title>
</head>
<body>
<header>
<h1>Kimchi</h1>
<nav>
<a href="../index.html">Zurück zur Übersicht</a>
</nav>
</header>
<main>
<img src="../img/kimchi.jpeg" alt="Kimchi" width="400">
<h2>Beschreibung</h2>
<p>Koreanisches fermentiertes Gemüse scharf, würzig und gesund.</p>
<h2>Zutaten (ergibt ca. 1 Glas)</h2>
<ul>
<li>1 Chinakohl</li>
<li>2 EL Salz</li>
<li>2 Knoblauchzehen, 1 Stück Ingwer</li>
<li>2 EL Gochugaru (Chilipulver)</li>
<li>1 TL Zucker, 1 Frühlingszwiebel</li>
</ul>
<h2>Zubereitung</h2>
<ol>
<li>Chinakohl in Stücke schneiden, salzen und 2 Stunden ziehen lassen.</li>
<li>Wasser abgießen, mit Gewürzpaste mischen.</li>
<li>In Glas füllen, 23 Tage bei Zimmertemperatur fermentieren lassen.</li>
<li>Kühl lagern und genießen.</li>
</ol>
</main>
<footer>
<p>© 2025 Meine Lieblingsrezepte</p>
</footer>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Nudelpfanne</title>
</head>
<body>
<header>
<h1>Nudelpfanne</h1>
<nav>
<a href="../index.html">Zurück zur Übersicht</a>
</nav>
</header>
<main>
<img src="../img/nudelpfanne.jpeg" alt="Nudelpfanne" width="400">
<h2>Beschreibung</h2>
<p>Schnelles Wokgericht mit Gemüse und Nudeln ideal für den Feierabend.</p>
<h2>Zutaten (für 2 Personen)</h2>
<ul>
<li>200 g Nudeln</li>
<li>1 Paprika, 1 Zucchini</li>
<li>1 Zwiebel, 1 Knoblauchzehe</li>
<li>2 EL Sojasauce</li>
<li>Etwas Öl zum Braten</li>
</ul>
<h2>Zubereitung</h2>
<ol>
<li>Nudeln kochen und beiseitestellen.</li>
<li>Gemüse anbraten, Nudeln hinzufügen.</li>
<li>Mit Sojasauce abschmecken und servieren.</li>
</ol>
</main>
<footer>
<p>© 2025 Meine Lieblingsrezepte</p>
</footer>
</body>
</html>

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Vegetarische Ramen</title>
</head>
<body>
<header>
<h1>Vegetarische Ramen</h1>
<nav>
<a href="../index.html">Zurück zur Übersicht</a>
</nav>
</header>
<main>
<img src="../img/ramen.jpeg" alt="Vegetarische Ramen" width="400">
<h2>Beschreibung</h2>
<p>Japanische Nudelsuppe mit Gemüse und würziger Brühe perfekt für kalte Tage.</p>
<h2>Zutaten (für 2 Personen)</h2>
<ul>
<li>150 g Ramen-Nudeln</li>
<li>1 Liter Gemüsebrühe</li>
<li>1 Möhre, 1 Frühlingszwiebel</li>
<li>100 g Tofu</li>
<li>Sojasauce, Sesamöl, Chili</li>
</ul>
<h2>Zubereitung</h2>
<ol>
<li>Brühe erhitzen, mit Sojasauce und Sesamöl würzen.</li>
<li>Gemüse schneiden und kurz mitköcheln lassen.</li>
<li>Nudeln und Tofu hinzufügen, 5 Minuten ziehen lassen.</li>
<li>Mit Chili und Frühlingszwiebeln garnieren.</li>
</ol>
</main>
<footer>
<p>© 2025 Meine Lieblingsrezepte</p>
</footer>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Bunter Salat</title>
</head>
<body>
<header>
<h1>Bunter Salat</h1>
<nav>
<a href="../index.html">Zurück zur Übersicht</a>
</nav>
</header>
<main>
<img src="../img/salat.jpeg" alt="Bunter Salat" width="400">
<h2>Beschreibung</h2>
<p>Frischer, leichter Salat mit knackigem Gemüse perfekt als Beilage oder leichtes Mittagessen.</p>
<h2>Zutaten (für 2 Personen)</h2>
<ul>
<li>1 Kopf Blattsalat</li>
<li>1 Tomate, ½ Gurke</li>
<li>1 Karotte, etwas Mais</li>
<li>2 EL Olivenöl, 1 EL Essig</li>
<li>Salz, Pfeffer</li>
</ul>
<h2>Zubereitung</h2>
<ol>
<li>Gemüse waschen und in Stücke schneiden.</li>
<li>Mit Öl und Essig anmachen.</li>
<li>Mit Salz und Pfeffer abschmecken.</li>
</ol>
</main>
<footer>
<p>© 2025 Meine Lieblingsrezepte</p>
</footer>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Login</title>
</head>
<body>
<h1>Kundenkonto</h1><br>
<h2>Melden Sie sich bitte an</h2><br>
<form action="" method="GET">
<label for="email">E-Mail:</label>
<input type="email" name="email" id="email" required><br>
<label for="password">Passwort:</label>
<input type="password" name="password" id="password" required><br>
<button type="submit">Login</button>
</form>
</body>
</html>
<!--
Aufgabe 8
a)
Ja die Eingabe wurde als Query Parameter übernommen
Problematisch ist das, weil sowohl Passwort als auch Benutzername in der URL sichtbar sind (Klartext)
b)
Nein ich bekomme keine Meldung aber das Formular wird auch nicht abgesendet
c)
Ja, es erscheint die Nachricht "bitte füllen Sie dieses Feld aus"
-->

View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Obstebestellung</title>
</head>
<body>
<h1>Bestellen Sie sich Ihr Obst direkt nach Hause!</h1>
<form action="" method="GET">
<label for="obst">Obst:</label>
<input type="text" id="obst" name="obst" list="obstListe" required>
<datalist id="obstListe">
<option value="Apfel">
<option value="Banane">
<option value="Birne">
<option value="Kirsche">
<option value="Traube">
<option value="Pfirsich">
<option value="Mango">
<option value="Erdbeere">
</datalist>
<br><br>
<label for="number">Stückzahl:</label>
<input type="number" min="1" max="10" name="number" id="number">
<br><br>
<label for"color">Farbe:</label>
<input type="color">
<br><br>
<button type="submit">Bestellen</button>
</form>
</body>
</html>
<!--
Aufgabe 8
a) Ja, werden übernommen:
http://127.0.0.1:3000/web/04/labor/04_loesungen/obstbestellung.html?obst=Apfel&number=10
b) ja, ich erhalte aber nicht nur Vorschläge für den Anfangsbuchstaben
c) Ja, die Eingaben werden trotzdem übernommen
http://127.0.0.1:3000/web/04/labor/04_loesungen/obstbestellung.html?obst=Maracuja&number=2
d) Ich erhalte die Validierungsnachricht bereits vor dem senden
-->

View File

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Workshop-Anmeldung</title>
</head>
<body>
<h1>Workshopanmeldung</h1>
<form action="http://localhost:8080/registrierung" method="POST">
<fieldset>
<legend>Persönliche Angaben:</legend>
<label for="vorname">Vorname:</label><br>
<input type="text" id="vorname" name="vorname" placeholder="Vorname" required><br><br>
<label for="nachname">Nachname:</label><br>
<input type="text" id="nachname" name="nachname" placeholder="Nachname" required><br><br>
<label for="email">E-Mail:</label><br>
<input type="email" id="email" name="email" required><br><br>
<label for="handy">Handynummer:</label><br>
<input type="tel" id="handy" name="handy"><br>
</fieldset>
<br>
<fieldset>
<legend>Kursauswahl:</legend>
<label for="kurs">Kurs:</label><br>
<input type="text" id="kurs" name="kurs" value="Webentwicklung Basics" readonly><br><br>
<label for="session">Bevorzugte Session:</label><br>
<select id="session" name="session" size="4">
<option value="vormittag">Vormittag</option>
<option value="nachmittag">Nachmittag</option>
<option value="abend">Abend</option>
<option value="wochenende">Wochenende</option>
</select>
</fieldset>
<br>
<fieldset>
<legend>Zusätzliche Optionen:</legend>
<input type="checkbox" id="agb" name="agb" required>
<label for="agb">Ich akzeptiere die Teilnahmebedingungen.</label><br>
<input type="checkbox" id="newsletter" name="newsletter" value="ja">
<label for="newsletter">Newsletter abonnieren.</label><br>
<input type="checkbox" id="equipment" name="equipment" value="ja">
<label for="equipment">Ich benötige spezielles Equipment.</label>
</fieldset>
<br>
<fieldset>
<legend>Teilnahmeformat:</legend>
<input type="radio" id="online" name="format" value="online" required>
<label for="online">Online</label><br>
<input type="radio" id="praesenz" name="format" value="praesenz">
<label for="praesenz">Präsenz</label>
</fieldset>
<br>
<button type="submit">Jetzt anmelden</button>
</form>
</body>
</html>

View File

@ -0,0 +1,65 @@
1.1) Antonette
1.2) 10
1.3) sunt aut facere repellat provident occaecati excepturi optio reprehenderit
1.4) 5
1.5) Ja
1.6) curl https://jsonplaceholder.typicode.com/posts?userId=2
2.1)68eb4a0b-6c49-44e9-aec8-5af947d22141
curl https://hp-api.onrender.com/api/characters/staff
2.2) curl https://hp-api.onrender.com/api/character/68eb4a0b-6c49-44e9-aec8-5af947d22141
2.3) blond
3) siehe Datei staudenpflanzen.json
4.1)
{
"name": "Alex",
"alter": 30,
"wohnort": "Berlin"
}
4.2)
{
"produktname": "Kopfhörer",
"preis": 98.99,
"verfügbarkeit": "Ja",
"farben":["schwarz", "weiß"]
}
4.3)
{
"benutzername": "maria1999",
"passwort": "abc123",
"rolle": "Admin",
"adresse": {
"straße": "Bauernring 15",
"stadt": "Weilbach",
"plz": 12345
}
}
4.4)
[
{
"titel": "Task1",
"erledigt": true
},
{
"titel": "Task2",
"erledigt": false
}
]
4.5)
{
"titel": "Blabla",
"autor": "Blubb",
"inhalt": "Nix",
"kommentar": {
"autor": "Niemand",
"text": "Auch nix!"
}
}

View File

@ -0,0 +1,99 @@
{
"openapi": "3.0.0",
"info": {
"title": "Simple Greeting API",
"version": "1.0.0"
},
"servers": [
{
"url": "http://localhost:8080"
}
],
"paths": {
"/hello": {
"get": {
"parameters": [
{
"name": "name",
"in": "query",
"description": "Name",
"required": false,
"schema": {"type": "string"}
}
],
"summary": "Returns a greeting",
"responses": {
"200": {
"description": "Greeting response in plain text.",
"content": {
"text/plain": {
"schema": {
"type": "string"
},
"example": "Hello!"
}
}
}
}
},
"post": {
"requestBody":{
"required": true,
"content": {
"text/plain":{
"schema":{"type": "string"}
}
}
},
"summary": "Returns a plain text greeting",
"responses": {
"200": {
"description": "Plain text greeting response",
"content": {
"text/plain": {
"schema": {
"type": "string"
},
"example": "Hello!"
}
}
}
}
}
},
"/hello-json": {
"post": {
"summary": "Returns a greeting using a JSON body",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" }
},
"required": ["name", "age"]
},
"example": {
"name": "Florian",
"age": 23
}
}
}
},
"responses": {
"200": {
"description": "Greeting response in plain text",
"content": {
"text/plain": {
"schema": { "type": "string" },
"example": "Hello Florian, you are 23!" }
}
}
}
}
}
}
}

View File

@ -0,0 +1,30 @@
[
{
"_id": "6909f3da83629c03e8adedd7",
"name": "Lavendel",
"botanischer_name": "Lavandula angustifolia",
"standort": "Sonnig, trocken",
"besonderheiten": "Duftend, bienenfreundlich, winterhart"
},
{
"_id": "6909f3db83629c03e8adedd9",
"name": "Funkie",
"botanischer_name": "Hosta",
"standort": "Halbschatten bis Schatten",
"besonderheiten": "Dekoratives Laub, schneckenanfällig, robust"
},
{
"_id": "6909f3db83629c03e8adedda",
"name": "Sonnenhut",
"botanischer_name": "Echinacea purpurea",
"standort": "Sonnig",
"besonderheiten": "Heilpflanze, zieht Schmetterlinge, schneckenanfällig"
},
{
"_id": "6909f3dc83629c03e8adeddb",
"name": "Tränendes Herz",
"botanischer_name": "Lamprocapnos spectabilis",
"standort": "Halbschatten",
"besonderheiten": "Herzförmige Blüten, romantisch, giftig"
}
]

View File

@ -0,0 +1,72 @@
openapi: 3.0.0
info:
title: Workshop-Anmeldung API
version: 1.0.0
servers:
- url: http://localhost:8080
paths:
/registrierung:
post:
summary: Anmeldung zu einem Workshop
description: API für Anmeldedaten eines den Workshops.
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WorkshopForm'
application/json:
schema:
$ref: '#/components/schemas/WorkshopForm'
responses:
'200':
description: Erfolgreiche Anmeldung
'400':
description: Ungültige Eingabe
components:
schemas:
WorkshopForm:
type: object
properties:
vorname:
type: string
example: "Max"
nachname:
type: string
example: "Mustermann"
email:
type: string
format: email
example: "max@beispiel.de"
handy:
type: string
example: "+491751234567"
kurs:
type: string
example: "Webentwicklung Basics"
session:
type: string
enum: ["vormittag", "nachmittag", "abend", "wochenende"]
example: "abend"
agb:
type: string
enum: ["ja", "on"]
example: "on"
newsletter:
type: string
enum: ["ja", "on"]
example: "ja"
equipment:
type: string
enum: ["ja", "on"]
example: "ja"
format:
type: string
enum: ["online", "praesenz"]
example: "online"
required:
- vorname
- nachname
- email
- agb
- format

View File

@ -0,0 +1,79 @@
package main
import (
"encoding/json"
"fmt"
"os"
)
type Book struct {
ID int `json:"id"`
Titel string `json:"titel"`
Autor string `json:"autor"`
Read bool `json:"read"`
}
type Library struct {
Books []Book `json:"books"`
}
// fügt ein Buch der Library hinzu
func (l *Library) Add(titel, autor string) {
id := len(l.Books) + 1
newBook := Book{ID: id, Titel: titel, Autor: autor, Read: false}
l.Books = append(l.Books, newBook)
}
// Markiert ein Buch als gelesen
func (l *Library) Read(id int) {
for i := range l.Books {
if l.Books[i].ID == id {
l.Books[i].Read = true
}
}
}
// Listet alle Bücher auf
func (l *Library) List() {
if len(l.Books) == 0 {
fmt.Println("Keine Bücher vorhanden.")
return
}
for _, b := range l.Books {
status := "ungelesen"
if b.Read {
status = "gelesen"
}
fmt.Printf("%d: %s (%s) %s\n", b.ID, b.Titel, b.Autor, status)
}
}
// Liste als JSON speichern
func (l *Library) Save(filename string) error {
data, err := json.MarshalIndent(l, "", " ")
if err != nil {
return err
}
err = os.WriteFile(filename, data, 0644)
if err != nil {
return err
}
return nil
}
// JSON aus Datei laden
func Load(filename string) (*Library, error) {
data, err := os.ReadFile(filename)
if err != nil {
if os.IsNotExist(err) {
return &Library{}, nil
}
return nil, err
}
var l Library
jsonErr := json.Unmarshal(data, &l)
return &l, jsonErr
}

View File

@ -0,0 +1,22 @@
{
"books": [
{
"id": 1,
"titel": "Testbuch",
"autor": "Testautor",
"read": false
},
{
"id": 2,
"titel": "Test2",
"autor": "222",
"read": false
},
{
"id": 3,
"titel": "Test3",
"autor": "EEEE",
"read": false
}
]
}

View File

@ -0,0 +1,3 @@
module kommandozeilenprogramm
go 1.24.5

View File

@ -0,0 +1,73 @@
package main
// fmt für ausgaben, os für Kommandozeilenargumente, strconv um strings in ints umzuwandeln
import (
"fmt"
"os"
"strconv"
)
// prüfen, ob mind. 1 Kommando übergeben wurde
func main() {
if len(os.Args) < 2 {
fmt.Println("Bitte einen Befehl eingeben")
return
}
filename := "books.json"
library, err := Load(filename)
if err != nil {
fmt.Println("Fehler beim Laden der JSON-Datai:", err.Error())
return
}
switch os.Args[1] {
case "add":
// Wenn Argumente kleiner 4, Hilfe ausgeben
if len(os.Args) < 4 {
fmt.Println("Benutze: add / Titel / Autor ")
return
}
// sonst titel = Argument 2 und autor = Argument 3
titel := os.Args[2]
autor := os.Args[3]
library.Add(titel, autor)
if err := library.Save(filename); err != nil {
fmt.Println("Fehler beim Speichern:", err.Error())
return
}
fmt.Println("Buch hinzugefügt.")
case "list":
library.List()
case "read":
if len(os.Args) < 3 {
fmt.Println("Benutze: read / ID")
return
}
id, convErr := strconv.Atoi(os.Args[2])
if convErr != nil {
fmt.Println("Die ID muss eine Zahl sein.")
return
}
library.Read(id)
if err := library.Save(filename); err != nil {
fmt.Println("Fehler beim Speichern:", err.Error())
return
}
fmt.Println("Buch als gelesen markiert.")
default:
fmt.Println("Kein bekanntes Kommando(add/list/red")
}
}

View File

@ -0,0 +1,128 @@
package main
import (
"encoding/json"
"fmt"
"net/http"
)
// Struct Unmarshal, Felder müssen exportiert sein (Großbuchstabe) und opt. mit json Tag (8.2)
type WorkshopForm struct {
Vorname string `json:"vorname"`
Nachname string `json:"nachname"`
Email string `json:"email"`
Handy string `json:"handy"`
Kurs string `json:"kurs"`
Session string `json:"session"`
Agb string `json:"agb"`
Newsletter string `json:"newsletter"`
Equipment string `json:"equipment"`
Format string `json:"format"`
}
// Handler Funktion anlegen
// w = Antwort an Browser, r=Anfrage vom Client
func workshopHandler(w http.ResponseWriter, r *http.Request) {
// Prüfen auf POST, Fehler falls andere Methode
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// ließt den Body des Requests ein und befüllt FormValue(), sofern keine Fehler auftauchen
err := r.ParseForm()
if err != nil {
http.Error(w, "Fehler beim Einlesen des Formulars", http.StatusBadRequest)
return
}
// Wenn Felder die als required markiert wurden leer sind: Fehlermeldung
vorname := r.FormValue("vorname")
if vorname == "" {
http.Error(w, "Vorname fehlt", http.StatusBadRequest)
return
}
nachname := r.FormValue("nachname")
if nachname == "" {
http.Error(w, "Nachname fehlt", http.StatusBadRequest)
return
}
email := r.FormValue("email")
if email == "" {
http.Error(w, "E-Mail fehlt", http.StatusBadRequest)
return
}
handy := r.FormValue("handy")
// Checkboxen auslesen
agb := r.FormValue("agb")
if agb == "" {
http.Error(w, "AGBs müssen akzeptiert werden", http.StatusBadRequest)
return
}
// newsletter und equipment beliben leer, wenn nicht angehakt
newsletter := r.FormValue("newsletter")
equipment := r.FormValue("equipment")
// Radio Buttons
format := r.FormValue("format")
if format == "" {
http.Error(w, "Wählen sie ein Kursformat", http.StatusBadRequest)
return
}
// Dropdown
session := r.FormValue("session")
if session == "" {
http.Error(w, "Wählen sie eine Zeit aus", http.StatusBadRequest)
return
}
fmt.Println("Vorname: ", vorname)
fmt.Println("Nachname: ", nachname)
fmt.Println("E-Mail: : ", email)
fmt.Println("Telefon: ", handy)
fmt.Println("Newsletter:", newsletter)
fmt.Println("Equipment:", equipment)
fmt.Println("Format:", format)
fmt.Println("Session:", session)
fmt.Fprintln(w, "POST Request funktioniert")
}
// Erweiterung um Json Daten zu empfangen (Aufgabe 8.2)
func jsonHandler(w http.ResponseWriter, r *http.Request) {
//Nur POST
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// lesen und unmarshal
// Variable für die Daten aus der Form
var workshopForm WorkshopForm
// Prüfung auf gültiges json, falls Fehler 400
err := json.NewDecoder(r.Body).Decode(&workshopForm)
if err != nil {
http.Error(w, "Json ungültig", http.StatusBadRequest)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(workshopForm)
}
func main() {
// Anfrage an Pfad in HTML /registrierung, worshop Handler wird aufgerufen
http.HandleFunc("/registrierung", workshopHandler)
http.HandleFunc("/registrierung-json", jsonHandler)
fmt.Println("Server läuft auf http://localhost:8080")
http.ListenAndServe(":8080", nil)
}

View File

@ -0,0 +1,110 @@
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("hello world")
fmt.Println("go" + "lang")
fmt.Println("1+1=", 1+1)
fmt.Println("7.0/3.0 =", 7.0/3.0)
fmt.Println("True && False", true && false)
fmt.Println("True || False", true || false)
fmt.Println(!true)
/* hello world
golang
1+1= 2
7.0/3.0 = 2.3333333333333335
True && False false
True || False true
false */
var a = "initial"
var b, c int = 1, 2
var d = true
var e int
// shorthand für Deklaration + Initialisierung
f := "apple"
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
fmt.Println(e)
fmt.Println(f)
// initial , 1, 2, true, 0, apple
fmt.Println("---------------------------------")
constants()
fmt.Println("---------------------------------")
fors()
fmt.Println("---------------------------------")
}
const s string = "constant"
func constants() {
fmt.Println(s)
const n = 500000000
const d = 3e20 / n
fmt.Println(int64(d))
fmt.Println(math.Sin(n))
// constant,600000000000,-0.28470407323754404
}
func fors() {
i := 1
for i <= 3 {
fmt.Println(i)
i = i + 1
//123
}
fmt.Println()
for j := 0; j < 3; j++ {
fmt.Println(j)
//0 1 2
}
fmt.Println()
for i := range 3 {
fmt.Println("range", i)
}
fmt.Println()
for {
fmt.Println("loop")
break
}
fmt.Println()
for n := range 6 {
if n%2 == 0 {
continue
}
fmt.Println(n)
}
}

View File

@ -0,0 +1,5 @@
module kekse
go 1.24.5
require github.com/google/uuid v1.6.0

View File

@ -0,0 +1,2 @@
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=

View File

@ -0,0 +1,68 @@
package main
import (
"fmt"
"net/http"
"github.com/google/uuid"
)
// create Cookie HTTP Handler
func createHandler(w http.ResponseWriter, r *http.Request) {
//UUID erzeugen
id := uuid.NewString()
// Keks erstellen
cookie := &http.Cookie{
Name: "keks",
Value: id,
Path: "/",
}
// keks setzten
http.SetCookie(w, cookie)
// Ausgabe Browser
fmt.Fprintf(w, "Keks erstellt: %s\n", id)
}
// show Cookie, falls vorhanden
func showHandler(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("keks")
if err != nil {
fmt.Fprintln(w, "Kein Cookie vorhanden")
return
}
fmt.Fprintf(w, "Keks gefunden: %s\n", cookie.Value)
}
// delete Cookie
func deleteHandler(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("keks")
if err != nil {
http.Error(w, "Kein Cookie gefunden, löschen nicht möglich", http.StatusBadRequest)
return
}
// Maxage - 1 löscht Cookie
cookie.MaxAge = -1
// schickt neuen Set Cookie Header an Browser
http.SetCookie(w, cookie)
fmt.Fprintln(w, "Cookie gelöscht")
}
func main() {
// Endpunkte registrieren
http.HandleFunc("/create-cookie", createHandler)
http.HandleFunc("/show-cookie", showHandler)
http.HandleFunc("/delete-cookie", deleteHandler)
fmt.Println("Server läuft auf http://localhost:8080")
http.ListenAndServe(":8080", nil)
}

View File

@ -0,0 +1,128 @@
package main
import (
"encoding/json"
"fmt"
"net/http"
)
// Struct Unmarshal, Felder müssen exportiert sein (Großbuchstabe) und opt. mit json Tag (8.2)
type WorkshopForm struct {
Vorname string `json:"vorname"`
Nachname string `json:"nachname"`
Email string `json:"email"`
Handy string `json:"handy"`
Kurs string `json:"kurs"`
Session string `json:"session"`
Agb string `json:"agb"`
Newsletter string `json:"newsletter"`
Equipment string `json:"equipment"`
Format string `json:"format"`
}
// Handler Funktion anlegen
// w = Antwort an Browser, r=Anfrage vom Client
func workshopHandler(w http.ResponseWriter, r *http.Request) {
// Prüfen auf POST, Fehler falls andere Methode
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// ließt den Body des Requests ein und befüllt FormValue(), sofern keine Fehler auftauchen
err := r.ParseForm()
if err != nil {
http.Error(w, "Fehler beim Einlesen des Formulars", http.StatusBadRequest)
return
}
// Wenn Felder die als required markiert wurden leer sind: Fehlermeldung
vorname := r.FormValue("vorname")
if vorname == "" {
http.Error(w, "Vorname fehlt", http.StatusBadRequest)
return
}
nachname := r.FormValue("nachname")
if nachname == "" {
http.Error(w, "Nachname fehlt", http.StatusBadRequest)
return
}
email := r.FormValue("email")
if email == "" {
http.Error(w, "E-Mail fehlt", http.StatusBadRequest)
return
}
handy := r.FormValue("handy")
// Checkboxen auslesen
agb := r.FormValue("agb")
if agb == "" {
http.Error(w, "AGBs müssen akzeptiert werden", http.StatusBadRequest)
return
}
// newsletter und equipment beliben leer, wenn nicht angehakt
newsletter := r.FormValue("newsletter")
equipment := r.FormValue("equipment")
// Radio Buttons
format := r.FormValue("format")
if format == "" {
http.Error(w, "Wählen sie ein Kursformat", http.StatusBadRequest)
return
}
// Dropdown
session := r.FormValue("session")
if session == "" {
http.Error(w, "Wählen sie eine Zeit aus", http.StatusBadRequest)
return
}
fmt.Println("Vorname: ", vorname)
fmt.Println("Nachname: ", nachname)
fmt.Println("E-Mail: : ", email)
fmt.Println("Telefon: ", handy)
fmt.Println("Newsletter:", newsletter)
fmt.Println("Equipment:", equipment)
fmt.Println("Format:", format)
fmt.Println("Session:", session)
fmt.Fprintln(w, "POST Request funktioniert")
}
// Erweiterung um Json Daten zu empfangen (Aufgabe 8.2)
func jsonHandler(w http.ResponseWriter, r *http.Request) {
//Nur POST
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// lesen und unmarshal
// Variable für die Daten aus der Form
var workshopForm WorkshopForm
// Prüfung auf gültiges json, falls Fehler 400
err := json.NewDecoder(r.Body).Decode(&workshopForm)
if err != nil {
http.Error(w, "Json ungültig", http.StatusBadRequest)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(workshopForm)
}
func main() {
// Anfrage an Pfad in HTML /registrierung, worshop Handler wird aufgerufen
http.HandleFunc("/registrierung", workshopHandler)
http.HandleFunc("/registrierung-json", jsonHandler)
fmt.Println("Server läuft auf http://localhost:8080")
http.ListenAndServe(":8080", nil)
}

View File

@ -0,0 +1,92 @@
openapi: 3.0.0
info:
title: Workshop-Anmeldung API
version: 1.0.0
servers:
- url: http://localhost:8080
paths:
/registrierung:
post:
summary: Anmeldung zu einem Workshop (Formular)
description: API für Anmeldedaten eines Workshops per HTML-Formular.
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WorkshopForm'
responses:
'200':
description: Erfolgreiche Anmeldung (Formulardaten angenommen)
'400':
description: Ungültige Eingabe (fehlende oder fehlerhafte Formulardaten)
/registrierung-json:
post:
summary: Anmeldung zu einem Workshop (JSON)
description: API für Anmeldedaten eines Workshops im JSON-Format.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WorkshopForm'
responses:
'200':
description: Erfolgreiche Anmeldung (JSON-Daten zurückgegeben)
content:
application/json:
schema:
$ref: '#/components/schemas/WorkshopForm'
'400':
description: Ungültige JSON-Eingabe
components:
schemas:
WorkshopForm:
type: object
properties:
vorname:
type: string
example: "Max"
nachname:
type: string
example: "Mustermann"
email:
type: string
format: email
example: "max@beispiel.de"
handy:
type: string
example: "+491751234567"
kurs:
type: string
example: "Webentwicklung Basics"
session:
type: string
enum: ["vormittag", "nachmittag", "abend", "wochenende"]
example: "abend"
agb:
type: string
enum: ["ja", "on"]
example: "on"
newsletter:
type: string
enum: ["ja", "on"]
example: "ja"
equipment:
type: string
enum: ["ja", "on"]
example: "ja"
format:
type: string
enum: ["online", "praesenz"]
example: "online"
required:
- vorname
- nachname
- email
- agb
- format

View File

@ -0,0 +1,24 @@
package main
import (
"fmt"
"net/http"
)
// Handler Funktion login
func loginHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Sie sind eingeloggt")
}
// Handler Funktion Logout
func logoutHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Sie sind ausgeloggt")
}
func main() {
http.HandleFunc("/login", loginHandler)
http.HandleFunc("/logout", logoutHandler)
http.ListenAndServe(":8080", nil)
}

View File

@ -0,0 +1,92 @@
########################################
# AUFGABE 1 Routing (/login, /logout)
# Server vorher starten im Routing-Ordner:
# cd /workspaces/lab-development-imb/web/08/labor/08_loesungen/Routing
# go run main.go
########################################
# Login testen
curl 'http://localhost:8080/login'
# Logout testen
curl 'http://localhost:8080/logout'
########################################
# AUFGABE 2 JSON-Daten empfangen
# Server vorher starten im JSON-Ordner:
# cd "/workspaces/lab-development-imb/web/08/labor/08_loesungen/JSONEmpfangen"
# go run main.go
########################################
# 2.1 Formular-Endpunkt /registrierung
# Erfolgreicher POST mit Formulardaten (Status 200)
curl -X POST 'http://localhost:8080/registrierung' \
-d 'vorname=Max' \
-d 'nachname=Mustermann' \
-d 'email=max@example.com' \
-d 'handy=01701234567' \
-d 'kurs=Webentwicklung Basics' \
-d 'format=online' \
-d 'session=abend' \
-d 'agb=on'
# Fehlerfall provozieren (z.B. Vorname fehlt → Status 400)
curl -X POST 'http://localhost:8080/registrierung' \
-d 'nachname=Mustermann' \
-d 'email=max@example.com' \
-d 'format=online' \
-d 'session=abend' \
-d 'agb=on'
# 2.2 JSON-Endpunkt /registrierung-json
# Erfolgreicher JSON-POST (Status 200, JSON wird zurückgegeben)
curl -X POST 'http://localhost:8080/registrierung-json' \
-H 'Content-Type: application/json' \
-d '{
"vorname": "Max",
"nachname": "Mustermann",
"email": "max@example.com",
"handy": "01701234567",
"kurs": "Webentwicklung Basics",
"session": "abend",
"agb": "on",
"newsletter": "ja",
"equipment": "ja",
"format": "online"
}'
# Fehlerfall: ungültiges JSON (Status 400, "Json ungültig")
curl -X POST 'http://localhost:8080/registrierung-json' \
-H 'Content-Type: application/json' \
-d 'ich bin kein gültiges json'
########################################
# AUFGABE 3 Cookies mit UUID
# Server vorher starten im Cookies-Ordner:
# cd /workspaces/lab-development-imb/web/08/labor/08_loesungen/Cookies
# go run main.go
########################################
# 3.1 Cookie erzeugen (/create-cookie)
# Setzt Cookie "keks=<UUID>" und zeigt die UUID an.
# Gleichzeitig speichern wir das Cookie in cookies.txt
curl -i --cookie-jar cookies.txt 'http://localhost:8080/create-cookie'
# 3.2 Cookie anzeigen (/show-cookie)
# Liest Cookie "keks" aus cookies.txt und zeigt den Wert an.
curl -i --cookie cookies.txt 'http://localhost:8080/show-cookie'
# 3.3 Cookie löschen (/delete-cookie)
# Setzt MaxAge = -1 und löscht den Cookie.
curl -i --cookie cookies.txt 'http://localhost:8080/delete-cookie'
# 3.4 Optional: prüfen, dass er wirklich weg ist
curl -i --cookie cookies.txt 'http://localhost:8080/show-cookie'
# Erwartet: "Kein Cookie vorhanden"

View File

@ -0,0 +1,20 @@
// Produktarray
const produkte = [
{ produkt: "Joghurt", preis: 2.49 },
{ produkt: "Brot", preis: 3.29 },
{ produkt: "Käse", preis: 8.99 },
{ produkt: "Duschgel", preis: 2.79 }
];
// neues Array
const rabattProdukte = produkte.map(p => {
return {
produkt: p.produkt,
preis: (p.preis * 0.9).toFixed(2) // Preis um 10% reduziert und gerundet
};
});
// Ausgabe
console.log(rabattProdukte);

View File

@ -0,0 +1,5 @@
module db_insert
go 1.24.5
require github.com/lib/pq v1.10.9

View File

@ -0,0 +1,2 @@
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=

View File

@ -0,0 +1,166 @@
package main
import (
"database/sql"
"fmt"
"log"
"net/http"
"strings"
_ "github.com/lib/pq"
)
// INSERT
type insertHandler int
func (ihandler insertHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// auf Post prüfen
if r.Method != http.MethodPost {
http.Error(w, "Nur Post ist erlaubt", http.StatusMethodNotAllowed)
return
}
//Formulardaten einlesen
err := r.ParseForm()
if err != nil {
http.Error(w, "gesendetes Formular ungültig", http.StatusBadRequest)
return
}
name := r.FormValue("name")
alter := r.FormValue("alter")
hobbies := r.Form["hobby"]
// alter und name sollten vorhanden sein
if name == "" {
http.Error(w, "Name fehlt", http.StatusBadRequest)
return
}
if alter == "" {
http.Error(w, "Alter fehlt", http.StatusBadRequest)
return
}
// Hobbies mit Komma separiert zusammenfügen
alleHobbies := strings.Join(hobbies, ", ")
//DB Verbindung öffnen
connStr := "user=devuser password=devpass dbname=devdb host=localhost port=5432 sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Println("Datenbank nicht erreichbar", err)
http.Error(w, "Server Fehler", http.StatusInternalServerError)
return
}
defer db.Close()
//Verbindung testen
err = db.Ping()
if err != nil {
log.Println("Datenbank nicht erreichbar", err)
http.Error(w, "Interner Server Error", http.StatusInternalServerError)
return
}
log.Println("Verbindung erfolgreich hergestellt")
//Insert
query := `INSERT INTO personen (name, hobbies, alter) VALUES ($1, $2, $3)`
_, err = db.Exec(query, name, alleHobbies, alter)
if err != nil {
log.Println("Fehler beim Einfügen der Daten", err)
http.Error(w, "Interner Server Fehler", http.StatusInternalServerError)
return
}
fmt.Fprintln(w, "Datensatz erfolgreich eingefügt")
}
// UPDATE
type updateHandler int
func (uhandler updateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// nur POST erlauben
if r.Method != http.MethodPost {
http.Error(w, "Nur Post ist erlaubt", http.StatusMethodNotAllowed)
return
}
// Formulardaten einlesen
err := r.ParseForm()
if err != nil {
http.Error(w, "gesendetes Formular ungültig", http.StatusBadRequest)
return
}
name := r.FormValue("name")
alter := r.FormValue("alter")
hobbies := r.Form["hobby"]
if name == "" {
http.Error(w, "Name fehlt", http.StatusBadRequest)
return
}
if alter == "" {
http.Error(w, "Alter fehlt", http.StatusBadRequest)
return
}
// Hobbies zusammenfügen
alleHobbies := strings.Join(hobbies, ", ")
// DB-Verbindung
connStr := "user=devuser dbname=devdb host=localhost port=5432 sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Println("Datenbank nicht erreichbar", err)
http.Error(w, "Server Fehler", http.StatusInternalServerError)
return
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Println("Datenbank nicht erreichbar", err)
http.Error(w, "Interner Server Fehler", http.StatusInternalServerError)
return
}
// Update-Query
query := `UPDATE personen SET hobbies = $1, alter = $2 WHERE name = $3`
res, err := db.Exec(query, alleHobbies, alter, name)
if err != nil {
log.Println("Fehler beim Update", err)
http.Error(w, "Interner Server Fehler", http.StatusInternalServerError)
return
}
rowsAffected, _ := res.RowsAffected()
if rowsAffected == 0 {
http.Error(w, "Kein Datensatz mit diesem Namen gefunden", http.StatusNotFound)
return
}
fmt.Fprintln(w, "Datensatz erfolgreich aktualisiert")
}
func main() {
var ihandler insertHandler
var uhandler updateHandler
http.Handle("/insert", ihandler) // Insert-Endpunkt
http.Handle("/update", uhandler) // Update-Endpunkt
log.Println("Server startet auf http://localhost:8080")
log.Fatal(http.ListenAndServe("localhost:8080", nil))
}

View File

@ -0,0 +1,9 @@
const zahlen = [38, 0, 226, 384, 111, 500383];
for (let i = 0; i < zahlen.length; i++){
if (zahlen[i] === 0){
console.log("Null");
} else {
console.log(zahlen[i] % 2 === 0 ? "Gerade Zahl" : "Ungerade Zahl")
}
}

View File

@ -0,0 +1,20 @@
const headline = document.getElementById("headline");
const adventButton = document.getElementById("adventButton");
const imageContainer = document.getElementById("imageContainer")
adventButton.addEventListener("click", () =>{
//Überschrift ändern
headline.textContent = "Einen fröhlichen ersten Advent";
//Adventskranz erscheint
const img = document.createElement("img");
img.src ="Adventskranz.png";
img.alt = "Adventskranz";
imageContainer.appendChild(img);
//Button verschwindet
adventButton.style.display="none";
})

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="de">
<head>
<title>Advent</title>
<meta charset="utf-8">
</head>
<body>
<h1 id="headline">Alle Jahre wieder...</h1>
<button id="adventButton">Erste 🕯️ anzünden</button>
<div id="imageContainer"></div>
<script src="01.js"></script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

View File

@ -0,0 +1,44 @@
const helden = {
"Chase": "Chase ist auf Spur!",
"Marshall": "Ich bin startklar!",
"Skye": "Diese Pfote hebt ab!",
"Rocky": "Wegwerfen? Kommt nicht in die Tüte!",
"Rubble": "Rubble ist zur Stelle!",
"Zuma": "Los gehts ins Wasser!",
"Everest": "Eis und Schnee ich bin bereit!",
"Tracker": "Ich höre alles!",
};
//
const formular = document.getElementById("pawFormular");
const meldung = document.getElementById("meldung");
const spruch = document.getElementById("spruch");
const name = document.getElementById("name");
formular.addEventListener("submit", ev =>{
ev.preventDefault(); // verhindert neuladen
const eingabe = name.value.trim();
let gefunden = false;
for(let h in helden){
if(h.toLowerCase() === eingabe.toLowerCase()){
gefunden = true;
break
}
}
if(!eingabe || !gefunden){
meldung.textContent = "Bitte gib einen echten Paw Patrol Helden an";
spruch.textContent = "";
return;
}
meldung.textContent = "Gute Wahl " + eingabe + " ist dabei!";
spruch.textContent = helden[eingabe];
});

View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Paw Patrol - Helfer auf vier Pfoten</title>
</head>
<body>
<h1>Lieblings-Fellfreund</h1>
<form id="pawFormular">
<label for="name">Gib hier den Namen ein: </label>
<input type="text" id="name" name="fellfreund">
<button type="submit">Spruch ausgeben</button>
</form>
<p id="meldung"></p>
<h2 id="spruch"></h2>
<script src="paw.js"></script>
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Buntes HTML</title>
</head>
<body>
<h1>Jetzt wird es bunt</h1>
<h2>Alles in Blau-Tönen</h2>
<span id="dark">Dieser Text ist darkblue.</span>
<br>
<span id="light">Dieser Text ist lightskyblue.</span>
<h2>Alles in Violett-Tönen</h2>
<p class="pastell">Dieser Absatz ist pink.</p>
<p class="neon">Dieser Absatz ist magenta.</p>
<h2>Alles in Grün-Tönen</h2>
<p class="frosch">
<span class="blatt">Hier ist alles greenyellow.</span>
<br>
<br>
<span class="blatt">Auch der Bereich zwischen dem Text.</span>
</p>
</body>
</html>

View File

@ -0,0 +1,32 @@
body{
background-color: slateblue;
}
h1{
color: lightcoral;
}
h2{
color: whitesmoke;
}
#dark{
color: darkblue;
}
#light{
color: lightskyblue;
}
.pastell{
color: pink;
}
.neon{
color: magenta;
}
.frosch{
color: greenyellow;
background-color: greenyellow;
}

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Colors</title>
</head>
<body>
<input type="color" id="color" name="color">
<label for="color">Farbauswahl</label>
<script src="color.js"></script>
</body>
</html>

View File

@ -0,0 +1,12 @@
const colorInput = document.getElementById("color");
colorInput.addEventListener("input", ev =>{
const colorSelected = ev.target.value;
document.body.style.backgroundColor = colorSelected;
alert("Ihre Farbwahl: " + colorSelected);
});

View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tagesschau - Maschinenbau-Bilanz</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<p class="headline">Schlechte Jahresbilanz</p>
<h1>Maschinenbauer warnen die Politik</h1>
<p class="meta">Stand: 09.12.2025 12:32 Uhr</p>
<p class="summary">Der Branchenverband der Maschinenbauer zieht eine schlechte Jahresbilanz 2025. Der VDMA verlangtReformen. Sonst
würden noch mehr Unternehmen abwandern. Vor allem der Mittelstand leidet unter den Standortbedingungen.</p>
<p class="meta">Von Axel J, SWR</p>
<p>
Julia Schnitzler schaut von ihrem Büro auf die Landstraße, die direkt an ihrem Unternehmen entlang führt. Von
hier
aus gehen die Spezialanlagen des Herstellers Strassburger Filter in alle Welt. Julia Schnitzler ist hier
geschäftsführende Gesellschafterin.
</p>
<p>"Wir sind aufgrund unserer Expertise international führend, aber es wird immer
schwerer. Der Standort Deutschland macht uns zu schaffen. Auch international wird das Geschäftsklima immer
rauer",
fasst die Geschäftsfrau ein ernüchterndes Jahr zusammen. "Unsere Exporte sind um mehr als zehn Prozent
zurückgegangen." Die Firma fertigt Filtrationssysteme für die Bereiche Pharma, Chemie und Kosmetik. Die Exporte
gehen vor allem nach Südostasien oder auch nach Nordamerika.
</p>
<h2>Druck durch chinesische Konkurrenz</h2>
<p>Im rheinhessischen Westhofen hat der Betrieb 50 Angestellte. Auch im chinesischen
Shanghai arbeiten zwei Spezialisten für das deutsche Unternehmen. China war lange ein starker Markt für den
deutschen Filterbauer. "Das hat sich geändert: Die Nachfrage ist zurückgegangen. Es gibt immer mehr chinesische
Wettbewerber, die in ihrem heimischen Markt bevorzugt werden", sagt Schnitzler. Qualitativ sei man noch ein
gutes
Stück voraus. Dafür seien die Chinesen bei den Preisen kaum noch zu schlagen. "Chinesische Firmen haben viel
niedrigere Energiepreise. Auch deshalb bieten sie Produkte an, die teils bis zu 75 Prozent billiger als unsere
Anlagen sind."</p>
<p>Die US-Zölle verschärften die Krise. "Dadurch wird alles noch komplizierter - und unsicherer. Viele
unserer Kunden warten erstmal ab. Wer weiß schon, was sich morgen wieder ändert." Pläne zur Verlagerung des
Betriebes in die USA habe sie nicht. Aber Schnitzler stellt fest: "Es wird einem in den USA aufgrund der neuen
Gesetzeslage inzwischen sehr einfach gemacht, eine Niederlassung zu gründen."
</p>
<p>Daheim setzen der Firma die
Standortbedingungen immer mehr zu. Vor allem die fehlenden Fachkräfte sind ein Problem. Beim Thema
Bürokratieabbau
schüttelt Julia Schnitzler fast schon resigniert den Kopf. "Alle reden davon, aber es wird immer mehr. Ständig
gibt
es neue Richtlinien", sagt die geschäftsführende Gesellschafterin "Ein Beispiel: Wenn wir ein bestimmtes Bauteil
in
einen Filter verbauen, ist das für die Verwaltung eine Kleinigkeit. Liefern wir es aber als Ersatzteil separat
aus,
entsteht ein enormer Dokumentationsaufwand. Das kostet Zeit, bindet Mitarbeiter und wird immer teurer. Dieses
Geld
fehlt dann woanders."
</p>
<p class="meta"><span class="source">Quelle</span>: www.tagesschau.de, abgerufen am 9.12.2025</p>
</body>
</html>

View File

@ -0,0 +1,26 @@
html {
font-size: 16px;
}
body {
font-family: 'Open Sans', sans-serif;
}
h1, h2 {
color: #005CA9;
}
.headline {
font-size: 0.8rem;
color: darkgray;
}
.meta {
font-size: 0.7rem;
font-style: italic;
color: lightgray;
}
.source {
text-decoration: underline;
}

View File

@ -0,0 +1,43 @@
1. Termine:
Hintergrundfarbe: keine
Schriftfarbe: standard (schwarz)
Unterstrichen? nein
2. 10k-Lauf:
Hintergrundfarbe: orange
Schriftfarbe: yellowgreen
Unterstrichen? nein
3. Elternabend:
Hintergrundfarbe: red
Schriftfarbe: yellowgreen
Unterstrichen? ja!
4. Wocheneinkauf:
Hintergrundfarbe: orange
Schriftfarbe: purple
Unterstrichen? nein
5. Yoga:
Hintergrundfarbe: orange
Schriftfarbe: purple
Unterstrichen?
6. Handball-Training:
Hintergrundfarbe: blue
Schriftfarbe: white
Unterstrichen? nein
7. Mathearbeit:
Hintergrundfarbe: blue
Schriftfarbe: white
Unterstrichen? nein
8. Fußball-Training:
Hintergrundfarbe: blue
Schriftfarbe: violet
Unterstrichen? nein
9. FCB vs. Eintracht:
Hintergrundfarbe: orange
Schriftfarbe: turquoise
Unterstrichen? nein
10. Pizza-Tag!:
Hintergrundfarbe: keine
Schriftfarbe: brown
Unterstrichen? nein
*Hintergrundfarbe*, *Schriftfarbe* und *unterstrichen/nicht unterstrichen*

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -0,0 +1,115 @@
.styled-select {
appearance: none;
}
.styled-checkbox {
appearance: none;
width: 1.2rem;
height: 1.2rem;
border: 1px solid #000000;
border-radius: 4px;
background-color: #ffffff;
/* richtet sich mittig zur Textzeile/Nachbarelementen aus */
vertical-align: middle;
/* dient als Anker für absolute Kinder */
position: relative;
}
.styled-checkbox:checked {
background-color: #000000;
border-color: #ffffff;
}
.styled-checkbox:checked::after {
/* Häkchen-Symbol */
content: "\2713";
color: #ffffff;
font-size: 1rem;
/* Position relativ zum nächsten positionierten Eltern-Element */
position: absolute;
/* obere Kante in die Mitte (50%) des Eltern-Elements setzen */
top: 50%;
/* linke Kante in die Mitte (50%) des Eltern-Elements setzen */
left: 50%;
/* sich selbst um 50% der eigenen Breite/Höhe zurückschieben → exakt zentriert */
transform: translate(-50%, -50%);
}
.styled-radio {
appearance: none;
width: 1.2rem;
height: 1.2rem;
border: 1px solid #000;
border-radius: 50%;
background-color: #ffffff;
/* richtet sich mittig zur Textzeile/Nachbarelementen aus */
vertical-align: middle;
/* dient als Anker für absolute Kinder */
position: relative;
}
.styled-radio:checked {
border-color: #ffffff;
background-color: #000000;
}
.styled-radio:checked::after {
content: "";
width: 0.5rem;
height: 0.5rem;
background-color: #ffffff;
border-radius: 50%;
/* Position relativ zum nächsten positionierten Eltern-Element */
position: absolute;
/* obere Kante in die Mitte (50%) des Eltern-Elements setzen */
top: 50%;
/* linke Kante in die Mitte (50%) des Eltern-Elements setzen */
left: 50%;
/* sich selbst um 50% der eigenen Breite/Höhe zurückschieben → exakt zentriert */
transform: translate(-50%, -50%);
}
html {
font-size: 18px;
font-style: oblique;
font-family: 'Courier New', Courier, monospace;
}
body{
background-image: url(img/background.jpg);
background-position: center;
background-size: cover;
margin: 20px;
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-right: 2rem;
}
h1 {
margin: 20px;
padding: 20px;
}
legend {
font-weight: bold;
font-size: 1.2rem;
}
fieldset {
border-color: #1440a2;
}
form{
backdrop-filter: blur;
}

View File

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="styles_workshop.css">
<title>Workshop-Anmeldung</title>
</head>
<body>
<h1>Workshop-Anmeldung</h1>
<form action="https://web-637691723779.europe-west2.run.app/registrierung" method="post">
<fieldset>
<legend>Persönliche Angaben:</legend>
<label for="vorname">Vorname:</label><br>
<input type="text" name="vorname" id="vorname" placeholder="Vorname" required><br>
<label for="nachname">Nachname:</label><br>
<input type="text" name="nachname" id="nachname" placeholder="Nachname" required><br>
<label for="email">E-Mail:</label><br>
<input type="email" name="email" id="email" autocomplete="email"><br>
<label for="telefon">Handynummer:</label><br>
<input type="tel" name="telefon" id="telefon" pattern="^01[5-7][0-9]{7,10}$"><br><br>
</fieldset>
<fieldset>
<legend>Kursauswahl:</legend>
<label for="kurs">Kurs:</label><br>
<input type="text" name="kurs" id="kurs" value="Webentwicklung Basics" readonly disabled><br><br>
<label for="sessions">Bevorzugte Sessions:</label><br>
<select id="sessions" name="sessions" class="styled-select" multiple size="4">
<option value="vormittag">Vormittag</option>
<option value="nachmittag">Nachmittag</option>
<option value="abendsession">Abend</option>
<option value="wochenende">Wochenende</option>
</select><br>
</fieldset>
<fieldset>
<legend>Zusätzliche Optionen:</legend>
<input type="checkbox" id="agb" name="agb" class="styled-checkbox" required>
<label for="agb">Ich akzeptiere die Teilnahmebedingungen.</label><br>
<input type="checkbox" id="newsletter" name="newsletter" value="ja" class="styled-checkbox" >
<label for="newsletter">Newsletter abonnieren.</label><br>
<input type="checkbox" id="equipment" name="equipment" value="ja" class="styled-checkbox" >
<label for="equipment">Ich benötige spezielles Equipment.</label><br>
</fieldset>
<fieldset>
<legend>Teilnahmeformat:</legend>
Format wählen:<br>
<input type="radio" id="online" name="format" value="online" class="styled-radio" required>
<label for="online">Online</label><br>
<input type="radio" id="praesenz" name="format" value="praesenz" class="styled-radio">
<label for="praesenz">Präsenz</label><br>
</fieldset>
<br>
<input type="submit" value="Jetzt anmelden">
</form>
</body>
</html>

View File

@ -0,0 +1,37 @@
<!DOcTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" method="POST">
<title>Anamesebogen</title>
</head>
<body>
<h1>Anamesebogen</h1>
<h2>Bitte ausfüllen</h2>
<form>
<fieldset>
<legend>Persönliches</legend>
<label for="name">Name:</label>
<input type="text" name="name" id="name" required><br><br>
<label for="vorname">Vorname:</label>
<input type="text" name="vorname" id="vorname" required><br><br>
<label for="gebdatum">Geburtsdatum</label>
<input type="date" name="gebdatum" id="gebdatum" required><br><br>
<label for="gender">Geschlecht</label>
<select name="gender" id="gender" required><br><br>
<option value="Weiblich">weiblich</option>
<option value="männlich">männlich</option>
<option value="divers">divers</option>
<option value="ka">keine Angabe</option>
</select>
</fieldset>
<fieldset>
<legend>Körperdaten</legend>
<label for="gewicht">Gewicht (kg):</label>
<input type="number" name="gewicht" id="gewicht"><br><br>
<label for="groesse">Größe (cm):</label>
<input type="number" name="groesse" id="groesse"><br><br>
</fieldset>
<button type="submit">Absenden</button>
</form>
</body>
</html>

View File

@ -0,0 +1,62 @@
package main
import (
"encoding/json"
"net/http"
"time"
)
// ist ein Struct sowas wie eine Klasse in Java ?
type Klient struct {
Name string `json:"name"`
Vorname string `json:"vorname"`
Gebdatum time.Time `json:"gebdatum"`
Geschlecht string `json:"gender"`
Gewicht int `json:"gewicht"`
Groesse int `json:"groesse"`
}
func anameseHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Methode ungültig", http.StatusMethodNotAllowed)
return
}
// ist ka dann eine Art Objekt von der Klasse KLient?
var k Klient
err := json.NewDecoder(r.Body).Decode(&k)
if err != nil {
http.Error(w, "Kein gültiges Json", http.StatusBadRequest)
return
}
if k.Name == "" || k.Vorname == "" || k.Geschlecht == "" {
http.Error(w, "Pflichtfelder sind leer", http.StatusBadRequest)
return
}
if k.Gebdatum.IsZero() {
http.Error(w, "Geburtsdatum fehlt", http.StatusBadRequest)
return
}
if k.Gewicht == 0 || k.Groesse == 0 {
warnings = append(warnings, "BMI kann nicht berechnet werden")
}
// Erfolg und Warnung zurückgeben wnn genu wird die response varibale genutzt?
response := map[string]interface{}{
"message:": "Klient erfolgreich angelegt",
"warnings": warnings,
}
//ok response habe ich hier gefunden, aber den Rest dieses Codes verstehe ich gerade nich
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(response)
}
func main() {
}

View File

@ -0,0 +1,45 @@
openapi: 3.0.x
info:
title: Anamese API
version: 1.0.0
description: API für Anamesebogen
servers:
- url: http://localhost:8080
paths:
/anamese:
post:
summary: Daten erfassen
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Klient'
responses:
'200':
description: Klient erfolgreich angelegt
'400':
description: Eingaben ungültig
components:
schemas:
Klient:
type: object
properties:
name:
type: string
vorname:
type: string
gebdatum:
type: date
gender:
type: string
enum: [weiblich, männluch, divers, ka]
gewicht:
type: number
groesse:
type: number
required:
- name
- vorname
- gebdatum
- gender

View File

@ -0,0 +1,85 @@
openapi: 3.0.x
info:
title: Wichteln
version: 1.0.0
description: API für Wichtelaktion
servers:
- url: http://localhost:8080
paths:
/wichtelaktion:
post:
summary: Aktion anlegen
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
adminEmail:
type: string
format: email
startDate:
type: string
format: date
endDate:
type: string
format: date
required:
- name
- adminEmail
- startDate
- endDate
responses:
'200':
description: Aktion erfolgreich erstellt
'400':
description: Aktion konnte nicht erstellt werden
/wichtelaktion/{id}/invite:
post:
summary: Teilnehmer einladen und Tokens generieren
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
emails:
type: array
items:
type: string
reqired:
- emails
responses:
'200':
description: Teilnehmer erfolgreich eingeladen
'400':
description: Teilnehmer konnten nicht eingeladen werden
/wichtelaktion/{id}/:
put:
summary: Wichtelaktion bearbeiten
parameters:
- name: id
in: path
required: true
schema:
type: string
responseBody:
required: true
content:
application/json:
schema: