Textuelle Programmierung

Die vorliegenden Materialien wurden von Daniel Hoherz und André Tempel erstellt. Sollten andere Editoren die Materialien erstellt haben, werden diese explizit genannt.

In der Einheit zur Codierungstheorie haben wir bereits das Graustufenmodell kennengelernt. Hiermit können Pixelbilder erstellt und gespeichert werden, die Graustufen mit den Werten 0 (schwarz) bis 255 (weiß) darstellen.
Mittels dieser Codierung lassen sich dann solche Pixelbilder darstellen:

Ein einfaches 4×4 Pixelbild im Gaustufenmodell

Codiert sieht das Bild dann wie folgt aus: 255 255 255 255 255 0 0 255 123 255 255 123 123 123 123 123
Es liegen also drei Graustufenwerte 0 (schwarz), 123 (grau) und 255 (weiß) vor.
Doch wie kann ich dieses Bild nun programmiertechnisch umsetzen

Als erstes müssen wir festlegen, wie groß das Fenster werden soll, indem unsere Pixelbild angezeigt werden soll. Dazu nutzen wir die Anweisung:

 size(x, y);

x und y sollen hier Platzhalter, sogenannte Paramter, sein, welche durch konkrete Werte ersetzt werden müssen. Wobei x, der erste Wert, für die breite des Fensters steht und y, der zweite Wert, für die Höhe des Fensters steht. Bspw. liefert die folgenden Anweisung eine Fenster der Breite 500 und der Höhe 200.

 size(500, 200);

Um nun ein Quadrat zu zeichen, benutzen wir die Anweisung

 rect(x, y, a, b);

Wobei die ersten beiden Parameter für den Startpunkt in unserem Fenster stehen. x steht für den x-Wert und y für den y-Wert, denn in dem Fenster ist ein Koodinatorenkreuz hinterlegt, welche oben links immer (0/0) beginnt. Die Parameter a und b stehen für die Breite des Rechtecks (a) und die Höhe (b), wobei immer vom Urpsrungspunkt (x/y) ausgegangen wird.

size(100, 100);
rect(10, 20, 50, 20);

Ausgabe des Codes oben

Es ist zu erkennen, dass auf dem Fenster ein Rechteck gezeichnet wurde, dessen Breite größer ist, als dessen Höhe.
Um nun die Farben zu tauschen, sodass der Hintergrund weiß ist und das Rechteck einen Grauton hat, benutzen wir die beiden Befehle:

background(x);
fill(x);

Für den Parameter x können wir unsere Grauwerte von 0 (schwarz) bis 255 (weiß) einsetzen. Fügen wir nun alle vier Anweisungen zusammen, um einen

size(100, 100);
background(255);        //weiß
fill(123);              //grau
rect(10, 20, 50, 20);

Weißer Hintergrund mit einem grau ausgefülltem Rechteck

Vergessen Sie nicht: Machen Sie sich Fotos von Ihren Ergebnissen und machen Sie sich dazu Notizen.

  1. Es soll nun mithilfe der Anweisungen ein erstes kleines 2×2-Pixelbild erstellt werden. Hinweis: Wir werden im Folgenden die Pixel etwas größer darstellen, damit wir sie besser sehen können.
  2. Erstellen Sie zunächst ein Fenster mit der Größe 100×100 und der Hintergrundfarbe weiß.

    Fügen Sie 4 Rechtecke mit den Kantenlängen 50×50-Pixel hinzu, sodass sie sich nicht überschneiden und das Fenster in 4 Teile geteilt ist (4 Pixel).

    Geben Sie nun jedem Pixel einen anderen Grauton.

  1. Erstellen Sie ein 6×6-Pixel großes Bild eines Smiley oder etwas Vergleichbares. Wählen Sie hierfür eine andere Fenstergröße und auch eine andere Größer der Pixel. Ihr Bild könnte so aussehen.
  2. Mögliches Ergebnis

Hier folgen noch Übungsaufgabe.

Inhalt So gut kann ich das:
++ +
Ich weiß, was die Anweisungen size();, background();, fill(); und rect(); machen.
Ich kann ein Fenster in der Größe anpassen.
Ich weiß, wie ich ein Rechteck platziere und in der Größe anpasse.
Ich kann die Hintergrund- und Füllfarbe bzgl. Graustufen verändern.

Wir stellen uns mal vor, dass wir das folgende Programm haben, welches das nebenstehende Bild herausgibt:

size(100, 100);
background(255);
//Erste Zeile
fill(0);          
rect(0, 0, 25, 25);
fill(123);          
rect(25, 0, 25, 25);
fill(0);          
rect(50, 0, 25, 25);
fill(255);          
rect(75, 0, 25, 25);
//Zweite Zeile
fill(123);          
rect(0, 25, 25, 25);
fill(123);          
rect(25, 25, 25, 25);
fill(255);          
rect(50, 25, 25, 25);
fill(0);          
rect(75, 25, 25, 25);
//Dritte Zeile
fill(255);          
rect(0, 50, 25, 25);
fill(123);          
rect(25,50, 25, 25);
fill(0);          
rect(50, 50, 25, 25);
fill(255);          
rect(75, 50, 25, 25);
//Vierte Zeile
fill(255);          
rect(0, 75, 25, 25);
fill(123);          
rect(25, 75, 25, 25);
fill(255);          
rect(50, 75, 25, 25);
fill(0);          
rect(75, 75, 25, 25);

Ergebnis des Programms

Angenommen ich möchte alle weißen Pixel in einen leichten Grauton ändern. Was müsste ich machen?

Hier wird noch eine Erklärung für die Variablen kommen.

Vergessen Sie nicht: Machen Sie sich Fotos von Ihren Ergebnissen und machen Sie sich dazu Notizen.

  1. Wir wenden nun die Variablen auf das Beispiel oben an. Kopieren Sie sich den Quellcode oben und fügen Sie ihn in ein neues Projekt ein.
  2. Erstellen Sie zunächst drei Variablen vom Datentyp Ganzzahl, um dadrin die drei Grautöne 0 (schwarz), 123 (grau) und 255 (weiß) zu speichern.

    Ersetzen Sie im der Anweisung fill(); den Wert durch den jeweils passenden Vartiablennamen.

    Verändern Sie die Werte der Variablen und gucken Sie, was bei dem Bild geschieht.

  1. Mit den Pixelbildern werden Wärmebilder dargestellt. Aber auch bei solchen Wärmebildern ist es manchmal notwendig den Durchschnitt zu ermitteln, um so verschiedene Wärmebilder zu vergleichen.
  2. Starten Sie ein neues Programm und legen Sie fünf Ganzzahl-Variable an, in denen Sie Temperaturwerte speichern.

    Ermitteln Sie nun den Durchschnitt und lassen Sie den Durchschnittswert in einer Variable speichern und geben Sie diesen Wert auf der Konsole aus.

Hier werden noch Übungsaufgaben folgen.
Inhalt So gut kann ich das:
++ +
Ich kann eine Variable deklarieren und initialisieren.
Ich kann den Wert einer Variable ändern.
Ich kann Operationen (Addition etc.) auf Variablen anwenden.
Ich kann Text und Variablenwerte auf der Konsole ausgeben lassen.

Hier kommt noch ein Einstieg hin.

Hier wird noch eine Erklärung eingefügt.

