Fibonacci fehlerhafter Doctest

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Monty Cobra
User
Beiträge: 9
Registriert: Donnerstag 12. Mai 2016, 17:56

Hallo. Ich versuche gerade doctests für eine Fibonacci-Funktion zu schreiben,fehlerhafte, um entsprechend eine Fehlerausgabe zu erhalten.

Code: Alles auswählen

import doctest

def fibdoc3(n):
    """ 
    
    >>> fibdoc3(1)==1
    True
    
    >>> 

    """
    if n<1:
        return n
       
    else:
        return fibdoc3(n-1)+fibdoc3(n-2)
    

if __name__ == "__main__": 
    doctest.testmod()
Das wäre soweit mein Doctest.
Möchte ich aber den Test ausführen ,bekomme ich nur Fehlermeldungen.
Die Fibonacci-Funktion läuft, ich habe sie schon separat getestet und doctest würde sich grundsätzlich auch importieren lassen.

Code: Alles auswählen

>>> import fibdoc3
>>>doctest.testmod()
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    doctest.testmod()
NameError: name 'doctest' is not defined

>>>doctest.testmod(verbose=True)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    doctest.testmod(verbose=True)
NameError: name 'doctest' is not defined
Was mache ich falsch?
BlackJack

@Monty Cobra: Du versuchst auf `doctest` zuzugreifen ohne es importiert zu haben.

So wie Du das Modul geschrieben hast, solltest Du es nicht importieren sondern als Programm ausführen. Also ausserhalb der Python-Shell.
Monty Cobra
User
Beiträge: 9
Registriert: Donnerstag 12. Mai 2016, 17:56

Erstmal danke für die rasche Antwort.
BlackJack hat geschrieben:@Monty Cobra: Du versuchst auf `doctest` zuzugreifen ohne es importiert zu haben.
Reicht es denn nicht aus das der Import von Doctest Teil des Programms ist? Aber auch wenn ich das separat importiere klappt es bei mir nicht so ganz.

Code: Alles auswählen

>>> import doctest
>>> import fibdoc3
>>>doctest.testmod()
TestResults(failed=0, attempted=0)
>>> doctest.testmod(verbose=True)
1 items had no tests:
    __main__
0 tests in 1 items.
0 passed and 0 failed.
Test passed.
TestResults(failed=0, attempted=0)
BlackJack hat geschrieben:So wie Du das Modul geschrieben hast, solltest Du es nicht importieren sondern als Programm ausführen. Also ausserhalb der Python-Shell.
Ich ging davon aus das das die gängigste Variante des Doctest ist. Mit Programm ausführen meinst du die (in meinem Falle) Eingabeaufforderungskonsole von Windows?
BlackJack

@Monty Cobra: Du erwartest da ein ganz klein wenig zu viel Magie von Python. Natürlich hast Du nicht auf magische Weise alle Namen in der Python-Shell nur weil Du ein Modul importiert hast. Das funktioniert dort genau so wie in Modulen. Würden die Namen automatisch implizit zusätzlich importiert würde das auch ganz schnell zu einem sehr unübersichtlichen Chaos ausarten wenn Du ein paar Module importierst. Das hast Du lauter Namen wo Du wissen müsstest wo die herkommen und früher oder später auch Kollisionen weil es Module gibt die gleiche Namen für unterschiedliche Dinge definieren. Das ist ja gerade der Zweck von Modularisierung, dass man Namensräume schafft die voneinander getrennt sind, so dass man sich keine Gedanken machen muss ob irgendein anderes Modul vielleicht den gleichen Namen für einen Wert verwendet.

`doctest.testmod()` macht dann tatsächlich ein bisschen Voodoo, allerdings auch wieder nicht so viel wie Du erwartest. Wenn man dort nicht angibt *welches* Modul getestet werden soll, dann wird das Modul getestet von dem aus die Funktion aufgerufen wird. Also in Deinem Fall das Modul in dem die REPL von der Python-Shell ausgeführt wird und das `__main__` heisst. Dort sind zu dem Zeitpunkt bei Dir offenbar keine Objekte mit Doctests vorhanden.

Ja, mit Programm ausführen meine ich das Modul zum Beispiel in einer Betriebssystemshell als Programm auszuführen. Dafür ist ja das ``if __name__ = '__main__':`` da. Und das ist in der Tat nicht unüblich in Module die keine eigenständigen Programme sind, Testcode auf diese Weise zu integrieren. Der Docstring vom `doctest`-Modul enthält da ein Beispiel. Wobei man bei grösseren Projekten dann eher etwas verwendet was die ganzen Module nach Testfällen absucht, statt jedes einzelne Modul als Programm zu starten um die Tests auszuführen. `nose` und `py.test` sind da zum Beispiel Kandidaten die (AFAIK) beide auch Doctests mit erfassen können.

Ansonsten ist auch das Doctest-Modul selber als Programm ausführbar, Beispielsweise über ``python -m doctest``. Damit kann man sowohl Python-Module als auch beliebige Textdateien verarbeiten.
Monty Cobra
User
Beiträge: 9
Registriert: Donnerstag 12. Mai 2016, 17:56

Hm das klingt logisch, ich hatte das wohl falsch im Kopf behalten. Ich muss also auf jeden Fall separat doctest importieren. Wegen testmod,ach so, ja, jetzt klappt das ganze wie gewünscht. Danke dir für deine Hilfe.
Antworten