Lehrzeit

Schule & Informatik

Diese verdammte for-Schleife

Das ist, glaube ich, der Gedanke, den viele meiner 10. und leider auch 11.-Klässler haben, wenn mal wieder der Compiler meckert oder das Programm nicht das tut, was es soll. Ich versuche dann den Schülern  zu erklären, dass die Struktur, die sie sich einprägen müssen,  wie folgt aussieht (erstellt mit „meinem“ EBNF-Syntaxdiagramm-Wandler):

Aber irgendwie klappt das bei ganz vielen nicht. Meine neueste Vermutung, warum sich so viele damit schwer lautet: for-Schleife und Arrays habe ich bisher mehr oder weniger zusammen eingeführt. Damit habe ich aber zwei Konzepte miteinander verknüpft, die eigentlich gar nichts zwingend miteinander zu tun haben. Das möchte ich dieses Jahr trennen. Ich führe erstmal die for- und später auch die while-Schleife ein und viiiiiiieeeel später dann die Arrays.

Und damit das alles nicht so langweilig wird und die Schüler auch Programmierergebnisse sehen, greife ich auf Processing zurück. Darüber schrieb ich bereits schon einmal und möchte hier meinen Weg darstellen. Ob das dann alles so geklappt hat, werde ich in ein paar Wochen schreiben.

Basis für die Schüler ist ein fast leeres BlueJ-Projekt (FarbenSpielVorlage), das in einem +libs-Ordner die processing-Library enthält. Dazu noch zwei Klassen, damit die Schüler sich nicht lange mit der Startkonfiguration rumärgern müssen. Und um es gleich vorwegzunehmen: Man könnte auch gleich mit einem Online-Processing-Editor bzw. p5.js-Editor anfangen, aber es geht um Java und ich möchte nicht unnötig Verwirrungs stiften. Erst  „int“ und „double“  etc. bei Java einführen und dann JavaScript-Variablendefinitionen wie beispielsweise „let x=0;“ sind für Programmieranfänger dann doch ein wenig viel.

Das schöne bei processing ist, dass man als Programmierer gleich „coole“ Sachen programmieren kann. Anregungen findet man dazu bei processing selbst, aber auch bei p5 bzw. beim CodingTrain.

Bei meinem Startbeispiel (FarbenSpielVorlage) wird zwar nur ein weißer Punkt an der Stelle gezeichnet an die der Anwender  geklickt hat. Aber wer mal versucht hat, dies direkt in Java umzusetzen, wird den Unterschied erkennen:

 if (mousePressed) {
    fill(255);
    ellipse(mouseX, mouseY, 10, 10);
 }

Hier können die Schüler einzelne Parameter (Farbe, Größe) leicht unter meiner Anleitung verändern.

Sollen aber mehrer Punkt gezeichnet werden, so wird irgendeine Form der Zählwiederholung benötigt, wie die Schüler sie oftmals aus der 7. Klasse bei Karol kennengelernt haben. Und schon bin ich bei der for-Schleife und damit bei beispielsweise dem nebenstehenden Verlauf.

Daraufaufbauen ließe sich ein Funktionsplotter umsetzen oder Lissajous-Figuren realisieren. Auch einfache Spiele wären denkbar.

Für den Übergang zu den Arrays nehme ich dann wieder das Startprojekt, speichere aber dann die geklickten Punkt in diesem Array und iteriere über dieses Feld.  Mal schauen, wie es wird.

 

 

 

