示例#1
0
def test_switch():
    func = switch(
        lambda x: x[0],
        {
            "A": lambda x: x.lower(),
            "B": lambda x: x.upper(),
        },
        default=lambda x: x[::-1],
    )
    assert _apply(func, "Apple") == "apple"
    assert _apply(func, "Banana") == "BANANA"
    assert _apply(func, "Cherry") == "yrrehC"
示例#2
0
def test_chain():
    func = chain([{"x": 7}, lambda name: {"name": name}, {"x": 8}])
    assert _apply(func, "john") == {"x": 8, "name": "john"}
示例#3
0
def test_apply_func():
    assert _apply(lambda x, y: x + y, 2, 5) == 7
示例#4
0
def test_apply_func_by_name():
    assert _apply(lambda x, y: x + y, x=2, y=5) == 7
示例#5
0
def test_apply_lit_ignores_arguments():
    assert _apply(7, "garbage1", garbage2="garbage3") == 7
示例#6
0
def test_apply_lit():
    assert _apply(7) == 7
示例#7
0
def _to_gv(graph, style: Style, subgraph_func=None):
    """
    Serializes a `NetworkX`_ graph as a `GraphViz`_ string.

    :param graph: A `NetworkX`_ ``Graph``, ``DiGraph``, ``MultiGraph``, or ``MultiDiGraph``.
    :param style: A :class:`~nxv.Style` object.
    :param subgraph_func: An optional function ``f(u, d)`` that returns a subgraph key,
                          where ``u`` is a `NetworkX`_ node and ``d`` is its attribute dict.
    :return: The raw `GraphViz`_ string format to pass as input to one of the GraphViz layout algorithms.
    """

    if subgraph_func is None:
        subgraph_func = _default_subgraph_func

    graph_attrs = _apply(style.graph, graph, graph.graph)
    graph_type = graph_attrs.get(
        "type", "digraph" if nx.is_directed(graph) else "graph")
    assert graph_type in {"graph", "digraph"}
    edge_str = {"graph": "--", "digraph": "->"}[graph_type]
    ids = {u: f"node{i:04}" for i, u in enumerate(graph.nodes())}

    no_subgraph_nodes = []
    subgraph_nodes = {}
    for u, d in graph.nodes(data=True):
        subgraph = _apply(subgraph_func, u, d)
        if subgraph is None:
            no_subgraph_nodes.append((u, d))
        else:
            subgraph_nodes.setdefault(subgraph, []).append((u, d))

    def node_declaration(u, d):
        node_attrs = _apply(style.node, u, d)
        return f"{ids[u]} {_attributes_modifier(node_attrs)};"

    def edge_declaration(*edge):
        u, v = edge[:2]
        edge_attrs = _apply(style.edge, *edge)
        return f"{ids[u]} {edge_str} {ids[v]} {_attributes_modifier(edge_attrs)};"

    def subgraph_declaration(subgraph, nodes, attrs):
        return _block(
            _graph_identifier("subgraph", attrs.get("name", str(subgraph))),
            [_graph_attrs_declaration(attrs)] +
            [node_declaration(u, d) for u, d in nodes],
        )

    edges_kwargs = ({
        "keys": True,
        "data": True
    } if is_multi_graph(graph) else {
        "data": True
    })

    lines = _block(
        _graph_identifier(graph_type, graph_attrs.get("name", "G")),
        ([_graph_attrs_declaration(graph_attrs)] +
         [node_declaration(u, d) for u, d in no_subgraph_nodes] + [
             line for subgraph, nodes in subgraph_nodes.items()
             for line in subgraph_declaration(subgraph, nodes,
                                              _apply(style.subgraph, subgraph))
         ] + [edge_declaration(*edge)
              for edge in graph.edges(**edges_kwargs)]),
    )

    return "\n".join(lines)
示例#8
0
 def edge_declaration(*edge):
     u, v = edge[:2]
     edge_attrs = _apply(style.edge, *edge)
     return f"{ids[u]} {edge_str} {ids[v]} {_attributes_modifier(edge_attrs)};"
示例#9
0
 def node_declaration(u, d):
     node_attrs = _apply(style.node, u, d)
     return f"{ids[u]} {_attributes_modifier(node_attrs)};"