""" A coroutine to compute a running average. Testing ``averager`` by itself:: # tag::RETURNING_AVERAGER_DEMO1[] >>> coro_avg = averager() >>> next(coro_avg) >>> coro_avg.send(10) # <1> >>> coro_avg.send(30) >>> coro_avg.send(6.5) >>> coro_avg.send(None) # <2> Traceback (most recent call last): ... StopIteration: Result(count=3, average=15.5) # end::RETURNING_AVERAGER_DEMO1[] Catching `StopIteration` to extract the value returned by the coroutine:: # tag::RETURNING_AVERAGER_DEMO2[] >>> coro_avg = averager() >>> next(coro_avg) >>> coro_avg.send(10) >>> coro_avg.send(30) >>> coro_avg.send(6.5) >>> try: ... coro_avg.send(None) ... except StopIteration as exc: ... result = exc.value ... >>> result Result(count=3, average=15.5) # end::RETURNING_AVERAGER_DEMO2[] """ # tag::RETURNING_AVERAGER[] from collections import namedtuple Result = namedtuple('Result', 'count average') def averager(): total = 0.0 count = 0 average = None while True: term = yield if term is None: break # <1> total += term count += 1 average = total/count return Result(count, average) # <2> # end::RETURNING_AVERAGER[]