Solving an interview Python question

Recently I applied for a remote Python job and I faced the challenge of answering a really tricky Python question, and the question is the following.

Write a one-line Python generator expression that provides an infinite stream of unique integers that are evenly divided by any of the ascii values for the characters in "close". 4440, 4444, 4455 are examples of numbers in this stream. Assume any needed Python standard library modules are already imported.

I managed to solve it really quick and I wanted to share with you how I did it.

logo

Understanding the question

We have to make a one line Python code to define a generator that generates values according the constrains given. The final result should be something like this.

generator = (generator_code)

The syntax to create generators from comprehension is to use parenthesis instead of square brackets.

but first let's talk a little bit about comprehension.

Comprehension

List comprehension

We can create lists on the fly by using a for loop inside square brackets, let's take the following example.

squares = [x ** 2 for x in range(1, 6)]
print(squares)
[1, 4, 9, 16, 25]

This will create a list of the squares values for the number from 1 to 5.

Generator expression

Now we can create a generator expression from this by replacing the square brackets with parenthesis.

squares = (x ** 2 for x in range(1, 6))
print(squares)
<generator object <genexpr> at 0x000002C77E2D4D60>

This will create a generator object that we can use from the scope of a for loop.

for square in squares:
    print(square)

    
1
4
9
16
25

We can also use the next built-in method to generate the elements one by one.

squares = (x ** 2 for x in range(1, 6))
next(squares)
1
next(squares)
4

If we exhaust the values in the generator we will have the following exception.

Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    next(squares)
StopIteration

Infinite generator expression

We have some of the foundations to solve the Python question, something that it is required for this problem is to generate infinite values, so our for loop must be perpetual. One way we can do this is to use inside the for loop another generator.

count generator from the itertools

The itertools module comes with some generators by default that we can use, one is the count generator.

This generator generates infinite integer numbers by providing a starting point and a step value. If we combine this with the previous code.

from itertools import count
squares = (x ** 2 for x in count(1, 1))

This generator is not exhaustible, if you use a for loop to exhaust this generator you will have a non stop script running.

Understanding the ASCII

In this problem we have to verify if an integer number is evenly divided by any of the ascii values for the characters in "close".

Each character in the ASCII table has an equivalent integer number, we can use the ord built-in method to find out this.

word = "close"
for char in word:
    print(ord(char))


99
108
111
115
101

We can create a list comprehension to create a list of these numbers.

numbers = [ord(char) for char in "close"]

Using if expressions

We can combine the power of if statements with generator expression, let's take a look at the following example.

squares = (x ** 2 for x in count(1, 1) if x % 2 == 0)
next(squares)
4
next(squares)
16
next(squares)
36
next(squares)
64

This generator will generate only those square values that are even or evenly divided by two.

Solving the Python question

Dividing by several numbers

Now that know the Python fundamentals behind this problem we can combine them all to solve this challenge, but first let's explain something else, we need to verify that the number we are generating is evenly divided by any of a set of numbers, this case the ord values for "close".

For this case we can create a dummy list of ones (1) if an even division is found

number = 4444
numbers = [ord(char) for char in "close"]
[1 for value in numbers if number % value == 0]
[1]

We can use this to check the length of the returning list, if the length is greater than zero, then there is a evenly divisor.

Final solution

Now we can combine all of these into one single line of code.

generator = (x for x in count(1, 1) if len([1 for value in [ord(char) for char in "close"] if x % value == 0]) > 0)

If we use the next built-in method we will have the following.

next(generator)
99
next(generator)
101
next(generator)
108
next(generator)
111
next(generator)
115
next(generator)
198
next(generator)
202
next(generator)
216
next(generator)
222
next(generator)
230
next(generator)
297
next(generator)
303
next(generator)
324

An infinite generator that generates an infinite stream of unique integers that are evenly divided by any of the ascii values for the characters in "close"

Conclusion

We the practice of Python coding you can gain the skill of solving interview level challenges.

I hope you enjoyed this entry as I enjoyed writing it.

Best regards.

0 Comments

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel