Restgeldberechnung geht nicht

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
Dispersio
User
Beiträge: 11
Registriert: Freitag 24. November 2006, 14:24

Hallo,
habe mir einen kleinen Denkanstoß aud dem Topic http://www.python-forum.de/topic-4511,15.html geholt und folgendes Progamiert (ich weis nicht toll bin eben Anfänger :D)

Code: Alles auswählen

def menue():
    print 'Herzlich Willkommen!'
    print 'Was wollen Sie denn kaufen?'
    print 'Geben Sie ...'
    print '1 ein um einen Einzelfahrschein zu Kaufen (Euro 1,50)'
    print '2 ein um eine Streifenkarte zu Kaufen (Euro 6,00)'
    print '3 ein um einen Halbpreisfahrschein zu kaufen (Euro 0,80)'
    print '4 ein um einen 2Fahrten-Halbpreisfahrschein zu kaufen (Euro 1,50)'
    print '5 ein um einen 4Fahrten-Halbpreisfahrschein zu kaufen (Euro 3,00)'
    print '6 ein um einen 2Fahrten-Seniorenfahrschein zu kaufen (Euro 2,00)'
    print '7 ein um eine Wiener-Einkaufskarte zu kaufen (Euro 4,00)'
    print '8 ein um eine 24Std-Karte zu kaufen (Euro 5,00)'
    print '9 ein um eine 72Std-Karte zu kaufen (Euro 12,00)'
    print '10 ein um eine Wien-Karte zu kaufen (Euro 16,90)'
    print '11 ein um eine Wochenkarte zu kaufen (Euro 12,50)'
    print '12 ein um eine 8-Tage-Karte zu kaufen (Euro 24,50)'
    print '13 ein um eine Monatskarte zu kaufen (Euro 45,00)'
    print '14 ein um eine Monatskarte mit Sozialkarte zu kaufen (Euro 15,20)'

#Die Kartenpreise werden definiert
einzelfahrschein = 1.5
streifenkarte = 6
halbpreisfahrschein = 0.8
halbpreisfahrschein2 = 1.5
halbpreisfahrschein4 = 3
seniorenfahrschein2 = 2
einkaufskarte = 4
stundenkarte24 = 5
stundenkarte72 = 12
wienkarte = 16.9
wochenkarte = 12.5
tageskarte8 = 24.5
monatskarte = 45
monatskartesenioren = 15.2
auswahl = False
wechselproblem = True




menue()
print
print '_' * 80
print
#Man waehlt welchen Schein/Karte man haben will
while auswahl == False:
    wahl = input('Geben Sie jetzt ihre auswahl an --> ')
    if wahl > 14:
        print 'Falsche Eingabe wiederhohlen Sie bitte'
    else:
        auswahl = True
#Man gibt sein Geld ein
while wechselproblem == True:
    geld = input('Geben Sie jetzt ihr Geld ein --> ')
    if geld > 100:
        print 'Betrag zu Hoch bitte geben Sie passend'
    else:
        wechselproblem = False
        
#Die Berechnung des Restgeldes
if wahl == 1:
    restgeld = geld - einzelfahrschein
    ausgabe = 'Einzelfahrschein'
elif wahl == 2:
    restgeld = geld - streifenkarte
    ausgabe = 'Streifenkarte'
elif wahl == 3:
    restgeld = geld - halbpreisfahrschein
    ausgabe = 'Halbpreisfahrschein'
elif wahl == 4:
    restgeld = geld - halbpreisfahrschein2
    ausgabe = '2Fahrten-Halbpreisfahrschein'
elif wahl == 5:
    restgeld = geld - halbpreisfahrschein4
    ausgabe = '4Fahrten-Halbpreisfahrschein'
elif wahl == 6:
    restgeld = geld - seniorenfahrschein2
    ausgabe = '2Fahrten-Seniorenfahrscheinn'
elif wahl == 7:
    restgeld = geld - einkaufskarte
    ausgabe = 'Wiener-Einkaufskarte'
