The following script prompts the user for a positive integer and is meant to make sure
that the given value is in the range 1-99
.
#!/usr/bin/env python3
def get_positive_int():
while True:
l = int(input("Level: "))
if 0 < l < 100:
return l
else:
get_positive_int()
l = get_positive_int()
print(l)
Submitting a positive integer yields no unexpected behaviour:
Level: 5
5
Yet when I give a negative integer than my interaction with the script looks like this:
Level: -300
Level: 5
Level: 5
5
I also noticed that when I remove the while
loop from get_positive_int
:
def get_positive_int():
l = int(input("Level: "))
if 0 < l < 100:
return l
else:
get_positive_int()
then my interaction with the script looks like this:
Level: -300
Level: 5
None
Why doesn't my code print 5
right away when it is submitted after submitting -300
?
Why does get_positive_int
seem to return None
despite having been given 5
?
I have not noticed such behaviour in other languages as in Bash
get_positive_int() {
echo "Level: "
read l
if [[ "${l}" -gt 0 ]] && [[ "${l}" -lt 100 ]]; then
:
else
get_positive_int
fi
}
get_positive_int
echo "${l}"
or in Racket
(define (take-positive-int) (displayln "Level: ")(let ((l (string->number (read-line))))
(if (and (> l 0) (< l 100)) l
(take-positive-int))))
(define l (take-positive-int))
(displayln l)
where the interaction looks like this:
Level:
-300
Level:
5
5
CodePudding user response:
Python requires explicit use of the return
to output a value. You probably want this:
def get_positive_int():
while True:
l = int(input("Level: "))
if 0 < l < 100:
return l
else:
return get_positive_int()
l = get_positive_int()
print(l)
This will output like:
Level: 101
Level: 100
Level: 99
99
You also don't need to mix recursion and a while
loop. You could do this purely in a while loop
def get_positive_int():
while True:
l = int(input("Level: "))
if 0 < l < 100:
return l
or purely with recursion:
def get_positive_int():
l = int(input("Level: "))
if 0 < l < 100:
return l
else:
return get_positive_int()
CodePudding user response:
You need to return the recursive call:
def get_positive_int():
while True:
l = int(input("Level: "))
if 0 < l < 100:
return l
else:
return get_positive_int()
However, you don't need a recursive call:
def get_positive_int():
while not(0 < (l:= int(input("Level: "))) < 100):
print("value not between 0 and 100")
return l
l = get_positive_int()
print(l)
CodePudding user response:
Because you not use return
statement, you need to explicitly specify return value, if you don't do this, python
will return None
value. Also I suggest you to that don't use recursive function until you really need it because it can damage your code, let's say user give negative numbers all the time like below ;
def get_positive_int():
while True:
l = -4
if 0 < l < 100:
return l
else:
get_positive_int()
l = get_positive_int()
print(l)
Output:
Traceback (most recent call last):
File "b.py", line 12, in <module>
l = get_positive_int()
File "b.py", line 10, in get_positive_int
get_positive_int()
File "b.py", line 10, in get_positive_int
get_positive_int()
File "b.py", line 10, in get_positive_int
get_positive_int()
[Previous line repeated 995 more times]
File "b.py", line 7, in get_positive_int
if 0 < l < 100:
RecursionError: maximum recursion depth exceeded in comparison
You can simply modify your code like this ;
def get_positive_int():
while True:
l = int(input("Level: "))
if 0 < l < 100:
return l
l = get_positive_int()
print(l)
Output:
Level: 300
Level: 300
Level: -5
Level: 6
6