Vergessen Sie nicht: Machen Sie sich Fotos von Ihren Ergebnissen und machen Sie sich dazu Notizen.

  1. Erstellen Sie ein 2×2-Wärmebilde, wo 2 beliebige Graustufenwerte in Variablen gespeichert werden und nur mit diesen Werten wir das Wärmebild erstellt.
  2. Erstellen Sie mithilfe einer bedingten Anweisung eine Abfrage, welcher der beiden Variablenwerte größer ist und der Wert dieser Variable soll auf den Wert -255 gesetzt werden.

    Erstellen Sie eine erneute Ausgabe des Pixelbildes und nutzen Sie beim fill();-Befehl die Variablennamen. Das Bild sollte im Vergleich zum vorherigen anders aussehen. Um den Unterschied deutlich zu machen, können Sie vor der Ausgabe den Befehl delay(2000); verwenden.

  1. Erweitern Sie Ihr Programm aus Aufgabe 1, indem Sie nun 3 beliebige Graustufenwerten in Variablen speichern.
  2. Erstellen Sie mithilfe von bedingten Anweisungen eine Abfrage, welcher der Variablenwerte der größte ist und diese Variable soll auf den Wert -255 gesetzt werden.

    Erstellen Sie eine erneute Ausgabe des Pixelbildes und nutzen Sie beim fill();-Befehl die Variablennamen. Das Bild sollte im Vergleich zum vorherigen anders aussehen. Um den Unterschied deutlich zu machen, können Sie vor der Ausgabe den Befehl delay(2000); verwenden.

Hier werden noch Übungsaufgaben folgen.
Inhalt So gut kann ich das:
++ +
Ich kann einfache bedingte Anweisungen und Verzweigungen schreiben.
Ich kenne den Unterschied zwischen den beiden Forme.n
Ich kann die Bedingung mit <, > und == formulieren.
Ich kann aus den Aufgaben ermitteln, welche der Formen ich brauche.

Wir haben bisher recht kleine Bilder betrachtet, aber in Wirklichkeit sind solche Pixelbilder mehrere tausend Pixel groß. Welcher Problem taucht dabei auf, solche Bilder zu speichern, wie wir es bisher mittels Variablen gemacht haben?

Eine Erklärung wird noch einegfügt.

Vergessen Sie nicht: Machen Sie sich Fotos von Ihren Ergebnissen und machen Sie sich dazu Notizen.

  1. Im Folgenden soll eine Reihung vom Datentyp Ganzzahl erzeugt werden und dadrin sollen zufällige Graustufenwerte gespeichert werden.
  2. Deklarieren Sie eine Ganzzahl Reihung mit 4 Werten.

    Weisen Sie der Reihung nacheinander zufällige Graustufenwerte zu.

    Erzeugen mithilfe der Werte aus der Reihung das Graustufenbild.

  1. Im Folgenden wird mit den Werten der Reihung etwas gemacht.
  2. Bestimmen Sie den Durchschnitt der Graustufenwerte der Reihung.

    Nun soll verglichen werden, welcher der Werte kleiner ist als der durchschnittliche Grausufenwert und diese Werte der Reihung sollen mit dem Wert -250 überschreiben.

    Erzeugen mithilfe der neuen Werte aus der Reihung das neue Graustufenbild.

Hier werden noch Übungsaufgaben folgen.
Inhalt So gut kann ich das:
++ +
Ich kann eine Reihung deklarieren.
Ich kann mittels Indices auf die gespeicherten Werte der Reihung zugreifen.
Ich kann in Reihungen Werte speichern und ändern.
Ich kann mit den Werten von Reihungen arbeiten.

Hier wird noch ein Einstieg kommen.

Hier folgt noch eine Erklärung.

Vergessen Sie nicht: Machen Sie sich Fotos von Ihren Ergebnissen und machen Sie sich dazu Notizen.

  1. Unsere Reihung soll die erste Zeile eines 6×6 großen Pixelbildes speichern und dann darstellen.
  2. Deklarieren Sie eine Ganzzahl Reihung mit 6 Einträgen und weisen Sie diesen Einträgen Werte zu. Diese Reihung soll unsere erste Zeile des Bildes darstellen.

    Lassen Sie die Werte nacheinander auf der Konsole ausgeben, indem Sie eine Schleife verwenden.

    Erstellen Sie eine Ausgabe der Reihung in einem Fenster das 10 hoch und 60 breit ist und wo jeder Pixel 10×10 groß ist, indem Sie eine Schleife verwenden.

  1. Nun führen wir einige Operationen auf unsere Reihung aus Aufgabe 1 aus.
  2. Implementieren Sie einen Algorithmus, der die Reihung durchläuft und dabei nach dem kleinsten Wert der Reihung sucht und am Ende den Index ausgibt.

    Erweitern Sie Ihren Algorithmus, sodass er anschließend die kleinste Zahl mit der ersten Zahl der Reihung tauscht.

    Erklären Sie, was Sie an Ihrem Algorithmus aus Aufgabe 2a ändern müssen, um nach dem größten Wert zu suchen.

Hier werden noch Übungsaufgaben folgen.
Inhalt So gut kann ich das:
++ +
Ich kann For-Schleifen anlegen.
Ich kann mittels einer For-Schleife eine Reihung durchlaufen.
Ich kann While-Schleifen anlegen.
Ich kann die Bedingungen von While-Schleifen formulieren.

Vergleichen Sie die beiden Darstellung des gleichen Algorithmus miteinander.
Gibt es Gemeinsamkeiten und Unterschiede?
Welches der beiden Darstellungen finden Sie leichter zu verstehen?
Welche Darstellung würden Sie besser verstehen, wenn Sie keine Programmierkenntnisse hätten?

size(50, 10);
int[] zeile = new int[5];
for (int i = 0; i < zeile.length; i++){
  zeile[i] = (int) random(1, 256);
}
for (int i = 0; i < zeile.length; i++){
  fill(zeile[i]);
  rect(i*10, 0, 10, 10);
}

Ein Struktogramm

Stell dir vor, du möchtest einen neuen Freund einladen, aber anstatt einfach zu sagen, was er tun soll, schreibst du ihm eine klare Anleitung, damit er genau weiß, wie er zu dir kommt. So ähnlich funktionieren Struktogramme in der Programmierung!
Struktogramme, auch bekannt als Nassi-Shneiderman-Diagramme, wurden in den 1970er Jahren von zwei klugen Köpfen, Isaac Nassi und Benjamin Shneiderman, erfunden. Diese Diagramme helfen Programmierern dabei, die logische Struktur von Programmen und Algorithmen auf eine einfache Art und Weise darzustellen – fast wie eine Landkarte für einen Weg!
Der Hauptzweck von Struktogrammen ist es, die Planung und Dokumentation von Software zu erleichtern. Sie bieten eine klare, visuelle Darstellung der Abläufe, sodass jeder sofort erkennen kann, was als Nächstes passiert.
Mit Struktogrammen können Programmierer die Logik eines Programms besser verstehen und sie helfen, Ideen anderen zu erklären. Sie nutzen die vier grundlegenden Kontrollstrukturen, die in jedem Programm wichtig sind:

Anweisung: Diese werden als einfache Rechtecke notiert, in denen das auszuführend reingeschrieben wird.

int zahl = 5;

Anweisung als Struktogramm

Sequenz: Diese wird einfach als mehrere Rechtecke dargestellt, die zusammenhängend sind.

size(50, 50);
background(0);
fill(255);
rect(20, 20, 10, 10);

Anweisung als Struktogramm

Bedingte Anweisung: Hierbei beginnt es erst mit dem Bedingungsblock, wo die Bedingung reingeschrieben wird, bspw. ob es regnet. Danach folgt die Verzweigung. Im linken Teil kommen die Anweisungen rein, die ausgeführt werden sollen, wenn die Bedingung wahr also zutreffend ist. Und im rechten Teil werden die Anweisungen notiert, die bei Nichterfüllung der Bedingung (falsch) ausgeführt werden sollen, sofern es welche gibt. In Struktogrammen wird zwischen einer einfachen bedingten Anweisungen und einer Verzweigung grafisch nicht unterschieden.

