From c026c25007d012c0b6cc68d02f83b776285e9422 Mon Sep 17 00:00:00 2001
From: maaikedieuwertje <maaikedieuwertje@gmail.com>
Date: Fri, 9 Mar 2018 16:36:02 +0100
Subject: [PATCH] Issue #52: enable multiple attr_cond (nested list) and change
 attr_include and attr_exclude to nested list.

Former-commit-id: 73fb4821330d6c9e193de8e82e8a9f4e8ef1fd9a
---
 examples/scripts/ssbj/(X)DSM/FPG_MDF-GS.pdf | Bin 35469 -> 35469 bytes
 examples/scripts/ssbj/(X)DSM/RCG.pdf        | Bin 35474 -> 35474 bytes
 examples/scripts/ssbj/CMDOWS/RCG.xml        |   4 +-
 kadmos/graph/graph_kadmos.py                |  79 ++++++++++++++++----
 4 files changed, 65 insertions(+), 18 deletions(-)

diff --git a/examples/scripts/ssbj/(X)DSM/FPG_MDF-GS.pdf b/examples/scripts/ssbj/(X)DSM/FPG_MDF-GS.pdf
index 11ee009a587df50b870ba360cd72c87f142f25f7..24c9ec2789586cf8b834fd332ab98f9dc49ee781 100644
GIT binary patch
delta 128
zcmeC3%G5iRX@h*5mZhPYk&%(Hwt=C#fq}Xvm%eX)ic4Zis)B}#m63s=g@LgFRLN$~
ywx`Taj;`jW=EknZMh0f)=7x?gPR0f%rY^>oW~PQFE`|nXb_zBGluRz@k_7-dAs?gw

delta 128
zcmeC3%G5iRX@h*5mXV>cfr+t!wt=C#fq}Xvm%eX)ic4Zis)B}#m63s=g@LgFRLN$~
ywx`Tat|m?{Zf3@g78cG%7UoVSmW~!?7Os|trWP)SjxH8vb_zBGluRz@k_7-v_aIaN

