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
Eigenes Objekt?
Ein kleiner Ansatz:
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.
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
>>>
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.
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.lunar hat geschrieben:Eine Währung ist imho kein eigener Datentyp, dieses System wäre auch ziemlich unflexibel.
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.
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
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.
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.
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.
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
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
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).
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.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.
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.
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
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
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.
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.
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.
Da gibt es schon was: http://pypi.python.org/pypi/currency.converter/
Ich würde sowas tendenziell eher wie folgt machen:
Die jeweiligen Währungen werden im dict oben eingetragen. Dabei wird jeweils der gegenwärtige Euro-Kurs der entsprechenden Währung angegeben.
Ganz zufrieden bin ich damit aber auch noch nicht - so wie es jetzt ist, wird man wahrscheinlich ab und an Money()-Objekte und normale ints / floats verwechseln und somit Fehler produzieren (wie lunar schon schrieb). Eigentlich wollte ich dir auch nur kurz zeigen, dass das mit dem Umrechnen eigentlich recht einfach ist und man mit einer Klasse auskommt.
//edit: Also bitte keine Haue, da fehlt sicher noch einiges, um damit arbeiten zu können - ich würde es an deiner Stelle eigentlich wirklich ohne Klassen machen und nur die entsprechenden Umrechnungsfunktionen schreiben.
Code: Alles auswählen
# coding:utf-8
CURRENCIES = {
'EUR':1.0,
"USD":0.765872712
}
class Money():
def __init__(self, amount, currency="EUR"):
self.amount = float(amount)
self.currency = currency
def __str__(self):
return self.amount
def __add__(self, amount):
return float(self.amount.get_amount_in_standard_currency() + amount.get_amount_in_standard_currency())
def __sub__(self, amount):
return float(self.amount.get_amount_in_standard_currency() - amount.get_amount_in_standard_currency())
def get_amount_in_standard_currency(self):
return float(self.amount * CURRENCIES[self.currency])
geld1 = Money(20)
geld2 = Money(15, "USD")
print "Zusammen: %f" % (geld1 + geld2)
print "Abzüglich: %f " %(geld1 - geld2)
Ganz zufrieden bin ich damit aber auch noch nicht - so wie es jetzt ist, wird man wahrscheinlich ab und an Money()-Objekte und normale ints / floats verwechseln und somit Fehler produzieren (wie lunar schon schrieb). Eigentlich wollte ich dir auch nur kurz zeigen, dass das mit dem Umrechnen eigentlich recht einfach ist und man mit einer Klasse auskommt.
//edit: Also bitte keine Haue, da fehlt sicher noch einiges, um damit arbeiten zu können - ich würde es an deiner Stelle eigentlich wirklich ohne Klassen machen und nur die entsprechenden Umrechnungsfunktionen schreiben.
Hey Barabbas, super, vielen Dank.
Auch wenn ich nicht unbedingt mit etwas fertigem gerechnet hätte (ich bin kein Schüler, ich mache das als Hobby! ) hast du das echt super gelöst.
Vielen Dank, kann ich denke ich fast 1:1 übernehmen und noch erweitern.
Auch wenn ich nicht unbedingt mit etwas fertigem gerechnet hätte (ich bin kein Schüler, ich mache das als Hobby! ) hast du das echt super gelöst.
Vielen Dank, kann ich denke ich fast 1:1 übernehmen und noch erweitern.
Hallo Barabbas
Bei mir wirft dein Skript folgende Exception:
Gruss wuf
Bei mir wirft dein Skript folgende Exception:
Code: Alles auswählen
Traceback (most recent call last):
File "euro_class_02_01.py", line 29, in <module>
print "Zusammen: %f" % (geld1 + geld2)
File "euro_class_02_01.py", line 17, in __add__
return float(self.amount.get_amount_in_standard_currency() + amount.get_amount_in_standard_currency())
AttributeError: 'float' object has no attribute 'get_amount_in_standard_currency'
Take it easy Mates!
achso, es muss nicht "self.amount.get_amount_in_standard_currency()" sondern "self.get_amount_in_standard_currency()" heißen.
Wenn du die beiden betreffenden Zeilen korrigierst, sollte es gehen:
Wenn du die beiden betreffenden Zeilen korrigierst, sollte es gehen:
Code: Alles auswählen
# coding:utf-8
CURRENCIES = {
'EUR':1.0,
"USD":0.765872712
}
class Money():
def __init__(self, amount, currency="EUR"):
self.amount = float(amount)
self.currency = currency
def __str__(self):
return self.amount
def __add__(self, amount):
return float(self.get_amount_in_standard_currency() + amount.get_amount_in_standard_currency())
def __sub__(self, amount):
return float(self.get_amount_in_standard_currency() - amount.get_amount_in_standard_currency())
def get_amount_in_standard_currency(self):
return float(self.amount * CURRENCIES[self.currency])
geld1 = Money(20)
geld2 = Money(15, "USD")
print "Zusammen: %f" % (geld1 + geld2)
print "Abzüglich: %f " %(geld1 - geld2)