denke ich, das Kernproblem dabei ist, dass Ihre fib
Funktion zwei völlig getrennte Aufgaben hat:
- Umgang mit Benutzereingabe und Validierung; und
- Berechnen von Fibonacci-Zahlen.
Von dem Namen würde ich sagen, es sollte nur # 2 tun!
Stattdessen Struktur Ihres Programm wie:
def positive_integer():
"""Loops until the user enters a positive integer."""
...
def fib(n):
"""Prints first n Fibonacci numbers."""
if n < 0:
raise ValueError
prev = 0
curr = 1
for terms in range(n): # note simplification here
nxt = prev + curr
print str(curr),
prev = curr
curr = nxt
fib(positive_integer())
Jetzt haben Sie zwei Funktionen, die jeweils mit einer klaren Einzel Verantwortung. Dies macht jede weniger komplex; der range
Aufruf ist jetzt einfacher, zum Beispiel, da er annehmen kann, n
ist bereits eine ganze Zahl (und wenn nicht, erhält der Benutzer eine vernünftige TypeError
, um ihnen zu sagen, was schief gelaufen ist).
Zum Schreiben positive_input
siehe Asking the user for input until they give a valid response; Eine Schleife ist dafür besser als eine Rekursion.
Als weitere refactor, können Sie tatsächlich schneiden die drei Linien
nxt = prev + curr
prev = curr
curr = nxt
nur eins:
prev, curr = curr, curr + prev
Beachten Sie auch, dass im Allgemeinen, sollten Sie Ihre try
Blöcke so kurz halten, wie möglich und Ihre except
Klauseln so spezifisch wie möglich. Dies macht sie nützlicher beim Lesen des Codes ("Ich denke, diese eine Sache könnte schief gehen, und in diesem Fall können wir das tun") und bedeutet, dass legitime Probleme nicht ruhig ignoriert werden.Insbesondere sollten Sie fast nie direkt mit Exception
umgehen (entweder in raise
oder except
), es ist viel zu breit, um einen Fall sinnvoll zu behandeln.
Sie sollten den Test für negative Zahlen bewegen außen * * die 'try' - Sie * wollen * es einen Fehler verursachen! Beachten Sie auch, dass "try" Blöcke so kurz wie möglich sein sollten, und "except" Tests so spezifisch wie möglich, sonst verstecken Sie echte Probleme. – jonrsharpe