Repository: pgmpy/pgmpy
Pull request #805 (2016-12-24 20:48:56)

Added tests for NaiveBayes._get_ancestors_of


Patch:
diff --git a/.travis.yml b/.travis.yml
index f1972807..3dae1288 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,8 +2,8 @@ language: python
 virtualenv:
     system_site_packages: false
 env:
-    - DISTRIB="conda" PYTHON_VERSION="3.5" COVERAGE="true"
     - DISTRIB="conda" PYTHON_VERSION="3.4" COVERAGE="true"
+    - DISTRIB="conda" PYTHON_VERSION="3.3" COVERAGE="true"
     - DISTRIB="conda" PYTHON_VERSION="2.7" COVERAGE="true"
 
 before_install:
diff --git a/appveyor.yml b/appveyor.yml
index afe897ba..3e08acec 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -21,7 +21,7 @@ build_script:
   - SET PATH=C:\Py;C:\Py\Scripts;C:\Py\Library\bin;%PATH%
   - conda config --set always_yes yes
   - conda update conda --quiet
-  - conda install numpy scipy pandas pip nose mock wrapt --quiet
+  - conda install numpy scipy pandas pip nose mock --quiet
   - pip install pyparsing
   - python setup.py develop
   - set "GIT_DIR=%cd%"
diff --git a/pgmpy/models/NaiveBayes.py b/pgmpy/models/NaiveBayes.py
index 83ed9904..bcc67e18 100644
--- a/pgmpy/models/NaiveBayes.py
+++ b/pgmpy/models/NaiveBayes.py
@@ -160,10 +160,13 @@ class NaiveBayes(BayesianModel):
         >>> ind
         [(b _|_ d, c | a)]
         """
-        independencies = Independencies()
+        independencies = []
         for variable in [variables] if isinstance(variables, str) else variables:
             if variable != self.parent_node:
-                independencies.add_assertions([variable, list(set(self.children_nodes) - set(variable)), self.parent_node])
+                independencies.append(Independencies(
+                    [variable, list(set(self.children_nodes) - set(variable)), self.parent_node]))
+            else:
+                independencies.append(None)
         return independencies
 
     def fit(self, data, parent_node=None, estimator_type=None):
diff --git a/pgmpy/utils/state_name.py b/pgmpy/utils/state_name.py
index 97dd8ffa..01c28c8a 100644
--- a/pgmpy/utils/state_name.py
+++ b/pgmpy/utils/state_name.py
@@ -1,4 +1,3 @@
-from wrapt import decorator
 """
 The file contains decorators to manage the user defined
 variable state names. It maps the internal representaion