int zahl1 = (int) random(1,7);
int zahl2 = (int) random(1,7);
if(zahl1 > zahl2){
  print("Zahl 1 ist größer");
}

Einfache bedingte Anweisung als Struktogramm
int zahl1 = (int) random(1,7);
int zahl2 = (int) random(1,7);
if(zahl1 > zahl2){
  print("Zahl 1 ist größer");
}
else{
    print("Zahl 2 ist größer");
}

Verzweigung als Struktogramm

Schleifen: Diese werden als Struktogrammauch nicht unterschieden. Das Struktogramm einer Schleife zeigt auch zunächst den Bedingungsblock, also ist bspw. die Zähschleife schon oft genug durchgelaufen oder ist die Bedingung der bedingte Schleife erfüllt. Dann kommen die Anweisungen, welche die Schleife ausführen sollen. Diese Anweisungen werden von der Schleife umschlossen. Dieses Umschließen kennen wir aus Scratch bereits.

for(int i = 0; i < 3; i++){
    print(i);
}

For-Schleife als Struktogramm
int pixelfarbe = 0;
while(pixelfarbe < 123){
    pixelfarbe = pixelfarbe +1;
}

Bedingte Schleife als Struktogramm

Vergessen Sie nicht: Machen Sie sich Fotos von Ihren Ergebnissen und machen Sie sich dazu Notizen.

  1. Überführen Sie die folgenden Programme in ein Struktogramm.
    Wenn Sie auf das Symbol links vom "Spenden"-Button drücken, können Sie das Bild herunterladen.
  2. int z1 = (int) random(1, 7);
    int z2 = (int) random(1, 7);
    int hilfe = 0;
    if(z1 < z2){
      hilfe = z1;
      z1 = z2;
      z2 = hilfe;
    }
    
    

    int z1 = (int) random(1, 7);
    int versuche = 1;
    while (z1 != 6){
      print("Keine 6, würfel erneut.");
      z1 = (int) random(1, 7);
      versuche = versuche + 1;
    }
    print("Nach " + versuche + " Versuchen kam endlich eine 6.");
    
    
  1. Entwickeln Sie zu den folgenden Aufgabenstellungen jeweils ein Struktogramm.
  2. Ein Programm soll dem Benutzer bei einer Temperatur unter 18°Grad sagen, dass er eine Jacke mitnehmen soll und ansonsten, dass es warm genug ist, ohne Jacke rauszugehen.

    Um Abweichungen der Temperatur zu ermitteln, wird der aktuelle Monat mit dem vorjahres Monat verglichen. Der durchschnittliche Wert des vorjahres Monats liegt bei 17°Grad. Die aktuellen Monatstemperaturen liegen in einer Reihung vor. Daraus muss noch der Durchschnitt ermittelt werden und dann müssen die beiden Werte verglichen werden, um zu sagen, ob der diesjährige Monate wärmer ist oder nicht.

  1. Setzen Sie Ihr Ergebnis aus Aufgabe 2a oder 2b als Algorithmus in Processing um.

In Kürze wird hier krasser Inhalt erscheinen. Bis das passiert ist, gibt es hier einen Informatiker-Witz: Ich habe alle meine Passwörter in "warnichtkorrekt" geändert, so sagt mir mein Rechner, wie es lautet, wenn ich es vergessen habe.

Inhalt So gut kann ich das:
++ + - --
Ich kann ein Struktogramm lesen.
Ich kann ein Struktogramm erstellen.
Ich kann ein Struktogramm als Algorithmus umsetzen.
Ich kann einen Algorithmus als Struktogramm umsetzen.

Ich möchte mit Ihnen ein kleines Spiel spielen. Nehmen Sie sich das Code Mainia-Kartenspiel von vorne. Was Sie aus der Verpackung benötigen, sind der Würfel und die ganzen Karten mit der grünen Vorderseite. Sie können das Spiel auch anspruchsvoller gestalten, wenn Sie noch die Karten mit der gelben Vorderseite hinzunehmen, bis auf die die folgenden Karten: „int Zahl…“, „int x…“, „int zahl…“ und „zahl = zahl %...“.

Spielablauf:
Mischen Sie nun alle Karten und teilen diese vollständig unter den Spielern aus, es ist unerheblich, ob alle Spieler die gleiche Anzahl an Karten haben.
Nun würfelt der Startspieler den Würfel und die Variable zahl erhält diesen Wert als Startwert. Wird bspw. die -1 gewürfelt, startet die Variable zahl mit dem Wert -1.

Beispielhafte Karten aus dem Kartenspiel

Nun legen die Spielerinnen und Spieler ihre Karten nacheinander ab. Jede Karte führt allerdings dazu, dass der Wert von zahl geändert wird. Wird bspw. als erste Karte zahl=zahl + 4 gelegt und der Startwert von zahl war -1, muss nun (-1)+4 gerechnet werden und dieser Wert wird in zahl gespeichert, also 3. Nun kann der nächste Spieler seine Karte ablegen, sobald er diese Anweisung verarbeitet hat. Je schneller man seine Karte spielt, desto schwieriger wird es natürlich für die anderen Spielerinnen und Spieler die Anweisungen auszuführen.
Gewonnen hat, wer am Ende den korrekten Wert der Variable zahl ermittelt hat.
Wichtig: Legen Sie die Karten wirklich sorgsam auf den Stapel, sodass die Reihenfolge stets erhalten bleibt, damit am Ende nachvollzogen werden kann, welchen Wert die Variable zahl hat.
Spielen Sie das Spiel mindestens zwei Mal.
Inwiefern hilft Ihnen Ihre Kenntnis aus dem Video bei diesem Spiel?

Vergessen Sie nicht: Machen Sie sich Fotos von Ihren Ergebnissen und machen Sie sich dazu Notizen.

  1. Vervollständigen Sie die Tracetabellen arbeitsteilig, sodass einer von Ihnen die Tabelle 1 und der andere die Tabelle 2 macht.
    Stellen Sie sich anschließend Ihrer Ergebnisse vor.
  2. Zuweisung zahl ergebnis zuwachs
    zahl = 0 0
    ergebnis = 0 0 0
    zuwachs = 1 0 0 1
    zahl = zahl + 1 1 1
    ergebnis = ergebnis + zuwachs
    zuwachs = zuwachs + 2
    zahl = zahl + 1
    ergebnis = ergebnis + zuwachs
    zuwachs = zuwachs + 2
    zahl = zahl + 1
    ergebnis = ergebnis + zuwachs
    zuwachs = zuwachs + 2
    ergebnis = ergebnis + zahl

    Zuweisung mitglieder neu zuwachs
    zuwachs = 0, mitglieder = 5 5 0
    neu = 7 5 7 0
    mitglieder = mitglieder + neu 12 7 0
    zuwachs = mitglieder – neu
    neu = neu + 1
    mitglieder = mitglieder + neu
    zuwachs = mitglieder – neu
    neu = neu + 6
    mitglieder = neu
    mitglieder = mitglieder + neu
    zuwachs = mitglieder
    mitglieder = zuwachs + neu
    neu = neu + zuwachs

  1. Dokumentieren Sie für die folgenden Programme, den Verlauf der Werteveränderung in einer Tracetabellen.
    Hinweis: Sie finden unter den Aufgaben die Möglichkeit eine Tracetaballen digital zu erstellen und sich das Ergebis als Bild zu speichern.
  2. int rot = 255;
    int gruen = 0;
    int blau = 125;
    int grauwert = (rot+gruen+blau)/3;
    if (grauwert > 128) {
      rot = 255;
      gruen = 255;
      blau = 255;
    } else {
      rot = 0;
      gruen = 0;
      blau = 0;
    }
    
    

    Bei dem Datentyp String handelt es sich um Zeichenketten also Zeichen, Wörter oder ganze Sätze. Wenn man in einer String-Variablen nichts speichern möchte, dann schreibt man eben = "".

    String[] text = new String[3];
    text[0] = "Bald";
    text[1] = "sind";
    text[2] = "Ferien.";
    String ausgabe = "";
    for (int i = 0; i < text.length; i++) {
      ausgabe = ausgabe + text[i] + " ";
      text[i] = "";
    }
    
    
    int[] zahlen = new int[4];
    int zahlen[0] = 7;
    int zahlen[1] = 8;
    int zahlen[2] = 5;
    int zahlen[3] = 1;
    int hilfe = 0;
    for(int i = 1; i < zahlen.length, i++){
        if(zahlen[i-1] > zahlen[i]){
            hilfe = zahlen[i-1];
            zahlen[i-1] = zahlen[i];
            zahlen[i] = hilfe;
        }
    }
    
    

Hiermit können Sie eine Tracetabelle erstellen. Jedes Mal, wenn Sie auf "Neue Tabelle erstellen" klicken, wird eine neue Tabellenerzeugen realisiert:

  1. (optional) Wir betrachten den Algorithmus aus Aufgabe 2c noch etwas genauer.
  2. Sie haben bereits festgestellt, dass der Wert 8 nach hinten rückt.
    Erläutern Sie, was geschieht, wenn die For-Schleife noch zwei weitere vollständig ausgeführt wird.

    Ergänzen Sie nun das Programm aus Aufgabe 2c, sodass die Werte sortiert werden und am Ende die Werte der Reihung ausgegeben werden.

  1. Untern finden Sie verschiedene Aufgaben mit unterschiedlichen Sterneanzahl. Die Anzahl der Sterne gibt die Schwierigkeit der Aufgabe an. Ihre Aufgabe ist es so viele Aufgaben zu erledigen, sodass Sie mindestens 5 Sterne gesammelt haben.
    Untersuchen Sie mithilfe von Tracetabellen die Algorithmen hinsichtlich ihrer Funktionsweise und korrigieren Sie ggf. den Code, sodass der Algorithmus korrekt funktioniert.
0 von 5 Sternen

Herzlichen Glückwunsch! Du hast alle Aufgaben erfolgreich abgeschlossen!

Wow! Du hast mehr als 5 Sterne gesammelt!

★☆☆
Erledigt

Aufgabe a

Der Algorithmus soll die Summe der Zahlen der Reihung zahlen berechnen. Erstellt eine Tracetabelle mit den Variablen summe, i und zahlen[i].

int[] zahlen = {1, 2, 3, 4, 5};
int summe = 0;
for (int i = 0; i <= zahlen.length; i++) {
  summe = summe + zahlen[i];
  // Hier eine neue Zeile in der
  // Tracetabelle erstellen
}

Nachdem Sie das erstemal bei Zeile 5 angekommen sind, sollte die Variablen folgende Werte haben: summe=1, i=0 und zahlen[i]=1 und Sie sollten dadurch eine Zeile in der Tracetabelle haben.

Bei zahlen[i] muss jeden Schleifendurchlauf das i durch den entsprechenden Variablenwert ersetzt werden.

Dieser Algorithmus arbeitet nicht korrekt, da er über die Reihung hinausgeht. Wo geschieht das?

★☆☆
Erledigt

Aufgabe b

Der Algorithmus soll den Durchschnitt der Zahlen der Reihung werte berechnen. Erstellt eine Tracetabelle mit den Variablen summe, i, werte[i] und durchschnitt.

float[] werte = {2.0, 4.0, 6.0};
float summe = 0;
for (int i = 0; i < werte.length; i++) {
  summe = summe + werte[i];
  // Hier eine neue Zeile in der
  // Tracetabelle erstellen
}
float durchschnitt = summe / werte.length;
// Hier eine neue Zeile in der
// Tracetabelle erstellen

Die erste Zeile der Tracetabelle lautet: i=0, werte[i]=2.0, summe=2.0 und durchschnitt=-

Die letzte Zeile der Tracetabelle lautet: i=-, werte[i]=-, summe=12.0 und durchschnitt=4.0

Überlege einfach selbst, ob der Durchschnitt der drei Werte wirklich 4 sein kann.

★★☆
Erledigt

Aufgabe c

Der Algorithmus soll sowohl den maximalen als auch den minimalen Wert in einer Reihung ermitteln. Die Reihung ist {3, 5, 1, 8, 2}. Erstellt eine Tracetabelle mit den Variablen max, min,i und werte[i].

int max = werte[0];
int min = werte[0];
for (int i = 1; i < werte.length; i++) {
  if (werte[i] > max) {
    min = werte[i];
  } else {
    if (werte[i] < min) {
      max = werte[i];
    }
  }
  // Hier eine neue Zeile in der
  // Tracetabelle erstellen
}

Die erste Zeile der Tracetabelle lautet: i=1, werte[i]=5, max=3, min=5

Die letzte Zeile der Tracetabelle lautet: i=4, werte[i]=2, max=1, min=2

Irgendetwas bei der Zuweisung der Werte nach den Prüfungen stimmt nicht.

★★☆
Erledigt

Aufgabe d

Der Algorithmus soll die Anzahl der positiven und negativen int-Zahlen in einer Reihung zählen. Die Reihung ist {-1, 2, -3, 4, 5, 0}. Erstellt eine Tracetabelle mit den Variablen anzahlPositiv, anzahlNegativ, i und zahlen[i].

int anzahlPositiv = 0;
int anzahlNegativ = 0;
for (int i = 0; i < zahlen.length; i++) {
  if (zahlen[i] > 0) {
    anzahlPositiv++;
  } else {
    if (zahlen[i] <= 0) {
      anzahlNegativ++;
    }
  }
  // Hier eine neue Zeile in der
  // Tracetabelle erstellen
}

Die erste Zeiel der Tracetabelle lautet: anzahlPositiv=0, anzahlNegativ=1, i=0 und zahlen[i]=-1

Die letzte Zeiel der Tracetabelle lautet: anzahlPositiv=3, anzahlNegativ=3, i=0 und zahlen[i]=0

Eine Bedingungen muss falsch formuliert sein.

★★★
Erledigt

Aufgabe e

Der Algorithmus soll das Produkt aller positiven Zahlen in der Reihung zahlen berechnen. Die Reihung ist {-1, 2, -3, 4, 5}. Erstellt eine Tracetabelle für die Variablen produktPositiv, i und zahlen[i].

int[] zahlen = {-1, 2, -3, 4, 5};
int produktPositiv = 0;
for (int i = 0; i < zahlen.length; i++) {
  if (zahlen[i] > 0) {
    produktPositiv = produktPositiv*zahlen[i];
  }
  // Hier eine neue Zeile in der
  // Tracetabelle erstellen
}

Die erste Zeiel der Tracetabelle lautet: produktPositiv=0, i=0 und zahlen[i]=-1

Beachte stets, welchen Wert produktPositiv zuvor hatte.

Die letzte Zeile der Tracetabelle lautet: produktPositiv=0, i=4 und zahlen[i]=5

★★★
Erledigt

Aufgabe f

