updated contents from Atlas repo
This commit is contained in:
5
iterables/CACM/citation.txt
Normal file
5
iterables/CACM/citation.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Examples in this directory were adapted from:
|
||||
|
||||
Erik Meijer. 2014. The curse of the excluded middle.
|
||||
Commun. ACM 57, 6 (June 2014), 50-55. DOI=10.1145/2605176
|
||||
http://doi.acm.org/10.1145/2605176
|
||||
10
iterables/CACM/closed_file.py
Normal file
10
iterables/CACM/closed_file.py
Normal file
@@ -0,0 +1,10 @@
|
||||
"""
|
||||
Erik Meijer. 2014. The curse of the excluded middle.
|
||||
Commun. ACM 57, 6 (June 2014), 50-55. DOI=10.1145/2605176
|
||||
http://doi.acm.org/10.1145/2605176
|
||||
"""
|
||||
|
||||
with open('citation.txt', encoding='ascii') as fp:
|
||||
get_contents = lambda: fp.read()
|
||||
|
||||
print(get_contents())
|
||||
17
iterables/CACM/haha.py
Normal file
17
iterables/CACM/haha.py
Normal file
@@ -0,0 +1,17 @@
|
||||
"""
|
||||
Erik Meijer. 2014. The curse of the excluded middle.
|
||||
Commun. ACM 57, 6 (June 2014), 50-55. DOI=10.1145/2605176
|
||||
http://doi.acm.org/10.1145/2605176
|
||||
"""
|
||||
|
||||
def ha():
|
||||
ha = 'Ha'
|
||||
print(ha)
|
||||
return ha
|
||||
|
||||
# prints 'Ha' twice before showing result
|
||||
print('result ->', ha() + ha())
|
||||
|
||||
# prints 'Ha' only once before showing reult
|
||||
ha_res = ha() # common subexpression elimination
|
||||
print('result ->', ha_res + ha_res)
|
||||
22
iterables/CACM/less_more.py
Normal file
22
iterables/CACM/less_more.py
Normal file
@@ -0,0 +1,22 @@
|
||||
"""
|
||||
Meijer, Erik - The Curse of the Excluded Middle
|
||||
DOI:10.1145/2605176
|
||||
CACM vol.57 no.06
|
||||
"""
|
||||
|
||||
def less_than_30(n):
|
||||
check = n < 30
|
||||
print('%d < 30 : %s' % (n, check))
|
||||
return check
|
||||
|
||||
def more_than_20(n):
|
||||
check = n > 20
|
||||
print('%d > 20 : %s' % (n, check))
|
||||
return check
|
||||
|
||||
l = [1, 25, 40, 5, 23]
|
||||
q0 = (n for n in l if less_than_30(n))
|
||||
q1 = (n for n in q0 if more_than_20(n))
|
||||
|
||||
for n in q1:
|
||||
print('-> %d' % n)
|
||||
14
iterables/CACM/zero_div.py
Normal file
14
iterables/CACM/zero_div.py
Normal file
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
Erik Meijer. 2014. The curse of the excluded middle.
|
||||
Commun. ACM 57, 6 (June 2014), 50-55. DOI=10.1145/2605176
|
||||
http://doi.acm.org/10.1145/2605176
|
||||
"""
|
||||
|
||||
l = range(10, -1, -1)
|
||||
try:
|
||||
res = (1/x for x in l)
|
||||
except ZeroDivisionError:
|
||||
res = []
|
||||
|
||||
for z in res:
|
||||
print(z)
|
||||
40
iterables/sentence_gen.doctest
Normal file
40
iterables/sentence_gen.doctest
Normal file
@@ -0,0 +1,40 @@
|
||||
>>> 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']
|
||||
23
iterables/sentence_gen.py
Normal file
23
iterables/sentence_gen.py
Normal file
@@ -0,0 +1,23 @@
|
||||
"""
|
||||
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
|
||||
|
||||
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>
|
||||
|
||||
# done! <3>
|
||||
40
iterables/sentence_genexp.doctest
Normal file
40
iterables/sentence_genexp.doctest
Normal file
@@ -0,0 +1,40 @@
|
||||
>>> 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']
|
||||
44
iterables/sentence_genexp.py
Normal file
44
iterables/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()
|
||||
40
iterables/sentence_iter.doctest
Normal file
40
iterables/sentence_iter.doctest
Normal file
@@ -0,0 +1,40 @@
|
||||
>>> 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']
|
||||
65
iterables/sentence_iter.py
Normal file
65
iterables/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 SentenceIter(self.words) # <2>
|
||||
|
||||
|
||||
class SentenceIter:
|
||||
|
||||
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()
|
||||
40
iterables/sentence_iter2.doctest
Normal file
40
iterables/sentence_iter2.doctest
Normal file
@@ -0,0 +1,40 @@
|
||||
>>> 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']
|
||||
37
iterables/sentence_iter2.py
Normal file
37
iterables/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
|
||||
42
iterables/simplest_generators.doctest
Normal file
42
iterables/simplest_generators.doctest
Normal file
@@ -0,0 +1,42 @@
|
||||
>>> def gen_123():
|
||||
... yield 1
|
||||
... yield 2
|
||||
... yield 3
|
||||
...
|
||||
>>> gen_123 # doctest: +ELLIPSIS
|
||||
<function gen_123 at 0x...>
|
||||
>>> gen_123() # doctest: +ELLIPSIS
|
||||
<generator object gen_123 at 0x...>
|
||||
>>> for i in gen_123():
|
||||
... print(i)
|
||||
1
|
||||
2
|
||||
3
|
||||
>>> g = gen_123()
|
||||
>>> next(g)
|
||||
1
|
||||
>>> next(g)
|
||||
2
|
||||
>>> next(g)
|
||||
3
|
||||
>>> next(g)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
StopIteration
|
||||
|
||||
|
||||
>>> def gen_AB():
|
||||
... print('start')
|
||||
... yield 'A'
|
||||
... print('continue')
|
||||
... yield 'B'
|
||||
... print('end.')
|
||||
...
|
||||
>>> for c in gen_AB():
|
||||
... print('--->', c)
|
||||
...
|
||||
start
|
||||
---> A
|
||||
continue
|
||||
---> B
|
||||
end.
|
||||
103
iterables/vector.py
Normal file
103
iterables/vector.py
Normal file
@@ -0,0 +1,103 @@
|
||||
"""
|
||||
|
||||
The `+` operator produces a `Vector` result.
|
||||
|
||||
>>> v1 = Vector(2, 4)
|
||||
>>> v2 = Vector(2, 1)
|
||||
>>> v1 + v2
|
||||
Vector(4, 5)
|
||||
|
||||
We can also implemement the `*` operator to perform scalar multiplication
|
||||
or elementwise multiplication.
|
||||
|
||||
>>> v = Vector(3, 4)
|
||||
>>> abs(v)
|
||||
5.0
|
||||
>>> v * 3
|
||||
Vector(9, 12)
|
||||
>>> abs(v * 3)
|
||||
15.0
|
||||
>>> v25 = Vector(2, 5)
|
||||
>>> v71 = Vector(7, 1)
|
||||
>>> v71 * v25
|
||||
Vector(14, 5)
|
||||
|
||||
A vector can be used in a boolean context, where it will be considered
|
||||
_falsy_ if it has magnitude zero, otherwise it is _truthy_::
|
||||
|
||||
>>> bool(v)
|
||||
True
|
||||
>>> bool(Vector(0, 0))
|
||||
False
|
||||
|
||||
Vectors can have n-dimensions::
|
||||
|
||||
>>> v3 = Vector(1, 2, 3)
|
||||
>>> len(v3)
|
||||
3
|
||||
>>> v3
|
||||
Vector(1, 2, 3)
|
||||
>>> abs(v3) # doctest:+ELLIPSIS
|
||||
3.74165738...
|
||||
>>> v3 + Vector(4, 5, 6)
|
||||
Vector(5, 7, 9)
|
||||
>>> v3 * 5
|
||||
Vector(5, 10, 15)
|
||||
>>> v2 + v3
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Addition applies only to vectors of equal dimensions.
|
||||
|
||||
The `repr` of a Vector is produced with the help of the `reprlib.repr`
|
||||
function, limiting the size of the output string:
|
||||
|
||||
>>> Vector(*range(100))
|
||||
Vector(0, 1, 2, 3, 4, 5, ...)
|
||||
|
||||
"""
|
||||
|
||||
# BEGIN VECTOR_ITER
|
||||
import math
|
||||
import numbers
|
||||
import reprlib
|
||||
|
||||
EQ_DIMENSIONS_MSG = '%s applies only to vectors of equal dimensions.'
|
||||
|
||||
class Vector:
|
||||
"""An n-dimensional vector"""
|
||||
|
||||
def __init__(self, *components): # <1>
|
||||
self._components = tuple(components) # <2>
|
||||
|
||||
def __repr__(self):
|
||||
return 'Vector' + (reprlib.repr(self._components)) # <3>
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._components) # <4>
|
||||
|
||||
def __abs__(self):
|
||||
return math.sqrt(sum(comp*comp for comp in self)) # <5>
|
||||
|
||||
def __len__(self):
|
||||
return len(self._components) # <6>
|
||||
|
||||
def __add__(self, other):
|
||||
if len(self) != len(other):
|
||||
raise ValueError(EQ_DIMENSIONS_MSG % 'Addition')
|
||||
return Vector(*(a+b for a, b in zip(self, other))) # <7>
|
||||
|
||||
def __mul__(self, other):
|
||||
if isinstance(other, numbers.Number):
|
||||
return Vector(*(comp*other for comp in self)) # <8>
|
||||
else:
|
||||
return self.elementwise_mul(other) # <9>
|
||||
|
||||
def elementwise_mul(self, other):
|
||||
if len(self) != len(other):
|
||||
raise ValueError(EQ_DIMENSIONS_MSG %
|
||||
'Elementwise multiplication')
|
||||
return Vector(*(a*b for a, b in zip(self, other))) # <10>
|
||||
|
||||
def __bool__(self):
|
||||
return any(self) # <11>
|
||||
# END VECTOR_ITER
|
||||
43
iterables/vector_flex_init.py
Normal file
43
iterables/vector_flex_init.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
A more flexible `__init__` for the Vector class
|
||||
|
||||
A Vector can be built from an iterable:
|
||||
|
||||
>>> Vector([10, 20, 30])
|
||||
Vector(10, 20, 30)
|
||||
>>> Vector(range(1, 5))
|
||||
Vector(1, 2, 3, 4)
|
||||
|
||||
Or from two more arguments:
|
||||
|
||||
>>> Vector(100, 200)
|
||||
Vector(100, 200)
|
||||
>>> Vector(1, 2, 3, 4, 5)
|
||||
Vector(1, 2, 3, 4, 5)
|
||||
|
||||
One-dimensional vectors are not supported:
|
||||
|
||||
>>> Vector(99)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: Vector() takes one iterable argument or at least 2 scalar arguments
|
||||
|
||||
"""
|
||||
|
||||
import reprlib
|
||||
|
||||
|
||||
class Vector:
|
||||
"""An n-dimensional vector"""
|
||||
|
||||
def __init__(self, first, *rest): # <1>
|
||||
if rest:
|
||||
self._components = (first,) + tuple(rest) # <3>
|
||||
else:
|
||||
try:
|
||||
self._components = tuple(first) # <2>
|
||||
except TypeError:
|
||||
raise TypeError('Vector() takes one iterable argument or at least 2 scalar arguments')
|
||||
|
||||
def __repr__(self):
|
||||
return 'Vector' + reprlib.repr(self._components)
|
||||
Reference in New Issue
Block a user