Skip to content

Commit

Permalink
vertex_attrs option for from_dicts
Browse files Browse the repository at this point in the history
  • Loading branch information
tscizzle committed Oct 4, 2016
1 parent 951595b commit 522796f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 9 deletions.
14 changes: 11 additions & 3 deletions docs/library.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ graphpy.graph
- each tuple is of the form ((hashable, hashable),) representing ((v0_val, v1_val),), or ((hashable, hashable), dict) representing ((v0_val, v1_val), attrs)
- **Returns**
- UndirectedGraph object defined by *vertices* and *edges*
- *classmethod* **from_dict** (*graph_dict*)
- *classmethod* **from_dict** (*graph_dict*, *vertex_attrs* =None)
- **Parameters**
- **graph_dict** <dict>
- hashable -> tuple[]
Expand All @@ -176,6 +176,10 @@ graphpy.graph
- (hashable,), length-1 tuple containing the val of the vertex to which the edge points
- (hashable, dict), length-2 tuple containing the val of the vertex to which the edge points and the edge's attributes
- if there are duplicate declarations of an edge (like v1 appearing in v0's list and v0 appearing in v1's list) with different attributes, the one to keep is chosen arbitrarily
- **vertex_attrs** <dict>
- hashable -> dict
- each vertex's val mapped to an attrs dict, as used in vertex creation
- vertices in vertex_attrs but not in graph_dict are added as new vertices
- **Returns**
- UndirectedGraph object defined by *graph_dict*
- *classmethod* **from_directed_graph** (*directed_graph*)
Expand Down Expand Up @@ -277,7 +281,7 @@ graphpy.graph
- each tuple is of the form ((hashable, hashable),) representing ((v_from_val, v_to_val),), or ((hashable, hashable), dict)) representing ((v_from_val, v_to_val), attrs))
- **Returns**
- DirectedGraph object defined by *vertices* and *edges*
- *classmethod* **from_dict** (*graph_dict*)
- *classmethod* **from_dict** (*graph_dict*, *vertex_attrs* =None)
- **Parameters**
- **graph_dict** <dict>
- hashable -> tuple[]
Expand All @@ -286,6 +290,10 @@ graphpy.graph
- (hashable,), length-1 tuple containing the val of the vertex to which the edge points
- (hashable, dict), length-2 tuple containing the val of the vertex to which the edge points and the edge's attributes
- if there are duplicate declarations of an edge (like v1 appearing in v0's list and v0 appearing in v1's list) with different attributes, the one to keep is chosen arbitrarily
- **vertex_attrs** <dict>
- hashable -> dict
- each vertex's val mapped to an attrs dict, as used in vertex creation
- vertices in vertex_attrs but not in graph_dict are added as new vertices
- **Returns**
- DirectedGraph object defined by *graph_dict*
- *classmethod* **from_transpose** (*transpose_graph*)
Expand Down Expand Up @@ -349,7 +357,7 @@ graphpy.graph
- **v_vals** <tuple>
- **Returns**
- DirectedEdge object with vertices with vals of v_vals[0] and v_vals[1], or None if no such edge is in this graph
- *method* **add_vertex** (*val* =None, attrs =None)
- *method* **add_vertex** (*val* =None, *attrs* =None)
- **Parameters**
- **val** <hashable>
- **attrs** <dict>
Expand Down
22 changes: 20 additions & 2 deletions graphpy/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ def from_lists(cls, vertices, edges):
return g

@classmethod
def from_dict(cls, graph_dict):
def from_dict(cls, graph_dict, vertex_attrs=None):
""" Generate a graph by passing in a dictionary of vertex vals each
mapped to a set of vals of vertices to which there is an edge """
vertex_attrs = vertex_attrs or {}

g = cls()

for v_val in graph_dict:
Expand Down Expand Up @@ -91,6 +93,13 @@ def from_dict(cls, graph_dict):
except EdgeAlreadyExistsException:
pass

for v_val, v_attrs in vertex_attrs.items():
if not g.has_vertex(v_val):
g.add_vertex(v_val)
v = g.get_vertex(v_val)
for attr, value in v_attrs.items():
v.set(attr, value)

return g

@classmethod
Expand Down Expand Up @@ -317,9 +326,11 @@ def from_lists(cls, vertices, edges):
return g

