0

Trying to understand a bit more of the generator/send function in python. I read some in the link: generator send function purpose which helped a lot.

But I am trying to understand the code below. Why is the next(checker) necessary? Doesnt the send function automatically ask for the next item in the generator? I tried just having the next(checker) before the for loop but that doesnt function the same way. I thought the send function sends 'attempt' as x and yields whether x == password. I just dont understand why its necessary to have the next(checker) in the loop.

def checkPassword(attempts, password):
    def check():
        while True:
            x = yield
            yield x == password

    checker = check()
    for i, attempt in enumerate(attempts):
        next(checker)
        if checker.send(attempt):
            return i + 1

    return -1

The function above is base on the problem:

"In order to validate your function, you want to test it locally. Given a list of attempts and the correct password, return the 1-based index of the first correct attempt, or -1 if there were none.

Example

For attempts = ["hello", "world", "I", "like", "coding"] and password = "like", the output should be checkPassword(attempts, password) = 4."

1 Answer 1

5

Doesnt the send function automatically ask for the next item in the generator?

Yeah, but the way this generator is written, half the values come from this yield:

x = yield

which just yields None. The calls to next consume the None.


The generator could have been written differently, to eliminate most of the next calls:

def checkPassword(attempts, password):
    def check():
        x = yield
        while True:
            x = yield x == password

    checker = check()
    next(checker)
    for i, attempt in enumerate(attempts):
        if checker.send(attempt):
            return i + 1

    return -1

However, the yield/send communication between a generator and its user cannot start with a send, since a fresh generator is stopped at the beginning of the function body instead of at a yield that could receive a value. Thus, there always has to be a next (or equivalently a send(None)) before you can start sending values the generator will use.

Sign up to request clarification or add additional context in comments.

4 Comments

I still dont understand fully. x = yield just yields None? I thought x = yield is executed when the send function is called, passing attempt to x, then yield true or false back?
@user1179317: The x = part is executed when you call send. When you call next, the generator advances to the yield, yields None, and pauses. When you call send, the object you sent becomes the value of the yield expression and is assigned to x, and the return value of send comes from the next yield.
Okay, i think i got it. Thanks
@user1179317 hope this link works but here is a visual from fluent python

Your Answer

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.