Der Algorithmus soll die Summe aller int-Zahlen in einer übergebenen Reihung bis zu einem bestimmten Wert berechnen und zurückgeben. So soll bei einem Wert von 3 nur die Zahlen addiert werden, die kleiner oder gleich sind als 3. Die übergebene Reihung ist {5, 2, 3, 8, -2} und der Wert 3. Erstellt eine Tracetabelle für die Variablen summe, i und zahlen[i].

int[] zahlen = {5, 2, 3, 8, -2};
int wert = 3;
int summe = 0;
for (int i = 0; i < zahlen.length; i++) {
  if (zahlen[i] != wert) {
    summe += zahlen[i];
  }
  // Hier eine neue Zeile in der
  // Tracetabelle erstellen
}

Die erste Zeile der Tracetabelle lautet: summe=5, i=0 und zahlen[i]=5

Mache dir bei der bedingten Anweisung klar, welche Werte jeweils in zahlen[i] und wert zu genau diesem Zeitpunkt gespeichert sind.

Die letzte Zeile der Tracetabelle sollte summe=13 , i=4 und zahlen[i]=-2

Wählen Sie zunächst aus, ob Sie auf dem grünen Niveau (Einstieg), blauen Niveau (Standard) oder lila Niveau (Fortgeschritten) arbeiten möchten. Sie können jederzeit wechseln.

  1. Dokumentieren Sie die Werteveränderung der folgenden Programme mittels Tracetabellen.
    int x = 12;
    int y;
    if (x > 10) {
        y = x * 2;
    } else {
        y = x - 2;
    }
    
    
    int summe = 0;
    for (int i = 1; i <= 6; i++) {
        if (i % 2 == 0) {
            summe += i;
        }
    }
    
    
    int[] zahlen = {1, 2, 3, 4, 5};
    int summe = 0;
    for (int i = 0; i < zahlen.length; i++) {
        summe += zahlen[i];
    }
    
    

Hiermit können Sie eine Tracetabelle erstellen:

Inhalt So gut kann ich das:
++ + - --
Ich kann eine Tracetabelle hinsichtlich der notwendigen Variablen erstellen.
Ich kann eine Tracetabelle zu einem Ablauf aus Anweisungen erstellen (bspw. Aufgabe 1) und ausfüllen.
Ich kann eine Tracetabellen zu einem Algorithmus mit mit bedingten Anweisungen erstellen und ausfüllen.
Ich kann eine Tracetabellen zu einem Algorithmus mit mit Reihungen erstellen udn ausfüllen.
Ich kann eine Tracetabellen zu einem Algorithmus mit mit For-Schleifen erstellen und ausfüllen.
void setup() {
  size(400, 400);
}

void draw() {
  background(255); // Hintergrund auf Weiß setzen
  //mouseX nimmt den aktuellen x-Wert der Maus
  //auf dem Fenster
  //mousey nimmt den aktuellen y-Wert der Maus
  //auf dem Fenster
  rect(mouseX, mouseY, 50, 50); 
}


Ergebnis des linken Programms

Das Programm auf der linken Seite liefert das Ergebnis rechts. Untersuchen Sie folgenden Aspekte:

  • Beschreiben Sie, welche Befehle Sie bereits kennen und was diese machen.
  • Beschreiben Sie anschließend, welche Befehle Ihnen neu sind und was diese vllt. machen.
  • Es gibt hier die beiden Operationen setup() und draw(). Stellen Sie Vermutungen dazu an, was diese beiden machen.

In Processing sind setup() und draw() zwei grundlegende Operationen, die für die Erstellung von interaktiven Grafiken und Animationen verwendet werden.

Die setup()-Operation wird einmalig ausgeführt, wenn das Programm gestartet wird. Hier werden initiale Einstellungen vorgenommen, wie die Größe des Fensters, die Hintergrundfarbe und andere einmalige Konfigurationen.
In diesem Beispiel wird das Fenster auf 500x500 Pixel festgelegt, und der Hintergrund wird auf eine weiße Farbe gesetzt. Diese Einstellungen sind wichtig, um den Ausgangszustand des Programms zu definieren.

void setup() {
  // Setzt die Fenstergröße auf 500x500 Pixel
  size(500, 500); 
  // Setzt den Hintergrund auf Weiß
  background(255); 
}

void draw() {
  // Hintergrund auf Weiß setzen
  background(255);
  // Füllfarbe auf Schwarz setzen
  fill(0);
  // Zeichne einen Kreis an der Mausposition
  ellipse(mouseX, mouseY, 50, 50); 
}

Die draw()-Operation wird kontinuierlich in einer Schleife ausgeführt, nachdem setup() abgeschlossen ist. Hier können Animationen erstellt und die Grafiken aktualisieren werden. Alles, was im draw()-Block steht, wird so oft wiederholt, wie es nötig ist, um eine flüssige Darstellung zu gewährleisten.
In diesem Beispiel wird bei jedem Durchlauf von draw() der Hintergrund auf Weiß gesetzt, und ein schwarzer Kreis wird an der aktuellen Mausposition gezeichnet. Dadurch folgt der Kreis der Mausbewegung.

mouseX und mouseY sind vordefinierte Variablen in Processing, die die aktuelle Position der Maus im Fenster angeben. mouseX gibt die horizontale Position an, während mouseY die vertikale Position angibt.
In diesem Beispiel oben in der draw()-Operatrion wird ein Kreis an der Position gezeichnet, an der sich die Maus befindet, wodurch der Eindruck entsteht, dass der Kreis der Maus folgt.

mousePressed ist eine vordefinierte boolesche Variable (Wahrheitswert), die angibt, ob die Maustaste gedrückt ist (wahr) oder eben nicht (true). Sie kann in Bedingungen verwendet werden, um Interaktionen auszulösen, wenn der Benutzer mit der Maus klickt.

void setup() {
  size(400, 400);
}

void draw() {
  if (mousePressed) {
    // Füllfarbe auf Rot setzen
    fill(255, 0, 0); 
    // Zeichne einen roten Kreis an der Mausposition
    ellipse(mouseX, mouseY, 50, 50); 
  }
}


Ergebnis des linken Programms

In diesem Beispiel wird ein roter Kreis an der Mausposition gezeichnet, wenn die Maustaste gedrückt ist. Wenn die Maustaste nicht gedrückt ist, passiert nichts.

