Lektion 1

Der Aufbau von Funktionen
Für jedes Kapitel der Lernumgebung muss eine eigene Funktion erstellt werden.
Eine Funktion besteht aus 3 Teilen:
Datentyp (void)
Name (hier immer der Name des Kapitels)
Anweisungsblock (mit den Befehlen)
Die einzelnen Bestandteile
Funktionsname
In der Lernumgebung muss für jedes Kapitel eine neue Funktion erstellt werden.
Generell gilt:
Keine Umlaute/Sonderzeichen/Leerzeichen: (also kein ä, ü, ö, ß , …) .
Der Name sollte auch nicht nur aus einem Großbuchstaben bestehen.
Klammern ( )
Hinter dem Namen stehen runde Klammern.
Klammern { }
Die Befehle (Anweisungen) kommen zwischen die geschweiften Klammern.
Um die Zusammengehörigkeit des abzuarbeitenden Codes zu markieren, werden die auszuführenden Anweisungen (Befehle) üblicherweise in einem Bereich mit geschweiften Klammern { } eingefasst. Die zusammengefassten Anweisungen werden als Anweisungsblock bezeichnet.
Für die Lernumgebung bedeutet das, dass für jedes Kapitel eine neuer Anweisungsblock (eine neue Funktion) erstellt werden muss.
Genau so erstellen wir später auch Zählschleifen, if/else-Abfragen und Schleifen.
Für die geschweiften Klammern { }
Windows | [ AltGr – 7 ] und [ AltGr – 0] |
macOS | [ Alt – 8 ] und [ Alt – 9 ] |
Generell gilt: Suche das Symbol auf deiner Tastatur und verwende die richtige Tastenkombination (je nachdem, ob das Symbol hochgestellt oder daneben ist):
Hiweis: Das Beispiel gilt für Windows
Datentyp void
void ist ein sogenannter Dtentyp.
In der Lernumgebung wird nur dieser Datentyp verwendet, daher müssen wir an dieser Stelle nicht weiter darauf eingehen.
Natürlich gibt es mehrere Datentypen (beispielsweise int). Die Unterschiede werden in der Arduino-Reihe genauer betrachtet. Durch unterschiedliche Dtentypen können Funktionen beispielsweise Werte zurückgeben oder reservieren unterschiedlich viel Speicherplatz auf einem Chip.
0.0.1 "karelsFirstProgram"
Dein Code (die Befehle aus der Tabelle) musst zwischen die geschweiften Klammern { … }.
Nutze die Tasten F1 – F6
Manchmal sind die „F-Tasten“ bereits mit anderen Funktionen belegt, das erkennst du daran, wenn adere/zusätzliche Symbole auf den Tasten sind. Dann einfach die Fn-Taste gedrückt halten, um sie zu nutzen.
void karelsFirstProgram() { // (Neue) Funktion
moveForward();
pickBeeper();
moveForward();
turnLeft();
moveForward();
turnRight();
moveForward();
dropBeeper();
moveForward();
}
1.1.1 "obtainArtifact"
Um ein „neues“ Kapitel zu lösen, muss zunächst eine neue Funktion erstellt werden.
Die Funktion setzt sich (hier) aus void Name und den geschweiften Klammern zusammen.
void obtainArtifact(){
// your code here
}
void obtainArtifact(){
turnRight();
moveForward();
turnLeft();
moveForward();
moveForward();
moveForward();
turnLeft();
moveForward();
pickBeeper();
moveForward();
turnLeft();
moveForward();
moveForward();
moveForward();
turnLeft();
moveForward();
turnLeft();
}

