Seite 1 von 1
Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Donnerstag 2. September 2010, 12:52
von mcdaniels
Habe in Anlehnung an das Buch "Einstieg in Python3" folgendes Programm geschrieben, welches u.a. im Moment nur Additionsaufgaben stellt.
Code: Alles auswählen
import random
def auswaehlen():
print('********************************************************')
print('== Einfache Rechenübungen mit den Grundrechnungsarten ==')
print('********************************************************')
print ('1 .. Addieren 2 .. Subtrahieren')
rechenart = int(input('Bitte wählen: '))
if rechenart == 1:
rechnen()
else:
print ('Leider noch nicht eingebaut')
def zahlen_generieren():
random.seed()
zufallszahl1 = random.randint(1,10)
zufallszahl2 = random.randint(1,10)
ergebnis = zufallszahl1 + zufallszahl2
return(ergebnis, zufallszahl1, zufallszahl2) #gibt TUPEL zurück!
def rechnen():
rechnungen = int(input ('Wieviele Rechnungen:'))
while rechnungen > 0:
zahlen = zahlen_generieren() #TUPEL [0] = ergebnis, [1] = zufallszahl1, [2] = zufallszahl2
rechnungen -= 1
print ('Bitte berechnen Sie',zahlen[1],'+',zahlen[2])
eingabe = int(input ('Ihre Eingabe: '))
if eingabe == zahlen[0]:
print('Stimmt, Sie haben richtig gerechnet')
elif eingabe != zahlen[0]:
print('Leider stimmt Ihre Berechnung nicht!')
auswaehlen()
auswaehlen()
Beim Start wird die Funktion auswaehlen() aufgerufen, durchläuft dann die Auswahl der Rechenart + nach Auswahl die Funktion rechnen(). Nach Abschluss der Funktion rechnen() wird das Programm allerdings anscheinend genau dort beendet. Also kommt die letzte Zeile, die das Programm wieder von "vorne" starten sollte nicht zum Zug.
Deshalb habe ich nun als letzte Zeile in der Funktion rechnen() abermals auswaehlen() aufgerufen. Nun funktioniert es, wie ich es mir vorstelle.
ABER: Ist dies wirklich genau so im Sinne des Erfinders bzw. macht man das so, wie ich es gelöst habe, oder gibt es elegantere Wege um Python zu sagen: "Noch einmal von vorne?"
LG
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Donnerstag 2. September 2010, 13:02
von bwbg
Sicherlich macht das Programm vorerst, was du willst. ABER (es gibt immer ein aber) das Programm wird dir nach ein paar (mehr) Durchläufen um die Ohren fliegen, wenn das Rekursionslimit erreicht ist.
"auswählen" ruft "rechnen" ruft "auswählen" ruft "rechnen" ... you've got the point?
Schreibe eine "main"-Funktion welche das ganze in einer Schleife mit entsprechender Abbruchbedingung ausführt.
Grüße ... Heiko
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Donnerstag 2. September 2010, 13:09
von cofi
mcdaniels hat geschrieben:Code: Alles auswählen
zahlen = zahlen_generieren() #TUPEL [0] = ergebnis, [1] = zufallszahl1, [2] = zufallszahl2
Kommentiere nie, was der Code auch sagen koennte:
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Donnerstag 2. September 2010, 14:47
von BlackJack
@mcdaniels: `random.seed()` brauchst Du nicht. Unter bestimmten Umständen kann das dem "Zufall" sogar abträglich sein.
Bei `zahlen_generieren()` ist das `ergebnis` doch von der Operation abhängig, das heisst Du müsstest später für andere Operationen auch wieder Zufallszahlen in einer entsprechenden Funktion generieren, obwohl das an sich doch (fast) unabhängig von der Operation ist. Und wenn die Operation vor dem Aufruf der Funktion bekannt ist, dann ist das `ergebnis` redundant, denn das ergibt sich ja aus den beiden Zahlen und der Operation.
Die ``while``-Schleife in `rechnen()` sollte man durch eine ``for``-Schleife ersetzen. ``while``-Schleifen sind für Fälle, wo man vor Eintritt in die Schleife noch nicht weiss wie oft die Schleife (maximal) durchlaufen werden wird.
Bei einem ``if`` in einem folgenden ``elif`` genau die gegenteilige Bedingung zu prüfen ist überflüssig. Dafür gibt es ``else``.
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Donnerstag 2. September 2010, 15:14
von mcdaniels
Hallo alle!
Danke fürs Feedback.
@Blackjack: Natürlich hast du recht, da gehört noch einiges verbessert UND angepasst.
@cofi: Jawohl wird gemacht
@bwbg:
Schreibe eine "main"-Funktion welche das ganze in einer Schleife mit entsprechender Abbruchbedingung ausführt.
Du meinst, das ganze in def main() "einpacken"?
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Donnerstag 2. September 2010, 15:53
von mcdaniels
Könnt Ihr mir eventuell kurz "zeigen" wie das mit dem Mainloop aussehen soll? Ich seh da momentan nicht durch...

Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Donnerstag 2. September 2010, 16:07
von cofi
`auswaehlen` umgebaut:
Code: Alles auswählen
def auswaehlen():
print('********************************************************')
print('== Einfache Rechenübungen mit den Grundrechnungsarten ==')
print('********************************************************')
while True:
print ('1 .. Addieren 2 .. Subtrahieren nicht-zahl .. Abbrechen')
try:
rechenart = int(input('Bitte wählen: '))
if rechenart == 1:
rechnen()
else:
print ('Leider noch nicht eingebaut')
except ValueError:
break
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Donnerstag 2. September 2010, 19:06
von mcdaniels
Hey Cofi!
Danke Dir...
Allerdings wurde oben etwas betreffend Funktion main() erwähnt. Ist dies nun sinnvoll bzw. "Standard"? Ist Main als "Funktion" zu verstehen, die quasi "das gesamte Programm" inkl. weiterer Funktionen "beinhaltet" (Alles unter main():) also eingerückt... ?
Code: Alles auswählen
def main():
def funktion1():
anweisung
anweisung
anweisung
def funktion2():
anweisung
....
if __name__ == "__main__":
main()
Ist das ein mainloop und wann macht man das so? Vor allem müsste man ja dennoch innerhalb der Funktion main() die andren Funktionen aufrufen, damit das Programm läuft, oder sehe ich das falsch?
LG
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Donnerstag 2. September 2010, 19:12
von cofi
mcdaniels hat geschrieben:Allerdings wurde oben etwas betreffend Funktion main() erwähnt. Ist dies nun sinnvoll bzw. "Standard"? Ist Main als "Funktion" zu verstehen, die quasi "das gesamte Programm" inkl. weiterer Funktionen "beinhaltet" (Alles unter main():) also eingerückt... ?
Nein. `main` ist nur der Standardname. Wenn du Funktionen innerhalb einer Funktion definierst, werden die bei jedem Aufrufen der Funktion neu erstellt, das ist aber meistens nicht noetig und in dem Fall sogar unerwuenscht, weil du dann von aussen nicht auf die Funktionen zugreifen kannst, sollte das Programm auch als Modul verwendet werden.
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Dienstag 7. September 2010, 19:10
von mcdaniels
Hallo!
Habe nun mein "Grundrechenprogramm" (Entwurf) fertig. Nachdem es doch einiges an Zeilen sind mal per pastebin:
EDIT: Zeile 23 und 24 gehören raus...
http://www.python-forum.de/pastebin.php?mode=view&s=58
Um immer nur Ganzzahlendivisionen durchzuführen, habe ich in einer While Schleife definiert, dass so lange per Zufallsgenerator 2 Zahlen für die Division generiert werden, bis der Rest der Division Null ist (Modulo Operator).
Hoffe auf eure Verbesserungsvorschläge...
LG
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Dienstag 7. September 2010, 20:57
von EyDu
Hallo.
Dir ist aber schon aufgefallen, dass die Funktionen nahezu identisch sind

? Die solltest du zu einer Funktion zusammenfassen und die Unterschiede per Parameter implementieren. Wenn man weiß, dann man auch Funktionen an Namen binden kann, dann ist die Lösung geschenkt.
Sebastian
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Mittwoch 8. September 2010, 09:02
von mcdaniels
Hi!
Ja, ist mir aufgefallen.. hab ich mir im Bett schon überlegt (gestern Nacht)
Funktionen an Namen binden? Was meinst du damit genau?
lg
Re: Funktionsaufrufe in meiner Art sinnvoll?
Verfasst: Mittwoch 8. September 2010, 09:08
von cofi
Code: Alles auswählen
def foo(bar):
pass
bar = foo
baz = bar
bar is foo #True
baz is foo #True
EyDu dachte wohl an sowas
Code: Alles auswählen
def rechne(op, one, two):
return op(one, two)
import operator
import functools
addiere = functools.partial(rechne, operator.add)
subtrahiere = functools.partial(rechne, operator.sub)
...