elif wahl == 8:
    restgeld = geld - stundenkarte24
    ausgabe = '24Std-Karte'
elif wahl == 9:
    restgeld = geld - stundenkarte72
    ausgabe = '72Std-Karte'
elif wahl == 10:
    restgeld = geld - wienkarte
    ausgabe = 'Wien-Karte'
elif wahl == 11:
    restgeld = geld - wochenkarte
    ausgabe = 'Wochenkarte'
elif wahl == 12:
    restgeld = geld - tageskarte8
    ausgabe = '8-Tage-Karte'
elif wahl == 13:
    restgeld = geld - monatskarte
    ausgabe = 'Monatskarte'
elif wahl == 14:
    restgeld = geld - monatskartesenioren
    ausgabe = 'Monatskarte mit Sozialkarte'
else:
    print 'Ein Fehler ist aufgetreten'

print
print '_' * 80
print
#Man bekommt seinen Schein/Karte
print 'Hier haben Sie ihre/n', ausgabe
print
print '_' * 80
print

#Das Wechselgesld wird berechnet
#Berechnung der Hunderter
hunderter = round(restgeld / 100 -0.5)
restgeld = restgeld - 100 * hunderter
#Berechnung der Fuenfziger
funfziger = round(restgeld / 50 -0.5)
restgeld = restgeld - 50 * funfziger
#Berechnung der Zwanziger
zwanziger = round(restgeld / 20 -0.5)
restgeld = restgeld - 20 * zwanziger
#Berechnung der Zehner
zehner = round(restgeld / 10 -0.5)
restgeld = restgeld - 10 * zehner
#Berechnung der Fuenfer
funfer = round(restgeld / 5 -0.5)
restgeld = restgeld - 5 * funfer
#Berechnung der Zwei-Euro
zweieuro = round(restgeld / 2 -0.5)
restgeld = restgeld - 2 * zweieuro
#Berechnung der Euro
euro = round(restgeld / 1 -0.5)
restgeld = restgeld - 1 * euro
#Berechnung der 50Cent
funfzigcent = round(restgeld / 0.5 -0.5)
restgeld = restgeld - 0.5 * funfzigcent
#Berechnung der 20Cent
zwanzigcent = round(restgeld / 0.2  -0.5)
restgeld = restgeld - 0.2 * zwanzigcent
#Berechnung der 10Cent
zehncent = round(restgeld / 0.1  -0.5)
restgeld = restgeld - 0.1 * zehncent
#Berechnung der 5Cent
funfcent = round(restgeld / 0.05  -0.5)
restgeld = restgeld - 0.05 * funfcent
#Berechnung der 2Cent
zweicent = round(restgeld / 0.02  -0.5)
restgeld = restgeld - 0.02 * zweicent
#Berechnung der Cent
cent = round(restgeld / 0.01  -0.5)
restgeld = restgeld - 0.01 * cent

#Das wechselgeld wird ausgegeben
if hunderter != 0:    
    print 'Sie bekommen', int(hunderter), 'Hunderter zurueck'
if funfziger != 0:
    print 'Sie bekommen', int(funfziger), 'Fuenfziger zurueck'
if zwanziger != 0:
    print 'Sie bekommen', int(zwanziger), 'Zwanziger zurueck'
if zehner != 0:
    print 'Sie bekommen', int(zehner), 'Zehner zurueck'
if funfer != 0:
    print 'Sie bekommen', int(funfer), 'Fuenfer zurueck'
if zweieuro != 0:
    print 'Sie bekommen', int(zweieuro), 'Zweieuro zurueck'
if euro != 0:
    print 'Sie bekommen', int(euro), 'Euro zurueck'
if funfzigcent != 0:
    print 'Sie bekommen', int(funfzigcent), 'Fuenfzig-Cent zurueck'
if zwanzigcent != 0:
    print 'Sie bekommen', int(zwanzigcent), 'Zwanzig-Cent zurueck'