Vergessen Sie nicht: Machen Sie sich Fotos von Ihren Ergebnissen und machen Sie sich dazu Notizen.

  1. Kopieren Sie sich das Beispiel aus dem Einstieg und öffnen Sie es in Processing. Im Folgenden werden einige Modifikationen an dem Beispiel vorgenommen.
  2. Sorgen Sie als erstes dafür, dass der Kasten eine andere Füllfarbe hat.

    Nun soll es etwas bunter werden. Die Füllfarbe des Rechtecks soll sich stetig verändern. Beispielsweise könnte Sie mit dem Befehle (int) random() arbeiten oder Sie nutzen die mouseX und mouseY in dem Befehl fill().

    Als Vorletztes soll sich die Farbe nur ändern, wenn die Maustaste gedrückt wurde.
    Verändern Sie das Programm, sodass die Farbe des Rechtecks geändert wird, wenn die Maustaste gedrückt wurde.

    Entfernen Sie den Befehl background() aus der draw()-Operation und fügen Sie diesen in setup()-Operation ein.
    Beschreiben Sie Ihr Ergebnis.

  1. Wir entwickeln im Folgenden eine kleine eigene Animation, die vollkommen automatisch abspielt. Bei der Animation soll sich ein Rechteck oder Kreis zunächst von links nach rechts bewegen und aus dem Bild verschwinden und wieder auf der linken Seite ankommen. Gehen Sie die folgenden Aufgabenteile durch, um die Aufgabe zu lösen.
  2. Erstellen Sie zunächst eine neue Datei, in der Sie die Operationen setup() und draw() reinschreiben und wo Sie zunächst ein Rechteck oder ein Kreis darstellen.

    Erweitern Sie Ihr Programm, sodass mittels einer Variable der Kreis/das Rechteck sein Position selbstständig nach rechts verändert.

    Bis hier sollte sich das Objekt einfach nur nach rechts bewegen und dort verschwinden. Nun soll es so verändert werden, dass, wenn das Objekt rechts verschwunden ist, es wieder am Anfang startet.

    Ergänzen Sie noch, wenn die Maustaste gedrückt wird, dass sich dann die Farbe des Objektes zufällig ändert sowie die Geschwindigkeit mit der sich das Objekt von links nach rechts bewegt.

    Ergänzen Sie ein weiteres Objekt, dass von unten nach oben gleitet und dann wieder unten auftaucht.

  1. Projektaufgabe: Diese Aufgabe stellt ein kleines Projekt dar und ist etwas umfangreicher und anspruchsvoller.
    Ziel dieses Projektes ist es eine interaktives Pixelraster zu erstellen, wo die einzelnen Zellen angeklickt werden können und diese dann schwarz werden bzw. wenn diese schon schwarz waren, dass sie dann wieder weiß werden. In der GIF rechts sehen Sie, wie dieses aussehen kann.
    Unten werden einzelne Schritte vorgeschlagen, in denen Sie vorgehen können. Sie können es auch vollkommen selbstständig probieren. Hinweis: Sie brauchen die Befehle mousePressed, get() und color().

  2. Zunächst sollten Sie sich darum kümmern, dass das Raster gezeichnet wird. Machen Sie sich klar, ob das Raster immer wieder gezeichnet werden muss oder ob es genügt, dass es ein Mal gezeichnet wird.

    Als nächstes muss auf das Drücken der Taste reagiert werden. Da das immer geschieht wieder dynamisch. Überlegen Sie sich, wo die Bedingungen dafür implementiert werden muss und reduzieren Sie Ihre Implementierung erstmal darauf, dass ein weißes Quadrat schwarz gefärbt wird.

    Was haben wir bisher: Wir haben das Pixel-Raster und wir haben es, dass das Programm auf einem Mausklick reagiert. Nun muss noch die entsprechende Reaktion, also das Schwarzfärben realisiert werden.
    Die Idee könnte sein, so zu tun, als wenn man den entsprechenden Pixel schwarz einfärbt, aber in Wirklichkeit, wird an der Stelle ein schwarz eingefärbtes Quadrat gezeichnet. Versuchen Sie als erstes ein Quadrat an der Stelle zu zeichen, wo Ihre Maus beim Klicken ist. Sobald Sie das haben, sorgen Sie dafür, dass das Quadrat richtig positioniert wird. Hinweis: Beauen Sie am Ende in der Bedingungen auf jeden Fall einen deleay(100); ein, sonst wird der Klick nicht passend registriert.

    Was haben wir bisher: Wir können ein Pixel schwarz färben. Was kommt nun?
    Nun müssen wir es irgendwie schaffen, dass ein bereits schwarzer Pixel wieder weiß wird. Also ist es beim Klicken mit der Maus wichtig, welche Farbe der Pixel hat. Die Bedingungen der bedingten Anweisung muss geändert und die bedingte Anweisung muss zu einer if-else-if-Anweisunge geändert werden. Mit der ersten Bedingungen wird geprüft, ob die Taste gedrückt wurde und der Pixel weiß ist und mit der zweiten Bedingungen wird geprüft, ob die Taste gedrückt wurde und der Pixel schwarz ist. Sie benötigen die Operation get().

Hier wird in kürze Übungsmaterial erscheinen, solange gibt es diesen Witz hier:
Wenn Baumeister Gebäude so bauten, wie Programmierer Programme entwickeln, dann würde der erste Specht, der vorbeikäme, die Zivilisation zerstören!!!

Inhalt So gut kann ich das:
++ + - --
Ich kenne den Unterschied zwischen setup() und draw().
Ich kann setup() und draw() nutzen, um Animationen zu erstellen.
Ich kann mit den Systemvariablen mouseX und mouseY arbeiten.
Ich kann mit der SystemvariablenmousePressed arbeiten.
Ein Scratch-Programm mit einer Operation
Ergebnis des linken Programms. Das Programm wurde mehrfach gestartet.

Das Programm auf der linken Seite ist in Scratch programmiert und rechts sehen Sie, was passiert, wenn man das Programm mehrfach ausführt. Untersuchen Sie folgenden Aspekte:

  • Untersuchen Sie, was es mit dem roten Block auf sich hat.
  • Erinnern Sie sich daran, wie der rote Block hieß und was im Allgemeinen sein Zweck war.
  • Erinnern Sie daran, wie man solche Blöcke nannte?
void setup() {
  size(500, 500);
  background(255);
  kunst(10);
}

void kunst(int anzahl) {
  int groeße;
  for (int i = 0; i < anzahl; i++) {
    groeße = (int) random(10, 50);
    rect(random(0, 500), random(0, 500), groeße, groeße);
  }
}

Ergebnis des linken Programms. Das Programm wurde mehrfach gestartet.

Das Programm auf der linken Seite liefert das Ergebnis rechts. Untersuchen Sie folgenden Aspekte:

  • Untersuchen Sie, welche Codezeilen für das Zeichnen der Quadrate verantwortlich ist.
  • In dem Scratch-Beispiel mit der Operation wurden auch Quadrate gezeichnet. Wo sehen Sie Gemeinsamkeiten und Unterschiede zwischen den beiden Programmen? (Bleiben Sie bitte bei der Operation.)
  • Angenommen Sie sollten eine Operation addieren() implementieren, die zwei Ganzzahlen als Übergabeparameter erhält und dann diese beiden Zahlen addiert und auf der Konsole ausgibt. Wie würden Sie diese Operation implementieren?

Operationen sind definierte Blöcke von Code, die eine bestimmte Aufgabe oder Berechnung ausführen. Sie ermöglichen es Programmierern, komplexe Aufgaben in kleinere, überschaubare Teile zu zerlegen, die einfacher zu verstehen, zu testen und zu warten sind.
Das Verständnis von Operationen ist entscheidend, um effektive und modulare Programme zu erstellen. Im Folgenden werden wir den Aufbau von Operationen sowie deren Typen – mit und ohne Übergabeparameter – erläutern.

Beim Definieren einer Operation sind immer zwei Sachen zu beachten. Einmal gibt es den Operationskopf und den Operationskörper.
Der Operationskopf besteht immer aus drei Teilen:

  • Rückgabewert: Gibt an, welchen Datentyp die Operation zurückgibt. Wenn die Operation keinen Wert zurückgibt, verwenden wir void. Diesen Fall betrachen wir als erstes. Also merken Sie sich, dass als erstes void stehen muss.
  • Operationsname: Ein aussagekräftiger Name, der beschreibt, was die Operation macht. In unserem Beispiel oben, ist kunst der Operationsname.
  • Übergabeparameter: In den Klammern nach dem Operationsnamen werden die Übergabeparameter definiert. Jeder Parameter hat einen Datentyp und einen Namen. Wenn keine Parameter benötigt werden, bleiben die Klammern leer. Im obigen Beispiel gab es den Übergabeparamter int anzahl. Die Parameter sind Platzhalter für konkrete Werte, welche die Operation zum Arbeiten braucht.

