Python 3.0 im Informatikunterricht der Jahrgangsstufe 8 Einführung V. Berg 2015 Der Text wird zurzeit ständig aktualisiert. Die aktuelle Version stammt vom 10.05.15. Einleitung Die Programmiersprache Python Installation Der interaktive Modus und Idle Einfache Datentypen Ganze Zahlen Gleitkommazahlen Zeichenketten Variablen Arithmetische Operatoren für Zahlen Mathematische Standardfunktionen Aufgaben 1 Informative Programme Grundlegendes zu Python-Programmen Aufgaben 2 Turtle Die Turtle und ihre Befehle Aufgaben 3 Schreiben einer Funktion Architektur am Bildschirm Kontrollstrukturen Verzweigungen Aufgaben 4 Wiederholungen For-Schleife While-Schleife Aufgaben 5 Wahr oder falsch Funktionen mit Rückgabe Aufgabe 6 Rekursion Objekte und Methoden Polyturtle Strings, Tuples und Listen Strings Tuples Listen Aufgaben 7 Wörterbücher Caesar-Code Einleitung Die Programmiersprache Python Python ist eine objektorientierte Skriptsprache, die Anfang der 1990er-Jahre von Guido van Rossum am CWI (Centrum voor Wiskunde en Informatica) in Amsterdam entwickelt wurde und heute auf einer Vielzahl von Betriebssystem-Plattformen (Unix/Linux, Windows, MacOS, etc.) verfügbar ist. Ihre leicht lesbare Syntax und umfangreiche Standard-Bibliothek ("Batteries included") sowie eine Vielzahl von Erweiterungen aus den verschiedensten Bereichen (GUI, Netzwerke, Datenbanken, Graphik, 3D, Audio, Video, Web, GIS, Numerik, Spiele, etc.) haben sie zum Mittel der Wahl bei vielen Open-Source-Projekten und in namhaften Unternehmen und Organisationen gemacht. Die Sprache ist nach der britischen Komikertruppe Monty Python benannt, nicht etwa nach der gleichnamigen Schlangengattung. Installation Die jeweils aktuelle Version (zur Zeit Version 2.7.9 vom 10.12.2014, Version 3.4.3 vom 25.02.2015) von Python findet man auf der offiziellen Python-Website unter http://www.python.org. Es gibt Versionen für Windows, Linux und Mac OS X. Viele Linux-Distributionen beinhalten Python bereits. Unter Windows muss Python in jedem Fall installiert werden. Im Unterricht wird die Version 3 benutzt. Nach der Installation unter Windows befinden sich im Startmenü unter Python 3.4 zwei wichtige Einträge: IDLE(Python GUI) und Python(command line). Das erste Programm startet die graphische Entwicklungsumgebung, das zweite den interaktiven Modus. Der interaktive Modus und IDLE Im interaktiven Modus können einzelne Programmzeilen eingegeben und direkt betrachtet werden. Zum Erlernen der Sprache Python wäre er somit fast ideal, da sehr schnell kleine Programme oder Programmzeilen getestet werden können. Seine Lesbarkeit ist jedoch sehr schlecht, da in einem schwarzen Fenster graue Schrift benutzt wird. Die IDLE (Integrated DeveLopment Enviroment) ist eine graphische Entwicklungsumgebung (Python-Shell). Beim Starten wird ein Fenster geöffnet, das wie der interaktive Modus Direkteingaben zulässt. Über den Menüpunkt File New Window kann eine Python-Programmdatei erstellt und editiert werden. Für das Programmieren ist diese Oberfläche wesentlich brauchbarer als der interaktive Modus. Die Python Shell meldet sich in beiden Versionen mit dem Bereitschaftszeichen (Prompt) >>>. Nach dem Prompt kann man einen Ausdruck oder eine Anweisung eingeben. Wie vorgeschlagen kann man einmal die Begriffe "copyright", "credits" und "license()" eingeben. Nach Auswertung der Eingabe durch den Interpreter wird eine Ausgabe in der nächsten Zeile gemacht. Dieses Verfahren lässt sich nicht auf mehrere Programmzeilen anwenden. Dazu benutzt man wie schon erwähnt einen Editor. Die Ausgabe kann dann auch in der Python-Shell erfolgen. Einfache Datentypen Die interaktive Python-Shell kann man auch als "Taschenrechner" nutzen. Man tippt einfach den gewünschten Ausdruck nach dem Prompt ein, und betätigt die Eingabetaste. >>> 13+4*3 25 >>> (13+4)*3 51 >>> (3-5)*(13+4) -34 Python kennt, wie die meisten anderen Programmiersprachen, die Regel "Punktrechnung geht vor Strichrechnung". Genauso werden Klammern in arithmetischen Ausdrücken erkannt. Eine Besonderheit ist das oder die Divisionszeichen. In Python werden drei verschiedene Divisionszeichen verwendet. >>> 6/4 1.5 >>> 6 // 4 1 >>> 6 % 4 2 Die erste Rechnung verwendet das „normale“ Divisionszeichen. Das Ergebnis ist wie erwartet. Was passiert aber bei den anderen Divisionen? Dividiert man zwei Ganzzahlen mittels des doppelten Divisionszeichens ist auch das Ergebnis eine Ganzzahl. 4 ist in 6 einmal enthalten. Dividiert man zwei Ganzzahlen mittels des Prozentzeichens, führt man eine modulo-Division durch Das Ergebnis ist der Rest der Division. Dividiert man 8%4 erhält man 0, da es bei dieser Division keinen Rest gibt. Ganze Zahlen und Gleitkommazahlen Das Literal für eine ganze Zahl (int) besteht aus den Ziffern 0 bis 9 und eventuell einem positiven oder negativem Vorzeichen. Das Literal der Gleitkommazahl (float) besteht aus einem Vorkommateil, einem Dezimalpunkt und einem Nachkommateil. Wichtig ist, dass ein Dezimalpunkt und kein Dezimalkomma, wie im Deutschen üblich, verwendet wird. Das Komma hat in Python eine andere Funktion, es ist in der Regel ein Trennzeichen. Zeichenketten Zeichenketten (string) sind neben den Zahlen von entscheidender Bedeutung. Sie ermöglichen es, Texte einzulesen, zu speichern und auszugeben. Um einen String zu erzeugen, wird der Text in doppelte Hochkommata geschrieben: >>> “Hallo Welt“ ’Hallo Welt’ Der Interpreter gibt den Text in einfachen Hochkommata aus. Möchte man dies verhindern, benötigt man die print-Anweisung: >>> print (“Hallo Welt“) Hallo Welt >>> print (“3*12“) 3*12 >>> print (3*12) 36 “3*12“ ist ein String und wird von print Zeichen für Zeichen hingeschrieben, 3*12 ist ein arithmetischer Ausdruck und wird zuerst berechnet und dann ausgegeben. >>> print (“3*12“,3*12) 3*12 36 Die Klammern sind beim print-Befehl zwingend vorgeschrieben. Variablen Wie in anderen Programmiersprachen ist es auch in Python möglich, einer Zahl oder einem String einen Namen zuzuweisen. In solch einer Zuweisung wird der Namen auf der linken und das Literal auf der rechten Seite eines Gleichheitszeichens notiert. Der Variabelenname (Bezeichner) darf aus allen Buchstaben des Alphabets und dem Unterstrich zusammengesetzt werden. Nach mindestens einem Buchstaben oder dem Unterstrich dürfen auch Ziffern verwendet werden. Bestimmte Schlüsselwörter (reservierte Wörter) dürfen nicht als Namen verwendet werden. Die folgende Tabelle enthält die Python Schlüsselworte: and assert elif else global if or pass yield Break Class Continue Def Del except exec finally for from import in is lambda not print raise return try while >>> name=0.5 >>> var123=12 >>> string=“Hallo Welt“ >>> name 0.5 >>> string ‘Hallo Welt’ >>> 2*name 1.0 >>> (var123+var123)/3 8.0 >>> var123+name 12.5 >>> a=1+2 >>> b=var123/4 >>> a+b 6 Mathematische Standardfunktionen Neben den Operatoren für Addition, Subtraktion, Division und Multiplikation bietet Python eine Reihe vordefinierter Funktion an. Diese befinden sich zum Teil im Modul math. Deshalb muss dieses zu Programmanfang geladen werden: from math import * Folgende Funktionen werden häufig benötigt (eine vollständige Liste befindet sich in den Dokumentationen): Funktion fabs(x) exp(x) log(x) log(x,y) log10(x) pow(x,y) sqrt(x) sin(x) cos(x) tan(x) Bedeutung Argument ist vom Typ Absolutbetrag int, float Exponentialfunktion int, float natürlicher int, float Logarithmus Logarithmus zur int, float Basis y Zehnerlogarithmus int, float Potenz xy int, float Quadratwurzel int, float Sinus (Argument int, float im Bogenmaß) Cosinus (Argument int, float im Bogenmaß) Tangens int, float Ergebnis ist vom Typ float float float Beispiel float log(8,2) float float float float log10(100) pow(2,3) sqrt(25) sin(30) float cos(30) float tan(30) fabs(-3.5) exp(3) log(3) asin(x) acos(x) atan(x) pi degrees(x) radians(x) (Argument im Bogenmaß) Arcussinus (Argument im Bogenmaß) Arcuscosinus (Argument im Bogenmaß) Arcustangens (Argument im Bogenmaß) die Zahl Pi wandelt Winkel vom Bogenmaß in Gradzahl um wandelt Winkel von Gradzahl in Bogenmaß um int, float float asin(30) int, float float acos(30) int, float float atan(30) int, float float float pi degrees(0.8) int, float float radians(30) Aufgaben 1 1. Gib den Bildschirmausdruck an! Kontrolliere anschließend durch Eingabe der Programme. a) print ("a = "), b) print ("a = ") c) print ("a = ") d) print (“a = “), print (9) print (9) print () print () print (9) print () print (9) 2. Verfahre wie in Aufgabe 1. a) print ("9 17 Ende") c) print ("9","17","Ende") b) d) print ("9" "17" "Ende") print (9,17,"Ende") 3. Schreibe ein Programm, das nach Eingabe der Zahlen 5 und – 20 den folgenden Ausdruck liefert (nur print-Anweisungen: 5 -20 -205 -20 Das war’s 4. Gib die Werte der Variablen nach Ausführung der Anweisungsteile an. a) a=5 b) a=5 c) a=3 b=4 b=4 x=a a=2*a c = -10 x=x*x b=a+b c=a*b x=a+x a=a*a a=b–1+c a=x-a b=3*(a–c)*(a–c) 5. Schreibe ein Programm zur Berechnung des jeweiligen Terms. a) a² - 7 b) a–b c) a*b -----------a+b a–b 6. Berechne den Wert der folgenden Zuweisungen: a) a = 3 + 14 % ( 7 * 5 ) b) b = 3 + 14 % 7 * 5 c) c = ( 3 + 14 ) % 7 * 5 d) d = 3 * 14 % 7 * 5 d) a+b ------a*b e) e = ( 17 % 5 ) + ( 17 / 5 ) * 5 f) f = ( 100 / 15 ) % ( 15 – 2 / 3) 7. Schreibe ein Programm zur Berechnung des jeweiligen Terms. a) (a+b)² b) a² + b² c) (a*b)² e) ab+2 f) ab+2 g) √a + 2 i) │a³-4b² │ j) │-b │ k) 232 - 216 d) h) l) a*b² √(a + 2) a² * b³ Informative Programme Die bisherigen Beispiele sind wenig benutzerfreundlich. Man muss sich jeweils merken, was eingeben wurde und was der Computer ausrechnet. Folgende Aufgabe soll etwas benutzerfreundlicher gestaltet werden: Ein Autofahrer möchte aus der verbrauchten Benzinmenge und der Anzahl der gefahrenen Kilometer den durchschnittlichen Benzinverbrauch pro 100 km Fahrstrecke berechnen. Das Ergebnis soll auf zwei Nachkommastellen gerundet werden. Wie kann man nun ein kleines Programm mit Python schreiben? In der Python Shell klickt auf File und dann auf New Window. In dem nun geöffneten Editor schreibt man das benötigte Programm. Man benötigt Eingabe-, Verarbeitungs- und Ausgaberoutinen (EVA-Prinzip). Die Verarbeitungs- und Ausgaberoutinen entsprechen den Eingaben im Direktmodus. Die Eingabeaufforderung erfolgt durch den Befehl input. Eine Eingabe wie 2+2 wird als String verarbeitet. Wenn eine Zahl eingeben werden soll, muss das Ergebnis von input explizit in einen Wert des Datentyps int (ganze Zahl) oder float (Gleitkommazahl) konvertiert werden. Das Programm sieht wie folgt aus: benzinmenge=float(input("Benzinverbrauch in Litern: ")) strecke=float(input("zugehoerige Wegstrecke in Kilometern: ")) verbrauch=benzinmenge/strecke*100 print ("Verbrauch je 100 km Wegstrecke in Litern: ",round(verbrauch,2)) Der Befehl round(x,n) rundet die Gleitkommazahl auf n Nachkommastellen. Der Parameter n ist optional und mit 0 vorbelegt. Bevor das Programm startet, fordert Python den Benutzer auf, den Quelltext zu speichern. Es ist sinnvoll, einen Ordner einzurichten, in dem man alle seine Programmierversuch speichern kann. Pythonprogramme müssen die Endung .py haben. Der Name des Programms sollte so gewählt werden, dass man auch später noch leicht erkennen kann, was das Programm macht. Benutzt man im Quelltext Sonderzeichen wie ä, ö, ü und ß meldet sich Python mit einer Warnung, dass die Codierung nicht dem Standard-ASCII-Zeichensatz entspricht. Beantwortet man die Warnung mit Ok wird die benötigte Erklärung automatisch in das Programm eingefügt. Ein weiteres Beispiel: Mischungstemperatur bei Wasser. Mischt man m 1 kg Wasser der Temperatur t1 und m2 kg Wasser der Temperatur t2, so stellt sich als Mischungstemperatur die Temperatur t=(m1t1 + m2t2) : (m1 + m2) ein. print ("Temperatur und Masse der ersten Wassermenge:") temp1=float(input("Temperatur: ")) masse1=float(input("Masse: ")) print print ("Temperatur und Masse der zweiten Wassermenge:") temp2=float(input("Temperatur: ")) masse2=float(input("Masse: ")) mischtemp=(masse1*temp1+masse2*temp2)/(masse1+masse2) print print ("Mischungstemperatur:",round(mischtemp,2)) Oft möchte man bei Berechnungen mit Gleitkommazahlen nur den ganzzahligen Anteil für weitere Berechnungen nutzen. Wie kann man den Nachkommateil entfernen? Dazu nutzt man den Befehl int(a.b). Das Ergebnis dieses Befehls ist a. Beispiel: Eine einzugebende Anzahl von Sekunden soll in größere Zeiteinheiten, nämlich in Jahre, Tage, Stunde, Minuten und Sekunden umgewandelt werden. Um Sekunden in Minuten umzurechnen teilt man den Sekundenwert durch 60. Man bildet den ganzzahligen Anteil und bestimmt anschließend den Rest. Den Minutenwert teilt man wieder durch 60, um den Stundenwert zu erhalten; es wird wieder der ganzzahlige Anteil bestimmt und der Rest bestimmt. Von den Stunden gelangt man zu den Tagen und anschließend zu den Jahren (Schaltjahre werden nicht berücksichtigt). sekunden=int(input("Eingabe der Sekunden: ")) minuten=int(sekunden / 60); sekunden=sekunden-minuten*60 stunden=int(minuten/60) minuten=minuten-stunden*60 tag=int(stunden/24) stunden=stunden-tag*24 jahr=int(tag/365) tag=tag-jahr*365 print (jahr, tag, stunden, minuten, sekunden) Aufgaben 2 1. Schreibe ein vollständiges Programm und teste es aus: a) Aus den Seiten a und b eines Rechtecks sind Umfang und Flächeninhalt zu berechnen. b) Der Zins ist aus Kapital, Zinssatz und der Anzahl der Tage zu bestimmen. c) Berechne R aus R1, R2, R3 nach der Formel R1 * R2 R = R3 + ----------R1 + R2 2. Das folgende Programm zur Berechnung eines Kegelstumpfes enthält syntaktische Fehler. Welche? # Programm Volumen from math import gk1=float(imput("Grundkreisradius 1: ")) gk2=float(input("Grundkreisradius 2: ")) h=(input("Hoehe: ")) V=pi*h(gk1*gk1+gk1*gk2+gk2*gk2)/3 print "Volumen:",) 3. Aus Länge, Breite und Höhe eines Quaders sollen dessen Volumen und der Inhalt der Oberfläche berechnet werden. 4. Die Jahreszinsen können nach der Formel z=k*p:100 berechnet werden. Dabei bedeutet k das Kapital, p den jährlichen Zinssatz in Prozenten und x die Zinsen. Schreibe ein Programm, mit dem der Computer nach Eingabe von Kapital und Zinssatz die Jahreszinsen berechnen und ausdrucken kann. 5. Eine Schraubenfeder verlängert sich bei einem Gewicht von 28 g um 18 mm. Die Verlängerung der Feder ist dem Gewicht des angehängten Körpers proportional. Schreibe ein Programm, mit dem der Computer nach Eingabe des Gewichtes des angehängten Körpers die zugehörige Verlängerung der Feder bestimmen kann. 6. Bei der Bank müssen häufig Münzen gezählt werden. Deshalb ist ein Programm nötig, mit dem nach Eingabe der Anzahl der verschiedenen Münzen der Geldbetrag in Euro und Cent ausgedruckt werden kann. Turtle Die Turtle und ihre Befehle Die Programmiersprache LOGO ist vor allem wegen ihrer Turtle-Graphik bekannt geworden. Eine oder mehrere virtuelle Schildkröten (engl.:turtle) lassen sich auf dem Bildschirm bewegen und ziehen bei Bedarf eine farbige Linie hinter sich her. Diese Turtle-Graphiken lassen sich auch mit Python realisieren. Ein entsprechendes Modul ist in Python 2.5 eingebaut und lässt sich bei Bedarf aufrufen und verwenden. Ein kleiner schwarzer Pfeil stellt die Turtle dar. Durch entsprechende Befehle lässt sich der Pfeil steuern. Das folgende Programm zeichnet ein schwarzes Rechteck: from turtle import * forward(50) left(90) forward(50) left(90) forward(50) left(90) forward(50) Was bedeuten die Befehle? Mit der Befehlsfolge from turtle import * wird das Modul TURTLE geladen und die im Modul implementierten Befehle lassen sich direkt durch Aufruf verwenden. Der Befehl forward(50) gibt der Turtle den Befehl, sich 50 Pixel nach vorne zu bewegen. Da die Turtle zu Beginn des Programms nach Osten ausgerichtet ist, bewegt sie sich 50 Pixel nach rechts. left(90) dreht die Turtle um 90 Grad nach links. Sie ist jetzt nach Norden ausgerichtet. forward(50) bewegt sie wieder 50 Pixel nach vorne (hier nach oben). Nach Abschluss der Befehlsfolge hat die Turtle ihre Ausgangsposition wieder erreicht. Die Blickrichtung ist jetzt Süden. Um die ursprüngliche Ausrichtung zu erhalten, muss noch einmal der Befehl left(90) ausgeführt werden. Das Programm wird um drei Befehle erweitert: from turtle import * reset() color("red") width(5) forward(50) left(90) forward(50) left(90) forward(50) left(90) forward(50) reset(): Der Befehl löscht den Bildschirm, setzt den Stift auf die Ausgangsposition und alle Variablen auf ihre Vorgabewerte zurück. color(“red“): Der Befehl bestimmt die Stiftfarbe, der Farbwert ist in Anführungszeichen zu setzen. Zulässig sind die HTML-Farbwerte. width(x): x definiert die Strichstärke des Stiftes in Pixel. Das Programm wird nochmals erweitert bzw. verändert: from turtle import * color("red") begin_fill() forward(80) left(90) forward(80) left(90) forward(80) left(90) forward(80) end_fill() up() forward(80) left(90) forward(80) down() color("blue") begin_fill() forward(80) left(90) forward(80) left(90) forward(80) left(90) forward(80) end_fill() up() left(90) backward(160) down() color("yellow") begin_fill() forward(80) left(90) forward(80) left(90) forward(80) left(90) forward(80) end_fill() color("red") begin_fill() schaltet die Turtle in den Füllmodus, end_fill() beendet den Füllmodus. up() und down() heben und senken den Stift. Solange der Stift angehoben ist, zeichnet die Turtle eine unsichtbare Linie backward(x): Die Turtle geht x Pixels rückwärts. Das Turtle-Modul enthält noch eine Menge weiterer Befehle, die für Zeichnungen und Konstruktionen genutzt werden können. In der folgenden Tabelle sind die wichtigsten aufgelistet (auch die schon besprochenen Befehle): degrees() radians() setup(***) title(title_str) reset() clear() speed(speed) delay(delay) forward(distance) backward(distance) left(angle) right(angle) up() down() width(width) color(s) write(text[,move]) begin_fill() end_fill() Winkel werden in Grad angegeben Winkel werden im Bogenmaß angegeben Größe und Position des Fensters werden bestimmt. Schlüsselwörter sind width, height, startx und starty. setup(): 50%*50% des Bildschirms, zentriert setup (width=200, height=200, startx=0, starty=0): Fenster hat eine Größe von 200*200 Pixel, links oben auf dem Bildschirm setup(width=.75, height=0.5, startx=None, starty=None): Fenstergröße beträgt 75% * 50% des Bildschirms, zentriert title(“Versuch”): Fenster erhält die Überschrift “Versuch” Bildschirm wird gelöscht, Turtle wird zentriert, Variablen werden auf Vorgabewerte gesetzt. Bildschirm wird gelöscht Die Geschwindigkeit der Turtle wird festgelegt: speed(“fastest”):keine Verzögerung speed(“fast”): 5 ms Verzögerung speed(“normal”): 10 ms Verzögerung speed(“slow“): 15 ms Verzögerung speed(“slowest“): 20 ms Verzögerung delay(25): Die Geschwindigkeit der Turtle wird auf 25 ms gesetzt. forward(80): Die Turtle bewegt sich 80 Pixel nach vorne backward(80): Die Turtle bewegt sich 80 Pixel nach hinten left(45): Die Turtle dreht sich um 45 Grad nach links right(90): Die Turtle dreht sich um 90 Grad nach rechts Der Zeichenstift wird angehoben Der Zeichenstift wird abgesenkt width(2): Die Breite des Stiftes beträgt 2 Pixel color(“red“): Die Zeichenfarbe ist rot. write(“Hallo“): An der aktuellen Stiftposition wird „Hallo“ geschrieben. Wenn move wahr ist, bewegt sich der Stift an die rechte untere Ecke des Textes. Die Vorgabe für move ist falsch. Um eine Figur farblich auszufüllen, kann zu Beginn auch dieser Befehl genutzt werden. Zum Abschluss des Füllvorgangs muss dieser Befehl gesetzt werden. circle(radius[,extent]) circle(50): Dieser Befehl zeichnet einen Kreis mit dem Radius 50 Pixel, dessen Mittelpunkt sich 50 Pixel links von der aktuellen Turtleposition befindet. circle(50,180): extent gibt an, welcher Teil des Kreises gezeichnet werden soll. Der Wert 180 zeichnet einen Halbkreis. Wenn kein voller Kreis gezeichnet wird, ist der Endpunkt des Kreisbogens die aktuelle Stiftposition. Der Bogen wird entgegen dem Uhrzeigersinn gezeichnet, wenn radius positiv ist; ist radius negativ wird mit dem Uhrzeigersinn gezeichnet. Die Richtung der Turtle wird durch extent beeinflußt. goto(x,y) goto(-50,100): Die Turtle geht zur Position -50,100. setx(x) setx(40): Die x-Koordinate der Turtle wird auf 40 gesetzt. sety(y) sety(40): Die y-Koordinate der Turtle wird auf 40 gesetzt. window_width() Mit diesem Befehl kann die Breite des Fensters abgefragt werden. window_height() Mit diesem Befehl kann die Höhe des Fensters abgefragt werden. position() Mit diesem Befehl kann die aktuelle Position der Turtle abgefragt werden. heading() Dieser Befehl gibt die Richtung der Turtle wieder. setheading(angle) Die Richtung der Turtle wird auf angle gesetzt. Hier noch ein Beispiel, das viele der oben angeführten Befehle benutzt: from turtle import * forward(50) left(90) forward(50) left(90) forward(50) left(90) forward(50) left(90) up() goto(-100,-100) down() color("red") speed("fastest") write("künstlerisch wertvoll") forward(50) left(90) forward(50) left(90) forward(50) left(90) forward(50) left(90) up() goto(100,100) down() color("blue") speed("normal") # 1. Quadrat # Stift hoch # neue Turtleposition # neue Farbe # Zeichengeschwindigkeit # Text # 2. Quadrat begin_fill() forward(50) left(90) forward(50) left(90) forward(50) left(90) forward(50) left(90) end_fill() up() setx(200) down() color("green") forward(50) left(90) forward(50) left(90) forward(50) left(90) forward(50) left(90) up() goto(-150,150) down() color("tomato") speed("fast") width(5) circle(50) left(90) begin_fill() color("gold") circle(50) end_fill() left(90) color("sienna") circle(50) left(90) color("steelblue") circle(50) up() forward(300) down() width(1) circle(50,180) circle(-50,180) circle(50,-180) circle(-50,-180) circle(-100,90) forward(200) circle(-100,45) circle(-90,45) circle(-80,45) circle(-70,45) circle(-60,45) circle(-50,45) circle(-40,45) circle(-30,45) circle(-20,45) circle(-90,45) # 3. Quadrat, gefüllt # neuer x-Wert der Turtle # 4. Quadrat # vier Kreise # Linien # Richtung der Turtle beachten Auf den Befehl circle soll hier noch etwas genauer eingegangen werden. Das folgende kleine Programm zeichnet zwei Kreise: from turtle import * circle(50) circle(-50) Der Befehl circle(50) zeichnet einen Kreis, dessen Mittelpunkt sich 50 Pixel links von der aktuellen Turtleposition befindet; der zweite Befehl zeichnet einen Kreis, dessen Mittelpunkt sich 50 Pixel rechts von der aktuellen Position befindet. Ist der Wert des Radius positiv wird der Kreis nach links gezeichnet, ist der Wert negativ nach rechts. Folgerichtig zeichnet das folgende Programm zweimal denselben Kreis. from turtle import * circle(50) left(180) circle(-50) Der Befehl circle kann auch mit einer Erweiterung genutzt werden: circle(100,180). Dieser Befehl zeichnet einen Halbkreis, dessen Mittelpunkt sich 100 Pixel links von der aktuellen Position befindet. Der Halbkreis wird entgegen dem Uhrzeigersinn gezeichnet. Ist die Erweiterung negativ (circle(100,-180)), wird ebenfalls ein Halbkreis gezeichnet. Die Turtle bewegt sich jedoch rückwärts und zeichnet deshalb einen Halbkreis im Uhrzeigersinn. Der Mittelpunkt befindet sich immer noch 100 Pixel rechts von der aktuellen Position. Aufgaben 3 Zeichne folgende Figuren: Schreiben einer Funktion In den Beispielen wurden mehrmals Quadrate gleicher Größe gezeichnet. Für jedes Quadrat wurden jedes Mal die gleichen Befehle eingegeben. Dies ist nicht nur umständlich, es macht die Programme auch schwer lesbar. Ein beliebiges Quadrat kann wie folgt gezeichnet werden: forward(seite) left(90) forward(seite) left(90) forward(seite) left(90) forward(seite) left(90) Um dem Programm verständlich zu machen, dass diese Befehlsfolge ein Quadrat ergibt, definiert man eine Funktion namens Quadrat: def quadrat(): forward(seite) left(90) forward(seite) left(90) forward(seite) left(90) forward(seite) left(90) Diese Funktion wird im Programm aufgerufen. Der Quellcode für ein Programm, dass vier Quadrate unterschiedlicher Größe zeichnen soll, könnte wie folgt aussehen: from turtle import * def quadrat(): forward(seite) left(90) forward(seite) left(90) forward(seite) left(90) forward(seite) left(90) seite=60 quadrat() seite=100 quadrat() seite=140 quadrat() seite=180 quadrat() Noch einfacher wäre es, wenn man den Wert für die Seite beim Aufruf der Funktion direkt übergeben könnte. Unter Python bereitet das kein Problem. Die Funktion wird einfach abgewandelt: def quadrat(seite): ….. Das Programm sieht dann so aus: from turtle import * def quadrat(seite): forward(seite) left(90) forward(seite) left(90) forward(seite) left(90) forward(seite) left(90) quadrat(60) quadrat(100) quadrat(140) quadrat(180) Das Programm wird nochmals verändert: from turtle import * def quadrat(seite): forward(seite) left(90) forward(seite) left(90) forward(seite) left(90) forward(seite) left(90) seite=60 quadrat(seite) quadrat(seite+40) quadrat(seite+80) quadrat(seite+120) Der Wert der Variablen Seite soll beobachtet werden. Im Hauptprogramm beträgt der Wert von Seite immer 60. In der Funktion ist er aber im ersten Quadrat 60, im zweiten 100, im dritten 140 und im vierten 180. Überprüft man nach dem Zeichnen den Wert von Seite (in der Python-Shell den Befehl print (seite) eingeben), so beträgt er 60. Wie ist dies möglich? Anscheinend sind die Werte der Variablen Seite im Hauptprogramm andere als die Werte der Variablen Seite in der Funktion. Ändert man im Hauptprogramm oder in der Funktion den Namen der Variablen Seite, läuft das Programm weiterhin fehlerfrei. Die Erklärung für dieses Verhalten: Python unterscheidet zwischen lokalen und globalen Variablen. In der Definition der Funktion wurde die Variablen Seite eingetragen. Die Variable Seite ist deshalb eine lokale Variable, die nur in der Funktion gültig ist. Dass im Hauptprogramm ebenfalls eine Variable Seite vorkommt, interessiert Python nicht. Auf die Bedeutung von lokaler und globaler Variable wird später noch eingegangen. In der Turtlegraphik liegt der Mittelpunkt des Kreises bei positiven Radiuswerten immer links von der Turtle, bei negativen Werten immer rechts. In der Geometrie ist es aber üblich, vom Mittelpunkt ausgehend einen Kreis mit einem bestimmten Radius zu zeichnen. Mit Hilfe einer Funktion soll durch Angabe der Mittelpunktskoordinaten und des Radius ein Kreis gezeichnet werden. Dabei ist die Richtung der Turtle zu beachten. Diese Kreisfunktion richtet zum Zeichnen die Turtle nach Osten aus. Um die ursprüngliche Richtung wieder herzustellen, wird der Richtungswert zwischengespeichert und am Ende der Funktion wieder übergeben. def kreis(xm,ym,radius): richtung=heading() setheading(0) up() goto(xm, ym-radius) down() circle (radius) setheading(richtung) Diese Funktion kann man auch zum Zeichnen von Kreisbögen nutzen. Dazu muss sie etwas abgewandelt werden. Zwei weitere Werte werden durch Aufruf übergeben: die Winkelposition, ab dem der Kreisbogen gezeichnet werden soll und der eigentliche Winkelbogen. def kreisbogen(xm,ym,radius,start,laenge): richtung=heading() setheading(start) up() goto(xm, ym-radius) down() circle (radius,laenge) setheading(richtung) Architektur am Bildschirm Die Fassade eines Bauwerks ist aus unterschiedlichen Bauteilen zusammengesetzt. Wände, Türen , Dächer, Fenster sind auf ganz verschiedene Art miteinander von Architekten kombiniert worden. Quadrate, Rechtecke, Kreise usw. sind bereits mit der Turtle gezeichnet worden. Es sollen jetzt architektonische Elemente erstellt werden, die alle auf dieselbe Art und Weise aufgerufen werden sollen: Name(xpos, ypos, farbe). Damit diese Objekte vernünftig am Bildschirm angeordnet werden können, sollen sie alle eine Rastergröße von 100*100, oder 50*100 oder 50*50 oder 25*100 Pixeln haben. Die Definition für ein großes Quadrat könnte dann wie folgt aussehen: def quadrat(xpos,ypos,farbe): up() goto(xpos+1,ypos+1) down() begin_fill() color(farbe) for i in range(4): forward(98) left(90) end_fill() forward(0) Für ein kleines Quadrat sieht die Größenanordnung etwas anders aus: def quadratk(xpos,ypos,farbe): up() goto(xpos+1,ypos+1) down() begin_fill() color(farbe) for i in range(4): forward(48) left(90) end_fill() forward(0) Alle Elemente werden mit den Variablen xpos, ypos und farbe aufgerufen. Damit die Elemente voneinander unterschieden werden könne, haben alle einen farblosen Rand von einem Pixel Breite. Die Ausrichtung der Turtle ist zu Beginn und am Ende der Funktion immer nach Osten. Welche Elemente für eine Zeichnung benötigt werden, liegt im Ermessen jedes Einzelnen, der solch eine Graphik herstellen möchte. In dem Beispiel sind 16 Bauelemente und 4 Fensterelemente verwandt worden. Die Fensterelemente orientieren sich dabei an den entsprechenden Bauelementen. Beispiel: def rechtecks(xpos,ypos,farbe): up() goto(xpos+1,ypos+1) down() begin_fill() color(farbe) for i in range(2): forward(48) left(90) forward(98) left(90) end_fill() forward(0) def fen4(xpos,ypos,farbe): up() goto(xpos+7,ypos+11) down() begin_fill() color(farbe) for i in range(2): forward(36) left(90) forward(36) left(90) end_fill() up() goto(xpos+7,ypos+55) down() begin_fill() for i in range(2): forward(36) left(90) forward(36) left(90) end_fill() forward(0) rechtecks(175,-100,"black") fen4(175,-100,"white") Kontrollstrukturen Für die Datentypen int, long, float und bool sind vergleichende Operatoren definiert. Jeder dieser Operatoren liefert als Ergebnis einen Wahrheitswert True oder False. Folgende Operatoren werden von Python bereit gestellt: Operator == != <> < <= > >= Beispiel x == y x != y x <> y x<y x <= y x>y x >= y Ergebnis wahr, wenn x und y gleich sind wahr, wenn x und y verschieden sind analog zu !=, bitte nicht verwenden wahr, wenn x kleiner ist als y wahr, wenn x kleiner oder gleich y ist wahr, wenn x größer y ist wahr, wenn x größer oder gleich y ist Verzweigungen Den Aufgaben, die der Rechner bisher zu lösen hatte, war eines gemeinsam: er musste nacheinander in der ihm vorgegebenen Reihenfolge verschiedene Anweisungen ausführen. Oft ist es jedoch notwendig, dass der Rechner selber Entscheidungen treffen muss. In Python gibt es für Fallunterscheidungen die klassische if-Anweisung. Eine if-Anweisung besteht im einfachsten Fall aus einem Anweisungskopf, der eine Bedingung enthält und aus einem Codeblock als Anweisungskörper. Der Codeblock wird nur ausgeführt, wenn die Bedingung wahr ist. Bei einer Bank werden bei einem Girokonto für jede Buchung 0,20 € berechnet. lediglich die ersten fünf Buchungen sind kostenfrei. Nach Eingabe der Anzahl der Buchungen soll der Rechner die Gebühren berechnen und ausdrucken. anzahl=int(input("Wie viele Buchungen? ")) gebuehr=0.0 buchung=0.2 gratis=5 if anzahl>=gratis: gebuehr=buchung*(anzahl-gratis) print ("Gebuehren:", gebuehr) In vielen Fällen ist es aber mit einer einzelnen if-Anweisung nicht getan. Man benötigt eine Kette von Fallunterscheidungen. Angenommen, die Variable x kann den Wert 1 bis 10 annehmen. Der jeweilige Wert soll ausgedruckt werden. Formuliert man das Problem mit if-Anweisungen, sähe das Programm wie folgt aus: if x==1: print if x==2: print if x==3: print if x==4: print usw. “x hat den Wert 1“ “x hat den Wert 2“ “x hat den Wert 3“ “x hat den Wert 4“ Wenn x tatsächlich den Wert 10 hat, werden alle zehn Anweisungen abgearbeitet. Sie werden aber auch alle abgearbeitet, wenn x den Wert 1 hat. Wenn x gleich 1 ist, bräuchten die übrigen neun Anweisungen nicht mehr bearbeitet werden. Python bietet die Anweisung elif an, die dieses Problem lösen kann. Das Programm sieht dann wie folgt aus: if x==1: print “x elif x==2: print “x elif x==3: print “x elif x==4: print “x usw. hat den Wert 1“ hat den Wert 2“ hat den Wert 3“ hat den Wert 4“ Schreibarbeit erspart sich nicht, aber das Programm wird schneller abgearbeitet. Eine weitere Ergänzung der if-Anweisung ist die zweiseitige Entscheidung. Wenn die Bedingung im Anweisungskopf nicht erfüllt ist, soll ein zweiter Codeblock ausgeführt werden. Dieser zweite Codeblock wird mit else eingeleitet. Ein Beispiel: Der Computer soll feststellen, ob eine Zahl a durch b teilbar ist. zahl_a=int(input("Zahl a: ")) zahl_b=int(input("Zahl b: ")) if zahl_a%zahl_b==0: print zahl_a," ist durch ",zahl_b," teilbar" else: print zahl_a," ist durch ",zahl_b," nicht teilbar" Sicherlich ist die Schaltjahrregelung bekannt. Jahre, die durch 4 teilbar sind, sind Schaltjahre. Ausgenommen sind Jahre, die durch 100 teilbar sind. Sie sind keine Schaltjahre, es sei, denn, sie sind durch 400 teilbar. Das Jahr 2008 ist also ein Schaltjahr, 1900 war kein Schaltjahr, 2000 war ein Schaltjahr. Das folgende Programm überprüft nach Eingabe der Jahreszahl, ob ein Schaltjahr vorliegt oder nicht. jahr=int(input("Eingabe des Jahres: ")) if jahr%4==0: if jahr%100==0: if jahr%400==0: print "Schaltjahr" else: print "kein Schaltjahr" else: print "Schaltjahr" else: print "kein Schaltjahr" Beispiel: Bekanntlich kann man nicht immer aus drei beliebigen Streckenlängen ein Dreieck konstruieren. Es ist dies jedoch immer möglich, wenn die größte Streckenlänge kleiner als die Summe der verbleibenden Streckenlängen ist. Nach Eingabe der drei Streckenlängen (Maximum zuerst) soll die Konstruierbarkeit beurteilt und gegebenenfalls auf Rechtwinkligkeit überprüft werden. c=float(input("Bitte längste Seite eingeben: ")) a=float(input("Bitte zweite Seite eingeben: ")) b=float(input("Bitte dritte Seite eingeben: ")) if (a + b)<= c: print ("kein Dreieck konstruierbar") else: if a*a+b*b == c*c: print ("Dreieck ist konstruierbar - rechtwinklig") else: print ("Dreieck ist konstruiebar - nicht rechtwinklig") Beispiel: Es ist die Lösung der Gleichung ax2 + bx + c = 0 mit a, b, c auszugeben nach Eingabe von a, b und c. from math import sqrt a=float(input("a = ")) b=float(input("b = ")) c=float(input("c = ")) if a==0: if b==0: if c==0: print "L = R" else: print "L = [ ]" else: x0=-c/b print "L = [ ",x0," ]" else: diskr=b*b-4*a*c if diskr>0: d=sqrt(diskr) x1=(-b-d)/(2*a) x2=(-b+d)/(2*a) print ("L = [ ",x1,", ",x2," ]") else: if diskr==0: x0=-b/(2*a) print ("L = [",x0," ]") else: print ("L = [ ]") Aufgaben 4 1. Zu einem gegebenen Datum soll die Nummer des Tages in diesem Jahr angegeben werden. 2. Für die Bestimmung des Osterdatums gilt die Osterformel von Gauss. Es bedeuten: j = Jahreszahl p = ganzzahliger Teil von j/100 n = Rest von j/100 q = ganzzahliger Teil von p/3 r = ganzzahliger Teil von p/4 x = Dreißigerrest von 15 + p – q – r y = Siebenerrest von p – r + 4 a = Neunzehnerrest von j b = Viererrest von j c = Siebenerrest von j d = Dreißigerrest von 19a + x e = Siebenerrest von 2b + 4c +6d + y Dann ist Ostern am (22+d+e). März oder am (d+e-9). April, je nachdem ob (22+d+e)<= 31 ist oder nicht. Ausnahmen: Ist d=29 und e=6, so ist Ostern am 19. April. Ist d=28 und e=6, so ist Ostern am 18. April. 3. Umrechnung von Maßeinheiten der Temperatur oC = Grad Celsius, oR = Grad Réaumur, oF = Grad Fahrenheit Der Gefrierpunkt des Wassers ist bei 0 oC = 0 oR = 32 oF, der Siedepunkt bei 100 oC = 80 oR = 212 oF. Es ist ein Programm zu schrieben, das die Werte der einen Skala in jede der beiden anderen umrechnen kann. 4. Bekanntlich sind zwei geraden in einer Ebene mit den Gleichungen y=ax+b und und y=cx +d durch die Zahlen a, b , c und d festgelegt. Schriebe ein Programm, mit dem der Computer den Schnittpunkt berechnen und ausgeben kann. Dabei soll auch der Fall berücksichtigt werden, dass die geraden parallel sind. Wiederholungen Sehr oft ist es notwendig, das Befehlsfolgen oder Befehle mehrfach ausgeführt werden. Dabei unterscheidet man zwei Szenarien: man kennt die Anzahl der benötigten Aufrufe („Würfele 3 mal“) oder man kennt sie nicht („Würfele, bis du eine sechs geworfen hast“). Für beide Fälle hat Python entsprechende Befehle. Den ersten Fall löst man mit einer for-Schleife, den zweiten mit einer while-Schleife. FOR-Schleife Die for-Schleife hat folgende Struktur: for target_list in expression_list: Anweisungblock Hinter dem Schlüsselwort for kommt üblicherweise eine Laufvariable oder rein Tupel von Variablennamen. Danach folgt das Schlüsselwort in und dahinter ein Ausdruck, der eine Ansammlung von Objekten beschreibt. Im einfachsten Fall handelt es sich um eine Sequenz. Die folgenden Beispiele sollen diese Aussagen deutlicher machen: >>> for farbe in (“rot“, “gelb“, “gruen“): print (farbe) rot gelb gruen >>> >>> for i in [1, 2, 3, 4, 5]: print (i*i,end=“ “) 1 4 9 16 25 >>> >>> for element in [2, 5, 11]: print (element) 2 5 11 >>> Gemeinsam ist allen Beispielen, dass die Anzahl der Elemente in der expression_list beschränkt war. Wie sieht es aber aus, wenn eine Schleife 100 mal oder noch öfter durchlaufen werden soll? Hilfreich für die Formulierung vieler Durchläufe ist die range()-Funktion. Der Aufruf von range(n) erzeugt eine Liste ganzer Zahlen von 0 bis n-1. >>> for nummer in range(5): print (nummer, end=“ “) 0 1 2 3 4 >>> Gerade dieses letzte Beispiel gibt die Standardanweisung für die for-Schleife wieder. range kann dabei nicht nur ein Limit setzen, sondern allgemein in drei Varianten verwendet werden: range(stop), range(start, stop), range(start, stop, step). Im folgenden Beispiel wird 36 mal ein Quadrat gezeichnet. Der Winkel der Turtle wird bei jedem Schleifenaufruf um 10 Grad verändert. Außerdem werden zwei Werte an die Funktion übergeben: seite und farbe, und es gibt einen neuen Befehl tracer(n). tracer(0) schaltet die Turtle aus (sie ist nicht mehr sichtbar) und tracer(1) schaltet sie wieder ein. Die Zeichengeschwindigkeit wird damit in Programmen (bei denen es nicht darauf ankommt, die Turtle zu beobachten) deutlich erhöht. from turtle import * def quadrat(seite,farbe): color(farbe) for i in range(4): forward(seite) left(90) winkel=0 tracer(0) for i in range(36): quadrat(100,"red") winkel=winkel+10 setheading(winkel) Neben dem Quadrat gibt es noch eine große Anzahl von n-Ecken. In n_ecken sind die Innenwinkel und die Seitenlängen immer gleich: Im Quadrat hat man vier Winkel mit jeweils 90 Grad, die Kantenlänge ist beliebig, aber bei allen vier Seiten gleich groß. Der Drehwinkel betrug 90 Grad. Im gleichseitigen Dreieck beträgt der Drehwinkel 120 Grad, im Fünfeck 72 Grad. Allgemein gilt: der Drehwinkel der Turtle beträgt bei einem n-Eck 360/n Grad. Das folgende Programm zeichnet beliebige nEcke. Die Anzahl der Ecken muss jeweils eingetragen werden. from turtle import * def n_eck(seite,anzahl): drehwinkel=360/anzahl for i in range(anzahl): forward(seite) left(drehwinkel) n_eck(60,5) Das folgende Programm ist zum Probieren: from turtle import * def n_eck(seite,anzahl,breite,stiftfarbe,fuellfarbe): width(breite) color(stiftfarbe) begin_fill() for i in range(anzahl): forward(seite) left(360/anzahl) color(fuellfarbe) end_fill() winkel=0 eck=7 stiftbreite=3 wiederholung=6 speed("fast") for i in range(wiederholung): n_eck(100,eck,stiftbreite,"blue","yellow") winkel=winkel+360/wiederholung setheading(winkel) Wie oben schon erwähnt wurde, kann die expression_list auch aus einer Liste bestehen. Im folgenden Beispiel sollen Quadrate verschiedener Seitenlänge mehrmals gezeichnet werden: siebenmal ein Quadrat mit der Seitenlänge 90, siebenmal eines mit der Seitenlänge 70 und siebenmal eines mit der Seitenlänge 40. Des weiteren soll nach jedem Durchgang Randfarbe und Blattfarbe gewechselt werden. Wie funktioniert das? Unter Python ist die folgende Anweisung zulässig: >>> x,y=y,x Zwei Variablen können miteinander getauscht werden. Dieses Tauschen von Werten soll etwas erläutert werden. >>> >>> >>> 10 >>> 20 x=10 y=20 x y Dieses Verhalten von Python ist normal. >>> x,y (10, 20) Python kann aber auch die Werte dieser Variablen in einer Anweisung in einem Tupel ausgeben (Tupel sind an der runden Klammer erkennbar). Die Sprache erlaubt auch die gleichzeitige Zuweisung an mehrere Variablen: >>> x,y=10,20 >>> x 10 >>> y 20 >>> x,y (10, 20) >>> y,x (20, 10) >>> x,y=y,x >>> x,y (20,10) >>> y,x (10, 20) Die Anweisung für das Zeichnen der Quadrate soll wie folgt aussehen: n_eck([90, 70,40], 4, 7, 3, “blue“, “pink“). 90, 70 und 40 sind die gewünschten Seitenlängen, 4 steht für Viereck, 7 für die gewünschte Anzahl, 3 für die Strichstärke, blue und pink für Rand- bzw. Füllfarbe. from turtle import * def n_eck(seitenliste, eckenzahl, wiederholungen, breite, stiftfarbe, fuellfarbe): width(breite) color(stiftfarbe) winkel=0 for seite in seitenliste: for i in range(wiederholungen): begin_fill() for i in range(eckenzahl): forward(seite) left(360/eckenzahl) color(fuellfarbe) end_fill() winkel=winkel+360/wiederholungen setheading(winkel) color(stiftfarbe) stiftfarbe,fuellfarbe=fuellfarbe, stiftfarbe n_eck([90,70, 40],4,7,3,"green","yellow") WHILE-Schleife Es soll ein Würfelprogramm entwickelt werden. Im vorigen Abschnitt wurde die FORSchleife vorgestellt. Mit Hilfe dieser Schleife soll ein Programm formuliert werden, dass dreimal eine beliebige Zahl würfeln soll. Anschließend soll die Summe der drei Würfe ausgegeben werden. Zum Erzeugen von Zufallszahlen stellt Python ein eigenes Modul random zu Verfügung. Aus diesem Modul wird die Funktion randrange benötigt. randrange(n) erzeugt Zufallszahlen im Bereich von 0 bis n-1. randrange(6) erzeugt die Würfelzahlen 0 bis 5. Die Befehlszeile wurf=randrange(6)+1 sorgt dafür, dass die richtigen Zahlen von 1 bis 6 gespeichert werden. from random import randrange summe=0 print ("Folgende Ergebnisse wurden erzielt:",end=“ “) for i in range(3): wurf=randrange(6)+1 print (wurf,) summe=summe+wurf print () print ("Summe aller Würfe:", summe) Die Aufgabe wird nun abgewandelt. Es soll solange gewürfelt werden, bis eine 6 gewürfelt wird. Die Würfe sollen angezeigt werden und die Summe aller Würfe ausgegeben werden. Das obige Programm wird etwas verändert: from random import randrange summe=0 wurf=0 print ("Folgende Ergebnisse wurden erzielt:",end=““) while wurf<6: wurf=randrange(6)+1 print (wurf,end=““) summe=summe+wurf print () print ("Summe aller Würfe:", summe) Natürlich lassen sich while-Scheifen auch in der Turtle-Graphik verwenden. Das folgende Beispiel berechnet die Werte für eine Polygonspirale und zeichnet sie. Beispiel:Polygonspirale from turtle import * def spirale(winkel, zuwachs): maxstrecke=250.0 strecke=1.0 while strecke < maxstrecke: forward(strecke) left(winkel) strecke=strecke+zuwachs spirale(154,1.5) Bei einer while-Schleife wird vor Eintritt in den Schleifenkörper geprüft, ob die Bedingung für die Schleife erfüllt ist. Wenn ja, wird anschließend die Schleife so oft durchlaufen, bis die Bedingung erfüllt wird. Es ist beim Programmieren aber darauf zu achten, dass sich das Programm nicht in einer Schleife aufhängt. Python bietet zwei Möglichkeiten, Schleifendurchläufe abzubrechen. Die breakAnweisung beendet einen Schleifendurchlauf vorzeitig. Ein Beispiel: from random import randrange zu_ratende_zahl=randrange(1024)+1 ratezahl=0 while ratezahl != zu_ratende_zahl: ratezahl=input("Raten Sie: ") if ratezahl>zu_ratende_zahl: print ("Zahl ist zu groß") else: print ("Zahl ist zu klein") if ratezahl==0: print ("Das Spiel wird abgebrochen") break else: print ("Sie haben es geschafft") Die continue-Anweisung bricht im Gegensatz zu break nicht die gesamte Schleife ab, sondern nur den aktuelle Schleifendurchlauf. Zur näherungsweisen Berechnung der Quadratwurzel aus einer Zahl a gibt es das folgende Verfahren, das nach Heron von Alexandrien (ca. 60 n.Chr.) benannt ist. - Wähle eine Zahl a. - Halbiere die Zahl a und nenne das Ergebnis b. - Dividiere die Zahl a durch die Zahl b und nenne das Ergebnis c. - Solange (c – b) * (c - b) > 0.00000001 tue - Addiere zu der Zahl b die Zahl c und nenne die Hälfte der Summe b. - Dividiere die Zahl a durch die Zahl b und nenne das Ergebnis c. - Drucke die Zahl c. Programmtechnisch sieht das Verfahren wie folgt aus: from math import sqrt a=float(raw_input("Bitte eine Zahl eingeben: ")) b=a/2 c=a/b while (c-b)*(c-b)>0.00000001: b=(b+c)/2 c=a/b print ("Heron-Wurzel: ",c) print ("Wurzel mit Funktion SQRT: ",sqrt(a)) Aufgaben 5 1. Alle natürlichen Zahlentrippel (a, b, c) mit a²+b²=c² heißen pythagoreische Zahlentrippel. Es ist ein Programm zu erstellen, das nach Eingabe einer Zahl n>=2 alle solchen Zahlentrippel (a, b, c) ausgibt mit a<b<c für alle c<=n. 2. Schreibe ein Programm, das alle Möglichkeiten ausgibt und die Anzahl der Möglichkeiten zählt, wie man einen Geldbetrag in € mit 0,10 €, 0,20 €, 0,50 €, 1 € und 2 € Stücken begleichen kann. 3. Umrechnung römischer Zahlen ins Dezimalsystem: Eine Zahl, die im römischen System geschreiben ist (z.B. XXIV) ist ins Dezimalsystem zu übersetzen und umgekehrt. Fehlerhaft geschriebene römische Zahlen sind zurückzuweisen. Es dürfen höchstens 3 gleiche Zeichen hintereinander stehen (außer bei M = 1000). Zur Subtraktion dürfen nur I, X, C benutzt werden, und zwar darf I nur vor V und X stehen, X nur vor L und C, C nur vor D und M. Z.B.: 99 XCIX, 39 XXXIX, 40 XL. 4. Spieler A merkt sich eine beliebige Zahl, die kleiner ist als g (z.B. g=1000). Sein Gegenspieler B hat diese durch möglichst wenige Fragen der Art: „Ist die Zahl im Intervall [a,b]?“ herauszufinden. A ist der Computer. Ein Zufallszahlengenerator bildet eine beliebige Zahl <= g. Der Spieler B gibt eine obere und untere Schranke an, zwischen denen er die Zahl vermutet. Der Computer sagt ja oder nein und zählt die Fragen. Schreibe ein Programm. 5. Es ist ein Programm zu schrieben, das eine ganze, höchstens 9-stellige Zahl in Worten schreibt. 6. Die Dauer einer weniger als 24 Stunden dauernden Reise ist zu berechnen bei gegebener Abfahrts- und Ankunftszeit. Die Zeitangaben sollen in drei- bzw. vierstelligen Ziffern eingegeben werden (z.B. 1445). Nach der Eingabe der beiden Zahlen soll die Korrektheit der Angaben geprüft werden (z.B. sollen 179 oder 2617 zurückgewiesen werden. Wahr oder Falsch In Python gibt es den Datentyp bool für logische Wahrheitswerte. Sie werden durch die Literale True und False repräsentiert. Dabei ist unbedingt auf die Schreibweise zu achten. Die logischen Verknüpfungen and, not und or sind bereits aus den ifAnweisungen bekannt. Mit Boolschen Variablen lassen sich auch for-Schleifen bilden. Beispiel: Es soll eine Wahrheitstafel für die Konjunktion ausgedruckt werden. print " A B A und B" print "-------------------------" for a in [False,True]: for b in [False,True]: c = a and b if a: print ("wahr ",end=” else: print ("falsch",end=“ if b: print ("wahr ",end=“ else: print ("falsch",end=“ if c: print ("wahr ",end=“ else: print ("falsch",end=“ print “) “) “) “) “) “) Beispiel: Michaela schreibt Einladungen für ihre Geburtstagsfeier. Sie möchte möglichst viele ihrer Freundinnen einladen. Dabei gibt es nur einige Probleme: Silvia hatte Streit mit Monika und will auf keinen Fall kommen, wenn Monika eingeladen wird. Karin und Annette sind unzertrennliche Freundinnen und nur im Doppelpack erhältlich: entweder kommen beide oder beide nicht. Beate, Monika und Karin sollen auch nicht zusammen eingeladen werden, sondern nur zwei von den dreien. Wenn muss Michaela nun einladen, damit das Haus voll wird? for silvia in [False,True]: for monika in [False,True]: for karin in [False,True]: for annette in [False,True]: for beate in [False,True]: a=not monika or not silvia b=(karin and annette) or (not karin and not annette) c=(beate and monika and not karin) or \ (beate and not monika and karin) or \ (not beate and monika and karin) d=a and b and c if d: if silvia: print "Silvia ", if monika: print "Monika ", if karin: print "Karin ", if annette: print "Annette ", if beate: print "Beate ", print Aufgabe 6 1. Drucke eine Wahrheitstafel für die Disjunktion. 2. Drucke eine Wahrheitstafel für die Subjunktion. Funktionen mit Rückgabe Programme werden durch Funktionen sehr übersichtlich. Außerdem haben sie den Vorteil, dass sie mehrfach aufgerufen werden können. Der Programmierumfang eines Programms lässt sich damit deutlich reduzieren. In den bisherigen Beispielen haben die Funktionen Werte aus dem Hauptprogramm übernommen und verarbeitet. Oft ist es jedoch nötig, dass innerhalb einer Funktion ein Wert berechnet werden soll, der anschließend vom Hauptprogramm wieder benutzt werden muss. Beispiel: Es soll der ggT und das kgV zweier Zahlen berechnet werden. Zur Berechnung des kgV wird der ggT benötigt. Der ggT lässt sich wie folgt berechnen: Ein Teiler von a und b ist auch ein Teiler von a-b bzw. b-a. Mit diesem Satz gilt ggT(a,b)=ggT(a-b),b) für a>b, ggT(a,b)=a für a=b und ggT(a,b)=ggT(a,b-a) für a<b. Setzt man dies programmtechnisch um, erhält man die folgende Funktion: def ggt(a,b): while a!=b: if a>b: a=a-b else: b=b-a return a print ggt(92,69) Das kgV berechnet sich nach der Formel kgV(a,b)=a*b/ggT(a,b). Das Programm wird um die benötigten Programmzeilen erweitert. def ggt(a,b): while a!=b: if a>b: a=a-b else: b=b-a return a def kgv(a,b): wert=a*b/ggt(a,b) return wert zahl1=int(input("1. Zahl: ")) zahl2=int(input("2. Zahl: ")) print ("ggt: ",ggt(zahl1,zahl2)) print ("kgV: ",kgv(zahl1,zahl2)) Ein weiteres Beispiel stammt aus der Bruchrechnung. Zwei Brüche sollen addiert werden. Dazu muss zuerst der Hauptnenner gebildet werden. Anschließend werden die Brüche erweitert und dann die Zähler addiert. Zuletzt werden Zähler und Nenner gekürzt. Das Ergebnis wird ausgegeben. def ggt(a,b): while a != b: if a>b: a=a-b else: b=b-a return a def kgv(a,b): c=(a*b)/ggt(a,b) return c def erw(a,b,c): d=a*(c // b) return d def add(a,b): c=a+b return c def kuerze(a,b): c=a // b return c def ausgabe(a,b,c,d,e,f): print ("%4i" % a, " ","%4i" % c," print "------ + ------ = ------" print ("%4i" % b, " ","%4i" % d," ","%4i" % e) ","%4i" % f) zaehler1=int(input("1. Zaehler: ")) nenner1=int(input("1. Nenner: ")) zaehler2=int(input("2. Zaehler: ")) nenner2=int(input("2. Nenner: ")) gemn=kgv(nenner1,nenner2) neuz1=erw(zaehler1,nenner1,gemn) neuz2=erw(zaehler2,nenner2,gemn) sumz=add(neuz1,neuz2) kuerz=ggt(gemn,sumz) endz=kuerze(sumz,kuerz) endn=kuerze(gemn,kuerz) ausgabe(zaehler1,nenner1,zaehler2,nenner2,endz,endn) In Python lassen sich Ausgabewerte mit dem Formatierungsoperator % und einem Formatierungsstring formatieren. Das allgemeine Format einer solchen printAnweisung lautet: print formatierungsstring % wert Der Formatierungsstring muss in Anführungsstrichen stehen. Er besteht (vereinfacht) aus dem Zeichen %, einer (optionalen) Angabe der Stellenzahl, (optional) einem Punkt gefolgt von der Anzahl der dargestellten Zeichen des Wertes bzw. bei Gleitkommazahlen der Anzahl der Nachkommastellen und einem Buchstaben, der das Datenformat kennzeichnet: i für ganze Zahlen, f für Dezimalzahlen, s für Strings. Die Angabe “%4i“ % a druckt eine Ganzzahl a mit der Feldweite 4. Interessant ist der formatierte Ausdruck vor allem in Tabellen. Rekursion In der Informatik taucht sehr häufig ein Begriffspaar auf: Iteration und Rekursion. Programme lassen sich in der Regel sowohl iterativ als auch rekursiv formulieren. Ein klassischer Fall ist die Berechnung der Fakultät. Unter der Fakultät einer natürlichen Zahl n versteht man das Produkt n*(n-1)*(n-2)*(n-3)*...*3*2*1 (5!=120). def fakultaet_iterativ(n): fakultaet = 1 faktor = 2 while faktor <= n: fakultaet = fakultaet * faktor faktor = faktor + 1 return fakultaet n=int(raw_input("Fakultaet von:")) print fakultaet_iterativ(n) def fakultaet_rekursiv(n): if n <= 1: return 1 else: return ( n * fakultaet_rekursiv(n-1) ) n=int(input("Fakultaet von:")) print (fakultaet_rekursiv(n)) Die Iteration arbeitet mit Schleifen, die Rekursion mit Verzweigungen. Eine Funktion heißt rekursiv, wenn sie sich in ihrem Anweisungsteil selbst aufruft. Es gibt aber viele Programmiersituationen, bei denen ein rekursive Programmierung wesentlich einfacher ist als eine iterative bzw. bei denen eine äquivalente iterative Lösung nicht so leicht zu finden ist. Ein Beispiel ist die Konstruktion von Binärbäumen. Unter einem binären Baum versteht man eine Verzweigungsstruktur (Baum) mit der Eigenschaft, dass an jeder Gabelung zwei neue Zweige hervorsprießen. Binäre Bäume haben folgende rekursive Struktur: Entweder ist der Baum leer, oder er besteht aus einem linken Teilbaum, einem Stamm und einem rechten Teilbaum. Damit bietet sich folgendes Verfahren an: zeichne ganzen Baum: zeichne Stamm zeichne links kleineren ganzen Baum zeichne rechts kleineren ganzen Baum kehre zum Fußpunkt des Stamms zurück Wie sieht der Baum aber aus? Die Äste sind kleiner als der Stamm und sie stehen in einem bestimmten Winkel zueinander. Außerdem muss der Baum ein Ende haben. Dies führt zur folgender Funktion: def baum(stufe,stamm,winkel,faktor): if stufe < 1: return # Rücksprung in die aufrufende Funktion forward(stamm) # linker Teilbaum left(winkel) baum(stufe-1,faktor* stamm,winkel,faktor) right(winkel) # rechter Teilbaum right(winkel) baum(stufe-1,faktor * stamm,winkel,faktor) left(winkel) # zurück backward(stamm) Das komplette Programm sieht wie folgt aus: from turtle import * def baum(stufe,stamm,winkel,faktor): if stufe < 1: return forward(stamm) left(winkel) baum(stufe-1,faktor* stamm,winkel,faktor) right(winkel) right(winkel) baum(stufe-1,faktor * stamm,winkel,faktor) left(winkel) backward(stamm) up() goto(0,-200) left(90) down() baum(8,200,45,0.5) Eine rekursive Funktion hat in der Regel folgende Gestalt: def arbeite_rekursiv: if <Abbruchbedingung>: <Anweisung1> else: <Anweisung2> arbeite_rekursiv <Anweisung3> Anweisung 1 ist der direkte Fall der Rekursion und die else-Anweisungen sind der Rekursionsfall. Wenn Anweisung 1 eine leere Anweisung ist, kann man auch mit einer einseitigen Verzweigung arbeiten (siehe Beispiel). Entscheidend ist, dass Anweisung 2 nach endlich vielen Schritten zu einer Abbruchsbedingung führt. Anweisung 3 kann leer sein. Objekte und Methoden Bei der Turtle-Programmierung wurden Befehle wie forward, backward, left oder right benutzt. Mit diesen Befehlen (Methoden) konnte eine Turtle (Objekt) gesteuert werden. Objekte werden nach einem Bauplan erzeugt, der Klasse oder der Klassendefiniton. Die Klasse, die Turtles erzeugen kann, heißt Pen. Um selber Turtle-Objekte zu produzieren, muss man den Klassennamen aus dem Modul turtle importieren. Dies geschieht durch die Anweisung from turtle import Pen Um jetzt eine Turtle zu produzieren, wird ein Name für das neue Turtle-Objekt benötigt. Eine einfache Zuweisung ermöglicht dies: axel = Pen() Für ein Projekt Polyturtle werden vier Turtles benötigt. Also werden noch drei weitere Objekt erzeugt: bert = Pen() cico = Pen() dino = Pen() Wie kann man die vier Turtles jetzt steuern? Im Gegensatz zu den bisherigen TurtleProgrammen wurde nur die Klasse Pen importiert. Mithilfe der Anweisung name=Pen() wurden vier Objekte erzeugt. Jedes Objekt hat nun eigene Methoden (Befehle), die objektgebunden aufgerufen werden müssen. Dies erfolgt durch den Methodenaufruf objektname.methodenname(arg1, arg2...). Beispiel: Die vier Turtles sollen unterschiedliche Farben erhalten und sollen am Ausgangspunkt unterschiedliche Ausgangsrichtungen erhalten. Anschließend sollen alle vier ein gleichseitiges Dreieck zeichnen. from turtle import Pen alex=Pen() bert=Pen() cico=Pen() dino=Pen() alex.setheading(0) alex.color("blue") bert.setheading(90) bert.color("green") cico.setheading(180) cico.color("red") dino.setheading(270) dino.color("black") kroeten=[alex,bert,cico,dino] for i in kroeten: i.left(30) i.forward(60) i.right(120) i.forward(60) i.right(120) i.forward(60) Vereinbarungsgemäß werden Klassenbezeichner mit einem Großbuchstaben begonnen, Objekte mit einem Kleinbuchstaben. Polyturtle Eine Polyturtle ist ein Gebilde, das aus mehreren unanbahängig voneinander operierenden Turtles besteht. In dem folgenden Beispiel sitzen die Turtles in den Ecken eines Quadrates. Auf ein Kommando hin starten sie zur Verfolgungsjagd; T1 läuft hinter T2, T2 hinter T3, T3 hinter T4 und T4 hinter T1 her. from turtle import Pen alex=Pen() bert=Pen() cico=Pen() dino=Pen() kroeten=[alex,bert,cico,dino] alex.up() alex.color("blue") alex.goto(-200,-200) alex.down() bert.up() bert.color("green") bert.goto(200,-200) bert.down() cico.up() cico.color("red") cico.goto(200,200) cico.down() dino.up() dino.color("black") dino.goto(-200,200) dino.down() def spirale(zahl,faktor): for i in range(zahl): x0=alex.position()[0]+(bert.position()[0]alex.position()[0])*faktor y0=alex.position()[1]+(bert.position()[1]alex.position()[1])*faktor x1=bert.position()[0]+(cico.position()[0]bert.position()[0])*faktor y1=bert.position()[1]+(cico.position()[1]bert.position()[1])*faktor x2=cico.position()[0]+(dino.position()[0]cico.position()[0])*faktor y2=cico.position()[1]+(dino.position()[1]cico.position()[1])*faktor x3=dino.position()[0]+(alex.position()[0]dino.position()[0])*faktor y3=dino.position()[1]+(alex.position()[1]dino.position()[1])*faktor alex.goto(x0,y0) bert.goto(x1,y1) cico.goto(x2,y2) dino.goto(x3,y3) spirale(200,0.1) Das Programm wird dahingehend verändert, dass zwischen der Position der Schildkröte und ihres Ziels die Verbindungsstrecke gezeichnet wird. from turtle import Pen,tracer alex=Pen() bert=Pen() cico=Pen() dino=Pen() kroeten=[alex,bert,cico,dino] for i in kroeten: i.tracer(0) alex.up() alex.color("blue") alex.goto(-200,-200) alex.down() bert.up() bert.color("green") bert.goto(200,-200) bert.down() cico.up() cico.color("red") cico.goto(200,200) cico.down() dino.up() dino.color("black") dino.goto(-200,200) dino.down() for i in range(100): x0=alex.position()[0]+(bert.position()[0]-alex.position()[0])*0.05 y0=alex.position()[1]+(bert.position()[1]-alex.position()[1])*0.05 x1=bert.position()[0]+(cico.position()[0]-bert.position()[0])*0.05 y1=bert.position()[1]+(cico.position()[1]-bert.position()[1])*0.05 x2=cico.position()[0]+(dino.position()[0]-cico.position()[0])*0.05 y2=cico.position()[1]+(dino.position()[1]-cico.position()[1])*0.05 x3=dino.position()[0]+(alex.position()[0]-dino.position()[0])*0.05 y3=dino.position()[1]+(alex.position()[1]-dino.position()[1])*0.05 alex.goto(x0,y0) alex.goto(x1,y1) alex.goto(x0,y0) bert.goto(x1,y1) bert.goto(x2,y2) bert.goto(x1,y1) cico.goto(x2,y2) cico.goto(x3,y3) cico.goto(x2,y2) dino.goto(x3,y3) dino.goto(x0,y0) dino.goto(x3,y3) for i in kroeten: i.tracer(1) Das Programm lässt sich weiter abändern. T1 verfolgt im ersten Lauf T2, T2 T3 usw. In einem zweiten Lauf verfolgt T1 T4, T4 T3 usw. from turtle import Pen alex=Pen() bert=Pen() cico=Pen() dino=Pen() kroeten=[alex,bert,cico,dino] for i in kroeten: i.tracer(0) i.up() alex.color("blue") alex.goto(-200,-200) bert.color("green") bert.goto(200,-200) cico.color("red") cico.goto(200,200) dino.color("black") dino.goto(-200,200) for i in kroeten: i.down() for i in range(4): dino.forward(400) dino.right(90) for i in range(100): x0=alex.position()[0]+(bert.position()[0]-alex.position()[0])*0.05 y0=alex.position()[1]+(bert.position()[1]-alex.position()[1])*0.05 x1=bert.position()[0]+(cico.position()[0]-bert.position()[0])*0.05 y1=bert.position()[1]+(cico.position()[1]-bert.position()[1])*0.05 x2=cico.position()[0]+(dino.position()[0]-cico.position()[0])*0.05 y2=cico.position()[1]+(dino.position()[1]-cico.position()[1])*0.05 x3=dino.position()[0]+(alex.position()[0]-dino.position()[0])*0.05 y3=dino.position()[1]+(alex.position()[1]-dino.position()[1])*0.05 alex.goto(x0,y0) alex.goto(x1,y1) alex.goto(x0,y0) bert.goto(x1,y1) bert.goto(x2,y2) bert.goto(x1,y1) cico.goto(x2,y2) cico.goto(x3,y3) cico.goto(x2,y2) dino.goto(x3,y3) dino.goto(x0,y0) dino.goto(x3,y3) for i in kroeten: i.up() alex.goto(-200,-200) bert.goto(200,-200) cico.goto(200,200) dino.goto(-200,200) for i in kroeten: i.down() for i in range(4): dino.forward(400) dino.right(90) for i in range(100): x0=alex.position()[0]+(dino.position()[0]-alex.position()[0])*0.05 y0=alex.position()[1]+(dino.position()[1]-alex.position()[1])*0.05 x1=bert.position()[0]+(alex.position()[0]-bert.position()[0])*0.05 y1=bert.position()[1]+(alex.position()[1]-bert.position()[1])*0.05 x2=cico.position()[0]+(bert.position()[0]-cico.position()[0])*0.05 y2=cico.position()[1]+(bert.position()[1]-cico.position()[1])*0.05 x3=dino.position()[0]+(cico.position()[0]-dino.position()[0])*0.05 y3=dino.position()[1]+(cico.position()[1]-dino.position()[1])*0.05 alex.goto(x0,y0) alex.goto(x1,y1) alex.goto(x0,y0) bert.goto(x1,y1) bert.goto(x2,y2) bert.goto(x1,y1) cico.goto(x2,y2) cico.goto(x3,y3) cico.goto(x2,y2) dino.goto(x3,y3) dino.goto(x0,y0) dino.goto(x3,y3) Es muss aber nicht immer ein Quadrat mit 4 Turtles sein; man kann auch andere geometrische Figuren benutzen und eine andere Anzahl von Turtles. from turtle import Pen,tracer alex=Pen() bert=Pen() cico=Pen() dino=Pen() edda=Pen() fine=Pen() kroeten=[alex,bert,cico,dino,edda,fine] alex.color("blue") bert.color("green") cico.color("red") dino.color("black") edda.color("yellow") fine.color("gold") for i in kroeten: i.tracer(0) def ausgangspunkt(): winkel=0 for i in kroeten: i.up() winkel=winkel+60 i.left(winkel) i.forward(200) i.down() ausgangspunkt() for i in range(100): x0=alex.position()[0]+(bert.position()[0]-alex.position()[0])*0.05 y0=alex.position()[1]+(bert.position()[1]-alex.position()[1])*0.05 x1=bert.position()[0]+(cico.position()[0]-bert.position()[0])*0.05 y1=bert.position()[1]+(cico.position()[1]-bert.position()[1])*0.05 x2=cico.position()[0]+(dino.position()[0]-cico.position()[0])*0.05 y2=cico.position()[1]+(dino.position()[1]-cico.position()[1])*0.05 x3=dino.position()[0]+(edda.position()[0]-dino.position()[0])*0.05 y3=dino.position()[1]+(edda.position()[1]-dino.position()[1])*0.05 x4=edda.position()[0]+(fine.position()[0]-edda.position()[0])*0.05 y4=edda.position()[1]+(fine.position()[1]-edda.position()[1])*0.05 x5=fine.position()[0]+(alex.position()[0]-fine.position()[0])*0.05 y5=fine.position()[1]+(alex.position()[1]-fine.position()[1])*0.05 alex.goto(x0,y0) alex.goto(x1,y1) alex.goto(x0,y0) bert.goto(x1,y1) bert.goto(x2,y2) bert.goto(x1,y1) cico.goto(x2,y2) cico.goto(x3,y3) cico.goto(x2,y2) dino.goto(x3,y3) dino.goto(x4,y4) dino.goto(x3,y3) edda.goto(x4,y4) edda.goto(x5,y5) edda.goto(x4,y4) fine.goto(x5,y5) fine.goto(x0,y0) fine.goto(x5,y5) ausgangspunkt() for i in range(100): x0=alex.position()[0]+(fine.position()[0]-alex.position()[0])*0.05 y0=alex.position()[1]+(fine.position()[1]-alex.position()[1])*0.05 x1=bert.position()[0]+(alex.position()[0]-bert.position()[0])*0.05 y1=bert.position()[1]+(alex.position()[1]-bert.position()[1])*0.05 x2=cico.position()[0]+(bert.position()[0]-cico.position()[0])*0.05 y2=cico.position()[1]+(bert.position()[1]-cico.position()[1])*0.05 x3=dino.position()[0]+(cico.position()[0]-dino.position()[0])*0.05 y3=dino.position()[1]+(cico.position()[1]-dino.position()[1])*0.05 x4=edda.position()[0]+(dino.position()[0]-edda.position()[0])*0.05 y4=edda.position()[1]+(dino.position()[1]-edda.position()[1])*0.05 x5=fine.position()[0]+(edda.position()[0]-fine.position()[0])*0.05 y5=fine.position()[1]+(edda.position()[1]-fine.position()[1])*0.05 alex.goto(x0,y0) alex.goto(x1,y1) alex.goto(x0,y0) bert.goto(x1,y1) bert.goto(x2,y2) bert.goto(x1,y1) cico.goto(x2,y2) cico.goto(x3,y3) cico.goto(x2,y2) dino.goto(x3,y3) dino.goto(x4,y4) dino.goto(x3,y3) edda.goto(x4,y4) edda.goto(x5,y5) edda.goto(x4,y4) fine.goto(x5,y5) fine.goto(x0,y0) fine.goto(x5,y5) for i in kroeten: i.tracer(1) Man kann seiner Phantasie freien Lauf lassen. from turtle import Pen,setup setup(width=800,height=800,startx=None,starty=None) alex=Pen() bert=Pen() cico=Pen() dino=Pen() alex.color("blue") bert.color("green") cico.color("red") dino.color("black") kroeten=[alex,bert,cico,dino] def bild1(): for i in range(100): x0=alex.position()[0]+(bert.position()[0]-alex.position()[0])*0.05 y0=alex.position()[1]+(bert.position()[1]-alex.position()[1])*0.05 x1=bert.position()[0]+(cico.position()[0]-bert.position()[0])*0.05 y1=bert.position()[1]+(cico.position()[1]-bert.position()[1])*0.05 x2=cico.position()[0]+(dino.position()[0]-cico.position()[0])*0.05 y2=cico.position()[1]+(dino.position()[1]-cico.position()[1])*0.05 x3=dino.position()[0]+(alex.position()[0]-dino.position()[0])*0.05 y3=dino.position()[1]+(alex.position()[1]-dino.position()[1])*0.05 alex.goto(x0,y0) alex.goto(x1,y1) alex.goto(x0,y0) bert.goto(x1,y1) bert.goto(x2,y2) bert.goto(x1,y1) cico.goto(x2,y2) cico.goto(x3,y3) cico.goto(x2,y2) dino.goto(x3,y3) dino.goto(x0,y0) dino.goto(x3,y3) def bild2(): for i in range(100): x0=alex.position()[0]+(dino.position()[0]-alex.position()[0])*0.05 y0=alex.position()[1]+(dino.position()[1]-alex.position()[1])*0.05 x1=bert.position()[0]+(alex.position()[0]-bert.position()[0])*0.05 y1=bert.position()[1]+(alex.position()[1]-bert.position()[1])*0.05 x2=cico.position()[0]+(bert.position()[0]-cico.position()[0])*0.05 y2=cico.position()[1]+(bert.position()[1]-cico.position()[1])*0.05 x3=dino.position()[0]+(cico.position()[0]-dino.position()[0])*0.05 y3=dino.position()[1]+(cico.position()[1]-dino.position()[1])*0.05 alex.goto(x0,y0) alex.goto(x1,y1) alex.goto(x0,y0) bert.goto(x1,y1) bert.goto(x2,y2) bert.goto(x1,y1) cico.goto(x2,y2) cico.goto(x3,y3) cico.goto(x2,y2) dino.goto(x3,y3) dino.goto(x0,y0) dino.goto(x3,y3) def ausgang(a,b,c): for i in kroeten: i.tracer(0) i.up() alex.goto(-b,-b+c) bert.goto(a,-b+c) cico.goto(a,a+c) dino.goto(-b,a+c) for i in kroeten: i.down() ausgang(0,400,0) bild1() ausgang(0,400,0) bild2() ausgang(400,0,0) bild1() ausgang(400,0,0) bild2() ausgang(0,400,400) bild1() ausgang(0,400,400) bild2() ausgang(400,0,-400) bild1() ausgang(400,0,-400) bild2() Strings, Tupels und Listen Python stellt eine Klasse von Datentypen zur Verfügung, mit der Folgen von gleichartigen oder verschiedenen Elementen verwaltet werden können. Diese sequentiellen Datentypen sind str (und unicode), list und tuple (Strings, Listen und Tupels). Beispiele für Listen, Tupels und Strings sind: >>> >>> >>> >>> >>> >>> listeA listeB listeC listed tupelA tupelB = = = = = = [3 ,4, 5, 5.5, 6] [“red“, “yellow“, “green“] [1, [2, 3], [4, [5, 6]]] [ ] (1, 3) (1, (2,3), “hallo”, [ ]) >>> tupelC = (“Fritz”,) >>> tupelD = ( ) >>> stringA = “X” >>> stringB = “Hallo Welt” >>> stringC = “” Beim Erzeugen durch Anschreiben unterscheiden sich Tupel und Listen nur durch die Art der Klammer. In einem einelementigen Tupel muss nach dem einzigen Element ein Komma gesetzt werden, damit es von Klammerausdrücken unterschieden werden kann. Der wesentliche Unterschied zwischen den beiden fast identischen Datypen ist, dass eine Liste nach der Erzeugung verändert werden kann, während ein Tupel keine Änderung des Anfangsinhalts zulässt: list ist mutable, tuple ist immutable. Für alle Sequenzen gibt es neben unterschiedlichen auch gemeinsame Operatoren. Anhand des Datentyps str sollen die gemeinsamen Operatoren erläutert werden: 1. x in s: Es wird geprüft, ob x in s enthalten ist. Das Ergebnis ist vom Typ bool. >>> s = “Python ist eine Skriptsprache“ >>> “y“ in s True >>> s=[1,2,3,4,5,6] >>> 5 in s True 2. x not in s: Es wird geprüft, ob x nicht in s enthalten ist. >>> s = “Python ist eine Skriptsprache“ >>> “y“ not in s False >>> s=[1,2,3,4,5,6] >>> 3.5 not in s True 3. s + t: Das Ergebnis ist eine neue Sequenz. >>> s = “Hallo“ >>> t = “Welt“ >>> s+t ’Hallo Welt’ 4. s += t: Erzeugt eine Verkettung von s und t und weist sie s zu. >>> s = “Volks“ >>> s += “wagen“ >>> s ’Volkswagen’ 5. s *= n: Erzeugt das Produkt von s * n und weist es s zu. >>> s = “SOS “ >>> s *= 3 >>> s ’SOS SOS SOS’ 6. s[i]: Liefert das i-te Element von s >>> s = “Sylt“ >>> s[1] ’y’ >>> s[-1] ‘t’ Man beachte die Zählweise der Indizes. Das erste Element von links hat den Index 0. 7. s[i:j]: Liefert den Ausschnitt aus s von i bis j. >>> s = “Ameisen“ >>> s[1:6] ‘meise’ 8. len(s): Gibt die Anzahl der Elemente von s an. >>> s = “Wie lang ist dieser Satz“ >>> len(s) 24 9. min(s): Liefert das kleinste Element von s, sofern eine Ordnungsrelation für die Elemente definiert ist, z.B. Alphabet. >>> >>> ‘G’ >>> >>> ‘e’ s=“Geometrie“ min(s) s=”geometrie” min(s) Beim Vergleich von Groß- und Kleinbuchstaben untereinander Kleinbuchstaben immer größer: „a“ ist kleiner „z“ aber größer „Z“. gelten >>> s=[4,2,6,3,9,8] >>> min(s) 2 10. max(s): Liefert das größte Element von s. Strings String-Instanzen verfügen über Methoden, die den Umgang mit Zeichenketten vereinfachen. Aufgrund der großen Anzahl von String-Methoden wird im folgenden Text nur auf einzelne beispielhaft eingegangen. Drei Chinesen mit dem Kontrabass... Sicherlich kennt jeder den folgenden Kinderreim: Drei Chinesen mit dem Kontrabass sitzen auf der Strasse und erzaehlen sich was. Da kommt die Polizei und fragt: Wass ist denn das? Drei Chinesen mit dem Kontrabass! Die anderen Strophen sind der ersten Strophe recht ähnlich: Nur wird an Stelle der verschiedenen Vokale immer derselbe Vokal gesungen. stringA="Drei Chinesen mit dem Kontrabass" stringB="sitzen auf der Strasse und erzaehlen sich was." stringC="Da kommt die Polizei und fragt:" stringD="Was ist denn das?" vokal=input("Gib einen Vokal an: ") for i in (stringA, stringB, stringC, stringD, stringA): for j in("a","A","e","E","i","I","o","O","u","U"): i=i.replace(j,vokal) print (i) Wie oft kommt im Originaltext der Buchstabe „D“ vor? Dabei ist es egal, ob der Buchstabe klein oder groß geschrieben wird. stringA="Drei Chinesen mit dem Kontrabass" stringB="sitzen auf der Strasse und erzaehlen sich was." stringC="Da kommt die Polizei und fragt:" stringD="Was ist denn das?" zahl=0 buchstabe=input("Welcher Buchstabe soll ueberprueft werden? ") buchstabe.upper() for i in (stringA, stringB, stringC, stringD, stringA): i.upper() zahl=zahl+i.count(buchstabe) print zahl Folgende Methoden dienen zum Suchen von Teilstrings: s.find(Teilstring[,start[,ende]]) >>> >>> 8 >>> -1 >>> -1 >>> -1 >>> 8 s="Es lebe Delphi bei der Stringmanipulation" s.find("Delphi") s.find("Delphi",10,18) s.find("Delphi",2,10) s.find("Delphi",0,10) s.find("Delphi",0,15) s.count(Teilstring[,start[,ende]]) >>> s="Es lebe Delphi bei der Stringmanipulation" >>> s.count("Delphi") 1 Folgende Methoden dienen zum Ersetzen von Teilstrings: s.replace(alt,neu[,Anzahl]) >>> >>> 'Es >>> s="Es lebe Delphi bei der Stringmanipulation" s.replace("e","x") lxbx Dxlphi bxi dxr Stringmanipulation' s="Es lebe Delphi bei der Stringmanipulation" >>> s.replace("e","x",4) 'Es lxbx Dxlphi bxi der Stringmanipulation' s.lower() >>> s="Es lebe Delphi bei der Stringmanipulation" >>> s.lower() 'es lebe delphi bei der stringmanipulation' s.upper() >>> s.upper() >>> s="Es lebe Delphi bei der Stringmanipulation" 'ES LEBE DELPHI BEI DER STRINGMANIPULATION' Folgende Methoden dienen zum Entfernen von Zeichen am Anfang oder am Ende von Strings: s.strip([char]) s.lstrip([char]) >>> s="Risotto" >>> s.lstrip("Ris") 'otto' s.rstrip([char]) Tupel Tupel sind unveränderliche Sequenzen. Man kann ein Element eines Tupels nicht mit einem neuen Wert überschreiben. Außerdem sind für Tupel-Elemente keine Methoden definiert. Listen Listen sind für die Verwaltung beliebiger Instanzen auch unterschiedlicher Datentypen geeignet. Eine Liste kann Zahlen, Strings und auch weitere Listen enthalten. Inhalte einer Liste lassen sich auch nach ihrer Erzeugung verändern. Deshalb sind weitere Operatoren für diesen sequentiellen Datentyp vorhanden. 1. s[i]=x: Das Element von s mit dem Index i wird durch x ersetzt. >>> s = [1,2,3,4,5,6] >>> s[3] = 8 >>> s [1,2,3,8,5,6] 2. s[I:j]=t: Der Teil s[I:j] wird durch t ersetzt. >>> s=["rot","rot","rot"] >>> s[1:3]=["gelb","gruen"] >>> s ['rot', 'gelb', 'gruen'] 3. del s[i]: Das i-te Element von s wird entfernt. 4. del s[i:j]: Die Elemente mit den Indizes i bis j werden gelöscht. Beispiel: Eine Klassenarbeit brachte folgende Ergebnisse: 3 mal sehr gut, 6 mal gut, 9 mal befriedigend, 8 mal ausreichend, 4 mal mangelhaft und 1 mal ungenügend. Die Noten sollen graphisch mit Hilfe von Sternenreihen veranschaulicht werden. notenliste=[0,0,0,0,0,0] j=1 for i in range(6): notenliste[i]=int(raw_input("Haufigkeit der Note "+chr(i+1+48)+": ")) for i in range(6): print "Note ",i+1,": ", for j in range(notenliste[i]): print "*", print Ein weiteres Beispiel stammt aus der Chemie. Was leistet das folgende Programm? lauge=["Natronlauge","Kalilauge","Kalkwasser"] saeure=["Salzsaeure","Schwefelsaeure","Salpetersaeure","Kohlensaeure"] def schreiben(i,j): #global lauge,saeure if i==lauge[0]: print "Natrium", elif i==lauge[1]: print "Kalium", elif i==lauge[2]: print "Calcium", if j==saeure[0]: print "chlorid + Wasser" elif j==saeure[1]: print "sulfat + Wasser" elif j==saeure[2]: print "nitrat + Wasser" elif j==saeure[3]: print "carbonat + Wasser" for i in lauge: for j in saeure: print i+" + "+j," = ", schreiben(i,j) Neben den Operatoren existieren für Listen Methoden.: 1. s.append(x): Hängt x ans Ende von s an. 2. s.extend(t): Hängt alle Elemente einer Liste t ans Ende von s an. 3. s.count(x): Gibt an, wie oft das Element x in s vorkommt. 4. s.index(x[,i[,j]]): Gibt den Index des ersten Vorkommens von x im Bereich von i<=k<j zurück. 5. s.insert(i,x): Fügt x an der Stelle i in s ein. 6. s.pop([i]): Gibt das i-te Element von s zurück und entfernt es aus s. Ist i nicht angegeben, wird das letzte Element genommen. 7. s.remove(x): Entfernt das erste Vorkommen von x aus s. 8. s.reverse(): Kehrt die Reihenfolge der Elemente in s um. 9. s.sort(): Sortiert s. Es folgen Beispiele für Listenmethoden. Beispiel 1: Nach seiner Eingabe soll ein Wort in umgekehrter Lesart ausgegeben werden, z.B. wird PYTHON zu NOHTYP. wort=[ ] w="" while w!="#": w=raw_input("Buchstabe: ") if w!="#": wort.append(w) wort.reverse() for i in wort: print i.upper(), Beispiel 2: Es sollen alle Primzahlen bis zu einer einzugebenden Zahl n ausgegeben werden. Dies soll nach dem Verfahren „Sieb des Eratosthenes“ erfolgen. sieb=[ ] zahl=int(raw_input("Primzahlen bis n= ")) for i in range(zahl): sieb.append(False) for i in range(2,zahl): if sieb[i]==False: print i, for j in range(zahl // i): sieb[i*j]=True Aufgabe 7 1. Es soll die Zahl der Tage des Monats und der Wochentag; auf den der 1. Tag des Monats fällt, eingegeben werden. Auszudrucken ist ein Monatkalender in einer der beiden nachstehenden Formen: MONTAG 5 12 MO DI MI DO FR SA SO DIENSTAG 6 13 1 2 3 4 5 MITTWOCH 7 .... 6 7 8 9 10 11 12 DONNERSTAG 1 8 FREITAG 2 9 SAMSTAG 3 10 SONNTAG 4 11 2. Es gibt verschiedene Methoden bei Proportionalwahlverfahren. Zwei davon sollen hier behandelt und ihre Wirkung verglichen werden. Gegeben sind die Stimmenzahlen der Parteien und die Zahl der zu vergebenden Sitze. a) Verfahren nach d’Hondt: Die Parteistimmenzahlen werden nacheinander durch 1, 2 , 3 usw. geteilt. Die Sitze werden nach der Größe dieser Teilzahlen der Reihe nach zugeteilt. Bei gleichen Teilzahlen entscheidet das Los. b) Verfahren nach Hagenbach – Bischoff: Die Gesamtstimmzahl wird durch die um 1 erhöhte Zahl der Sitze geteilt und auf die nächste ganze Zahl aufgerundet. Die Sitzzahlen der Parteien erhält man, indem man die Parteistimmenzahlen durch diesen Wahlquotienten teilt und auf die nächste ganze Zahl abrundet (1. Verteilung). Bleiben zu verteilende Sitze übrig, so wird die Stimmenzahl jeder Partei durch die um 1 erhöhte Zahl der ihr bereits zugewiesenen Sitze geteilt und der erste der noch zu verteilenden Sitze der Partei mit der größten Verteilungszahl zugewiesen. Dieses Verfahren wird solange fortgesetzt, bis alle Sitze verteilt sind. Allenfalls entscheidet bei gleichen Verteilungszahlen das Los. Wörterbücher (Dictionaries) Dictionary heißt auf Deutsch Wörterbuch. Ein einfaches Wörterbuch „Deutsch – Englisch“ besteht aus Paaren von Worten. Einem deutschen Wort ist die englische Übersetzung, also ein zweites Wort zugeordnet. Das folgende Beispiel zeigt ein Miniwörterbuch als Python-Dictionary: woerterbuch = {“mother“:“Mutter“, “father“:“Vater“, “child“:“Kind“, “son“:“Sohn“, “daughter“:“Tochter“} Dictionaries bestehen daher aus einer Menge von Paaren von Objekten, den sogenanten Schlüssel-Wert-Paaren. Die Wertepaare sind durch Kommata getrennt, zwischen den Wertepaaren steht ein Doppelpunkt. Eingefasst werden die Wertepaare durch geschweifte Klammern. Der Schlüssel ist die Adresse des Wertes. Mit seiner Hilfe hat man direkten Zugriff auf den Wert. Dazu schriebt man den Schlüssel in eckige Klammern. >>>woerterbuch [“child“] ’Kind’ Ein Dictionary kann Schritt für Schritt aufgebaut werden. Zuerst erzeugt man ein leeres Wörterbuch. >>> Kopfnoten { } Dann trägt man die Schlüssel-Wert-Paare einzeln ein: >>> Kopfnoten [’1’] = ’sehr gut’ >>> Kopfnoten [’2’] = ’gut’ >>> Kopfnoten [’3’] = ’befriedigend’ >>> Kopfnoten [’4’] = ’unbefriedigend’ >>> Kopfnoten ['2'] 'gut' >>> Kopfnoten {'1': 'sehr gut', '3': 'befriedigend', '2': 'gut', '4': 'unbefriedigend'} Bei der letzten Ausgabe ist zu beachten, dass die Einträge im Wörterbuch ungeordnet sind. Man hat keinen Einfluss auf die Reihenfolge der Einträge. Wie bei Listen und Strings gibt es auch bei den Dictionaries Methoden: d.clear(): Diese Anweisung entfernt alle Schlüssel-Werte-Paare aus dem Dictionary. Zurück bleibt ein leeres Wörterbuch, d.h., das Dictionary selbst wird nicht gelöscht. d.get(k,x): Der Aufruf liefert aus einem Dictionary d den mit dem Schlüssel k assoziierten Wert, sofern k in der Liste vorhanden ist. Ansonsten wird der Wert x zurückgegeben. d.keys(): Der Aufruf liefert eine Liste mit allen Schlüsseln. d.values(): Der Aufruf liefert eine Liste mit alle Werten. k in d und k not in d Mit diesen Methoden kann man überprüfen, ob ein Schlüssel in der Schlüsselliste vorhanden ist oder nicht. Im ersten Fall liefert der Ausdruck den Wert True, wenn der Schlüssel vorhanden ist, im zweiten Fall den Wert False. Ist der Schlüssel nicht vorhanden, sind die Rückgabewerte False und True. Der Caesar-Code Eine der ältesten kryptographischen Methoden ist die Caesar-Verschlüsselung. Jeder Buchstabe des zu verschlüsselnden Textes wird durch einen anderen ersetzt. Wichtig ist dabei die Ersetzungsvorschrift. Bei Caesar wurde das Alphabet einfach um eine bestimmte Anzahl von Buchstaben verschoben: ABCDEFGHIJKLMNOPQRSTUVWXYZ BCDEFGHIJKLMNOPQRSTUVWXYZA CDEFGHIJKLMNOPQRSTUVWXYZAB DEFGHIJKLMNOPQRSTUVWXYZABC EFGHIJKLMNOPQRSTUVWXYZABCD FGHIJKLMNOPQRSTUVWXYZABCDE GHIJKLMNOPQRSTUVWXYZABCDEF Aus „WIR GREIFEN IM MORGENGRAUEN AN“ wird COX MXKOLKT OS SUXMKTMXGAKT GT. Diese Ersetzungsvorschrift lässt sich durch ein Dictionary beschreiben: code = {"A":"G","B":"H","C":"I"} usw. Damit für code die Schlüssel-Werte-Paare produziert werden können, wird zuerst eine Liste klar mit allen Buchstaben des Alphabets hergestellt. Der Befehl chr(x) erzeugt ein Zeichen mit dem ASCII-Code x. X muss einen Wert zwischen 0 und 255 haben. Die Großbuchstaben des Alphabets beginnen bei x=65. klar=[] for i in range(26): klar.append(chr(i+65)) Anschließend wird die Liste geheim erstellt. Der Buchstabe A soll durch G ersetzt werden. G ist der siebte Buchstabe des Alphabets. Da der Listenindex bei 0 beginnt, wird die Liste klar ab der Stelle 6 in die Liste geheim übernommen und die fehlenden Buchstaben werden angehängt. geheim=klar[6:]+klar[:6] Aus den Listen klar und geheim wird jetzt das Dictionary code erstellt. code={} for i in range(26): code[klar[i]]=geheim[i] In der Eingabeaufforderung der IDLE kann man das Ergebnis überprüfen. >>> klar ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] >>> geheim ['G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F'] >>> code {'A': 'G', 'C': 'I', 'B': 'H', 'E': 'K', 'D': 'J', 'G': 'M', 'F': 'L', 'I': 'O', 'H': 'N', 'K': 'Q', 'J': 'P', 'M': 'S', 'L': 'R', 'O': 'U', 'N': 'T', 'Q': 'W', 'P': 'V', 'S': 'Y', 'R': 'X', 'U': 'A', 'T': 'Z', 'W': 'C', 'V': 'B', 'Y': 'E', 'X': 'D', 'Z': 'F'} Jetzt fehlt nur noch der Verschlüsselungsbefehl. Der zu verschlüsselnde Text wird Zeichen für Zeichen dekodiert. Falls Leerzeichen im Text auftauchen, müssen diese berücksichtigt werden. for a in text: geheimtext=geheimtext+code.get(a," ") Der bisherige Quelltext sieht wie folgt aus: text="Wir greifen im Morgengrauen an" text=text.upper() geheimtext="" klar=[] for i in range(26): klar.append(chr(i+65)) geheim=klar[6:]+klar[:6] code={} for i in range(26): code[klar[i]]=geheim[i] for a in text: geheimtext=geheimtext+code.get(a," ") print geheimtext Möchte man den Text wieder entschlüsseln, werden die folgenden Zeilen noch angehängt: dcode={} ent="" for i in range(26): dcode[geheim[i]]=klar[i] for a in geheimtext: ent=ent+dcode.get(a," ") print ent Das ganze Programm lässt sich noch etwas eingabefreundlicher gestalten. Außerdem kann das bisherige Programm nur den mit dem Programm selbst verschlüsselten Text entschlüsseln. Was macht man aber, wenn man die CaesarVerschiebung nicht kennt? Brutale Gewalt! Unter der Voraussetzung, dass der Geheimtext nach Caesar verschlüsselt wurde, wird der Text entschlüsselt. text=raw_input("Geben Sie den Text ein: ") ver=int(raw_input("Ist der Text unverschluesselt oder verschluesselt (Eingabe 0 bzw. 1):")) text=text.upper() geheimtext="" klar=[] ent="" code={} dcode={} for i in range(26): klar.append(chr(i+65)) if ver==0: schiebung=int(raw_input("Bitte den Verschiebungswert eingeben")) geheim=klar[schiebung:]+klar[:schiebung] for i in range(26): code[klar[i]]=geheim[i] for a in text: geheimtext=geheimtext+code.get(a," ") print geheimtext else: for j in range(26): ent="" geheim=klar[j:]+klar[:j] for i in range(26): dcode[geheim[i]]=klar[i] for a in text: ent=ent+dcode.get(a," ") dcode.clear() print ent Dateien Dateien sind Datenobjekte, die unter einem Dateinamen auf einem Speicher abgelegt und vom Betriebssystem verwaltet werden. Um auf eine Datei lesend oder schreibend zugreifen zu können, muss zuerst ein File-Objekt generiert werden. Als Parameter wird der Pfad und der Modus übergeben. Die Datei wird geöffnet. >>> datei = file(dateiname,“r“) >>> datei = file(dateiname,“w“) Der Dateiname kann eine vollständige Pfadangabe oder nur den Dateinamen enthalten. Wird nur der Dateiname angegeben, wird die Datei im aktuellen Verzeichnis gespeichert. Unter Windows kann die Pfadangabe wie folgt erfolgen: >>> datei = file ( 'c:/Ordner/versuch.txt',"w") oder >>> datei = file ( 'c:\\Klett\\versuch2.txt',"w") Eingelesen wird die Datei durch Zuweisung: >>> text = datei.read() bzw. gespeichert durch die Zuweisung >>> datei.write(text) Sowohl nach dem Lesen als auch dem Schreiben wird die Datei geschlossen mit der Anweisung >>> datei.close() TK-Inter