if zehncent != 0:
    print 'Sie bekommen', int(zehncent), 'Zehn-Cent zurueck'
if funfcent != 0:
    print 'Sie bekommen', int(funfcent), 'Fuenf-Cent zurueck'
if zweicent != 0:
    print 'Sie bekommen', int(zweicent), 'Zwei-Cent zurueck'
if cent != 0:
    print 'Sie bekommen', int(cent), 'Cent zurueck'
print
print 'Danke fuer ihren einkauf'
mein Problem ist jetzt Folgendes:
Nehmen wir an ich will einen 4Fahren-Fahrschein um €3,00 Kaufen. Ich gebe dem Automaten €50. Also sollte er mir 2 * €20, 1 * €5 und 1 * €2 ausgeben.
Gibt aber -1 * €100, 2 * €50, 2 * €20, 1 * €5, 1 * €2, -1 * €1, 2 * 50Cent, -1 * 20Cent, 2 * 10Cent, -1 * 5Cent, 2 * 2Cent und 1 * 1Cent

Rechnerisch betrachtet wenn man bei zeile 117 anfängt stell ich mir das so vor:
Restgeld = 47€
47/100 ergibt in Python 0 - 0,5 weil er immer abrunden soll ergebit 0,5 durch das Runden letztendlich wieder 0 (also nicht -1)
--> Zeile 118 47 = 47 * 0

und eben bei den anderen so weiter

Wo ist da der Hacken?????
BlackJack

Dispersio hat geschrieben:Rechnerisch betrachtet wenn man bei zeile 117 anfängt stell ich mir das so vor:
Restgeld = 47€
47/100 ergibt in Python 0 - 0,5 weil er immer abrunden soll ergebit 0,5 durch das Runden letztendlich wieder 0 (also nicht -1)
--> Zeile 118 47 = 47 * 0

und eben bei den anderen so weiter

Wo ist da der Hacken?????
Probier doch einfach aus ob das was Du Dir vorstellst, so stimmt:

Code: Alles auswählen

In [31]: 47 / 100
Out[31]: 0

In [32]: 47 / 100 - 0.5
Out[32]: -0.5

In [33]: round(47 / 100 - 0.5)
Out[33]: -1.0
Ups.

Du kannst es Dir etwas einfacher mit der `divmod()` Funktion machen. Die teilt zwei Zahlen und gibt das ganzzahlige Ergebnis und den Rest zurück:

Code: Alles auswählen

In [34]: divmod(47, 100)
Out[34]: (0, 47)

In [35]: divmod(47, 20)
Out[35]: (2, 7)
Und Du hast eine sich extrem wiederholende Programmstruktur. Als nächsten Schritt könntest Du die Daten in entsprechende Datenstrukturen verpacken und damit das Programm sehr viel kürzer und wartungsfreundlicher machen.
Dispersio
User
Beiträge: 11
Registriert: Freitag 24. November 2006, 14:24

Vielen dank für die schnelle hilfe
BlackJack hat geschrieben:
Probier doch einfach aus ob das was Du Dir vorstellst, so stimmt:

Code: Alles auswählen

In [31]: 47 / 100
Out[31]: 0

In [32]: 47 / 100 - 0.5
Out[32]: -0.5

In [33]: round(47 / 100 - 0.5)
Out[33]: -1.0
Ups.
Da hätte ich wirklich selbst draufkommen sollen :oops: .
Probiert habe ichs eh, nur hald mit 0,5 und nicht mit -0,5 das war der fehler
BlackJack hat geschrieben: Als nächsten Schritt könntest Du die Daten in entsprechende Datenstrukturen verpacken und damit das Programm sehr viel kürzer und wartungsfreundlicher machen.
Meinst du damit in Klassen und Funktionen?? Denn das versuche ich Krampfhaft zu verstehen. Mein größtest Problem ist zum beispiel, wie kann ich eine Variable aus einer Funktion in der anderen verwenden.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