@classmethod
def from_dict(cls, graph_dict):
def from_dict(cls, graph_dict, vertex_attrs=None):
""" Generate a graph by passing in a dictionary of vertex vals each
mapped to a set of vals of vertices to which there is an edge """
vertex_attrs = vertex_attrs or {}

g = cls()

for v_val in graph_dict:
Expand Down Expand Up @@ -348,6 +359,13 @@ def from_dict(cls, graph_dict):
except EdgeAlreadyExistsException:
pass

for v_val, v_attrs in vertex_attrs.items():
if not g.has_vertex(v_val):
g.add_vertex(v_val)
v = g.get_vertex(v_val)
for attr, value in v_attrs.items():
v.set(attr, value)

return g

@classmethod
Expand Down
27 changes: 23 additions & 4 deletions tests/test_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,23 +101,33 @@ def test_create_undirected_graph_from_dict(self):
(2, 2): [],
'v3': [],
'v4': []}
g = UndirectedGraph.from_dict(graph_dict)
vertex_attrs = {'v0': {'city': 'Paris'},
1: {'continent': 'Europe', 'city': 'London'},
'v5': {'city': 'Jamestown'}}
g = UndirectedGraph.from_dict(graph_dict, vertex_attrs=vertex_attrs)

v0 = g.get_vertex('v0')
v1 = g.get_vertex(1)
v2 = g.get_vertex((2, 2))
v3 = g.get_vertex('v3')
v4 = g.get_vertex('v4')
v5 = g.get_vertex('v5')
e01 = g.get_edge(('v0', 1))
e02 = g.get_edge(('v0', (2, 2)))
e13 = g.get_edge((1, 'v3'))
self.assertEqual(g.num_vertices, 5)
self.assertEqual(g.num_vertices, 6)
self.assertEqual(g.num_edges, 3)
self.assertEqual(set(v0.neighbors), set([v1, v2]))
self.assertEqual(set(v1.neighbors), set([v0, v3]))
self.assertEqual(set(v2.neighbors), set([v0]))
self.assertEqual(set(v3.neighbors), set([v1]))
self.assertEqual(set(v4.neighbors), set())
self.assertEqual(set(v5.neighbors), set())
self.assertEqual(v0.get('city'), 'Paris')
self.assertEqual(v1.get('continent'), 'Europe')
self.assertEqual(v1.get('city'), 'London')
self.assertEqual(v5.get('city'), 'Jamestown')
self.assertIsNone(v2.get('city'))
self.assertIsNone(e01.get('weight'))
self.assertEqual(e02.get('weight'), 5)
self.assertIsNone(e13.get('weight'))
Expand Down Expand Up @@ -468,16 +478,20 @@ def test_create_directed_graph_from_dict(self):
(2, 2): [],
'v3': [],
'v4': []}
g = DirectedGraph.from_dict(graph_dict)
vertex_attrs = {'v0': {'city': 'Paris'},
1: {'continent': 'Europe', 'city': 'London'},
'v5': {'city': 'Jamestown'}}
g = DirectedGraph.from_dict(graph_dict, vertex_attrs=vertex_attrs)

v0 = g.get_vertex('v0')
v1 = g.get_vertex(1)
v2 = g.get_vertex((2, 2))
v3 = g.get_vertex('v3')
v4 = g.get_vertex('v4')
v5 = g.get_vertex('v5')
e01 = g.get_edge(('v0', 1))
e02 = g.get_edge(('v0', (2, 2)))
self.assertEqual(g.num_vertices, 5)
self.assertEqual(g.num_vertices, 6)
self.assertEqual(g.num_edges, 4)
self.assertEqual(set(v0.outs), set([v1, v2]))
self.assertEqual(set(v1.outs), set([v0, v3]))
Expand All @@ -489,6 +503,11 @@ def test_create_directed_graph_from_dict(self):
self.assertEqual(set(v2.ins), set([v0]))
self.assertEqual(set(v3.ins), set([v1]))
self.assertEqual(set(v4.ins), set())
self.assertEqual(v0.get('city'), 'Paris')
self.assertEqual(v1.get('continent'), 'Europe')
self.assertEqual(v1.get('city'), 'London')
self.assertEqual(v5.get('city'), 'Jamestown')
self.assertIsNone(v2.get('city'))
self.assertIsNone(e01.get('weight'))
self.assertEqual(e02.get('weight'), 5)
with self.assertRaises(BadGraphInputException):
Expand Down

0 comments on commit 522796f

Please sign in to comment.