Luap12 hat geschrieben:
Was genau ist PEP8?
http://www.python.org/dev/peps/pep-0008/
Da drin wird beschrieben, wie man seinen Quelltext formatieren sollte. Hältst Du Dich an die Konvention, so können anderen Deinen Code leichter lesen und verstehen.
Luap12 hat geschrieben:
Hyperion hat geschrieben:- Die Bennenung ist "suboptimal"; was sollen denn "ga()" und "ka()" tun?
das hat für mich system^^ ga= großer abstand; ka = kleiner Abstand
Du erkennst selber den Denkfehler? "für mich..."
In einem halben Jahr weißt Du das ggf. nicht mehr so einfach. Als ich zu proggen lernte mit dem genialen Commodore Basic V2.0 wäre ich froh über beliebig lange Namen gewesen. (@BlackJack: Ja, ich weiß, man konnte auch mehr als 2 Byte lange Namen in den Quellcode schreiben, aber beim Lookup hat der Interpreter ja nur die ersten beiden benutzt
)
Also: wähle stets aussagekräftige Namen!
Hyperion hat geschrieben:- Wieso nutzt Du Funktionen nicht für die bessere Aufgliederung Deines Tools? Du könntest so eine universelle Eingaberoutine schreiben, und dieses nicht jedes Mal für alle Rechen-OPs und Menüauswahlen wiederholen! Nennt man auch DRY (Don't repeat yourself) Auch für jede Operation könnte man eine Funktion schreiben.
Also ich denke das kann man auch als Anfänger kapieren
(Zumal Du ja schon Funktionen nutzt!)
Beispiel:
Code: Alles auswählen
def add():
# hier Code für Addition
def sub():
# s.o.
def main():
# hier Schleife mit Menüauswahl
while True:
print "Menü: 1-Addition, 2-Subtraktion, ..."
choice = int(input(...))
if choice == 1:
add()
elif choice == 2:
sub()
Zusätzlich könntest Du eine Funktion basteln, die Dir eine beliebige Frage printet und dann einen Zahlenwert zurückliefert, so in der Art:
Code: Alles auswählen
def get_value(question):
while True:
try:
return int(input(question))
except ValueError, e:
print "Bitte nur Zahlen eingeben!"
Damit kannst Du dann die einzelnen Operationen verschlanken:
Code: Alles auswählen
def add():
summand_a = get_value("Bitte geben Sie den 1. Summanden ein")
summand_b = get_value("Bitte geben Sie den 1. Summanden ein")
return summand_a + summand_b
Hyperion hat geschrieben:
- Anstelle der "if zahla == x"-Kaskaden würde man da besser ein Dictionary nutzen, um an die ausgewählte Funktion zu verzweigen.
Damit ist folgendes Konstrukt gemeint:
Code: Alles auswählen
operations = {
1: add,
2: sub
}
# Aufruf von Funktion, die zum Schlüssel "1" passt:
operations[1]()
# Anstelle eines konkreten Schlüssels, nimm die Benutzeriengabe der Menüwahl
choice = get_choice()
operations[choice]()
Damit kannst Du relativ einfach weitere Funktionen nachträglich hinzufügen, ohne in irgendwelchen if...elif..else-Konstrukten rumzupfuschen. Auch die Ausgabe der Menüoptionen sind so dynamisch, da Du den Text ja aus dem Dictionary gewinnen könntest, wenn man es noch ein wenig aufbohrt:
Code: Alles auswählen
operations = {
1: {"op": add, "info": "Addition"},
2: {"op": sub, "info": "Subtraktion"
}
choice = get_choice(operations)
# und hier zu Funktion
def get_choice(operations):
for key, value in operations.iteritems():
print "{key} - {info}".format(key, **value)
return int(input("Auswahl"))
Natürlich könnte man auch die oben bereits implementierte nutzen und die Ausgabe der Optionen separat implementieren.
Hyperion hat geschrieben:
- Generell gibt es das operator-Modul. In diesem findet man die Funktionen, die Du hier anbietest auch als Funktion. Somit könnte man sehr kompakten Code schreiben, der im Menü-Dispatcher direkt die richtige Funktion mit den Operanden aufruft.
Im operator-Modul gibt es Wrapper für die von Dir genutzten Operatoren:
Code: Alles auswählen
In [28]: from operator import add
In [29]: add(1, 4)
Out[29]: 5
In [30]: from operator import sub
In [31]: sub(add(1, 4), 2)
Out[31]: 3
Dies kann man nun nutzen, um sich die eigene Implementierung der Funktionen zu sparen. Wir verzweigen im Dispatcher eben nicht auf unsere eigenen Funktionen, sondern die bereits im operator-Modul implementierten.
Code: Alles auswählen
from operator import add, sub
operations = {
1: add,
2: sub
}
# Benutzer nach Menüauswahl fragen -> an "choice" binden
# Benutzer nach Operanden fragen -> an "op_a", "op_b" binden
# und dann der Aufruf:
operations[choice](op_a, op_b)
Hyperion hat geschrieben:
- Entferne den Code auf Moduleben und lagere den eigentlichen Einstieg in eine main()-Funktion aus mit dem 'if __name__ == "__main__"'-Hook.
Verlagere alles in Funktionen und schreibe dann ganz unten:
Code: Alles auswählen
# dein bisheriger Code
# Füge eine Funktion ein, die "main" heißt. Das ist quasi der Einstieg in deine Logik
def main():
# hier Code, z.B. die Endlosschleife mit menüauswahl usw.
if __name__ == "__main__":
main()
Somit kannst Du Dein Script per import selber in einer Shell oder einem anderen Script importieren und die Funktionen getrennt aufrufen. Zudem kannst Du es aber auch ganz "normal" als Script starten.
Hyperion hat geschrieben:
- bei except fange immer nur die konkreten Exceptions auf, die Du auch behandeln willst.
Naja, habe ich ja oben schon gezeigt mit dem "ValueError". Indem Du die konkrete Exception angibst, die Du behandeln willst, verschluckt Dein Programm keine anderen evtl. aufgetretenen Exceptions. So wie bei Dir bekommst Du andere Ausnahmen nicht mit.
Hyperion hat geschrieben:
Den Rest verstehe ich beim besten Willen nicht... Sry, aber ich bin noch nicht solange dabei, ich bin froh das der TR erstmal so funktioniert wie er hier beschrieben ist.
So, ich hoffe ich konnte ein wenig Licht ins Dunkel bringen
Btw: Iirc BlackJack (oder doch sma?) hatten grad neulich erst ein nettes Taschenrechner-Beispiel hier gezeigt, welches viele von den Techniken zeigt, die ich hier kurz umrissen habe.
Edit: Da isser:
http://python-forum.de/viewtopic.php?p=175585#p175585