Dann kommt der Operationskörper in den geschweiften Klammern {}. Diese enthalten die Anweisungen, die ausgeführt werden, wenn die Operation aufgerufen wird. Innerhalb dieses Blocks können beliebige Anweisungen, Variablen und Kontrollstrukturen verwendet werden.

Soll die Operation nun genutzt werden, verwendet man den Namen der Operation gefolgt von den runden Klammern (). Wenn die Operation Parameter hat, müssen in den Klammern entsprechende Werte eingetragen werden. In unserem Beispiel wurde mit kunst(10) die Operation verwendet und der Parameter erhält den konkreten Wert 10 und arbeitet damit.

Die Verwendung von Operationen bietet mehrere Vorteile:

  1. Modularität: Durch die Aufteilung des Codes in separate Funktionen wird der Code modularer. Dies bedeutet, dass jede Funktion unabhängig entwickelt und getestet werden kann, was die Fehlersuche erleichtert.
  2. Wiederverwendbarkeit: Einmal definierte Funktionen können an verschiedenen Stellen im Programm wiederverwendet werden, ohne dass der Code dupliziert werden muss. Dies spart Zeit und reduziert die Wahrscheinlichkeit von Fehlern.
  3. Lesbarkeit: Gut benannte Funktionen verbessern die Lesbarkeit des Codes. Programmierer können den Zweck einer Funktion auf einen Blick erkennen, was das Verständnis des gesamten Programms erleichtert.
  4. Abstraktion: Funktionen ermöglichen es, komplexe Logik hinter einfachen Funktionsaufrufen zu verbergen. Dies hilft, den Fokus auf das "Was" und nicht auf das "Wie" zu legen, was die Programmierung intuitiver macht.

