update from Atlas
This commit is contained in:
31
14-it-generator/aritprog.rst
Normal file
31
14-it-generator/aritprog.rst
Normal file
@@ -0,0 +1,31 @@
|
||||
===========================================
|
||||
Tests for arithmetic progression generators
|
||||
===========================================
|
||||
|
||||
Tests with built-in numeric types::
|
||||
|
||||
>>> ap = aritprog_gen(1, .5, 3)
|
||||
>>> list(ap)
|
||||
[1.0, 1.5, 2.0, 2.5]
|
||||
>>> ap = aritprog_gen(0, 1/3, 1)
|
||||
>>> list(ap)
|
||||
[0.0, 0.3333333333333333, 0.6666666666666666]
|
||||
|
||||
|
||||
Tests with standard library numeric types::
|
||||
|
||||
>>> from fractions import Fraction
|
||||
>>> ap = aritprog_gen(0, Fraction(1, 3), 1)
|
||||
>>> list(ap)
|
||||
[Fraction(0, 1), Fraction(1, 3), Fraction(2, 3)]
|
||||
>>> from decimal import Decimal
|
||||
>>> ap = aritprog_gen(0, Decimal('.1'), .3)
|
||||
>>> list(ap)
|
||||
[Decimal('0'), Decimal('0.1'), Decimal('0.2')]
|
||||
|
||||
|
||||
Test producing an empty series::
|
||||
|
||||
>>> ap = aritprog_gen(0, 1, 0)
|
||||
>>> list(ap)
|
||||
[]
|
||||
26
14-it-generator/aritprog_float_error.py
Normal file
26
14-it-generator/aritprog_float_error.py
Normal file
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
Demonstrate difference between Arithmetic Progression calculated
|
||||
as a series of increments accumulating errors versus one addition
|
||||
and one multiplication.
|
||||
"""
|
||||
|
||||
from fractions import Fraction
|
||||
from aritprog_v0 import ArithmeticProgression as APv0
|
||||
from aritprog_v1 import ArithmeticProgression as APv1
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
ap0 = iter(APv0(1, .1))
|
||||
ap1 = iter(APv1(1, .1))
|
||||
ap_frac = iter(APv1(Fraction(1, 1), Fraction(1, 10)))
|
||||
epsilon = 10**-10
|
||||
iteration = 0
|
||||
delta = next(ap0) - next(ap1)
|
||||
frac = next(ap_frac)
|
||||
while abs(delta) <= epsilon:
|
||||
delta = next(ap0) - next(ap1)
|
||||
frac = next(ap_frac)
|
||||
iteration +=1
|
||||
|
||||
print('iteration: {}\tfraction: {}\tepsilon: {}\tdelta: {}'.
|
||||
format(iteration, frac, epsilon, delta))
|
||||
37
14-it-generator/aritprog_runner.py
Normal file
37
14-it-generator/aritprog_runner.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import doctest
|
||||
import importlib
|
||||
import glob
|
||||
|
||||
|
||||
TARGET_GLOB = 'aritprog*.py'
|
||||
TEST_FILE = 'aritprog.rst'
|
||||
TEST_MSG = '{0:16} {1.attempted:2} tests, {1.failed:2} failed - {2}'
|
||||
|
||||
|
||||
def main(argv):
|
||||
verbose = '-v' in argv
|
||||
for module_file_name in sorted(glob.glob(TARGET_GLOB)):
|
||||
module_name = module_file_name.replace('.py', '')
|
||||
module = importlib.import_module(module_name)
|
||||
gen_factory = getattr(module, 'ArithmeticProgression', None)
|
||||
if gen_factory is None:
|
||||
gen_factory = getattr(module, 'aritprog_gen', None)
|
||||
if gen_factory is None:
|
||||
continue
|
||||
|
||||
test(gen_factory, verbose)
|
||||
|
||||
|
||||
def test(gen_factory, verbose=False):
|
||||
res = doctest.testfile(
|
||||
TEST_FILE,
|
||||
globs={'aritprog_gen': gen_factory},
|
||||
verbose=verbose,
|
||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)
|
||||
tag = 'FAIL' if res.failed else 'OK'
|
||||
print(TEST_MSG.format(gen_factory.__module__, res, tag))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
main(sys.argv)
|
||||
24
14-it-generator/aritprog_v0.py
Normal file
24
14-it-generator/aritprog_v0.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""
|
||||
Arithmetic progression class
|
||||
|
||||
>>> ap = ArithmeticProgression(1, .5, 3)
|
||||
>>> list(ap)
|
||||
[1.0, 1.5, 2.0, 2.5]
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class ArithmeticProgression:
|
||||
|
||||
def __init__(self, begin, step, end=None):
|
||||
self.begin = begin
|
||||
self.step = step
|
||||
self.end = end # None -> "infinite" series
|
||||
|
||||
def __iter__(self):
|
||||
result = type(self.begin + self.step)(self.begin)
|
||||
forever = self.end is None
|
||||
while forever or result < self.end:
|
||||
yield result
|
||||
result += self.step
|
||||
44
14-it-generator/aritprog_v1.py
Normal file
44
14-it-generator/aritprog_v1.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""
|
||||
Arithmetic progression class
|
||||
|
||||
# BEGIN ARITPROG_CLASS_DEMO
|
||||
|
||||
>>> ap = ArithmeticProgression(0, 1, 3)
|
||||
>>> list(ap)
|
||||
[0, 1, 2]
|
||||
>>> ap = ArithmeticProgression(1, .5, 3)
|
||||
>>> list(ap)
|
||||
[1.0, 1.5, 2.0, 2.5]
|
||||
>>> ap = ArithmeticProgression(0, 1/3, 1)
|
||||
>>> list(ap)
|
||||
[0.0, 0.3333333333333333, 0.6666666666666666]
|
||||
>>> from fractions import Fraction
|
||||
>>> ap = ArithmeticProgression(0, Fraction(1, 3), 1)
|
||||
>>> list(ap)
|
||||
[Fraction(0, 1), Fraction(1, 3), Fraction(2, 3)]
|
||||
>>> from decimal import Decimal
|
||||
>>> ap = ArithmeticProgression(0, Decimal('.1'), .3)
|
||||
>>> list(ap)
|
||||
[Decimal('0.0'), Decimal('0.1'), Decimal('0.2')]
|
||||
|
||||
# END ARITPROG_CLASS_DEMO
|
||||
"""
|
||||
|
||||
|
||||
# BEGIN ARITPROG_CLASS
|
||||
class ArithmeticProgression:
|
||||
|
||||
def __init__(self, begin, step, end=None): # <1>
|
||||
self.begin = begin
|
||||
self.step = step
|
||||
self.end = end # None -> "infinite" series
|
||||
|
||||
def __iter__(self):
|
||||
result = type(self.begin + self.step)(self.begin) # <2>
|
||||
forever = self.end is None # <3>
|
||||
index = 0
|
||||
while forever or result < self.end: # <4>
|
||||
yield result # <5>
|
||||
index += 1
|
||||
result = self.begin + self.step * index # <6>
|
||||
# END ARITPROG_CLASS
|
||||
31
14-it-generator/aritprog_v2.py
Normal file
31
14-it-generator/aritprog_v2.py
Normal file
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
Arithmetic progression generator function::
|
||||
|
||||
>>> ap = aritprog_gen(1, .5, 3)
|
||||
>>> list(ap)
|
||||
[1.0, 1.5, 2.0, 2.5]
|
||||
>>> ap = aritprog_gen(0, 1/3, 1)
|
||||
>>> list(ap)
|
||||
[0.0, 0.3333333333333333, 0.6666666666666666]
|
||||
>>> from fractions import Fraction
|
||||
>>> ap = aritprog_gen(0, Fraction(1, 3), 1)
|
||||
>>> list(ap)
|
||||
[Fraction(0, 1), Fraction(1, 3), Fraction(2, 3)]
|
||||
>>> from decimal import Decimal
|
||||
>>> ap = aritprog_gen(0, Decimal('.1'), .3)
|
||||
>>> list(ap)
|
||||
[Decimal('0.0'), Decimal('0.1'), Decimal('0.2')]
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# BEGIN ARITPROG_GENFUNC
|
||||
def aritprog_gen(begin, step, end=None):
|
||||
result = type(begin + step)(begin)
|
||||
forever = end is None
|
||||
index = 0
|
||||
while forever or result < end:
|
||||
yield result
|
||||
index += 1
|
||||
result = begin + step * index
|
||||
# END ARITPROG_GENFUNC
|
||||
11
14-it-generator/aritprog_v3.py
Normal file
11
14-it-generator/aritprog_v3.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# BEGIN ARITPROG_ITERTOOLS
|
||||
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
|
||||
# END ARITPROG_ITERTOOLS
|
||||
14
14-it-generator/aritprog_v4.py
Normal file
14
14-it-generator/aritprog_v4.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# BEGIN ARITPROG_ITERTOOLS
|
||||
import itertools
|
||||
|
||||
|
||||
def aritprog_gen(begin, step, end=None):
|
||||
if end is not None and begin >= end:
|
||||
return
|
||||
yield type(begin + step)(begin)
|
||||
tail_gen = itertools.count(begin+step, step)
|
||||
if end is not None:
|
||||
tail_gen = itertools.takewhile(lambda n: n < end, tail_gen)
|
||||
for x in tail_gen:
|
||||
yield x
|
||||
# END ARITPROG_ITERTOOLS
|
||||
13
14-it-generator/aritprog_v5.py
Normal file
13
14-it-generator/aritprog_v5.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# BEGIN ARITPROG_ITERTOOLS
|
||||
import itertools
|
||||
|
||||
|
||||
def aritprog_gen(begin, step, end=None):
|
||||
if end is not None and begin >= end:
|
||||
return
|
||||
yield type(begin + step)(begin)
|
||||
tail_gen = itertools.count(begin+step, step)
|
||||
if end is not None:
|
||||
tail_gen = itertools.takewhile(lambda n: n < end, tail_gen)
|
||||
yield from tail_gen
|
||||
# END ARITPROG_ITERTOOLS
|
||||
51
14-it-generator/fibo_by_hand.py
Normal file
51
14-it-generator/fibo_by_hand.py
Normal file
@@ -0,0 +1,51 @@
|
||||
"""
|
||||
Fibonacci generator implemented "by hand" without generator objects
|
||||
|
||||
>>> from itertools import islice
|
||||
>>> list(islice(Fibonacci(), 15))
|
||||
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# BEGIN FIBO_BY_HAND
|
||||
class Fibonacci:
|
||||
|
||||
def __iter__(self):
|
||||
return FibonacciGenerator()
|
||||
|
||||
|
||||
class FibonacciGenerator:
|
||||
|
||||
def __init__(self):
|
||||
self.a = 0
|
||||
self.b = 1
|
||||
|
||||
def __next__(self):
|
||||
result = self.a
|
||||
self.a, self.b = self.b, self.a + self.b
|
||||
return result
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
# END FIBO_BY_HAND
|
||||
|
||||
# for comparison, this is the usual implementation of a Fibonacci
|
||||
# generator in Python:
|
||||
|
||||
|
||||
def fibonacci():
|
||||
a, b = 0, 1
|
||||
while True:
|
||||
yield a
|
||||
a, b = b, a + b
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
for x, y in zip(Fibonacci(), fibonacci()):
|
||||
assert x == y, '%s != %s' % (x, y)
|
||||
print(x)
|
||||
if x > 10**10:
|
||||
break
|
||||
print('etc...')
|
||||
24
14-it-generator/sentence.py
Normal file
24
14-it-generator/sentence.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""
|
||||
Sentence: access words by index
|
||||
"""
|
||||
|
||||
import re
|
||||
import reprlib
|
||||
|
||||
RE_WORD = re.compile('\w+')
|
||||
|
||||
|
||||
class Sentence:
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = text
|
||||
self.words = RE_WORD.findall(text) # <1>
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.words[index] # <2>
|
||||
|
||||
def __len__(self, index): # <3>
|
||||
return len(self.words)
|
||||
|
||||
def __repr__(self):
|
||||
return 'Sentence(%s)' % reprlib.repr(self.text) # <4>
|
||||
54
14-it-generator/sentence.rst
Normal file
54
14-it-generator/sentence.rst
Normal file
@@ -0,0 +1,54 @@
|
||||
==============================
|
||||
Tests for a ``Sentence`` class
|
||||
==============================
|
||||
|
||||
A ``Sentence`` is built from a ``str`` and allows iteration
|
||||
word-by-word.
|
||||
|
||||
::
|
||||
>>> s = Sentence('The time has come')
|
||||
>>> s
|
||||
Sentence('The time has come')
|
||||
>>> list(s)
|
||||
['The', 'time', 'has', 'come']
|
||||
>>> it = iter(s)
|
||||
>>> next(it)
|
||||
'The'
|
||||
>>> next(it)
|
||||
'time'
|
||||
>>> next(it)
|
||||
'has'
|
||||
>>> next(it)
|
||||
'come'
|
||||
>>> next(it)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
StopIteration
|
||||
|
||||
|
||||
Any punctuation is skipped while iterating::
|
||||
|
||||
>>> s = Sentence('"The time has come," the Walrus said,')
|
||||
>>> s
|
||||
Sentence('"The time ha... Walrus said,')
|
||||
>>> list(s)
|
||||
['The', 'time', 'has', 'come', 'the', 'Walrus', 'said']
|
||||
|
||||
|
||||
White space including line breaks are also ignored::
|
||||
|
||||
>>> s = Sentence('''"The time has come," the Walrus said,
|
||||
... "To talk of many things:"''')
|
||||
>>> s
|
||||
Sentence('"The time ha...many things:"')
|
||||
>>> list(s)
|
||||
['The', 'time', 'has', 'come', 'the', 'Walrus', 'said', 'To', 'talk', 'of', 'many', 'things']
|
||||
|
||||
|
||||
Accented Latin characters are also recognized as word characters::
|
||||
|
||||
>>> s = Sentence('Agora vou-me. Ou me vão?')
|
||||
>>> s
|
||||
Sentence('Agora vou-me. Ou me vão?')
|
||||
>>> list(s)
|
||||
['Agora', 'vou', 'me', 'Ou', 'me', 'vão']
|
||||
25
14-it-generator/sentence_gen.py
Normal file
25
14-it-generator/sentence_gen.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""
|
||||
Sentence: iterate over words using a generator function
|
||||
"""
|
||||
|
||||
import re
|
||||
import reprlib
|
||||
|
||||
RE_WORD = re.compile('\w+')
|
||||
|
||||
|
||||
class Sentence:
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = text
|
||||
self.words = RE_WORD.findall(text)
|
||||
|
||||
def __repr__(self):
|
||||
return 'Sentence(%s)' % reprlib.repr(self.text)
|
||||
|
||||
def __iter__(self):
|
||||
for word in self.words: # <1>
|
||||
yield word # <2>
|
||||
return # <3>
|
||||
|
||||
# done! <4>
|
||||
21
14-it-generator/sentence_gen2.py
Normal file
21
14-it-generator/sentence_gen2.py
Normal file
@@ -0,0 +1,21 @@
|
||||
"""
|
||||
Sentence: iterate over words using a generator function
|
||||
"""
|
||||
|
||||
import re
|
||||
import reprlib
|
||||
|
||||
RE_WORD = re.compile('\w+')
|
||||
|
||||
|
||||
class Sentence:
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = text # <1>
|
||||
|
||||
def __repr__(self):
|
||||
return 'Sentence(%s)' % reprlib.repr(self.text)
|
||||
|
||||
def __iter__(self):
|
||||
for match in RE_WORD.finditer(self.text): # <2>
|
||||
yield match.group() # <3>
|
||||
44
14-it-generator/sentence_genexp.py
Normal file
44
14-it-generator/sentence_genexp.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""
|
||||
Sentence: iterate over words using a generator expression
|
||||
"""
|
||||
|
||||
# BEGIN SENTENCE_GENEXP
|
||||
import re
|
||||
import reprlib
|
||||
|
||||
RE_WORD = re.compile('\w+')
|
||||
|
||||
|
||||
class Sentence:
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = text
|
||||
|
||||
def __repr__(self):
|
||||
return 'Sentence(%s)' % reprlib.repr(self.text)
|
||||
|
||||
def __iter__(self):
|
||||
return (match.group() for match in RE_WORD.finditer(self.text))
|
||||
# END SENTENCE_GENEXP
|
||||
|
||||
|
||||
def main():
|
||||
import sys
|
||||
import warnings
|
||||
try:
|
||||
filename = sys.argv[1]
|
||||
word_number = int(sys.argv[2])
|
||||
except (IndexError, ValueError):
|
||||
print('Usage: %s <file-name> <word-number>' % sys.argv[0])
|
||||
sys.exit(1)
|
||||
with open(filename, 'rt', encoding='utf-8') as text_file:
|
||||
s = Sentence(text_file.read())
|
||||
for n, word in enumerate(s, 1):
|
||||
if n == word_number:
|
||||
print(word)
|
||||
break
|
||||
else:
|
||||
warnings.warn('last word is #%d, "%s"' % (n, word))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
65
14-it-generator/sentence_iter.py
Normal file
65
14-it-generator/sentence_iter.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""
|
||||
Sentence: iterate over words using the Iterator Pattern, take #1
|
||||
|
||||
WARNING: the Iterator Pattern is much simpler in idiomatic Python;
|
||||
see: sentence_gen*.py.
|
||||
"""
|
||||
|
||||
# BEGIN SENTENCE_ITER
|
||||
import re
|
||||
import reprlib
|
||||
|
||||
RE_WORD = re.compile('\w+')
|
||||
|
||||
|
||||
class Sentence:
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = text
|
||||
self.words = RE_WORD.findall(text)
|
||||
|
||||
def __repr__(self):
|
||||
return 'Sentence(%s)' % reprlib.repr(self.text)
|
||||
|
||||
def __iter__(self): # <1>
|
||||
return SentenceIterator(self.words) # <2>
|
||||
|
||||
|
||||
class SentenceIterator:
|
||||
|
||||
def __init__(self, words):
|
||||
self.words = words # <3>
|
||||
self.index = 0 # <4>
|
||||
|
||||
def __next__(self):
|
||||
try:
|
||||
word = self.words[self.index] # <5>
|
||||
except IndexError:
|
||||
raise StopIteration() # <6>
|
||||
self.index += 1 # <7>
|
||||
return word # <8>
|
||||
|
||||
def __iter__(self): # <9>
|
||||
return self
|
||||
# END SENTENCE_ITER
|
||||
|
||||
def main():
|
||||
import sys
|
||||
import warnings
|
||||
try:
|
||||
filename = sys.argv[1]
|
||||
word_number = int(sys.argv[2])
|
||||
except (IndexError, ValueError):
|
||||
print('Usage: %s <file-name> <word-number>' % sys.argv[0])
|
||||
sys.exit(1)
|
||||
with open(filename, 'rt', encoding='utf-8') as text_file:
|
||||
s = Sentence(text_file.read())
|
||||
for n, word in enumerate(s, 1):
|
||||
if n == word_number:
|
||||
print(word)
|
||||
break
|
||||
else:
|
||||
warnings.warn('last word is #%d, "%s"' % (n, word))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
37
14-it-generator/sentence_iter2.py
Normal file
37
14-it-generator/sentence_iter2.py
Normal file
@@ -0,0 +1,37 @@
|
||||
"""
|
||||
Sentence: iterate over words using the Iterator Pattern, take #2
|
||||
|
||||
WARNING: the Iterator Pattern is much simpler in idiomatic Python;
|
||||
see: sentence_gen*.py.
|
||||
"""
|
||||
|
||||
import re
|
||||
import reprlib
|
||||
|
||||
RE_WORD = re.compile('\w+')
|
||||
|
||||
|
||||
class Sentence:
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = text
|
||||
|
||||
def __repr__(self):
|
||||
return 'Sentence(%s)' % reprlib.repr(self.text)
|
||||
|
||||
def __iter__(self):
|
||||
word_iter = RE_WORD.finditer(self.text) # <1>
|
||||
return SentenceIter(word_iter) # <2>
|
||||
|
||||
|
||||
class SentenceIter():
|
||||
|
||||
def __init__(self, word_iter):
|
||||
self.word_iter = word_iter # <3>
|
||||
|
||||
def __next__(self):
|
||||
match = next(self.word_iter) # <4>
|
||||
return match.group() # <5>
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
36
14-it-generator/sentence_runner.py
Normal file
36
14-it-generator/sentence_runner.py
Normal file
@@ -0,0 +1,36 @@
|
||||
import doctest
|
||||
import importlib
|
||||
import glob
|
||||
|
||||
|
||||
TARGET_GLOB = 'sentence*.py'
|
||||
TEST_FILE = 'sentence.rst'
|
||||
TEST_MSG = '{0:16} {1.attempted:2} tests, {1.failed:2} failed - {2}'
|
||||
|
||||
|
||||
def main(argv):
|
||||
verbose = '-v' in argv
|
||||
for module_file_name in sorted(glob.glob(TARGET_GLOB)):
|
||||
module_name = module_file_name.replace('.py', '')
|
||||
module = importlib.import_module(module_name)
|
||||
try:
|
||||
cls = getattr(module, 'Sentence')
|
||||
except AttributeError:
|
||||
continue
|
||||
test(cls, verbose)
|
||||
|
||||
|
||||
def test(cls, verbose=False):
|
||||
|
||||
res = doctest.testfile(
|
||||
TEST_FILE,
|
||||
globs={'Sentence': cls},
|
||||
verbose=verbose,
|
||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)
|
||||
tag = 'FAIL' if res.failed else 'OK'
|
||||
print(TEST_MSG.format(cls.__module__, res, tag))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
main(sys.argv)
|
||||
29
14-it-generator/yield_delegate_fail.py
Normal file
29
14-it-generator/yield_delegate_fail.py
Normal file
@@ -0,0 +1,29 @@
|
||||
""" Example from `Python: The Full Monty`__ -- A Tested Semantics for the
|
||||
Python Programming Language
|
||||
|
||||
__ http://cs.brown.edu/~sk/Publications/Papers/Published/pmmwplck-python-full-monty/
|
||||
|
||||
"The following program, [...] seems to perform a simple abstraction over the
|
||||
process of yielding:"
|
||||
|
||||
Citation:
|
||||
|
||||
Joe Gibbs Politz, Alejandro Martinez, Matthew Milano, Sumner Warren,
|
||||
Daniel Patterson, Junsong Li, Anand Chitipothu, and Shriram Krishnamurthi.
|
||||
2013. Python: the full monty. SIGPLAN Not. 48, 10 (October 2013), 217-232.
|
||||
DOI=10.1145/2544173.2509536 http://doi.acm.org/10.1145/2544173.2509536
|
||||
"""
|
||||
|
||||
# BEGIN YIELD_DELEGATE_FAIL
|
||||
def f():
|
||||
def do_yield(n):
|
||||
yield n
|
||||
x = 0
|
||||
while True:
|
||||
x += 1
|
||||
do_yield(x)
|
||||
# END YIELD_DELEGATE_FAIL
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('Invoking f() results in an infinite loop')
|
||||
f()
|
||||
24
14-it-generator/yield_delegate_fix.py
Normal file
24
14-it-generator/yield_delegate_fix.py
Normal file
@@ -0,0 +1,24 @@
|
||||
""" Example adapted from ``yield_delegate_fail.py``
|
||||
|
||||
The following program performs a simple abstraction over the process of
|
||||
yielding.
|
||||
|
||||
"""
|
||||
|
||||
# BEGIN YIELD_DELEGATE_FIX
|
||||
def f():
|
||||
def do_yield(n):
|
||||
yield n
|
||||
x = 0
|
||||
while True:
|
||||
x += 1
|
||||
yield from do_yield(x)
|
||||
# END YIELD_DELEGATE_FIX
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('Invoking f() now produces a generator')
|
||||
g = f()
|
||||
print(next(g))
|
||||
print(next(g))
|
||||
print(next(g))
|
||||
|
||||
Reference in New Issue
Block a user