moved lispy from 02 to 18
This commit is contained in:
@@ -5,7 +5,7 @@ import itertools
|
||||
def aritprog_gen(begin, step, end=None):
|
||||
first = type(begin + step)(begin)
|
||||
ap_gen = itertools.count(first, step)
|
||||
if end is not None:
|
||||
ap_gen = itertools.takewhile(lambda n: n < end, ap_gen)
|
||||
return ap_gen
|
||||
if end is None:
|
||||
return ap_gen
|
||||
return itertools.takewhile(lambda n: n < end, ap_gen)
|
||||
# end::ARITPROG_ITERTOOLS[]
|
||||
|
||||
43
17-it-generator/coroaverager.py
Normal file
43
17-it-generator/coroaverager.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
A coroutine to compute a running average
|
||||
|
||||
# tag::CORO_AVERAGER_TEST[]
|
||||
>>> coro_avg = averager() # <1>
|
||||
>>> next(coro_avg) # <2>
|
||||
0.0
|
||||
>>> coro_avg.send(10) # <3>
|
||||
10.0
|
||||
>>> coro_avg.send(30)
|
||||
20.0
|
||||
>>> coro_avg.send(5)
|
||||
15.0
|
||||
|
||||
# end::CORO_AVERAGER_TEST[]
|
||||
# tag::CORO_AVERAGER_TEST_CONT[]
|
||||
|
||||
>>> coro_avg.send(20) # <1>
|
||||
16.25
|
||||
>>> coro_avg.close() # <2>
|
||||
>>> coro_avg.close() # <3>
|
||||
>>> coro_avg.send(5) # <4>
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
StopIteration
|
||||
|
||||
# end::CORO_AVERAGER_TEST_CONT[]
|
||||
|
||||
"""
|
||||
|
||||
# tag::CORO_AVERAGER[]
|
||||
from collections.abc import Generator
|
||||
|
||||
def averager() -> Generator[float, float, None]: # <1>
|
||||
total = 0.0
|
||||
count = 0
|
||||
average = 0.0
|
||||
while True: # <2>
|
||||
term = yield average # <3>
|
||||
total += term
|
||||
count += 1
|
||||
average = total/count
|
||||
# end::CORO_AVERAGER[]
|
||||
96
17-it-generator/coroaverager2.py
Normal file
96
17-it-generator/coroaverager2.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""
|
||||
A coroutine to compute a running average.
|
||||
|
||||
Testing ``averager2`` by itself::
|
||||
|
||||
# tag::RETURNING_AVERAGER_DEMO_1[]
|
||||
|
||||
>>> coro_avg = averager2()
|
||||
>>> next(coro_avg)
|
||||
>>> coro_avg.send(10) # <1>
|
||||
>>> coro_avg.send(30)
|
||||
>>> coro_avg.send(6.5)
|
||||
>>> coro_avg.close() # <2>
|
||||
|
||||
# end::RETURNING_AVERAGER_DEMO_1[]
|
||||
|
||||
Catching `StopIteration` to extract the value returned by
|
||||
the coroutine::
|
||||
|
||||
# tag::RETURNING_AVERAGER_DEMO_2[]
|
||||
|
||||
>>> coro_avg = averager2()
|
||||
>>> next(coro_avg)
|
||||
>>> coro_avg.send(10)
|
||||
>>> coro_avg.send(30)
|
||||
>>> coro_avg.send(6.5)
|
||||
>>> try:
|
||||
... coro_avg.send(STOP) # <1>
|
||||
... except StopIteration as exc:
|
||||
... result = exc.value # <2>
|
||||
...
|
||||
>>> result # <3>
|
||||
Result(count=3, average=15.5)
|
||||
|
||||
# end::RETURNING_AVERAGER_DEMO_2[]
|
||||
|
||||
Using `yield from`:
|
||||
|
||||
|
||||
# tag::RETURNING_AVERAGER_DEMO_3[]
|
||||
|
||||
>>> def compute():
|
||||
... res = yield from averager2(True) # <1>
|
||||
... print('computed:', res) # <2>
|
||||
... return res # <3>
|
||||
...
|
||||
>>> comp = compute() # <4>
|
||||
>>> for v in [None, 10, 20, 30, STOP]: # <5>
|
||||
... try:
|
||||
... comp.send(v) # <6>
|
||||
... except StopIteration as exc: # <7>
|
||||
... result = exc.value
|
||||
received: 10
|
||||
received: 20
|
||||
received: 30
|
||||
received: <Sentinel>
|
||||
computed: Result(count=3, average=20.0)
|
||||
>>> result # <8>
|
||||
Result(count=3, average=20.0)
|
||||
|
||||
# end::RETURNING_AVERAGER_DEMO_3[]
|
||||
"""
|
||||
|
||||
# tag::RETURNING_AVERAGER_TOP[]
|
||||
from collections.abc import Generator
|
||||
from typing import Union, NamedTuple
|
||||
|
||||
class Result(NamedTuple): # <1>
|
||||
count: int # type: ignore # <2>
|
||||
average: float
|
||||
|
||||
class Sentinel: # <3>
|
||||
def __repr__(self):
|
||||
return f'<Sentinel>'
|
||||
|
||||
STOP = Sentinel() # <4>
|
||||
|
||||
SendType = Union[float, Sentinel] # <5>
|
||||
# end::RETURNING_AVERAGER_TOP[]
|
||||
# tag::RETURNING_AVERAGER[]
|
||||
def averager2(verbose: bool = False) -> Generator[None, SendType, Result]: # <1>
|
||||
total = 0.0
|
||||
count = 0
|
||||
average = 0.0
|
||||
while True:
|
||||
term = yield # <2>
|
||||
if verbose:
|
||||
print('received:', term)
|
||||
if isinstance(term, Sentinel): # <3>
|
||||
break
|
||||
total += term # <4>
|
||||
count += 1
|
||||
average = total / count
|
||||
return Result(count, average) # <5>
|
||||
|
||||
# end::RETURNING_AVERAGER[]
|
||||
7
17-it-generator/fibo_gen.py
Normal file
7
17-it-generator/fibo_gen.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from collections.abc import Iterator
|
||||
|
||||
def fibonacci() -> Iterator[int]:
|
||||
a, b = 0, 1
|
||||
while True:
|
||||
yield a
|
||||
a, b = b, a + b
|
||||
@@ -21,7 +21,7 @@ class Sentence:
|
||||
def __iter__(self):
|
||||
for word in self.words: # <1>
|
||||
yield word # <2>
|
||||
return # <3>
|
||||
# <3>
|
||||
|
||||
# done! <4>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user