Just a beginner question about good practice.
Take this bit of code for example. I want a particular user input, and if they enter something crazy, I obviously want to run the code inside the function again.
def get_difficulty():
chosen_difficulty = str(raw_input("*** Choose difficulty: Easy, Medium or Hard: ").lower())
if chosen_difficulty == "hard":
return 10
elif chosen_difficulty == "medium":
return 15
elif chosen_difficulty == "easy":
return 20
else:
print "*** Did you enter 'Easy', 'Medium' or 'Hard'?"
print "*** Sorry that was passive aggressive. You obviously didn't..."
return get_difficulty()
Is it ok to make the function handle the else case like this? It seems inelegant; if the person entered something wrong five times the function would be nested 5 times and eventually the right answer would have to cascade down through the return of each function.
It works fine, but is there a better way?
In your case a loop is the correct way to handle repeated input:
def get_difficulty():
while True:
chosen_difficulty = raw_input("*** Choose difficulty: Easy, Medium or Hard: ").lower()
try:
return {"hard": 10, "medium": 15, "easy": 20}[chosen_difficulty]
except KeyError:
print "*** Did you enter 'Easy', 'Medium' or 'Hard'?"
print "*** Sorry that was passive aggressive. You obviously didn't..."
What you discovered is called "recursion" and there is fundamentally nothing wrong about it. It is a strong concept that often leads to elegant formulation of problems. The Fibonacci numbers are an often presented problem that is easily solvable with recursion: We want to generate the number sequence 1, 1, 2, 3, 5, 8, 13, .. so the n+1
entry is (n-1) + (n). This leads to the following algorithm:
def fibonacci(n):
"""Generate the n-th fibonacci number"""
if n == 0 or n == 1:
return(1)
else:
return(fibonacci(n-2) + fibonacci(n-1))
Every recursive function can be turned into an iterative one. For the n-th fibonacci sequence there exists a closed form, you can look it up in the wikipedia article . As you see there are two "irrational numbers" that can be expressed by sum/division of square root of two. So sometimes problems are "recursive by nature" and recursive solutions can be short, where as a iterative solution might "look ugly"/"be longer".
So recursion is in general a good thing, but in python it is not always a good solution. As you already pointed out, if a user inserts five time a wrong input the function stack will have five function calls. Python has a max recurion depth and if a user would enter consecutively wrong input he could crash the program. In case of user input this is not realy a problem, but in other cases you can run more easily into the maximal recursion depth.
Tail-recursion (which is not implemented in python) is a way to allow for arbitrary recursion depths. Haskell and lisp uses this concept, you can read more on wikipedia or this stackoverflow post .
The canonical way to handle input verification in python is a while loop as pointed out by Daniel.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.