Tutorial¶
This guide can help you start working with Kinbaku.
Creating a graph¶
A Graph is a collection of nodes (vertices) along with
ordered pairs of nodes called edges. The current version of Kinbaku only support directed graph.
Create an empty graph with no nodes and no edges.
>>> import kinbaku as kn
>>> G = kn.Graph("test.db", flag="n")
You should see a test.db file in your current folder. The flag parameter can be “r” (read), “w” (write) and “n” (new/empty).
In Kinbaku, nodes can be any str object of max_key_len length: for efficiency reasons, Kinbaku requires you to specify the maximum key length ahead of time.
>>> import kinbaku as kn
>>> G = kn.Graph("test.db", max_key_len=20, flag="n")
>>> G.add_node("a_very_long_node_key")
Note
the maximum key length cannot be changed once the graph is created!
Creating nodes and edges¶
Let’s start with some simple manipulations. You can add one node using the following code:
>>> import kinbaku as kn
>>> G = kn.Graph("test.db", flag="n")
>>> G.add_node("A")
>>> G.add_node("B")
>>> G.add_node("C")
Note
The key cannot be changed once the node is created. Keep in mind that strings are the only accepted type for node keys.
Add an edge from A to B using:
>>> G.add_edge("A", "B")
If the nodes do not exist, they are created.
Accessing nodes and edges¶
You can iterate through the nodes:
>>> for node in G.nodes:
>>> print(node)
and through the edges:
>>> for edge in G.edges:
>>> print(edge)
You can get a node using its key:
>>> print(G.node("A"))
>>> print(G["A"]) # alternatively
and an edge using its endpoints:
>>> print(G.edge("A", "B"))
>>> print(G["A", "B"]) # alternatively
Checking if a node or an edge exists:
>>> print(G.has_node("A")) # True
>>> print(G.has_node("D")) # False
>>> print(G.has_edge("A", "B")) # True
Removing nodes and edges¶
Removing a node can be done in one line:
>>> G.remove_node("C")
This will remove all edges that link to or from C.
Likewise,
>>> G.remove_edge("A", "B")
to remove an edge. Removing a non-existing edge will throw an exception.
Neighbors and predecessors¶
Kinbaku uses Networkx conventions: the neighbors of a node A are all the nodes X where A -> X. Predecessors are all the X where X -> A.
>>> G.add_edge("A", "B")
>>> G.add_edge("A", "C")
>>> for node in G.neighbors("A"):
>>> print(node) # should print B and C
>>> for node in G.predecessors("B"):
>>> print(node) # should print A
Custom attributes¶
Each edge and vertex can have custom attributes by inheriting from the Node and Edge dataclasses.
from dataclasses import dataclass
import kinbaku as kn
@dataclass(repr=False)
class User(kn.structure.Node):
name: str = ""
email: str = ""
@dataclass(repr=False)
class Friendship(kn.structure.Edge):
love: float = 0.
G = kn.Graph("test.db", node_class=User, edge_class=Friendship, flag="n")
# create nodes
G.add_node("john", attr={"name": "John B.", "email": "john@john.com"})
G["jack"] = {"name": "Jack H."} # alternatively
# create edge
G.add_edge("john", "jack", attr={"love": .5})
# update data
G["jack"] = {"name": "Jack C."}
G["john", "jack"] = {"love": .8}
# see results
print(G["john"])
print(G["jack"])
print(G["john", "jack"])
Attention
updating data using add_node, add_edge or the dictionary syntax will not update individual fields, but replace the whole content.
Algorithms¶
Coming soon.