Rechnungswesen für Arme

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
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

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?
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.
Benutzeravatar
pillmuncher
User
Beiträge: 1532
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Sophus hat geschrieben:Was mache ich hier falsch?
Falsch ist, das Tutorial nicht zu lesen. Da du es offensichtlich lieber vorgelesen bekommst, hier:

Code: Alles auswählen

>>> # Integer division returns the floor:
... 7/3
2
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
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

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:

Code: Alles auswählen

print( repr(0.05) ) # Ausgabe: '0.050000000000000003'
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.
a fool with a tool is still a fool, www.magben.de, YouTube
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@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 :twisted:

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.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

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).
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
darktrym
User
Beiträge: 785
Registriert: Freitag 24. April 2009, 09:26

Dann warst du sicher nicht Wahlleiter, ich wüsste auch nicht dass das jemals auf den Zettel stand. :roll:
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

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.
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

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 ...
Benutzeravatar
noisefloor
User
Beiträge: 4257
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

möchte man bei sowas nicht so wie so das decimal-Modul importieren und Dezimalzahlen rechnen?

Gruß, noisefloor
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

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.
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

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.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

/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.

Bild

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?
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.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

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 "======================="
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: was gewinnst Du, wenn Du Decimal immer gleich wieder in float umwandelst ???
Du solltest endlich String-Format statt der String-Addition einbauen!
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

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()'?
Benutzeravatar
Kebap
User
Beiträge: 786
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Sirius3 meint wohl diese Zeilen:

print " = Listenverkaufspreis (netto): " + str(LVKP_netto) + " Euro"
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
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.
Benutzeravatar
Kebap
User
Beiträge: 786
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

@BlackJack: Danke fürs Widersprechen. Tatsächlich meinte er anscheinend sogar 2 unterschiedliche Sachen in seinen 2 Zeilen.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Antworten