import unittest
from musket_core import coders
import numpy as np
import pandas as pd
import os
import math

fl=__file__

fl=os.path.dirname(fl)
class TestCoders(unittest.TestCase):

    def test_binary_num(self):
        a=np.array([0,1,0,1])
        bc=coders.get_coder("binary",a, None)
        self.assertEqual(bc[0], 0, "should be zero")
        self.assertEqual(bc[1], 1, "should be one")
        v=bc._decode(np.array([0.6]))
        self.assertEqual(v, 1, "should be one")
        v=bc._decode(np.array([0.2]))
        self.assertEqual(v, 0, "should be zero")
        pass
    def test_binary_str(self):
        a=np.array(["0","1","0","1"])
        bc=coders.get_coder("binary",a, None)
        self.assertEqual(bc[0], 0, "should be zero")
        self.assertEqual(bc[1], 1, "should be one")
        v=bc._decode(np.array([0.6]))
        self.assertEqual(v, "1", "should be one")
        v=bc._decode(np.array([0.2]))
        self.assertEqual(v, "0", "should be zero")
        pass
    def test_binary_str2(self):
        a=np.array(["","1","","1"])
        bc=coders.get_coder("binary",a, None)
        self.assertEqual(bc[0], 0, "should be zero")
        self.assertEqual(bc[1], 1, "should be one")
        v=bc._decode(np.array([0.6]))
        self.assertEqual(v, "1", "should be one")
        v=bc._decode(np.array([0.2]))
        self.assertEqual(v, "", "should be zero")
        pass
    def test_binary_bool(self):
        a=np.array([True,False,True,False])
        bc=coders.get_coder("binary",a, None)
        self.assertEqual(bc[0], 1, "should be zero")
        self.assertEqual(bc[1], 0, "should be one")
        v=bc._decode(np.array([0.6]))
        self.assertEqual(v, True, "should be one")
        v=bc._decode(np.array([0.2]))
        self.assertEqual(v, False, "should be zero")
        pass
    
    def test_categorical_num(self):
        a=np.array([0,1,2,1])
        bc=coders.get_coder("categorical_one_hot",a, None)
        
        self.assertEqual(bc[0][0], True, "should be zero")
        self.assertEqual(bc[0][1], False, "should be one")
        v=bc._decode(np.array([0.3,0.4,0.45]))
        self.assertEqual(v, 2, "should be one")
        v=bc._decode(np.array([0.2,0.1,0.1]))
        self.assertEqual(v, 0, "should be zero")
        pass
    
    def test_categorical_str(self):
        a=np.array(["a","b","c","b"])
        bc=coders.get_coder("categorical_one_hot",a, None)
        
        self.assertEqual(bc[0][0], True, "should be zero")
        self.assertEqual(bc[0][1], False, "should be one")
        v=bc._decode(np.array([0.3,0.4,0.45]))
        self.assertEqual(v, "c", "should be one")
        v=bc._decode(np.array([0.2,0.1,0.1]))
        self.assertEqual(v, "a", "should be zero")
        pass
    
    def test_categorical_str2(self):
        a=np.array(["","b","c","b"])
        bc=coders.get_coder("categorical_one_hot",a, None)
        
        self.assertEqual(bc[0][0], True, "should be zero")
        self.assertEqual(bc[0][1], False, "should be one")
        v=bc._decode(np.array([0.3,0.4,0.45]))
        self.assertEqual(v, "c", "should be one")
        v=bc._decode(np.array([0.2,0.1,0.1]))
        self.assertEqual(v, "", "should be zero")
        pass
    
    def test_categorical_pd(self):
        a=np.array([math.nan,1,2,1])
        bc=coders.get_coder("categorical_one_hot",a, None)
        
        self.assertEqual(bc[0][2], True, "should be zero")
        self.assertEqual(bc[0][1], False, "should be one")
        v=bc._decode(np.array([0.3,0.4,0.45]))
        self.assertEqual(math.isnan(v),True, "should be one")
        v=bc._decode(np.array([0.2,0.1,0.1]))
        self.assertEqual(v, 1, "should be zero")
        pass
    
    def test_multiclass(self):
        a=np.array(["1 2","0 2","0",""])
        bc=coders.get_coder("multi_class",a, None)
        
        val=bc[0]
        self.assertEqual((val==np.array([False,True,True])).sum(), 3,"Fixing format")
        for i in range(len(a)):
            val=bc[i]
            r=bc._decode(val)
            self.assertEqual(r, a[i], "Decoding should work also")
        pass
    
    def test_multiclass1(self):
        a=np.array(["1_2","0_2","0",""])
        bc=coders.get_coder("multi_class",a, None)
        
        val=bc[0]
        self.assertEqual((val==np.array([False,True,True])).sum(), 3,"Fixing format")
        for i in range(len(a)):
            val=bc[i]
            r=bc._decode(val)
            self.assertEqual(r, a[i], "Decoding should work also")
        pass
    
    def test_multiclass2(self):
        a=np.array(["1","","",""])
        bc=coders.get_coder("multi_class",a, None)
        
        val=bc[0]
        self.assertEqual((val==np.array([True])).sum(), 1,"Fixing format")
        for i in range(len(a)):
            val=bc[i]
            r=bc._decode(val)
            self.assertEqual(r, a[i], "Decoding should work also")
        pass
