# Generating random integers in one of three ranges

I have a function returns a random integer number. This function only accepts these three numbers 1,2 and 3(there's another function in my code which is make sure of this otherwise that function will raise ValueError and re-prompt the user again). If the function gets 1 it should generate a random number between 0-9. If gets 2 it should generate a random number between 10-99. And lastly, if gets 3 it should generate a number between 100-999. I'm wondering if there is a way in which I don't use all these ifs.

My code for now:

from random import randrange

def generate_integer(level):
if level == 1:
N = randrange(0,10)
elif level ==2:
N = randrange(10,100)
else:
N = randrange(100,1000)
return N

• Your code does not do what you say it does. Check your ranges. Commented May 5, 2022 at 3:07
• Oh, I have edited my question again. The range for 2 is between 10-99. And for 3 is between 100-999 Commented May 5, 2022 at 3:15
• (Mention (not least in the source code) whether the upper bound is to be exclusive or inclusive.) Commented May 5, 2022 at 5:39

An issue I see with this code is that it behaves unexpectedly if passed another value than 1, 2 or 3: it silently accepts any value and assumes anything other than 1 and 2 is 3, which is not what is specified in your description of the code.

Invalid/out of range inputs should cause the function to raise an exception.

Furthermore, the function should be documented (using a docstring) to indicate what values are accepted. Using python type hints to specify what type of input and output the caller should provide/expect can also be useful.

Finally, the logic can be improved by using a lookup table.

def generate_integer(level: int) -> int:
"""Return a random integer in a range specified by the level argument:

level = 1: [0,9]
level = 2: [10,99]
level = 3: [100,999]"""

bounds = [0, 10, 100, 1000]
return randrange(bounds[level-1], bounds[level])


This code will raise a TypeError or IndexError if called with an invalid value. You could add your own checks for type and range of the argument in order to have more descriptive error messages, but in a simple case like this it might not be necessary.

>>> 10**1
10
>>> 10**2
100
>>> 10**3
1000


So you can do randrange(10**(level - 1), 10**level) for a similar solution (level 1 results in a range (1, 10) rather than (0, 10)).

• I have tried to do so. But as you mentioned the number zero is not included. I need to include the number 0. Commented May 5, 2022 at 3:17
• randrange([0, 0, 10, 100][level], 10**level) Commented May 5, 2022 at 5:36
• Great answer. But what is the purpose of the first 0 in the list? Commented May 5, 2022 at 5:47
• @Ahmed Symmetry.
– l0b0
Commented May 5, 2022 at 19:31