@Dispersio: Du hast viele Codezeilen die fast identisch sind... Das schreit gerade dazu dict zu benutzten. Schau dir mal dir Grundlagen darüber an: [wiki]Tutorial/Dictionary[/wiki]

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Dispersio
User
Beiträge: 11
Registriert: Freitag 24. November 2006, 14:24

OK

Mit den dict muss ich mich noch mehr beschäftigen. Ich habs aber mal mit Listen gemacht.

Code: Alles auswählen

def menue():
    print 'Herzlich Willkommen!'
    print 'Was wollen Sie denn kaufen?'
    print 'Geben Sie ...'
    for i in range (1,len(kartenpreis)):
        print i, 'ein um eine/n', kartenname[i], 'zu Kaufen', kartenpreis[i],\
'Euro'

kartenpreis = ["platzfueller", 1.50, 6.00, 0.80, 1.50, 3.00, 2.00, \
4.00, 5.00, 12.00, 16.90, 12.50, 24.50, 45.00, 15.20]
kartenname= ["platzfueller", "Enzelfahrschein", "Streifenkarte", \
"Halbpreisfahrschein", "2Fahrten-Halbpreisfahrschein", \
"4Fahrten-Halbpreisfahrschein", "2Fahrten-Seniorenfahrschein",\
"Wiener-Einkaufskarte", "24Std-Karte", "72Std-Karte", \
"Wien-Karte", "Wochenkarte", "8-Tage-Karte", "Monatskarte", \
"Monatskarte mit Sozialkarte"]
scheine = [100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01]
scheinname = ["Hunderter", "Fuenfziger", "Zwanziger", "Zehner",\
"Fuenfer", "Zwei-Euro", "Ein-Euro", "Fuenfzig Cent", \
"Zwanzig Cent", "Zehn Cent", "Fuenf Cent", "Zwei Cent","Cent"]
rueckgeld = []        
auswahl = False
wechselproblem = True
menue()
print
print '_' * 80
print
#Man waehlt welchen Schein/Karte man haben will
while auswahl == False:
    wahl = input('Geben Sie jetzt ihre auswahl an --> ')
    if wahl > 14:
        print 'Falsche Eingabe wiederhohlen Sie bitte'
    else:
        auswahl = True
#Man gibt sein Geld ein
while wechselproblem == True:
    geld = input('Geben Sie jetzt ihr Geld ein --> ')
    if geld > 100:
        print 'Betrag zu Hoch bitte geben Sie passend'
    else:
        wechselproblem = False

restgeld = geld - kartenpreis[wahl]

print
print '_' * 80
print
#Man bekommt seinen Schein/Karte
print 'Hier haben Sie ihre/n', kartenname[wahl]
print
print '_' * 80
print
#Das Wechselgesld wird berechnet und ausgegeben
for i in range(len(scheine)):
    zwischenergebnis = divmod(restgeld, scheine[i])
    rueckgeld.append(zwischenergebnis[0])
    restgeld = restgeld - scheine[i] * rueckgeld[i]

    if rueckgeld[i] != 0:
        print 'Sie bekommen', int(rueckgeld[i]), scheinname[i], 'zurueck.'
Hoffe das ihr das zumindest so ähnlich gemeint habt.

Danke nochmals für die Hilfe :D

Edit: BlackJacks tipp im Code eingebaut
Zuletzt geändert von Dispersio am Mittwoch 29. November 2006, 16:29, insgesamt 1-mal geändert.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Die printkaskade kannst du so ändern:

Code: Alles auswählen

def menue():
    print """Herzlich Willkommen!
Was wollen Sie denn kaufen?
Geben Sie ...'
1 ein um einen Einzelfahrschein zu Kaufen (Euro 1,50)
2 ein um eine Streifenkarte zu Kaufen (Euro 6,00)
3 ein um einen Halbpreisfahrschein zu kaufen (Euro 0,80)
4 ein um einen 2Fahrten-Halbpreisfahrschein zu kaufen (Euro 1,50)
5 ein um einen 4Fahrten-Halbpreisfahrschein zu kaufen (Euro 3,00)
usw."""
Dann sollte so was in der Art bei rauskommen:

Code: Alles auswählen

Herzlich Willkommen!
Was wollen Sie denn kaufen?
Geben Sie ...'
1 ein um einen Einzelfahrschein zu Kaufen (Euro 1,50)
2 ein um eine Streifenkarte zu Kaufen (Euro 6,00)
3 ein um einen Halbpreisfahrschein zu kaufen (Euro 0,80)
4 ein um einen 2Fahrten-Halbpreisfahrschein zu kaufen (Euro 1,50)
5 ein um einen 4Fahrten-Halbpreisfahrschein zu kaufen (Euro 3,00)
usw.
lg
EDIT:
P.S.: Willkommen im Forum :)
Dispersio
User
Beiträge: 11
Registriert: Freitag 24. November 2006, 14:24

XtraNine hat geschrieben:Die printkaskade kannst du so ändern:

Code: Alles auswählen

def menue():
    print """Herzlich Willkommen!
Was wollen Sie denn kaufen?
Geben Sie ...'
1 ein um einen Einzelfahrschein zu Kaufen (Euro 1,50)
2 ein um eine Streifenkarte zu Kaufen (Euro 6,00)
3 ein um einen Halbpreisfahrschein zu kaufen (Euro 0,80)
4 ein um einen 2Fahrten-Halbpreisfahrschein zu kaufen (Euro 1,50)
5 ein um einen 4Fahrten-Halbpreisfahrschein zu kaufen (Euro 3,00)
usw."""
Ich glaub das ist aber eher Geschmacksache. Oder?
Hat aber den Vortleil das man nicht dauernd print tipseln muss. :P
XtraNine hat geschrieben:P.S.: Willkommen im Forum :)
Danke
BlackJack

Dispersio hat geschrieben:
BlackJack hat geschrieben: Als nächsten Schritt könntest Du die Daten in entsprechende Datenstrukturen verpacken und damit das Programm sehr viel kürzer und wartungsfreundlicher machen.
Meinst du damit in Klassen und Funktionen?? Denn das versuche ich Krampfhaft zu verstehen. Mein größtest Problem ist zum beispiel, wie kann ich eine Variable aus einer Funktion in der anderen verwenden.
Wenn Du eine Variable innerhalb einer Funktion verwenden willst, dann übergibst Du sie als Argument.

Und an Klassen habe ich noch gar nicht gedacht. Bei dem Programm kommst Du auch mit den vorhandenen Datentypen recht weit.

Zum Beispiel hast Du eine Reihe von verschiedenen Karten die einen Namen und einen Preis haben. Möchtest Du davon etwas ändern oder eine Karte hinzufügen oder löschen, musst Du im Moment Änderungen über das gesamte Programm verteilt vornehmen, und die gleiche Änderung mehrfach. Name und Preis tauchen zum Beispiel beide sowohl im Menü, als auch weiter unten im Programm auf.

Name und Preis gehören zusammen, also bietet es sich an beide in ein Tupel zu stecken, und weil Du eine ganze Reihe davon hast, kannst Du diese Tupel dann wiederum in eine Liste stecken.

Code: Alles auswählen

tickets = [('Einzelfahrschein', 1.50),
           ('Streifenkarte', 6.00),
           ('Halbpreisfahrschein', 0.80)] # usw.
Dann kannst Du das Programm so umschreiben das die Namen der Karten und die Preise immer aus dieser Datenstruktur genommen werden und nicht mehr im Programm verteilt stehen.

Und die vielen gleichartigen Programmteile lassen sich durch Schleifen, oder eben gezielte Zugriffe auf die Liste erheblich verkürzen.

