Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
363 lines (305 sloc) 11.1 KB
#!/usr/bin/python
# -*- coding: utf-8 -*-
#WTFPL
"""test for rules of consistency in algebrae
call the script as it is to see the result for various objects
(int, str, list, numpy array, VectorDict)
and rules tested.
Mainly the tests are coming out of a math book
"""
from copy import deepcopy
from VectorDict import can_be_walked, VectorDict
def try_copy_or_copy(self, src, dst):
copy = None
if hasattr(src, "copy"):
copy = src.copy()
else:
copy = deepcopy(src)
setattr(self, dst, copy)
class ConsistentAlgebrae(object):
"""test wether an addition for two object is consistant"""
def __init__(self, **kw):
"""
only method really callable.
Arguments :
- neutral : neutral element of addition for the object ;
- scalar : real, float, or complex (normaly anything that is 1D,
and follow algebraic rules);
- one : an element to test
- other : other element to test
optionnal :
- other_scalar : real, float, or complex
(normaly anything that is 1D, and follow algebraic rules);
- context : default "print" make it verbose ;
- collect_values : default lambda x : x, if testing for conservation
a lambda fonction for getting the values
"""
self.fail = 0
self.context= kw.get("context", "print" )
self.counter = 0
self.success = 0
self.neutral = None
self.one = None
self.other = None
self.another = None
self.algebraic_logic = False
self._neutral = kw["neutral"]
self._another = kw["another"]
self._one = kw["one"]
self._other = self._other = kw["other"]
self.equal = kw.get("equal", None)
self.scalar = kw.get("scalar", 3)
self.other_scalar = kw.get("other_scalar", 4)
self.collect_values = kw.get("collect_values", lambda x: x)
self.pre_test()
self.LesserCommutativity()
if hasattr(self.one, '__rmul__'):
self.BetterCommutativity()
if hasattr(self.one, '__div__'):
self.EvenBetterCommutativity()
if can_be_walked(self.one):
self.Conservation()
self.finalize()
def EvenBetterCommutativity(self):
self.test_fraction_consisentcy()
self.test_div_consisentcy()
def pre_test(self):
if "print" == self.context :
print "\n" + "*" * 50
print "\ntesting for %r class\n" % (self._one.__class__.__name__)
print " a = %r" % self._one
print " b = %r" % self._other
print " c = %r" % self._another
print " an_int = %r " % self.scalar
print " other_scalar = %r " % self.other_scalar
print " neutral element for addition is %r " % self._neutral
print "\n" + "*" * 50
def finalize(self):
"""success or not ? """
if "print" == self.context:
print "*" * 50 + "\n"
print "%(counter)r/%(success)r" % self.__dict__
if self.counter == self.success and self.algebraic_logic:
print "%r respects the algebraic acceptation of addition" % (
self._one.__class__
)
else:
print "%r follows the dutch logic " % (
self._one.__class__
)
print "\n" + "*" * 50
else:
print "%(success)d/%(counter)d test passed" % ( self.__dict__ )
if self.success == self.counter:
print "test PASSED"
else:
raise Exception("Test Failed")
def fixture_and_test(method):
def pprint(self,method, res, left, right):
print "\ntest #%d" % self.counter
print method.__doc__
print "%s is %s" % (method.__name__, res)
if "ko" == res:
print res
print "%r != %r " % (left, right)
def praise(self,method, res, left, right):
if "ko" == res:
print "FAIL"
print "test #%d" % self.counter
print method.__doc__
print "%r != %r " % (left, right)
print "%r" % res
self.fail += 1
def reinit_me(self, *a, **kw):
to_reinit = dict(_one="one",
_other="other",
_another="another",
_neutral="neutral")
for src, dst in to_reinit.items():
obj_src = getattr(self, src)
try_copy_or_copy(self, obj_src, dst)
res = "Arg : "
is_equal = False
(left,right) = (None , None)
try:
(left, right) = method(self, *a, **kw)
if self.equal:
is_equal = self.equal(left, right)
else:
is_equal = left == right
res = is_equal and "ok" or "ko"
except Exception as e:
res += "%r" % e
finally:
self.counter += 1
self.success += is_equal and 1 or 0
if 'print' == self.context:
pprint(self, method, res, left, right )
else:
praise(self, method, res, left, right)
reinit_me.__doc__ = method.__doc__
return reinit_me
@fixture_and_test
def test_commutativity(self):
""" a + b = b + a """
return (self.other + self.one, self.one + self.other)
@fixture_and_test
def test_neutral(self):
""" a + neutral = a """
return (self.neutral + self.one, self.one)
@fixture_and_test
def test_scalar_multiplication(self):
""" an_int * a = a + ... + a (n times ) """
left = self.scalar * self.one
right = self.one.copy()
for i in xrange(self.scalar - 1):
right += self.one
return (left, right)
@fixture_and_test
def test_multiplicative_identity(self):
""" 1 * a = a """
return 1 * self.one, self.one
@fixture_and_test
def test_associativity(self):
"""( a + b ) + c = a + ( b + c )"""
return (
self.one + (self.other + self.another),
(self.one + self.other) + self.another
)
@fixture_and_test
def test_div_consisentcy(self):
""" a * n / 2 = a + ... + a n /2 times (n beign odd)"""
right = (self.one * (self.scalar * 2)) / 2
left = self.one
for i in xrange(self.scalar - 1):
left = left + self.one
return left, right
@fixture_and_test
def test_fraction_consisentcy(self):
""" a / 2 = .5 * a"""
### not implemented because of the float equality shit
return self.one / 2.0, .5 * self.one
@fixture_and_test
def test_multiply_scalar_symmetric(self):
""" a * other_scalar = other_scalar * a """
return (
self.other_scalar * self.one,
self.one * self.other_scalar
)
@fixture_and_test
def test_multiply_scalar_associativity(self):
""" ( an_int + other_scalar ) a = an_int * a + other_scalar * a """
return (
(self.scalar + self.other_scalar) * self.one,
self.scalar * self.one + self.other_scalar * self.one
)
@fixture_and_test
def test_scalar_commutativity(self):
""" an_int * a = a * an_int """
return self.scalar * self.one, self.one * self.scalar
@fixture_and_test
def test_associativity_scalar_multiplication(self):
""" ( an_int * other_scalar ) * a = an_int ( other_scalar * a )"""
return (
(self.scalar * self.other_scalar) * self.one,
self.scalar * (self.other_scalar * self.one))
@fixture_and_test
def test_negative(self):
""" -a = -1 * a """
return -1 * self.one, self.one.__neg__()
@fixture_and_test
def test_substraction(self):
""" a - b = a + ( -1 * b) """
return self.one - self.other, self.one + (-1 * self.other)
@fixture_and_test
def test_distributivity(self):
""" an_int ( a + b) = an_int *a + an_int * b """
return (
self.scalar * (self.one + self.other),
self.scalar * self.one + self.scalar * self.other
)
@fixture_and_test
def conservation(self):
"""sum of the parts = sum of the total"""
return (
sum(self.collect_values(self.one + self.other)),
sum(self.collect_values(self.one)) + \
sum(self.collect_values(self.other))
)
@fixture_and_test
def conservation_neg(self):
"""sum of the differences == differences of the sum"""
return (
sum(self.collect_values(self.one - self.other)),
sum(self.collect_values(self.one)) - \
sum(self.collect_values(self.other))
)
def LesserCommutativity(self):
self.test_commutativity()
self.test_neutral()
def BetterCommutativity(self):
self.test_multiplicative_identity()
self.test_scalar_multiplication()
self.test_scalar_commutativity()
self.test_negative()
self.test_associativity_scalar_multiplication()
self.test_multiply_scalar_associativity()
self.test_multiply_scalar_symmetric()
self.test_associativity()
self.test_substraction()
self.test_distributivity()
self.algebraic_logic = True
def Conservation(self):
self.conservation()
self.conservation_neg()
if '__main__' == __name__:
import os, sys, inspect
cmd_folder = os.path.abspath(
os.path.join(
os.path.split(
inspect.getfile( inspect.currentframe() )
)[0] ,
"."
)
)
if cmd_folder not in sys.path:
sys.path.insert(0, cmd_folder)
try:
from numpy import array as array
ConsistentAlgebrae(
neutral=array([0, 0, 0]),
one=array([1, 2, 3]),
another=array([5, 2, 3]),
other=array([3, 4, -1]),
equal=lambda left, right: (right == left).all(),
)
except Exception as e:
print "only lamers dont use numpy"
ConsistentAlgebrae(
neutral=0,
one=1,
other=2,
another=3
)
ConsistentAlgebrae(
neutral=[],
one=[1],
other=[2],
another=[42]
)
ConsistentAlgebrae(
neutral="",
one="1",
other="2",
another="4"
)
ConsistentAlgebrae(
neutral=VectorDict(int, {}),
one=VectorDict(int, {"one": 1, "one_and_two": 3}),
other=VectorDict(int, {"one_and_two": - 1, "two": 2}),
another=VectorDict(int, {"one": 3, 'two': 2, "three": 1}),
collect_values=lambda x: x.values()
)
one = VectorDict(int, {"one": 1, "one_and_two": 12})
other = VectorDict(int, {"one_and_two": - 9, "two": 2})
print "just for fun \n\t%r\n\t+\n\t%r\n\t=\n\t%r" % (one, other, one + other)