Seite 1 von 2
Verbesserungsvorschläge....
Verfasst: Dienstag 9. März 2010, 00:52
von rolgal_reloaded
Hallo zusammen,
ich mal wieder zur Abwechslung
Abgesehen davon, dass das Programm noch fertig geschrieben werden muss: was würdet ihr unbedingt anders machen und warum? Vielen Dank im Voraus!
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: cp1252 -*-
from math import pi, pow
def eingaben_check(*eingaben):
try:
return [int(eingabe) for eingabe in eingaben]
except ValueError:
print "Fehler bei der Eingabe!"
return False
def umfang_rechteck(a, b):
return (a + b) * 2
def flaeche_rechteck(a, b):
return a * b
def umfang_dreieck(a, b, c):
return a + b + c
def flaeche_rwdreieck(a, b):
return (a * b) / 2
def umfang_kreis(r):
return 2 * r * pi
def flaeche_kreis(r):
return pow(r, 2) * pi
if __name__ == "__main__":
print "============Menü============"
print "1. Umfang Rechteck"
print "2. Fläche Rechteck"
print "3. Umfang Dreieck"
print "4. Fläche Rechtw. Dreieck"
print "5. Umfang Kreis"
print "6. Fläche Kreis"
print "e für Ende"
print "============================="
while True:
auswahl = raw_input("Bitte treffen Sie eine Auswahl: ")
if auswahl == "1":
a = raw_input("Bitte einen Wert für a eingeben: ")
b = raw_input("Bitte einen Wert für b eingeben: ")
test = eingaben_check(a, b)
if test:
ergebnis = umfang_rechteck(*test)
print "Die Fläche des Rechtecks beträgt", ergebnis
elif auswahl == "2":
pass
elif auswahl == "e":
break
else:
print auswahl, "ist eine ungültige Eingabe!"
print "Ende des Programms"
LG
r_r
Verfasst: Dienstag 9. März 2010, 01:13
von derdon
Verfasst: Dienstag 9. März 2010, 01:19
von rolgal_reloaded
Guter Tipp,....
allerdings gings mir persönlich, was wohl unklar war, mehr um die ganze Geschichte - Eingabe, Überprüfung, Verarbeitung, Ausgabe...
Dennoch werde ich mul wie vorgeschlagen berücksichtigen
LG
r_r
Verfasst: Dienstag 9. März 2010, 02:58
von rolgal_reloaded
Von mir selbst....
Code: Alles auswählen
def eingaben_check(*eingaben):
try:
return [int(eingabe) for eingabe in eingaben]
except ValueError:
print "Fehler bei der Eingabe!"
return False
ist eigentlich umsonst, oder?
Verfasst: Dienstag 9. März 2010, 03:29
von Defnull
Wenn du das "return False" weg lässt, wird eben im Fehlerfall None statt False zurück gegeben.
Verfasst: Dienstag 9. März 2010, 03:36
von rolgal_reloaded
Ok, es ist spät....vielleicht deshalb....aber was ändert in dem Fall "None" gegenüber "False"?
Grüße, r_r
Verfasst: Dienstag 9. März 2010, 08:20
von BlackJack
@rolgal_reloaded: `None` ist halt was anderes als `False`. Ausserdem fehlt ohne das explizite ``return`` in der Funktion ein IMHO wichtiger Hinweis für den Leser, nämlich was im Fehlerfall zurück gegeben wird. Das es ein implizites ``return None`` am Ende jeder Funktion gibt, ist ja ain ganz klein wenig "Magie", die man kennen muss.
Ich finde aber Fehlerrückgabewerte sowieso nicht so toll. Insbesondere wenn man eine Ausnahme in einen solchen "umwandelt". Ausnahmen sind ja gerade dazu erfunden worden, um solche "speziellen" Werte loswerden zu können.
Die Argumentüberhabe mit ``*`` vermeide ich so gut wie's geht. IMHO ist sie hier überflüssig, denn wenn sowohl in der Funktionssignatur als auch beim Aufruf der ``*`` nötig ist, kann man ihn auch an beiden Stellen weglassen.
Statt der "list comprehension" könnte man auch ``map(int, eingaben)`` schreiben.
`test`!? Der Name passt nicht.
Und wenn man keine ganzen Zahlen eingibt, dann bekommt man keine Fehlermeldung!?
Wenn Du die anderen Zweige mit Quelltext füllst, wirst Du wahrscheinlich feststellen, dass die am Ende sehr ähnlichen Quelltext enthalten. Da sollte man dann überlegen etwas generischeres zu schreiben, was dann entsprechend parametrisiert wird.
Verfasst: Dienstag 9. März 2010, 08:23
von EyDu
Wenn du im Fehlerfall False zurückgibst, dann solltest du bei Erfolg auch True zurückgeben. None ist gerade für solche Fälle wie deinen geeignet: Entweder man hat ein Ergebnis (deine Liste) oder keins (None).
Deine LC kanst du übrigens aucheinfach so schreiben:
Ich würde aber die Ausgabe lieber direkt Abfangen als über einen Rückgabewert.
Sebastian
Verfasst: Dienstag 9. März 2010, 09:53
von rolgal_reloaded
BlackJack hat geschrieben:@rolgal_reloaded:
Die Argumentüberhabe mit ``*`` vermeide ich so gut wie's geht. IMHO ist sie hier überflüssig, denn wenn sowohl in der Funktionssignatur als auch beim Aufruf der ``*`` nötig ist, kann man ihn auch an beiden Stellen weglassen.
Hätte ich auch gemeint, funzt aber nicht. Aber wahrscheinlich übersehe ich etwas weiteres ?!
Statt der "list comprehension" könnte man auch ``map(int, eingaben)`` schreiben.
Ist schön, hat aber für Anfänger auch wieder was von Magie.
`test`!? Der Name passt nicht.
Gibt wahrscheinlich noch besseres, aber warum passt es nicht?
Und wenn man keine ganzen Zahlen eingibt, dann bekommt man keine Fehlermeldung!?
Machen wir float, nehme an, du hast das gemeint.
Wenn Du die anderen Zweige mit Quelltext füllst, wirst Du wahrscheinlich feststellen, dass die am Ende sehr ähnlichen Quelltext enthalten. Da sollte man dann überlegen etwas generischeres zu schreiben, was dann entsprechend parametrisiert wird.
Das steht außer Zweifel, aber du weisst eh...
LG
r_r
Verfasst: Dienstag 9. März 2010, 10:03
von rolgal_reloaded
EyDu hat geschrieben:Wenn du im Fehlerfall False zurückgibst, dann solltest du bei Erfolg auch True zurückgeben. None ist gerade für solche Fälle wie deinen geeignet: Entweder man hat ein Ergebnis (deine Liste) oder keins (None).
Auch ein Aspekt, vor allem durchaus auch erklärbar.
Ich würde aber die Ausgabe lieber direkt Abfangen als über einen Rückgabewert.
Sebastian
Vorschlag in Bezug auf das Beispiel?
LG
r_r
Verfasst: Dienstag 9. März 2010, 10:06
von BlackJack
@rolgal_reloaded: `map()` ist eine ganz normale Funktion, da sehe ich nichts magisches.
`test` enthält keinen Test und auch kein Ergebnis eines Tests, darum passt der Name halt nicht. Halt nein: *manchmal* wird der Name doch an so etwas wie ein Testergebnis gebunden. Aber dass ich das nicht so vorteilhaft finde, habe ich ja schon geschrieben.
Nein `float()` meine ich nicht. Ich dachte der Benutzer wird nicht über Falscheingaben informiert. Da habe ich übersehen, dass die Umwandlungsfunktion nicht nur testet, sondern auch eine Ausgabe macht. Das gehört da IMHO auch nicht rein. Man sollte Logik und Benutzerinteraktion trennen.
Verfasst: Dienstag 9. März 2010, 10:23
von rolgal_reloaded
BlackJack hat geschrieben:@rolgal_reloaded: `map()` ist eine ganz normale Funktion, da sehe ich nichts magisches.
Na ich auch nicht

