update from Atlas
This commit is contained in:
5
attic/iterables/CACM/citation.txt
Normal file
5
attic/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
attic/iterables/CACM/closed_file.py
Normal file
10
attic/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
attic/iterables/CACM/haha.py
Normal file
17
attic/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
attic/iterables/CACM/less_more.py
Normal file
22
attic/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
attic/iterables/CACM/zero_div.py
Normal file
14
attic/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)
|
||||
38
attic/iterables/almost_aritprog_v0.py
Normal file
38
attic/iterables/almost_aritprog_v0.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""
|
||||
Arithmetic progression class
|
||||
|
||||
>>> ap = ArithmeticProgression(1, .5, 3)
|
||||
>>> list(ap)
|
||||
[1.0, 1.5, 2.0, 2.5]
|
||||
|
||||
|
||||
"""
|
||||
|
||||
from collections import abc
|
||||
|
||||
|
||||
class ArithmeticProgression:
|
||||
|
||||
def __init__(self, begin, step, end):
|
||||
self.begin = begin
|
||||
self.step = step
|
||||
self.end = end
|
||||
|
||||
def __iter__(self):
|
||||
return ArithmeticProgressionIterator(self)
|
||||
|
||||
|
||||
class ArithmeticProgressionIterator(abc.Iterator):
|
||||
|
||||
def __init__(self, arithmetic_progression):
|
||||
self._ap = arithmetic_progression
|
||||
self._index = 0
|
||||
|
||||
def __next__(self):
|
||||
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
|
||||
else:
|
||||
raise StopIteration
|
||||
35
attic/iterables/almost_aritprog_v6.py
Normal file
35
attic/iterables/almost_aritprog_v6.py
Normal 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
|
||||
48
attic/iterables/paragraph.py
Normal file
48
attic/iterables/paragraph.py
Normal file
@@ -0,0 +1,48 @@
|
||||
"""
|
||||
Paragraph: iterate over sentences and words with generator functions.
|
||||
The ``.words()`` generator shows the use of ``yield from``.
|
||||
|
||||
::
|
||||
>>> p = Paragraph("The cat. The mat. Is the cat on the mat?"
|
||||
... " The cat is on the mat.")
|
||||
>>> for s in p:
|
||||
... print(s)
|
||||
...
|
||||
Sentence('The cat.')
|
||||
Sentence('The mat.')
|
||||
Sentence('Is the cat on the mat?')
|
||||
Sentence('The cat is on the mat.')
|
||||
>>> list(p.words()) # doctest: +NORMALIZE_WHITESPACE
|
||||
['The', 'cat', 'The', 'mat', 'Is', 'the', 'cat', 'on',
|
||||
'the', 'mat', 'The', 'cat', 'is', 'on', 'the', 'mat']
|
||||
|
||||
|
||||
.. Note:: sample text from `McGuffey's First Eclectic Reader`__
|
||||
|
||||
__ http://www.gutenberg.org/cache/epub/14640/pg14640.txt
|
||||
"""
|
||||
|
||||
import re
|
||||
import reprlib
|
||||
|
||||
from sentence_gen import Sentence
|
||||
|
||||
|
||||
RE_SENTENCE = re.compile('([^.!?]+[.!?]+)')
|
||||
|
||||
|
||||
class Paragraph:
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = text
|
||||
|
||||
def __repr__(self):
|
||||
return 'Paragraph(%s)' % reprlib.repr(self.text)
|
||||
|
||||
def __iter__(self):
|
||||
for match in RE_SENTENCE.finditer(self.text):
|
||||
yield Sentence(match.group().strip())
|
||||
|
||||
def words(self):
|
||||
for sentence in self:
|
||||
yield from sentence
|
||||
42
attic/iterables/simplest_generators.doctest
Normal file
42
attic/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
attic/iterables/vector.py
Normal file
103
attic/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
attic/iterables/vector_flex_init.py
Normal file
43
attic/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)
|
||||
@@ -1,24 +0,0 @@
|
||||
"""
|
||||
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>
|
||||
Reference in New Issue
Block a user