Skip to content

Commit

Permalink
Add python bindings for attribute read/write (#1156)
Browse files Browse the repository at this point in the history
* add python bindings for attribute read/write

* fix string conversion

* fix test typo

* fix string conversion
  • Loading branch information
bernlu committed Jan 8, 2024
1 parent cb48d13 commit 71d66b1
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
12 changes: 12 additions & 0 deletions networkit/graph.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ cdef extern from "<networkit/graph/Graph.hpp>":
void set(node, int) except +
int get(node) except +
int get(node, int) except +
void write(string) except +
void read(string) except +
void swap(_NodeIntAttribute& other)
string getName() except +

Expand All @@ -195,6 +197,8 @@ cdef extern from "<networkit/graph/Graph.hpp>":
void set(node, double) except +
double get(node) except +
double get(node, double) except +
void write(string) except +
void read(string) except +
void swap(_NodeDoubleAttribute& other)
string getName() except +

Expand All @@ -211,6 +215,8 @@ cdef extern from "<networkit/graph/Graph.hpp>":
void set(node, string) except +
string get(node) except +
string get(node, string) except +
void write(string) except +
void read(string) except +
void swap(_NodeStringAttribute& other)
string getName() except +

Expand All @@ -230,6 +236,8 @@ cdef extern from "<networkit/graph/Graph.hpp>":
int get2(node, node) except +
int get(edgeid, int) except +
int get2(node, node, int) except +
void write(string) except +
void read(string) except +
void swap(_EdgeIntAttribute& other)

cdef extern from "<networkit/graph/Graph.hpp>":
Expand All @@ -248,6 +256,8 @@ cdef extern from "<networkit/graph/Graph.hpp>":
double get2(node, node) except +
double get(edgeid, double) except +
double get2(node, node, double) except +
void write(string) except +
void read(string) except +
void swap(_EdgeDoubleAttribute& other)

cdef extern from "<networkit/graph/Graph.hpp>":
Expand All @@ -266,6 +276,8 @@ cdef extern from "<networkit/graph/Graph.hpp>":
string get2(node, node) except +
string get(edgeid, string) except +
string get2(node, node, string) except +
void write(string) except +
void read(string) except +
void swap(_EdgeStringAttribute& other)

cdef class Graph:
Expand Down
47 changes: 47 additions & 0 deletions networkit/graph.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,12 @@ cdef class NodeIntAttribute:
preincrement(self._iter)
return val

def write(self, path: str):
return self._this.write(stdstring(path))

def read(self, path: str):
return self._this.read(stdstring(path))


cdef class NodeDoubleAttribute:
cdef setThis(self, _NodeDoubleAttribute& other, _Graph* G):
Expand Down Expand Up @@ -1202,6 +1208,12 @@ cdef class NodeDoubleAttribute:
preincrement(self._iter)
return val

def write(self, path: str):
return self._this.write(stdstring(path))

def read(self, path: str):
return self._this.read(stdstring(path))

cdef class NodeStringAttribute:

cdef setThis(self, _NodeStringAttribute& other, _Graph* G):
Expand Down Expand Up @@ -1241,6 +1253,12 @@ cdef class NodeStringAttribute:
preincrement(self._iter)
return val

def write(self, path: str):
return self._this.write(stdstring(path))

def read(self, path: str):
return self._this.read(stdstring(path))

class NodeAttribute:
"""
Generic class for node attributes returned by networkit.graph.attachNodeAttribute().
Expand Down Expand Up @@ -1290,6 +1308,12 @@ class NodeAttribute:

def __next__(self):
return next(self._iter)

def write(self, path: str):
return self.attr.write(path)

def read(self, path: str):
return self.attr.read(path)


# The following 3 classes EdgeIntAttribute, EdgeDoubleAttribute and
Expand Down Expand Up @@ -1351,6 +1375,11 @@ cdef class EdgeIntAttribute:
preincrement(self._iter)
return val

def write(self, path: str):
return self._this.write(stdstring(path))

def read(self, path: str):
return self._this.read(stdstring(path))

cdef class EdgeDoubleAttribute:
cdef setThis(self, _EdgeDoubleAttribute& other, _Graph* G):
Expand Down Expand Up @@ -1402,6 +1431,12 @@ cdef class EdgeDoubleAttribute:
val = dereference(self._iter)
preincrement(self._iter)
return val

def write(self, path: str):
return self._this.write(stdstring(path))

def read(self, path: str):
return self._this.read(stdstring(path))

cdef class EdgeStringAttribute:

Expand Down Expand Up @@ -1455,6 +1490,12 @@ cdef class EdgeStringAttribute:
val = (val[0], pystring(val[1]))
preincrement(self._iter)
return val

def write(self, path: str):
return self._this.write(stdstring(path))

def read(self, path: str):
return self._this.read(stdstring(path))

class EdgeAttribute:
"""
Expand Down Expand Up @@ -1503,6 +1544,12 @@ class EdgeAttribute:
def __next__(self):
return next(self._iter)

def write(self, path: str):
return self.attr.write(path)

def read(self, path: str):
return self.attr.read(path)


cdef cppclass EdgeCallBackWrapper:
void* callback
Expand Down
42 changes: 42 additions & 0 deletions networkit/test/test_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,24 @@ def testNodeAttributes(self):

G.detachNodeAttribute("attribute")

def testNodeAttributeReadWrite(self):
G = nk.Graph(5)

for attType in [int, float, str]:
attVals = [attType(u) for u in G.iterNodes()]

attrs = G.attachNodeAttribute("attribute", attType)
attrsRead = G.attachNodeAttribute("attributeRead", attType)
for u in G.iterNodes():
attrs[u] = attVals[u]
attrs.write('test.attrs')
attrsRead.read('test.attrs')
for u in G.iterNodes():
self.assertEqual(attrs[u], attrsRead[u])

G.detachNodeAttribute("attribute")
G.detachNodeAttribute("attributeRead")

def testEdgeAttributesMandatoryIndexing(self):
G = nk.Graph(5)
with self.assertRaises(Exception):
Expand Down Expand Up @@ -352,6 +370,30 @@ def testEdgeAttributesByNodePair(self):
self.assertEqual(attrs[u,v], attVals[u])

G.detachEdgeAttribute("attribute")

def testEdgeAttributeReadWrite(self):
G = nk.Graph(5)
G.indexEdges()

G.addEdge(0, 1)
G.addEdge(0, 2)
G.addEdge(1, 3)
G.addEdge(2, 4)

for attType in [int, float, str]:
attVals = [attType(u+v) for u,v in G.iterEdges()]

attrs = G.attachEdgeAttribute("attribute", attType)
attrsRead = G.attachEdgeAttribute("attributeRead", attType)
for u,v in G.iterEdges():
attrs[u,v] = attVals[u]
attrs.write('test.attrs')
attrsRead.read('test.attrs')
for u,v in G.iterEdges():
self.assertEqual(attrs[u,v], attrsRead[u,v])

G.detachEdgeAttribute("attribute")
G.detachEdgeAttribute("attributeRead")

def testRandomEdgesReproducibility(self):
numSamples = 10
Expand Down

0 comments on commit 71d66b1

Please sign in to comment.