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

KlaliB hat geschrieben:1x100€ 1x50€ 1x20€ 1x5€
aber wie soll ich das machen ich mach auch byte python durchgelesen und so
mit tupel oder liste allein geht das nicht
Die Rechnung ist doch im Prinzip so:

Ziehe vom aktuellen Betrag den höchsten verfügbaren Schein ab

1. 175 - 100 = 75 -> 1 Hunderter weg, Rest 75
2. 75 - 100 geht nicht -> versuche mit nächsttieferem
3. 75 - 50 = 25 -> 1 Fünfziger, Rest 25
usw.

Eigentlich ist das total banal. Aber gut, ich kann verstehen, dass man das als Anfänger anders sieht.

EDIT: Oder besser gesagt, da ich die Funktion jetzt auch geschrieben habe:

1. Teile den Betrag durch den höchstmöglichen Scheinwert um die Anzahl der Scheine zu bekommen
2. Wenn mehr als 0 Scheine herauskommen: Ziehe diese Anzahl * den Scheinwert vom Betrag ab
3. Mache eine Ausgabe, die sagt, wieviele Scheine mit welchem Scheinwert es gab und wie hoch der Rest ist
4. Wiederhole Schritt 1-3 für den nächsttieferen Scheinwert

Du könntest dies mal untereinander in Python ausgedrückt schreiben und dein Ergebnis (also den Code) posten. Dann kann man über Optimierungen nachdenken, da ja auffällt, dass sich eine Menge wiederholt und immer nur ein paar Zahlen ausgetauscht werden. Viel Erfolg. :)
KlaliB
User
Beiträge: 50
Registriert: Mittwoch 13. Mai 2009, 13:28

Naja, egal :)
hab es zwar nicht geschaft, aber werde mir morgen wohl was anderes einfallen lassen. mal sehen :wink: .
danke für die hilfe :wink:
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@snafu: Das funktioniert aber nur bei recht kleinen und überschaubaren Objekten. Ab einer gewissen Komplexität ist Planung notwendig, da man nicht mehr alles überschauen kann und so unnötige Entwicklungen vermiden werden können. Das wird spätestens dann notwedig, wenn man eine Zeitabschätzung machen muss oder mit mehreren Personen zusammenarbeitet. Hat eben nicht jeder sein eigenes Projekt, an dem er so lange rumwerkeln kann wie er möchte ;-)
Das Leben ist wie ein Tennisball.
Benutzeravatar
snafu
User
Beiträge: 6831
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich sprach ja eigentlich auch die ganze Zeit von Einzelprojekten. ;)
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

snafu, du kannst aber mit sicherheit deine effizienz erhöhen.
du sollst ja kein komplettes design basteln und auch wirklich jedes UML diagram malen... :shock:

was aber sehr viel bringt ist sich erstmal gedanken zu machen was passieren soll, das irgendwie malen, das dann wiederum in einen rudimentären testbaren code packen und dann nach und nach aufbauen. tdd, sicher schonmal gehört. du musst da auch garkeine akademisches tdd verwenden. es reicht meist wenn die tests in deinem kopf sind. randfälle andere spezialfälle testen.

ich arbeite zb viel für embedded systems mit statecharts. das ist herrlich. ich kann erst wunderbar die logik malen, habe direkt ein testbares grundgerüst und kann das nach und nach mit leben füllen und ständig testen. statecharts sind aber nur für ereignisgetriebene systeme sinnvoll. (ua auch GUIs!)



und ich konnte mich leider nicht zurückhalten...
(wenn du diesen code so abgibst fliegst du auf jeden auf. du solltest ihn mindestens verstehen und die bezeichner und kommentare in deine sprache ändern)

(python 2.6, py3 verhält sich anders bei division)

Code: Alles auswählen


"""
Hausfrauenmischung
"""

scheine = [5, 10, 20, 50, 100, 200, 500]

betrag = raw_input("Wieviel soll ausgezahlt werden: ")

#betrag is jetzt noch eine zeichenkette, damit kann man nicht rechen
#also machen wir eine zahl draus
betrag = int(betrag)

#der betrag muss glatt durch 5 teilbar sein,
#sonst kann er nicht ausgezahlt werden
if betrag % 5 != 0:
    print "dieser betrag kann nicht ausgezahlt werden!"

