Skip to content

Commit 83b4869

Browse files
committed
chore: format code
1 parent acbd63c commit 83b4869

File tree

1 file changed

+153
-14
lines changed

1 file changed

+153
-14
lines changed

src/ssspx/io.py

Lines changed: 153 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,40 @@
1515

1616

1717
def _iter_edges(G: Graph) -> Iterable[Tuple[int, int, float]]:
18-
"""Yield all edges ``(u, v, w)`` from ``G``."""
18+
"""
19+
Iterates over all edges in the given graph.
20+
21+
Args:
22+
G (Graph): The graph object containing adjacency information.
23+
24+
Yields:
25+
Tuple[int, int, float]: A tuple representing an edge in the graph,
26+
where the first element is the source node index (u),
27+
the second element is the destination node index (v),
28+
and the third element is the edge weight (w).
29+
"""
1930
for u in range(G.n):
2031
for v, w in G.adj[u]:
2132
yield u, v, w
2233

2334

2435
def _read_csv(path: Path) -> Tuple[int, EdgeList]:
25-
"""Parse a CSV/TSV edges file."""
36+
"""
37+
Reads a CSV file containing edge data and returns the number of nodes and the edge list.
38+
39+
Each line in the file should contain at least three columns: source node, target node, and edge weight.
40+
Lines starting with '#' or empty lines are ignored. Columns can be separated by commas or tabs.
41+
42+
Args:
43+
path (Path): The path to the CSV file.
44+
45+
Returns:
46+
Tuple[int, EdgeList]: A tuple containing the number of nodes (max node id + 1) and a list of edges,
47+
where each edge is represented as a tuple (u, v, w).
48+
49+
Raises:
50+
GraphFormatError: If no edges are parsed from the file.
51+
"""
2652
edges: EdgeList = []
2753
max_id = -1
2854
with path.open("r", encoding="utf-8") as fh:
@@ -47,14 +73,41 @@ def _read_csv(path: Path) -> Tuple[int, EdgeList]:
4773

4874

4975
def _write_csv(path: Path, G: Graph) -> None:
50-
"""Write ``G`` as a CSV edges file."""
76+
"""
77+
Writes the edges of a graph to a CSV file.
78+
79+
Each row in the CSV file represents an edge in the graph, with columns for the source node, target node, and edge weight.
80+
81+
Args:
82+
path (Path): The file path where the CSV will be written.
83+
G (Graph): The graph whose edges will be written to the CSV file.
84+
85+
Returns:
86+
None
87+
"""
5188
with path.open("w", encoding="utf-8") as fh:
5289
for u, v, w in _iter_edges(G):
5390
fh.write(f"{u},{v},{w}\n")
5491

5592

5693
def _read_jsonl(path: Path) -> Tuple[int, EdgeList]:
57-
"""Parse a JSON Lines edges file."""
94+
"""
95+
Reads a JSON Lines (JSONL) file containing graph edges and returns the
96+
number of nodes and the edge list.
97+
98+
Each line in the file should be a JSON object with keys "u", "v", and "w",
99+
representing the source node, target node, and edge weight, respectively.
100+
101+
Args:
102+
path (Path): Path to the JSONL file.
103+
104+
Returns:
105+
Tuple[int, EdgeList]: A tuple containing the number of nodes
106+
(max node id + 1) and a list of edges as (u, v, w) tuples.
107+
108+
Raises:
109+
GraphFormatError: If no edges are parsed from the file.
110+
"""
58111
edges: EdgeList = []
59112
max_id = -1
60113
with path.open("r", encoding="utf-8") as fh:
@@ -74,14 +127,42 @@ def _read_jsonl(path: Path) -> Tuple[int, EdgeList]:
74127

75128

76129
def _write_jsonl(path: Path, G: Graph) -> None:
77-
"""Write ``G`` as a JSON Lines edges file."""
130+
"""
131+
Writes the edges of a graph to a file in JSON Lines (JSONL) format.
132+
133+
Each line in the output file represents an edge as a JSON object
134+
with keys 'u', 'v', and 'w', corresponding to the source node, target node,
135+
and edge weight, respectively.
136+
137+
Args:
138+
path (Path): The file path where the JSONL data will be written.
139+
G (Graph): The graph object containing the edges to be serialized.
140+
141+
Returns:
142+
None
143+
"""
78144
with path.open("w", encoding="utf-8") as fh:
79145
for u, v, w in _iter_edges(G):
80146
fh.write(json.dumps({"u": u, "v": v, "w": w}) + "\n")
81147

82148

83149
def _read_mtx(path: Path) -> Tuple[int, EdgeList]:
84-
"""Parse a MatrixMarket edges file."""
150+
"""
151+
Reads a Matrix Market (.mtx) file and extracts the edge list.
152+
153+
Args:
154+
path (Path): Path to the Matrix Market file.
155+
156+
Returns:
157+
Tuple[int, EdgeList]: A tuple containing the number of nodes (n) and the edge list.
158+
The edge list is a list of tuples (u, v, w), where u and v are zero-based node indices,
159+
and w is the edge weight.
160+
161+
Notes:
162+
- Lines starting with '%' are treated as comments and skipped.
163+
- Assumes the file contains at least three columns: source, target, and weight.
164+
- Node indices in the file are assumed to be 1-based and are converted to 0-based.
165+
"""
85166
edges: EdgeList = []
86167
it = path.open("r", encoding="utf-8")
87168
with it as fh:
@@ -105,7 +186,20 @@ def _read_mtx(path: Path) -> Tuple[int, EdgeList]:
105186

