1
\$\begingroup\$

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
asked May 5, 2022 at 1:50
\$\endgroup\$
3
  • \$\begingroup\$ Your code does not do what you say it does. Check your ranges. \$\endgroup\$ Commented 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\$ Commented 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\$ Commented May 5, 2022 at 5:39

2 Answers 2

2
\$\begingroup\$

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.

Toby Speight
87.2k14 gold badges104 silver badges322 bronze badges
answered May 5, 2022 at 8:47
\$\endgroup\$
1
\$\begingroup\$
>>> 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)).

answered May 5, 2022 at 3:14
\$\endgroup\$
4
  • \$\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\$ Commented May 5, 2022 at 3:17
  • \$\begingroup\$ randrange([0, 0, 10, 100][level], 10**level) \$\endgroup\$ Commented May 5, 2022 at 5:36
  • \$\begingroup\$ Great answer. But what is the purpose of the first 0 in the list? \$\endgroup\$ Commented May 5, 2022 at 5:47
  • \$\begingroup\$ @Ahmed Symmetry. \$\endgroup\$ Commented May 5, 2022 at 19:31

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.