Programmieren: Einstieg zu Java mit BlueJ Der folgende Text und die Aufgaben stützen sich auf das Buch "Java lernen mit BlueJ" (David J. Barnes und Michael Kölling). BlueJ ist eine Java-Entwicklungsumgebung, die an der Deakin University, Australien, und der University of Kent in Canterbury, England ausdrücklich mit dem Ziel entwickelt wurde, der Einführung in die objektorientierte Programmierung zu dienen. BlueJ eignet sich sehr gut, um zu verstehen, was eine Klasse, ein Objekt oder eine Methode ist und ist sehr übersichtlich gestaltet. BlueJ kann kostenlos von www.bluej.org heruntergeladen werden. Um die folgenden Aufgaben lösen zu können, müssen die vorbereiteten Projekte auf einen beschreibbaren Datenträger (Festplatte oder Stick) gespeichert werden. Kopiere also die auf Moodle vorbereiteten "Projekte" auf dein persönliches Gerät oder deinen Stick. Allgemeines zur Benutzung von BlueJ Nach dem Öffnen oder erstellen eines BlueJ-Projekts erscheint im Fenster ein Diagramm mit verschiedenen Feldern. Jedes dieser Felder symbolisiert eine Klasse. Die Pfeile geben an, wie die Klassen miteinander verknüpft sind. Die Klassen können einzeln kompiliert werden (Rechtsklick auf die Klasse -> compile) oder alle zusammen (Linksklick auf das Feld compile). Der Code der einzelnen Klassen kann problemlos angeschaut werden (Rechtsklick auf die Klasse -> Open Editor). Die Beispiele können evtl. nicht geändert und unter gleichem Namen gespeichert werden. Solltest du eines der Beispiele ändern wollen, speichere es untern einem neuen Namen. Dies ist auch sinnvoll, wenn die Änderungen unter gleichem Namen gehen – so hast du sicher noch immer die ursprüngliche Version des Programms. Von jeder Klasse können nun verschiedene Objekte erzeugt werden (Rechtsklick auf die Klasse -> new …). Die Objekte erscheinen als rote Felder unterhalb des Diagramms. Ein Rechtsklick auf die Objekte zeigt nun die verschiedenen Methoden, mit welchen die Objekte verändert werden können. B. Bieri: Java mit BlueJ 1 Zeichnen mit BlueJ Aufgabe 1 Starte BlueJ und öffne das Projekt "Figuren" (Project -> Open Project -> Figuren). Erzeuge ein Objekt der Klasse Kreis, mache ein Objekt davon sichtbar und bewege es in deinem Feld hin und her. Ändere die Farbe deines Kreises. (Diese Aufgabe dient nur dazu, dass du dich mit BlueJ etwas vertraut machen kannst. Programmieren musst du bei dieser Aufgabe noch nichts.) Aufgabe 2 Betrachte den Code des Kreises und ändere diesen so, a) dass die Bewegung nach rechts doppelt so weit geht, b) der Kreis eine andere Farbe bekommt. Versuche andere Änderungen beim Kreis vorzunehmen. Aufgabe 3 Erzeuge mehrere Objekte und bewege diese so lange, bis sie das Bild eines Hauses mit einer Sonne bilden. (Auch für diese Aufgabe muss nichts programmiert werden.) Aufgabe 4 Warum weiss das Programm was du meinst, wenn du die Farbe z.B. von "blau" auf "rot" änderst? (Beim Turtle mussten wir doch immer Color.red schreiben…). Aufgabe 5 Öffne nun das Projekt "Zeichnung". Du siehst, dass zusätzlich zu den bereits bekannten Klassen eine Klasse "Zeichnung" hinzugefügt wurde. Das Diagramm zeigt, dass die Klasse Zeichnung die Figuren der vorherigen Aufgabe benutzt. Wenn du den Code der Klasse Zeichnung anschaust, siehst du, dass diese Klasse durch den Aufruf der Methode "zeichne" Objekte der Klassen aus der letzten Aufgabe erzeugt und diese so bewegt, dass ein Haus entsteht. Das Programm macht also genau das, was du bei Aufgabe 3 mühsam selbst von Hand gemacht hast. Füge der Zeichnung eine Wolke hinzu, welche die Sonne teilweise verdeckt – die Form der Wolke ist nicht so wichtig – sie sollte aber blau sein. Zusatzaufgabe: Füge der Zeichnung eine zweite Sonne hinzu, welche beim Aufruf der Methode "Sonnenuntergang" (auch diese muss noch geschrieben werden), langsam untergeht. B. Bieri: Java mit BlueJ 2 Hinweise zu neuen Befehlen Aus Scratch und Turtle sind euch viele Befehle schon sehr vertraut. Einige Dinge, welche in den folgenden Aufgaben vorkommen sind aber neu. System.out.println(…) Z.B. ist euch die Methode "System.out.println(…) unbekannt. Diese Methode gibt ihre Parameter auf der Konsole aus. In der Klammer können "Strings" also Textteile oder Zahlen stehen. Handelt es sich bei der Ausgabe um Text, muss dieser in Anführungszeichen gesetzt werden. Bei Zahlen ist dies nicht nötig. Verschiedene Ausgaben werden mit einem + verknüpft. Kommentare Oft ist es sinnvoll, den eigenen (oder fremden) Code zu kommentieren, damit man später wieder versteht, was man gemacht hat. Ist der Kommentar nur eine Zeile lang, kann dieser mit // gekennzeichnet werden. (Text, welcher hinter // steht, wird vom Programm nicht beachtet.) Ist der Kommentar länger als eine Zeile, wird das Zeichen /* für den Beginn des Kommentars und */ für das Ende des Kommentars verwendet. Logische Operatoren Nicht immer reicht ein <, > oder == in einer "If-Abfrage". Manchmal möchte man auch mehrere Bedingungen gleichzeitig erfüllt haben. Um Mehrere Bedingungen zu verknüpfen brauchen wir logische Operatoren: && bedeutet "und": Z.B. wird (x>3 && x<5) erfüllt, wenn x grösser als 3 und kleiner als 5 ist – also nur für x=4. || bedeutet "oder": Z.B. wird (x==4 || x<=2) für die Natürlichen Zahlen {1,2,4} erfüllt. ! bedeutet "nicht": Z.B. wird (x%2!=0) für ungerade Zahlen erfüllt. (Das "Modulo" kennt ihr ja bereits vom Turtle.) Beachte immer, was stärker bindet (wie bei "Punkt vor Strich" in der Mathematik). Setze im Zweifelsfall Klammern. Aufgabe 1 Gib an, mit welchen natürlichen Zahlen die folgenden logischen Ausdrücke "wahr" sind: a) !(x>5) && (x%2==0) b) (x!=2) && (x<4) c) (x<4) || (x>20 && x<25) B. Bieri: Java mit BlueJ 3 Lösungen zu Aufgabe 1 a) {2,4} b) {1,3} c) {1,2,3,21,22,23,24} Aufgabe 2 Schreibe selbst einige logische Operationen auf, welche dann von deinen KollegInnen gelöst werden müssen. B. Bieri: Java mit BlueJ 4 Einfache Programme ohne spezielle Bibliotheken Ihr habt sicher festgestellt, dass ihr für die Zeichnungen bei den ersten Aufgaben – ähnlich wie bei Turtle – bereits vorbereitete Bibliotheken verwendet habt. Diese wurden zu Beginn des Programms importiert. Im Folgenden werden wir ein Programm anschauen, welches ohne spezielle Bibliotheken auskommt. Bei diesem kann also jeder Befehl im Code nachvollzogen werden. Aufgabe 1 Öffne (aus Kapitel 2) das Projekt "Naiver Ticketautomat". Lies den Code dieser Klasse und notiere dir, was das Programm kann und was für einen einigermassen sinnvollen Ticketautomat noch fehlt. Aufgabe 2 Ergänze den Ticketautomaten aus Aufgabe 1, damit er sinnvoll funktioniert. Je nach Zeit kannst du deinen Ticketautomat beliebig mit Funktionen erweitern. Aufgabe 3 Schreibe ein Programm, welchem du dein Gewicht und deine Grösse geben kannst, und welches dann deinen Bodymassindex berechnet und dir sagt, ob du Unter-, Über- oder Normalgewichtig bist. (Angaben darüber, wie man den Bodymassindex berechnet und wie die Zusammenhänge zwischen Alter, Bodymassindex und Normalgewicht sind, findest du im Internet.) Hinweis: Versuche nicht, alles auf einmal zu programmieren. Du kannst mit einem einfachen Programm beginnen und dieses dann laufend ergänzen: 1. Schreibe ein Programm, welches dir sagt, dass du dein Gewicht in Kilogramm und deine Grösse in Meter angeben sollst. 2. Ergänze dieses Programm um eine Methode, welcher du diese gewünschten Grössen geben kannst, und welches dir dann dein Gewicht und deine Grösse herausschreibt. 3. Ergänze dein Programm um eine Methode, welche deinen Bodymassindex berechnet und dir diesen herausschreibt. 4. Ergänze dein Programm um eine Methode, welcher du dein Alter geben kannst und welches dir dann aufgrund deines Bodymassindex sagt, ob du Unter-, Über- oder Normalgewichtig bist. B. Bieri: Java mit BlueJ 5 Aufgabe 4 Schreibe ein Programm, mit welchem ein Primarschüler das Kopfrechnen trainieren kann. Man soll angeben können, wie gross die zu verrechnenden Zahlen höchstens sein sollen. Das Programm muss dann zwei Zahlen in der gewünschten Grösse herausschreiben. Danach soll eine Methode gewählt werden können, welche einem nach der Summe, dem Produkt oder der Differenz der beiden Zahlen fragt und je nach Antwort, welche man gibt lobt oder tadelt. Achtung: Primarschüler kennen keine negativen Zahlen. Bei der Subtraktion werden sie einfach die kleinere Zahl von der grösseren subtrahieren. Hinweis Beginne auch bei dieser Aufgabe mit einem einfachen Programm, welches du dann immer mehr erweiterst. B. Bieri: Java mit BlueJ 6 Berechnungen mit Java Numerik Um aufwändige Rechnungen zu erledigen, sind Computer besonders geeignet. Bevor wir eine Anwendung kennenlernen, welches speziell für die Mathematik entwickelt wurde, werden wir ein erstes einfaches Mathematikprogramm mit BlueJ erstellen. Das Gebiet, welches sich damit beschäftigt, wie man komplexe Aufgaben der Mathematik mit dem Computer annähernd lösen kann, wird Numerik genannt. Scanner importieren und verwenden Für die folgende Aufgabe soll es möglich sein, anzugeben, wie viele Iterationen die Berechnung machen soll. Dazu muss das Programm Zahlen verwenden, welche zuvor vom Benutzer angegeben werden. Dazu braucht es einen "Scanner", welcher in der Lage ist, eingegebene Zahlen ins Programm einzulesen. Dazu ist es nötig, diesen Scanner am Anfang des Programms zu importieren: import java.util.Scanner; Zuerst muss ein Objekt der Klasse Scanner erzeugt werden: Scanner sc = new Scanner(System.in); So kann später der Befehl: sc.nextInt(); verwendet werden. Dieser Befehl liest jeweils die nächste Zahl ein, welche vom Benutzer eingegeben wird. Berechnung von Pi mit Hilfe einer unendlichen Summe Ca. 1658 fanden Madhava, James Gregory und Gottfied Willhelm Leibniz eine Formel zur Berechnung von Pi über eine unendliche Summe. Die Formel lautet: 1 1 1 1 1 1 . 1 ... 1 (1)i 4 3 5 7 9 11 2i 1 i 1 Je mehr Summanden wir nehmen, umso genauer wird unsere Zahl Pi angenähert. Von Hand ist dies eine sehr aufwändige Methode. Da der Computer in der Lage ist, sehr schnell viele Summanden zu addieren, eignet sich diese Methode, um Pi mit Hilfe eines Computers anzunähern. B. Bieri: Java mit BlueJ 7 Aufgabe 1 Schreibe ein Programm, in welchem man die Anzahl Iterationen (also die Anzahl Summanden) eingeben kann und welches dann das angenäherte Pi rausgibt. Hinweis: Eine einfache Möglichkeit, das Programm zu schreiben ist, Pi zuerst auf 1 zu setzen und dann mit einer for-Schleife in jedem Durchgang den neuen Summanden dazu zu addieren. (Das vorherige Pi wird dann also überschrieben und die Anzahl Durchgänge der Schleife entsprechen der Anzahl gewünschter Iterationen.) Aufgabe 2 Teste dein Programm, nachdem du es geschrieben hast, indem du die Zahl der Iterationen variierst: Deine Zahl sollte sich mit höheren Iterationen Pi immer genauer annähern, bzw. die Zahl sollte gleich bleiben, wenn du mehrmals hintereinander die gleiche Iterationenanzahl angibst. B. Bieri: Java mit BlueJ 8 Bisektion: Ein numerisches Verfahren zur Bestimmung von Nullstellen Für lineare bzw. quadratische Funktionen benötigen wir keine numerischen Verfahren. Solche Gleichungen können einfach und exakt gelöst werden. Wenn wir aber kompliziertere Funktionen betrachten, kann es sein, dass es nicht mehr möglich ist, eine exakte Lösung zu finden und man zu numerischen Verfahren greift. Ein sehr einfaches (allerdings auch nicht sehr schnelles) Verfahren, um solche Nullstellen anzunähern, ist das Bisektionsverfahren. Eine wichtige Voraussetzung für das Bisektionsverfahren ist, dass die Funktion stetig ist – also keine Sprungstellen hat. Offensichtlich sind die Werte einer Funktion f auf der einen Seite der Nullstelle negativ und auf der anderen Seite positiv. Für die Beschreibung des Verfahrens gehen wir hier von einer Funktion aus, welche um die Nullstelle herum steigt. Weiter nehmen wir an, dass die Funktion im Intervall [a; b] eine Nullstelle hat. Es gilt also: f hat eine Nullstelle in [a; b] und es gilt f(a) < 0 und f(b) > 0. Wir halbieren nun das Intervall [a; b] und geben dem Mittelpunkt dieses Intervalls einen neuen Namen - zum Beispiel m. Jetzt untersuchen wir die Funktion f an der Stelle m und schauen, ob f(m) < 0 oder f(m) > 0 ist. f(m) < 0 würde bedeuten, dass die Nullstelle zwischen m und b liegt. f(m) > 0 würde bedeuten, dass die Nullstelle zwischen a und m liegt. Um weiterzufahren, wählen wir das Intervall aus, in welchem sich die Nullstelle befindet (also [m; b] oder [a;m]) und halbieren dieses ... So geht das weiter, bis wir ein Intervall haben, das klein genug ist, um unserem Anspruch an Genauigkeit zu genügen. B. Bieri: Java mit BlueJ 9 Beispiel zur Bisektion Gegeben ist die Funktion f(x) = x5-4x2+1. Diese Funktion hat im Intervall [1; 2] eine Nullstelle. Berechne diese so genau, dass der Fehler nicht grösser als 0.125 ist. Lösung zum Beispiel Zunächst schauen wir, ob die Funktion im Intervall [1; 2] tatsächlich eine Nullstelle haben muss: f(1) = 15 – 4·12 + 1 = -2 f(2) = 25 – 4·22 + 1 = 17 => f(1) < 0 < f(2) => Da die Funktion stetig ist, muss sie im Intervall [1; 2] eine Nullstelle haben. Wir betrachten nun den Mittelpunkt des Intervalls [1; 2]: m1 = (1+2)/2 = 1.75 f(1.5) = 1.55 – 4·1.52 + 1 = -0.4 < 0 Die Nullstelle liegt also im Intervall [1.5; 2] und wir fahren mit diesem Intervall weiter: m2 = (1.5+2)/2 = 1.75 f(1.75) = 1.755 – 4·1.752 + 1 = 5.1 > 0 Die Nullstelle liegt also im Intervall [1:5; 1:75] und wir fahren mit diesem Intervall weiter: m3 = (1.5+1.75)/2 = 1.625 f(1:625) = 1.6255 – 4·1.6252 + 1 = 1.768 > 0 Die Nullstelle liegt also im Intervall [1:5; 1:625]. Da dieses Intervall nun nicht mehr grösser ist als 0.125, kann auch der Fehler nicht mehr grösser sein und wir können das Verfahren hier abbrechen. Der genaue Wert beträgt 1.5286. B. Bieri: Java mit BlueJ 10 Aufgabe 1 Schreibe ein Programm, welches für die Funktion f(x)=x2-4x+3 angibt, in welchem Intervall die Nullstelle liegt. (Die Funktion darf direkt im Code eingetragen werden.) Folgende Eingaben müssen bei dem Programm gemacht werden können: 1. Obergrenze des Startintervalls 2. Untergrenze des Startintervalls 3. Toleranz: So gross darf der Abstand der berechneten Lösung höchstens vom korrekten Resultat abweichen. Das Programm muss folgende Methoden haben: Eingabe: Hier muss man die Eingaben machen können. NullstelleUeberpruefen: Es wird überprüft, ob die Funktion zwischen den gegebenen Grenzen überhaupt eine Nullstelle haben muss. LoesungsintervallAusgeben: Es wird ein Intervall ausgegeben, in welchem sich die Nullstelle befindet. Das Intervall darf nicht grösser sein, als die Toleranz, welche in der Methode Eingabe angegeben wurde. B. Bieri: Java mit BlueJ 11