Freitag, 3. Dezember 2010
Musterlösung zu Übungsbeispiele für Python vom 1.12.2010 (POS1: 1BHIF)
Prüfen, ob durch die Angabe dreier Längen ein Dreieck gegeben ist.
Zwei Seiten müssen immer länger als die dritte sein. Man muss dies für alle Möglichkeiten prüfen, denn z.B.
a = 3, b = 4, c = 1
Da stimmt zwar a + b > c (7 > 1) und b + c > a (4 > 3), jedoch nicht a + c > b (4 == 4)!
Bei der Lösung wird eine Schleife verwendet.
False leifern muss und wenn
Hier ist zu
Zwei Seiten müssen immer länger als die dritte sein. Man muss dies für alle Möglichkeiten prüfen, denn z.B.
a = 3, b = 4, c = 1
Da stimmt zwar a + b > c (7 > 1) und b + c > a (4 > 3), jedoch nicht a + c > b (4 == 4)!
Bei der Lösung wird eine Schleife verwendet.
def ist_dreieck(a, b, c): """liefert True, wenn durch a, b und c ein gültiges Dreieck definiert ist""" i = 3 while i > 0: if a + b <= c: return False # kein Dreieck a, b, c = b, c, a i = i - 1 return TrueMan könnte das Problem natürlich auch durch logische Verknüpfung der Prüfungen lösen:
def ist_dreieck(a, b, c): """liefert True, wenn durch a, b und c ein gültiges Dreieck definiert ist""" if a + b > c and b + c > a and c + a > b: ret = True else: ret = False return retOder gleich so:
def ist_dreieck(a, b, c): """liefert True, wenn durch a, b und c ein gültiges Dreieck definiert ist""" return a + b > c and b + c > a and c + a > bBei der zweiten Aufgabe soll geprüft werden, ob durch zwei Seiten und einem Winkel ein Quadrat gegeben ist. Die beiden Seiten müssen gleich lang sein (und größer 0) und der Winkel 90°:
def ist_quadrat(a, b, w): """liefert True, wenn durch a und b sowie dem Winkel w ein Quadrat definiert ist""" quadrat = False if a > 0: if a == b: if w == 90: quadrat = True # else entfällt, da die Variable quadrat schon mit False vorbelegt ist. return quadratOder wieder kürzer mit logischer Verknüpfung:
def ist_quadrat(a, b, w): """liefert True, wenn durch a und b sowie dem Winkel w ein Quadrat definiert ist""" return a == b and w == 90 and a > 0Die Schaltjahrprüfung könnte so erfolgen:
def ist_schaltjahr(jahr): """liefert True, wenn das gegebene Jahr ein Schaltjahr ist. Seit Ende 1582 gilt der Gregorianische Kalender, bei dem folgende Regel für die Schaltjahrbestimmung anzuwenden sind: In allen Jahren, deren Jahreszahl durch vier teilbar ist, ist der 29. Februar ein Schalttag und damit ist dieses Jahr ein Schaltjahr. Eine Ausnahme bilden allerdings die vollen Jahrhundertjahre 1700, 1800, 1900 usw., auch Säkularjahre genannt. Hiervon erhalten nur diejenigen einen Schalttag, deren Jahreszahl durch 400 teilbar ist. Jedes vierte Säkularjahr ist somit ein Schaltjahr. Für alle Jahre <= 1582 liefert die Funktion False, weil da das Schaltjahr nicht definiert ist, sonst gilt obige Regel.""" if jahr <= 1582: schaltjahr = False elif jahr % 400 == 0: schaltjahr = True elif jahr % 100 == 0: schaltjahr = False elif jahr % 4 == 0: schaltjahr = True else: schaltjahr = False return schaltjahrJahre bis 1582 können keine Schaltjahre sein, da der Gregorianische Kalender erst im Jahr 1582 definiert wurde. Zum Test der Schaltjahrprüfung noch ein paar Worte, aber zunächst die Testfunktion, die ein paar Jahreszahlen prüft, von denen man weiß, dass sie kein Schaltjahr sind sowie Zahlen, bei denen bekannt ist, dass sie Schaltjahre sind:
def test_ist_schaltjahr(): for jahr in (1000, 1580, 1581, 1582, 1900, 1999, 2003): assert not ist_schaltjahr(jahr) for jahr in (1996, 2000, 2004): assert ist_schaltjahr(jahr) print("ist_schaltjahr ok")Die Anweisung
assert
ist für Programmierer und dient zum Prüfen der Bedingung, die gleich dahinter folgt, gedacht. Zum Beispiel: assert 3 < 4Die Bedingung ist wahr, daher läuft das Programm weiter. Ist die Bedingung hingegen falsch, so wird das Programm mit einer Fehlermeldung abgebrochen:
>>> assert 3 > 4 Traceback (most recent call last): File "Zusätzlich kann ein Text als Fehlermeldung angegeben werden:", line 1, in assert 3 > 4 AssertionError
>>> assert 3 > 4, "3 ist nicht größer als 4" Traceback (most recent call last): File "Angewendet auf obige Testfunktion bedeutet das, dass immer, wenn", line 1, in assert 3 > 4, "3 ist nicht größer als 4" AssertionError: 3 ist nicht größer als 4
assert not ist_schaltjahr(jahr)
die Funktion ist_schaltjahr(jahr)
den Wert assert ist_schaltjahr(jahr)
steht, True
geleifert werden muss, damit das Programm nicht abgebrochen wird. Der nächste Punkt ist die for jahr in (1000, 1580, 1581, 1582, 1900, 1999, 2003):
-Zeile. Die Variable jahr
bekommt der Reihe nach die Werte 1000, 1580, 1581, 1582, 1900, 1999, 2003 und der eingerückte Code-Block (die eine Zeile) wird ausgeführt. Das ist die for
-Schleife, welche im Buch im Kapitel 7 auch erklärt wird. Die Funktion test_ist_schaltjahr()
prüft also zunächst ein paar Jahre, die kein Schaltjahr sind und ein paar Schaltjahre. Die Fibonaccizahlen können wie folgt ermittelt werden: def fib(n): """liefert die Fibonaccizahl zu n. Die Zahlen sind wie definiert: fib(0) -> 0 fib(1) -> 1 fib(2) -> 1 fib(3) -> 2 fib(4) -> 3 fib(5) -> 5 fib(6) -> 8 ... fib(10) -> 55 ... fib(15) -> 610""" f = 0 a = 0 b = 1 i = 0 while i < n: f = a + b b, a = a, f i += 1 return fFür n = 0 und n = 1 sind die (Anfangs-)Werte vordefiniert.
fib(0) = 0
und fib(1) = 1
. Danach gilt die Regel, dass die n. Fibonaccizahl die Summe der beiden Vorgänger ist, also fib(n - 1) + fib(n - 2)
(Siehe dazu auch Wikipedia: Fibonacci-Folge). Die Variable f
hat immer den Wert der aktuellen Fibonaccizahl und ist daher mit 0 initialisiert. Die Variable a und b haben immer den Wert der beiden Vorgänger. Sie können das leicht sehen, wenn Sie print(...)
-Anweisungen einfügen und sich dadurch den Ablauf der Berechnung anzeigen lassen: def fib(n): """liefert die Fibonaccizahl zu n.""" f = 0 a = 0 b = 1 i = 0 while i < n: f = a + b print(i, ": f =", f, "a =", a, "b =", b) # Testausgabe b, a = a, f i += 1 return f print(fib(10))..gibt dann folgendes aus:
0 : f = 1 a = 0 b = 1 1 : f = 1 a = 1 b = 0 2 : f = 2 a = 1 b = 1 3 : f = 3 a = 2 b = 1 4 : f = 5 a = 3 b = 2 5 : f = 8 a = 5 b = 3 6 : f = 13 a = 8 b = 5 7 : f = 21 a = 13 b = 8 8 : f = 34 a = 21 b = 13 9 : f = 55 a = 34 b = 21 55Die Ausgabe einer Tabelle mithilfe der Funktion
fib()
ist einfach (oder doch etwas kompliziert, weil die eckigen Klammern dazukommen): def fibtab(n): """erzeugt eine Tabelle der Fibonaccizahlen bis inclusive n. z.B. gibt fibtab(10) folgendes aus: [0, 1, 1, 2, 3, 5, 8] oder fibtab(100): [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] Hinweis: verwenden Sie als Zeilenumbruch ", " beim print, also print(wert, end=', ') außer natürlich beim letzten Wert, hier ist "]" gefordert. """ i = 0 print("[", end = "") f = fib(i) while f <= n: print(f, end = "") i += 1 f = fib(i) if f > n: print("]") else: print(", ", end = "")Wir müssen sicherstellen, dass zunächst
"["
ohne Zeilenumbruch ausgegeben wird. Die Funktion print(...)
hat einen optionalen Parameter end
, der angibt, was zum Schluss ausgegeben werden soll. Standardmäßig ist das "\n"
, was einen Zeilenumbruch bewirkt. Setzt man den Wert end = ""
, so wird ein Leerstring, also nichts, ausgegeben. In der Schleife muss man noch prüfen, ob man das Ende erreicht hat und in diesem Fall "]"
(mit Zeilenumbruch) ausgibt. Im Normalfall wird ein Komma ohne Zeilenumbruch ausgegeben (letzte Zeile). Beachten Sie, dass der Parameter n
hier die Grenze der Fibonaccizahl angibt und nicht die wievielte (wie bei fib(n)
). Die Lösung zum Beispiel, die Summe der Vielfachen von 3 und 5 kleiner als ein Maximum: def sum_3_5(max): """ bilde Summe der Vielfachen von 3 und 5 kleiner als max. Beispielsweise liefert sum_3_5(10) 23, weil die Vielfachen von 3 < 10 sind 3 + 6 + 9 = 18 die Vielfachen von 5 < 10 sind 5 18 + 5 = 23 sum_3_5(20) liefert 78, weil 3+ 6+9+ 12+15+18=63 5+ 10+ =15 (15 ist in obiger Liste schon enthalten!) sum_3_5(25) liefert 143, weil 3+ 6+9+ 12+ 18+ 21+24=93 (Vielfache von 5 stehen darunter) 5+ 10+ 15+ 20 =50 sum_3_5(100) liefert 2318 (ohne Beweis) """ summe = 0 i = 0 while i < max: if i % 5 == 0: summe += i elif i % 3 == 0: summe += i i += 1 return summeDie Laufvariable
i
wird immer dann zur summe
dazugezählt, wenn sie durch 5 teilbar ist oder wenn sie durch 3 teilbar ist. Der Operator %
berechnet den Rest der Division. Ist der Rest 0, so ist die erste durch die zweite Zahl teilbar. Das Beispiel zum finden des nächstkleineren bzw. gleichen Quadrats kann so mit einer Probiermethode gelöst werden: def minquad(zahl): """finde die nächstkleinere oder gleichgroße ganze Zahl, die eine Quadratzahl ist. Beispiele: minquad(16) -> 16 (weil 4 * 4 = 16 <= 16) minquad(24) -> 24 (weil 4 * 4 = 16 <= 14) minquad(25) -> 25 (weil 5 * 5 = 25 <= 25) minquad(26) -> 25 (weil 5 * 5 = 25 <= 26) """ i = 0 mq = 0 while i ** 2 <= zahl: mq = i ** 2 i += 1 return mq
i ** 2
bedeutet i2. Man könnte natürlich auch i * i
schreiben. Diese Funktion prüft einfach sukzessive alle Quadrate, bis eines gefunden wurde, das größer als die gegebene Zahl ist. Der Wert davor (die Variable mq
) ist natürlich das Ergebnis, weil das der größte Wert war, für den die Bedingung gilt. Es geht natürlich schneller und einfacher, wenn man sich eine Formel überlegt: from math import sqrt from math import floor def minquad(zahl): """finde die nächstkleinere oder gleichgroße ganze Zahl, die eine Quadratzahl ist. Beispiele: minquad(16) -> 16 (weil 4 * 4 = 16 <= 16) minquad(24) -> 16 (weil 4 * 4 = 16 <= 24) minquad(25) -> 25 (weil 5 * 5 = 25 <= 25) minquad(26) -> 25 (weil 5 * 5 = 25 <= 26) """ return int(floor(sqrt(zahl))) ** 2Die Funktion
floor(x)
liefert die nächstkleinere ganze Zahl zu x (bei positiven Zahlen schneidet dir Funktion die Nachkommastellen der übergebenen Zahl ab). Z.B: >>> from math import floor >>> floor(3.14) 3 >>> floor(3) 3 >>> floor(-3.14) -4Wenn man die nächstkleinere ganze Zahl der Wurzel quadriert, hat man das gewünschte Ergebnis. Die Turtle-Funktion zum Dreieckzeichnen könnte wie folgt aussehen und braucht nicht weiter erklärt werden:
def dreieck(a, w): """zeichnet ein gleichseitiges Dreieck der Seitenlänge a, gedreht um den Winkel w. w = 0 bedeutet, dass die eine Seite horizional ist. w = 90 bedeutet, dass das Dreieck nach LINKS um 90° gedreht ist, d.h. eine Seite ist vertikal. Das Dreieck soll rechts neben des angegebenen Punktes gezeichnet werden. """ # nehme an Turtle sieht nach oben (wie auch beim Starten) right(90 - w) pendown() for i in range(3): forward(a) left(120) penup() left(90 - w)Um ein Dreieck an eine bestimmte Position zu setzen, kann zusätzlich die Funktion
setpos(x, y)
, welche die Turtle an die Postion x,y setzt, verwendet werden: def dreieck_an_pos(a, w, x, y): """zeichnet ein Dreieck mit Hilfe der Funktion dreieck(a, w) an der Position x, y.""" penup() setpos(x, y) dreieck(a, w)Abgesehen von den Turtle-Funktionen können Sie die Funktionen direkt auf der Website http://codepad.org testen. Dort können Sie auch andere Programmiersprachen probieren. Die Python-Version ist leider nicht aktuell, daher könnte es sein, dass einiges doch nicht direkt so funktioniert. Diese einfachen Beispiele funktionieren aber.
Hier ist zu
minquad(zahl)
zu sehen:Labels: Lösung, POS1-1, Python
Abonnieren Posts [Atom]
Kommentar veröffentlichen