Eigenes Objekt?

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.
sprudel
User
Beiträge: 248
Registriert: Donnerstag 8. März 2007, 17:12

Freitag 17. April 2009, 13:14

Hallo,
ich habe mir für mein Kassensystem überlegt dass es recht sinnvoll wäre einen eigenen Objekttyp für Geldmengen zu haben.

Ich möchte das Objekt idealerweise so haben, dass cih damit rechnen kann, es aber mit print z.B. trotzdem als "0,25 €" ausgegeben wird.
Wie kann ich sowas verwirklichen?

Mir fällt da garkein Anfang ein, hoffe ihr wisst da eine Idee.

LG Chris
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Freitag 17. April 2009, 13:25

Ein kleiner Ansatz:

Code: Alles auswählen

>>> class Euro(object):
...     def __init__(self, value):
...         self.value = value
...     def __str__(self):
...         return "%f euro" % self.value
...     def __add__(self, other):
...         return Euro(self.value + other.value)
...
>>> eins = Euro(1)
>>> zwei = Euro(2)
>>> print eins
1.000000 euro
>>> print zwei
2.000000 euro
>>> drei = eins+zwei
>>> print drei
3.000000 euro
>>>
Bei Geld solltest du besser das decimal-Modul benutzen und keine Floats, aber das soll auch nur ein Beispiel sein. Neben "__add__" gibt es noch jede Menge weitere Methoden wie "__sub__", oder "__mul__", die findest du aber alle in der Dokumentation.

Du könntest auch von Decimal erben und die gewünschten Methoden (automatisch) überschreiben. Dazu gab es hier vor kurzem auch einen Thread.
Das Leben ist wie ein Tennisball.
lunar

Freitag 17. April 2009, 13:30

Eine Währung ist imho kein eigener Datentyp, dieses System wäre auch ziemlich unflexibel.
sprudel
User
Beiträge: 248
Registriert: Donnerstag 8. März 2007, 17:12

Freitag 17. April 2009, 13:32

lunar hat geschrieben:Eine Währung ist imho kein eigener Datentyp, dieses System wäre auch ziemlich unflexibel.
Nunja, es geht hier ja eher darum dass ich nicht immer mit Floats arbeiten möchte.

Ich möchte einfach eine flexible Möglichkeit in einem Objekt haben.

ich möchte auch ganz einfach folgendes können:

a = Money("0,23€")

print a sollte dann selbiges zurückgeben,
a = a+1
sollte dann allerdings in "1,23€" enden.
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Freitag 17. April 2009, 13:39

Es kommt immer auf den Kontext drauf an, ob Währungen eigenen Datentypen sind oder nicht. Ich möchte nicht einen Euro einfach mit 2 addieren, sondern wieder mit Euro. Wenn man mit vielen verschiedenen Währungen rechnet hat man außerdem den Vorteil, dass man diese über irgend einen Referenzkurs addieren kann.

Es soll da auch eine Raumfahrtbehörde geben, welche, wegen solchen Kleinigkeiten mit Einheiten, Sonden an Planeten vorbei schießt ;-)
Das Leben ist wie ein Tennisball.
Nocta
User
Beiträge: 290
Registriert: Freitag 22. Juni 2007, 14:13

Freitag 17. April 2009, 13:40

Naja du kannst das €-Zeichen auch später noch dranhängen und einfach float (oder decimal oder sonstwas) benutzen ;)
Oder wenn's dir wirklich so wichtig ist, dass das ganze automatisch abläuft, einfach von float (oder sonstigem) erben und bei __str__ ein € dranhängen.
sprudel
User
Beiträge: 248
Registriert: Donnerstag 8. März 2007, 17:12

Freitag 17. April 2009, 13:43

Nocta, das klingt gut.


das war dann

class Money(float):

oder?

Bevor ihr fragt: Nein, ich brauche das nicht für die Schule, noch ist es privat, meine Ausbildung fängt erst im September an, da lerne ich dann die Grundsätze nochmal neu, noch ist es ein reines Hobby ;-)
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Freitag 17. April 2009, 14:02

Nein. Warum willst du unbedingt eigene Klassen benutzen? Siehe auch den Post von lunar. Rechne doch einfach mit den Werten, wie du es gewohnt bist und benutze das Decimal-Modul, weil die Genauigkeit bei Währungen eine große Rolle spielt (wurde auch schon erwähnt).
lunar

Freitag 17. April 2009, 14:25

