-1

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
John Smith
  • 835
  • 1
  • 7
  • 19
  • I hope this is an academic question, because in Python noone would write something like this with recursion. That's a task for a `while True` loop. See [Asking the user for input until they give a valid response](https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response) – Matthias Aug 30 '22 at 11:11
  • 1
    You're not returning the result from the recursion; the `else:` branch is equivalent to `get_positive_int(); return None`. – molbdnilo Aug 30 '22 at 11:28
  • 1
    Does this answer your question? [Why does my recursive function return None?](https://stackoverflow.com/questions/17778372/why-does-my-recursive-function-return-none) – VLAZ Aug 30 '22 at 11:44

3 Answers3

3

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()
PirateNinjas
  • 1,908
  • 1
  • 16
  • 21
  • 1
    Yup, all of the problems OP mentioned come down to function not returning the recursive call output and staying in the loop. – matszwecja Aug 30 '22 at 11:00
1

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)
Tom McLean
  • 5,583
  • 1
  • 11
  • 36
0

Because you not use return statement, you need to explicitly specify return value, if you don't do this, python will return None value. If you call a function recursively and this recursion reach 1000(default, and can be check with sys.getrecursionlimit()) , python will throw a RecursionError exception and your program will terminate if you don't catch this error , 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
Veysel Olgun
  • 552
  • 1
  • 3
  • 15