Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| modul:m323:learningunits:lu01:deklarativimperativ [2025/11/13 10:28] – kmaurizi | modul:m323:learningunits:lu01:deklarativimperativ [2026/08/18 10:12] (aktuell) – Ueberarbeitet: Korrektur Seiteneffekte, Einstiegsanalogie, Unplugged-Aktivitaet, durchgehendes Beispiel, Uebungen; Tags auf neue Kompetenzmatrix admin | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| ====== LU01a - Deklarative vs. Imperative Programmierung ====== | ====== LU01a - Deklarative vs. Imperative Programmierung ====== | ||
| - | ===== Einführung | + | |
| - | Programmierung | + | ===== Einstieg: Taxi oder Navi? ===== |
| + | |||
| + | Stellen Sie sich vor, Sie sitzen in einem Taxi. Es gibt zwei Arten, ans Ziel zu kommen: | ||
| + | |||
| + | * **„Fahren Sie 300 Meter geradeaus, dann links, an der Ampel rechts, nach dem Kreisel die zweite Ausfahrt …" | ||
| + | * **„Zum Hauptbahnhof, | ||
| + | |||
| + | Beide bringen Sie ans Ziel. Im ersten Fall bestimmen //Sie// jeden Schritt – Sie müssen den Weg kennen und tragen die Verantwortung für jeden Abzweiger. Im zweiten Fall beschreiben Sie nur das //Ziel// – wie der Fahrer dorthin kommt, ist seine Sache. | ||
| + | |||
| + | Genau das ist der Unterschied zwischen **imperativer** und **deklarativer** | ||
| + | |||
| + | <WRAP center round tip 80%> | ||
| + | **Diskussionsfrage für den Einstieg** | ||
| + | |||
| + | Wann ist welche Variante besser? Sammeln Sie Argumente, bevor Sie weiterlesen. | ||
| + | |||
| + | //Mögliche Antworten:// | ||
| + | </ | ||
| + | |||
| + | ===== Aktivität: Der menschliche Roboter (ohne Computer, ca. 10 Minuten) ===== | ||
| + | |||
| + | Diese Übung macht den Unterschied körperlich erfahrbar. | ||
| + | |||
| + | **Aufbau:** Eine Person spielt den Roboter, eine Person gibt die Befehle. Ziel: Der Roboter soll einen Stift vom Pult holen und der Kommandogeberin überreichen. | ||
| + | |||
| + | ^ Runde ^ Erlaubte Sprache ^ Beobachtung ^ | ||
| + | | **1 – Imperativ** | Nur Einzelbefehle: | ||
| + | | **2 – Deklarativ** | Nur ein einziger Satz, der das Ergebnis beschreibt: '' | ||
| + | |||
| + | **Auswertung im Plenum:** | ||
| + | |||
| + | - In welcher Runde war der Befehl kürzer? //(Runde 2)// | ||
| + | - In welcher Runde wussten Sie genau, was passieren | ||
| + | - Was passiert | ||
| + | | ||
| ===== Imperative Programmierung ===== | ===== Imperative Programmierung ===== | ||
| + | |||
| Imperative Programmierung wird oft als die traditionellste Art der Programmierung betrachtet. Sie ist eine Art Anweisungsliste oder Rezept, das dem Computer sagt, was er tun soll. | Imperative Programmierung wird oft als die traditionellste Art der Programmierung betrachtet. Sie ist eine Art Anweisungsliste oder Rezept, das dem Computer sagt, was er tun soll. | ||
| Zeile 12: | Zeile 47: | ||
| ===== Deklarative Programmierung ===== | ===== Deklarative Programmierung ===== | ||
| + | |||
| Deklarative Programmierung ist eher eine Art, dem Computer zu sagen, was er erreichen soll, ohne zu beschreiben, | Deklarative Programmierung ist eher eine Art, dem Computer zu sagen, was er erreichen soll, ohne zu beschreiben, | ||
| - **Was, nicht Wie**: Der Schwerpunkt liegt auf dem, was erreicht werden soll, nicht auf dem, wie es erreicht werden soll. | - **Was, nicht Wie**: Der Schwerpunkt liegt auf dem, was erreicht werden soll, nicht auf dem, wie es erreicht werden soll. | ||
| - | - **Keine Seiteneffekte**: Die Funktionen haben keine Nebeneffekte, d.h., sie ändern nichts in der Welt außerhalb | + | - **Ausführung durch das System**: Wie das Ergebnis konkret berechnet wird, entscheidet die Sprache bzw. die Laufzeitumgebung – zum Beispiel |
| - **Höhere Abstraktion**: | - **Höhere Abstraktion**: | ||
| - **Beispiel**: | - **Beispiel**: | ||
| + | |||
| + | ===== Das durchgehende Beispiel: Die Notenliste ===== | ||
| + | |||
| + | Wir lösen ein und dieselbe Aufgabe in beiden Stilen. Diese Aufgabenstellung begleitet uns durch das ganze Kapitel. | ||
| + | |||
| + | <WRAP center round box 80%> | ||
| + | **Aufgabe: | ||
| + | </ | ||
| + | |||
| + | <code python> | ||
| + | noten = [(" | ||
| + | </ | ||
| + | |||
| + | ==== Variante 1: Imperativ ==== | ||
| + | |||
| + | <code python> | ||
| + | bestanden = [] # 1. Leeres Gefäss vorbereiten | ||
| + | for eintrag in noten: | ||
| + | name = eintrag[0] | ||
| + | note = eintrag[1] | ||
| + | if note >= 5.0: # 4. Bedingung prüfen | ||
| + | bestanden.append(name.upper()) | ||
| + | |||
| + | print(bestanden) | ||
| + | </ | ||
| + | |||
| + | Fünf gedankliche Schritte, und der Zustand von '' | ||
| + | |||
| + | <WRAP center round tip 80%> | ||
| + | **Live-Demo: | ||
| + | </ | ||
| + | |||
| + | ==== Variante 2: Deklarativ (List Comprehension) ==== | ||
| + | |||
| + | <code python> | ||
| + | bestanden = [name.upper() for name, note in noten if note >= 5.0] | ||
| + | |||
| + | print(bestanden) | ||
| + | </ | ||
| + | |||
| + | Gelesen wird das als Satz: //„Nimm den Namen in Grossbuchstaben, | ||
| + | |||
| + | ==== Variante 3: Deklarativ (map und filter) ==== | ||
| + | |||
| + | <code python> | ||
| + | bestanden = list(map(lambda p: p[0].upper(), | ||
| + | | ||
| + | |||
| + | print(bestanden) | ||
| + | </ | ||
| + | |||
| + | Diese Bausteine – '' | ||
| + | |||
| + | ==== Variante 4: Dieselbe Frage als SQL ==== | ||
| + | |||
| + | <code sql> | ||
| + | SELECT UPPER(name) FROM noten WHERE note >= 5.0; | ||
| + | </ | ||
| + | |||
| + | Auffällig: Die SQL-Abfrage und die List Comprehension sind fast identisch aufgebaut – //Was auswählen//, | ||
| + | |||
| + | ==== Die Schlüsselfrage: | ||
| + | |||
| + | Stellen Sie der Klasse diese Frage und vergleichen Sie Variante 1 mit Variante 2: | ||
| + | |||
| + | ^ In Variante 1 vorhanden ^ In Variante 2 verschwunden, | ||
| + | | Die leere Liste '' | ||
| + | | Die Schleife '' | ||
| + | | Der Index-Zugriff '' | ||
| + | | Das '' | ||
| + | | Die Reihenfolge der fünf Schritte | … nur noch das Ergebnis beschrieben wird. | | ||
| + | |||
| + | **Merksatz für die Wandtafel: | ||
| + | |||
| + | ==== Warum das relevant ist: der Klassiker-Bug ==== | ||
| + | |||
| + | Dieses Beispiel eignet sich hervorragend, | ||
| + | |||
| + | <code python> | ||
| + | def bestanden_imperativ(liste, | ||
| + | for name, note in liste: | ||
| + | if note >= 5.0: | ||
| + | ergebnis.append(name) | ||
| + | return ergebnis | ||
| + | |||
| + | print(bestanden_imperativ(noten)) | ||
| + | print(bestanden_imperativ(noten)) | ||
| + | </ | ||
| + | |||
| + | Derselbe Aufruf, dasselbe Argument – zwei verschiedene Ergebnisse. Der Grund: Die Liste '' | ||
| + | |||
| + | Genau solche Fehler will die funktionale Programmierung mit **Unveränderlichkeit** und **puren Funktionen** ausschliessen – siehe [[.: | ||
| + | |||
| + | ===== Alltagsbeispiele zum Durchspielen ===== | ||
| + | |||
| + | Diese Paare eignen sich gut zum Sammeln an der Wandtafel. Lassen Sie die Klasse jeweils raten, welche Spalte welchem Paradigma entspricht. | ||
| + | |||
| + | ^ Situation ^ Imperativ (das Wie) ^ Deklarativ (das Was) ^ | ||
| + | | Kaffee | „Mahle 18 g Bohnen, verteile sie gleichmässig, | ||
| + | | Möbel | Die IKEA-Anleitung mit 34 nummerierten Schritten | „Stell mir ein Bett ins Zimmer." | ||
| + | | Bildbearbeitung | Über jedes Pixel iterieren und den Helligkeitswert um 20 erhöhen | Schieberegler „Helligkeit +20 %" | | ||
| + | | Webseite | Mit Canvas Linien, Rechtecke und Text an Koordinaten zeichnen | ''< | ||
| + | | Wäsche | „Fülle Wasser ein, heize auf 40 °C, drehe die Trommel 12 Minuten …" | Programm „Buntwäsche 40°" wählen | | ||
| + | | Daten | Über alle Datensätze schleifen und passende sammeln | '' | ||
| + | |||
| + | ===== Erkennungsmerkmale: | ||
| + | |||
| + | Woran erkennt man den Stil beim Blick auf fremden Code? | ||
| + | |||
| + | ^ Merkmal ^ Deutet auf ^ | ||
| + | | '' | ||
| + | | Eine Variable wird mehrfach überschrieben ('' | ||
| + | | '' | ||
| + | | List Comprehension, | ||
| + | | Es wird ein //neuer// Wert erzeugt statt ein bestehender geändert | deklarativ | | ||
| + | | Der Code liest sich wie ein Satz über das Ergebnis | deklarativ | | ||
| + | |||
| + | Ein guter Test: **Kann man den Code laut vorlesen und es klingt wie eine Beschreibung des Ergebnisses – oder wie eine Anleitung? | ||
| + | |||
| + | ===== Die häufigste Fehlvorstellung ===== | ||
| + | |||
| + | <WRAP center round important 80%> | ||
| + | **Achtung: deklarativ heisst nicht automatisch seiteneffektfrei** | ||
| + | |||
| + | Seiteneffektfreiheit ist keine Eigenschaft der deklarativen Programmierung an sich, sondern der //puren funktionalen// | ||
| + | |||
| + | SQL ist deklarativ, aber ein '' | ||
| + | |||
| + | Richtig ist: // | ||
| + | </ | ||
| ===== Vergleich ===== | ===== Vergleich ===== | ||
| - | * **Kontrolle vs. Abstraktion**: | + | * **Kontrolle vs. Abstraktion**: |
| * **Lesbarkeit**: | * **Lesbarkeit**: | ||
| * **Effizienz**: | * **Effizienz**: | ||
| * **Fehleranfälligkeit**: | * **Fehleranfälligkeit**: | ||
| + | |||
| + | ===== Mini-Übungen ===== | ||
| + | |||
| + | <WRAP center round todo 80%> | ||
| + | **Ü1 – Umschreiben.** Formulieren Sie diesen imperativen Code deklarativ um: | ||
| + | |||
| + | <code python> | ||
| + | zahlen = [3, 8, 1, 9, 4, 7] | ||
| + | gross = [] | ||
| + | for z in zahlen: | ||
| + | if z > 5: | ||
| + | gross.append(z * 10) | ||
| + | </ | ||
| + | |||
| + | **Ü2 – Zuordnen.** Imperativ oder deklarativ? '' | ||
| + | |||
| + | **Ü3 – Übersetzen.** Beschreiben Sie das Rezept „Spiegelei braten" | ||
| + | </ | ||
| + | |||
| + | <WRAP center round info 80%> | ||
| + | **Lösungshinweise** | ||
| + | |||
| + | **Ü1:** '' | ||
| + | |||
| + | **Ü2:** '' | ||
| + | |||
| + | **Ü3:** Verloren geht die Kontrolle über Details (Pfanne, Hitze, Garzeit). Gewonnen werden Kürze und die Freiheit des Ausführenden, | ||
| + | </ | ||
| + | |||
| + | Weiterführende Aufgaben: [[.: | ||
| ===== Schlussfolgerung ===== | ===== Schlussfolgerung ===== | ||
| + | |||
| Während die imperative Programmierung den Programmierern die vollständige Kontrolle über den Prozess gibt, bietet die deklarative Programmierung eine elegante und oft intuitivere Methode zur Lösung von Problemen. Die Wahl zwischen diesen Stilen hängt oft von der Art des Problems, den Anforderungen an die Effizienz und die Vorlieben des Programmierers ab. In der modernen Softwareentwicklung werden oft Elemente beider Stile kombiniert, um eine effiziente und wartbare Lösung zu schaffen. | Während die imperative Programmierung den Programmierern die vollständige Kontrolle über den Prozess gibt, bietet die deklarative Programmierung eine elegante und oft intuitivere Methode zur Lösung von Problemen. Die Wahl zwischen diesen Stilen hängt oft von der Art des Problems, den Anforderungen an die Effizienz und die Vorlieben des Programmierers ab. In der modernen Softwareentwicklung werden oft Elemente beider Stile kombiniert, um eine effiziente und wartbare Lösung zu schaffen. | ||
| ---- | ---- | ||
| - | {{tag> | + | {{tag> |
| - | [[https:// | + | [[https:// |