[Im Aufbau] benchmark.py
benchmark.py v1.0.2 beta: http://lodgeit.lucumr.pocoo.org/show/79/
Bin fertig. Sollte jetzt alles den Richtlinien von PEP8 entsprechen.
GetRanking gibts nun nicht mehr. Hab das so gelöst: Nach dem in run() die Laufzeit untersucht wurde, wird danach das ranking erzeugt und in self.ranking gespeichert. Damit spare ich mir nen Gettert self.ranking ist ein list von dicts => [{}, {}, ...]
print_ranking() gibt das ranking aus. Falls aber run() nicht ausgeführt wurde und gleich print_ranking() benutzt wird, wird eine Exception ausgelöst, die auf den Fehler hinweist. Ist mMn gut gelöst, weil stattdessen ein IndexError ausgelöst werden würde, da ja self.ranking ohne run() leer bleibt benchmark.py ist aber gut dokumentiert und die main() wurde um alle möglichen Beispielen erweitert.
@Leo: Habe alles nach deinen Vorschlägen geändert bis auf folgendes:
Das spielt ja aber auch keine rolle, da es intern ist (und nur temporär) und nachher alles als list von dicts in self.ranking gespeichert wird => [{}, {}, …].
lg
Bin fertig. Sollte jetzt alles den Richtlinien von PEP8 entsprechen.
GetRanking gibts nun nicht mehr. Hab das so gelöst: Nach dem in run() die Laufzeit untersucht wurde, wird danach das ranking erzeugt und in self.ranking gespeichert. Damit spare ich mir nen Gettert self.ranking ist ein list von dicts => [{}, {}, ...]
print_ranking() gibt das ranking aus. Falls aber run() nicht ausgeführt wurde und gleich print_ranking() benutzt wird, wird eine Exception ausgelöst, die auf den Fehler hinweist. Ist mMn gut gelöst, weil stattdessen ein IndexError ausgelöst werden würde, da ja self.ranking ohne run() leer bleibt benchmark.py ist aber gut dokumentiert und die main() wurde um alle möglichen Beispielen erweitert.
@Leo: Habe alles nach deinen Vorschlägen geändert bis auf folgendes:
Hier kann ich nicht die Datenstruktur ändern. Das ganze basisiert darauf dass alles in die Liste gepusht wird, und danach die liste nach der Zeit (die sich jeweils auf Index 0 befindet) sortiert wird. Wenn ich nun ein dict machen würde dann würde es nur nach den Key sortiert und daher unbrauchbar. Hab das getestet und daher mache ich das so => [[], [], []]Zeile 154: self._data[0][0], [0][0] sieht sehr nichtssagend aus, vielleicht kann an hier eine andere Datenstruktur verwenden? Zum Beipiel ein Dict, mit einer Listen innen drin, oder sowas ähnliches?
Das spielt ja aber auch keine rolle, da es intern ist (und nur temporär) und nachher alles als list von dicts in self.ranking gespeichert wird => [{}, {}, …].
lg
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
IMHO sind die eigenen Fehlerklassen unnötig!
Warum nicht an der stelle einen normalen ValueError werfen? Dann kann man sich die eigenen Fehler-Klassen Zeile 39-51 komplett sparen. Ich würde es so machen:
Ein del(bench) vor einem bench = Benchmark() ist überflüssig. Zeile 207 und 218
Code: Alles auswählen
def print_ranking(self):
"""Diese Methode zeigt das Ranking an stdout an."""
if not self.ranking:
raise NoValueError("Das Attribut ranking von %s enthaelt keine"
" Daten!\n"
"Folgende Methode/Funktion hat die"
" Exception ausgeloest: %s"
% (self, self.print_ranking)
)
Code: Alles auswählen
def print_ranking(self):
"""Diese Methode zeigt das Ranking an stdout an."""
if not self.ranking:
raise ValueError(
"Keine Daten vorhanden,"
" da Benchmark noch nicht ausgeführt wurde!"
)
Hier die neue version: http://paste.pocoo.org/show/82/
diff: http://paste.pocoo.org/compare/81/
P.S.: Die docstring muss ich noch anpassen für die exceptions. Ging jetzt nicht auf die schnelle.
----
Ne, das sehe ich anders. Es geht ja gerade um die Differenzierung von Fehlern.
Hier ein Beispiel (Hab die Klasse erweitert):
angenommen wir übergeben statt einer Funktion eine Variable als Referenz…
…dann kommt folgender traceback beim ausführen von add_function() der nichts sagend ist und wohlmöglich als Unterstellung genutzt werden könnte, das man keine richtige Fehlerüberprüfung implementiert hat (zu recht!)-->
So, nun implementiere ich in add_function eine Überprüfung:
Nun der gleiche aufruf:
Traceback:
Das ist schon viel aussagekräftiger
Genauso verhält es sich mit ValueError, das kein Bestandteil des Moduls ist. Warum so was benutzen, wenn es doch transparenter geht in dem ich dafür eine Eigene Exception definiere? Was passiert wenn irgendwas anderes im Try Block einen ValueError auslöst, das nichts mit meine Modul zu tun hat? Dann würde ich das wohl möglich abfangen und eine total falsche Fehlerbehandlung machen Weist du was ich meine? Dan lieber eine eigen Exception die dafür sorgt das _nur_ die exceptions, im _pasenden_ except-block, abgefangen werden die von _meinen_ Modul ausgelöst werden.
Außerdem, geht es doch darum das man für jeden Fehler eine eigene passende Fehlerbehandlung macht. Das ist aber nicht möglich wen ich eine fremde Exception benutze, die mit meinem Modul nichts zu tun hat und dann auf einmal ne exception von irgendwo anders kommt und im gleichen except_block abgefangen werden, wo sie aber _nicht_ abgefangen werden dürfen!
EDIT: im main() ist ein Beispiel.
diff: http://paste.pocoo.org/compare/81/
P.S.: Die docstring muss ich noch anpassen für die exceptions. Ging jetzt nicht auf die schnelle.
----
Ne, das sehe ich anders. Es geht ja gerade um die Differenzierung von Fehlern.
Hier ein Beispiel (Hab die Klasse erweitert):
angenommen wir übergeben statt einer Funktion eine Variable als Referenz…
Code: Alles auswählen
a = 0
bench = Benchmark()
bench.add_function(a, "LC", loops)
[…]
Code: Alles auswählen
self._functions.append([ref.__name__, comment, ref, args])
AttributeError: 'int' object has no attribute '__name__'
Code: Alles auswählen
if str(type(ref)) != "<type 'function'>":
raise WrongArgumentError("Das uebergeben Argument an ref ist "
"keine Referenz auf eine Funktion!")
Code: Alles auswählen
a = 0
bench = Benchmark()
bench.add_function(a, "LC", loops)
[…]
Code: Alles auswählen
raise WrongArgumentError("Das uebergeben Argument an ref ist "
__main__.WrongArgumentError: Das uebergeben Argument an ref ist keine Referenz auf eine Funktion!
Genauso verhält es sich mit ValueError, das kein Bestandteil des Moduls ist. Warum so was benutzen, wenn es doch transparenter geht in dem ich dafür eine Eigene Exception definiere? Was passiert wenn irgendwas anderes im Try Block einen ValueError auslöst, das nichts mit meine Modul zu tun hat? Dann würde ich das wohl möglich abfangen und eine total falsche Fehlerbehandlung machen Weist du was ich meine? Dan lieber eine eigen Exception die dafür sorgt das _nur_ die exceptions, im _pasenden_ except-block, abgefangen werden die von _meinen_ Modul ausgelöst werden.
Außerdem, geht es doch darum das man für jeden Fehler eine eigene passende Fehlerbehandlung macht. Das ist aber nicht möglich wen ich eine fremde Exception benutze, die mit meinem Modul nichts zu tun hat und dann auf einmal ne exception von irgendwo anders kommt und im gleichen except_block abgefangen werden, wo sie aber _nicht_ abgefangen werden dürfen!
EDIT: im main() ist ein Beispiel.
Es ist nicht garantiert das die Zeichenkette vom Funktionstyp immer so aussieht und Du verhinderst damit das etwas anderes als Funktionen übergeben wird. Methoden werden zurückgewiesen und auch Objekte die `__call__()` implementieren. Beides unnötige Einschränkungen. Versuchs mal mit:XtraNine hat geschrieben:So, nun implementiere ich in add_function eine Überprüfung:Code: Alles auswählen
if str(type(ref)) != "<type 'function'>": raise WrongArgumentError("Das uebergeben Argument an ref ist " "keine Referenz auf eine Funktion!")
Code: Alles auswählen
if not callable(ref):
raise TypeError('ref is not callable')
104beta - http://paste.pocoo.org/show/83/
...
@jens: OK, hab das durch ValueError ersetzt. Dan darf man halt nicht alles in einen Try-Block packen...Ist vielleicht auch pythonischer wenn man nicht alles in einem Try-Block drin hat.
@BlackJack:
Hab ich hinzugefügt. Hab auch das TypeError zum raisen genommen.
Ich weiß das es ein wenig OT ist: Wie viel sollte man eigentlich überprüfen? Ich denke mit ref sollte das noch ok sein, damit nicht der traceback…
…abgezeigt wird, sondern ein eigener. Obwohl eigentlich der Benutzter selber dafür sorge tragen sollte das er die Klasse/Methode richtig benutzt.
Das bringt mich dann auf die frage: Wie viel sollte man selber schon als Fehlerüberprüfung für Argumente oder den Inhalt der Argumente implementieren? Wer trägt eigentlich die Verantwortung? -> Der jenige der die Klasse schreibt und es nach _seinen vorgaben_ 100%ig funktioniert oder der Jenige der die Klasse nach _abweichenden vorgaben_ benutzt und somit Fehler produziert. Sollte man für letzteres trotzdem eine eigene Fehlermeldung ausgegeben werden oder sollte man so stur sein und sich denken "Verdammt noch mal benutzt die Klasse so wie ich sie beschreiben habe und RTFM!"
Wie sieht ihr das Thema? Ich persönlich würde ja für jede mögliche Unwägbarkeit ne eigen exception auslösen, damit der Benutzer bei Falscher Benutzung einen Feedback erhält. Oder sollte ich mich da von dem C++ Dogma gänzlich lösen. Was ist Pythonischer?
Auch das Thema keine eigenen Exception Klassen zu implementiere, sonder schon passende vorhanden zu nutzen (wie im Beispiel mit ValueError und TypeError) hat mich ein wenig verunsichert.
lg
Edit (Leonidas): Thread kann aufgrund von Softwarebugs leider an dieser Stelle nicht mehr weitergeführt werden (daher geschlossen), dafür bitte den neuen Thread verwenden. Sorry für die Unbequemlichkeiten.
...
@jens: OK, hab das durch ValueError ersetzt. Dan darf man halt nicht alles in einen Try-Block packen...Ist vielleicht auch pythonischer wenn man nicht alles in einem Try-Block drin hat.
@BlackJack:
Hab ich hinzugefügt. Hab auch das TypeError zum raisen genommen.
Ich weiß das es ein wenig OT ist: Wie viel sollte man eigentlich überprüfen? Ich denke mit ref sollte das noch ok sein, damit nicht der traceback…
Code: Alles auswählen
self._functions.append([ref.__name__, comment, ref, args])
AttributeError: 'int' object has no attribute '__name__'
Das bringt mich dann auf die frage: Wie viel sollte man selber schon als Fehlerüberprüfung für Argumente oder den Inhalt der Argumente implementieren? Wer trägt eigentlich die Verantwortung? -> Der jenige der die Klasse schreibt und es nach _seinen vorgaben_ 100%ig funktioniert oder der Jenige der die Klasse nach _abweichenden vorgaben_ benutzt und somit Fehler produziert. Sollte man für letzteres trotzdem eine eigene Fehlermeldung ausgegeben werden oder sollte man so stur sein und sich denken "Verdammt noch mal benutzt die Klasse so wie ich sie beschreiben habe und RTFM!"
Wie sieht ihr das Thema? Ich persönlich würde ja für jede mögliche Unwägbarkeit ne eigen exception auslösen, damit der Benutzer bei Falscher Benutzung einen Feedback erhält. Oder sollte ich mich da von dem C++ Dogma gänzlich lösen. Was ist Pythonischer?
Auch das Thema keine eigenen Exception Klassen zu implementiere, sonder schon passende vorhanden zu nutzen (wie im Beispiel mit ValueError und TypeError) hat mich ein wenig verunsichert.
lg
Edit (Leonidas): Thread kann aufgrund von Softwarebugs leider an dieser Stelle nicht mehr weitergeführt werden (daher geschlossen), dafür bitte den neuen Thread verwenden. Sorry für die Unbequemlichkeiten.