Programmieren im Unterricht mit Python

Werbung
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
Herunterladen