Source code for cfpq_data.graphs.readwrite.txt

"""Read (and write) a graph from (and to) TXT file."""
import logging
import pathlib
import shlex
from typing import Union, Iterable, Iterator

import networkx as nx

__all__ = [
    "graph_from_text",
    "graph_to_text",
    "graph_from_txt",
    "graph_to_txt",
]


[docs] def graph_from_text(text: Iterable[str]) -> nx.MultiDiGraph: """Returns a graph from text. Parameters ---------- text : Iterable[str] The text with which the graph will be created. Examples -------- >>> from cfpq_data import * >>> g = graph_from_text(["1 A 2"]) >>> g.number_of_nodes() 2 >>> g.number_of_edges() 1 Returns ------- g : MultiDiGraph Loaded graph. """ graph = nx.MultiDiGraph() for edge in text: try: u, label, v = shlex.split(edge.strip()) graph.add_edge( u_for_edge=u, v_for_edge=v, label=label, ) except Exception as e: raise ValueError( f"{edge} does not match the input format: FROM LABEL TO" ) from e logging.info(f"Load {graph=} from {text=}") return graph
[docs] def graph_to_text(graph: nx.MultiDiGraph, *, quoting: bool = False) -> Iterator[str]: """Turns a graph into its text representation. Parameters ---------- graph : MultiDiGraph Graph to text. quoting : bool If true, quotes will be added. Examples -------- >>> from cfpq_data import * >>> g = labeled_cycle_graph(2) >>> list(graph_to_text(g, quoting=True)) ["'0' 'a' '1'", "'1' 'a' '0'"] >>> list(graph_to_text(g, quoting=False)) ['0 a 1', '1 a 0'] Returns ------- text : str Generator of graph edges. """ for u, v, edge_labels in graph.edges(data=True): for label in edge_labels.values(): if quoting: yield f"'{u}' '{label}' '{v}'" else: yield f"{u} {label} {v}" logging.info(f"Turn {graph=} into text with {quoting=}")
[docs] def graph_from_txt(path: Union[pathlib.Path, str]) -> nx.MultiDiGraph: """Returns a graph loaded from a TXT file. Parameters ---------- path : Union[Path, str] The path to the TXT file with which the graph will be created. Examples -------- >>> from cfpq_data import * >>> g_1 = graph_from_text(["1 A 2"]) >>> p = graph_to_txt(g_1, "test.txt") >>> g = graph_from_txt(p) >>> g.number_of_nodes() 2 >>> g.number_of_edges() 1 Returns ------- g : MultiDiGraph Loaded graph. """ with open(path, "r") as f: graph = graph_from_text(f) logging.info(f"Load {graph=} from {path=}") return graph
[docs] def graph_to_txt( graph: nx.MultiDiGraph, path: Union[pathlib.Path, str], *, quoting: bool = False, ) -> pathlib.Path: """Returns a path to the TXT file where the graph will be saved. Parameters ---------- graph : MultiDiGraph Graph to save. path: Union[Path, str] The path to the file where the graph will be saved. quoting : bool If true, quotes will be added. Examples -------- >>> from cfpq_data import * >>> g = labeled_cycle_graph(42, label="a") >>> path = graph_to_txt(g, "test.txt", quoting=False) Returns ------- path : Path Path to a TXT file where the graph will be saved. """ with open(path, "w") as f: for edge in graph_to_text(graph=graph, quoting=quoting): f.write(edge + "\n") dest = pathlib.Path(path).resolve() logging.info(f"Save {graph=} to {dest=}") return dest