Beispiel #1
0
def test_add_node_to_empty_graph():
    graph = Graph()
    graph.add_node("Test")

    expected = {"Test": {}}
    output = graph.graph
    assert output == expected
Beispiel #2
0
def test_add_same_node_twice():
    graph = Graph()
    graph.add_node("Node_1")
    graph.add_node("Node_1")

    expected = {"Node_1": {}}
    output = graph.graph
    assert output == expected
Beispiel #3
0
 def test_get_weight(self):
     """
     Test getting the weight of an edge between two nodes.
     """
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     g.add_edge("A", "B", 123.45)
     self.assertEqual(g.get_weight("A", "B"), 123.45)
Beispiel #4
0
 def test_add_edge_invalid_end(self):
     """
     Test adding an edge where the end node does not exist.
     """
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     with self.assertRaises(ValueError) as context:
         g.add_edge("A", "C")
     self.assertIn("end", str(context.exception))
Beispiel #5
0
 def test_add_edge_with_value(self):
     """
     Test adding an edge to the graph.
     """
     correct = "{'A': {'B': 22.22}, 'B': {}}"
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     g.add_edge("A", "B", 22.22)
     self.assertEqual(str(g), correct)
Beispiel #6
0
 def test_add_edge_default(self):
     """
     Test adding an edge to the graph.
     """
     correct = "{'A': {'B': 0.0}, 'B': {}}"
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     g.add_edge("A", "B")
     self.assertEqual(str(g), correct)
Beispiel #7
0
 def test_repr(self):
     """
     Test the correctness of the __repr__ function.
     """
     correct = "{'A': {}, 'B': {}, 'C': {}}"
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     g.add_node("C")
     self.assertEqual(repr(g), correct)
Beispiel #8
0
 def test_add_weight_no_edge(self):
     """
     Test addting the weight of an edge that does not exist.
     """
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     with self.assertRaises(ValueError) as context:
         g.add_weight("A", "B", 1.51)
     self.assertIn("edge", str(context.exception))
Beispiel #9
0
 def test_add_weight_invalid_start(self):
     """
     Test addting the weight of an edge where the start node does not exist.
     """
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     with self.assertRaises(ValueError) as context:
         g.add_weight("C", "B", 20.00)
     self.assertIn("start", str(context.exception))
Beispiel #10
0
 def test_set_weight_invalid_end(self):
     """
     Test setting the weight of an edge where the end node does not exist.
     """
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     with self.assertRaises(ValueError) as context:
         g.set_weight("A", "C", 44.43)
     self.assertIn("end", str(context.exception))
Beispiel #11
0
 def test_add_node_duplicate(self):
     """
     Test that an exception is thrown when adding two nodes with the same
     name.
     """
     g = Graph()
     self.assertEqual(g.size(), 0)
     g.add_node("A")
     with self.assertRaises(ValueError):
         g.add_node("A")
Beispiel #12
0
 def test_add_node_str(self):
     """
     Test the success of adding a new node to the graph using
     the string representation of the graph.
     """
     correct = "{'A': {}, 'B': {}, 'C': {}}"
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     g.add_node("C")
     self.assertEqual(str(g), correct)
Beispiel #13
0
 def test_add_weight(self):
     """
     Test updating the weight of an edge between two nodes.
     """
     correct = "{'A': {'B': 3.14}, 'B': {}}"
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     g.add_edge("A", "B")
     g.add_weight("A", "B", 3.14)
     self.assertEqual(str(g), correct)
Beispiel #14
0
 def test_add_node_size(self):
     """
     Test the success of adding a new node to the graph using the size
     of the graph.
     """
     g = Graph()
     self.assertEqual(g.size(), 0)
     g.add_node("A")
     self.assertEqual(g.size(), 1)
     g.add_node("B")
     self.assertEqual(g.size(), 2)
Beispiel #15
0
 def test_getitem(self):
     """
     Test using the __getitem__ method which is accessed using [].
     """
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     g.add_node("C")
     g.add_edge("B", "C", 1.0)
     g.add_edge("B", "A", 2.0)
     g.add_edge("A", "C")
     self.assertEqual(str(g["A"]), "{'C': 0.0}")
     self.assertEqual(str(g["B"]), "{'C': 1.0, 'A': 2.0}")
     self.assertEqual(str(g["C"]), "{}")
