Programmieren im Unterricht mit Python Python in Beispielen: Eine Einführung für Programmierer J. Arnold, M. Guggisberg, T. Kohn, A. Plüss c 2015, TigerJython Team Copyright http://www.tigerjython.ch/ http://jython.tobiaskohn.ch/ Version vom 5./6. September 2015. Programmieren im Unterricht mit Python 1 Listen und Summen Die Primzahlen eignen sich hervorragend als BeispielListe, weil die Zahlen nicht regelmässig verteilt sind. In diesem Abschnitt stellen wir verschiedene Techniken vor, um die Summe einer Liste von Primzahlen (oder anderem) zu berechnen. Einführung For-Schleifen in Python arbeiten immer mit Listen: Die Laufvariable geht der Reihe nach alle Elemente einer Liste durch. Damit ist diese Technik prädestiniert, um die Summe zu bilden. For-Schleife 1 2 3 4 5 primes = [2, 3, 5, 7, 11, 13, 17, 19] summe = 0 for p in primes: summe += p print summe In Python wird eine Funktion mit def definiert und gibt mit return ein Resultat zurück. Indem wir den Code oben in eine Funktion verpacken, haben wir flexibleren, wiederverwendbaren Code. Funktionen 1 2 3 4 5 def summe(liste): result = 0 for zahl in liste: result += zahl return result 6 7 8 primes = [2, 3, 5, 7, 11, 13, 17, 19] print summe(primes) Weil Variablen in Python keinen festen Typ haben, können wir die Summenfunktion auch so umschreiben, dass sie Strings (Zeichenketten) zusammenhängt. Eine Funktion für alles 1 2 3 4 5 6 7 8 def summe(liste): if liste != []: result = head(liste) for item in tail(liste): result += item return result else: return None 9 10 11 12 primes = [2, 3, 5, 7, 11, 13, 17, 19] print summe(primes) print summe(["Tic", "Tac", "Toe"]) c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss 3 Programmieren im Unterricht mit Python 4 Für die Rekursion haben sich die Funktionen head und tail als nützlich herausgestellt. Dabei gibt head(liste) das erste Element zurück, tail(liste) den Rest – wiederum als Liste. Rekursion 1 2 3 4 5 def summe(liste): if liste == []: return 0 else: return head(liste) + summe(tail(liste)) Mit head und tail können wir das erste Element einer Liste abspalten. head([2,3,5]) = 2 tail([2,3,5]) = [3,5] 6 7 8 primes = [2, 3, 5, 7, 11, 13, 17, 19] print summe(primes) Wir gehen noch einen Schritt weiter und machen sogar die «Addition» austauschbar. Wir können dann nicht nur Summen, sondern auch Produkte mit der gleichen Funktion berechnen. Dazu nutzen wir aus, dass Funktionen in Python 1.-Klass-Objekte sind. Das heisst, wir können eine Funktion als Parameter an eine andere Funktion übergeben! Für Profis: Falten* 1 2 3 4 5 def fold(liste, op): result = head(liste) for item in tail(liste): result = op(result, item) return result 6 7 8 def add(x, y): return x + y 9 10 11 def mul(x, y) return x * y 12 13 14 15 primes = [2, 3, 5, 7, 11, 13, 17, 19] print fold(primes, add) print fold(primes, mul) Noch etwas schöner wird es, wenn wir Lambda-Ausdrücke verwenden, um kurze Funktionen direkt in den Code einzubetten. Die Operationsfunktionen add und mul oben können wir im Prinzip auch so schreiben: add = lambda x, y: x + y mul = lambda x, y: x * y Die Namen add und mul sind aber ebenfalls überflüssig und wir rufen fold direkt so auf: 1 2 3 primes = [2, 3, 5, 7, 11, 13, 17, 19] print fold(primes, lambda x, y: x + y) print fold(primes, lambda x, y: x * y) c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss Listen und Summen 5 AUFGABEN 1. Schreibe eine Funktion fakult(n), die die Fakultät n! = 1 · 2 · 3 · · · n einer Zahl n berechnet. Natürlich geht das auf völlig verschiedene Arten und die interessante Aufgabe wäre, möglichst viele verschiedene Wege für die Berechnung zu finden. 2. Ein altes Rätsel von Sam Loyd (1841–1911): Neulich sah ich mir zusammen mit einem Freund die Attraktionen auf Coney Island an, und dabei lernten wir kennen, was uns jemand als das ehrlichste Spiel am ganzen Strand anpries. Da waren zehn kleine Figuren, die man mit einem Ball umwerfen musste. Der Mann sagte: «Für 1 Cent haben Sie einen Wurf, und Sie können werfen, so oft Sie wollen, und so dicht ’rangehen, wie Sie wollen. Zählen Sie die Zahlen auf den Figuren, die Sie umwerfen zusammen, und wenn Sie genau 50 haben, nicht mehr und nicht weniger, erhalten Sie eine prächtige Maggie-ClineZigarre mit einem Goldband drum herum.» Unser Geld war alle, noch bevor wir heraus hatten, wie man eigentlich gewinnen konnte. Ausserdem fiel uns auf, dass eine ganze Menge Leute genauso wenig Maggie-Cline-Zigarren rauchten wie wir. Wissen Sie, wie man genau 50 Punkte macht? Die Aufgabe besteht also darin, aus den gegebenen Zahlen jene herauszusuchen, die zusammen die Summe 50 ergeben: 25, 27, 3, 12, 6, 15, 9, 30, 21, 19 Schreibe ein Programm, das diese Aufgabe für dich übernimmt! c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss Programmieren im Unterricht mit Python 6 2 Fibonacci-Zahlen berechnen Die Fibonacci-Zahlen sind das klassische Beispiel für eine rekursiv definierte Zahlenfolge: Einführung an = an−2 + an−1 , a0 = a1 = 1 1, 1, 2, 3, 5, 8, 13, 21, . . . In diesem Abschnitt untersuchen wir verschiedene rekursive und iterative Möglichkeiten, um die Fibonacci-Zahlen zu berechnen. Der naive Ansatz Wir beginnen mit dem naiven Ansatz und definieren eine Funktion fib(n) aus der rekursiven Formel oben. Aber vorsicht: Dieser Ansatz hat eine exponentielle Laufzeit! 1 2 3 4 5 def fib(n): if n < 2: return 1 else: return fib(n-2) + fib(n-1) 6 7 print fib(30) Ein iterativer Ansatz (d. h. mit einer Schleife) arbeitet viel schneller und ist ebenfalls einfach zu programmieren. Python erleichtert uns die Arbeit sehr, indem wir mit liste[-1] bzw. liste[-2] auf das letzte und zweitletzte Element einer Liste zugreifen können. Iterativer Ansatz mit Liste 1 2 3 4 5 6 def fib(n): F = [1, 1] repeat n-1: x = F[-2] + F[-1] F.append(x) return F[-1] 7 8 print fib(30) In diesem zweiten iterativen Ansatz verzichen wir auf die Liste. Eigentlich genügt es ja, wenn wir von der Liste jeweils die beiden letzten Elemente speichern. Python erlaubt uns, hier mit Tupeln zu arbeiten und die Abbildung (a, b) 7→ (b, a + b) direkt umzusetzen. Iterativer Ansatz ohne Liste 1 2 3 4 def fib(n): (a, b) = (1, 1) repeat n-1: (a, b) = (b, a+b) c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss Fibonacci-Zahlen berechnen 5 7 return b 6 7 print fib(30) Als letzten Ansatz stellen wir noch «Memoization» vor. Um den rekursiven Ansatz schneller zu machen speichern wir hier die Werte, die bereits berechnet wurden. Dazu verwenden wir ein Dictionary (Hash-Table, s. unten). Memoization: Rekursion mit Liste 1 2 3 4 5 6 7 8 9 10 memo_table = {} def fib(n): if n < 2: return 1 elif n in memo_table: return memo_table[n] else: result = fib(n-2) + fib(n-1) memo_table[n] = result return result 11 12 print fib(30) Alternativ wäre hier noch eine kürzere Variante des selben: 1 2 3 4 5 memo_table = {0: 1, 1: 1} def fib(n): if n not in memo_table: memo_table[n] = fib(n-2) + fib(n-1) return memo_table[n] 6 7 print fib(30) Neben Listen sind auch Dictionaries in Python fest eingebaute Datenstrukturen. Die Schlüssel ("Name", (3,4) etc.) dürfen beliebige (unveränderbare) Datentypen haben. Dictionaries BDFL = {"Name": "van Rossum", "Vorname": "Guido", "Geb-Jahr": 1956, "BDFL": True} PT = {(3, 4): 5, (5, 12): 13, (20, 21): 29} print "Name", BDFL["Name"] print PT[(5, 12)] Bei Memoization gehen wir davon aus, dass es aufwendig oder teuer ist, den Funktionswert f (x) für einen Wert x zu berechnen. Deshalb verwenden wir eine Liste oder Tabelle und speichern alle Funktionswerte von f (x) nach deren ersten Berechnung. Für einen bestimmten Wert x1 kann also der erste Aufruf von f (x1 ) noch teuer sein. Ab dem zweiten Aufruf liegt das Resultat aber bereits vor und wird direkt der Liste/Tabelle entnommen. Was ist Memoization? Memoization ist eine spezielle Form des «Caching» von Funktionswerten. c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss Programmieren im Unterricht mit Python 8 3 Listen: Chaos und Ordnung Für viele Zwecke ist es nützlich, eine Liste mit Zufallszahlen erstellen zu können, um dann mit einer solchen zufälligen Liste weiterzuarbeiten. Dazu laden wir die Funktin randint aus dem random-Modul und erzeugen dann mit randint(0, 20) eine Zufallszahl zwischen 0 und 20. Zufallszahlen 1 2 3 4 from random import randint liste = [] repeat 30: liste.append(randint(0, 20)) Mit List-Comprehensions geht das natürlich auch kürzer: from random import randint liste = [randint(0, 20) for x in range(30)] Jede ganze Zahl lässt sich auch binär schreiben. So hat 69 etwa die Binärdarstellung 0100 0101. Diese Binärdarstellung soll uns Python liefern. Dabei sind // die Ganzzahl-Division und % der Rest dieser Ganzzahl-Division. Zahlen binär zerlegen 1 2 3 4 5 6 binary = [] zahl = 69 repeat 8: binary.insert(0, zahl % 2) zahl = zahl // 2 print binary Pythons Divisionsoperatoren: 61 / 8 = 7.625 61 // 8 = 7 61 % 8 = 5 Mit join werden die einzelnen Ziffern zu einem String ohne Kommata verbunden, so dass eine eigentliche Binärzahl entsteht: print join(binary) Nachdem wir eine Liste erzeugt haben wollen wir sie auch sortieren. Hier ist ein einfacher Algorithmus, der demonstriert, wie man Elemente aus einer ersten Liste entfernen und an eine andere Liste anhängen kann. Sortieren (I) 1 2 3 4 5 6 7 def my_sort(liste): result = [] while liste != []: x = min(liste) liste.remove(x) result.append(x) return result # x aus alter Liste entfernen # x an neue Liste anhängen 8 9 10 print my_sort([14, 3, 4, 5, 17, 7, 18, 11, 19]) print my_sort(["Kuh", "Biene", "Zebra", "Emu", "Affe"]) c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss Listen: Chaos und Ordnung Diese Variante des Sortierens erstellt eine neue Liste, in der jedes Element an der richtigen Stelle eingefügt wird, so dass die Liste jederzeit korrekt sortiert ist. Elemente, die grösser sind als alle bisherigen können nicht eingefügt werden, sondern werden am Ende angehängt. Sortieren (II) 1 2 3 4 5 6 7 8 9 10 11 12 def my_sort(liste): result = [] for item in liste: inserted = False for i in indices(result): if result[i] > item: result.insert(i, item) inserted = True break if not inserted: result.append(item) return result 13 14 print my_sort([14, 3, 4, 5, 17, 7, 18, 11, 19]) Die dritte Variante eines Sortieralgorithmus ist «Merge-Sort». Wir arbeiten hier mit Rekursion und nutzen aus, dass wir eine Liste in Python sehr einfach auftrennen können: Sortieren (III): Merge-Sort liste = [4, 9, 1, 7, 5, 3] liste[2:4] -> [1, 7] liste[:3] -> [4, 9, 1] liste[3:] -> [7, 5, 3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def merge_sort(liste): if len(liste) <= 1: return liste # Liste aufteilen und Teile sortieren: idx = len(liste) // 2 partA = merge_sort(liste[:idx]) partB = merge_sort(liste[idx:]) # Teillisten miteinander verschmelzen: result = [] while partA != [] and partB != []: if head(partA) < head(partB): result.append(head(partA)) partA = tail(partA) else: result.append(head(partB)) partB = tail(partB) # Entweder partA oder partB ist hier leer: return result + partA + partB 19 20 print merge_sort([4, 9, 1, 7, 5, 3]) c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss 9 10 Programmieren im Unterricht mit Python Diese einfache Variante einer Filter-Funktion zeigt, wie du in Python mit in direkt prüfen kannst, ob ein Element in einer Liste vorkommt. Filtern 1 2 3 4 5 6 def filter(liste, allowed): result = [] for item in liste: if item in allowed: result.append(item) return result 7 8 print filter([4, -3, 0, 2, -5], [0, 2, 4, 6, 8]) Hier noch die Kurzversion mit List Comprehensions: def filter(liste, allowed): return [x for x in liste if x in allowed] AUFGABEN 3. Schreibe eine Funktion, die aus einer gegebenen Liste alle doppelt vorkommenden Elemente entfernt. 4. Schreibe eine Funktion, die zwei Listen vergleicht und die Anzahl der Elemente zurückgibt, die in beiden Listen vorkommen. 5. Schreibe eine Funktion, die zu einer gegebenen Liste eine zufällige Permutation erzeugt und zurückgibt. 6. Schreibe eine Lotto-Simulation. Wähle zuerst 6 Zahlen aus 42 aus und führe dann 10 000 Ziehungen mit 7 Zufallszahlen durch. Das Programm gibt dann jedes Mal die 7 Zahlen aus, wenn 4, 5 oder 6 «richtige» dabei sind und zählt zusammen, wie oft du mit deinen 6 Glückszahlen gewonnen hast. 7. Gegeben ist eine Liste, die nur die Zahlen 0 und 1 enthält. Fin- de darin die längste Abfolge von Nullen oder Einsen. Für die Eingabe [0, 1, 1, 0, 0, 1, 1, 1, 0] wäre die längste Folge [1, 1, 1]. Das Programm soll drei Informationen dazu ausgeben: Die Länge der Folge, ob es Nullen oder Einsen sind und an welcher Stelle in der Liste die Folge auftritt. c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss Listen: Punkte und Polygone 4 11 Listen: Punkte und Polygone Punkte lassen sich in Python direkt mit Tupeln abbilden. Ein Tupel ist eine «unveränderbare» Liste. Einmal erzeugt, ändern sich die Elemente eines Tupels also nicht mehr. Für ein Polygon verwenden wir dann eine Liste von Tupeln. Hier ist ein gleichseitiges Dreieck: Einführung Tupel werden im Gegensatz zu Listen mit runden Klammern geschrieben: Liste: [1, 2, 3] Tupel: (1, 2, 3) [(-34.6, -20), (0, 40), (34.6, -20)] In diesem Abschnitt arbeiten wir mit solchen Polygonen. Als Einstieg lassen wir uns das Polygon zunächst einmal zeichnen. Dazu verwenden wir die Turtle-Grafik, die für unsere Zwecke mehr als ausreicht. Das Polygon zeichnen 1 2 3 4 from gturtle import * makeTurtle() speed(-1) setPenColor("black") # # # # Turtle-Bibliothek laden Turtle-Fenster öffnen Turtle möglichst schnell Linien-Farbe: Schwarz 5 6 7 8 9 10 coords = [(-34.6, -20), (0, 40), (34.6, -20)] (x, y) = coords[-1] # Startpunkt setPos(x, y) for (x, y) in coords: moveTo(x, y) Die Distanz eines Punkts zum Ursprung müssen wir selber berechnen. Dazu laden wir die Wurzel-Funktion sqrt aus dem Mathematik-Modul math und definieren eine neue Funktion. Anschliessend suchen wir den Punkt, der am nächsten beim Ursprung liegt. Distanzen Anstelle von sqrt könnten wir auch x**0.5 (x0.5 ) verwenden. 1 from math import sqrt 2 3 4 5 def dist((x0, y0), (x1, y1)): d = (x1 - x0)**2 + (y1 - y0)**2 return sqrt(d) 6 7 8 9 10 11 12 13 14 15 coords = [(1, 9), (2, 8), (3, 7), (4, 6), (5, 5), (6, 4)] min_point = head(coords) min_dist = dist(min_point, (0, 0)) for point in coords: d = dist(point, (0, 0)) if d < min_dist: min_dist = d min_point = point print min_point c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss 12 Programmieren im Unterricht mit Python Wenn wir Polygone darstellen können, dann ist es ein kleiner Schritt zu Funktionsgraphen. In diesem Beispiel erzeigen wir eine Liste mit Punkten auf der Parabel y = 15 x2 . Graphen coords = [] for x in range(-10, 11): coords.append((5*x, x**2)) In Python lässt sich das auch kürzer schreiben als: coords = [(5*x, x**2) for x in range(-10, 11)] AUFGABEN 8. Schreibe ein Programm, das für eine beliebige Funktion den Gra- phen und die Koordinatenachsen zeichnet. Das Turtle-Fenster hat in der Regel eine Grösse von 600 × 400 Pixeln mit dem Punkt (0, 0) in der Mitte. Hinweis: Verwende für die folgenden Aufgaben das Polygon: [(34, 24), (31, 53), (70, 99), (80, 96), (104, 64), (55, 21), (44, 19), (46, 48)] 9. Schreibe eine Funktion center, die den Schwerpunkt eines Polyg- ons berechnet. xS = x1 + x2 + x3 + · · · + xn n yS = y1 + y2 + y3 + · · · + yn n 10. Schreibe eine Funktion circumference, die den Umfang des Poly- gons ermittelt. 11. Ermittelte den Durchmesser eines Polygons, also die längste Di- stanz zwischen zwei Punkten. 12. Finde in einer Liste von Koordinaten drei Punkte, die sich zu einem rechtwinkligen Dreieck verbinden lassen. Idealerweise findet dein Programm natürlich alle solchen Tripel, ohne eines doppelt auszugeben. 13. Finde in einer Liste von Koordinaten vier Punkte A, B, C, D, so dass die Strecken AB und CD senkrecht zueinander stehen. c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss Strings: Text analysieren 5 13 Strings: Text analysieren Python kann relativ gut mit Strings (Zeichenketten) umgehen und bietet eine Vielzahl von Funktionen. Dabei unterscheidet Python nicht, ob ein String in einfache oder doppelte Anfährungszeichen eingeschlossen wird: Einführung "Python ist toll!" == ’Python ist toll!’ Die Länge des Strings lässt sich mit len("...") bestimmen. In vielerlei Hinsicht unterscheiden sich Strings in Python kaum von Listen. So können wir auch mit einer for-Schleife die einzelnen Buchstaben/Zeichen eines Strings durchgehen und so die vorkommenden «E» zählen. Buchstaben zählen 1 2 3 4 5 6 def count_e(text): count = 0 for letter in text: if letter in ["e", "E"]: count += 1 return count 7 8 print count_e("Python lernen macht Spass!") Bei einfachen Text-Verschlüsselungen lohnt es sich, eine Frequenzanalyse des Textes vorzunehmen und die Häufigkeiten der Buchstaben zu zählen. Hier lassen wir das Python erledigen und verwenden dazu ein «Dictionary». Frequenzanalyse 1 2 3 4 5 6 7 8 9 10 11 12 def freq_analysis(text): # Tabelle enthält zur Zeit nur Eintrag für ’a’ und ’e’. letters = {"a": 0, "e": 0} for ch in text: ch = ch.lower() # Alles in Kleinbuchstaben if ch in letters: # Vorhandenen Wert erhöhen: letters[ch] += 1 else: # Neuer Eintrag wird automatisch erstellt: letters[ch] = 1 return letters 13 14 print freq_analysis("Python lernen ist cool!") c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss 14 Programmieren im Unterricht mit Python Python kann einen gegebenen String mit split direkt zerlegen und liefert dann eine Liste mit den einzelnen Teilstücken. Das nutzen wir, um die Wörter in einem String zu zählen. Wörter zählen 1 2 3 def count_words(text): words = text.split(" ") return len(words) 4 5 print count_words("Python ist auch eine Schlange.") Dieses Programm liest aus einem gegebenen String eine hexadezimale Zahl heraus. Aus "3F" wird damit 63. In Python selber lassen sich hexadezimale Zahlen als 0x3F direkt eingeben. Parsen einer Zahl Mit ord(’A’) ermitteln wir den Ascii-Code eines einzelnen Zeichens. Die Umkehrung dazu wäre chr(65), die aus dem Ascii-Code wiederum einen String erzeugt. 1 2 3 4 5 6 7 8 9 10 11 12 eingabe = inputString() zahl = 0 for ch in eingabe.upper(): zahl *= 0x10 if ’0’ <= ch <= ’9’: zahl += (ord(ch) - ord(’0’)) elif ’A’ <= ch <= ’F’: zahl += (ord(ch) - ord(’A’) + 10) else: print "Fehler: Ungültiges Zeichen", ch break print zahl AUFGABEN 14. Schreibe die Funktion count_words so um, dass sie Wörter wie «Python-Kurs» als zwei eigene Wörter zählt. 15. Schreibe ein Programm, das einen Text mit der Caesar-Chiffre ver- schlüsselt. 16. Schreibe ein Programm, das eine Längen-Eingabe wie «14 cm» oder «5 in» entgegennimmt und die Länge in Meter ausgibt. Hinweis: 1 in = 2.54 cm, 1 ft = 30.48 cm, bzw. in Python: factors = {"in": 0.0254, "ft": 0.3048} c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss Klassen und eigene Datentypen* 6 15 Klassen und eigene Datentypen* Python ist zwar objektorientiert, unterscheidet sich aber massiv von OOP-Sprachen wie Java. Es gibt weder Interfaces noch Information Hiding. Bei einem Aufruf wie myObject.foo() kümmert sich Python nicht um den Typ von myObject, sondern sucht in der entsprechenden Klasse lediglich nach der Methode foo. Einführung Beim Definieren einer Klasse ist wichtig, dass self immer mitangegeben werden muss: Sowohl als erster Parameter jeder Methode als auch für den Zugriff auf Felder. In Python können wir zu einem Objekt jederzeit neue Felder hinzufügen, indem wir ihnen einen Wert zuweisen. myObject.field=123 erzeugt direkt ein neues Feld im Objekt myObject, falls es nicht schon vorhanden ist. Objekte erzeugen Dieses Verhalten nutzen wir in TigerJython aus und bieten die Funktion makeObject an, um ein zunächst leeres Objekt zu erstellen. Dieses lässt sich danach je nach Bedarf mit Feldern ergänzen. 1 2 3 4 5 ball = makeObject() ball.pos = (1, 2, 3) ball.radius = 4 ball.color = makeColor("red") print ball Die Felder können aber auch direkt in makeObject angegeben werden: 1 2 3 ball = makeObject(pos=(1, 2, 3), radius=4) ball.color = makeColor("red") print ball Eine neue Klasse lässt sich relativ schnell und einfach definieren. Die grösste Schwierigkeit besteht darin, das self nicht zu vergessen. Eine neue Instanz wird danach direkt mit Vector() erzeugt. Eine Klasse für Vektoren In diesem Beispiel überladen wir mit den Methoden __add__ und __mul__ eigentlich die Plus- bzw. Stern-Operatoren +, * und __repr__ entspricht in Java der Methode toString(). 1 class Vector: 2 3 4 5 6 # Konstruktor: def __init__(self, x, y, z=0): self.x = x self.y = y c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss 16 7 Programmieren im Unterricht mit Python self.z = z 8 9 10 11 12 13 # Gibt ein *neues* Objekt mit der Summe zurück: def __add__(self, that): return Vector(self.x + that.x, self.y + that.y, self.z + that.z) 14 15 16 17 18 19 20 # Entspricht Self * That: def __mul__(self, that): if type(that) is int: return Vector(self.x * that, self.y * that, self.z * that) 21 22 23 24 # Entspricht That * Self: def __rmul__(self, that): return self.__mul__(that) 25 26 27 28 29 # Wird von ’print’ aufgerufen: def __repr__(self): x, y, z = self.x, self.y, self.z return "({0}, {1}, {2})".format(x, y, z) 30 31 32 33 v1 = Vector(1, 2, 3) v2 = Vector(2, -3) print v1 + v2 * 2 AUFGABEN 17. Ergänze die Vektor-Klasse um die Methode __sub__ und eine Me- thode dotP für das Skalarprodukt. 18. Schreibe eine Klasse Fraction, die einen Bruch darstellt und im- plementiere die vier Grundrechenarten +, -, * und / (über die Methode __truediv__). c 2015, J. Arnold, M. Guggisberg, T. Kohn, A. Plüss