import unittest
from numpy import *
from random import *
#import copy

class Gene:
    def mutate(self, rate):
        raise "NYI"

class VectorGene (Gene):
    def __init__(self, v, sigma):
        self.v = v
        self.sigma = sigma
        self.generation = 0
        self.fitness = 0.0

    def mutate(self, rate):
        v = self.v.copy()
        for i in range(0, len(v)):
            if random() <= rate:
                v[i] = self.mutateElement(v[i])
        inst = self.__class__()
        inst.v = v
        inst.sigma = self.sigma
        inst.generation = self.generation + 1
        return inst
                
    def mutateElement(self, x):
        return gauss(x, self.sigma)

    def __repr__(self):
        return "VectorGene(%s, %s)" % (repr(self.v), repr(self.sigma))

    __str__ = __repr__

class MockVectorGene(VectorGene):
    
    def mutateElement(self, x):
        return x + 1

class TestGene(unittest.TestCase):

    def assertEqualA(self, a, b):
        # Assert Equal Array
        self.assertEqual(a.all(), b.all(), "%s != %s" % (str(a), str(b)))

    def testStuff(self):
        a = array([0,1,2])
        b = array([0,1,2])
        g = MockVectorGene(a, 5.0)
        self.assertEqual([0], [0])
        self.assertEqualA(a, array([0,1,2]))
        g2 = g.mutate(1.0)
        self.assertEqualA(g.v, array([0,1,2]))
        self.assertEqualA(g2.v, array([1,2,3]))

        g3 = g.mutate(0.0)
        self.assertEqualA(g.v, array([0,1,2]))
        self.assertEqualA(g3.v, array([0,1,2]))
        self.assertTrue(True)

if __name__ == '__main__':
    unittest.main()