Am Beispiel des Menüs: Dort werden ganz viele ähnliche Texte ausgegeben. Wenn man sich die anschaut, stellt man fest, dass sie sich im Grunde nur an drei Punkten unterscheiden: die Nummer, der Kartenname und der Preis. Für jede Karte wird so ein Text ausgegeben. "Für jede Karte" ist ein guter Hinweis auf eine ``for``-Schleife über die Karten:

Code: Alles auswählen

def menu(tickets):
    print 'Herzlich Willkommen!'
    print 'Was wollen Sie denn kaufen?'
    print 'Geben Sie ...'
    for i, (name, price) in enumerate(tickets):
        print '%2d für %s (EUR %0.2f)' % (i + 1, name, price)
Und wenn der Anwender eine Zahl eingegeben hat um eine Fahrkarte auszuwählen, kommst Du über die Nummer ganz schnell an den entsprechenden Namen und den Preis. Einfach das Element am entsprechenden Index aus der Liste holen.

Ähnlich lässt sich die Wechselgeldberechnung verkürzen. Da wird für jeden Geldschein-/Münzbetrag das gleiche gemacht. Man kann die Beträge in eine Liste stecken und als Ergebnis auch wieder eine Liste berechnen, die für jede(n) Schein/Münze die Anzahl enthält. Für die Ausgabe kann man in die Liste zu den Beträgen auch die Schein-/Münznamen packen und die Ausgabe gleich in einem Durchgang erledigen.
Dispersio
User
Beiträge: 11
Registriert: Freitag 24. November 2006, 14:24

BlackJack hat geschrieben: Am Beispiel des Menüs: Dort werden ganz viele ähnliche Texte ausgegeben. Wenn man sich die anschaut, stellt man fest, dass sie sich im Grunde nur an drei Punkten unterscheiden: die Nummer, der Kartenname und der Preis. Für jede Karte wird so ein Text ausgegeben. "Für jede Karte" ist ein guter Hinweis auf eine ``for``-Schleife über die Karten:

Code: Alles auswählen

def menu(tickets):
    print 'Herzlich Willkommen!'
    print 'Was wollen Sie denn kaufen?'
    print 'Geben Sie ...'
    for i, (name, price) in enumerate(tickets):
        print '%2d für %s (EUR %0.2f)' % (i + 1, name, price)
Hab den Code oben mal geändert
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Über die zueilen 61-103 würde ich mir nochmal Gedanken machen ob man das nicht anders lösen kann. Die machen alle fast das gleiche. Das lässt sich bestimmt noch besser strukturieren. (Ich hasse 1K if Kaskaden, besonders wenn die zu 90% das gleiche mache.).

Anbeiten würde es sich wenn du erstmal die Datenstruktur wählst die BlackJack vorgenschalgen aht. Danach schreibst du eine parametisierte Funktion die über 2 Parameter auf die Datenstruktur zurückgreift. Die Parameter representeiren dabei den jeweiligen index der Datenstrucktur.

z.B. so:

Code: Alles auswählen

def mach_was (x, y):
    return datenstruktur[x] - datenstruktur[y]
So in der art. Somit kannst du dir diese if kasskade erschparen die wirklcih in jeder Verzweigung das gleiche tut :)
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Halt anders!

Code: Alles auswählen

datenstruktur = {
1: 1.5, #einzelfahrschein
2: 6 # streifenkarte
# usw...  
}

def berechne_restgeld(geld, ds, wahl):
    return geld - ds[wahl]

so in etwas müsste das gehen.
Dispersio
User
Beiträge: 11
Registriert: Freitag 24. November 2006, 14:24

XtraNine hat geschrieben:Halt anders!

Code: Alles auswählen

datenstruktur = {
1: 1.5, #einzelfahrschein
2: 6 # streifenkarte
# usw...  
}

def berechne_restgeld(geld, ds, wahl):
    return geld - ds[wahl]

so in etwas müsste das gehen.
So hab ich es eh mit dem dict probiert, aber ich finde das mit ner Liste einfacher und schöner
Antworten