yield

See also section 16.1.7.

 
#!/usr/bin/env python3
# taken from https://lerner.co.il/2020/05/08/making-sense-of-generators-coroutines-and-yield-from-in-python/
import random

# generator function, returns a generator
def myfunc1():
    yield 1
    yield 2
    yield 3

# coroutine, yield is on the right side of an assignment
def myfunc2():
    x = ”
    while True:
        print(f'Yielding x ({x}) and waiting')
        x = yield x # the value is received from send()
        if x is None: 
            break
        print(f'Got x {x}. Doubling.')
        x = x * 2

def pl_sentence(sentence):
    output = []
    for one_word in sentence.split():
        if one_word[0] in 'aeiou':
            output.append(one_word + 'way')
        else:
            output.append(one_word[1:] + one_word[0] + 'ay')
    return ' '.join(output)

def pig_latin_translator():
    s = ”
    while True:
        s = yield pl_sentence(s)
        if s is None:
            break
        
def bad_service_chatbot():
    answers = ["We don't do that",
               "We will get back to you right away",
               "Your call is very important to us",
               "Sorry, my manager is unavailable"]
    yield "Can I help you?"
    s = ”
    while True:
        if s is None:
            break
        s = yield random.choice(answers)

def wrapper(data):
    for one_item in data:
        yield one_item

def wrapper2(data):
    yield from data

def switchboard():
    choice = yield "Send 1 for Pig Latin, 2 for support"
    if choice == 1:     
        yield from pig_latin_translator() 
    elif choice == 2:
        yield from bad_service_chatbot()
    else:
        return
    
def switchboard2():
    while True:
        choice = yield "1 for PL, 2 for support, 3 to exit"
        if choice == 1:
            yield from pig_latin_translator()
        elif choice == 2:
            yield from bad_service_chatbot()
        elif choice == 3:
            return
        else:
            print('Bad choice; try again')    

def main():
    g = myfunc1() # g is a generator object implementing the iterator protocaol
                 # it knows what to do in a foor loop
    for i in g: 
        print( "%d" % i)

    g = myfunc1()
    print( "%d" % next(g))
    print( "%d" % next(g))
    print( "%d" % next(g))

    g = myfunc2() # coroutine
    print( "main: %s" % repr( next(g)))     # -> ”
    print( "main: %s" % repr( g.send(10)))  # -> 20
    print( "main: %s" % repr( g.send(123))) # -> 246
 

    g = pig_latin_translator()
    print( "main: %s" % repr( next(g)))
    print( "main: %s" % repr( g.send( "this is a test")))
    print( "main: %s" % repr( g.send( "hello")))

    g2 = bad_service_chatbot()
    print( "%s" % repr( next( g2)))
    print( "%s" % repr( g2.send( "I want to complain")))

    g = wrapper( 'abcd')
    print( "%s" % repr( list( g)))
    g = wrapper2( 'abcd')
    print( "%s" % repr( list( g)))

    s = switchboard()
    print( "%s" % repr( next( s)))
    print( "%s" % repr( s.send(1)))
    print( "%s" % repr( s.send('hello')))

    s = switchboard2()
    print( "%s" % repr( next( s)))
    print( "%s" % repr( s.send(2)))
    print( "%s" % repr( s.send('hi there')))
    print( "%s" % repr( s.send( None)))
    print( "%s" % repr( s.send(1)))
    print( "%s" % repr( s.send( "hello")))
    
    return 

if __name__ == "__main__":
    main()