Verfasst: Dienstag 9. März 2010, 15:31
von rolgal_reloaded
Wenn ich über Eure Anregungen nachdenke, komme ich zu folgender Fassung, ist wohl besser?
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: cp1252 -*-
from math import pi, pow
def umfang_rechteck(a, b):
return (a + b) * 2
def flaeche_rechteck(a, b):
return a * b
def umfang_dreieck(a, b, c):
return a + b + c
def flaeche_rwdreieck(a, b):
return (a * b) / 2
def umfang_kreis(r):
return 2 * r * pi
def flaeche_kreis(r):
return pow(r, 2) * pi
def ausgabe(funktion, *eingaben):
try:
ergebnis = funktion(*map(float, eingaben))
print "Das Ergebnis lautet: ", ergebnis
except ValueError:
print "Fehler bei der Eingabe!"
if __name__ == "__main__":
print "============Menü============"
print "1. Umfang Rechteck"
print "2. Fläche Rechteck"
print "3. Umfang Dreieck"
print "4. Fläche Rechtw. Dreieck"
print "5. Umfang Kreis"
print "6. Fläche Kreis"
print "e für Ende"
print "============================="
while True:
auswahl = raw_input("Bitte treffen Sie eine Auswahl: ")
if auswahl == "1":
a = raw_input("Bitte einen Wert für a eingeben: ")
b = raw_input("Bitte einen Wert für b eingeben: ")
ausgabe(umfang_rechteck, a, b)
elif auswahl == "2":
pass
elif auswahl == "e":
break
else:
print auswahl, "ist eine ungültige Eingabe!"
print "Ende des Programms"
Verfasst: Dienstag 9. März 2010, 15:40
von EyDu
Hallo.
Du solltest dir noch eine main-Funktion anlegen.
Noch ein Tipp für die Benutzereingaben:
Code: Alles auswählen
>>> spam = {1:lambda x: x*2, 2:lambda x: x*x}
>>> spam[1](4)
8
>>> spam[2](4)
16
>>>
Die Abfragen von a, b und r kannst du dort auch noch einbauen. Aber nicht in die Berechnungsfunktionen und ohne zusätzliche Funktion für jede Berechnung.
Verfasst: Dienstag 9. März 2010, 15:52
von derdon
EyDu: Du empfiehlst aufsteigende ganze Zahlen als Schlüssel für dicts zu verwenden? Warum?
Verfasst: Dienstag 9. März 2010, 15:55
von EyDu
derdon hat geschrieben:EyDu: Du empfiehlst aufsteigende ganze Zahlen als Schlüssel für dicts zu verwenden? Warum?
Das hat etwas mit der Erdrotation zu tun, ist aber viel komplex um das hier zu erläutern.
Verfasst: Dienstag 9. März 2010, 16:00
von jbs
Code: Alles auswählen
def umfang_rechteck(a,b):
return a*b
def end():
raise KeyboardInterrupt
def main():
options = {'1': dict(str='Umfang Rechteck', func=umfang_rechteck, params=('a','b')),
'e': {'func': end},
}
def print_menu():
print 'Menu'
for i in range(1, len(options)):
print '%s. %s' %(i, options[str(i)]['str'])
print 'e for end'
print
def get_choice():
exercise = None
while not exercise:
choice = raw_input('Bitte treffen Sie eine Auswahl: ')
exercise = options.get(choice, None)
params = {}
for param in exercise.get('params', ()):
params[param] = int(raw_input("Bitte einen Wert fuer %s eingeben: " %param))
return exercise['func'], params
try:
while True:
print_menu()
func, kwargs = get_choice()
print func(**kwargs)
print
except KeyboardInterrupt:
print 'end'
if __name__ == '__main__':
main()
Ganz so schön ist das nicht gemacht mit dem Mischen von Zahlen und dem "e".
Verfasst: Dienstag 9. März 2010, 19:17
von rolgal_reloaded
Warum eine Funktion main?
Das wirkt für mich überflüssig
Und ob die Funktionen im Dict. besser lesbar sind....da kann ich sie doch frisch ausschreiben, der Zweizeiler ist mir da sympahtischer, oder gibts in deiner Fassung einen wesentlichen Vorteil?
LG
r_r
Verfasst: Dienstag 9. März 2010, 19:55
von BlackJack
@rolgal_reloaded: `main()` weil Code und Variablen auf Modulebene unsauber sind. Da besteht halt immer die Gefahr, dass man die aus versehen oder absichtlich zur Kommunikation zwischen Funktionen oder Methoden verwendet und damit unnötige Abhängigkeiten einbaut die schwerer zu verstehen sind.
Von welchen zwei Zeilen Code redest Du? Überleg Dir mal wie man bei Deinem Code weitere Funktionen hinzufügt und wie das bei jbs' Code aussieht.
Verfasst: Dienstag 9. März 2010, 20:02
von rolgal_reloaded
BlackJack hat geschrieben:@rolgal_reloaded: `main()` weil Code und Variablen auf Modulebene unsauber sind. Da besteht halt immer die Gefahr, dass man die aus versehen oder absichtlich zur Kommunikation zwischen Funktionen oder Methoden verwendet und damit unnötige Abhängigkeiten einbaut die schwerer zu verstehen sind.
Von welchen zwei Zeilen Code redest Du? Überleg Dir mal wie man bei Deinem Code weitere Funktionen hinzufügt und wie das bei jbs' Code aussieht.
Ich rede von den zwei Zeilen, die meine Funktionen für die Berechnungen haben.
LG r_r