Beispiel #16
0
def random_int_graph(n=5, max_degree=5):
    g = Graph()
    alphabet = [i for i in range(n + 1)]
    r = random.choice(alphabet)
    g.add_node(r)
    alphabet.remove(r)

    while n > 0:
        a = random.choice(alphabet)
        alphabet.remove(a)
        b = random.choice(list(g.graph.keys()))
        g.add_edge(a, b)
        n -= 1
        continue
    return g
Beispiel #17
0
 def test_iter(self):
     """
     Test iteration over the graph. This should iterate over the nodes
     of the graph.
     """
     g = Graph()
     g.add_node("A")
     g.add_node("B")
     g.add_node("C")
     g.add_node("D")
     i = iter(g)
     self.assertEqual(next(i), "A")
     self.assertEqual(next(i), "B")
     self.assertEqual(next(i), "C")
     self.assertEqual(next(i), "D")
Beispiel #18
0
def test_create_graph_basic():
    '''
    test the basic creation api, along a happy path
    '''
    g = Graph()

    assert g.add_node('a')
    assert g.add_node('b')
    assert g.add_node('c')

    # import ipdb; ipdb.set_trace()
    assert g.contains('a')
    assert g.contains('b')
    assert g.contains('c')

    nodes = list(g.nodes())
    assert 'a' in nodes
    assert 'b' in nodes
    assert 'c' in nodes

    g.add_edge('a', 'b')
    g.add_edge('a', 'c')

    edges = list(g.edges())
    assert len(
        edges) == 4  # "undirected" graph, must have edges both ways both times
    assert ('a', 'b', 1) in edges
    assert ('b', 'a', 1) in edges
    assert ('a', 'c', 1) in edges
    assert ('c', 'a', 1) in edges

    a_neigh = list(g.neighbors('a'))
    assert len(a_neigh) == 2
    assert ('b', 1) in a_neigh
    assert ('c', 1) in a_neigh

    b_neigh = list(g.neighbors('b'))
    assert len(b_neigh) == 1
    assert ('a', 1) in b_neigh

    c_neigh = list(g.neighbors('c'))
    assert len(c_neigh) == 1
    assert ('a', 1) in c_neigh
Beispiel #19
0
def test_add_node_different_types_multiple():
    graph = Graph()
    graph.add_node("Node_1")
    graph.add_node(1)
    graph.add_node(2.3456)

    expected = {"Node_1": {}, 1: {}, 2.3456: {}}
    output = graph.graph
    assert output == expected
Beispiel #20
0
class EvenSplit():
    """
    The EvenSplit class contains the code which handles adding people,
    transactions, and reducing the graph into the minimum number of
    transactions.
    """
    def __init__(self):
        """
        Construct a new EvenSplit instance.
        """
        self.graph = Graph()

    def __str__(self):
        """
        Return a string form of the EvenSplit object. This is the same as
        using the internal graph's __str__ function.
        """
        return str(self.graph)

    def __repr__(self):
        """
        Return a human-readable string form of the EvenSplit object. This is
        the same as using the internal graph's __repr__ function.
        """
        return repr(self.graph)

    def add_person(self, name: str):
        """
        Add a new person to the EvenSplit object. This adds a new node for the
        given name and connects it to all other nodes within the graph,
        excluding itself.
        """
        if name is None:
            raise ValueError("Name cannot be None!")
        self.graph.add_node(name)
        for person in self.graph:
            if person != name:
                self.graph.add_edge(name, person)
                self.graph.add_edge(person, name)

    def add_transaction(self, name: str, amount: float):
        """
        Add a transaction and evenly split the amount across all people.
        """
        split_amount = amount / self.count()
        for person in self.graph:
            if person != name:
                self.graph.add_weight(person, name, split_amount)

    def count(self):
        """
        Return the number of people in the graph.
        """
        return self.graph.size()

    def read(self, i: IO[str] = stdin):
        """
        Read in the people and their transactions and construct the graph
        with the input.
        """
        num_users = int(next(i))
        for _ in range(num_users):
            self.add_person(next(i).strip())

        num_transactions = int(next(i))
        for _ in range(num_transactions):
            line = next(i).split()
            self.add_transaction(line[0], float(line[1]))

    def print(self, out: IO[str] = stdout):
        """
        Print the state of the split as transactions from one
        person to another.
        """
        out.write("Here's how to get even:\n")
        for person in self.graph:
            for other in self.graph[person]:
                amount = "${:,.2f}".format(self.graph[person][other])
                out.write(person + " pays " + other + " " + amount + "\n")