When you go to a job interview, you should be prepared to be asked anything related to the backend stack. For example, you might be asked, «What are generators?». In that case, you should understand what generators are and how they work in Python.
You should also know that they use yield instead of return and that they allow you to generate a sequence of values on demand. But theory is just the start. You might also be asked to implement a simple generator function. One classic task is to implement a function that generates random numbers within a specific range.
Task:
Write a random_numbers(a, b, k) generator function that will return a sequence of random numbers in a given range and with a given length.
a (int)
is the lower border of the range of random numbers (inclusive)
b (int)
is the upper border of the range of random numbers (inclusive)
k (int)
— the number of random numbers that the generator should return in one cycle
# usage example
gen = random_numbers(a=5, b=10, k=3)
# first call next()
print(next(gen)) # output 3 random numbers from 5 to 10, for example: [7, 9, 5]
# second call next()
print(next(gen)) # output another 3 random numbers for example: [10, 6, 8]
# and so on
Requirements:
1. Perform a generator function random_numbers(a, b, k)
2. Use the module random
to generate random numbers
3. The generator should return a list of k
random numbers each time it runs next().
4. Once the generator is exhausted (for example, when calling infinitely next
), it should not throw a StopIteration
error (in practice, this is not critical for the interview, but if the candidate marks infinity himself, it would be a plus
Additionally: Is it possible to make this generator infinite so that it does not throw an exception? StopIteration
?
Why this task is appropriate for an interview:
random
module to generate random numbers.k
elements.Let's move from words to action:
import random
def random_numbers(*, a: int, b: int, k: int):
while True:
result = []
for _ in range(k):
result.append(random.randint(a, b))
yield result
# Example of use:
gen = random_numbers(a=5, b=10, k=3)
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
import random:
— Import the random
module to work with random numbers.
def random_numbers(*, a: int, b: int, k: int):
— Define the function generator random_numbers, which takes three arguments according to the problem condition.
while True:
— Create an infinite cycle so that the generator does not stop. This will allow random number sequences to be generated for as long as necessary. If this is removed, the generator will stop.
result = []:
— At each iteration of the cycle, we create an empty result
list to which we will add random numbers.
for _ in range(k):
— Run the cycle k times to generate k random numbers.
random.randint(a, b):
— The random.randint()function generates a random integer in the range a to b (inclusive).
result.append(...):
— Each generated random number is added to the list result
.
yield result:
— The yield
keyword turns the function into a generator. yield result returns the result list and pauses the generator, preserving its state. The following run next() will resume execution at the point where it was paused, and generate the next list.
This generator is infinite due to the cycle while True
This means: without it, the generator function will throw an exception StopIteration