From 3339753aae163e2f54cea416a61ada1a7af28197 Mon Sep 17 00:00:00 2001 From: pratikgl Date: Tue, 26 Oct 2021 19:00:36 +0530 Subject: [PATCH 1/6] add_vertex doc modified --- pydatastructs/graphs/graph.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pydatastructs/graphs/graph.py b/pydatastructs/graphs/graph.py index f19fc8e97..983867d62 100644 --- a/pydatastructs/graphs/graph.py +++ b/pydatastructs/graphs/graph.py @@ -89,7 +89,8 @@ def neighbors(self, node): def add_vertex(self, node): """ - Adds the input vertex to the node. + Adds the input vertex to the node, or does nothing + if the input vertex is already in the graph. """ raise NotImplementedError( "This is an abstract method.") @@ -97,7 +98,7 @@ def add_vertex(self, node): def remove_vertex(self, node): """ Removes the input vertex along with all the edges - pointing towards to it. + pointing towards it. """ raise NotImplementedError( "This is an abstract method.") From dd51f78ffff57b63c528f96b2d04b0c44b21f547 Mon Sep 17 00:00:00 2001 From: pratikgl Date: Tue, 26 Oct 2021 22:59:14 +0530 Subject: [PATCH 2/6] Doc added for ODA and DODA --- pydatastructs/linear_data_structures/arrays.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/arrays.py b/pydatastructs/linear_data_structures/arrays.py index 32fa0ee42..e4bc24223 100644 --- a/pydatastructs/linear_data_structures/arrays.py +++ b/pydatastructs/linear_data_structures/arrays.py @@ -15,7 +15,8 @@ def __str__(self) -> str: class OneDimensionalArray(Array): ''' - Represents one dimensional arrays. + Represents one dimensional static arrays of + fixed size. Parameters ========== @@ -269,7 +270,8 @@ class DynamicArray(Array): class DynamicOneDimensionalArray(DynamicArray, OneDimensionalArray): """ - Represents dynamic one dimensional arrays. + Represents resizable and dynamic one + dimensional arrays. Parameters ========== From 50a91326bae9ed223135ee42b95b5496e312d00f Mon Sep 17 00:00:00 2001 From: pratikgl Date: Wed, 27 Oct 2021 19:27:40 +0530 Subject: [PATCH 3/6] Updated error message for add_edge --- pydatastructs/graphs/adjacency_list.py | 33 +++++++++++++++++++------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/pydatastructs/graphs/adjacency_list.py b/pydatastructs/graphs/adjacency_list.py index a06e35533..316aec91f 100644 --- a/pydatastructs/graphs/adjacency_list.py +++ b/pydatastructs/graphs/adjacency_list.py @@ -26,8 +26,8 @@ def __new__(cls, *vertices): @classmethod def methods(self): return ['is_adjacent', 'neighbors', - 'add_vertex', 'remove_vertex', 'add_edge', - 'get_edge', 'remove_edge', '__new__'] + 'add_vertex', 'remove_vertex', 'add_edge', + 'get_edge', 'remove_edge', '__new__'] def is_adjacent(self, node1, node2): node1 = self.__getattribute__(node1) @@ -52,12 +52,29 @@ def remove_vertex(self, name): node_obj.adjacent.remove(name) def add_edge(self, source, target, cost=None): - source, target = self.__getattribute__(source), \ - self.__getattribute__(target) - source.add_adjacent_node(target.name) - if cost is not None: - self.edge_weights[source.name + "_" + target.name] = \ - GraphEdge(source, target, cost) + if not hasattr(self, source): + raise ValueError("Vertex %s is not present in the graph." + " Call Graph.add_vertex() to add a new" + " vertex. Graph.add_edge is only responsible" + " for adding edges and it will not add new" + " vertices on its own. This is done to maintain" + " clear separation between the functionality of" + " the two methods." %(source)) + elif not hasattr(self, target): + raise ValueError("Vertex %s is not present in the graph." + " Call Graph.add_vertex() to add a new" + " vertex. Graph.add_edge is only responsible" + " for adding edges and it will not add new" + " vertices on its own. This is done to maintain" + " clear separation between the functionality of" + " the two methods." %(target)) + else: + source, target = self.__getattribute__(source), \ + self.__getattribute__(target) + source.add_adjacent_node(target.name) + if cost is not None: + self.edge_weights[source.name + "_" + target.name] = \ + GraphEdge(source, target, cost) def get_edge(self, source, target): return self.edge_weights.get( From 2956049a2b923e02a3a9edfb08922856e51b4df1 Mon Sep 17 00:00:00 2001 From: pratikgl Date: Wed, 27 Oct 2021 19:27:55 +0530 Subject: [PATCH 4/6] Steps to create a graph added --- pydatastructs/graphs/graph.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pydatastructs/graphs/graph.py b/pydatastructs/graphs/graph.py index 983867d62..8239f0b0d 100644 --- a/pydatastructs/graphs/graph.py +++ b/pydatastructs/graphs/graph.py @@ -49,6 +49,14 @@ class Graph(object): ========== .. [1] https://en.wikipedia.org/wiki/Graph_(abstract_data_type) + + Note + ==== + Steps to create a graph: + 1. Create nodes (AdjacencyListGraphNode or AdjacencyListMatrixNode) + 2. Add nodes to the graph + 3. Add edges b/w these nodes + """ __slots__ = ['_impl'] From 0ff290954ba23659c4114b412d2903fb6cfd810c Mon Sep 17 00:00:00 2001 From: pratikgl Date: Thu, 28 Oct 2021 10:04:15 +0530 Subject: [PATCH 5/6] modified docs --- pydatastructs/graphs/adjacency_list.py | 39 +++++++++++--------------- pydatastructs/graphs/graph.py | 4 +++ 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/pydatastructs/graphs/adjacency_list.py b/pydatastructs/graphs/adjacency_list.py index 316aec91f..eeb30b357 100644 --- a/pydatastructs/graphs/adjacency_list.py +++ b/pydatastructs/graphs/adjacency_list.py @@ -52,29 +52,24 @@ def remove_vertex(self, name): node_obj.adjacent.remove(name) def add_edge(self, source, target, cost=None): + error_msg = "Vertex %s is not present in the graph. \ + Call Graph.add_vertex() to add a new \ + vertex. Graph.add_edge is only responsible \ + for adding edges and it will not add new \ + vertices on its own. This is done to maintain \ + clear separation between the functionality of \ + the two methods." if not hasattr(self, source): - raise ValueError("Vertex %s is not present in the graph." - " Call Graph.add_vertex() to add a new" - " vertex. Graph.add_edge is only responsible" - " for adding edges and it will not add new" - " vertices on its own. This is done to maintain" - " clear separation between the functionality of" - " the two methods." %(source)) - elif not hasattr(self, target): - raise ValueError("Vertex %s is not present in the graph." - " Call Graph.add_vertex() to add a new" - " vertex. Graph.add_edge is only responsible" - " for adding edges and it will not add new" - " vertices on its own. This is done to maintain" - " clear separation between the functionality of" - " the two methods." %(target)) - else: - source, target = self.__getattribute__(source), \ - self.__getattribute__(target) - source.add_adjacent_node(target.name) - if cost is not None: - self.edge_weights[source.name + "_" + target.name] = \ - GraphEdge(source, target, cost) + raise ValueError(error_msg %(source)) + if not hasattr(self, target): + raise ValueError(error_msg %(target)) + + source, target = self.__getattribute__(source), \ + self.__getattribute__(target) + source.add_adjacent_node(target.name) + if cost is not None: + self.edge_weights[source.name + "_" + target.name] = \ + GraphEdge(source, target, cost) def get_edge(self, source, target): return self.edge_weights.get( diff --git a/pydatastructs/graphs/graph.py b/pydatastructs/graphs/graph.py index 8239f0b0d..93d4bb218 100644 --- a/pydatastructs/graphs/graph.py +++ b/pydatastructs/graphs/graph.py @@ -52,9 +52,13 @@ class Graph(object): Note ==== + Steps to create a graph: + 1. Create nodes (AdjacencyListGraphNode or AdjacencyListMatrixNode) + 2. Add nodes to the graph + 3. Add edges b/w these nodes """ From 32e07f543f5b7127bbb6748231ee9bdb04d40412 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Sun, 31 Oct 2021 16:04:22 +0530 Subject: [PATCH 6/6] Polished and added tests --- README.md | 14 +++++++------- pydatastructs/graphs/adjacency_list.py | 19 ++++++++++--------- pydatastructs/graphs/adjacency_matrix.py | 12 ++++++++++++ pydatastructs/graphs/graph.py | 12 +++++------- .../graphs/tests/test_adjacency_list.py | 4 ++++ .../graphs/tests/test_adjacency_matrix.py | 4 ++++ 6 files changed, 42 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 09e9b6dc9..803c88b0e 100644 --- a/README.md +++ b/README.md @@ -101,11 +101,11 @@ Keep contributing!! Thanks to these wonderful people ✨✨: - - - + + +
- - - -
+ + + +
diff --git a/pydatastructs/graphs/adjacency_list.py b/pydatastructs/graphs/adjacency_list.py index eeb30b357..541ff3a1e 100644 --- a/pydatastructs/graphs/adjacency_list.py +++ b/pydatastructs/graphs/adjacency_list.py @@ -52,17 +52,18 @@ def remove_vertex(self, name): node_obj.adjacent.remove(name) def add_edge(self, source, target, cost=None): - error_msg = "Vertex %s is not present in the graph. \ - Call Graph.add_vertex() to add a new \ - vertex. Graph.add_edge is only responsible \ - for adding edges and it will not add new \ - vertices on its own. This is done to maintain \ - clear separation between the functionality of \ - the two methods." + source, target = str(source), str(target) + error_msg = ("Vertex %s is not present in the graph." + "Call Graph.add_vertex to add a new" + "vertex. Graph.add_edge is only responsible" + "for adding edges and it will not add new" + "vertices on its own. This is done to maintain" + "clear separation between the functionality of" + "these two methods.") if not hasattr(self, source): - raise ValueError(error_msg %(source)) + raise ValueError(error_msg % (source)) if not hasattr(self, target): - raise ValueError(error_msg %(target)) + raise ValueError(error_msg % (target)) source, target = self.__getattribute__(source), \ self.__getattribute__(target) diff --git a/pydatastructs/graphs/adjacency_matrix.py b/pydatastructs/graphs/adjacency_matrix.py index a75efabdf..64a39494c 100644 --- a/pydatastructs/graphs/adjacency_matrix.py +++ b/pydatastructs/graphs/adjacency_matrix.py @@ -57,6 +57,18 @@ def remove_vertex(self, node): def add_edge(self, source, target, cost=None): source, target = str(source), str(target) + error_msg = ("Vertex %s is not present in the graph." + "Call Graph.add_vertex to add a new" + "vertex. Graph.add_edge is only responsible" + "for adding edges and it will not add new" + "vertices on its own. This is done to maintain" + "clear separation between the functionality of" + "these two methods.") + if source not in self.matrix: + raise ValueError(error_msg % (source)) + if target not in self.matrix: + raise ValueError(error_msg % (target)) + self.matrix[source][target] = True if cost is not None: self.edge_weights[source + "_" + target] = \ diff --git a/pydatastructs/graphs/graph.py b/pydatastructs/graphs/graph.py index 93d4bb218..0c1b195a8 100644 --- a/pydatastructs/graphs/graph.py +++ b/pydatastructs/graphs/graph.py @@ -53,13 +53,11 @@ class Graph(object): Note ==== - Steps to create a graph: - - 1. Create nodes (AdjacencyListGraphNode or AdjacencyListMatrixNode) - - 2. Add nodes to the graph - - 3. Add edges b/w these nodes + Make sure to create nodes (AdjacencyListGraphNode or AdjacencyMatrixGraphNode) + and them in your graph using Graph.add_vertex before adding edges whose + end points require either of the nodes that you added. In other words, + Graph.add_edge doesn't add new nodes on its own if the input + nodes are not already present in the Graph. """ diff --git a/pydatastructs/graphs/tests/test_adjacency_list.py b/pydatastructs/graphs/tests/test_adjacency_list.py index d1635fc83..3dcef8a7a 100644 --- a/pydatastructs/graphs/tests/test_adjacency_list.py +++ b/pydatastructs/graphs/tests/test_adjacency_list.py @@ -1,5 +1,6 @@ from pydatastructs.graphs import Graph from pydatastructs.utils import AdjacencyListGraphNode +from pydatastructs.utils.raises_util import raises def test_adjacency_list(): v_1 = AdjacencyListGraphNode('v_1', 1) @@ -38,3 +39,6 @@ def test_adjacency_list(): g.remove_vertex('v') assert g.is_adjacent('v_2', 'v') is False assert g.is_adjacent('v_3', 'v') is False + + assert raises(ValueError, lambda: g.add_edge('u', 'v')) + assert raises(ValueError, lambda: g.add_edge('v', 'x')) diff --git a/pydatastructs/graphs/tests/test_adjacency_matrix.py b/pydatastructs/graphs/tests/test_adjacency_matrix.py index 3df819611..c0f7b7c06 100644 --- a/pydatastructs/graphs/tests/test_adjacency_matrix.py +++ b/pydatastructs/graphs/tests/test_adjacency_matrix.py @@ -1,5 +1,6 @@ from pydatastructs.graphs import Graph from pydatastructs.utils import AdjacencyMatrixGraphNode +from pydatastructs.utils.raises_util import raises def test_AdjacencyMatrix(): v_0 = AdjacencyMatrixGraphNode(0, 0) @@ -25,3 +26,6 @@ def test_AdjacencyMatrix(): assert neighbors == [v_1] g.remove_edge(0, 1) assert g.is_adjacent(0, 1) is False + + assert raises(ValueError, lambda: g.add_edge('u', 'v')) + assert raises(ValueError, lambda: g.add_edge('v', 'x'))