====== Programmierkonzepte in Python ====== {{fa>angle-double-down}} Eine **Variable** ist ein Behälter, in dem Daten gespeichert werden können. Stelle dir z.B. einen Koffer vor, in dem du etwas aufbewahren kannst. Die Variable ist der Koffer und der Wert der Variablen ist der Inhalt dieses Koffers. Eine Variable erstellt man mit dem Gleichheitszeichen: meinKoffer = 3 Jedes Mal, wenn ich nun die Variable //meinKoffer// in meinem Programm aufrufe, wird sie durch ihren aktuellen Wert ersetzt. Das Gleichheitszeichen ( = ) hat in der Programmierung also nicht dieselbe Bedeutung wie in der Mathematik: es testet nicht, ob die linke Seite gleich ist wie die rechte Seite, sondern es definiert eine Variable und weist dieser den Wert zu, der auf der rechten Seite steht. In einer Variablen kann man ganze Zahlen (integer), Kommazahlen (float), Text (Strings), Wahrheitswerte (True oder False) oder auch Listen (Arrays) speichern. \\ \\ Wichtige Variablen sollten so bezeichnet werden, dass ihre Aufgabe im Programm erkennbar ist. Als Namenskonventionen gibt es Camelcase (diesIstEineVariable) und Snakecase (dies_ist_eine_Variable) {{fa>angle-double-down}} **Funktion** oder **Prozedur** (die beiden Begriffe werden hier als Synonym betrachtet) bezeichnet ein Unterprogramm, das durch seinen Namen aufgerufen werden kann. Der Vorteil liegt auf der Hand: wenn mehrmals dieselben Anweisungen nacheinander ausgeführt werden sollen, kann man diese als Funktion speichern und diese Funktion dann mehrmals über ihren Namen aufrufen. Dies wird in Python durch den Befehl ''def'' realisiert. Funktionen dienen dazu Redundanz (überflüssiger Code, z.B. mehrmals dieselben Befehle) zu vermeiden und das Programm zu strukturieren (Unterprogramme). def baueSpirale(): drehRichtung = TurnDirection.LEFT # Alternativ: drehRichtung = TurnDirection.RIGHT for i in range(1,7): agent.turn(drehRichtung) agent.move(FORWARD,i) baueSpirale() ** Globale und lokale Variablen ** Oben wird die Variable ''drehRichtung'' innerhalb der Funktion ''baueSpirale'' definiert. Man kann sie dann nur innerhalb dieser Funktion verwenden: man spricht von einer **lokalen Variablen**. Würde man die Variable ausserhalb der Funktion (ganz zu Beginn des Codes) definieren, dann wäre sie überall im Programm sichtbar, auch in den Funktionen. Man spricht dann von einer **globalen Variablen**. ==== Funktion mit Parametern ==== Wenn man mit ''def'' eine eigene Funktion definiert, kann man diese flexibler machen, indem man Parameter verwendet. Dies sind Variablen, die beim Aufruf der Funktion übergeben werden und dann innerhalb der Funktion wie lokale Variablen funktionieren. So könnte man z.B. eine Funktion ''Hochhaus(n)'' definieren, welches ein Hochhaus mit n Etagen baut. Wenn man die Funktion dann aufruft, muss man für n einen konkreten Wert angeben: z.B. ''Hochhaus(7)''. Das Beispiel unserer Spirale können wir mit Parametern etwas eleganter gestalten: wir übergeben der Funktion die Drehrichtung als Parameter. def baueSpiraleNeu(richtung): for i in range(1,7): agent.move(FORWARD,1) agent.turn(richtung) baueSpiraleNeu(TurnDirection.LEFT) baueSpiraleNeu(TurnDirection.RIGHT) Nun können wir dieselbe Funktion verwenden, um rechtsdrehende und linksdrehende Spiralen zu bauen. Wir übergeben beim Aufruf der Funktion die Drehrichtung (''baueSpiraleNeu(TurnDirection.Right)'') und diese Drehrichtung ist dann innerhalb der Funktion an die Variable ''richtung'' gekoppelt (da wir bei der Definition der Funktion diesen Namen gewählt haben). {{fa>angle-double-down}} ==== Listen erstellen ==== Mit eckigen Klammern kann man in Python eine Liste erstellen. Dabei können die einzelnen Elemente der Liste ganz unterschiedliche Typen haben. Es können sogar selbst wieder Listen sein. Auf die einzelnen Elemente der Liste kann man zugreifen, indem man den Namen der Liste mit eckigen Klammern und dem Index angibt (der Index bezeichnet die Position des Elementes in der Liste - er beginnt bei 0. Gibt man als Index negative Zahlen an, so zählt Python vom letzten Element an rückwärts. D.h. das letzte Element der Liste ''Liste1'' erhält man mit ''Liste1[-1]'' >>> Liste1 = [1, 2, 3, 4, 5] >>> Liste2 = [51, "Hallo", True, 3.141592] >>> Liste1[1] 2 >>> Liste2[-1] 3.141592 >>> Listen verwendet man oft, wenn man viele Daten speichern muss. Statt dass man z.B. zehn Variablen ''v1=5, v2=3, v3=8, v4=9,..., v10=0.34'' definiert, erstellt man besser eine Liste 'v = [5,3,8,9,...,0.34]' und greift dann auf die Werte zu, indem man ''v[0]'', ''v[1]'' etc. aufruft. ==== Der range-Befehl ==== Sehr häufig möchte man eine regelmässige Liste von Zahlen erstellen: z.B. alle Zahlen von 1 bis 10 oder die Zahlen von 1 bis 100 in 2er-Schritten etc. Dazu ist der range-Befehl sehr praktisch: Er erstellt eine Liste von einem Startwert bis zu einem Endwert mit einer bestimmten Schrittweite: ^ range-Befehl ^ Bedeutung ^ | ''range(10)'' | Liste der Zahlen von 0 bis 10 (exklusive 10), also [0,1,2,3,4,5,6,7,8,9] | | ''range(4,9)''| Liste der Zahlen von 4 (inkl.) bis 9 (exkl.), also [4,5,6,7,8] | | ''range(13,25,3)''| Liste der Zahlen von 13 (inkl.) bis 25 (exkl.) in 3er-Schritten, also [13,16,19,22] | ==== Listen abklappern (durchgehen) ==== Ganz oft will man für alle Elemente in einer Liste dasselbe tun, d.h. man will die Liste "abklappern" (durchgehen) und dann für jedes Element dieselabe Aktion durchfühen. Z.B. hat man eine Liste von Positionen und möchte bei jeder Position ein Haus bauen, oder man hat eine Liste von Baumaterialien und man möchte für jedes dieser Materialien einen Block platzieren etc. Dafür gibt es in Python den Befehl ''for in ''. Am besten versteht man dies an einem Beispiel. Wir verbessern unser Programm, welches die Spirale baut, weiter: Der folgende Code kann verbessert werden: agent.move(FORWARD,1) agent.turn(richtung) agent.move(FORWARD,2) agent.turn(richtung) agent.move(FORWARD,3) agent.turn(richtung) agent.move(FORWARD,4) agent.turn(richtung) agent.move(FORWARD,5) agent.turn(richtung) agent.move(FORWARD,6) Wir sagen Python einfach: Gehe alle Zahlen von 1 bis 6 durch (sage der Variable z.B. ''zahl'') und mache dann die beiden Befehle: agent.move(FORWARD,zahl) agent.turn(richtung) Damit sieht unser Programm viel kürzer aus: def baueSpirale(richtung): for zahl in [1,2,3,4,5,6]: agent.move(FORWARD,zahl) agent.turn(richtung) Die Liste [1,2,3,4,5,6] können wir uns natürlich auch mit dem Range-Befehl erstellen lassen: def baueSpirale(richtung): for zahl in range(1,7): agent.move(FORWARD,zahl) agent.turn(richtung) Will man z.B. etwas 10-Mal wiederholen, so kann man einfach den Befehl: ''for i in range(10)'' verwenden. for i in range(10): # i geht die Zahlen von 0 bis 9 durch agent.move(FORWARD,2) agent.place(BACK) ^ Listenbefehl ^ Bedeutung ^ | ''L1 = [3, "bla", 5, 6]'' | Liste erstellen | | ''L1[1]'' | Auf das erste Element zugreifen (Achtung: Zählung beginnt bei 0!) | | ''len(L1)'' | Länge der Liste L1 (Anzahl der Elemente) | | '' [3,6]+[1,9]'' oder \\ ''[3,6].extend([1,9])'' | Listen zusammenfügen | | '' del L1[0]'' | Ein Element bei einem best. Index löschen | | '' L1.remove("bla")'' | Ein Element mit einem bestimmten Wert löschen | | '' L1[1:3]'' | Unterliste von Index 1 (inkl.) bis Index 3 (exkl.) | | '' L1[1:]'' | Unterliste von Index 1 (inkl.) bis zum Schluss der Liste | | '' 3 in L1'' | Testet, ob der Wert 3 in der Liste L1 enthalten ist. Gibt ''True'' oder ''False'' zurück. | {{fa>angle-double-down}} ==== Verzweigungen mit if ==== Mit der ''if'' Anweisung kann man Befehle nur dann ausführen lassen, wenn eine bestimmte Bedingung wahr (True) ist. if (agent.get_item_count(1)>0): # wenn noch Material im Fach 1 liegt agent.set_slot(1) # Das aktuelle Fach auf 1 setzen Man kann mit dem ''if''-Befehl auch mehrere Bedingungen prüfen (''elif'') und am Schluss etwas ausführen, wenn keine Bedingung zutrifft (''else''): if (agent.get_item_count(1)>0): # wenn Material im Fach 1 liegt agent.set_slot(1) # Fach 1 als aktuelles Fach setzen elif (agent.get_item_count(2)>0): # sonst: wenn Material in Fach 2 liegt agent.set_slot(2) # Fach2 als aktuelles Fach setzen else: # sost player.say("Ich habe nichts im Fach 1 oder 2!") # den Spieler sagen lassen, dass nichts im Inventarslot 1 oder 2 liegt. ==== Schleifen mit "while" ==== Wir haben bereits die ''for''-Schleife gesehen, um Befehle zu wiederholen. Mit der ''while''-Schleife kann man das auch tun, wobei die Wiederholung nicht durch eine Liste gesteuert ist (wie bei der ''for''-Schleife) sondern durch eine Bedingung. Solange die Bedinugung wahr (True) ist, werden die Befehle wiederholt: agent.set_slot(1) while agent.get_item_count(1)>0: # solange noch etwas im Fach 1 ist agent.place(BACK) # Material bauen agent.move(FORWARD,1) # nach vorne gehen [[gf2:start|Zurück zur Übersicht]]