Need help writing coroutine

Paul Hankin paul.hankin at gmail.com
Wed Nov 7 12:38:32 EST 2007


Matthew Wilson wrote:
> I'm working on two coroutines -- one iterates through a huge stream, and
> emits chunks in pieces.  The other routine takes each chunk, then scores
> it as good or bad and passes that score back to the original routine, so
> it can make a copy of the stream with the score appended on.
>
> I have the code working, but it just looks really ugly.  Here's a vastly
> simplified version.  One function yields some numbers, and the other
> function tells me if they are even or odd.
>
> def parser():
>     "I just parse and wait for feedback."
>     for i in 1, 2, 3, 4, 5:
>         score = (yield i)
>         if score:
>             print "%d passed!" % i
>
> def is_odd(n):
>     "I evaluate each number n, and return True if I like it."
>     if n and n % 2: return True
>
> def m():
>     try:
>         number_generator = parser()
>         i = None
>         while 1:
>             i = number_generator.send(is_odd(i))
>     except StopIteration: pass
>
> and here's the results when I run this:
> In [90]: m()
> 1 passed!
> 3 passed!
> 5 passed!
>
> So, clearly, the code works.  But it is nonintuitive for the casual
> reader.
>
> I don't like the while 1 construct, I don't like manually
> trapping the StopIteration exception, and this line is really ugly:
>
>     i = number_generator.send(is_odd(i))
>
> I really like the old for i in parser(): deal, but I can't figure out
> how to use .send(...) with that.
>
> Can anyone help me pretty this up?  I want to make this as intuitive as
> possible.

Why use coroutines?

def parser(score):
    for i in xrange(1, 6):
        yield i
        if score(i):
            print "%d passed!" % i

def is_odd(n):
    return n % 2

def m():
    for i in parser(is_odd):
        # Presumably do something here...
        pass

--
Paul Hankin




More information about the Python-list mailing list