hilfe hausaufgabe python
@SuperDAU²: Du berechnest immer noch ``betrag - scheine`` zweimal. Wie gesagt, die Bedingung in der inneren ``while``-Schleife kann man so umstellen, dass man da nichts ausrechnen muss.
Und statt der äusseren ``while``-Schleife würde ich eine ``for``-Schleife über `scheine` schreiben. Dann wirst Du das `i` los. Wenn Du nicht alle Scheine durchlaufen möchtest, auch wenn der `betrag` schon bei 0 ist, kannst Du die Schleife auch immer noch durch ein `break` verlassen.
Du gehst auch nicht mit dem Fall um, wenn der Anwender einen Betrag eingibt, der nicht durch die vorhandenen Scheine abgebildet werden kann.
Und statt der äusseren ``while``-Schleife würde ich eine ``for``-Schleife über `scheine` schreiben. Dann wirst Du das `i` los. Wenn Du nicht alle Scheine durchlaufen möchtest, auch wenn der `betrag` schon bei 0 ist, kannst Du die Schleife auch immer noch durch ein `break` verlassen.
Du gehst auch nicht mit dem Fall um, wenn der Anwender einen Betrag eingibt, der nicht durch die vorhandenen Scheine abgebildet werden kann.
Ich habe es mal probiert:
Allerdings habe ich folgende Ausgabe:
Das gibt zwar exakt 675, aber trotzdem wird die while-Schleife nicht richtig ausgeführt.
Edit: Problem selbst gelöst:
Um eine bessere Übersicht zu erhalten, hätte ich gerne etwas wie das
Code: Alles auswählen
#!/usr/bin/env python
# Bankautomat mit Hausfrauenmischung
scheine = [500, 200, 100, 50, 20, 10, 5]
scheine2 = [5, 10, 20, 50, 100, 200, 500]
trennzeichen = ', '
auszahlung = []
betrag = int(raw_input('Wieviel soll ausgezahlt werden? '))
for i in range(0, 7):
if betrag >= scheine2[i]:
auszahlung.append(str(scheine2[i]))
betrag = betrag - scheine2[i]
continue
while betrag > 0:
while betrag >= scheine[i]:
auszahlung.append(str(scheine[i]))
betrag = betrag - scheine[i]
i = i + 1
print 'Ihre Auszahlung:', trennzeichen.join(auszahlung)
Code: Alles auswählen
Wieviel soll ausgezahlt werden? 675
Ihre Auszahlung: 5, 10, 20, 50, 100, 200, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
Edit: Problem selbst gelöst:
Code: Alles auswählen
#!/usr/bin/env python
# Bankautomat
scheine = [500, 200, 100, 50, 20, 10, 5]
scheine2 = [5, 10, 20, 50, 100, 200, 500]
trennzeichen = ', '
u = 0
auszahlung = []
betrag = int(raw_input('Wieviel soll ausgezahlt werden? '))
for i in range(0, 7):
if betrag >= scheine2[i]:
auszahlung.append(str(scheine2[i]))
betrag = betrag - scheine2[i]
continue
while betrag > 0:
while betrag >= scheine[u]:
auszahlung.append(str(scheine[u]))
betrag = betrag - scheine[u]
u = u + 1
print 'Ihre Auszahlung:', trennzeichen.join(auszahlung)
Code: Alles auswählen
Ihre Auszahlung: 2*200, 1*100, 2*50, 3*20, 1*10, 1*5
Zuletzt geändert von SuperDAU² am Sonntag 24. Mai 2009, 17:13, insgesamt 1-mal geändert.
SuperDAU²: Was denkst Du was `i` in Zeile 15 für einen Wert hat? Überprüf mal ob Deine Erwartung mit der Realität übereinstimmt.
Und die erste Schleife sollte definitiv über die `scheine2` gehen, ohne den Index. Und man sollte dafür keine extra Liste angeben, wenn man die auch aus `scheine` erstellen kann -> `reversed()`.
Das ``continue`` ist sinnfrei.
Und die erste Schleife sollte definitiv über die `scheine2` gehen, ohne den Index. Und man sollte dafür keine extra Liste angeben, wenn man die auch aus `scheine` erstellen kann -> `reversed()`.
Das ``continue`` ist sinnfrei.
Hier nochmals der überarbeitete Code:
Mir kam die Idee es so umzuschreiben, aber dann bleibt das Programm stehen.
Wo ist der Fehler? Der Interpreter bleibt in Zeile 16 stecken.
Code: Alles auswählen
#!/usr/bin/env python
scheine = [5, 10, 20, 50, 100, 200, 500]
trennzeichen = ', '
u = 0
auszahlung = []
betrag = int(raw_input('Wieviel soll ausgezahlt werden? '))
for i in range(0, 7):
if betrag >= scheine[i]:
auszahlung.append(str(scheine[i]))
betrag = betrag - scheine[i]
scheine.reverse()
while betrag > 0:
while betrag >= scheine[u]:
auszahlung.append(str(scheine[u]))
betrag = betrag - scheine[u]
u = u + 1
print 'Ihre Auszahlung:', trennzeichen.join(auszahlung)
Code: Alles auswählen
#!/usr/bin/env python
scheine = [5, 10, 20, 50, 100, 200, 500]
trennzeichen = ', '
u = 0
auszahlung = []
betrag = int(raw_input('Wieviel soll ausgezahlt werden? '))
for i in range(0, 7):
if betrag >= scheine[i]:
auszahlung.append(str(scheine[i]))
betrag = betrag - scheine[i]
scheine.reverse()
for u in range(0, 7):
while betrag > 0:
while betrag >= scheine[u]:
auszahlung.append(str(scheine[u]))
betrag = betrag - scheine[u]
print 'Ihre Auszahlung:', trennzeichen.join(auszahlung)
Da du die Scheine umkehrst, ist scheine zu Beginn 500. Ist der Betrag < 500, dann ist die Bedingung der inneren while-Schleife nie erfüllt, folglich wird der Betrag nicht verringert und die äußere while-Schleife wird zur Endlosschleife.
SuperDAU²: Vergiss mal die erste auf Modulebene Schleife und gehe die zweite in Gedanken mit dem Betrag 15 mal Schritt für Schritt in Gedanken durch. Dann solltest Du drauf kommen warum das eine Endlosschleife werden kann.
Ich habe das Problem jetzt verstanden. Aber ich finde keine andere Lösung dazu als die vorherige Variante.
Was ist mit meiner Frage zwecks der Übersichtlichkeit? Wie bekomme ich eine Ausgabe in der Art von "6*500, 1*200, 1*100, 1*50, 3*20, 1*10, 2*5"?
Was ist mit meiner Frage zwecks der Übersichtlichkeit? Wie bekomme ich eine Ausgabe in der Art von "6*500, 1*200, 1*100, 1*50, 3*20, 1*10, 2*5"?
@BlackJack: Danke für den Hinweis. Ich hatte die Umformung wegen der besseren Lesbarkeit nicht vorgenommen. Für mein Produktivsystem werde ich dies nun natürlich aus Performance-Gründen entsprechend ändern.
Zuletzt geändert von EyDu am Sonntag 24. Mai 2009, 22:52, insgesamt 2-mal geändert.
Das Leben ist wie ein Tennisball.
Vielen Dank an snafu für den Tipp mit "count()". Irgendwie werde ich das Gefühl nicht los, dass man "auszahlungsliste" leichter hätte erstellen können. Geht das etwa wieder mit einer for-Schleife?
Außerdem habe ich eine weitere Frage: Wenn ein Schein in "auszahlung" nicht vorkommt, wie kann ich ihn dann in der "auszahlungsliste" entfernen?
Oder habt ihr eine andere bzw bessere Lösung für das Problem?
Code: Alles auswählen
#!/usr/bin/env python
# Bankautomat
scheine = [5, 10, 20, 50, 100, 200, 500]
u = 0
multi = '*'
trenn = ', '
trenn2 = ''
auszahlung = []
betrag = int(raw_input('Wieviel soll ausgezahlt werden? '))
for i in range(0, 7):
if betrag >= scheine[i]:
auszahlung.append(str(scheine[i]))
betrag = betrag - scheine[i]
scheine.reverse()
while betrag > 0:
while betrag >= scheine[u]:
auszahlung.append(str(scheine[u]))
betrag = betrag - scheine[u]
u = u + 1
auszahlungsliste = [str(auszahlung.count('500')), multi, str(scheine[0]), trenn,
str(auszahlung.count('200')), multi, str(scheine[1]), trenn,
str(auszahlung.count('100')), multi, str(scheine[2]), trenn,
str(auszahlung.count('50')), multi, str(scheine[3]), trenn,
str(auszahlung.count('20')), multi, str(scheine[4]), trenn,
str(auszahlung.count('10')), multi, str(scheine[5]), trenn,
str(auszahlung.count('5')), multi, str(scheine[6])]
print 'Ihre Auszahlung:', trenn2.join(auszahlungsliste)
Oder habt ihr eine andere bzw bessere Lösung für das Problem?
Zuletzt geändert von SuperDAU² am Sonntag 24. Mai 2009, 22:53, insgesamt 1-mal geändert.
@SuperDAU²: Schau Dir mal die `zip()`-Funktion an, Zeichenkettenformatierung mittels ``%``-Operator, und dann werd endlich mal `i` und `u` los, indem Du direkt über die Elemente der Liste iterierst.
Zumindest solltest Du aber die Initialisierung von `u` direkt vor der Schleife machen und nicht irgendwo oben, als weit weg von der Stelle wo's letztendlich gebraucht wird.
Zumindest solltest Du aber die Initialisierung von `u` direkt vor der Schleife machen und nicht irgendwo oben, als weit weg von der Stelle wo's letztendlich gebraucht wird.
War doch klar, dass Werte von Geldscheinen auf den ersten binären Nachkommastellen von PI beruhen:
Sollten also neue Noten eingeführt werden, so ergeben sich die Beträge:
Code: Alles auswählen
>>> reduce(lambda a,b: a+[(a[-1]*(4+b))/2], tuple((int(math.pi*2**8)>>i)&1 for i in range(7, 1, -1)), [5])
[5, 10, 20, 50, 100, 200, 500]
Code: Alles auswählen
>>> reduce(lambda a,b: a+[(a[-1]*(4+b))/2], tuple((int(math.pi*2**18)>>i)&1 for i in range(16, 1, -1)), [5])
[5, 10, 25, 50, 100, 250, 500, 1000, 2000, 4000, 10000, 25000, 62500, 156250, 390625, 976562]
Das Leben ist wie ein Tennisball.
@BlackJack:
Den Tipp mit zip() habe ich verstanden, aber was du mit
PS: Hast du die Fragen im meinem letzten Post gesehen?
MfG
Den Tipp mit zip() habe ich verstanden, aber was du mit
meinst, weiß ich leider nicht. Könntest du mir bitte ein Beispiel geben?Zeichenkettenformatierung mittels ``%``-Operator, und dann werd endlich mal `i` und `u` los, indem Du direkt über die Elemente der Liste iterierst.
PS: Hast du die Fragen im meinem letzten Post gesehen?
MfG
String-Formatierung:
Indizes:
Code: Alles auswählen
>>> "formatiere mich; int: %d, str: %s, float: %f" % (42, "spam", 3.1415)
'formatiere mich; int: 42, str: spam, float: 3.141500'
Code: Alles auswählen
for schein in scheine:
if betrag >= scheine:
auszahlung.append(str(scheine))
betrag = betrag - scheine
Das Leben ist wie ein Tennisball.
Ich hätte da jetzt noch diesen schicken 3-Zeiler im Angebot:
Berechnet die Haushaltsmischung. Falls beim Betrag ein Rest bleiben sollte, also der Betrag nicht durch 5 teilbar ist, fällt dieser Rest einfach weg. Testlauf:
Ein Beispiel für Zeichenkettenformatierung ist auch drin. 
Code: Alles auswählen
S=500,200,100,50,20,10,5;f=reduce;print', '.join('%d*%d'%(a,b) for a,b in zip((
lambda r,x:[a+b for a,b in zip(f(lambda (a,b),c:(a+[b//c],b%c),S,([],x))[0],
r[::-1])])(*f(lambda(a,b),c:(a+[b>=c],b-(b>=c)*c),S[::-1],([],input()))),S))
Code: Alles auswählen
bj@s8n:~$ python forum2.py
355
0*500, 0*200, 2*100, 2*50, 2*20, 1*10, 1*5

@EyDu:
Das mit der Stringformatierung hab ich jetzt auch verstanden. Wo mir das weiterhilft muss ich noch herausfinden
und zu dem 2. Codeblock:
Wenn ich den in mein Programm einfüge, wird dieser Block einfach übersprungen. Außerdem verstehe ich nicht, womit "schein" definiert ist.
@BlackJack:
Toll, wenn du mir den 3-Zeiler noch erklären kannst.
Das mit der Stringformatierung hab ich jetzt auch verstanden. Wo mir das weiterhilft muss ich noch herausfinden

und zu dem 2. Codeblock:
Wenn ich den in mein Programm einfüge, wird dieser Block einfach übersprungen. Außerdem verstehe ich nicht, womit "schein" definiert ist.
@BlackJack:
Toll, wenn du mir den 3-Zeiler noch erklären kannst.

Immerhin passt der Code schon auf eine Bildschirmzeile:
Und der Restbetrag erledigt sich ganz von alleine.
@SuperDAU²: du sollst den Code nicht einfach bei dir einfügen, er ersetzt deine erste for-Schleife des Codes. Wenn du das mit "schein" nicht verstehst, dann wirf noch einmal einen Blick ins Tutorial.
Edit: Indizes gespart.
Edit2: Modulo existiert...
Code: Alles auswählen
print reduce(lambda(a,c),b:(a%b,c+(a/b and[(a/b,b)]or[])),[500,200,100,50,20,10,5],(input(),[]))
print reduce(lambda(a,c),b:(a%b,c+[(a/b,b)]),[500,200,100,50,20,10,5],(input(),[]))
Code: Alles auswählen
sebastian@sepp:~$ python test.py
227
(2, [(1, 200), (1, 20), (1, 5)])
227
(2, [(0, 500), (1, 200), (0, 100), (0, 50), (1, 20), (0, 10), (1, 5)])
@SuperDAU²: du sollst den Code nicht einfach bei dir einfügen, er ersetzt deine erste for-Schleife des Codes. Wenn du das mit "schein" nicht verstehst, dann wirf noch einmal einen Blick ins Tutorial.
Edit: Indizes gespart.
Edit2: Modulo existiert...

Das Leben ist wie ein Tennisball.
Da waren doch glatt noch 21 Zeichen "zuviel" drin:
@SuperDAU²: Was ist denn daran nicht verständlich!? 
Code: Alles auswählen
S=500,200,100,50,20,10,5;f=reduce;r,x=f(lambda(a,b),c:([b>=c]+a,b-(b>=c)*c),
S[::-1],([],input()));print', '.join('%d*%d'%(a,b)for a,b in zip([a+b for a,b
in zip(f(lambda(a,b),c:(a+[b/c],b%c),S,([],x))[0],r)],S))

@BlackJack: ich hab mir deine Version mal genauer angeschaut, da haben wir wohl nahezu identischen Code produziert.
Und mal mit Formatierung:
Und mal mit Formatierung:
Code: Alles auswählen
print ", ".join("%d*%d"%x for x in reduce(lambda(a,c),b:(a%b,c+[(a/b,b)]),[500,200,100,50,20,10,5],(input(),[]))[1])
Code: Alles auswählen
sebastian@sepp:~$ python test.py
227
0*500, 1*200, 0*100, 0*50, 1*20, 0*10, 1*5
Das Leben ist wie ein Tennisball.
@EyDu: Jup, das sieht von der Struktur her aus wie meins. Nur das ich die Haushaltsmischung noch mit aufgenommen habe. Jetzt mit 41 Zeichen weniger, bin jetzt bei 173:
Die Zeichenkettenformatierung könntest Du auch noch weiter reinziehen und damit den Generatorausdruck einsparen.
Code: Alles auswählen
f=reduce;r,x=f(lambda(a,b),c:([(b>=c,c)]+a,b-(b>=c)*c),[5,10,20,50,100,200,500],
([],input()));print', '.join(f(lambda(a,b),(c,d):(a+['%d*%d'%(b/d+c,d)],b%d),r,
([],x))[0])