update from Atlas

This commit is contained in:
Luciano Ramalho 2015-04-05 12:07:28 -03:00
parent cf96836b60
commit bdccc3269a
25 changed files with 394 additions and 47 deletions

View File

@ -112,6 +112,7 @@ Test of slicing::
from array import array
import reprlib
import math
import numbers
class Vector:
@ -150,13 +151,13 @@ class Vector:
def __getitem__(self, index):
cls = type(self) # <1>
if isinstance(index, slice):
return cls(self._components[index]) # <2>
elif isinstance(index, int):
return self._components[index] # <3>
if isinstance(index, slice): # <2>
return cls(self._components[index]) # <3>
elif isinstance(index, numbers.Integral): # <4>
return self._components[index] # <5>
else:
msg = '{cls.__name__} indices must be integers'
raise TypeError(msg.format(cls=cls)) # <4>
raise TypeError(msg.format(cls=cls)) # <6>
# END VECTOR_V2
@classmethod

View File

@ -155,6 +155,7 @@ Other attributes can be set::
from array import array
import reprlib
import math
import numbers
class Vector:
@ -194,7 +195,7 @@ class Vector:
cls = type(self)
if isinstance(index, slice):
return cls(self._components[index])
elif isinstance(index, int):
elif isinstance(index, numbers.Integral):
return self._components[index]
else:
msg = '{.__name__} indices must be integers'

View File