106187

107188
def _write_mtx(path: Path, G: Graph) -> None:
108-
"""Write ``G`` as a MatrixMarket edges file."""
189+
"""
190+
Writes the given graph `G` to a Matrix Market (.mtx) file at the specified path.
191+
192+
The output file will contain the graph's adjacency matrix in coordinate format,
193+
where each line represents an edge with its source node, target node, and weight.
194+
Node indices are written as 1-based (Matrix Market convention).
195+
196+
Args:
197+
path (Path): The file path where the Matrix Market file will be written.
198+
G (Graph): The graph object containing nodes and weighted edges.
199+
200+
Returns:
201+
None
202+
"""
109203
edges = list(_iter_edges(G))
110204
with path.open("w", encoding="utf-8") as fh:
111205
fh.write("%%MatrixMarket matrix coordinate real general\n")
@@ -117,7 +211,7 @@ def _write_mtx(path: Path, G: Graph) -> None:
117211
def _read_graphml(path: Path) -> Tuple[int, EdgeList]:
118212
"""
119213
Parse a GraphML file and extract the edge list.
120-
214+
121215
Args:
122216
path (Path): Path to the GraphML file.
123217
Returns:
@@ -134,7 +228,7 @@ def _read_graphml(path: Path) -> Tuple[int, EdgeList]:
134228
max_id = -1
135229
for edge in root.findall(f".//{ns}edge"):
136230
u_str = edge.attrib.get("source", "")
137-
v_str = edge.attrib.get("target", "")
231+
v_str = edge.attrib.get("target", "")
138232
# Convert string IDs to integers
139233
if u_str.startswith("n"):
140234
u = int(u_str[1:])
@@ -143,7 +237,7 @@ def _read_graphml(path: Path) -> Tuple[int, EdgeList]:
143237
if v_str.startswith("n"):
144238
v = int(v_str[1:])
145239
else:
146-
v = int(v_str)
240+
v = int(v_str)
147241
w_attr = edge.attrib.get("weight")
148242
if w_attr is None:
149243
data = edge.find(f"{ns}data[@key='w']")
@@ -188,7 +282,16 @@ def _write_graphml(path: Path, G: Graph) -> None:
188282

189283

190284
def _detect_format(path: Path) -> Optional[str]:
191-
"""Infer graph format from ``path`` extension."""
285+
"""
286+
Detects the file format based on the file extension.
287+
288+
Args:
289+
path (Path): The path to the file whose format is to be detected.
290+
291+
Returns:
292+
Optional[str]: The detected format as a string ("csv", "jsonl", "mtx", "graphml"),
293+
or None if the format is not recognized.
294+
"""
192295
ext = path.suffix.lower()
193296
if ext in {".csv", ".tsv"}:
194297
return "csv"
@@ -202,7 +305,19 @@ def _detect_format(path: Path) -> Optional[str]:
202305

203306

204307
def read_graph(path: str, fmt: Optional[str] = None) -> Graph:
205-
"""Read a graph from ``path`` in the given format."""
308+
"""
309+
Reads a graph from a file in the specified format.
310+
311+
Args:
312+
path (str): The path to the graph file.
313+
fmt (Optional[str], optional): The format of the graph file. If None, the format is auto-detected.
314+
315+
Returns:
316+
Graph: The graph object constructed from the file.
317+
318+
Raises:
319+
GraphFormatError: If the graph format is unknown or unsupported.
320+
"""
206321
p = Path(path)
207322
fmt = fmt or _detect_format(p)
208323
if fmt is None or fmt not in _FMT_READERS:
@@ -212,7 +327,17 @@ def read_graph(path: str, fmt: Optional[str] = None) -> Graph:
212327

213328

214329
def write_graph(G: Graph, path: str, fmt: Optional[str] = None) -> None:
215-
"""Write ``G`` to ``path`` in the given format."""
330+
"""
331+
Writes a graph to a file in the specified format.
332+
333+
Parameters:
334+
G (Graph): The graph object to be written.
335+
path (str): The file path where the graph will be saved.
336+
fmt (Optional[str], optional): The format to use for writing the graph. If None, the format is auto-detected from the file extension.
337+
338+
Raises:
339+
GraphFormatError: If the format is unknown or unsupported.
340+
"""
216341
p = Path(path)
217342
fmt = fmt or _detect_format(p)
218343
if fmt is None or fmt not in _FMT_WRITERS:
@@ -221,7 +346,21 @@ def write_graph(G: Graph, path: str, fmt: Optional[str] = None) -> None:
221346

222347

223348
def load_graph(path: str, fmt: Optional[str] = None) -> Graph:
224-
"""Deprecated alias for :func:`read_graph`."""
349+
"""
350+
Loads a graph from the specified file path.
351+
352+
This function is deprecated; use `read_graph` instead.
353+
354+
Args:
355+
path (str): The path to the graph file.
356+
fmt (Optional[str], optional): The format of the graph file. Defaults to None.
357+
358+
Returns:
359+
Graph: The loaded graph object.
360+
361+
Deprecated:
362+
Since version 0.1.0. Will be removed in version 0.2.0. Use `read_graph` instead.
363+
"""
225364
warn_once(
226365
"load_graph is deprecated; use read_graph",
227366
since="0.1.0",

0 commit comments

Comments
 (0)