Schrittweise Verfeinerung
Wiederholung Was ist Programmieren? Lösungsidee Algorithmische Lösung Programm programmieren Problemstellung Lösung in der Form eines korrekten Programm Testplan Testfälle Testprogramm testen Programm löst Problemstellung Programm setzt eine algorithmisches Lösung in ein ausführbares Programm um Programm in Programmiersprache formuliert besteht aus durch den Computer ausführbaren Grundoperationen Test zeigt, dass Programm die Problemstellung richtig löst
Arbeiten mit Patterns Muster = Schema zur Lösung häufiger Aufgaben Problemstellung zerfällt in eine Reihe von Teilproblemen Problemstellung Teilproblem 1 Teilproblem 2 Für jedes Teilproblem braucht man eine Lösungsidee Lösungsidee gibt Hinweis auf anwendbare Patterns im Erfahrungsschatz Abrufen, Auswahl und Zusammensetzen der Patterns gibt eine grundsätzliche Lösung Durch Verfeinerung und Konkretisierung dieser Lösung kommt man zum Programm Einlesen Summieren Zählen Mischen... Patterns Auswählen Abrufen Zusammensetzen Lösungsidee 1 Lösungsidee Einlesen Summieren Zählen Prüfen Durchschnitt Ausgabe Algorithmische Lösung Programm programmieren
Wiederholung Abstraktion mit Methoden Mit Methoden hat man ein Mittel komplexe Programmteile auf Namen + Parameter zu reduzieren Dadurch kann man Komplexität von einer Methode in aufgerufene Methoden verlagern Beispiele int IO.readInt() double Math.sin(double x) static public void main(string[] args) { int x = IO.readInt(); int y = IO.readInt(); int g = ggt(x, y) ; int ggt(int x, int y) IO.writeLn("GGT von " + x + " u. " + y " = " + g); static int ggt(int x, int y) { int rest = x % y; while (rest!= 0) { x = y; y = rest; rest = x % y; return y;
Entwurfsmethode Schrittweise Verfeinerung Zerlegung der Problemstellung in Teilprobleme Teilproblem 1 Problemstellung Ermittlung der Teillösungen für die Teilprobleme Teillösungen ergeben eine Gesamtlösung Lösung Teil 1 Teilproblem 2 Lösung Teil 2 Teilproblem 3-1 Lösung Teil 3-1 Teilproblem 3 Teilproblem 3-2 Lösung Teil 3-1 Lösung Teil 3 Gesamtlösung Setze Zerlegung der Teilprobleme in kleinere Teilprobleme fort, bis jedes Problem für sich lösbar ist Teilproblem 3-3 Lösung Teil 3-1
Verfeinerung mit Methodenabstraktion Zerlege eine Problemstellung in Teilprobleme Füge diese Teilprobleme in einen Ablauf zusammen Definiere für die Teilprobleme Methodenschnittstellen Definiere verwendete Variablen und Datenstrukturen Verfeinere die Teilprobleme, indem du Implementierungen der Methoden vornimmst Beispiel: Berechne GGT von 2 Zahlen //1. Lese Zahlen x und y ein //2. Berechne GGT von x und y //3. Gib Ergebnis aus //1. Lese Zahlen x und y ein int x = readnumber(1); int x = readnumber(2); //2. Berechne GGT von x und y int g = ggt(x, y); //3. Gib Ergebnis aus putoutggt(g); static int ggt(int x, int y) { int rest = x % y; while (rest!= 0) { x = y; y = rest; rest = x % y; return y;
Verfeinerung durch Konkretisierung Definiere einen Lösung für ein Problem durch einen groben Ablauf Wende dabei eventuell Patterns an Für noch nicht gelöste Teile schreibe entsprechende Kommentare Konkretisiere die noch nicht bekannten Programmteile, indem du schrittweise Lösungen dafür erstellst geeignete Datenstrukturen definierst Beispiel: Gib die Worthäufigkeiten aus //1. solange Wörter vorhanden // 1.1 lies Wort // 1.2 zähle Wort //2. Gib Häufigkeit der Wörter aus // Datenstruktur für Worthäufigkeiten Input in = new Input("input.txt"); String word = readword(); while (word!= null) { // Zähle Häufigkeit von word word = readword(); in.close(); // Gib Häufigkeit aus
Verfeinerung mit Objekten Finde für die Problemstellung hilfreiche Objekte; erzeuge entsprechende Objekte Delegiere Aufgaben an diese Objekte, indem du Methoden dieser Objekte verwendest Realisiere für diese Objekte Klassen mit den entsprechende Methoden Beispiel: // Datenstruktur für Worthäufigkeiten WordTable tab = new WordTable(); Input in = new Input("input.txt"); String word = readword(); while (word!= null) { // Zähle Häufigkeit von word tab.count(word); word = readword(); in.close(); // Gib Häufigkeit aus tab.print(); public class WordTable() { public void count(string word) {... public void print() {...
Was bringt das? Die Komplexität steigt überproportional mit der Programmgröße Halbierung der Programmgröße reduziert die Komplexität um mehr als die Hälfte! Komplexität c tatsächlich zu erwarten < c/2 Programmgröße n/2 n
Beispiel Zahlenratespiel Aufgabenstellung - Es soll folgendes Spiel implementiert werden: Das Programm denkt sich eine Zahl zwischen 1 und 100 aus Der Benutzer darf die Zahl raten und das Programm antwortet, ob die Zahl richtig ist, zu klein oder zu groß ist Mit dieser Information darf der Benutzer abermals raten Ein Spiel endet, wenn der Benutzer die Zahl erraten oder er mehr als x-mal geraten hat (mit x z.b. 10) Es können beliebig viele Spiele gespielt werden Über alle Spiele soll am Schluss eine Statistik ausgegeben werden: Anzahl der gespielten Spiele Anzahl der gewonnenen Spiele Durchschnittliche Anzahl der Versuche pro Spiel
Beispiel Zahlenratespiel : Entwurfschritte (1) 1. Entwurfschritt: // while user wants to play // play a game with the user // count game in statistics // put out a statistics of all games 2. Entwurfschritt: boolean playagain; // put out header do { // play a game with the user GuessingGame game = new GuessingGame(); game.play (); // count game in statistics playagain = /* read reply from user */ while (playagain); // put out a statistics of all games
Beispiel Zahlenratespiel : Entwurfschritte (2) 3. Entwurfschritt: Klasse GuessingGame und Methode play class GuessingGame { int number = /* choose number between 1 and 100 */; int guess; int nrguesses = 0; void play() { do { nrguesses++; guess = makeguess(nrguesses); if (guess == number) { IO.writeLn(guess + " is correct!"); else if (guess < number) { IO.writeLn("That's too low. Try again! "); else if (guess > number) { IO.writeLn("That's too high. Try again: "); while (/* not won and number guesses < max guesses */); putoutresult();...
Beispiel Zahlenratespiel : Entwurfschritte (3) 4. Entwurfschritt: GuessingGame und playgame verfeinert class GuessingGame { static final int MAX_GUESSES = 10; int number = (int)(math.random()*100.0) + 1; int guess; int nrguesses = 0; void play() { do { nrguesses++; guess = makeguess(nrguesses); if (guess == number) { IO.writeLn(guess + " is correct!"); else if (guess < number) { IO.writeLn("That's too low. Try again! "); else if (guess > number) { IO.writeLn("That's too high. Try again: "); while (guess!= number && nrguesses < MAX_GUESSES); putoutresult();...
Beispiel Zahlenratespiel : Entwurfschritte (4) int makeguess(int guesscount) { int g; IO.write(" Guess " + guesscount + ": "); g = IO.readInt(); while (!IO.isOk() g < 1 g > 100) { IO.write(" Repeat" + guesscount + ". Guess: "); g = IO.readInt(); return g; void putoutresult() { if (guess!= number) { IO.writeLn("You lost! You have guessed " + nrguesses + " times "); IO.writeLn(" and you have not found out that " + " the number would have been " + number); else { IO.writeLn("You have won! You needed " + nrguesses + " guesses!"); // end GuessingGame
Beispiel Zahlenratespiel : Entwurfschritte (5) 5. Entwurfschritt: Konkretisierung der main-methode public static void main(string[] args) { boolean playagain; GameStatistics statistics = new GameStatistics(); putoutheader(); do { GuessingGame game = new GuessingGame(); game.play(); statistics.count(game); playagain = askusertocontinue(); while (playagain); statistics.print(); // put out statistics static boolean askusertocontinue() { IO.writeLn("Would you like to play again? (Y N) : "); char reply = IO.read(); while (reply!= Y && reply = N && reply!= y && reply = n ) {... return (reply == 'Y' reply == 'y');
Beispiel Zahlenratespiel : Entwurfschritte (6) 6. Entwurfschritt: Klasse GameStatistics class GameStatistics { int nrgames = 0, nrwon = 0, nrguessestotal = 0; void count(guessinggame game) { nrgames++; if (game.number == game.guess) { nrwon++; nrguessestotal = nrguessestotal + game.nrguesses; void print() { IO.writeLn(); IO.writeLn("Game Statistics"); IO.writeLn("----------------"); IO.writeLn("Games played: " + nrgames); IO.writeLn("Games won: " + nrwon); float avrgguesses = (float)nrguessestotal / nrgames; IO.writeLn("Average guesses per game: " + avrgguesses);