else:

    #in diese liste werden die auszuuahlenden scheine reingelegt
    ausgabefach = []

    #jeden schein moeglichst einmal ausgeben
    for schein in scheine:
        print "\n%dEUR schein auszahlen?" % schein
        if betrag < schein:
            print "der %dEUR schein ist groesser als der auszuzahlende restbetrag. abbrechen.\n" % schein
            break

        print "lege einen %dEUR schein ins ausgabefach" % schein
        ausgabefach.append(schein)

        betrag = betrag - schein
        #print "der rest des auszuzahlenden betrags ist jetzt noch %dEUR" % betrag


    #der rest des betrages wird mit moeglichst grossen scheinen ausgezahlt
    #dazu drehen wir erst schein liste um, damit sie mit dem groesten schein anfaengt
    scheine.reverse()

    for schein in scheine:
        #wieviele von diesem schein passen noch in den betrag
        anzahl_schein = betrag / schein

        if anzahl_schein > 0:
            print "vom %dEUR schein passen %d in den restbetrag von %dEUR" % (schein, anzahl_schein, betrag)
            #diesen schein jetzt anzahl_schein mal ins ausgabefach legen
            for s in range(anzahl_schein):
                ausgabefach.append(schein)
                betrag = betrag - schein

        else:
            print "vom %dEUR schein passt keiner in den restbetrag von %dEUR" % (schein, betrag)

    #jetzt das ausgabefach noch sortieren, damit die scheine auch beinander sind
    ausgabefach.sort()

    #ausgeben
    print
    print "hier ihre auszahlung: ", ausgabefach
http://www.kinderpornos.info
Benutzeravatar
snafu
User
Beiträge: 6831
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@Dill:

Vielleicht besser in Zeile 17:

Code: Alles auswählen

if betrag % scheine[0] != 0:
Das macht spätestens dann Sinn, wenn der Automat mit einem bestimmten Kontingent an Scheinen ausgestattet wird und irgendwann bemerkt, dass er keine Fünfer mehr hat. ;) Gut, dann würde man wohl auch eher mit Dictionaries arbeiten...
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

ja sicher, da könnte man so einiges anders machen.

ich wollte den code halt so verständlich wie möglich halten.
das wäre doch auch mal ein contest statt so kurz wie möglich so verständlich wie möglich. was mich noch stört sind zb die verschachtelten kontrollstrukturen.
http://www.kinderpornos.info
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ja, so verständlich wie möglich ...

Wer viel Zeit mitgebracht hat:

Code: Alles auswählen

import itertools, functools
betrag = 15
scheine = reduce(lambda a,b: a+[2*a[-1]+b*a[-1]/2], (0, 0, 1)*2, [5])
print [dict([(len(list(v)), k) for (k,v) in itertools.groupby(x)]) for x in map(functools.partial(filter, bool), set(map(tuple, map(sorted, filter(lambda x: sum(x)==betrag, itertools.product(scheine+[0], repeat=1+betrag/min(scheine)))))))]
Oder noch mehr Zeit:

Code: Alles auswählen

import itertools, functools
betrag = 15
print [dict([(len(list(v)), k) for (k,v) in itertools.groupby(x)]) for x in map(functools.partial(filter, bool), set(map(tuple, map(sorted, filter(lambda x: sum(x)==betrag, itertools.product(reduce(lambda a,b: a+[2*a[-1]+b*a[-1]/2], (0, 0, 1)*2, [5])+[0], repeat=betrag))))))]
Das Leben ist wie ein Tennisball.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

ich würde ja gerne mal das gesicht der lehrerin sehen wenn unser freund diese lösung abgibt.
http://www.kinderpornos.info
Benutzeravatar
snafu
User
Beiträge: 6831
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Code: Alles auswählen

#!/usr/bin/env python

sorten = [5, 10, 20, 50, 100, 200, 500]


def moeglichst_jeden_einmal(betrag):
    auszahlung = []
    for sorte in sorten:
        if betrag / sorte:
            auszahlung.append(sorte)
            betrag -= sorte
        else:
            break
    return auszahlung


def auszahlen(betrag):
    auszahlung = moeglichst_jeden_einmal(betrag)
    betrag -= sum(auszahlung)
    for sorte in reversed(sorten):
        for _ in xrange(betrag / sorte):
            auszahlung.append(sorte)
            betrag -= sorte
    return sorted(auszahlung)


if __name__ == '__main__':
    try:
        betrag = int(raw_input('Wieviel soll ausgezahlt werden: '))
    except ValueError:
        print 'Bitte nur ganze Zahlen eingeben.'
        exit(1)
    
    if betrag % sorten[0] or not betrag:
        print 'Dieser Betrag kann nicht ausgezahlt werden.'
        exit(2)
    
    auszahlung = auszahlen(betrag)
    
    print 'Ihre Auszahlung:'
    
    for sorte in sorted(set(auszahlung)):
        print '%d x %d Euro' % (auszahlung.count(sorte), sorte)
Zuletzt geändert von snafu am Sonntag 24. Mai 2009, 17:56, insgesamt 2-mal geändert.
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: 6831
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
Antworten