@@ -29,16 +28,17 @@ class StateNameInit():
     >>> print(phi.state_names)
     {'speed': ['low', 'medium', 'high'], 'switch': ['on', 'off'], 'time': ['day', 'night']}
     """
-    @decorator
-    def __call__(self, f, instance, args, kwargs):
-        # Case, when no state names dict is provided.
-        if 'state_names' not in kwargs:
-            # instance represents the self parameter of the __init__ method
-            instance.state_names = None
-        else:
-            instance.state_names = kwargs['state_names']
-            del kwargs['state_names']
-        f(*args, **kwargs)
+    def __call__(self, f):
+        def wrapper(*args, **kwargs):
+            # Case, when no state names dict is provided.
+            if 'state_names' not in kwargs:
+                # args[0] represents the self parameter of the __init__ method
+                args[0].state_names = None
+            else:
+                args[0].state_names = kwargs['state_names']
+                del kwargs['state_names']
+            f(*args, **kwargs)
+        return wrapper
 
 
 class StateNameDecorator():
@@ -158,42 +158,44 @@ class StateNameDecorator():
                     arg_val[var] = self.state_names[var].index(arg_val[var])
             return arg_val
 
-    @decorator
-    def __call__(self, f, instance, args, kwargs):
-        # instance represents the self parameter of the __init__ method
-        method_self = instance
-
-        if not method_self.state_names:
-            return f(*args, **kwargs)
-        else:
-            self.state_names = method_self.state_names
-
-        if self.arg and not self.return_val:
-            # If input parameters are in kwargs format
-            if self.arg in kwargs:
-                arg_val = kwargs[self.arg]
-                kwargs[self.arg] = self.get_mapped_value(arg_val)
+    def __call__(self, f):
+        def wrapper(*args, **kwargs):
+            # args[0] represents the self parameter of the __init__ method
+            method_self = args[0]
+
+            if not method_self.state_names:
                 return f(*args, **kwargs)
-            # If input parameters are in args format
             else:
-                for arg_val in args[:]:
-                    mapped_arg_val = self.get_mapped_value(arg_val)
-                    if mapped_arg_val:
-                        mapped_args = list(args)
-                        mapped_args[args.index(arg_val)] = mapped_arg_val
-                return f(*mapped_args, **kwargs)
-
-        elif not self.arg and self.return_val:
-            return_val = f(*args, **kwargs)
-
-            mapped_return_val = self.get_mapped_value(return_val)
-            # If the function returns only one output
-            if mapped_return_val:
-                return mapped_return_val
-
-            # If the function returns more than one output.
-            for ret_val in list(return_val):
-                mapped_ret_val = self.get_mapped_value(ret_val)
-                if ret_val:
-                    return_val[return_val.index(ret_val)] = mapped_ret_val
-            return return_val
+                self.state_names = method_self.state_names
+
+            if self.arg and not self.return_val:
+                # If input parameters are in kwargs format
+                if self.arg in kwargs:
+                    arg_val = kwargs[self.arg]
+                    kwargs[self.arg] = self.get_mapped_value(arg_val)
+                    return f(*args, **kwargs)
+                # If input parameters are in args format
+                else:
+                    for arg_val in args[1:]:
+                        mapped_arg_val = self.get_mapped_value(arg_val)
+                        if mapped_arg_val:
+                            mapped_args = list(args)
+                            mapped_args[args.index(arg_val)] = mapped_arg_val
+                    return f(*mapped_args, **kwargs)
+
+            elif not self.arg and self.return_val:
+                return_val = f(*args, **kwargs)
+
+                mapped_return_val = self.get_mapped_value(return_val)
+                # If the function returns only one output
+                if mapped_return_val:
+                    return mapped_return_val
+
+                # If the function returns more than one output.
+                for ret_val in list(return_val):
+                    mapped_ret_val = self.get_mapped_value(ret_val)
+                    if ret_val:
+                        return_val[return_val.index(ret_val)] = mapped_ret_val
+                return return_val
+
+        return wrapper
diff --git a/requirements-dev.txt b/requirements-dev.txt
index ab15a26a..206656f9 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -5,4 +5,3 @@ pandas
 pyparsing
 mock
 nose
-wrapt
diff --git a/requirements.txt b/requirements.txt
index fb4c749e..6eed30de 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,5 +3,3 @@ numpy==1.11.1
 scipy==0.18.0
 pandas==0.18.1
 pyparsing==2.1.8
-wrapt==1.10.8
-
diff --git a/setup.py b/setup.py
index cace146c..4c3ef836 100644
--- a/setup.py
+++ b/setup.py
@@ -10,9 +10,7 @@ setup(
     author=open("AUTHORS.rst").read(),
     url="https://github.com/pgmpy/pgmpy",
     classifiers=[
-        "Programming Language :: Python :: 3.5",
-        "Programming Language :: Python :: 3.4",
-        "Programming Language :: Python :: 2.7",
+        "Programming Language :: Python :: 3",
         "Intended Audience :: Developers",
         "Operating System :: Unix",
         "Operating System :: POSIX",


Test patch:
diff --git a/pgmpy/tests/test_models/test_NaiveBayes.py b/pgmpy/tests/test_models/test_NaiveBayes.py
index 22aec89b..74741d89 100644
--- a/pgmpy/tests/test_models/test_NaiveBayes.py
+++ b/pgmpy/tests/test_models/test_NaiveBayes.py
@@ -129,10 +129,13 @@ class TestNaiveBayesMethods(unittest.TestCase):
                               ('d', 's')])
 
     def test_local_independencies(self):
-        self.assertEqual(self.G1.local_independencies('a'), Independencies())
-        self.assertEqual(self.G1.local_independencies('b'), Independencies(['b', ['e', 'c', 'd'], 'a']))
-        self.assertEqual(self.G1.local_independencies('c'), Independencies(['c', ['e', 'b', 'd'], 'a']))
-        self.assertEqual(self.G1.local_independencies('d'), Independencies(['d', ['b', 'c', 'e'], 'a']))
+        self.assertListEqual(self.G1.local_independencies('a'), [None])
+        self.assertListEqual(self.G1.local_independencies('b'),
+                             [Independencies(['b', ['e', 'c', 'd'], 'a'])])
+        self.assertListEqual(self.G1.local_independencies('c'),
+                             [Independencies(['c', ['e', 'b', 'd'], 'a'])])
+        self.assertListEqual(self.G1.local_independencies('d'),
+                             [Independencies(['d', ['b', 'c', 'e'], 'a'])])
 
     def test_active_trail_nodes(self):
         self.assertListEqual(sorted(self.G2.active_trail_nodes('d')), ['d', 'g', 'l', 's'])
@@ -146,6 +149,12 @@ class TestNaiveBayesMethods(unittest.TestCase):
         self.assertListEqual(sorted(self.G2.active_trail_nodes('s', observed=['g', 'l'])), ['d', 's'])
         self.assertListEqual(sorted(self.G2.active_trail_nodes('s', observed=['d', 'l'])), ['s'])
 
+    def test_get_ancestors_of(self):
+        self.assertListEqual(sorted(self.G1._get_ancestors_of('b')), ['a', 'b'])
+        self.assertListEqual(sorted(self.G1._get_ancestors_of('e')), ['a', 'e'])
+        self.assertListEqual(sorted(self.G1._get_ancestors_of('a')), ['a'])
+        self.assertListEqual(sorted(self.G1._get_ancestors_of(['b', 'e'])), ['a', 'b', 'e'])
+
     def tearDown(self):
         del self.G1
         del self.G2