You are on page 1of 71

Vorbereitungskurs Informatik

Felix-Klein-Gymnasium Göttingen

Sommerhalbjahr 2009

Olaf Mädiger
Inhalt

Lernziel 1: Verstehen, was ein Programm ausmacht
● Grundstruktur eines Programms (EVA-Prinzip)
● Planung von Algorithmen (Struktrogramm, Ablaufdiagramm)
● Umsetzung eines Algorithmus in ein Programm ("Quadratzahl")
● Einfaches Beispiel: Mathematik-Algorithmus ("FlaecheKreis")
● Einfaches Beispiel: Linear-Algorithmus ("Quadratzahlen1bis10")
● Einfaches Beispiel: Mathematik-Algorithmus ("Summe1bis10")
● Einfaches Beispiel: Spiele-Algorithmus ("Wuerfelspiel")
● Einfaches Beispiel: Mathematik-Algorithmus ("PrimzahlN")
● Komplexeres Beispiel: Mathematik-Algorithmus ("IntegrateCircleArea")
● - fehlt - Einfaches Beispiel: Text-Algorithmus ("WortSpiegel")
● - fehlt - Übung eines einfachen Spiele-Algorithmus ("RateZahl")

Lernziel 2: Übertragung von Programmstrukturen auf Kara
● Vorstellung der Objekt-Welt von Kara (XY-Gitter, Kara, Baum, Blatt, Pils)
● Sensoren und Aktoren von Kara (BaumLinks/Vorn/Rechts,
● Befehle für Kara (Vor, Links, Rechts, Hebe, Senke)
● Einfache Beispiele der Programmierwelt von Kara
● Einfache Übungen für Kara

Lernziel 3: Übertragung von Programmstrukturen auf JavaKara
● Unterschiede zwischen Kara und JavaKara
● Einfache Übungen für JavaKara

Lernziel 4: Übertragung von Programmstrukturen auf Java
● Vorstellung
● Einfache Übungen
● Java-Elemente: Anweisungen und Ausdrücke
● Java-Elemente: Weitere Anweisungen
● Java-Elemente: Variablen und Datentypen
Lernziel 1: Verstehen, was ein Programm ausmacht

Grundstruktur eines Programms (EVA-Prinzip)

Woraus besteht ein Computer-Programm?

Der Ablauf eines Computer-Programms oder einfacher Programms besteht aus den Blöcken
Eingabe, Verabeitung und Ausgabe.
Ablauf heisst dabei die zeitliche Abfolge von durch den Computer ausgeführten Befehlen
auf der Grundlage eines vorher übersetzten Programmtextes.

(Tafel: Quelltext: Quadratzahl.txt → Übersetzer → Quadratzahl.exe)
Der Entwicklungszyklus eines Programms durchläuft die folgenden Schritte:
– Quadratzahl.txt (.c, ...) besteht aus lesbarem Text
– Übersetzer (Compiler, fertiges Programm) liest Quadratzahl.txt und übersetzt nach
– Quadratzahl.exe (lauffähiges Programm, nicht lesbarer Text, da Binärdatei)

Wie kann man sich einen Computer vorstellen?

Ein typischer Computer (Desktop-PC, Note- bzw. Netbook, PDA) besteht aus
materialisierten Funktionsblöcken wie Prozessor, Speicher, Festplatte, Schnittstellen,
Monitor, Tastatur, Maus, Netzteil mit den Funktionen:

Computer-Hardware (Blöcke → Tafel):
● Monitor: Visualisierung von Informationen für den Benutzer
● Tastatur, Maus: Eingabe von Informationen durch den Benutzer
● Netzteil: Energieversorgung und -verteilung (Ausblick: Ohmsches Gesetz: U = R * I)
● Festplatte: Laden und Speichern von Informationen (bleiben nach dem Ausschalten
erhalten)
● Speicher: Temporäres Laden und Speichern von Informationen während des Betriebs
(Laufzeit)
● Schnittstellen: Austausch von Informationen mit dem Rest der Welt

Demgegenüber besteht die Computer-Software in ihrer nicht materiellen Form aus
Informationen, die sich durch die Ausführung während eines Programmablaufs in den
verschiedenen Hardware-Modulen mit ihren entsprechenden eindeutigen Zuständen
„befinden“. In diesem Zusammenhang verändern die wechselden Zustände der Information
als „Bit Ein“ oder „Bit Aus“.

(Tafel: Zeitpfeil Laden, Ausführen und Schliessen)
Ein „normales“ Programm arbeitet während seiner Laufzeit (Laden vom Betriebssystem,
Ausführen unter dem Betriebssystem, Schliessen durch das Betriebssystem) seiner
Ausführung eine Folge von Befehlen ab, die mit dem Betriebssystem und damit auch mit
dem Benutzer wechselwirken.
Diese einfachen linearen Programme heissen Single- oder auch Monotask-Programme.
In ihnen startet das Programm einen Prozess, der streng sequentiell die durch das Programm
vorgegebenen Befehle stur abarbeitet.
(Tafel: Blöcke Main-Childs)
Demgegenüber erweitern sogenannte Multitasking-Programme den Main-Prozess eines
Programms durch eine endliche Zahl von Child-Prozessen, wobei jeder Prozess parallel zu
den anderen eine Folge von Befehlen abarbeitet. Als logische Konsequenz ergibt sich in
Multitasking-Programmen eine zusätzliche Wechselwirkung zwischen den Prozessen.

Eingabe

(Tafel: Editfeld im Fenster)
Eingabe bedeutet dabei die Vorgabe von Daten (Zahlen, Zeichen, Texten,..) an das
Programm. Die Eingabe von Daten erfolgt dabei durch den Benutzer oder durch Dateien
(das sind Datenmengen lokal auf dem Computer als Dateien (Files auf der Festplatte) oder
extern aus dem Netzwerk (Files von anderen Computern) oder aus Internet (Internet-Seiten,
Dienste)).

Im Fall der interaktiven Benutzereingabe sieht der Benutzer ein Bild auf dem Monitor mit
Engabemöglichkeiten. In entsprechenden Eingabefeldern gibt der Benutzer entsprechend der
aktuellen Programmsituation Zahlen oder Zeichenketten ein.

(Tafel: Prozessor, Festplatte, RAM)
Im Fall der automatisierten Eingabe liest das Programm seine Eingabedaten aus diversen
Datenströmen. Steht der Computer isoliert (ohne Verbindung zu anderen Computern und
damit auch ohne Verbindung zum Internet), fliessen Datenströme mittels denen der
Prozessor Informationen zwischen dem Speicher und der Festplatte hin- und herschiebt.
Im Speicher (RAM) liegt nach dem Lesen eines Datenstromes von der Festplatte (File) ein
Speicher-Abbild der zuvor gelesenen Datei vor.
Vorteil: Der Zugriff auf den Prozessor-Speicher erfolgt deutlich schneller als der Transfer
von Daten zwischen Prozessor und Festplatte

Verarbeitung

(Tafel: Folge, Folge von Befehlen)
Die eigentliche Hauptlast und damit die Hauptverweilzeit eines Programms liegt im
Verarbeitungsteil durch die Bearbeitung einer „Folge von Befehlen“.

(Frage: Was sind Befehle?)
Frage: Was sind „Befehle“?
Antwort: Anweisungen zur Transformation von Informationen.

(Tafel: I → f(I), I gegen f(I) auftragen)
Beispiel: Inverter mit der Funktion:
Wandel eine wahre Aussage in eine falsche Aussage und
Wandel eine falsche Aussage in eine wahre Aussage

(Tafel: in Diagramm eintragen)
Inverter(falsch) → wahr
Inverter(wahr) → falsch
Beispiel für Verarbeitung:
Addition einer Konstanten zu einer Variablen

(Tafel: ...)
Konstante: 1 (|N)
Variable: X (|N)

Anweisung zur Addition von X um 1:
X=X+1

Im Grunde sehen wir in dieser Abbildung (symbolisiert in diesem mathematischen
Ausdruck) unser erstes Computerprogramm. (Tafel: Start // X = 0 // X = X + 1 // End)
Ergänzt wird nach dem Start die Initialisierung der Variablen, in diesem Fall wird X auf
Null gesetzt. Vom Prinzip stellt damit die Initialisierung auch eine spezielle Form der
Eingabe dar.

Frage: Was macht unser Programm?

Jetzt zeichnen wir einen Zeitpfeil von oben nach unten und schreiben fortlaufende Ziffern an
die Zeilen des Programms.
Gehen wir jetzt mit Finger im Kopf die einzelnen Zeilen des Programms in fortlaufender
Zeitfolge durch, so stellen wir uns im Kopf die Transformation der Variablen X von 0 auf 1
im Geiste vor.

Antwort: Unser Programm erhöht den Wert der Variablen X von 0 auf 1

Haben wir das verstanden, können wir unter Kenntnis weitere Programmstrukturen einfache
Programme schreiben...

(Tafel: „AddiereVariableUm1“)
1 → Start

2→X=X+1 Zeitpfeil

3 → End
Ausgabe

Was nützt uns die Verarbeitung von Informationen während des Programmablaufs, wenn
wir den Computer nach Ablauf des Programms ausschalten?

Nichts, denn vor dem Ausschalten sollten wir uns die Informationen entweder in den
Zwischenzuständen oder oder in den Endzuständen der Verarbeitung anschauen bzw.
zwischenspeichern, um sie später anzuschauen!

Daher erweitern wir unser Schaubild:
(Tafel: Start // X = 0 // X = X + 1 // Ausgabe X // End)

und erkennen das EVA-Prinzip wieder!

(Tafel: EVA: E → V → A)

E

V

A
Lernziel 1: Verstehen, was ein Programm ausmacht

● Planung von Algorithmen (Struktrogramm, Ablaufdiagramm)

Was ist ein Algorithmus?

Noch einmal zurück zu unserem Einführungsprogramm.
(Tafel: X = X + 1)
Bisher beinhaltete unsere Programmzeile der Addition der Variablen X den Kernbefehl
unseres Programms.
Das Ergebnis des Programms hängt aber auch noch von der Initialisierungszeile ab – und
sogar wesentlich!
Ändern wir „X = 0“ auf „X = 5“, so wechselt die Ausgabe „Ausgabe X“ von zuvor 1 auf 6.
Unser Algorithmus hat sich in seiner Struktur nicht verändert, nur durch die veränderten
Anfangsbedingungen (Initialisierung 0 → 5) erhalten wir unterschiedliche Ergebnisse.

Daher definieren wir:
Der Algorithmus für ein Programm stellt eindeutig die Folge von Befehlen/Funktionen dar.
Mit einer eindeutigen Initialisierung ergibt sich ein eindeutiger Programmablauf und damit
ein eindeutiges Programmergebnis.

(Tafel: Exkurs Wikipedia, gezieltes Finden von Programmierinformationen)
Wikipedia:
Unter einem Algorithmus (auch Lösungsverfahren) versteht man eine genau definierte
Handlungsvorschrift zur Lösung eines Problems oder einer bestimmten Art von Problemen
in endlich vielen Schritten.

Ergänzung:
Bauen wir in unser Programm einen Sprung ein:
(Tafel: Schleife auf sich selbst)
„X = X + 1“ → „X = X + 1“
Gehen wir die Befehle einzeln von Start bis Ende durch....
Problem: Wir kommen niemals zum Ende!
Daher: Es handelt sich um einen nichteindeutigen Algorithmus auf der Grundlage einer
Endlosschleife!

(Tafel: „AddiereVariableUm1“)
1 → Start

2→X=X+1 Zeitpfeil

3 → End
Wie entwickelt man ein Programm?

(Zitat A. Flemming):
„Viele Programmieranfänger stürzen sich, nachdem die Aufgabe verkündet wurde, auf die
Rechner.
Das ist falsch! Wie so oft hat man eine ungefähre, aber keine brauchbare Idee. Wenn man
versucht, Ideenfindung und Umsetzung gleichzeitig am Rechner zu erledigen, verzettelt man
sich.
Wie geht man also am Besten vor?
Zuerst braucht man einen Zettel und einen Stift. Denken ohne Zettel und Stift ist kaum
möglich!
Als nächstes braucht man eine Grundidee. Diese besteht oft nur aus ein bis zwei Sätzen. Es
empfiehlt sich, diese Idee als Satz aufzuschreiben.
Gedanken im Kopf sind immer wirr. Erst wenn sie ausgesprochen oder aufgeschrieben
werden müssen, konkretisieren sie sich zu etwas Brauchbarem.“

(Tafel: Hardware zum Denken)
Hardware zum Denken
● Gehirn (ausgeruht, klar und frei)
● Zettel (weiss oder kariertes DINA4-Blatt)
● Arbeitsfläche (saubere, aufgeräumte Unterlage)
● Bleistift (mindestens HB, besser 2B, angespitzt)
● Radiergummi (nicht schmierend)
Lernziel 1: Verstehen, was ein Programm ausmacht

● Umsetzung eines Algorithmus in ein Programm ("Quadratzahl")

Was ist ein Ablaufdiagramm?

Wir nehmen daher einen Zettel (kariert oder weiss), einen Bleistift (angespitzt) und ein
Radiergummi (nicht schmierend) und legen alles auf eine genügend grosse Unterlage
(sauber und aufgeräumt).
Dann versuchen wir, unser Problem zu thematisieren und in Blöcke zu modularisieren.
Wir suchen daher eine Abbildung unserer Problemlösung auf einen Algorithmus in einer
abstrakten Sprache. →
Wir müssen den Algorithmus schriftlich formulieren.

Die Formulierung geschieht bei Profis in einem sogenannten Struktogramm. Wir begnügen
uns hier mit dem verständlichen formlosen Programmablaufplan. Dabei schreiben wir in
Stichworten, Symbolen und Kommentaren den Algorithmus in seiner ersten intuitiven
Version auf.

(Tafel: „Quadratzahl“, Schüler nach vorn)
Beispiel:

1 → Start

2 → Eingabe X E

3 → Bilde Y = X * X V

4 → Ausgabe „Quadrat von “ X „ ist “ Y A
5 → End

Mit dem Finger und im Kopf gehen wir die einzelnen Programmschritte durch...

Zeile 2: Diesmal erfolgt die Initialisierung von X durch eine Benutzereingabe.

Zeile 3: Zum ersten Mal sehen wir neben einer Variable X eine zweite Variable Y. Y wird
das Quadrat von X zugewiesen. In dieser Zeile erkennen wir eine Zuweisung.

Zeile 4: In Abhängigkeit von der Eingabe X erfolgt die Ausgabe des Quadrats von X durch
Y.

Da der Algorithmus so schön von oben nach unten durchläuft nennen wir ihn „Linear-
Algorithmus“. Dies ist ein Spezialfall!
Erläuterung zu Variablen

(Tafel: Variable als Kasten)
Um die hier noch einfache Variablenstruktur des Programms besser im Ablauf zu verstehen,
entwickeln wir ein Modell einer Variablen. Wir stellen uns eine Variable als Kasten vor.

Den Kasten und damit die Variable bezeichnen wir als Objekt. Jedes Objekt besitzt einen
Namen und einem Wert.

(Tafel: Variablen mit Name und Wert nach Start)
Variable Name Wert
1 X -
2 Y -

(Tafel: Variablen mit Name und Wert nach Eingabe X)
Variable Name Wert
1 X 5
2 Y -

(Tafel: Variablen mit Name und Wert nach Zuweisung)
Variable Name Wert
1 X 5
2 Y 25

(Tafel: Variablen mit Name und Wert nach Ausgabe)
Variable Name Wert
1 X 5
2 Y 25

Wir erkennen:
X ändert sich nur nach der Eingabe, Y ändert sich nur nach der Zuweisung.
Wichtig: Auf der rechten Seite der Zuweisung muss der Term der Zuweisung vollständig
und eindeutig definiert sein!
Nur dann erhält Y aus der Auswertung der Zuweisung seinen eindutigen und korrekten
Wert!

Was ist ein Debugger – Programm-Analyse „Step by Step“?

Wir analysieren mit dem Finger und Kopf die Funktionsweise unseres Programms. Wir
finden während der Laufzeit unseres Programms Fehler bei der schrittweisen Analyse.

Damit verhalten wir uns als Werkzeug zur Programmanalyse während der Laufzeit.
Ein Analyse-Tool im Computer werden wir später noch mehrfach einsetzen. Wir nennen
dieses Analyse-Tool „Debugger“.

So wie in unserer Tabellendarstellung liefert der professionelle Debugger zu den
Variablennamen die Werte während der einzelnen Programmschritte. Später mehr...
Lernziel 1: Verstehen, was ein Programm ausmacht
● Einfaches Beispiel: Mathematik-Algorithmus ("FlaecheKreis")

Berechne die Fläche eines Kreises

Genauer: Berechne die Fläche A eines Kreises bei gegebenem Radius R
Transfer: Berechne auch den Umfang U

Mathematik:

A = PI * R * R
U = 2 * PI * R

mit PI = 3.1414

(Tafel: Fläche Kreis und Umfang)

1 → Start

2 → Ausgabe „Berechnung Kreisfläche und Kreisumfang“

3 → Konstante PI = 3.1414

4 → Eingabe Variable R // Radius [mm]

5 → Ausgabe „Radius [mm] = “ R

4 → Variable A = PI * R * R // Fläche [mm2]

5 → Variable U = 2 * PI * R // Umfang [mm]

6 → Ausgabe „Fläche [mm2] ist “ A

7 → Ausgabe „Umfang [mm] ist “ U

8 → End
Lernziel 1: Verstehen, was ein Programm ausmacht
● Einfaches Beispiel: Linear-Algorithmus ("Quadratzahlen1bis10")

Die Erzeugung der Quadratzahlen von 1 bis 10

Aufgabe:
Geben neben den Zahlen von 1 bsi 10 mit der Schrittweite 1 die Quadratzahlen aus.

(Tafel: Fehlerhafte Liste)
Algorithmus:

1 → Start

2 → Ausgabe „Quadratzahlen von 1 bis 10“

3 → Ausgabe „Start“ (redundante Debug-Ausgabe)

4→X=1

5 → Durchlaufe

6 → Bilde Y = X * X Endlosschleife!!!

7 → Ausgabe „Quadrat von “ X „ ist “ Y

8 → solange X <= 10;

9 → Ausgabe „Ende“ (redundante Debug-Ausgabe)

10 → End

Laufzeitfehler (Runtime-Error)

Bewusst habe ich hier eine Zeile vergessen. Beim „debuggen“ mit dem Finger merken wir,
dass sich der Wert von X nur einmal ändert und dann (für immer!) erhalten bleibt
→ Damit wird das Abbruchkriterium der Schleife „solange X <= 10“ für immer und ewig
erfüllt!

Damit haben wir eine sogenannte Endlosschleife entworfen und ausgeführt.
Der Algorithmus ist damit fehlerhaft!

Den Fehler haben wir zur Laufzeit des Programms (beim debuggen) bemerkt. Diesen
Fehlertyp nennt man daher Laufzeitfehler.
Syntaxfehler (Compiletime-Error)

Ein anderer Fehlertyp heisst Syntaxfehler. Einen solchen Fehler bemerken wir nur dann,
wenn uns eine fehlerhafte Rechtschreibung direkt ins Auge springt:

(Tafel: kurzzeitige Änderung)
Zeile 4: X = 1 → X @@@@@uvw!!!

Das ergibt keinen Sinn. In unserer (bisher noch nicht näher spezifizierten) Syntax der
Programmzeilen waren diese Folgen von Sonderzeichen bisher in ihrer Funktion nicht
spezifiziert.

Wie können wir das Problem der Endlosschleife lösen?

„X hat sich nur einmal geändert“ → X muss sich ändern → X = X + 1 einfügen!

(Tafel: Korrigierte Liste)
1 → Start

2 → Ausgabe „Quadratzahlen von 1 bis 10“

3 → Ausgabe „Start“

4→X=1

5 → Durchlaufe

6 → Bilde Y = X * X

7 → Ausgabe „Quadrat von “ X „ ist “ Y
// Neue Zeile mit
8 →X=X+1 // schrittweiser Zunahme von X

9 → solange X <= 10; Kommentar!

10 → Ausgabe „Ende“

11 → End

Jetzt merken wir beim debuggen eine schrittweise Zunahme von X von 1 um 1 auf 10:
(Tafel: Durchlauf X, Y ← Schüler)
Wir durchlaufen X

X = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

und erhalten Y

Y = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Top! Damit haben wir erstmal eine Pause verdient!
Ergänzungen zum Programm „Quadratzahlen1bis10“

Zeile 9: heisst Abbruchkriterium für eine Schleife →
Zeilen 5 .. 9 bilden eine Schleife!
Zeilen 6 .. 8 Block

Neben der Zuweisung generieren wir aus der Notwendigkeit zur Formulierung unseres
Problems „Quadratzahlen von 1 bis 10“ eine Befehlsschleife.

Eigentlich kennen wir jetzt schon fünf wichtige Bestandteile zur Formulierung von
Algorithmen:

(Tafel: Bestandteile eines Algorithmus, Schüler)
– Variable (mit Name und Wert)
– Ausdruck (mathematischer Term, der einen Wert ergibt)
– Zuweisung (Befehl als Wertzuweisung einer Variablen)
– Block (Zusammenfassung einer endlichen Menge von Befehlen)
– Schleife (Befehl mit Block und Abbruchkriterium)
– Bedingung (Befehl zum bedingten Sprung)

Als Neuerung erkennen wir beim letzten Punkt die Bedingung und damit kommen wir zum
nächsten Beispiel „Wuerfelspiel“.
Lernziel 1: Verstehen, was ein Programm ausmacht
● Einfaches Beispiel: Linear-Algorithmus ("SummeZahlen1bis10")

Berechne die Summe der Zahlen von 1 bis 10

...damit wissen wir schon die Aufgabe!

(Tafel: Summe der Zahlen von 1 bis 10)
Algorithmus:

1 → Start

2 → Ausgabe „Berechnung der Summe der Zahlen von 1 bis 10“

3 → Lauf-Variable X = 1

4 → Variable Summe = 0

5 → Durchlaufe

6 → Bilde Summe = Summe + X

7 → solange X <= 10;

8 → Ausgabe „Summe ist “ Summe

9 → End
Lernziel 1: Verstehen, was ein Programm ausmacht
● Einfaches Beispiel: Spiele-Algorithmus ("Wuerfelspiel")

Das „Wuerfelspiel“

Aufgabe:
Erzeuge eine Zufallszahl im Bereich von 1 bis 6 mit Schrittweite 1. Dies ist dein
Würfelergebnis.
Gebe das Ergebnis aus.
Falls das Würfelergebnis identisch 6 ist, gebe zusätzlich zur „6“ das Wort „Maximum“ aus.

Einschub: Was ist eine Zufallszahl?

Eine Zufallszahl stellen wir uns als Variable R (kommt von Random) mit der Funktion

Random(R) → R, R = [0, 1) // 0 <= R < 1

(„[“ gehört zum Interval, „)“ gehört nicht zum Interval)

Beispiel einer Folge von Zufallszahlen:
R = [0.021, 0.314, 0.897, .. , 0.123] aber nicht R = 1 !

Algorithmus „Wuerfelspiel“

(Tafel: „Wuerfelspiel)

1 → Start

2 → Erzeuge Zufallszahl ZZ im Bereich von 1 .. 6

3 → Ist ZZ ungleich 6?

4 → Ja: (ZZ = [1, 2, 3, 4, 5]) Ausgabe ZZ

5 → Nein: (ZZ = 6) Ausgabe „Maximum“ ZZ

6 → End

Beim debuggen verzweigen wir in Abhängigkeit der Zufallszahl ZZ entweder zu Zeile 4
oder Zeile 5. Dementsprechend erfolgt die normale oder erweiterte Ausgabe.

Dies ist ein sehr einfaches Beispiel für eine Gruppe von Algorithmen. Wir nennen diese Art
von Algorithmus „Spiele-Algorithmus“.
Ergänzung: Äquivalent verhält sich die folgende Änderung:

3 → Ist ZZ gleich 6?

4 → Ja: (ZZ = 6) Ausgabe „Maximum“ ZZ

5 → Nein: (ZZ = [1, 2, 3, 4, 5]) Ausgabe ZZ

Wie transformieren sich Zufallszahlen für einen gewünschtes Intervall?

Random(R) → R, R = [0, 1) // 0 <= R < 1

0 <= R < 1

Sei nun unser Wunschintervall [1..6] bzw. [1..7), so verhelfen uns die folgenden
Äquivalenzumformungen zum Ergebnis:

0 <= R < 1 || * 6

0 <= R < 6 || + 1

1 <= R < 7 (und damit 1 <= R <= 6)
Lernziel 1: Verstehen, was ein Programm ausmacht
● Einfaches Beispiel: Mathematik-Algorithmus ("PrimzahlN")

„Primzahl N“

Aufgabe:
Prüfe, ob N eine Primzahl ist.
N sei Element der natürlichen Zahlen.

Algorithmus:

(Tafel: „PrimzahlN“)

1 → Start
2 → Eingabe N (als zu prüfende natürliche Zahl)
3 → Variable I = 2
4 → Variable Ende = falsch
5 → Solange Ende == falsch
6 → Ist N / 2 <= I ?
7 → wahr:
8 → Ausgabe N „ ist eine Primzahl!“
9 → Ende = wahr
10 → falsch:
11 → Ist Division N / I ohne Rest?
12 → wahr:
13 → Ausgabe N „ ist keine Primzahl“
14 → Ende = wahr
15 → falsch:
16 → I=I+1
17 → End

Transfer: Teilen mit oder ohne Rest – modulo

Wie realisieren wir eine mathematische Abbildung „Division N / I ohne Rest“?
Beispiel innerhalb der Programmiersprache Java: Google „ Java teilen ohne Rest“:

Wie schon in der ersten Stunde erwähnt, beschäftigen wir uns in den beiden Halbjahren des
10. Schuljahres innerhalb der „Einführung in die Informatik“ mit der Programmiersprache
„Java“.

In Java wird die Modulo-Operation mit einem % ausgeführt.

(Tafel: „PrimzahlN“)
Die syntaktische Notation: <%>
Wir sehen in einem Quelltext-Fenster:

Beispiel: Modulo-Operator <%> in Java-Quelltext

Der Rest interessiert uns erstmal nicht. Ausserdem wird vieles im Quelltext automatisch
erzeugt.

Drücken wir auf den grünen Start-Button, erhalten wir die Ausgabe in einem Konsolen-
Fenster:

Ausgabe in Java-Console: Ergebnis der Modulo-Operation

Transfer: Befehle in Java

Weiterhin: „Java Zuweisung“ „Java Bedingung“ „Java Schleife“
Lernziel 1: Verstehen, was ein Programm ausmacht
● Komplexeres Beispiel: Mathematik-Algorithmus ("IntegrateCircleArea")

„Integriere die Fläche eines Kreises“

Aufgabe:

R = Radius Circle Aquadrat
Ak = ? → zu berechnende Grösse! R
Aq = R * R
Akreis R
L = sqrt( X * X + Y * Y )

Carea : Counter für Treffer L <= R des Kreis-Areals
Ctotal : Counter über alle Punkte

Faktor 4 für Belegung eines Viertelkreises

Ak = 4 * R * R * Ca / Ct

Lösung: Y

Iteriere über alle Punkte Y: 0 <= Y <= R L
→ Iteriere über alle Punkte X: 0 <= X <= R

→ Berechne L = sqrt( X * X + Y * Y )

→ Wenn (L <= R) R
Dann Carea = 1 + Carea
X

→ Ctotal = NX * NY

→ AreaCircle = 4 * R * R * Carea / Ctotal

→ Ausgabe „ Radius = “ R „ AreaCircle = “ AreaCircle

Hinweise zur „Guten Programmierung“

Verwende keine Umlaute:
ä → ae
ö → oe
ü → ue

Verwende zur besseren Lesbarkeit Grossbuchstaben, möglichst keine Abkürzungen!
Und zu guter Letzt ein Blick auf ein entsprechendes Java-Programm mit gleicher Funktion:

package IntegrateCircleArea;

public class Main
{
public static void main(String[] args)
{
double R = 1;

int XIL = 1;
int XIH = 10000;
int NX = 1 + XIH - XIL;

int YIL = 1;
int YIH = 10000;
int NY = 1 + YIH - YIL;

double XL = 0.0;
double DX = R / NX;

double YL = 0.0;
double DY = R / NY;

int AreaCounter = 0;
double Y = YL;
for (int YI = YIL; YI <= YIH; YI++)
{
double X = XL;
for (int XI = XIL; XI <= XIH; XI++)
{
double L = Math.sqrt(X * X + Y * Y);
if (L <= R)
{
AreaCounter++;
}
X += DX;
}
Y += DY;
}

int TotalCounter = NX * NY;
double AreaCircle = 4.0 * R * R * AreaCounter / TotalCounter;
System.out.println("R = " + R + " -> A = " + AreaCircle);
}
}
AddOns

– Sendet mir bitte eure Hausaufgaben als PDF-Dokumente zu. (PDF-Creator).
– Schreibt den Namen auf die Lösung.
– Stellt mir auch Fragen. Ich bin eigentlich immer erreichbar.
– Ihr müsst auf keinen Fall alle Aufgaben lösen.
– Ihr sollt euch auf jeden Fall mit den Aufgaben beschäftigen!
– Natürlich werde ich den Einsatz bei den Hausaufgaben mit bei der Zensur
berücksichtigen.
Lernziel 2: Übertragung von Programmstrukturen auf Kara
● Vorstellung der Objekt-Welt von Kara (XY-Gitter, Kara, Baum, Blatt, Pilz)

Karas Welt

Aufgabe 1:
Plaziere Kara (Marienkäfer) auf seine Standard-Welt (9x9). Benutze die blauen
Kommandotasten zur Ausführung von Kara-Aktionen.
– Bewege dich in allen Richtungen.
– Nehme ein Klee(blatt) auf und lege es ab.
Aufgabe 2:
Setze einen Baum(stumpf) vor Kara und lasse Kara auf ihn zulaufen. Was passiert?

Lösung 2:
Kara bleibt vor dem Baum stehen (Fehlermeldung!)

Aufgabe 3:
Wie kannst du Objekte vernichten?

Lösung 3:
Vernichtung von Objekten durch Drag&Drop in den Mülleimer.

Aufgabe 4:
Plaziere einen Pilz vor Kara und bewege Kara in Richtung des Pilzes. Was passiert?

Lösung 4:
Kara schiebt den Pilz vor sich her.

Aufgabe 5:
Setze eine Baum hinter den Pilz von Aufgabe 4 und bewege Kara in Richtung des Pilzes.
Was passiert?

Lösung 5:
Kara kann den Pilz nicht durch den Baum schieben.

Aufgabe 6:
Positioniere ein Kleeblatt auf die Vorderseite von Kara. Was passiert beim Überschreiten
des Klees?
Lösung 6:
Wenn Kara sich über dem Klee befindet, sieht sie denselben, sonst nicht!
Ausserdem kann Kara den sichtbaren Klee aufheben und son ein Kleeblatt hinlegen.

Ergebnisse / Zusammenfassung:
– Kara kann sich bewegen
– Kara kennt die Objekte Klee, Baum, Pilz mit den Reaktionen:
Baum - Stop davor
Klee – Aufnehmen / Hinlegen
Pilz – Verschieben
– Kara lebt in einer NxM-Welt, die aber bezüglich ihrer Bewegung unendlich ist. Bei
Bewegungen über den Rand hinaus erfolgt ein Sprung zum gegenüberliegenden Rand.
– Kara empfängt aktuell nur Aktionen (Befehle) durch die "blauen" Tasten (Vor, Links,
Rechts, Nehmen, Ablegen), d. h. durch mühseliges und immer wiederkehrendes
Tippen... - Gibt es eine andere Lösung?

Ja: Wir schreiben ein Kara-Programm!
Aufgabe 7:
Schreibe dein erstes Kara-Programm. Drücke auf "Programmieren". Der Dialog "Kara
programmieren" erscheint nicht modal neben dem Fenster "Kara, der programmierbare
Marienkäfer":

Deine Aufgabe trägt den Namen "Kleeblatt-Inverter":

Konstruiere dir eine entsprechende Kara-Welt:
Setze den folgenden Algorithmus in ein Kara-Programm um:

1. Start: → Laufe
2. Laufe:
Klee detektiert ?
true: Klee aufheben, gehe vorwärts → Laufe
false: Klee hinlegen, gehe vorwärts → Laufe
3. End: (wird nicht erreicht)

Lösung 7:

Speichere sowohl Karas Welt als auch Karas Programm unter "Aufgabe7" in einem
Verzeichnis mit gleichem Namen "Aufgabe7".

Dann "Ausführen", "Programm laufen lassen" drücken und – beobachten....
Da kein "Stop"-Zustand programmiert wurde und auch nicht erreicht wird:
"Programmausführung abbrechen" drücken!

Alternativen "Programmausführung pausieren" und "Programm Schritt für Schritt
ausführen" ausprobieren!
Wichtige Ergebnisse:

Dein erstes Kara-Programm funktioniert fehlerfrei:

Immer dann, wenn Kara ein Feld mit Klee betritt, hebt sie den Klee auf und geht einen
Schritt weiter.

Immer dann, wenn Kara ein Feld ohne Klee findet, legt sie ein Kleeblatt auf das Feld und
geht einen Schritt weiter.

Anscheinend gibt es aber ein Problem mit dem Ende des Programms:
Der Zustand "Stop" wird niemals erreicht!

Philosophischer Transfer:

Frage: Muss Kara jemals einen Endzustand erreichen?

Antwort: Ja, denn jeder Algorithmus muss endlich sein!
Antwort: Nein, denn Kara lebt unendlich lange (bei laufendem Programm).

Wie können wir dennoch den Algorithmus endlich zwingen?
Wir setzen einen Stopper (Baum) an das Ende der Kara-Weltzeile!

Starte und führe das Programm aus. Was passiert?
So eine Gemeinheit: wir erhalten unsere erste Fehlermeldung während der Programm-
laufzeit, also einen Laufzeitfehler (Runtime-Error).

Wie lösen wir das Problem des Runtime-Errors?

Hilfe: wir suchen eine Bedingung zum Übergang in den Stop-Zustand.

Lösung 7B für ein terminiertes Programm:

Setze daher den folgenden Algorithmus in ein terminiertes Kara-Programm um:

1. Start: → Laufe
2. Laufe:
Baum detektiert?
falsch:
Klee detektiert ?
wahr:
Klee aufheben, gehe vorwärts → Laufe
falsch:
Klee hinlegen, gehe vorwärts → Laufe
wahr: → Stop
3. Stop: (End)

Karas Welt hat sich dabei nicht verändert:

Zuerst ergänzen wir im Zustand "Laufe" einen Sensor: "Baum vorne?":
Dann editieren wir die "Wenn-Dann" Aktionen des neuen und alten Sensors:

und lassen das Programm (nach dem Laden der alten "Aufgabe7"-Welt laufen...

Jetzt terminiert das Programm bei Detektion eines Baums - Glückwunsch!
Aufgabe 8:

A: Editiere und speichere eine Welt mit einer Baumfolge:
Kara – leer – Baum – leer – Baum – leer - ... - Baum

B: Formuliere einen Algorithmus "Kara als Baum-Umrunder".

C: Schreibe das auf dem Algorithmus (B) basierende Kara-Programm "UmrundeBaum".

D: Führe Tests mit dem Debugger aus.

Lösung 8A:

Zuerst konstruiere die Baumfolge-Welt:

Lösung 8B:

Programm "UmrundeBaum"
Zustand Operation(en)
Start → Entscheide

Entscheide Baum vorn?
Wahr: Drehe Links → RechtsHerum
Falsch: Gehe Vorwärts → Entscheide

RechtsHerum Gehe Vor Drehe Rechts
Gehe Vor Gehe Vor Drehe Rechts
Gehe Vor → Entscheide

Stop: Ende
Lösung 8C:

Lösung 8D:

Beim Debuggen sehen wir die zeitliche Abfolge der Abarbeitung aller Kommandos eines
Blocks der If-Bedingung.
Aufgabe 9:

Kara als "PacMan" (Spurensucher)

Aufgabe: Kara soll eine durchgehende Spur von Kleeblättern verfolgen.
Dabei soll sie, falls kein Klee auf ihrem Platz vorhanden ist, ein Kleeblatt hinlegen und falls
ein Kleeblatt auf ihrem Platz liegt, dasselbe aufnehmen.
Falls Kara auf einen Baum trifft, hält das Programm an.

Lösung 9A:

Kara Vorgabe-Welt:

Speichern als "PacMan".

Lösung 9B:

Programm "PacMan"
Zustand Operation(en)
Start → EsseKlee

EsseKlee Baum vorn? Auf Klee?
F F GV → SucheKlee
F W NK, GV → SucheKlee
W W NK → Stop
W F → Stop

SucheKlee Auf Klee?
W → EsseKlee
F DL, DL, GV DL, GV → SucheKlee

Stop: Ende
Lösung 9C:

Trick der Folge F = [L, L, V, L, V]:

(4)(0)

(3) ← → (1)

(2)

Karas Position wechselt von (0) auf (1) auf (2) auf (3) und wieder auf (0) beim einem
Durchlauf der Folge F (falls kein Blatt gefunden wird).
Damit "scannt" Kara alle Möglichkeiten zum Finden eines Kleeblatts in seiner direkten
Umgebung ab (aber auch nicht mehr).

Lösung 9D:
Genau diese Eigenschaft zeigt uns der Debugger.
AddOn: FSM – Finite State Machine (Endlicher Zustandsautomat)

FSM am Beispiel einer mechanischen Zimmertür

Wikipedia:

"Ein endlicher Automat (EA, auch Zustandsmaschine, englisch finite state machine (FSM))
ist ein Modell des Verhaltens, bestehend aus Zuständen, Zustandsübergängen und Aktionen.

Ein Automat heißt endlich, wenn die Menge der Zustände, die er annehmen kann (später S
genannt), endlich ist.
Ein EA ist ein Spezialfall aus der Menge der Automaten.
Ein Zustand speichert die Information über die Vergangenheit, d.h. er reflektiert die
Änderungen der Eingabe seit dem Systemstart bis zum aktuellen Zeitpunkt.
Ein Zustandsübergang zeigt eine Änderung des Zustandes des EA und wird durch logische
Bedingungen beschrieben, die erfüllt sein müssen, um den Übergang zu ermöglichen.
Eine Aktion ist die Ausgabe des EA, die in einer bestimmten Situation erfolgt. Es gibt vier
Typen von Aktionen
Eingangsaktion
Ausgabe wird beim Eintreten in einen Zustand generiert

Ausgangsaktion
Ausgabe wird beim Verlassen eines Zustandes generiert

Eingabeaktion
Ausgabe wird abhängig vom aktuellen Zustand und Eingabe generiert

Übergangsaktion
Ausgabe wird abhängig von einem Zustandsübergang generiert"
Aufgabe 10: Kara als Wächter (Innenläufer)

Aufgabe: Kara soll ein geschlossenes Rechteck von Bäumen von innen endlos umrunden.

Kara Vorgabe-Welt:

Speichern als "Innenlaeufer".

Lösung 10:

Programm "Innenlaeufer"
Zustand Operation(en)
Start → Laufe

Laufe Baum vorn? Baum rechts
W W DL → Laufe
W F DL → Laufe
F W GV → Laufe
F F GV → Laufe

Stop: Ende
Aufgabe 11: Kara als Wächter (Aussenläufer)

Aufgabe: Kara soll ein geschlossenen Rechteck von Bäumen von aussen endlos umrunden.

Kara Vorgabe-Welt:

Speichern als "Aussenlaeufer".

Lösung 11:

Programm "Aussenlaeufer"
Zustand Operation(en)
Start → Laufe

Laufe Baum links?
F DL GV → Laufe
W GV → Laufe

Stop: Ende (NC)
Aufgabe 12: Kara sucht den Ausgang (Ausgang)

Aufgabe: Kara soll innerhalb einer (fast) geschlossenen Baumreihe derselben folgen und
dabei einen Ausgang suchen. Beim Durchschreiten und Verlassen des Ausgangs soll Kara
stehenbleiben.

Kara Vorgabe-Welt:

Programm "Ausgang"
Zustand Operation(en)
Start → Laufe

Laufe Baum vorn? Baum rechts? Baum links?
F F F DL, GV, GV → Stop
F F W GV → Laufe
F W F GV → Laufe
F W W GV → Laufe
W F F GV → Laufe
W F W DR → Laufe
W W F GV → Laufe
W W W GV → Laufe

Stop: Ende
Ändere bitte zum Ausprobieren den nächsten Zustand "Stop" → "Laufe"
Was passiert?
Lernziel 3: Übertragung von Programmstrukturen auf JavaKara
● Unterschiede zwischen Kara und JavaKara

Bisher:
– Kara-Welt (<name>.world)
– Kara-Programm (<name>.kara)
– Die Programmierung von Kara erfolgt über Zustandsdiagramme.

Jetzt:
– Kara-Welt (<name>.world)
– Kara-Programm (<name>.java)
– Die Programmierung von Kara erfolgt über Java-Code. Dabei verfügt das Objekt Kara
über Methoden.

Methoden des Kara-Objekts
Methode Aufruf Bedeutung
Vorgabe Aktor
void move() kara.move(); Schritt vorwärts
void turnLeft() kara.turnLeft(); 90°-Linksdrehung
void turnRight() kara.turnRight(); 90°-Rechtsdrehung
void putLeaf() kara.putLeaf(); Kleeblatt hinlegen
void removeLeaf() kara.removeLeaf(); Kleeblatt aufnehmen
void setPosition(int x, int y) kara.setPosition(x, y); Kara auf Position (x,y)
java.awt.Point getPosition() kara.getPosition(); Koordinaten der
aktuellen Position
Abfrage Sensor
boolean treeFront() kara.treeFront() Kara vor Baum?
boolean treeLeft() kara.treeLeft() Baum links von Kara?
boolean treeRight() kara.treeRight() Baum rechts von Kara?
boolean onLeaf() kara.onLeaf() Kara auf Kleeblatt?
boolean mushroomFront() kara.mushroomFront() Kara vor Pilz?
void setPosition(int x, int y) kara.setPosition(x, y); Kara auf Position (x,y)
java.awt.Point getPosition() kara.getPosition(); Koordinaten der
aktuellen Position
● Einfache Aufgaben mit JavaKara

Aufgabe 1:

Starte JavaKara.
Drücke auf "Programmieren".
Es erscheint ein Programmierfenster mit Java-Code anstelle der Programmierung mit
Zuständen bei Normal-Kara .

Ihr seht folgenden Quelltext im Editor-Fenster:

import javakara.JavaKaraProgram;

/* BEFEHLE: kara.
* move() turnRight() turnLeft()
* putLeaf() removeLeaf()
*
* SENSOREN: kara.
* treeFront() treeLeft() treeRight()
* mushroomFront() onLeaf()
*/
public class FindeBaum extends JavaKaraProgram {

// hier können Sie eigene Methoden definieren

public void myProgram() {
// hier kommt das Hauptprogramm hin, zB:
while (!kara.treeFront()) {
kara.move();
}
}
}

Ändert den Quelltext "FindeBaum" folgendermassen ab:

import javakara.JavaKaraProgram;

/* BEFEHLE: kara.
* move() turnRight() turnLeft()
* putLeaf() removeLeaf()
*
* SENSOREN: kara.
* treeFront() treeLeft() treeRight()
* mushroomFront() onLeaf()
*/
public class FindeBaum extends JavaKaraProgram
{
public void myProgram()
{
while (!kara.treeFront())
{
kara.move();
}
}
}

Vorteil: Ihr seht unmittelbar, welche Blöcke von Anweisungen zusammengehören!
Speichert euer erstes Programm unter dem Namen "FindeBaum" in einem zuvor erstellten
Verzeichnis "Aufgabe1" ab und überprüft das Zwischenergebnis Datei auf Festplatte

"<path>\Aufgabe1\FindeBaum.java"

mit dem Explorer!

Wieder zurück zum Welt-Fenster: Konstruiere eine Welt entsprechend der Abbildung:

Speichere diese Welt unter dem Namen "FindeBaum"

"<path>\Aufgabe1\FindeBaum.world"

ab.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Beachte die Gleichheit der Namen "FindeBaum" zwischen Datei und class-name:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public class FindeBaum extends JavaKaraProgram
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
<path>\Aufgabe1\FindeBaum.java
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
"<path>\Aufgabe1\FindeBaum.world"
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Diese Gleichheit der Namen wird in Zukunft unbedingte Voraussetzung für das
korrekte Funktionieren von Programmen sein!

Ebenso verlange ich eine saubere Unterteilung der einzelnen Dateien durch korrekte
Benennung der Verzeichnisse!

Achtet auf korrekte Schreibweise!
Keine Umlaute verwenden!
Keine Leerzeichen in Namen verwenden!
Bei Namensgebungen: Erster Buchstabe gross, Rest klein!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Jetzt wird es (begrenzt) spannend:

Betätigt nun den Knopf "Ausführen": Das zuvor editierte Programm "FindeBaum.java" läuft
in der gewohnten Form ab, falls ihr keine Fehler gemacht habt...

Kara bleibt vor dem Baum stehen. Seht ihr dieses Verhalten von Kara auch aus der Vorlage
des Quelltextes?

Hinweis: Die while-Schleife

while (!kara.treeFront())
{
kara.move();
}

bedeutet frei "übersetzt":
Das Objekt Kara bewegt sich solange einen Schritt vor, wie Karas Sensor "Ist vor mir ein
Baum?" falsch ist.

Das Ausrufungszeichen <!> wirkt als Negations-Operator (!...und wieder einmal die
Negation...).
Damit wird aus "solange ein Baum vor Kara steht" entsprechend "while (kara.treeFront())"
"solange kein Baum vor Kara steht" entsprechend "while (!kara.treeFront())".

Wenn dann ein Baum vor Kara steht, wird die while-Schleife und damit dann auch das
Programm beendet, da nach der while-Schleife keine weiteren Befehle mehr folgen.

Zusammenfassung:
Wir haben jetzt neben zur Programmierung von Kara zwei ähnliche Verfahren
kennengelernt:

1. Programmierung von Kara mit Zustandsautomaten.
2. Programmierung von Kara mit Java-Quelltexten.

In Zukunft widmen wir uns nur noch der zweiten Methode "Programmierung von Kara mit
Java-Quelltexten".
Aufgabe 2: Kara als Wächter (Innenläufer)

Aufgabe: Kara soll ein geschlossenes Rechteck von Bäumen von innen endlos umrunden.

Karas Vorgabe-Welt:

1. Speichere Karas Welt als "Aufgabe2\Innenlaeufer.world", ganz Schlaue von euch
kopieren sich die Welt von "Innenlauefer.world" der Aufgaben der letzten Woche!)

2. Schreibt einen Quelltext entsprechend der folgenden Vorgabe:

import javakara.JavaKaraProgram;

public class Innenlaeufer extends JavaKaraProgram
{
public void myProgram()
{
while (true)
{
if (kara.treeFront())
{
kara.turnLeft();
kara.move();
}
if (kara.treeRight())
{
kara.move();
}
}
}
}

Versuche, dieses Programm zu verstehen.

Speichere das Programm unter "Aufgabe2\Innenlaeufer.java" ab.

Starte das Programm mit der World-Datei "Innenlaeufer.world".

Experimentiere mit den if-Bedingungen. Benutze dazu das <!> (Negations-Operator).

Ersetze "while (true)" durch "while (1 == 1)" -> Ergebnis?
Vergleiche das Programm mit der Zustandstabelle:

Programm "Innenlaeufer"
Zustand Operation(en)
Start → Laufe

Laufe Baum vorn? Baum rechts
W W DL → Laufe
W F DL → Laufe
F W GV → Laufe
F F GV → Laufe

Stop: Ende

Fällt dir die "gute Lesbarkeit und Übersichtlichkeit" des Quelltextes gegenüber der
Zustandstabelle auf?
Aufgabe 3: Kara als Wächter (Aussenläufer)

Aufgabe: Kara soll ein geschlossenen Rechteck von Bäumen von aussen endlos umrunden.

Karas Vorgabe-Welt:

Speichere Karas Welt als "Aufgabe3\Aussenlaeufer.world".

Schreibe einen Quelltext entsprechend der folgenden Vorgabe - und hier sollt ihr mal selber
einen Quelltext entwerfen und natürlich auch testen:

import javakara.JavaKaraProgram;

public class Aussenlaeufer extends JavaKaraProgram
{
public void myProgram()
{
while (true)
{
if (kara.treeLeft())
{
kara.move();
} else
{
kara.turnLeft();
kara.move();
}
}
}
}

Speichere dieses Java-Programm unter "Aufgabe3\Aussenlaeufer.java".
Aufgabe 4: Kara sucht einen Ausgang

Aufgabe: Kara soll innerhalb einer (fast) geschlossenen Baumreihe derselben folgen und
dabei einen Ausgang suchen. Beim Durchschreiten und Verlassen des Ausgangs soll Kara
stehenbleiben.

Karas Vorgabe-Welt:

Speichere Karas Welt als "Aufgabe4\Ausgangssuche.world".

Schreibe einen Quelltext Java-Programm und teste dieses :

import javakara.JavaKaraProgram;

public class Ausgangssuche extends JavaKaraProgram
{
public void myProgram()
{
Boolean Search = true;
while (Search)
{
if (kara.treeLeft() && kara.treeFront())
{ // und-Bedingung für Ecke!
kara.turnRight();
kara.move();
} else
if (kara.treeLeft())
{ // keine Ecke und kein Ausgang:
kara.move();
} else
{ // Kara steht frei!
kara.turnLeft();
kara.move();
kara.move();
Search = false;
}
}
}
}

Speichere das Programm unter "Aufgabe4\Ausgangssuche.world".
Aufgabe 5: Kara merkt sich Kleeblattpositionen

Aufgabe: Kara soll in einem endlosen Feld (keine Ränder!) die Kleeblätter aufspüren und
sich in einer Gehirn-Matrix die Positionen der Kleeblätter merken. Ausserdem soll eine
Ausgabe der Kleebattpositionen in einem Kommandozeilen-Fenster erfolgen (!).

Karas Vorgabe-Welt:

Speichere Karas Welt als "Aufgabe5\Matrix.world".

Schreibe folgenden Quelltext, speichere in unter "Aufgabe5\Matrix.java" und teste ihn mit
Karas Welt.

Dazu starten wir JavaKara unter der sogenannten Kommandozeile:

"Start" – "Ausführen"

Es erscheint ein Fenster,

in welches ihr "cmd" eingebt und mit "OK" bestätigt.
Danach öffnet sich das Kommandozeilen-Fenster:

Ihr wechselt den Pfad zu eurem Projekt:

"<projdrive>:"
"cd <projectpath>"

Mit "dir" seht ihr alle Dateien eures Projekts.
Kopiert euch JavaKara "javakara-x.jar" in euer Projektverzeichnis.
Mit "java -jar javakara-x.jar" startet die Oberfläche des Marienkäfers:

Gebt jetzt den folgenden Quelltext ein.
import javakara.JavaKaraProgram; Programm
import javakara.JavaKaraProgram; "Matrix.java"
import java.util.*;
import java.io.*;

public class Matrix extends JavaKaraProgram
{
public void myProgram()
{
int LX = 5;
int LY = 5;
Boolean[][] Leaf = new Boolean[LX][LY];
String Line;

tools.println("\n\rStart:");
tools.println("Detection of leafs:");

for (int Y = 0; Y < LY; Y++)
{
Line = "";
for (int X = 0; X < LX; X++)
{
Leaf[X][Y] = kara.onLeaf();
if (Leaf[X][Y])
{
Line += " X";
} else
{
Line += " .";
}
kara.move();
}
tools.println(Line);
kara.turnRight();
kara.move();
kara.turnLeft();
}

tools.println("Inversion of leafs:");
for (int Y = 0; Y < LY; Y++)
{
for (int X = 0; X < LX; X++)
{
if (!Leaf[X][Y])
{
kara.putLeaf();
} else
{
kara.removeLeaf();
}
kara.move();
}
kara.turnRight();
kara.move();
kara.turnLeft();
}

tools.println("End.");
}
}
Ladet das die Matrix-Welt und das Matrix-Programm und startet wie gewohnt.

Als Neuerung seht ihr im Kommandozeilen-Fenster eine Ausgabe während des Programm-
ablaufs. Ihr seht ein Abbild der Kleeblattbesetzung, welche Kara vorfindet. Diese Ausgabe
erinnert uns an die Debug-Funktion unseres formlosen Ablaufdiagramms!
Lernziel 4: Übertragung von Programmstrukturen auf Java
● Vorstellung

Wiederholung zum besseren Verständnis:

Bisher: Kara
– Kara-Welt (<name>.world)
– Kara-Programm (<name>.kara)
– Die Programmierung von Kara erfolgt über Zustandsdiagramme.

Bisher: JavaKara
– Kara-Welt (<name>.world)
– Kara-Programm (<name>.java)
– Die Programmierung von Kara erfolgt über Java-Code. Dabei verfügt das Objekt Kara
über Methoden.

Jetzt bis zum Ende: Java
– Reines (pures) Java → kein Kara-Marienkäfer mehr!
– Keine Programmieroberfläche für Kara (Kara und Zustandsdiagramme) mehr.
– Keine Programmieroberfläche für JavaKara (Kara und Java-Code) mehr.
– Neu: Programmieroberfläche NetBeans (typisch Version 6.7.1)

Installation von Java/JavaBeans

Alle, die Aufgabe 1 zum 29. August 2009 gelöst haben, können die Installation von
NetBeans als erledigt betrachten.

Für den Rest gilt: Die Installation von NetBeans entsprechend Aufgabe 1 zum 29. August
2009 unbedingt durchführen!

Ohne NetBeans werdet ihr in Zukunft keine Aufgaben bzw. Übungen mehr durchführen
können.

Für alle Kursteilnehmer gilt:
Gebt mir in jedem Fall nach erfolgter oder fehlerhafter Installation von NetBeans
Rückmeldung per Email!

Zum besseren Verständnis:

Die Installation von NetBeans beinhaltet in unserem Fall auch die Installation von Java.

Java mit seiner Java-Virtual-Machine (JVM) (Datei: "java.exe") ermöglicht auf jedem
Betriebssystem die Ausführung des durch den Java-Compiler (Datei: "javac.exe") zuvor
übersetzten Codes (Datei: Java-Quelltext -> .jar-Datei) eine Ausührung dieses Codes durch
diese virtuelle Maschine (Interpreter).
Ergänzend: Wikipedia: Java

"Java ist eine objektorientierte Programmiersprache und als solche ein eingetragenes
Warenzeichen der Firma Sun Microsystems. Sie ist eine Komponente der Java-Technologie.

Java-Programme werden in Bytecode übersetzt und dann in einer speziellen Umgebung
ausgeführt, die als Java-Laufzeitumgebung oder Java-Plattform bezeichnet wird. Deren
wichtigster Bestandteil ist die Java Virtual Machine (Java-VM), die die Programme
ausführt, indem sie den Bytecode interpretiert und bei Bedarf kompiliert (Hotspot-
Optimierung).

Java-Programme sind plattformunabhängig, das heißt sie laufen in aller Regel ohne weitere
Anpassungen auf verschiedenen Computern und Betriebssystemen, für die eine Java-VM
existiert. Sun selbst bietet Java-VMs für die Betriebssysteme Linux, Solaris und Windows
an. Andere Hersteller lassen ihre Java-VM für ihre Plattform zertifizieren, zum Beispiel die
Firma Apple für Mac OS X."

Ergänzend: Wikipedia: Java Virtual Machine

"Die Java Virtual Machine (abgekürzt Java VM oder JVM) ist der Teil der Java-
Laufzeitumgebung (JRE) für Java-Programme, der für die Ausführung des Java-Bytecodes
verantwortlich ist. Hierbei wird im Normalfall jedes gestartete Java-Programm in seiner
eigenen virtuellen Maschine ausgeführt. Der andere Teil der Java-Laufzeitumgebung sind
die Java-Klassenbibliotheken.

Die JVM dient dabei als Schnittstelle zur Maschine und zum Betriebssystem und ist für die
meisten Plattformen verfügbar. (z. B. Linux, Mac, Palm OS, Solaris, Windows, usw.). Die
JVM ist in den Programmiersprachen C und C++ geschrieben."

Programmieren in Java

An dieser Stelle zitiere ich wieder Herrn Flemming (FKG Open Book, "Kurzer Einstieg in
die Programmierung"):

"Computerprogramme sind meist auf einen Prozessor und ein Betriebssystem zugeschnitten.
Java-Programme sollen aber überall lauffähig sein. Dazu muss es ein Programm geben,
welches überall eine einheitliche Umgebung anbietet. Das ist die sogenannte Java-Maschine
(java.exe).

Weiterhin müssen Programme in eine Form gebracht werden, welche die Java-Maschine
versteht. Diese Übersetzungsaufgabe erledigt der Java-Compiler (javac.exe). Ein Java-
Programm muss nach jeder Änderung neu übersetzt werden. Java-Quelltexte haben die
Endung java, die übersetzten Programme haben die Endung class. Oft werden die vielen
Einzeldateien, die zu einem Javaprogramm gehören, in ein Archiv gepackt (Endung jar).
Auf vielen Maschinen ist die Endung jar bereits mit der Java-Maschine verknüpft, so dass
man die Programme mit einem Doppeklick starten kann.

Ein Programmierer muss sich all diese Programme besorgen. Dabei hat er die Wahl
zwischen verschiedenen Entwicklungsumgebungen. Im Folgenden soll das Vorgehen am
Beispiel der Sun-IDE NetBeans demonstriert werden."
– Lernziel 4: Übertragung von Programmstrukturen auf Java
● Einfache Übungen

1. Übung: Starten von JavaBeans

Nach erfolgreicher Installation starten wir NetBeans über:

"Start" – "Programme" – "NetBeans" – "NetBeans IDE 6.7.1" (blauer Würfel)

oder durch Doppelklick auf das Desktop-Icon "NetBeans IDE 6.7.1" (blauer Würfel).

Es vollzieht sich ein längerer Ladevorgang, bei dem das NetBeans-Lade-Logo erscheint:

und dann das IDE ("Integrated Development Environment", wir sagen auch "die IDE"
eingedeutscht für "die integrierte Entwicklungsumgebung").

Geben wir zuerst die Optionen für eine angemessene Tabulator-Schrittweite des Editors vor.
Unter "Tools" – "Options" geben wir die Grösse "2" für "Tabs and Indents" ein:
Die Entwicklungsumgebung "NetBeans" erlaubt dem Programmierer:

– die Eingabe von Java-Quelltexten ("<name>.java"), 1

– das Compilieren von Java-Quelltexten ("<name>.java" → "<name>.class")

– die Verwaltung von eigenen Projekten und Bibliotheken (Software-Module), 2

– das Ausprobieren des Laufzeitverhaltens seiner Software-Module mit dem Debugger
oder mit dem Ausgabefenster, 3

– die Analyse der Struktur seiner Software-Module, 4

– noch eine gewaltige Menge an Funktionalität, die wir zum Teil noch später
kennenlernen.

Ihr erkennt den einfachen Quelltext von "HelloWorld" – das Standard-Beginner-Programm
für alle Programmiersprachen.

2
1
3

4

Mit Druck auf "F6" startet ihr den Compiler. Falls der Quelltext keine Compile-Time-Error
enthält, startet die IDE die Ausführung des Programms im Ausgabefenster. Ihr seht die
Ausgabe von "Hello world!" (!).
2. Übung: Das erste Java-Programm "HelloWorld.java"

Startet die IDE und erzeugt ein neues Projekt "HelloWorld" durch:

"File" - "New Project"

"Next"
WICHTIG:
Alle Eingaben von "HelloWorld" erfolgen kompromisslos in genau dieser Schreibweise!!!

Nach "Finish" erzeugt die IDE ein neues "HelloWorld"-Projekt und ihr seht die IDE mit
entsprechendem Erscheinungsbild:

Falls die geschweiften Klammern dem von mir geforderten und eurem Schönheitsbild
entsprechen, ändert dieselben im Quelltext entsprechend.

Damit in Zukunft die durch die IDE automatisch generierten Quelltexte gleich wie oben
formatiert sind, ändert über "Tools" – "Templates"
das "Java Main Class"-Template mit dem in der IDE integrierten Editor durch Druck auf
"Open in Editor" und nach entsprechender Umformatierung der folgende zu speichernde
Text:

//
//---------------------------------------------
//
// Project:
//
//---------------------------------------------
//
// Date:
// Time:
// Version:
// Author:
// Description:
//
//
<#if package?? && package != "">
package ${package};

</#if>
public class ${name}
{
public static void main(String[] args)
{
}
}

Damit erhaltet ihr auf eurem Rechner bei der nächsten automatischen Projekt-Generierung
einen Quelltext mit "korrekter" Formatierung!

So soll unser Endergebnis aussehen:
Nach diesen Vorbereitungen geben wir den Quelltext von "HelloWorld" ein:

//
//--------------------------------------------- Quelltext
//
// Project: HelloWorld
//
//---------------------------------------------
//
// Date: 090923
// Time: 0945
// Version: 01V0101
// Author: OM
// Description:
// First Sample for demonstrating println-output.
//
//
package HelloWorld;

import static java.lang.System.out;

public class Main
{
public static void main(String[] args)
{
out.println("Hello world!");
}
}

Jetzt starten wir die Ausführung des Programms mit "F6" oder .

Im Ausgabefenster sehen wir nach dem Programmlauf die Ausgabe:

run:
Hello world! Konsole
BUILD SUCCESSFUL (total time: 0 seconds)

Hat alles geklappt? Glückwunsch!

Die Methode <println("Hello world!");> des Objekts "out" derselben Klassenbibliothek
"java.lang.System.out" erzeugt die Ausgabe im Konsolenfenster "Hello world!".

Das Betriebssystem führt beim Start des Programms "HelloWorld" die "main"-Methode des
Objekts "Main" aus. In dieser Methode steht nur ein einziger Befehl: die Ausgabe von
"Hello world!" im Konsolenfenster.

Beachtet vor allem die Kommentarzeilen des Quelltextes:
Zu einem guten Programmierstil gehört die Eingabe der Inhalte der "Project"-...
"Description"-Einträge durch den Programmierer.
– Lernziel 4: Übertragung von Programmstrukturen auf Java
● Java-Elemente: Anweisungen und Ausdrücke

Frage: Was ist ein Ausdruck, was ist eine Zuweisung?

Antwort: Unter einem Ausdruck verstehen wir eine Folge von mathematischen
Anweisungen, die einen arithmetischer Term bilden.
Das Ergebnis der Berechnung des Ausdrucks ergibt einen Wert. Dieser Wert des Ausdrucks
kann unterschiedlichen Typs sein:

– Ganzzahl-Typ (int)
– Fliesskomma-Typ (double)
– Wahrheits-Typ (Boolean)
– Text-Typ (String)

In einer Zuweisung wird einer Variablen (linke Seite, "X") der Wert eines Ausdrucks (rechte
Seite. "3 + 5") zugewiesen:

int X = 3 + 5;

Wir erzeugen das Projekt "Assignment" und geben als Quelltext in "Main" vor:

public class Main
{
public static void main(String[] args)
{
int I, J;
double X, Y;
boolean Result; Quelltext Projekt "Assignment"
String Line;

// Integer-Assignment
I = 3;
J = I + 1;
Line = "I = " + I;
out.println(Line);
Line = "J = " + J;
out.println(Line);

// Double-Assignment
X = 1.234;
Y = 2.123 * X;
Line = "X = " + X;
out.println(Line);
Line = "Y = " + Y;
out.println(Line);

// Boolean-Assignments
Result = (1.234 == X);
Line = "Result(==) = " + Result;
out.println(Line);
Result = (X == Y);
Line = "Result(!=) = " + Result;
out.println(Line);
}
}
Dann starten wir das Programm und analysieren die Ausgabe:

run:
I = 3
J = 4 Ausgabe Projekt "Assignment"
X = 1.234
Y = 2.6197820000000003
Result(==) = true
Result(!=) = false
BUILD SUCCESSFUL (total time: 0 seconds)

Das Programm arbeitet seinen Code von oben nach unten ab und liefert uns die Ausgaben
für "I", "J", "X", "Y" und "Result".

Die Zuweisungen der Variablen erfolgen nach der Auswertung der mathematischen
Ausdrücke.

Arbeiten mit dem Debugger

Wir sehen durch nach Aufruf der "out.println"-Methoden die Ergebnisse im
Ausgabefenster.
Die IDE bietet neben der Ausgabe der "Zwischenergebnisse von Hand" noch die
Möglichkeit der interaktiven Prüfung der Ausführung aller einzelnen Befehle mit dem
integrierten Debugger.

Dazu setzen wir mit der Maus im linken grauen Rand des Quelltext-Fensters einen
"Breakpoint":
nt
oi
kp
ea
Br

Starten wir jetzt das Programm nicht mit "F6" sondern mit

Debug über Menü

bzw. durch drücken auf:

Debug über Hotkey
Die Ausführung des Programms wird gestartet und ein grüner Pfeil zeigt den Stillstand des
Programms an dem Breakpoint an:

Für einen Schritt (eine Befehlszeile) weiter drücken wir "F8":

Gehen wir jetzt mit der Maus auf "I", so sehen wir einen Hint: I = (int) 3
Der Hint liefert uns damit den aktuellen Wert der Variablen "I"!

Noch interessanter zeigen sich uns die Werte aller Variablen über:

"Window" - "Debugging" - "Variables"

Hier entdecken wir die aktuellen Werte aller sichtbaren Variablen:

Speziell für "I" erkennen wir ebenfalls den schon zuvor beschriebenen Wert von "3";
Wieder mit "F8" weisen wir im Einzelschritt (SingleStep) der Variablen "J" den Wert "4"
zu:

rJ
tfü
er
rW
ue
Ne
Weiter mit
– "F8" : SingleStep – Anhalten nach jeder Zeile
– "F5" : Continue – Normaler Ablauf

Beobachte die Veränderung der Variableninhalte in Abhängigkeit der Abarbeitung der
Kommandos!

Gleichzeitig zu den Änderungen der Variableninhalte beobachte die Ausgaben im
Ausgabefenster:

Alle Inhalte ändern sich synchron zu den Eingaben der IDE!

Zusammenfassung

In diesem Abschnitt lernten wir arithmetische Ausdrücke und Zuweisungen in Java
kennen.

Mit Hilfe der JavaBeans IDE erzeugten wir ein Projekt, editierten den Quelltext des
Projekts, starteten den Compiler und die Ausführung des Programms.

Neben den Ausgaben im Kommanozeilen-Fenster lernten wir den Umgang mit dem
Debugger

Widmen wir uns nun weiteren Anweisungen.
Lernziel 4: Übertragung von Programmstrukturen auf Java
● Java-Elemente: Weitere Anweisungen

Welche weiteren Anweisungen lernen wir kennen?

Die folgenden Anweisungen:
– "if"- Bedingung
– "switch"- Bedingung
– "for"- Schleife
– "while"- Schleife

Dabei sind "if" und "switch" Bedingungsanweisungen, "for" und "while"
Schleifenanweisungen.

Einsatz der Anweisungen

Anweisung Gruppe Pseudo-Erklärung
if Bedingung ohne else:
Wenn Bedingung, dann BlockTrue
mit else:
Wenn Bedingung, dann BlockTrue, sonst
BlockFalse
switch Bedingung Mehrfache Abfrage aller möglichen Ergebnisse
einer Bedingung:
Wenn Bedingung
Fall1: Block1 sonst Fall2: Block2 sonst...
FallN: BlockN alternativ BloackAlternativ
for Schleife Schleife mit einer Variablen Index von Start bis
Ende: Bearbeite Block mit aktuellem Index
while Schleife Solange Bedingung bearbeite Block

Neben diesen Anweisungen gibt es noch die "do"-Schleife, die aber redundant neben der
"while"-Schleife existiert.
Anweisung: "if"- Bedingung

Quelltext-Beispiel

//
//---------------------------------------------
//
// Project: ConditionIf
//
//---------------------------------------------
//
// Date: 090924
// Time: 1733
// Version: 01V0101
// Author: OM Quelltext Projekt "ConditionIf"
// Description:
// Demo "if"
//
package ConditionIf;

import static java.lang.System.out;

public class Main
{
public static void main(String[] args)
{
int I, J;

I = 3;
J = 5;

String Line;

if (I == J) "if"-Bedingung
{
Line = "Equal: I(" + I + ") == J(" + J + ")";
} else
{
Line = "Unequal: I(" + I + ") != J(" + J + ")";
}

out.println(Line);
}
}

Ausgabe des Beispielprogramms "ConditionIf"

run:
Unequal: I(3) != J(5) "if"-Bedingung ergibt false
BUILD SUCCESSFUL (total time: 1 second)

Ändern wir die Zuweisung "I = 3;" in "I = 5;" erhalten wir die Ausgabe

run:
Equal: I(5) == J(5) "if"-Bedingung ergibt true
BUILD SUCCESSFUL (total time: 0 seconds)
Syntax der "if"-Bedingung:

if <condition> if <condition>
{ // case true {
<statement(s)> <blocktrue>
} else } else
{ // case false {
<statement(s)> <blockfalse>
} }

Das Symbol Block <block> steht für eine Anweisung oder eine Folge von
Anweisungen:

<block> == <statement(s)>
== <statement1>; <statement2>; .. <statementn>;
Anweisung: "for"- Schleife

Quelltext-Beispiel

//
//---------------------------------------------
//
// Project: LoopFor
//
//---------------------------------------------
//
// Date: 090924
// Time: 1955
// Version: 01V0101
// Author: OM Quelltext Projekt "LoopFor"
// Description:
// Demo "for"
//
package LoopFor;

import static java.lang.System.out;

public class Main
{
public static void main(String[] args)
{
for (int I = 0; I < 3; I++) "for"-Schleife
{
String Line = " " + I;
out.println(I);
}
}
}

Ausgabe des Beispielprogramms "LoopFor":
run:
0
1
2
BUILD SUCCESSFUL (total time: 0 seconds)

Syntax der "for"-Schleife:

for (<indexassignment> ; <indexcondition> ; <indexassignment>)
{
<block>
}
Anweisung: "switch"- Bedingung

Quelltext-Beispiel "ConditionSwitch"

//
//
//---------------------------------------------
//
// Date: 090925
// Time: 0734
// Version: 01V0101
// Author: OM
// Description: Quelltext Projekt "ConditionSwitch"
// Demo "switch"
//
package ConditionSwitch;

import static java.lang.System.out;

public class Main
{
public static void main(String[] args)
{
int State = 2;
String Line = "";

switch (State)
{
case 1:
Line = "State is 1";
break;
case 2:
Line = "State is 2";
break;
default:
Line = "State is undefined";
break;
}
out.println(Line);
}
}

Ausgabe des Beispielprogramms "ConditionSwitch":

run:
State is 2
BUILD SUCCESSFUL (total time: 0 seconds)0
Syntax der "switch"-Bedingung:

switch <expression>
{
case <constant expression 1>:
<statement(s) 1>
break;
case <constant expression 2>:
<statement(s) 2>
break;
case <constant expression 3>:
<statement(s) 3>
break;
...
case <constant expression n>:
<statement(s) n>
break;
default:
<statement(s)>
break;
}

Die <break>-Anweisungen sind Pflicht!

Testet den Quelltext mit dem Debugger bis zu folgendem Zustand:

Die Variable Line mit dem eigentlichen Inhalt "State is 2" wird inkorrekt durch "State is
undefined" überschrieben und dieser Wert dann (falsch) ausgegeben:

debug:
State is undefined
BUILD SUCCESSFUL (total time: 9 minutes 17 seconds)
Anweisung: "while"- Schleife

Quelltext-Beispiel "LoopWhile"

//
//
//---------------------------------------------
//
// Project: LoopWhile
//
//---------------------------------------------
//
// Date: 090925
// Time: 0807
// Version: 01V0101
// Author: OM
Quelltext Projekt "LoopWhile"
// Description:
// Demo "while"
//
package LoopWhile;

import static java.lang.System.out;

public class Main
{
public static void main(String[] args)
{
int I = 1;
while (I <= 3)
{
out.println(I);
I++;
}
}
}

Ausgabe des Beispielprogramms "LoopWhile":

run:
1
2
3
BUILD SUCCESSFUL (total time: 0 seconds)

Syntax der "while"-Bedingung:

while <condition>
{
<block>
}
Lernziel 4: Übertragung von Programmstrukturen auf Java
● Java-Elemente: Variablen und Datentypen