diff --git a/examples/scripts/ssbj/(X)DSM/RCG.pdf b/examples/scripts/ssbj/(X)DSM/RCG.pdf
index 2d8bbc66b09626827ce5b83d4bd9152129986e26..a01d3ba5b3ceb8e1793766672954830bec014736 100644
GIT binary patch
delta 126
zcmbO<m1)vcrVVOstY*fBrWTX6+vFgu&3<i9nd6O2+{{cJo!m?uoea!OOx>I;T`bIv
v98HX!Oq@(C%v|jhYzQieRj{+;DlSPZDyb++P2(~)F)=siQdM>JcjE#8d<r0@

delta 126
zcmbO<m1)vcrVVOstR_ZA24<7B+vFgu&3<i9nd2=@-Ha_QO${B*4UJt43|w5yP0bx$
v%`MDaj7$xkTnz0LYzQieRj{+;DlSPZDyb++P2(~)F)=siQdM>JcjE#8UG*S7

diff --git a/examples/scripts/ssbj/CMDOWS/RCG.xml b/examples/scripts/ssbj/CMDOWS/RCG.xml
index 856fc8e23..56ec5bf57 100644
--- a/examples/scripts/ssbj/CMDOWS/RCG.xml
+++ b/examples/scripts/ssbj/CMDOWS/RCG.xml
@@ -3,14 +3,14 @@
   <header>
     <creator>Lukas Mueller</creator>
     <description>RCG CMDOWS file of the super-sonic business jet test case optimization problem</description>
-    <timestamp>2018-03-09T14:22:04.103000</timestamp>
+    <timestamp>2018-03-09T16:31:55.880000</timestamp>
     <fileVersion>0.1</fileVersion>
     <cmdowsVersion>0.7</cmdowsVersion>
     <updates>
       <update>
         <modification>KADMOS export of a repository connectivity graph (RCG).</modification>
         <creator>Lukas Mueller</creator>
-        <timestamp>2018-03-09T14:22:04.103000</timestamp>
+        <timestamp>2018-03-09T16:31:55.880000</timestamp>
         <fileVersion>0.1</fileVersion>
         <cmdowsVersion>0.7</cmdowsVersion>
       </update>
diff --git a/kadmos/graph/graph_kadmos.py b/kadmos/graph/graph_kadmos.py
index 22d0919bb..eee135b88 100644
--- a/kadmos/graph/graph_kadmos.py
+++ b/kadmos/graph/graph_kadmos.py
@@ -3632,7 +3632,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin):
         Get all nodes with any of the listed attribute values:
 
         >>> all_nodes = self.find_all_nodes(category='all', subcategory='all',
-        >>>                                 attr_include=['problem_role'['constraint','objective'],'instance', 1])
+        >>>                                 attr_include=[['problem_role'['constraint','objective']],['instance', 1]])
         """
         # TODO: Update docstring
 
@@ -3652,14 +3652,34 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin):
         assert isinstance(xpath_exclude, type(None)) or isinstance(xpath_exclude, list)
         assert isinstance(print_in_log, bool)
         assert isinstance(print_attributes, str) or isinstance(print_attributes, list)
-        if isinstance(attr_cond, list):
+        if isinstance(attr_cond,type(None)):
+            pass
+        elif isinstance(attr_cond[0], basestring):
             assert len(attr_cond) == 3, "Attribute condition needs to be a list with three entries."
-        if isinstance(attr_include, list):
-            assert len(attr_include)%2 == 0, "Attribute(s) included needs to be a list with alternating the attribute" \
+        else:
+            assert isinstance(attr_cond[0][0],basestring), "Attribute condition can only handle one level of nesting."
+            for attr in attr_cond:
+                assert len(attr) == 3, "Attribute conditions need to be nested lists with three entries."
+        if isinstance(attr_include,type(None)):
+            pass
+        elif isinstance(attr_include[0], basestring):
+            assert len(attr_include) == 2, "Attribute included needs to be a list with the attribute" \
                                              " and (a list of) the desired value(s)."
-        if isinstance(attr_exclude, list):
-            assert len(attr_exclude)%2 == 0, "Attribute(s) excluded needs to be a list with alternating the attribute" \
+        else:
+            assert isinstance(attr_include[0][0],basestring), "Attribute(s) included can only handle one level of nesting."
+            for attr in attr_include:
+                assert len(attr) == 2, "Attributes included need to be nested lists with the attribute and " \
+                                       "(a list of) desired value(s)."
+        if isinstance(attr_exclude, type(None)):
+            pass
+        elif isinstance(attr_exclude[0], basestring):
+            assert len(attr_exclude) == 2, "Attribute excluded needs to be a list with the attribute" \
                                              " and (a list of) the desired value(s)."
+        else:
+            assert isinstance(attr_exclude[0][0],basestring), "Attribute(s) excluded can only handle one level of nesting."
+            for attr in attr_exclude:
+                assert len(attr) == 2, "Attributes excluded need to be nested lists with the attribute" \
+                                       " and (a list of) desired value(s)."
         assert len({category}.intersection(possible_categories)) != 0, \
             "Specified category '%s' does not exist. Please choose from %s." % (category, str(possible_categories))
         assert len({subcategory}.intersection(possible_subcategories)) != 0, \
@@ -3709,7 +3729,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin):
                                 # Determine if the node has a valid attribute value to be added
                                 if attr_cond is None:
                                     eval_node = True
-                                elif isinstance(attr_cond, list):
+                                elif isinstance(attr_cond[0], basestring):
                                     if attr_cond[0] in self.node[item]:
                                         if test_attr_cond(self.node[item][attr_cond[0]], attr_cond[1], attr_cond[2]):
                                             eval_node = True
@@ -3717,6 +3737,16 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin):
                                             eval_node = False
                                     else:
                                         eval_node = False
+                                else:
+                                    eval_node=True
+                                    for attr in attr_cond:
+                                        if attr[0] in self.node[item]:
+                                            if test_attr_cond(self.node[item][attr[0]],attr[1],attr[2]) and eval_node:
+                                                eval_node = True
+                                            else:
+                                                eval_node = False
+                                        else:
+                                            eval_node = False
                                 # noinspection PyUnboundLocalVariable
                                 if eval_node:
                                     if print_in_log:
@@ -3730,11 +3760,18 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin):
         # include all nodes (from selection) that have any of the specified attributes.
         if attr_include:
             filtered = set()
-            for attr in range(len(attr_include)-1):
-                if attr%2 == 0:
+            if isinstance(attr_include,type(None)):
+                pass
+            elif isinstance(attr_include[0],basestring):
+                for node in all_nodes:
+                    if self.node[node].get(attr_include[0]):
+                        if self.node[node][attr_include[0]] in attr_include[1]:
+                            filtered.add(node)
+            else:
+                for attr in attr_include:
                     for node in all_nodes:
-                        if self.node[node].get(attr_include[attr]):
-                            if self.node[node][attr_include[attr]] in attr_include[attr+1]:
+                        if self.node[node].get(attr[0]):
+                            if self.node[node][attr[0]] in attr[1]:
                                 filtered.add(node)
             filtered = list(filtered)
             all_nodes = filtered
@@ -3742,16 +3779,26 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin):
         # include all nodes (from selection) that have none of the specified attributes.
         if attr_exclude:
             filtered = list()
-            for attr in range(len(attr_exclude)-1):
-                if attr%2 == 0:
+            if isinstance(attr_exclude, type(None)):
+                pass
+            elif isinstance(attr_exclude[0],basestring):
+                for node in all_nodes:
+                    choice = True
+                    if self.node[node].get(attr_exclude[0]):
+                        if self.node[node][attr_exclude[0]] in attr_exclude[1]:
+                            choice = False
+                    if choice:
+                        filtered.append(node)
+            else:
+                for attr in attr_exclude:
                     for node in all_nodes:
                         choice = True
-                        if self.node[node].get(attr_exclude[attr]):
-                            if self.node[node][attr_exclude[attr]] in attr_exclude[attr+1]:
+                        if self.node[node].get(attr[0]):
+                            if self.node[node][attr[0]] in attr[1]:
                                 choice = False
                         if choice:
                             filtered.append(node)
-                all_nodes = filtered
+            all_nodes = filtered
 
         if xpath_include:
             filtered = list()
-- 
GitLab