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
-
\$\begingroup\$ Your code does not do what you say it does. Check your ranges. \$\endgroup\$Reinderien– Reinderien2022年05月05日 03:07:25 +00:00Commented May 5, 2022 at 3:07
-
\$\begingroup\$ Oh, I have edited my question again. The range for 2 is between 10-99. And for 3 is between 100-999 \$\endgroup\$Ahmed– Ahmed2022年05月05日 03:15:58 +00:00Commented May 5, 2022 at 3:15
-
2\$\begingroup\$ (Mention (not least in the source code) whether the upper bound is to be exclusive or inclusive.) \$\endgroup\$greybeard– greybeard2022年05月05日 05:39:36 +00:00Commented May 5, 2022 at 5:39
2 Answers 2
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)
).
-
\$\begingroup\$ I have tried to do so. But as you mentioned the number zero is not included. I need to include the number 0. \$\endgroup\$Ahmed– Ahmed2022年05月05日 03:17:53 +00:00Commented May 5, 2022 at 3:17
-
\$\begingroup\$
randrange([0, 0, 10, 100][level], 10**level)
\$\endgroup\$greybeard– greybeard2022年05月05日 05:36:44 +00:00Commented May 5, 2022 at 5:36 -
\$\begingroup\$ Great answer. But what is the purpose of the first 0 in the list? \$\endgroup\$Ahmed– Ahmed2022年05月05日 05:47:47 +00:00Commented May 5, 2022 at 5:47
-
\$\begingroup\$ @Ahmed Symmetry. \$\endgroup\$l0b0– l0b02022年05月05日 19:31:09 +00:00Commented May 5, 2022 at 19:31