Ein Baustein für Primzahltests
Verhaltensbeschreibung
Ziel ist es weiterhin, eine Funktion zu entwickeln, mit der man natürliche Zahlen daraufhin überprüfen kann, ob sie Primzahlen sind oder nicht.
Die Funktion istPrimzahl
verarbeitet eine Zahl vom Typ int
(d.h. eine ganze Zahl)
und liefert als Ergebnis einen Wert vom Typ bool
(d.h. einen der beiden Wahrheitswerte
True
oder False
) zurück.
Ein erster Implementierungsversuch
Hier eine Implementierung zu einem der Primzahltestalgorithmen aus dem letzten Abschnitt.
def istPrimzahl(n):
prim = True
k = 2
while k*k <= n and prim:
if n % k == 0:
prim = False
k = k+1
return prim
Aufgabe 1
Teste die Funktion mit mehreren Testaufrufen. Ist alles ok?
>>> istPrimzahl(13)
True
>>> istPrimzahl(15)
...
>>> istPrimzahl(7)
...
>>> istPrimzahl(551)
...
>>> istPrimzahl(2)
...
>>> istPrimzahl(1)
...
>>> istPrimzahl(0)
...
Eine Implementierung mit Testfällen
Eine implementierte Funktion sollte immer gründlich getestet werden. Meist reicht dazu nicht nur ein Testfall. Vielmehr muss man unterschiedlichste Situationen mit Testfällen abdecken. Hierzu zählen insbesondere die Randfälle.
Beim Testen kommt es darauf an , die Erwartungen, die man an eine Funktion hat, mit dem tatsächlichen Verhalten abzugleichen. Eine gute Strategie ist es, die Erwartungen vorab schon einmal zu dokumentieren.
Python bietet eine Möglichkeit, Verhaltensbeschreibungen in Form von Testfällen in die Implementierung von Funktionen zu integrieren und diese Testfälle dann automatisiert zu überprüfen. Mehr über dieses Thema findest du im Abschnitt Verhalten beschreiben und testen.
def istPrimzahl(n):
"""
Verhalten:
Übergabe: natürliche Zahl n
Rückgabe: True, falls n eine Primzahl ist
False, sonst
Testfälle:
>>> istPrimzahl(13)
True
>>> istPrimzahl(15)
False
>>> istPrimzahl(7)
True
>>> istPrimzahl(551)
False
>>> istPrimzahl(2)
True
>>> istPrimzahl(1)
False
>>> istPrimzahl(0)
False
"""
prim = True
k = 2
while k*k <= n and prim:
if n % k == 0:
prim = False
k = k+1
return prim
if __name__ == "__main__":
from doctest import testmod
testmod(verbose=True)
Wenn man diese Funktionsdefinition ausführt, dann werden die Testfälle überprüft und man erhält genaue Rückmeldungen.
>>>
Trying:
istPrimzahl(13)
Expecting:
True
ok
Trying:
istPrimzahl(15)
Expecting:
False
ok
Trying:
istPrimzahl(7)
Expecting:
True
ok
Trying:
istPrimzahl(551)
Expecting:
False
ok
Trying:
istPrimzahl(2)
Expecting:
True
ok
Trying:
istPrimzahl(1)
Expecting:
False
**********************************************************************
File "...", line 19, in __main__.istPrimzahl
Failed example:
istPrimzahl(1)
Expected:
False
Got:
True
Trying:
istPrimzahl(0)
Expecting:
False
**********************************************************************
File "...", line 21, in __main__.istPrimzahl
Failed example:
istPrimzahl(0)
Expected:
False
Got:
True
1 items had no tests:
__main__
**********************************************************************
1 items had failures:
2 of 7 in __main__.istPrimzahl
7 tests in 2 items.
5 passed and 2 failed.
***Test Failed*** 2 failures.
Aufgabe 2
(a) Probiere das selbst aus. Wie sind die Rückmeldungen von Python zu deuten?
(b) Verbessere die Funktionsdefinition so, dass alle Testfälle den Test bestehen. Tipp: Du musst zu Beginn eine zusätzliche Fallunterscheidung vorsehen.
Verwendung einer Funktion als Bausteins
Eine gut getestete Funktionsdefinition kann man bei weiterführenden Problemlösungen als Baustein verwenden. Hier ein Beispiel, bei dem überprüft werden soll, ob ein Primzahlzwilling vorliegt.
Der Funktionsbaustein wird hier mit einer import
-Anweisung in das Programm integriert.
Die importierte Funktion istPrimzahl
befindet sich hier in der Datei primzahltest.py
.
from primzahltest import istPrimzahl
def istPrimzahlzwilling(n):
"""
Verhalten:
Übergabe: natürliche Zahl n
Rückgabe: True, falls n und n+2 eine Primzahl ist
False, sonst
Testfälle:
>>> istPrimzahlzwilling(11)
True
>>> istPrimzahlzwilling(13)
False
>>> istPrimzahlzwilling(15)
False
"""
if istPrimzahl(n):
if istPrimzahl(n+2):
ergebnis = True
else:
ergebnis = False
else:
ergebnis = False
return ergebnis
if __name__ == "__main__":
from doctest import testmod
testmod(verbose=True)
Aufgabe 3
(a) Teste selbst, indem du die Funktionsdefinition ausführst.
(b) Die geschachtelte Fallunterscheidung kann man vermeiden, wenn man einen logischen Operator benutzt. Informiere dich im Abschnitt Wahrheitswerte und Bedingungen über logische Operatoren.
Aufgabe 4
Entwickle eine Funktionsdefinition für eine Funktion naechstePrimzahl
.
Benutze die Funktion istPrimzahl
als Baustein.
from primzahltest import istPrimzahl
def naechstePrimzahl(n):
"""
Verhalten:
Übergabe: natürliche Zahl n
Rückgabe: die nächste Primzahl, die größer oder gleich n ist
Testfälle:
>>> naechstePrimzahl(5)
5
>>> naechstePrimzahl(20)
23
>>> naechstePrimzahl(0)
2
"""
...
if __name__ == "__main__":
from doctest import testmod
testmod(verbose=True)