14 Kommentare

  1. Vielleicht hilft eine Form der foreach-Schleife, die über einen Zahlengenerator iteriert. Die allgemeine Form, die du in deinem Diagramm zeigst, ist sehr technisch und auch schwer zu verstehen. In Python sieht das sehr viel leichter aus.

    for i in range(5):
    print(i)

    Im Vergleich in Java:

    for(int i=0; i<6; i++) {
    System.out.println(i);
    }

    Das ist viel Syntax und viel Fehlerpotenzial. Wenn du ganz auf Syntaxfehler verzichten magst, wäre auch ein Blick in Scratch möglich, damit man das Konzept "Wiederholung durch Schleifen" dort versteht, bevor es in einer "richtigen" Programmiersprache umgesetzt wird.

    Der Ansatz mit Processing sieht aber auch vielversprechend aus.

  2. Hast du einen Grund dafür, mit der for-Schleife anzufangen? Die While -Schleife ergibt sich doch syntaktisch und semantisch direkt aus dem if-Befehl. Das finde ich viel schlüssiger. Ich zeige meinen Schülern (die allerdings wahrscheinlich nicht das Niveau deiner bayrischen Gymnasiasten haben) lange Zeit nur while. Auch beim Zählen verwenden die nur while. Bei Arrays bzw. Arraylists dann die for each Schleife und erst später mal bei einer Zusammenfassung aller Konzepte die klassische for-schleife und do-while.
    Käme das für dich nicht in Frage?

    • Das ist eine gute Frage… Für mich ist eine „klassische for-Schleife“ eigentlich nichts anderes als eine kompakte Form der while-schleife, da man die 3 Komponenten „Zähler-Variabe, Bedingung, Schrittweite“ einfach in einer Zeile zusammenfasst. Insofern könnte ich dieses Jahr erst mal die while-Schleife und dann, quasi als abkürzende Schreibweise, die „klassische for-Schleife“ einführen. Das werde ich mal versuchen.
      Eigentlich finde ich die ganze Thematik sowieso völlig veraltet. Wer benutzt heutzutage noch Arrays? Inzwischen werden doch wohl hauptsächlich (Array)Lists benutzt, oder? Und im Abitur wird es eigentlich auch nicht benutzt. Da hat man nur noch Objekte, die sich gegenseitig aufrufen. Da wird eine for-Schleife Zählwiederholung nur noch beim Thema Assembler benutzt.

      • „for als kompaktes while“: Genauso sehe ich das auch, zumindest in C, C++, Java. In Pascal gab es eine echte Zählschleife: for i := 1 to 17 do, in BASIC dasselbe sogar noch mit STEP für die Schrittweite. Das sind wirklich einfache Zählschleifen, auch sehr nahe an der (mathematischen) Sprechweise „für alle i von 1 bis 17 mache Folgendes“. Diese Nähe zur Sprache fehlt in C und Nachkommen völlig.
        Die for-Schleife in Java hat m.E. nur einen einzigen echten Vorteil: Die Zählvariable ist tatsächlich lokal zur Schleife und nicht zur Methode – aber das dürfte weder für meine noch deine Schüler allzu relevant sein.
        Zu Arrays: Auch da wieder volle Zustimmung. Ich bringe meinen Schülern tatsächlich nur die ArrayList bei. Allerdings mit Bauchschmerzen. Denn ich kann ja dann nicht mal richtig erklären, worauf sich das Wort „Array“ im Klassennamen bezieht. Und ich muss Ihnen sagen, dass sie ArrayList schreiben müssen, nicht ArrayList. (Das könnte sich aber mit Project Valhalla endlich ändern: http://openjdk.java.net/jeps/218)
        Aber: Die ArrayList ist wenigstens objektorientiert, eine ganz normale Klasse mit ganz normalen Methoden und (außer den Generics beim Deklarieren) keiner Spezialsyntax. Und der int/Integer-Problematik kann man natürlich ausweichen, indem man Listen von Strings oder Listen von MeineEigeneKlasse benutzt. Das ist dann schöner.
        Trotzdem ist meine Erfahrung: Egal wie sehr ich den Schülern diese Fallen aus dem Weg räume, Schleifen bleiben trotzdem schwierig, insb. die Verbindung zwischen Zähl- und anderen Variablen. Z.B. gelingt es fast keinem meiner Schüler ohne Hilfe, die Summe über die Werte in einer Liste oder gar den Durchschnitt dieser Werte zu berechnen. Auf die Idee, gleichzeitig zu zählen und eine andere Variable als Akkumulator zu benutzen, kommt keiner. Und selbst den entsprechenden Code nur zu *verstehen*, ist für viele eine echte Schwierigkeit. Ich versuche dabei immer daran zu denken, wie schwer sich selbst erfahrene Programmierer mit dem (inhaltlich identischen) reduce(+, liste, 0) tun.

        Fazit: Schleifen sind nicht ohne, deswegen sollte man wohl versuchen, Schwierigkeiten möglichst zu entkoppeln. Ich mache in Greenfoot inzwischen sogar erstmal Schleifen ganz ohne Variablen. Z.B. while (!onLeaf()) { move(); }. Aufgabe: Wie sieht der Bildschirm nach Ausführung der Schleife aus? Dann mit Zählvariablen. Dann mit komplexeren Rechnungen (effektiv heißt das SQL-Funktionen nachbauen: COUNT, SUM, AVG, s.o.). Und das Ganze mit komplexeren Objekten. Meine Lieblingsaufgabe: eine Liste aller Gegenstände eines Rollenspiel-Charakters ausgeben und zum Schluss deren Gesamtwert. Aber immer ohne die klassische for-Schleife…

        • ah, die spitzen Klammern wurden geklaut. Gemeint ist natürlich (mit größer/kleiner-Zeichen): Und ich muss Ihnen sagen, dass sie ArrayList[Integer] schreiben müssen, nicht ArrayList[int].

        • Die for-Schleife in Java hat m.E. nur einen einzigen echten Vorteil: Die Zählvariable ist tatsächlich lokal zur Schleife und nicht zur Methode – aber das dürfte weder für meine noch deine Schüler allzu relevant sein.

          Die Scoping-Problematik und was alles dahinter stecken kann, habe ich vor ein paar Wochen zum ersten Mal bewusst beim Coding Train auf youtube gesehen. Der Unterschied zwischen var und let war mir gar nicht so bewusst.

          Aber eine ähnliche Problematik habe ich bei Java und wenn Schüler fragen, warum if (name=="Hans") nicht geschrieben werden darf bzw. soll. In der 11. Klasse hole ich dann weiter aus und erzähle etwas vom Konstantenpool. In der 10. Klasse erzähle ich dann, dass zwei Schüler mit dem gleichen Namen „Anna“ ja auch verschiedene Personen sind. Selbst wenn sie gleich angezogen sind.

          Zurück zum Thema: Beim mir sind Variablen meistens Zettel, die man beschreiben kann. Ich habe also einen Zettel, der mitzählt und einen Zettel, auf dem aufaddiert wird. Viele tun sich damit aber auch damit schwer, weil einfach zu viel schon in den Köpfen der Schüler abläuft. Es ist das runterbrechen auf die grundlegenden Schritte, das die Schüler nicht schaffen. Ich muss da nochmal drüber nachdenken, wie ich das angehe. Mir schwebt da ein Ansatz wie beim Martin Kramer vor, der Theater-Elemente mit in den Unterricht einbaut.

          Dein Ansatz über Greenfoot mache ich häufig mit Hilfe von Kara. Da kann ich dann auch gleich noch endliche Automaten mit erschlagen.

          • String-Vergleich: Vom Konstantenpool brauche ich bei meiner Schülerklientel gar nicht zu sprechen anfangen. Aber toll, dass du das machst (Neid!) In Kotlin (s. mein anderer Kommentar unten) haben sie auch das das umgedreht: == entspricht equals() und === entspricht dem „Pointer-Vergleich“. Tolle Idee und wieder eine Ablenkung vom Wesentlichen weniger.

            Variablen: Das ist wirklich so viel schwieriger als man zuerst denkt! Martin Kramer ist sicher eine gute Inspiration. Lass uns wissen, welche Ideen dir gekommen sind. Eine meiner Erkenntnisse war, dass ich inzwischen versuche, zu jedem Thema erstmal viele *Leseaufgaben* zu stellen, d.h. ich gebe Code vor und die Schüler müssen z.B. sagen, welchen Wert die Variablen am Ende haben. Damit entkoppele ich (hoffentlich) das Verständnis vom Anwenden können. Gerade bei Schleifen ist es recht leicht, sich da nichttriviale Aufgaben auszudenken. So sehen die Schüler auch am Anfang mehr Beispiele für die richtige Anwendung der Konzepte, bevor sie sich selber daran versuchen.

            Kara: Mache ich genau wie du für den Einstieg. Nur nutze ich, weil ich nicht zu oft die Entwicklungsumgebung wechseln will, GreenfootKara http://code.makery.ch/library/greenfoot-kara/de/, so dass die Schüler dann später damit auch ihr mehrwöchiges Projekt, ein 2D-Spiel, entwickeln können. Parallel dazu kommt dann aber auch der Java-Editor http://javaeditor.org zum Einsatz, weil bei Greenfoot so viel „Magie“ im Hintergrund ist, dass es für die Schüler schwer ist zu verstehen ist, was genau bei der Programmausführung alles passiert. Außerdem ist das Modellierungstool des JavaEditors sehr schön.

          • Ein Freund des Javaeditors bin ich auch. Der kann so viel! Einfach toll. An manchen Stellen finde ich es dann aber auch übetrieben kompliziert, wie beispielsweise bei der Klassendefinition. Das muss man soviel rumklicken, dass selbst ich irgendwann den Überblick verliere und mehr über das „Wie muss ich das jetzt klicken“ nachdenke als über „Was brauche ich noch alles für meine Klasse.“

            Mit Greenfoot habe ich generell noch keine Erfahrung, da ich mit Karol, Karol mit Java und Kara eigentlich alles habe, was ich brauche. Ich schaue mir die Greenfoot-Kara aber gerne mal an.

            Und die Seminare kommen eigentlich immer zustande, wenigstens eins. Von durchschnittlich vielleicht 80 Informatikschülern in der 10. Klasse brauche ich ja nur mindestens 12 Schüler für einen Kurs. Das klappt in der Regel eigentlich immer.

  3. Die Lehrplankommission hält Arrays für so wichtig, dass die im G8-Lehrplan – was auch immer aus dem werden wird, zugegeben – eine noch größere Rolle spielen als bisher. Ob die Thematik veraltet ist… es geht ja nicht darum, die SuS auf einen Beruf als Programmierer vorzubereiten. Und wenn sie wissen sollen, ob sie eine ArrayList oder eine LinkedList verwenden sollen, müssen sie eben schon wissen, was ein Array ist.

    Andererseits… es fällt ihnen wirklich schwer. Ich überlege, ob man nicht über das hochsprachlichere Konzept Iteration herangehen soll, also erst einmal for(int element : numbers), habe das aber auch noch nie versucht, sondern es eher so wie Ingo gemacht. Also ohne while zuvor.

    Dass mit while-Schleife und expliziter Zählvariable habe ich auch schon versucht. Hat sich auch nicht als Königsweg herausgestellt, aber ist wohl schon auch ein Weg.

    • Arrays entsprechen ja auch schön anschaulich einem bestimmten Speicherbereich. Problematisch finde ich in Java halt, dass sie syntaktisch so wenig objektorientiert daherkommen. Und das widerspricht diesem absoluten Fokus auf OO in den Lehrplänen. Oder ist das bei euch in Zukunft nicht mehr so extrem?

      for(int element : numbers): Das meinte ich weiter oben mit „foreach-Schleife“. Funktioniert bei mir gut. Es gibt natürlich Fälle, wo man die Zählvariable gern hätte. Dann halt wieder mit einer while-Zählschleife und liste.get(i). Funktioniert auch ganz gut. In Python würde man dann „for i, obj in enumerate(liste)“ benutzen – das ist IMHO noch schöner. Aber man kann eben nicht alles haben.

      • Noch ein Nachtrag: In Kotlin (in vieler Hinsicht das „neue und verbesserte Java“) gibt es anscheinend nur noch die for-Schleife als Iteration. Zum Iterieren über die Indizes eines Arrays heißt es im Manual:

        If you want to iterate through an array or a list with an index, you can do it this way:
        for (i in array.indices) {
        print(array[i])
        }

        Sehr hübsch!

        • Von Kotlin hatte ich irgendwann mal gelesen. Da ich aber meinen Unterricht stark auf die Anforderungen des Abiturs ausrichte (und damit auf Java), kommt es nicht in Frage.

          Vielleicht sollte ich mal ein W-Seminar (vorwissenschaftliches Seminar an bayerischen Gymnasien) mit dem Thema „Andere Programmiersprachen“ anbieten. Oder ein P-Seminar an dem am Ende ein Vergleich verschiedener Programmiersprachen herauskommt. Dann hätte ich nicht immer die Diskussion am Anfang der 11. Klasse, dass Java „doch total Scheiße“ ist.

          Nach einem Jahr Uni kam im übrigen mal ein Schüler zu mir und meinte, dass ich recht hatte mit meiner Aussage „Es gibt keine schlechten Programmiersprachen, es gibt nur falsche Einsatzgebiete.“ und das er jetzt auch die Vorteile von Java zu schätzen weiß.

          • Kotlin: Ich habe bisher auch (noch) keine Zeile Kotlin programmiert und werde das sicher nicht so schnell im Unterricht einsetzen. Das Beispiel hab ich nur gebracht, weil man daran gut sieht, dass die Entwickler offensichtlich die alte for-Schleife auch für überflüssig halten. Überhaupt: Wenn man sich mal anschaut, was die bei Kotlin gegenüber Java geändert haben, dann ist das extrem spannend: keine primitiven Datentypen mehr, == statt equals(), void ist optional, Typinferenz, Deklaration im Pascal-Stil, null-sichere Datentypen, und und und. Lauter kleine und große Änderungen, die für mich alle total Sinn machen und ganz viele Klippen der Schüler umschiffen würden, da bin ich sicher. Und, da JVM-basiert, voll mit Java kompatibel. Es wäre halt toll, wenn es auch so schöne pädagogische Umgebungen wie Greenfoot, BlueJ, Kara/Karol, etc dafür gäbe wie für Java.

            W-Seminar/P-Seminar: Wenn du dafür genügend Interessenten hättest, wäre das bestimmt super. Ich hab mal (bei so einem Kurs für „Begabte“) auch Prolog und ein ganz bisschen Lisp gemacht. Fanden die toll!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

*

© 2017 Lehrzeit

Theme von Anders NorénHoch ↑