hilfe hausaufgabe python

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.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Dill hat geschrieben: (python 2.6, py3 verhält sich anders bei division)
Deswegen nimmt man ja auch, wie schon mehrmals in diesem Thread angedeutet, `//`.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

ich will aber keine kommentare in meinem code :roll:
http://www.kinderpornos.info
BlackJack

@EyDu: Der Teil über dem Bruchstrich lässt sich etwas kompakter ausdrücken:

Code: Alles auswählen

2 * a   + b * a     a   * (b + 4)
     -1        -1    -1
----------------- = -------------
        2                 2
Spart 5 Zeichen. :-)

Geschlossene Formel um den n. Notenwert zu berechnen (n=0..6) geht auch:

Code: Alles auswählen

In [564]: def f(n):a=(n-1)/3+(n+1)/3;return 2**(2*a-n+2)*3**(n/3+a-n+1)*5**(n/3+1)
   .....:

In [565]: map(f, xrange(7))
Out[565]: [5, 10, 20, 50, 100, 200, 500]
:-)
SuperDAU²
User
Beiträge: 20
Registriert: Sonntag 24. Mai 2009, 12:47

Ich habe mal probiert das Problem umzusetzen. Dazu sei gesagt ich programmiere erst seit einer Woche. Bei mir funktioniert es einwandfrei. Hat jemand einen Verbesserungsvorschlag?

Code: Alles auswählen

#!/usr/bin/env python

# Bankautomat
# 1. Scheine definieren und auszuzahlenden Betrag ermitteln
# 2. Ueberpruefung, ob betrag > 0 ist
# 3. Ueberpruefung, ob betrag - Schein 1 >= 0 ist
# 4. wenn Bedingung erfuellt ist, Schein 1 zu auszahlung hinzufuegen
# 5. Schein 1 von betrag subtrahieren
# 6. Wiederholung mit gleichem Schein bis betrag - Schein 1 < 0 ist
# 7. Schritte 2.-5. mit allen Scheinen durchfuehren bis betrag < 0 ist
# 8. Auszuzahlende Scheine ausgeben

scheine = [500, 200, 100, 50, 20, 10, 5]
trennzeichen = ', '
auszahlung = []
betrag = int(input('Wieviel soll ausgezahlt werden? '))

while betrag > 0:
    while (betrag - int(scheine[0])) >= 0:
        auszahlung.append('500')
        betrag = betrag - int(scheine[0])
    while (betrag - int(scheine[1])) >= 0:
        auszahlung.append('200')
        betrag = betrag - int(scheine[1])
    while (betrag - int(scheine[2])) >= 0:
        auszahlung.append('100')
        betrag = betrag - int(scheine[2])
    while (betrag - int(scheine[3])) >= 0:
        auszahlung.append('50')
        betrag = betrag - int(scheine[3])
    while(betrag - int(scheine[4])) >= 0:
        auszahlung.append('20')
        betrag = betrag - int(scheine[4])
    while (betrag - int(scheine[5])) >= 0:
        auszahlung.append('10')
        betrag = betrag - int(scheine[5])
    while (betrag - int(scheine[6])) >= 0:
        auszahlung.append('5')
        betrag = betrag - int(scheine[6])

print 'Ihre Auszahlung: ', trennzeichen.join(auszahlung)
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

SuperDAU² hat geschrieben:Hat jemand einen Verbesserungsvorschlag?
Nur um mal 2 zu nennen:

- Die ganzen Umwandlungen in ``int()``'s sind unnötig, da du die Werte ja schon als Integer in die Liste einträgst

- Warum werden beim Anhängen Strings benutzt? Du kannst normale Zahlen nutzen und diese später für ``join()`` mit ``map()`` aufbereiten. ``map()`` wendet auf jedes Element der Liste eine bestimmte Funktion an. In dem Fall also:

Code: Alles auswählen

map(str, auszahlung)
Und das ganze kann dann ge``join()``'t werden.
BlackJack

@SuperDAU²:

0. Statt `input()` besser `raw_input()` verwenden.

1. Die Bedingung der ``while``-Schleife so formulieren, dass dort keine Subtraktion benötigt wird. Das ist fast nur simples Umformen der Ungleichung.

