Modul programmieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Hi,

ich programmiere gerade ein Modul, das mir verschiedene Tools bereitstellt. Dabei ergeben sich für mich einige Fragen, wie die optimale Lösung aussehen könnte:

(1) Besser separate Funktionen oder besser statische Methoden als Teil einer Klasse?

Ich kann beides, aktuell habe ich da nur Funktionen reingepackt, so dass ich im Kern etwa folgendes mache:

Code: Alles auswählen

from modul import function
Macht es Sinn oder würde man produktiv besser auf statische Methoden wechseln? Irgendeine Erfahrung, gibt es eine Standardlösung für die Frage oder wird es später Vor- oder Nachteile je nach Lösung geben?

(2) Ich nutze die Funktionen für meine Aufgaben und habe erst einmal nicht an eine Weitergabe gedacht; u. a. berechne ich den Durchschnitt und zwar auf x Elemente einer Liste.

Im Kern mache ich so etwas:

Code: Alles auswählen


def get_durchschnitt(werteliste):
    return sum(werteliste) / len(werteliste)

werteliste = []
print(get_durchschnitt(werteliste[-20:]))

print(get_durchschnitt(werteliste[-30:]))

Ich könnte ja im Prinzip stattdessen auch wie folgt herangehen:

Code: Alles auswählen


def get_durchschnitt(werteliste, n):
    return sum(werteliste[-n:]) / n

werteliste = []
print(get_durchschnitt(werteliste, 20))

print(get_durchschnitt(werteliste, 30))

Gibt es bei den beiden Varianten Vor- oder Nachteile oder würdet ihr eine Lösung bevorzugen? Die zweite Lösung ist expliziter als die erste Herangehensweise, nur frage ich mich gerade, ob es Sinn macht einer Funktion immer die komplette Werteliste (mit > 5.000 Werten) zu übergeben. Irgendwelche Empfehlungen???
BlackJack

@pixewakb: Ad (1): Ganz klar Funktionen. Welchen Vorteil versprichst Du Dir denn von statischen Methoden? Das ist doch hauptsächlich ein Workaround bei Sprachen wie Java um doch so etwas wie Funktionen haben zu können. In Python sind die für den eher seltenen Fall das man eine polymorphe Funktion innerhalb einer (echten) Methode braucht die vom Datentyp abhängt auf dem die Methode aufgerufen wurde.

Ad (2): Da würde ich die erste Variante nehmen weil die zweite ewas macht was mehr ist als den Durchschnitt zu berechnen und da wohl alleine vom Namen niemand drauf kommen würde. Und jeder der den Durchschnitt von allen Elementen berechnen möchte und die Zusatzfunktionalität nicht benötigt muss immer auch ein zweites Argument übergeben. Selbst wenn man das mit einem Default-Wert löst wird dann innerhalb der Funktion immer eine Kopie der Liste angelegt, auch wenn man gar keinen Ausschnitt sondern alles berechnen möchte. Und die Funktion geht dann auch nur mit Objekten die „slicing” überhaupt verstehen.
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Bei der 2. Version mit zusätzlichem Parameter ist es expliziter, das hätte dafür gesprochen. Statische Methoden sind bei Weigend erklärt und zwar um "Toolboxen" zu programmieren, darum hätte ich es eingesetzt, nach der Einführung lerne/arbeite ich.

Danke fürs Feedback! Das Modul wird später mal etliche Funktionen bereithalten und da habe ich gerade bei 5 Funktionen schon Sorge, dass ich grundlegend im Design etwas falsch mache.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

pixewakb hat geschrieben:Bei der 2. Version mit zusätzlichem Parameter ist es expliziter, das hätte dafür gesprochen.
Nee, zwei Parameter sind mehr und unnötige Schreibarbeit und dazu noch fehleranfällig. Ein Objekt sollte schon selber wissen, wie viele Elemente es enthält. Und wenn es das nicht weiß, dann kann das spätestens dann entschieden werden, wenn über die Elemente iteriert wird.