Zählschleifen
Um Befehle mehrfach zu verwenden, kann „repeat (#Anzahl)“ verwendet werden.
Statt den Befehl moveForward() 4x zu schreiben, können wir ihn auch einfach 4x wiederholen.

void karelsRun(){
moveForward();
moveForward();
moveForward();
moveForward();
turnAround();
moveForward();
moveForward();
moveForward();
moveForward();
}
void karelsRun(){
repeat(4) {
moveForward();
}
turnAround();
repeat(4) {
moveForward();
}
}
Hinweis: Natürlich können in der Repeat-Anweisung auch mehrere Befehle stehen.
1.1.1 "obtainArtifact" mit Zählschleifen
Nutze diesmal die repeat-Anweisung
repeat(Anzahl){
…
}
Die repeat-Anweisung kann in den „normalen Code“ geschrieben werden.
Befehl();
Befehl();
repeat(Anzahl){
…
}
Befehl();
Genau wie oben (Funktionen erstellen) müssen alle Befehle (hier also moveForword(); ) in die geschweifte Klammer. In die runde Klammer wird die Anzahl an Wiederholungen geschrieben (hier 3).
void obtainArtifact() {
turnRight();
moveForward();
turnLeft();
repeat(3){ // 3x wiederholen
moveForward();
}
turnLeft();
moveForward();
pickBeeper();
moveForward();
turnLeft();
repeat(3){ // 3x wiederholen
moveForward();
}
turnLeft();
moveForward();
turnLeft();
}

Arbeiten mit Funktionen
Sachen, die oft gebraucht werden, können auch in eigenen Funktionen abgehandelt werden.
Wir können eigene Funktionen erstellen und sie aufrufen.
Funktionen erstellen
void Name(){
Anweisung;
Anweisung;
…
}
Funktionen aufrufen
Name();
Wir können jede Funktion aufrufen.
Anders als beim erstellen einer Funktion verwenden wir dazu nur den Namen (mit den runden Klammern) und enden mit einem Simikolon ;
Tastenkombination:
Das Semikolon beendet eine Anweisung.
moveForward();
In der Lernumgebung sind die 11 Befehle, die ihr nutzen könnt also im Prinzip nicht anderes als bereits vorimplementierte Funktionen (das lässt sich auch an den runden Klammern hinter den Befehlen erkennen). Auch in anderen Programmiersprachen gibt es bereits vorimplementierte Befehle (Codeteile).
Da die 11 Befehle aber bereits vorimplementiert (fertig programmiert) sind, könnt ihr sie einfach aufrufen und damit arbeiten.
Beispiel
void run() {
moveForward();
moveForward();
moveForward();
moveForward();
}
void Hin_Und_Her(){
run();
turnAround();
run();
}
Die Funktion run() wird hier in der Funktion Hin_Und_Her aufgerufen. Damit passiert wieder das selbe, wie oben.
Wir hätten auch wieder karelsRun verwenden können, da
run(); und Run(); und karelsRun() unterschiedliche Funktionen sind -> Groß- und Kleinschreibung beachten!!
1.1.2 " defuseOneBomb"
Erstelle eine „neue“ Funktion und rufe sie auf.
Nennen kannst du die Funktion, wie du willst.
void defuseOneBomb(){
run();
…
}
In dem Video (mit der Lösung) siehst du, wie (wann) das Programm die Funktionen aufruft.
void defuseOneBomb(){
run();
pickBeeper();
run();
}
void run (){
repeat(9){
moveForward();
}
turnAround();
}
1.1.3" defuseTwoBombs"
Mehr als 3 Anweisungen (Befehle) solltest du hier nicht brauchen!
Rufe „alte“ Funktionen auf, die du schon programmiert hast.
void defuseTwoBombs(){
defuseOneBomb();
turnLeft();
defuseOneBomb();
}
1.1.4 "practiceHomeRun"
Ihr habt beim programmieren oft mehrere Möglichkeiten.
Wie wäre es erneut mit Funktionsaufrufen oder (wie unten in „Code“) einfach mal mit einer repeat-Anweisung in einer repeat-Anweisung. Achte dabei auf die { } Klammern.
void practiceHomeRun(){
repeat(4){
repeat(9){
moveForward();
}
pickBeeper();
turnLeft();
}
}
Auch „Funktionsaufruf(e)“ wären hier eine Möglichkeit das Kapitel zu programmieren. Allerdings haben wir die Funktion „run()“ so aufgebaut, dass sich Karel in der Ecke komplett herrumdreht. Hier soll Karel jedoch „nur“ nach Links drehen. Daher ist es einfacher die repeat-Anweisung zu nutzen.
Aber generell gilt: Jeder Programmierer schreibt seinen Code mit sinem/ihrem eigenen Stil. Es gibt also nicht „die“ Lösung! Alles, was ihr hier findet sind Lösungsvorschläge!
1.2.1 "climbTheStairs"
Bisher stand in jeder repeat-Anweisung nur ein Befehl.
Natürlich könnt ihr auch mehrere Befehle hineinschreiben, die nacheinander ausgeführt werden.
void climbTheStairs(){
repeat(6){
moveForward();
turnLeft();
moveForward();
turnRight();
}
moveForward();
}
1.2.2 "fillTheHoles"
void fillTheHoles(){
repeat(4){
moveForward();
turnRight();
moveForward();
dropBeeper();
turnAround();
moveForward();
turnRight();
moveForward();
}
}

Kommentare
Kommentare sind Codeteile, die vom Programm nicht ausgeführt werden.
Kommentare sind für den Menschen, nicht für das Programm! Indirekt hast du sie bereits kennengelernt. In vielen der Videos oben findest du Kommentare als zusätzliche Erklärung (in grün). In den Codeschnippseln (Lösungen zum ausklappen) wurde bisher darauf verzichtet.
1 Zeile auskommentieren
// Alles, was hinter den 2 Strichen steht, wird nicht ausgeführt (Kommentar)
mehrere Zeile auskommentieren
/*
* So können auch mehrere Zeilen auskommentiert werden
*
* (das sind alles auskommentierte Zeilen)
*/
1.2.3 "saveTheFlower"
Nur ein gut kommentierter Code ist ein guter Code!
Über in den nächsten Kapitel mit Kommentaren umzugehen und ergänze deinen eigenen Code so mit nützlichen Hinweisen/Erklärungen.
Teilt euch den Code auf
Pyramide hochlaufen
oben
Pyramide runterlaufen
„letzte Stufe“
void saveTheFlower(){
moveForward();
pickBeeper();
repeat(4){ // Pyramide hoch
turnLeft();
moveForward();
moveForward();
turnRight();
moveForward();
}
dropBeeper(); // oben
moveForward();
repeat(3){ // runterlaufen
turnRight();
moveForward();
moveForward();
turnLeft();
moveForward();
}
turnRight(); // das darf nicht in die letzte repeat, weil er sonst gegen die Wand läuft
moveForward();
moveForward();
turnLeft();
}
1.2.4 "mowTheLawn"
Achte darauf, wo und wie Karel am Ende stehen soll <goal> und ob dein Code das auch so macht <start>.
Oft läuft Karel hier etwas weiter, als er eigentlich ´soll. Dann hast du zu viel in der repeat-Anweisung stehen und musst irgendetwas anders machen!
void mowTheLawn(){
repeat(2){
Reihe_1_Und_2();
letztesDrehen();
}
Reihe_1_Und_2();
moveForward();
}
// Mit selbst definierten Funktionen wird es leichter
void Reihe_1_Und_2(){
repeat(6){
moveForward();
pickBeeper();
}
repeat(2){
moveForward();
turnLeft();
}
repeat(6){
moveForward();
pickBeeper();
}
}
void letztesDrehen(){
repeat(2){
moveForward();
turnRight();
}
}
1.3.1 "harvestTheField"
Schau dir das Bewegungsmuster von Karel mal genau an. Um die 4 Beeper auf der Diagonalen einzusammeln (beispielsweise die ersten 4), hat er immer die gleichen Bewegungen.
Starte damit, in dem du dir eine Funktion [bsp „void Diagonal()“ ] erstellst.
void harvestTheField(){
Diagonal();
Ende();
Diagonal();
turnAround();
Diagonal();
Ende();
Diagonal();
}
void Diagonal(){
repeat(4){
moveForward();
pickBeeper();
turnRight();
moveForward();
turnLeft();
}
}
void Ende(){
repeat(2){
moveForward();
moveForward();
turnLeft();
}
}