Graph.py 3.18 KiB
# -*- coding: utf-8 -*-

from functools import reduce

from Model.Network.Node import Node
from Model.Network.Edge import Edge

class Graph(object):
    def __init__(self):
        super(Graph, self).__init__()

        self._node_ctor = Node
        self._edge_ctor = Edge

        self._nodes_ids = 0
        self._edges_ids = 0

        self._nodes = []
        self._edges = []

    def __repr__(self):
        return f"Graph {{nodes: {self._nodes}, edges: {self._edges}}}"

    def nodes(self):
        return self._nodes

    def nodes_names(self):
        return list(map(lambda n: n.name, self._nodes))

    def edges(self):
        return self._edges

    def nodes_counts(self):
        return len(self._nodes)

    def edges_counts(self):
        return len(self._edges)

    def is_node_exists(self, node_name):
        return reduce(
            lambda acc, n: (acc or (n.name == node_name)),
            self._nodes,
            False
        )

    def is_edge_exists(self, edge_name):
        return reduce(
            lambda acc, e: (acc or (e.name == edge_name)),
            self._edges,
            False
        )

    def node(self, node_name:str):
        return list(
            filter(
                lambda n: n.name == node_name,
                self._nodes
            )
        )[0]

    def _add_node(self, node):
        self._nodes.append(node)
        self._nodes_ids += 1
        return node

    def add_node(self, x:float = 0.0, y:float = 0.0):
        node = self._node_ctor(
            self._nodes_ids,
            f"Node {self._nodes_ids}",
            x = x, y = y
        )
        return self._add_node(node)

    def _add_edge(self, edge):
        # This edge already exists ?
        if any(filter(lambda e: (e.node1 == edge.node1 and
                                 e.node2 == edge.node2),
                      self._edges)):
            return None

        self._edges.append(edge)
        self._edges_ids += 1
        return edge

    def add_edge(self, n1:Node, n2:Node):
        edge = self._edge_ctor(self._edges_ids, "", n1, n2)
        return self._add_edge(edge)

    def remove_node(self, node_name:str):
        self._nodes = list(
            filter(
                lambda n: n.name != node_name,
                self._nodes
            )
        )

    def remove_edge(self, edge_name:str):
        self._edges = list(
            filter(
                lambda e: e.name != edge_name,
                self._edges
            )
        )

    def is_upstream_node(self, node):
        return reduce(
            lambda acc, e: (acc and (e.node2 != node or not e.enable)),
            self._edges,
            True
        )

    def is_downstream_node(self, node):
        return reduce(
            lambda acc, e: (acc and (e.node1 != node or not e.enable)),
            self._edges,
            True
        )

    def is_enable_node(self, node):
        return reduce(
            lambda acc, e: (
                acc or (
                    (e.node1 == node or
                     e.node2 == node)
                    and e.enable
                )
            ),
            self._edges,
            False
        )

    def is_enable_edge(self, edge):
        return edge.enable