Ich vermute mal, dass du das "explizit" einfach überinterpretiert hast. Explizit bedeutet nicht, dass du unnötig offensichtliche Dinge hinschreiben sollst. Wenn du das machst, dann wird der Code so unübersichtlich, dass er kaum noch lesbar ist. Hinzu kommt dann noch, dass die wirklich wichtigen Dinge dann leicht übersehen werden.
Das Leben ist wie ein Tennisball.
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Im konkreten Fall brauche ich eine Funktion, die Durchschnitte für eine Messwertliste erstellt, wobei mich die Messwerte pro Woche (n = 7), für 2 Wochen (n = 14) und dann im Monat, Quartal usw. interessieren. Gedanklich habe ich Sorge, dass ich irgendwann falsche Messwerte übergebe und dann nicht merke, dass die Rechnung falsch wird, weil z. B. die Messwertliste gar keine 7 Daten enthält. Das ist mein sehr konkretes Problem.
BlackJack

@pixewakb: Und wo ist da der Unterschied zwischen den beiden Varianten? Den Fehler kannst Du in beiden Fällen problemlos machen.
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Ich habe z. B. eine Funktion, wo ich für jeden Messwert einer Reihe die drei aufeinanderfolgenden vergleiche und verarbeite. Wenn ich das auch für den ersten machen will, dann muss ich folglich statt werte[-14:] dann werte[-16:] übergeben. Persönlich habe ich "Sorge", dass ich irgendwann nicht mehr bewusst habe, welche Daten die jeweilige Funktion erfordert und sich so Rechenfehler einschleichen. (Im Kern kann ich mein Magengrummeln also noch nicht genau fassen, zumindest nicht sprachlich formulieren.)
BlackJack

@pixewakb: Die Sorge verstehe ich, aber nicht wo der Unterschied bei den Varianten ist. Ob Du nun daran denken musst statt ``f(v[-14:])`` dann ``f(v[-16:])`` zu schreiben oder statt ``f(v, 14)`` dann ``f(v, 16)`` ist doch letztendlich egal, man muss dran denken und man kann in beiden Fällen den gleichen Fehler machen.
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Noch eine Frage:

Sagen wir mal ich brauche eine Funktion der Art berechne_xyz(...), wie würde diese Funktion dann typischerweise heißen?

Im Tutorial gibt es u. a. fib() für Fibonacci-Zahlen; von Klassen kenne ich nur die get-Funktionen. Gibt es einen Standardnamen, der anzeigt, dass ein Skript einen Wert xyz berechnet? Würde man XYZ dann übrigens groß oder klein schreiben???

Bin bei PEP8 nicht fündig (in den Abschnitten) geworden und konnte auf die Schnelle nichts finden.

Wenn ich das richtig deute, wird auf ein vorangestelltes get, calculate o. ä. ganz verzichtet!?

https://docs.python.org/2/library/math.html

Gibt es davon abweichende Namen? Konventionen?
BlackJack

@pixewakb: Die Gross-/Kleinschreibung von Funktionen sollte in PEP8 eigentlich abgedeckt sein: `klein_mit_unterstrichen()`.

Ansonsten beschreiben Funktionsnamen üblicherweise Tätigkeiten. `get_*()` deutet auf ”Getter” hin bei denen man üblicherweise erwartet das da nichts komplizierteres passiert sondern ein irgendwo hinterlegter Wert geholt wird. `calculate_*()` wäre für Berechnungen schon ganz gut — falls einem nichts passenderes einfällt. Wenn es mathematische Sachen sind, wird oft auch der Name der Funktion verwendet der in der Literatur üblich ist. So ganz eindeutig kann man da nichts sagen.

Die Namensgebung im `math`-Modul ist nicht frei gewählt, das sind im Grunde die Namen der C-Funktionen aus der C-Standardbibliothek.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

pixewakb hat geschrieben:Sagen wir mal ich brauche eine Funktion der Art berechne_xyz(...), wie würde diese Funktion dann typischerweise heißen?
Schau Dir einfach mal an, wie es in anderen Bibliotheken gemacht wird, dann bekommst Du schon Ideen für eigene Namen: http://docs.scipy.org/doc/numpy/referen ... stics.html

Statistische Grundfunktionen wie mean, std, median, ... braucht man übrigens nicht selbst zu implementieren, es ist alles schon da. Wenn Dir die paar statistischen Grundfunktionen in Numpy nicht ausreichen, dann schau Dir mal Pandas an: http://pandas.pydata.org/. Unglaublich was da an mächtiger Funktionalität geboten wird, insbesondere in Verbindung mit ipython notebook.
a fool with a tool is still a fool, www.magben.de, YouTube
Antworten