updated from Atlas repo

This commit is contained in:
Luciano Ramalho 2014-12-14 01:26:42 -02:00
parent dcd59eef31
commit 33d65dc590
21 changed files with 359 additions and 299 deletions

View File

@ -8,9 +8,9 @@ Arithmetic progression class
"""
import array
from collections import abc
class ArithmeticProgression:
def __init__(self, begin, step, end):
@ -29,7 +29,8 @@ class ArithmeticProgressionIterator(abc.Iterator):
self._index = 0
def __next__(self):
result = self._ap.begin + self._ap.step * self._index
first = type(self._ap.begin + self._ap.step)(self._ap.begin)
result = first + self._ap.step * self._index
if result < self._ap.end:
self._index += 1
return result

View File

@ -0,0 +1,35 @@
"""
Arithmetic progression generator function.
This is almost correct. The only problem is that the first
item in the series may not be of the same type as the rest,
an this may be important to the user::
>>> ap = aritprog_gen(1, .5, 3)
>>> list(ap)
[1, 1.5, 2.0, 2.5]
>>> ap = aritprog_gen(0, 1/3, 1)
>>> list(ap)
[0, 0.3333333333333333, 0.6666666666666666]
>>> from fractions import Fraction
>>> ap = aritprog_gen(0, Fraction(1, 3), 1)
>>> list(ap)
[0, Fraction(1, 3), Fraction(2, 3)]
>>> from decimal import Decimal
>>> ap = aritprog_gen(0, Decimal('.1'), .3)
>>> list(ap)
[0, Decimal('0.1'), Decimal('0.2')]
"""
# BEGIN ALMOST_ARITPROG_ITERTOOLS
import itertools
def aritprog_gen(begin, step, end=None):
ap_gen = itertools.count(begin, step)
if end is not None:
ap_gen = itertools.takewhile(lambda n: n < end, ap_gen)
return ap_gen
# END ALMOST_ARITPROG_ITERTOOLS

31
iterables/aritprog.rst Normal file
View 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)
[]

View 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))

View 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
iterables/aritprog_v0.py Normal file
View 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

View File

@ -1,48 +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
"""
import array
from collections import abc
# BEGIN ARITPROG_CLASS
class ArithmeticProgression:
def __init__(self, begin, step, end):
def __init__(self, begin, step, end=None): # <1>
self.begin = begin
self.step = step
self.end = end
self._build()
def _build(self):
self._numbers = array.array('d')
n = self.begin
while n < self.end:
self._numbers.append(n)
n += self.step
self.end = end # None -> "infinite" series
def __iter__(self):
return ArithmeticProgressionIterator(self._numbers)
class ArithmeticProgressionIterator(abc.Iterator):
def __init__(self, series):
self._series = series
self._index = 0
def __next__(self):
if self._index < len(self._series):
item = self._series[self._index]
self._index += 1
return item
else:
raise StopIteration
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

View File

@ -1,32 +1,31 @@
"""
Arithmetic progression class
Arithmetic progression generator function::
>>> ap = ArithmeticProgression(1, .5, 3)
>>> 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')]
"""
import array
from collections import abc
class ArithmeticProgression:
def __init__(self, begin, step, end):
self.begin = begin
self.step = step
self.end = end
self._build()
def _build(self):
self._numbers = array.array('d')
n = self.begin
while n < self.end:
self._numbers.append(n)
n += self.step
def __iter__(self):
for item in self._numbers:
yield item
return StopIteration
# 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

View File

@ -1,27 +1,11 @@
"""
Arithmetic progression class
>>> ap = ArithmeticProgression(1, .5, 3)
>>> list(ap)
[1.0, 1.5, 2.0, 2.5]
# BEGIN ARITPROG_ITERTOOLS
import itertools
"""
import array
from collections import abc
class ArithmeticProgression:
def __init__(self, begin, step, end=None):
self.begin = float(begin)
self.step = float(step)
self.end = end # None -> "infinite" series
def __iter__(self):
result = self.begin
forever = self.end is None
while forever or result < self.end:
yield result
result += self.step
raise StopIteration
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

View File

@ -1,29 +1,14 @@
"""
Arithmetic progression class
>>> ap = ArithmeticProgression(1, .5, 3)
>>> list(ap)
[1.0, 1.5, 2.0, 2.5]
# BEGIN ARITPROG_ITERTOOLS
import itertools
"""
import array
from collections import abc
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.step)(self.begin)
forever = self.end is None
index = 0
while forever or result < self.end:
yield result
index += 1
result = self.begin + self.step * index
raise StopIteration
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
iterables/aritprog_v5.py Normal file
View 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

54
iterables/sentence.rst Normal file
View 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']

View File

@ -1,40 +0,0 @@
>>> from sentence_gen import Sentence
>>> 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
>>> 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']
>>> 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']
>>> 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']

View File

@ -12,12 +12,14 @@ 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 match in RE_WORD.finditer(self.text): # <1>
yield match.group() # <2>
for word in self.words: # <1>
yield word # <2>
return # <3>
# done! <3>
# done! <4>

View 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>

View File

@ -1,40 +0,0 @@
>>> from sentence_genexp import Sentence
>>> 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
>>> 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']
>>> 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']
>>> 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']

View File

@ -1,40 +0,0 @@
>>> from sentence_iter import Sentence
>>> 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
>>> 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']
>>> 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']
>>> 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']

View File

@ -22,10 +22,10 @@ class Sentence:
return 'Sentence(%s)' % reprlib.repr(self.text)
def __iter__(self): # <1>
return SentenceIter(self.words) # <2>
return SentenceIterator(self.words) # <2>
class SentenceIter:
class SentenceIterator:
def __init__(self, words):
self.words = words # <3>

View File

@ -1,40 +0,0 @@
>>> from sentence_iter2 import Sentence
>>> 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
>>> 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']
>>> 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']
>>> 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']

View 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)

View File

@ -1,24 +0,0 @@
"""
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_v3 import ArithmeticProgression as APv3
from aritprog_v4 import ArithmeticProgression as APv4
ap3 = iter(APv3(1, .1))
ap4 = iter(APv4(1, .1))
ap_frac = iter(APv4(Fraction(1, 1), Fraction(1, 10)))
epsilon = 10**-10
iteration = 0
delta = next(ap3) - next(ap4)
frac = next(ap_frac)
while abs(delta) <= epsilon:
delta = next(ap3) - next(ap4)
frac = next(ap_frac)
iteration +=1
print('iteration: {}\tfraction: {}\tepsilon: {}\tdelta: {}'.
format(iteration, frac, epsilon, delta))