@ -135,17 +135,22 @@ Tests of hashing::
>>> v2 = Vector([3.1, 4.2])
>>> v3 = Vector([3, 4, 5])
>>> v6 = Vector(range(6))
>>> hash(v1), hash(v2), hash(v3), hash(v6)
(7, 384307168202284039, 2, 1)
>>> len(set([v1, v2, v3, v6]))
4
>>> hash(v1), hash(v3), hash(v6)
(7, 2, 1)
Most hash values of non-integers vary from a 32-bit to 64-bit CPython build::
>>> import sys
>>> hash(v2) == (384307168202284039 if sys.maxsize > 2**32 else 357915986)
True
"""
from array import array
import reprlib
import math
import numbers
import functools
import operator
@ -192,11 +197,11 @@ class Vector:
cls = type(self)
if isinstance(index, slice):
return cls(self._components[index])
elif isinstance(index, int):
elif isinstance(index, numbers.Integral):
return self._components[index]
else:
msg = '{.__name__} indices must be integers'
raise TypeError(msg.format(cls))
msg = '{cls.__name__} indices must be integers'
raise TypeError(msg.format(cls=cls))
shortcut_names = 'xyzt'

View File

@ -136,10 +136,15 @@ Tests of hashing::
>>> v2 = Vector([3.1, 4.2])
>>> v3 = Vector([3, 4, 5])
>>> v6 = Vector(range(6))
>>> hash(v1), hash(v2), hash(v3), hash(v6)
(7, 384307168202284039, 2, 1)
>>> len(set([v1, v2, v3, v6]))
4
>>> hash(v1), hash(v3), hash(v6)
(7, 2, 1)
Most hash values of non-integers vary from a 32-bit to 64-bit CPython build::
>>> import sys
>>> hash(v2) == (384307168202284039 if sys.maxsize > 2**32 else 357915986)
True
Tests of ``format()`` with Cartesian coordinates in 2D::
@ -187,6 +192,7 @@ Tests of ``format()`` with spherical coordinates in 2D, 3D and 4D::
from array import array
import reprlib
import math
import numbers
import functools
import operator
import itertools # <1>
@ -234,7 +240,7 @@ class Vector:
cls = type(self)
if isinstance(index, slice):
return cls(self._components[index])
elif isinstance(index, int):
elif isinstance(index, numbers.Integral):
return self._components[index]
else:
msg = '{.__name__} indices must be integers'

View File

@ -50,7 +50,7 @@ thrown when the device is empty::
OK
Load and pick 100 balls to verify that they are all come out::
Load and pick 100 balls to verify that they all come out::
>>> balls = list(range(100))
>>> globe = ConcreteTombola(balls)
@ -63,7 +63,7 @@ Load and pick 100 balls to verify that they are all come out::
True
Check that the order has changed is not simply reversed either::
Check that the order has changed and is not simply reversed::
>>> picks != balls
True
@ -71,9 +71,9 @@ Check that the order has changed is not simply reversed either::
True
Note: the previous 2 tests have a *very* small chance of failing
even if the implementation is OK. The probability of the 100
even if the implementation is OK. The probability of the 100
balls coming out, by chance, in the order they were loaded is
1/100!, or approximately 1.07e-158. It's much easier to win the
1/100!, or approximately 1.07e-158. It's much easier to win the
Lotto or to become a billionaire working as a programmer.
THE END

View File

@ -8,7 +8,7 @@ class TomboList(list): # <2>
def pick(self):
if self: # <3>
position = randrange(len(self))
return super().pop(position) # <4>
return self.pop(position) # <4>
else:
raise LookupError('pop from empty TomboList')

View File

@ -14,6 +14,14 @@ class C(A):
class D(B, C):
def pingpong(self):
def ping(self):
super().ping()
print('post-ping:', self)
def pingpong(self):
self.ping()
super().ping()
self.pong()
super().pong()
C.pong(self)

View File

@ -0,0 +1,35 @@
"""
# BEGIN UNARY_PLUS_DECIMAL
>>> import decimal
>>> ctx = decimal.getcontext() # <1>
>>> ctx.prec = 40 # <2>
>>> one_third = decimal.Decimal('1') / decimal.Decimal('3') # <3>
>>> one_third # <4>
Decimal('0.3333333333333333333333333333333333333333')
>>> one_third == +one_third # <5>
True
>>> ctx.prec = 28 # <6>
>>> one_third == +one_third # <7>
False
>>> +one_third # <8>
Decimal('0.3333333333333333333333333333')
# END UNARY_PLUS_DECIMAL
"""
import decimal
if __name__ == '__main__':
with decimal.localcontext() as ctx:
ctx.prec = 40
print('precision:', ctx.prec)
one_third = decimal.Decimal('1') / decimal.Decimal('3')
print(' one_third:', one_third)
print(' +one_third:', +one_third)
print('precision:', decimal.getcontext().prec)
print(' one_third:', one_third)
print(' +one_third:', +one_third)

View File

@ -0,0 +1,151 @@
"""
A 2-dimensional vector class
>>> v1 = Vector2d(3, 4)
>>> print(v1.x, v1.y)
3.0 4.0
>>> x, y = v1
>>> x, y
(3.0, 4.0)
>>> v1
Vector2d(3.0, 4.0)
>>> v1_clone = eval(repr(v1))
>>> v1 == v1_clone
True
>>> print(v1)
(3.0, 4.0)
>>> octets = bytes(v1)
>>> octets
b'd\\x00\\x00\\x00\\x00\\x00\\x00\\x08@\\x00\\x00\\x00\\x00\\x00\\x00\\x10@'
>>> abs(v1)
5.0
>>> bool(v1), bool(Vector2d(0, 0))
(True, False)
Test of ``.frombytes()`` class method:
>>> v1_clone = Vector2d.frombytes(bytes(v1))
>>> v1_clone
Vector2d(3.0, 4.0)
>>> v1 == v1_clone
True
Tests of ``format()`` with Cartesian coordinates:
>>> format(v1)
'(3.0, 4.0)'
>>> format(v1, '.2f')
'(3.00, 4.00)'
>>> format(v1, '.3e')
'(3.000e+00, 4.000e+00)'
Tests of the ``angle`` method::
>>> Vector2d(0, 0).angle()
0.0
>>> Vector2d(1, 0).angle()
0.0
>>> epsilon = 10**-8
>>> abs(Vector2d(0, 1).angle() - math.pi/2) < epsilon
True
>>> abs(Vector2d(1, 1).angle() - math.pi/4) < epsilon
True
Tests of ``format()`` with polar coordinates:
>>> format(Vector2d(1, 1), 'p') # doctest:+ELLIPSIS
'<1.414213..., 0.785398...>'
>>> format(Vector2d(1, 1), '.3ep')
'<1.414e+00, 7.854e-01>'
>>> format(Vector2d(1, 1), '0.5fp')
'<1.41421, 0.78540>'
Tests of `x` and `y` read-only properties:
>>> v1.x, v1.y
(3.0, 4.0)
>>> v1.x = 123
Traceback (most recent call last):
...
AttributeError: can't set attribute
Tests of hashing:
>>> v1 = Vector2d(3, 4)
>>> v2 = Vector2d(3.1, 4.2)
>>> hash(v1), hash(v2)
(7, 384307168202284039)
>>> len(set([v1, v2]))
2
"""
from array import array
import math
class Vector2d:
typecode = 'd'
def __init__(self, x, y):
self.__x = float(x)
self.__y = float(y)
@property
def x(self):
return self.__x
@property
def y(self):
return self.__y
def __iter__(self):
return (i for i in (self.x, self.y))
def __repr__(self):
class_name = type(self).__name__
return '{}({!r}, {!r})'.format(class_name, *self)
def __str__(self):
return str(tuple(self))
def __bytes__(self):
return (bytes([ord(self.typecode)]) +
bytes(array(self.typecode, self)))
def __eq__(self, other):
return tuple(self) == tuple(other)
def __hash__(self):
return hash(self.x) ^ hash(self.y)
def __abs__(self):
return math.hypot(self.x, self.y)
def __bool__(self):
return bool(abs(self))
def angle(self):
return math.atan2(self.y, self.x)
def __format__(self, fmt_spec=''):
if fmt_spec.endswith('p'):
fmt_spec = fmt_spec[:-1]
coords = (abs(self), self.angle())
outer_fmt = '<{}, {}>'
else:
coords = self
outer_fmt = '({}, {})'
components = (format(c, fmt_spec) for c in coords)
return outer_fmt.format(*components)
@classmethod
def frombytes(cls, octets):
typecode = chr(octets[0])
memv = memoryview(octets[1:]).cast(typecode)
return cls(*memv)

View File

@ -137,10 +137,15 @@ Tests of hashing::
>>> v2 = Vector([3.1, 4.2])
>>> v3 = Vector([3, 4, 5])
>>> v6 = Vector(range(6))
>>> hash(v1), hash(v2), hash(v3), hash(v6)
(7, 384307168202284039, 2, 1)
>>> len(set([v1, v2, v3, v6]))
4
>>> hash(v1), hash(v3), hash(v6)
(7, 2, 1)
Most hash values of non-integers vary from a 32-bit to 64-bit Python build::
>>> import sys
>>> hash(v2) == (384307168202284039 if sys.maxsize > 2**32 else 357915986)
True
Tests of ``format()`` with Cartesian coordinates in 2D::

View File

@ -135,10 +135,15 @@ Tests of hashing::
>>> v2 = Vector([3.1, 4.2])
>>> v3 = Vector([3, 4, 5])
>>> v6 = Vector(range(6))
>>> hash(v1), hash(v2), hash(v3), hash(v6)
(7, 384307168202284039, 2, 1)
>>> len(set([v1, v2, v3, v6]))
4
>>> hash(v1), hash(v3), hash(v6)
(7, 2, 1)
Most hash values of non-integers vary from a 32-bit to 64-bit Python build::
>>> import sys
>>> hash(v2) == (384307168202284039 if sys.maxsize > 2**32 else 357915986)
True
Tests of ``format()`` with Cartesian coordinates in 2D::
@ -183,6 +188,17 @@ Tests of ``format()`` with spherical coordinates in 2D, 3D and 4D::
'<1.00000, 1.57080, 0.00000, 0.00000>'
Unary operator tests::
>>> v1 = Vector([3, 4])
>>> abs(v1)
5.0
>>> -v1
Vector([-3.0, -4.0])
>>> +v1
Vector([3.0, 4.0])
Basic tests of operator ``+``::
>>> v1 = Vector([3, 4, 5])
@ -231,6 +247,7 @@ Tests of ``+`` with an unsuitable operand:
from array import array
import reprlib
import math
import numbers
import functools
import operator
import itertools
@ -265,9 +282,17 @@ class Vector:
hashes = (hash(x) for x in self)
return functools.reduce(operator.xor, hashes, 0)
# BEGIN VECTOR_V6_UNARY
def __abs__(self):
return math.sqrt(sum(x * x for x in self))
def __neg__(self):
return Vector(-x for x in self) # <1>
def __pos__(self):
return Vector(self) # <2>
# END VECTOR_V6_UNARY
def __bool__(self):
return bool(abs(self))
@ -278,7 +303,7 @@ class Vector:
cls = type(self)
if isinstance(index, slice):
return cls(self._components[index])
elif isinstance(index, int):
elif isinstance(index, numbers.Integral):
return self._components[index]
else:
msg = '{.__name__} indices must be integers'
@ -324,7 +349,7 @@ class Vector:
memv = memoryview(octets[1:]).cast(typecode)
return cls(memv)
# BEGIN VECTOR_V6
# BEGIN VECTOR_V6_ADD
def __add__(self, other):
try:
pairs = itertools.zip_longest(self, other, fillvalue=0.0)
@ -334,4 +359,4 @@ class Vector:
def __radd__(self, other):
return self + other
# END VECTOR_V6
# END VECTOR_V6_ADD

View File

@ -135,10 +135,15 @@ Tests of hashing::
>>> v2 = Vector([3.1, 4.2])
>>> v3 = Vector([3, 4, 5])
>>> v6 = Vector(range(6))
>>> hash(v1), hash(v2), hash(v3), hash(v6)
(7, 384307168202284039, 2, 1)
>>> len(set([v1, v2, v3, v6]))
4
>>> hash(v1), hash(v3), hash(v6)
(7, 2, 1)
Most hash values of non-integers vary from a 32-bit to 64-bit Python build::
>>> import sys
>>> hash(v2) == (384307168202284039 if sys.maxsize > 2**32 else 357915986)
True
Tests of ``format()`` with Cartesian coordinates in 2D::
@ -183,6 +188,17 @@ Tests of ``format()`` with spherical coordinates in 2D, 3D and 4D::
'<1.00000, 1.57080, 0.00000, 0.00000>'
Unary operator tests::
>>> v1 = Vector([3, 4])
>>> abs(v1)
5.0
>>> -v1
Vector([-3.0, -4.0])
>>> +v1
Vector([3.0, 4.0])
Basic tests of operator ``+``::
>>> v1 = Vector([3, 4, 5])
@ -258,10 +274,10 @@ Tests of ``*`` with unsuitable operands::
from array import array
import reprlib
import math
import numbers
import functools
import operator
import itertools
import numbers
class Vector:
@ -296,6 +312,12 @@ class Vector:
def __abs__(self):
return math.sqrt(sum(x * x for x in self))
def __neg__(self):
return Vector(-x for x in self)
def __pos__(self):
return Vector(self)
def __bool__(self):
return bool(abs(self))
@ -306,7 +328,7 @@ class Vector:
cls = type(self)
if isinstance(index, slice):
return cls(self._components[index])
elif isinstance(index, int):
elif isinstance(index, numbers.Integral):
return self._components[index]
else:
msg = '{.__name__} indices must be integers'

View File

@ -135,10 +135,15 @@ Tests of hashing::
>>> v2 = Vector([3.1, 4.2])
>>> v3 = Vector([3, 4, 5])
>>> v6 = Vector(range(6))
>>> hash(v1), hash(v2), hash(v3), hash(v6)
(7, 384307168202284039, 2, 1)
>>> len(set([v1, v2, v3, v6]))
4
>>> hash(v1), hash(v3), hash(v6)
(7, 2, 1)
Most hash values of non-integers vary from a 32-bit to 64-bit Python build::
>>> import sys
>>> hash(v2) == (384307168202284039 if sys.maxsize > 2**32 else 357915986)
True
Tests of ``format()`` with Cartesian coordinates in 2D::
@ -183,6 +188,17 @@ Tests of ``format()`` with spherical coordinates in 2D, 3D and 4D::
'<1.00000, 1.57080, 0.00000, 0.00000>'
Unary operator tests::
>>> v1 = Vector([3, 4])
>>> abs(v1)
5.0
>>> -v1
Vector([-3.0, -4.0])
>>> +v1
Vector([3.0, 4.0])
Basic tests of operator ``+``::
>>> v1 = Vector([3, 4, 5])
@ -283,10 +299,10 @@ Tests of operator `!=`::
from array import array
import reprlib
import math
import numbers
import functools
import operator
import itertools
import numbers
class Vector:
@ -326,6 +342,12 @@ class Vector:
def __abs__(self):
return math.sqrt(sum(x * x for x in self))
def __neg__(self):
return Vector(-x for x in self)
def __pos__(self):
return Vector(self)
def __bool__(self):
return bool(abs(self))
@ -336,7 +358,7 @@ class Vector:
cls = type(self)
if isinstance(index, slice):
return cls(self._components[index])
elif isinstance(index, int):
elif isinstance(index, numbers.Integral):
return self._components[index]
else:
msg = '{.__name__} indices must be integers'

View File

@ -0,0 +1,24 @@
import os
from time import sleep, time
from lelo import parallel
DELAY = .2
@parallel
def loiter(serial, delay):
pid = os.getpid()
print('%2d pid = %d' % (serial, pid))
sleep(delay)
return pid
t0 = time()
results = []
for i in range(15):
res = loiter(i, DELAY)
results.append(res)
print('Processes used: ', list(set(results)))
print('### Elapsed time: %0.2f' % (time() - t0))

View File

@ -0,0 +1,19 @@
import os
from parallelize import parallelize
from time import sleep, time
print('one process:')
t0 = time()
for i in range(12):
print('%2d pid = %d' % (i, os.getpid()))
sleep(.2)
print('elapsed time: %0.2f' % (time() - t0))
print()
print('several processes:')
t0 = time()
for i in parallelize(range(12)):
print('%2d pid = %d' % (i, os.getpid()))
sleep(.2)
print('elapsed time: %0.2f' % (time() - t0))

View File

@ -0,0 +1,23 @@
import os
from time import sleep, time
from parallelize import parallelize, per_item
DELAY = .2
def loiter(serial, delay):
pid = os.getpid()
print('%2d pid = %d' % (serial, pid))
sleep(delay)
return pid
t0 = time()
results = []
for i in parallelize(range(15), fork=per_item):
res = loiter(i, DELAY)
results.append(res)
print('Processes used: ', list(set(results)))
print('### Elapsed time: %0.2f' % (time() - t0))