Seite 1 von 1
Rechnungswesen für Arme
Verfasst: Sonntag 15. Juni 2014, 23:26
von Sophus
Hallo Leute,
irgendwie will meine kleine Rechnung nicht ganz aufgehen. Es geht einfach darum die Mehrwertsteuern aus einem Bruttopreis herauszurechnen. Hier mein Code:
Code: Alles auswählen
BruttoPreis = input(" Brutto: ") # Gehen wir mal davon aus die Ware kostet 100 Euro, also tragen wir hier die Zahl 100 ein.
MwSt = input(" - Umsatzsteuer (%): ") # Die Mehrwertsteuern betragen 19 %, also tragen wir hier die Zahl 19 ein.
a = 100
b = MwSt
c = a+b # Ergebnis: 119 | Hier habe ich mir eine kleine Brücke gebaut, denn die Zahl 119 brauche ich.
print c #Um sicher zu gehen, dass wir wirklich den Wert 119 bekommen, lasse ich es vorher ausgeben.
NettoPreis = float((BruttoPreis/c)*100) # Formel lautet jetzt: 100/119*100
R_NettoPreis = round (NettoPreis, 2) # Hier will ich die Kommazahlen auf zwei Stellen nach dem Komma begrenzen
print " = Preis ohne MwSt: " + str(R_NettoPreis) + " Euro" # Ergebnis: 0.0 Euro. Eigentlich müsste 84.03 Euro rauskommen.
Was mache ich hier falsch?
Re: Rechnungswesen für Arme
Verfasst: Sonntag 15. Juni 2014, 23:43
von BlackJack
@Sophus: Du rechnest mit ganzen Zahlen statt mit Gleitkommazahlen. Und `input()` sollte man in Python 2 nicht verwenden — da kann der Benutzer nahezu beliebigen Python-Code ausführen weil die Eingabe als Python-Ausdruck ausgewertet wird. Nimm `raw_input()` und wandle die eingegebene Zeichenkette in eine Gleitkommazahl um.
`round()` würde ich auch nicht benutzen wenn es um die Anzeige geht. Da kann man die Anzahl der Nachkommastellen per Formatierung lösen. Was man anstelle von ``+`` und `str()` verwenden sollte um Werte in Zeichenketten zu formatieren.
Re: Rechnungswesen für Arme
Verfasst: Sonntag 15. Juni 2014, 23:52
von pillmuncher
Sophus hat geschrieben:Was mache ich hier falsch?
Falsch ist, das
Tutorial nicht zu lesen. Da du es offensichtlich lieber vorgelesen bekommst, hier:
Und das hier als kleiner Denkanstoß:
Code: Alles auswählen
>>> 100 / 119
0
>>> 100. / 119
0.8403361344537815
>>> 100 / 119.
0.8403361344537815
>>> from __future__ import division # seit Python 2.2
>>> 100 / 119
0.8403361344537815
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 08:11
von MagBen
Es ist nicht völlig falsch Buchhaltung mit ganzen Zahlen zu machen. Wenn Du z.B. für die Buchhaltung in ein paar Stunden eine kleine Auswertung schreibst, die in SAP eine Woche dauern würde, dann sollten nachher auch die Summen stimmen, sonst fragt die Buchhaltung warum bei der 20 Millionen Summe es Abweichungen im Cent-Bereich zwischen SAP und Python gibt. Die wollen dann auch nicht hören, dass der PC 0.05 als float nicht exakt darstellen kann:
Um eine Übereinstimmung bis auf den letzten Cent zu erreichen, kannst Du deshalb entweder mit Decimal rechnen oder Du rechnest alle Währungsbeträge in 1/100 Cent mit long.
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 08:44
von Sirius3
@MagBen: bleibt noch zu klären, wann mit Bruchteilen von Cents gerechnet wird, wie wann gerundet wird, und ob irgendjemand die Rechenfehler von Excel einprogrammiert hat, um konsistent zu bleiben
Wenn man nicht gerade mit eine paar Milliarden rechnet, dürften Rechengenauigkeitsfehler sich nicht auf ein Cent addieren, sondern es liegt an einem der oberen Punkte.
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 09:12
von MagBen
Sirius3 hat geschrieben:Rechengenauigkeitsfehler
Es gibt Bereiche die kennen dieses Wort nicht. Ich habe mal als Wahlhelfer Stimmen ausgezählt, am Ende habe ich dann gefragt ob wir jetzt noch eine Fehlerrechnung machen (wie ich es aus den Physik-Praktikum kannte). Das fand der Wahlleiter nicht witzig.
Also es gibt Bereiche die erwarten einen Rechenfehler von 0. Den bekommst Du in der Buchhaltung eben nur mit Ganzzahlen. Auch die Mehrwertsteuerberechnung lässt sich steuerlich 100% korrekt mit Ganzahlen durchführen. Deshalb gibt es in den Microsoft Sprachen dazu den Datentyp Currency, dieser Datentyp verwaltet intern den Währungsbetrag als long.
Sirius3 hat geschrieben:Wenn man nicht gerade mit eine paar Milliarden rechnet, dürften Rechengenauigkeitsfehler sich nicht auf ein Cent addieren
Es hängt nicht nur von der Summe ab, sondern auch von der Anzahl der Rechenoperationen (und mein Rechner kann in jeder Sekunde Milliarden davon ausführen).
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 13:09
von darktrym
Dann warst du sicher nicht Wahlleiter, ich wüsste auch nicht dass das jemals auf den Zettel stand.

Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 13:17
von MagBen
darktrym hat geschrieben:Dann warst du sicher nicht Wahlleiter
Physiker!
Physiker wissen, dass da wo gemessen wird, da gibt's auch einen Fehler.
Buchhalter akzeptieren das zum Teil, dass es zwischen Soll und Ist eine Differenz gibt, aber nur wenn es um Bargeld geht, nicht bei elektronischen Daten.
Verwaltungsleuten scheint das aber völlig fremd zu sein, dass es beim einfachen Abzählen zu Fehlern kommen kann.
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 14:12
von /me
MagBen hat geschrieben:Physiker wissen, dass da wo gemessen wird, da gibt's auch einen Fehler.
Vor langen Jahren im Physikstudium, als die gemessene Kurve genau andersherum aussah als sie sollte: "Machen Sie einfach die Fehlerabschätzung groß genug und dann passt das schon." Als Wahlvorstand ist die Sache dann nicht mehr ganz so einfach ...
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 15:28
von noisefloor
Hallo,
möchte man bei sowas nicht so wie so das decimal-Modul importieren und Dezimalzahlen rechnen?
Gruß, noisefloor
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 15:32
von Sophus
Nun, ich habe meinen Code ein wenig angepasst: Aus 'input()' wurde nun 'raw_input'. Auch wurde die 'division' wie von euch empfohlen importiert.
Code: Alles auswählen
from __future__ import division
BruttoPreis = raw_input(" Brutto: ")
MwSt = raw_input(" - Umsatzsteuer (%): ")
a = 100
b = MwSt
c = a+b
print c
NettoPreis = (BruttoPreis/c*100)
R_NettoPreis = round (NettoPreis, 2)
print " = Preis ohne MwSt: " + str(R_NettoPreis) + " Euro"
Führe ich den Code aus, und gebe als Bruttowert "100.20" ein, im unserem Alltag würde man 100,20 schreiben, dann die MwSt 19%, dann bekomme ich folgende Fehlermeldung:
Traceback (most recent call last):
File "D:\Dan\Python\Tutorials\Brutto.py", line 7, in <module>
c = a+b
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Die besagt, dass er in der Zeile c = a+b nicht klar kommt.
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 15:44
von /me
Wie BlackJack schrieb: "[...] wandle die eingegebene Zeichenkette in eine Gleitkommazahl um."
Hint:
float
Und bitte werde diese unnützen und nichtssagenden
a,
b und
c los.
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 16:27
von Sophus
/me hat geschrieben:Wie BlackJack schrieb: "[...] wandle die eingegebene Zeichenkette in eine Gleitkommazahl um."
Hint:
float
Und bitte werde diese unnützen und nichtssagenden
a,
b und
c los.
Vielen Dank, ich habe nun die eingegebene Zeichenketten in eine Gleitkommazahl umgewandelt. Nun ein kleines Schönheitsproblem.
Code: Alles auswählen
def BKV():
LP = float(raw_input(" Listenpreis: "))
LR = float(raw_input(" - Lieferantenrabatt (%): "))
ZKP = (LP-LP*LR/100)
R_ZKP = round(ZKP, 2)
print " = Zieleinkaufspreis: " + str(R_ZKP) + " Euro"
print "-----------------------"
LSK = float(raw_input (" - Lieferantenskonto (%) "))
BKP = (ZKP-ZKP*LSK/100)
R_BKP = round(BKP,2)
print " = Bareinkaufspreis: " + str(R_BKP) + " Euro"
print "-----------------------"
BZK= float(raw_input("+ Bezugskosten "))
BZP = (BZK+BKP)
R_BZP = round(BZP, 2)
print " = Einstandspreis (Bezugspreis) " + str(R_BZP) + " Euro"
print "-----------------------"
GMK = float(raw_input(" + Gemeinkosten / Handlungskosten (%): "))
SKP = (BZP+(GMK*BZP)/100)
R_SKP = round(SKP, 2)
print " = Selbstkosten: " + str(R_SKP) + " Euro"
print "-----------------------"
GZS = float(raw_input(" + Gewinnzuschlag (%): "))
BVKP = (SKP+(SKP*GZS)/100)
R_BVKP = round(BVKP, 2)
print " = Barverkaufspreis: " + str(R_BVKP) + " Euro"
print "-----------------------"
KSK = float(raw_input(" + Kundenskonto (%): "))
ZVP = (BVKP/(100-KSK)*100)
R_ZVP = round(ZVP, 2)
print " = Zielverkaufspreis: " +str(R_ZVP) + " Euro"
print "-----------------------"
KR = float(raw_input(" + Kundenrabatt: "))
LVKP_netto = (ZVP/(100-KR)*100)
R_LVKP_netto = round(LVKP_netto, 2)
print " = Listenverkaufspreis (netto): " + str(R_LVKP_netto) + " Euro"
print "-----------------------"
UST = float(raw_input(" + Umsatzsteuer (%): "))
LVKP_brutto = LVKP_netto+LVKP_netto/100*UST
R_LVKP_brutto = round (LVKP_brutto, 2)
print " = Listenverkaufspreis (brutto): " + str(R_LVKP_brutto) + " Euro"
print "======================="
Und zum Vergleich dieses Schaubild.
Ab dem Kundenskonto "schummelt" mein Script (ab Zeile 31), und ich kann den Fehler nicht finden, da ich die Formel doch richtig angegeben habe. Hier "schummelt" Python nur um einen Cent, was nicht die Welt untergehen lässt. Aber wieso "schummelt" er? Sollte ich denn bei 'round()' anstatt 2 auf 3 setzen?
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 16:37
von BlackJack
@Sophus: Ich würde entweder gar nicht runden, sondern die Anzahl der Nachkommastellen bei der Anzeige durch eine entsprechende Formatierung beschränken/runden, oder Du musst Dich halt mit einem Datentyp beschäftigen der nicht die Rechenungenauigkeiten von Gleitkommazahlen aufweist die Binär gespeichert sind. Das `decimal`-Modul aus der Standardbibliothek kann da helfen.
Du könntest die Rechnung auch mal von Hand nachvollziehen und damit die Stelle finden wo sich Deine Rechnung von der vom Programm unterscheidet. Und vielleicht auch die Dokumentation zu `round()` durchlesen was das *genau* macht. Das überrascht vielleicht auch den ein oder anderen der bis dahin dachte runden seit etwas was eindeutig ist und jeder so macht wie man selbst denkt wie das gemacht werden sollte.
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 17:00
von Sophus
BlackJack hat geschrieben:@Sophus: Ich würde entweder gar nicht runden, sondern die Anzahl der Nachkommastellen bei der Anzeige durch eine entsprechende Formatierung beschränken/runden, oder Du musst Dich halt mit einem Datentyp beschäftigen der nicht die Rechenungenauigkeiten von Gleitkommazahlen aufweist die Binär gespeichert sind. Das `decimal`-Modul aus der Standardbibliothek kann da helfen.
Du könntest die Rechnung auch mal von Hand nachvollziehen und damit die Stelle finden wo sich Deine Rechnung von der vom Programm unterscheidet. Und vielleicht auch die Dokumentation zu `round()` durchlesen was das *genau* macht. Das überrascht vielleicht auch den ein oder anderen der bis dahin dachte runden seit etwas was eindeutig ist und jeder so macht wie man selbst denkt wie das gemacht werden sollte.
Vielen Dank. Ich habe mich mal an das Decimal-Modul herangetraut: Wie wir sehen, habe ich den 'round()' auskommentiert. Es wird also nicht mehr gerundet.
Code: Alles auswählen
def BKV():
LP = float(raw_input(" Listenpreis: "))
LR = float(raw_input(" - Lieferantenrabatt (%): "))
ZKP = float(Decimal(LP-LP*LR/100))
#R_ZKP = round(ZKP, 2)
print " = Zieleinkaufspreis: " + str(ZKP) + " Euro"
print "-----------------------"
LSK = float(raw_input (" - Lieferantenskonto (%) "))
BKP = float(Decimal(ZKP-ZKP*LSK/100))
#R_BKP = round(BKP,2)
print " = Bareinkaufspreis: " + str(BKP) + " Euro"
print "-----------------------"
BZK= float(raw_input("+ Bezugskosten "))
BZP = float(Decimal(BZK+BKP))
#R_BZP = round(BZP, 2)
print " = Einstandspreis (Bezugspreis) " + str(BZP) + " Euro"
print "-----------------------"
GMK = float(raw_input(" + Gemeinkosten / Handlungskosten (%): "))
SKP = float(Decimal(BZP+(GMK*BZP)/100))
#R_SKP = round(SKP, 2)
print " = Selbstkosten: " + str(SKP) + " Euro"
print "-----------------------"
GZS = float(raw_input(" + Gewinnzuschlag (%): "))
BVKP = float(Decimal(SKP+(SKP*GZS)/100))
#R_BVKP = round(BVKP, 2)
print " = Barverkaufspreis: " + str(BVKP) + " Euro"
print "-----------------------"
KSK = float(raw_input(" + Kundenskonto (%): "))
ZVP = float(Decimal(BVKP/(100-KSK)*100))
#R_ZVP = round(ZVP, 2)
print " = Zielverkaufspreis: " +str(ZVP) + " Euro"
print "-----------------------"
KR = float(raw_input(" + Kundenrabatt: "))
LVKP_netto = float(Decimal(ZVP/(100-KR)*100))
#R_LVKP_netto = round(LVKP_netto, 2)
print " = Listenverkaufspreis (netto): " + str(LVKP_netto) + " Euro"
print "-----------------------"
UST = float(raw_input(" + Umsatzsteuer (%): "))
LVKP_brutto = float(Decimal(LVKP_netto+LVKP_netto/100*UST))
#R_LVKP_brutto = round (LVKP_brutto, 2)
print " = Listenverkaufspreis (brutto): " + str(LVKP_brutto) + " Euro"
print "======================="
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 18:16
von Sirius3
@Sophus: was gewinnst Du, wenn Du Decimal immer gleich wieder in float umwandelst ???
Du solltest endlich String-Format statt der String-Addition einbauen!
Re: Rechnungswesen für Arme
Verfasst: Montag 16. Juni 2014, 18:27
von Sophus
Sirius3 hat geschrieben:@Sophus: was gewinnst Du, wenn Du Decimal immer gleich wieder in float umwandelst ???
Du solltest endlich String-Format statt der String-Addition einbauen!
Also raus mit dem 'float()'?
Re: Rechnungswesen für Arme
Verfasst: Dienstag 17. Juni 2014, 01:59
von Kebap
Sirius3 meint wohl diese Zeilen:
print " = Listenverkaufspreis (netto): " + str(LVKP_netto) + " Euro"
Re: Rechnungswesen für Arme
Verfasst: Dienstag 17. Juni 2014, 08:26
von BlackJack
@Kebap: Nein, er meint schon genau das was er gesagt hat: die Stellen wo ein `Decimal`-Objekt erstellt und gleich als nächste Operation in ein `float`-Objekt umgewandelt wird.
Re: Rechnungswesen für Arme
Verfasst: Mittwoch 18. Juni 2014, 17:08
von Kebap
@BlackJack: Danke fürs Widersprechen. Tatsächlich meinte er anscheinend sogar 2 unterschiedliche Sachen in seinen 2 Zeilen.