EyDu hat geschrieben:Es kommt immer auf den Kontext drauf an, ob Währungen eigenen Datentypen sind oder nicht. Ich möchte nicht einen Euro einfach mit 2 addieren, sondern wieder mit Euro.
Die interne Darstellung muss natürlich einheitlich sein. Das aber kann man auch dadurch erreichen, dass Währungen bei der Ein- und Ausgabe entsprechend in bzw. von einer internen Darstellung umgerechnet werden.

Zum einen erleichtert das den Umgang mit verschiedenen Währungen. Ansonsten stellt sich nämlich die Frage, was herauskommen soll, wenn man Euro mit Yen addiert. Zudem vermeidet man so, dass die äußere Darstellung von Werten von deren interner Darstellung abhängt. Werden Beträge in Objekten mit einem Typ entsprechend der Währung gespeichert, sind Typkonvertierungen erforderlich, wenn der Benutzer die verwendete Währung ändert. Andernfalls muss man nur dafür sorgen, dass die Beiträge entsprechend der aktuellen Währung neu angezeigt werden.

Ich persönlich würde zwar einen eigenen Datentyp für einen Geldbetrag verwenden, der bei arithmetischen Operationen mit Ganzzahlen oder Floats warnt, um Umrechnungsfehler zu vermeiden und eine explizite Konvertierung zu erzwingen, keinesfalls aber jede Währung mit einem eigenen Datentyp repräsentieren. Zur internen Darstellung würde ich eine Währung, beispielsweise Euro, verwenden. Alle Ein- und Ausgaben würde ich dann mittels einer weiteren Klasse in Euro bzw. in die bei der Anzeige gewünschte Währung umrechnen. Das hätte auch den Vorteil, dass die Umrechnung zentral implementiert ist, und man so leicht mehrere Datenquellen für Wechselkurse implementieren kann.
sprudel
User
Beiträge: 248
Registriert: Donnerstag 8. März 2007, 17:12

Freitag 17. April 2009, 14:30

Lunar, ich denke du verstehst was ich meine.
Ja, ich möchte es auch z.B. mit Pfund rechnen können.

Als Basis würde ich sehr gerne den Euro nehmen, da meine Software häufig im europäischen Bereich verwendet wird.

Man bräuchte also eine Basisklasse "Euro"

dann bräuchte man Klassen für z.B. Dollar.
Diese bräuchten dann alle eine Methode wie xy.to_euro(), welche ich dann zum Rechnen verwenden könnte.
Das Problem ist nur: Wie mache ich das mit den Objekten? Ich muss sagen, mit Objekten habe ich jetzt eher weniger Erfahrung. Gibt es irgeneine Liste für die ganzen Spezialmethoden wie z.B. __repr__ ?

LG Chris
lunar

Freitag 17. April 2009, 14:37

Irgendwie habe ich das Gefühl, dass du mein Posting nicht richtig gelesen hast, sonst wüsstest du ja, dass ich eben keine Klassen für jede Währung implementieren würde.
sprudel
User
Beiträge: 248
Registriert: Donnerstag 8. März 2007, 17:12

Freitag 17. April 2009, 14:40

Ein Datentyp ist doch eine Klasse, oder sehe ich das falsch?
lunar

Freitag 17. April 2009, 16:46

Nein, das ist schon richtig. Ich sagte ja nur, dass ich keinen separaten Datentyp für jede einzelne Währung nutzen würde. Stattdessen würde ich lediglich einen Datentyp für einen Geldbetrag einführen.

Diesen Datentyp könnte man mit zusätzlichen Methoden versehen, die beim Umgang mit Geld hilfreich sind. Außerdem würde ich diesen Datentyp so implementieren, dass man keine "gemischten" arithmetischen Operationen (z.B. "Money(0.25) + 0.25") durchführen könnte. Dadurch erzwingt man eine explizite Konvertierung der Eingabe (die als float vorliegt) über einen Wechselkurs in die intern verwendete Währung. Das verhindert Fehler.

Eine eigene Klasse für jede Währung ist viel zu umständlich und unflexibel.
sprudel
User
Beiträge: 248
Registriert: Donnerstag 8. März 2007, 17:12

Freitag 17. April 2009, 16:52

Hmm, okay, da hast du recht.

Wie fange ich sowas am besten an? Sry, ich kenn mich mit Objekten nicht sonderlich gut aus, das ist für mich Neuland, fasziniert mich aber trotzdem extremst.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Freitag 17. April 2009, 17:10

Antworten