Vergessen Sie nicht: Machen Sie sich Fotos von Ihren Ergebnissen und machen Sie sich dazu Notizen.

  1. Im Folgenden soll eine etwas hübschere Version der Einstiegsaufgabe erstellt werden. Dazu sollen Sie die Operation rechteck() erstellen, die ein Quadrat mit beliebiger Größe, beliebiger Position und zufälliger Farbe zeichnet. Folgen Sie den Schritten:
  2. Kopieren Sie den folgenden Quellcode in Processing.

    void setup() {
      size(500, 500);
      background(255);
    }
    void draw() {
      rechteck();
    }
    //Hier die Operation ergänzen.
    

    Ergänzen Sie zunächst den Operationskopf der Operation rechteck().

    Ergänzen Sie zunächst, dass ein Quadrat/Rechteck an einer beliebigen Stelle mit einer beliebigen Größe gezeichnet wird.

    Ergänzen Sie nun, dass das Rechteck mit einer zufälligen Farbe gefüllt wird.

    In Zeile 6 nach dem draw() ist der Operationsaufruf mit rechteck();. Testen Sie, was geschieht, wenn Sie die Befehl in die Operation setup() statt in draw() stehen haben und erklären Sie das Ergebnis.

  1. Im Folgenden werden ein paar kleinere Operationen implementiert, um den Umgang mit Operationen mit und ohne Übergabeparameter zu üben. Dafür erstellen Sie bitte zunächst ein neues Projekt, wo Sie schonmal setup() und draw() erstellen.
  2. Implementieren Sie eine Opration max(int z1, int z2), welche die beiden übergebenen Zahlen vergleicht und auf der Konsole ausgibt, welcher Wert größer ist.

    Implementieren Sie die Operation durchschnitt(int z1, int z2), welche den Durchschnitt der beiden Werte ermittelt und auf der Konsole ausgibt.

  1. Im Folgenden werden wir zwei Operationen erweitern. Die Operation drawCar(int x, int y) sorgt dafür, dass an einer bestimmten Position (x, y) in dem Fensterein Rechteckt gezeichnet wird, welches ein Auto darstellen sollen. Die Operation moveCar() verändert den Wert der Positionierung des Auto-Rechtecks, sodass es aussieht, dass es von links nach rechts fährt.
  2. Kopieren Sie den folgenden Quellcode in Processing und starten Sie das Programm.

    int car1X = 0; // Start-Position des Autos
    
    void setup() {
      size(500, 300);
      background(255);
    }
    
    void draw() {
      background(255);
      moveCars();
      drawCar(car1X, 150);
    }
    
    void drawCar(int x, int y) {
      fill(0, 0, 255); // Blau für das Auto
      rect(x, y, 50, 20); // Auto zeichnen
    }
    
    void moveCars() {
      car1X = car1X + 2; // Auto bewegt sich
      if (car1X > width) {
        car1X = 0;
      }// Zurücksetzen, wenn es den Bildschirm verlässt
    }
    

    Sorgen Sie dafür, dass ein zweites Auto oberhalb des ersten Autos fährt, indem Sie den Operationsaufruf nochmal einfügen und anpassen.

    Momentan fahren beiden Autos gleich schnell, das liegt daran, dass beide mit der Variablen car1X gestartet werden und nur der Wert dieser Variablen durch die Operation move() geändert wird.
    Ergänzen Sie eine weitere Variable car2X, welche das zweite Auto nutzt und ergänzen Sie in der Operation move(), dass auch der Wert der Variable car2X geändert wird, aber schneller als die andere Varable.

    Zur Zeit kann man die beiden Autos nicht voreinander unterscheiden. Wir wollen nun dafür sorgen, dass unterschiedliche Farben bekommen.
    Verändern Sie die Operation drawCar() so, dass neben den beiden Werten für die Position (x, y) auch noch ein eine Übergabeparamter für eine Farbe vorhanden ist und dass dieser Wert genutzt wird, um die Farbe fill()-Befehl zu verändern. Geben Sie dann dann auch noch den Autos oben in der draw()-Operation einen Farbwert mit. Sie brauchen dazu folgende Anweisungen: color farbe und color(255, 0, 0) (stellt die Farbe rot dar, das sollten Sie anpassen.

    Fügen Sie noch ein drittes Auto hinzu, welches an dem Rennen teilnimmt.

  1. Im Folgenden wollen wir einen Blumenmeer zeichnen. Dazu sollen verschiedenfarbige Blumen an verschiedenen Orten des Fensters gezeichnet werden. Als Blume nehmen wir einen Kreis circle(). Dieser Kreis muss entsprechend eingefärbt werden. Für das Zeichnen der Blume soll die Operation malBlume(int x, int y, int type) implementieren werden, die zwei Ganzahlen (x, y) für die Position auf dem Fenster als Parameter hat und eine weitere Ganzzahl (type) für die Blumenfarbe: 1: rot, 2: gelb, 3: blau.
  2. Implementieren Sie die Operation und testen Sie Ihr Ergebnis, indem Sie drei Blumen zeichnen lassen.

    Sollte der type der Blumen eine andere als 1, 2 oder 3 sein, dann soll die Blumenfarbe zufällig bestimmt werden.
    Verändern Sie die Opration malBlume(), sodass sie bei allen anderen Farben eine zufällige Farbe bestimmt.

    Als nächste soll eine neue Operation malBlumenwiese() implementiert werden, die keine Übergabeparamter besitzt. Die Operation soll vollkommen automatisch 20 (oder mehr Blumen) an zufälligen Positionen und mit zufälligen Farben zeichnen.

  1. Diese Aufgabe ist anspruchsvoll. Sie kennen sicherlich vor Wahlen die Säulendiagramme, wo die Prozentangaben der Parteien dargestellt werden. Ein solches Säulendiagramm sollen Sie nun mit den aktuellen Umfragewerten der Parteien erstellen. Dazu sollen Sie eine Reihung nutzen, welche die Prozentwerte speichert und eine Reihung, welche die Namen der Parteien speichert. Darüber hinaus sollen Sie eine Operation zeichneSaeule(double[] wert, String[] name) implementieren, die die Reihungen mit den Prozentwerten und den Parteinamen erhält und dann daraus die Säulen zeichnet. Hinweis: Sie können das Problem auch erstmal verkleinern, indem Sie nur zwei Parteiensäulen zeichnen lassen und die Parteinamen weglassen.

In Kürze wird hier krasser Inhalt erscheinen. Bis das passiert ist, gibt es hier einen Informatiker-Witz: Was isst ein Informatiker abends beim Fernsehen? – Mikrochips.

Inhalt So gut kann ich das:
++ + - --
Ich kann einen Operationskopf mit und ohne Übergabeparameter aus der Aufgabenstellung heraus implementieren.
Ich kann Übergabewerte und Übergabeparameter im Kontext der Operationen erläutern.
Ich kann die Funktionsweise einer vorgegeben Operation mit und ohne Übergabeparamter erläutern und sie in einem Programm nutzen.
Ich kann eine Operation im Programm aufrufen und nutzen.
Ich kann eine Operation selber implementieren.

Wir haben die Operation noteHalbjahr(int mNote, int sNote), welche uns aus diesen beiden Zahlen die Halbjahresnote berechnet.
Die Operation haben wir nun zwei Mal aufgerufen (Z. 2+3), um für die beiden Halbjahre die jeweiligen Noten zu bestimmen. Auf der Konsole werden die Ergebnisse auch angezeigt.

void setup() {
  noteHalbjahr(8, 8);
  noteHalbjahr(9, 9);
}
void noteHalbjahr(int mNote, int sNote) {
  double halbjahresNote = mNote*0.6+sNote*0.4;
  println(halbjahresNote);
}


Konsolenausgabe:
8.0
9.0

Doch nun soll aus diesen beiden Noten noch die Gesamtnote für das ganze Schuljahr berechnet werden.

  • Diskutieren Sie, ob es bzgl. der Umsetzung ein Problem gibt.
  • Erklären Sie, was Sie dafür bräuchten, um das umzusetzen.

Operationen mit Rückgabewert führen, wie andere Operationen auch, Befehle aus, um ein Problem zu lösen und zusätzlich geben sie das erstellte Ergebnis anschließend zurück. Das hat den Zweck, dass mit diesem Ergebnis weitergearbeitet werden kann.
Wir haben es im Einstieg gesehen, dort hätten wir gerne mit dem Ergebnis aus der Berechnung der Halbjahresnoten weiterggearbeitet, um die Ganzjahresnote zu ermitteln, aber das ging nicht. Operatoren mit Rückgabewert können das. Doch wie sind sie aufgebaut:
Operationen mit Rückgabewert unterscheiden sich nur in zwei Aspekten von andere Operationen:

Datentyp statt void
Im Operationskopf haben wir bisher immer am Anfang void geschrieben. Soll ein Wert zurückgegeben werden, dann muss am Anfang der entsprechende Datentyp stehen. Nehmen wir unser Notenbeispiel. Durch die Berechnung wird eine Dezimalzahl herauskommen, somit sollte der Operationskopf mit double starten. In Gänze sieht das dfann so aus:
double noteHalbjahr(int mNote, int sNote) {
    ...
}
Ergebnis zurückgeben mit return
Die Operation berechnet etwas und dieser Wert muss mittels des Befehls return zurückgegeben werden. In unserem Beispiel wird das Ergebnis in der Variablen halbjahresNote gespeichert und dann mittels return wieder zurückgegeben.
double noteHalbjahr(int mNote, int sNote) {
  double halbjahresNote = mNote*0.6+sNote*0.4;
  return halbjahresNote;
}

Wie wir im Einstieg schon gesagt haben: Wir möchten uns den berechneten Wert gerne speichern und daher braucht muss man sich bei Operationen mit Rückgabewert den zurückgegeben werden in einer Variablen speichern, wenn man die operation aufruft. Das sieht dann für dieses Beispiel so aus:

double note1 = noteHalbjahr(8,8);
double note2 = noteHalbjahr(9,9);

Somit werden die zurückgegeben Werte der Operation in den beiden Variablen gespeichert.

Im Allgemeinen gilt für die Operationen mit Rückgabewert, dass sie am Anfang mit dem Datentyp beginnen, den sie am Ende zurückgeben und es muss irgendwo die Anweisung return... kommen. Ansonsten bleibt es wie bei den Operationen.

  1. Wir setzen zunächst die Arbeit an der Einstiegsaufgabe fort. Dort wurden bisher nur die Halbjahresnoten berechnet, aber noch keine Ganzjahresnote. Befolgen Sie die folgenden Schritte, um das Problem zu lösen.
  2. Kopieren Sie den folgenden Quellcode in Processing.

    void setup(){
      double note1 = noteHalbjahr(8,8);
      double note2 = noteHalbjahr(9,9);
    }
    
    double noteHalbjahr(int mNote, int sNote) {
      double halbjahresNote = mNote*0.6+sNote*0.4;
      return halbjahresNote;
    }
    

    Ergänzen Sie nun als erstes den Operationskopf der Operation noteSchuljahr(double halbjahr1, double halbjahr2) und der Datentyp des Rückgabewertes soll double sein.

    Die Operation soll folgende machen: Sie soll die beiden Halbjahresnoten addieren und durch 2 teilen und anschließend soll dieser Wert zurückgegeben werden.

    Testen Sie nun Ihre Operation, indem Sie den Operationsaufruf

  1. Wir wollen ein wenig mit Farben herumspielen und werden nun einige Operationen mit Rückgabewert definieren, bei denen der Datentyp color eine Rolle spielt.
  2. Als erstes soll es eine Operation farbeErzeugen() geben, die einen Farbwert zurück gibt, also ist der Rückgabedatentyp color.
    Implementieren Sie die Operation, die einen zufälligen Farbwert zurückgibt.
    Testen Sie, ob Ihre Operation auch wirklich immer einen zufälligen Farbwert zurückgibt, indem Sie bspw. die Hintergrundfarbe immer dadurch ermitteln.

    Sorgen Sie nun dafür, dass sie zwei zufällige Farbwerte mit der Operation erzeugt werden und in Variablen gespeichert werden.

    Es soll nun eine Operation farbenMischen(color f1, color f2) implementiert werden, die die beiden Farben f1, f2 addiert/mischt und dann die gemischte Farbe zurückgibt. Leider kann man nicht f1+f2 machen, um die Farben zu mischen. Stattdessen muss man sich nacheinander den Rot-, Grün- und Blau-Teil mit den Operationen red(), green(), blue() herausziehen und kann dann die Werte addieren.
    Implementieren Sie die Operation, die die Farben mischt und die Mischfarbe ausgibt.

In Kürze wird hier krasser Inhalt erscheinen. Bis das passiert ist, gibt es hier einen Informatiker-Witz: Was isst ein Informatiker abends beim Fernsehen? – Mikrochips.

Inhalt So gut kann ich das:
++ + - --
Ich kann einen Operationskopf mit und ohne Übergabeparameter aus der Aufgabenstellung heraus implementieren.
Ich kann Übergabewerte und Übergabeparameter im Kontext der Operationen erläutern.
Ich kann die Funktionsweise einer vorgegeben Operation mit und ohne Übergabeparamter erläutern und sie in einem Programm nutzen.
Ich kann eine Operation im Programm aufrufen und nutzen.
Ich kann eine Operation selber implementieren.