2. Da steht sieben mal fast das gleiche. Die Unterschiede identifizieren, durch Variable(n) ersetzen, und eine ``for``-Schleife schreiben in der nur noch einmal eine ``while``-Schleife steht.

3. Mal erklären was die `int()`-Aufrufe in dem Programm bewirken.

4. Das alles in einer Funktion verschwinden lassen.
SuperDAU²
User
Beiträge: 20
Registriert: Sonntag 24. Mai 2009, 12:47

Danke für die tollen Tips. Nun sieht das Programm so aus.

Code: Alles auswählen

#!/usr/bin/env python

# Bankautomat
# 1. Scheine definieren und auszuzahlenden Betrag ermitteln
# 2. Ueberpruefung, ob betrag > 0 ist
# 3. Ueberpruefung, ob betrag - Schein i >= 0 ist
# 4. wenn Bedingung erfuellt ist, Schein i zu auszahlung hinzufuegen
# 5. Schein i von betrag subtrahieren
# 6. Wiederholung mit gleichem Schein bis betrag - Schein i < 0 ist
# 7. dann i um 1 erhoehen --> naechster Schein
# 8. Schritte 2.-7. bis alle Scheine fertig sind
# 9. Auszuzahlende Scheine ausgeben

scheine = [500, 200, 100, 50, 20, 10, 5]
i = 0
trennzeichen = ', '
auszahlung = []
betrag = int(input('Wieviel soll ausgezahlt werden? '))

while betrag > 0:
    while (betrag - scheine[i]) >= 0:
        auszahlung.append(str(scheine[i]))
        betrag = betrag - scheine[i]

    i = i + 1

print 'Ihre Auszahlung:', trennzeichen.join(auszahlung)
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

du solltest input wirklich durch raw_input ersetzten.

alles was über input eingegeben wird wird direkt interpretiert, input gibt also das gleiche zurück was dir der interpreter zurückgibt wenn du eine zeile dort eingibst.
bei zahlen geht das noch gut, aber wenn du zb einen string eingibst knallt es... kannst ja mal probieren. insb. was passiert wenn du "schein" oder irgendwas anderes was zu dem zeitpunkt schon gebunden ist eingibst..

raw_input() gibt immer einen string zurück.

was soll das "trennzeichen"?

",".join(a) geht auch.

kannste aber natürlich auch so lassen. wenn der kunde nen bankautomaten will, der per ";" trennt biste dann schneller fertig :)
http://www.kinderpornos.info
SuperDAU²
User
Beiträge: 20
Registriert: Sonntag 24. Mai 2009, 12:47

Danke, habe ich geändert.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

wenn du lust hast kannste ja mal probieren die hausfrauenmischung zu implementieren.

http://de.wikipedia.org/wiki/Hausfrauenmischung

(ohne oben zu spicken, ausser bei der lösung von eydu =) )
http://www.kinderpornos.info
BlackJack

@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.
SuperDAU²
User
Beiträge: 20
Registriert: Sonntag 24. Mai 2009, 12:47

Ich habe es mal probiert:

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)
Allerdings habe ich folgende Ausgabe:

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
Das gibt zwar exakt 675, aber trotzdem wird die while-Schleife nicht richtig ausgeführt.

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)
Um eine bessere Übersicht zu erhalten, hätte ich gerne etwas wie das

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

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.
SuperDAU²
User
Beiträge: 20
Registriert: Sonntag 24. Mai 2009, 12:47

Hier nochmals der überarbeitete Code:

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)
Mir kam die Idee es so umzuschreiben, aber dann bleibt das Programm stehen.

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)
Wo ist der Fehler? Der Interpreter bleibt in Zeile 16 stecken.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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

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.
SuperDAU²
User
Beiträge: 20
Registriert: Sonntag 24. Mai 2009, 12:47

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"?
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Was ist denn das genaue Problem? Falls es um die Anzahl der Vorkommnisse einer Sorte geht: Listen haben die Methode `count()`, die als Argument die Bezeichnung des zu zählenden Elements nimmt.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@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.
SuperDAU²
User
Beiträge: 20
Registriert: Sonntag 24. Mai 2009, 12:47

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?

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)
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?
Zuletzt geändert von SuperDAU² am Sonntag 24. Mai 2009, 22:53, insgesamt 1-mal geändert.
Antworten