[(10, 'os.path.dirname', 'os.path.dirname', (['fl'], {}), False, 'import os\n'), (14, 'numpy.array', 'np.array', (['[0, 1, 0, 1]'], {}), True, 'import numpy as np\n'), (15, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""binary"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (24, 'numpy.array', 'np.array', (["['0', '1', '0', '1']"], {}), True, 'import numpy as np\n'), (25, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""binary"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (34, 'numpy.array', 'np.array', (["['', '1', '', '1']"], {}), True, 'import numpy as np\n'), (35, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""binary"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (44, 'numpy.array', 'np.array', (['[True, False, True, False]'], {}), True, 'import numpy as np\n'), (45, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""binary"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (55, 'numpy.array', 'np.array', (['[0, 1, 2, 1]'], {}), True, 'import numpy as np\n'), (56, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""categorical_one_hot"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (67, 'numpy.array', 'np.array', (["['a', 'b', 'c', 'b']"], {}), True, 'import numpy as np\n'), (68, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""categorical_one_hot"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (79, 'numpy.array', 'np.array', (["['', 'b', 'c', 'b']"], {}), True, 'import numpy as np\n'), (80, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""categorical_one_hot"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (91, 'numpy.array', 'np.array', (['[math.nan, 1, 2, 1]'], {}), True, 'import numpy as np\n'), (92, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""categorical_one_hot"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (103, 'numpy.array', 'np.array', (["['1 2', '0 2', '0', '']"], {}), True, 'import numpy as np\n'), (104, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""multi_class"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (115, 'numpy.array', 'np.array', (["['1_2', '0_2', '0', '']"], {}), True, 'import numpy as np\n'), (116, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""multi_class"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (127, 'numpy.array', 'np.array', (["['1', '', '', '']"], {}), True, 'import numpy as np\n'), (128, 'musket_core.coders.get_coder', 'coders.get_coder', (['"""multi_class"""', 'a', 'None'], {}), False, 'from musket_core import coders\n'), (18, 'numpy.array', 'np.array', (['[0.6]'], {}), True, 'import numpy as np\n'), (20, 'numpy.array', 'np.array', (['[0.2]'], {}), True, 'import numpy as np\n'), (28, 'numpy.array', 'np.array', (['[0.6]'], {}), True, 'import numpy as np\n'), (30, 'numpy.array', 'np.array', (['[0.2]'], {}), True, 'import numpy as np\n'), (38, 'numpy.array', 'np.array', (['[0.6]'], {}), True, 'import numpy as np\n'), (40, 'numpy.array', 'np.array', (['[0.2]'], {}), True, 'import numpy as np\n'), (48, 'numpy.array', 'np.array', (['[0.6]'], {}), True, 'import numpy as np\n'), (50, 'numpy.array', 'np.array', (['[0.2]'], {}), True, 'import numpy as np\n'), (60, 'numpy.array', 'np.array', (['[0.3, 0.4, 0.45]'], {}), True, 'import numpy as np\n'), (62, 'numpy.array', 'np.array', (['[0.2, 0.1, 0.1]'], {}), True, 'import numpy as np\n'), (72, 'numpy.array', 'np.array', (['[0.3, 0.4, 0.45]'], {}), True, 'import numpy as np\n'), (74, 'numpy.array', 'np.array', (['[0.2, 0.1, 0.1]'], {}), True, 'import numpy as np\n'), (84, 'numpy.array', 'np.array', (['[0.3, 0.4, 0.45]'], {}), True, 'import numpy as np\n'), (86, 'numpy.array', 'np.array', (['[0.2, 0.1, 0.1]'], {}), True, 'import numpy as np\n'), (96, 'numpy.array', 'np.array', (['[0.3, 0.4, 0.45]'], {}), True, 'import numpy as np\n'), (97, 'math.isnan', 'math.isnan', (['v'], {}), False, 'import math\n'), (98, 'numpy.array', 'np.array', (['[0.2, 0.1, 0.1]'], {}), True, 'import numpy as np\n'), (107, 'numpy.array', 'np.array', (['[False, True, True]'], {}), True, 'import numpy as np\n'), (119, 'numpy.array', 'np.array', (['[False, True, True]'], {}), True, 'import numpy as np\n'), (131, 'numpy.array', 'np.array', (['[True]'], {}), True, 'import numpy as np\n')]