Beispiel #1
0
    def test_RecolorGraph_1_empty(self):
        g = Graph()

        self.assertEqual(g.get_vert_count(), 0)
        self.assertEqual(g.get_edge_count(), 0)

        recolor(g)

        self.assertEqual(g.get_vert_count(), 0)
        self.assertEqual(g.get_edge_count(), 0)
Beispiel #2
0
    def test_RecolorGraph_4_black_star(self):
        g = Graph()

        g.add_vert(Vertex("center", "white"))
        # Spokes:
        g.add_vert(Vertex("1", "black"))
        g.add_vert(Vertex("2", "black"))
        g.add_vert(Vertex("3", "black"))
        g.add_vert(Vertex("4", "black"))
        g.add_vert(Vertex("5", "black"))
        g.add_vert(Vertex("6", "black"))
        g.add_vert(Vertex("7", "black"))
        g.add_vert(Vertex("8", "black"))

        g.add_edge("center", "1")
        g.add_edge("center", "2")
        g.add_edge("center", "3")
        g.add_edge("center", "4")
        g.add_edge("center", "5")
        g.add_edge("center", "6")
        g.add_edge("center", "7")
        g.add_edge("center", "8")

        # The center and the spokes will alternate colors on each recoloring.
        for i in range(100):
            central_color = None
            spoke_color = None

            recolor(g)

            if i % 2 == 0:
                central_color = "black"
                spoke_color = "white"
            else:
                central_color = "white"
                spoke_color = "black"

            self.assertTrue(g.get_vert("center").color == central_color)
            self.assertTrue(g.get_vert("1").color == spoke_color)
            self.assertTrue(g.get_vert("2").color == spoke_color)
            self.assertTrue(g.get_vert("3").color == spoke_color)
            self.assertTrue(g.get_vert("4").color == spoke_color)
            self.assertTrue(g.get_vert("5").color == spoke_color)
            self.assertTrue(g.get_vert("6").color == spoke_color)
            self.assertTrue(g.get_vert("7").color == spoke_color)
            self.assertTrue(g.get_vert("8").color == spoke_color)
Beispiel #3
0
    def test_RecolorGraph_3_all_white(self):
        g = Graph()

        g.add_vert(Vertex("1", "white"))
        g.add_vert(Vertex("2", "white"))
        g.add_vert(Vertex("3", "white"))
        g.add_vert(Vertex("4", "white"))
        g.add_vert(Vertex("5", "white"))
        g.add_vert(Vertex("6", "white"))
        g.add_vert(Vertex("7", "white"))

        g.add_edge("1", "2")
        g.add_edge("1", "3")
        g.add_edge("2", "3")
        g.add_edge("4", "3")
        g.add_edge("4", "5")
        g.add_edge("5", "6")
        g.add_edge("6", "7")

        self.assertTrue(g.get_vert("1").color == "white")
        self.assertTrue(g.get_vert("2").color == "white")
        self.assertTrue(g.get_vert("3").color == "white")
        self.assertTrue(g.get_vert("4").color == "white")
        self.assertTrue(g.get_vert("5").color == "white")
        self.assertTrue(g.get_vert("6").color == "white")
        self.assertTrue(g.get_vert("7").color == "white")

        recolor(g)

        self.assertTrue(g.get_vert("1").color == "white")
        self.assertTrue(g.get_vert("2").color == "white")
        self.assertTrue(g.get_vert("3").color == "white")
        self.assertTrue(g.get_vert("4").color == "white")
        self.assertTrue(g.get_vert("5").color == "white")
        self.assertTrue(g.get_vert("6").color == "white")
        self.assertTrue(g.get_vert("7").color == "white")
Beispiel #4
0
def clicked_vertex_or_go_or_turn_button(clickData, go_clicks, load_clicks, displayed_fig, k_curr, path, curr_turn):
    """
    This callback handles reaction to clicking:
        - a vertex in the graph
        - the "GO" button to advance the turn
        - the "Load" button to import a graph
    All three events are lumped together in this callback because all share
    Output("displayed-graph", "figure"), and an Output can only be assigned
    to one callback.
    """
    global loaded_hr_graph
    global clicked_verts_this_turn
    global node_positions

    ctx = dash.callback_context
    thing_clicked = ctx.triggered[0]["prop_id"].split(".")[0]

    k_nums = [int(i) for i in k_curr.split("/")]
    turn_num = int(curr_turn[6:])
    normal_k_color = {
        "display": "inline-block",
        "color": "black",
        "background": "white"
    }
    inverted_k_color = {
        "display": "inline-block",
        "color": "white",
        "background": "black"
    }
    ret_color = normal_k_color

    # Clicked graph vertex ###################################################
    if (thing_clicked == "displayed-graph") and (clickData is not None):
        clicked_vert_color = clickData["points"][0]["marker.color"]
        clicked_vert_id = clickData["points"][0]["text"]

        #############################
        # Flip clicked vertex color #
        #############################
        if clicked_vert_color == "black":
            new_color = "white"
        else:
            new_color = "black"

        displayed_fig["data"][0]["marker"]["color"][clickData["points"][0]["pointNumber"]] = new_color

        ####################
        # Update k readout #
        ####################
        if clicked_vert_id not in clicked_verts_this_turn:
            # If clicking this vertex for the first time (its id is not in
            # clicked_verts_this_turn), increment k
            # and store new_color (for reference when recoloring
            # loaded_hr_graph later)
            clicked_verts_this_turn[clicked_vert_id] = new_color
            if len(k_nums) == 1:
                # Still on first turn; k is shown as a single number with
                # no denominator.
                ret_str = f"{k_nums[0] + 1}"
            elif len(k_nums) == 2:
                # On turn 2 or greater; show k as n/d where n is the d from
                # previous turn and n is verts clicked this turn
                ret_str = f"{k_nums[0] + 1} / {k_nums[1]}"

                # Invert k background and color if n != d
                # (This serves as a visual aid so the user clicks the
                # same number of vertices each turn)
                if (k_nums[0] + 1) != k_nums[1]:
                    ret_color = inverted_k_color
                else:
                    ret_color = normal_k_color
        else:
            # If this vertex was already clicked (its id is already in
            # clicked_verts_this_turn), decrement k.
            clicked_verts_this_turn.pop(clicked_vert_id)
            if len(k_nums) == 1:
                ret_str = f"{k_nums[0] - 1}"
            elif len(k_nums) == 2:
                ret_str = f"{k_nums[0] - 1 } / {k_nums[1]}"

                if (k_nums[0] - 1) != k_nums[1]:
                    ret_color = inverted_k_color
                else:
                    ret_color = normal_k_color

        return displayed_fig, ret_str, ret_color, False, "", curr_turn
    # Clicked GO button ########################################################
    elif (thing_clicked == "go-button") and (go_clicks):
        ################################
        # Recolor graph and update fig #
        ################################
        for id in clicked_verts_this_turn.keys():
            loaded_hr_graph.get_vert(id).color = clicked_verts_this_turn[id]
        hr_logic.recolor(loaded_hr_graph)

        new_fig = figure_from_hr_graph(loaded_hr_graph)

        ####################
        # Update k readout #
        ####################
        clicked_verts_this_turn.clear()

        # Show n/d where n is 0 and d is n from previous turn
        if k_nums[0] == 0:
            ret_color = normal_k_color
        else:
            ret_color = inverted_k_color

        return new_fig, f"0 / {k_nums[0]}", ret_color, False, "", f"Turn: {turn_num + 1}"
    # Clicked Load button ######################################################
    elif (thing_clicked == "load-button") and (load_clicks):
        try:
            loaded_hr_graph = hr_io.load_graph(path)
        except Exception as e:
            return displayed_fig, k_curr, normal_k_color, True, repr(e), curr_turn

        node_positions = None # Wipe positions to regenerate for new graph
        new_fig = figure_from_hr_graph(loaded_hr_graph)

        return new_fig, k_curr, normal_k_color, False, "", "Turn: 0"
    # Nothing clicked; standard Dash trigger of all callbacks at startup #######
    else:
        return displayed_fig, k_curr, normal_k_color, False, "", curr_turn
Beispiel #5
0
    def test_RecolorGraph_0_normal(self):
        g = Graph()

        g.add_vert(Vertex("1", "white"))
        g.add_vert(Vertex("2", "white"))
        g.add_vert(Vertex("3", "black"))
        g.add_vert(Vertex("4", "white"))
        g.add_vert(Vertex("5", "white"))

        g.add_edge("1", "2")
        g.add_edge("1", "3")
        g.add_edge("3", "2")
        g.add_edge("4", "3")
        g.add_edge("5", "4")
        g.add_edge("5", "5")

        self.assertTrue(g.get_vert("1").color == "white")
        self.assertTrue(g.get_vert("2").color == "white")
        self.assertTrue(g.get_vert("3").color == "black")
        self.assertTrue(g.get_vert("4").color == "white")
        self.assertTrue(g.get_vert("5").color == "white")

        # print("Before recoloring:")
        # print_graph_colors(g)

        # After 4 recolorings, the entire graph should be black.

        recolor(g)  # 1

        # print("Recolor 1:")
        # print_graph_colors(g)

        self.assertTrue(g.get_vert("1").color == "black")
        self.assertTrue(g.get_vert("2").color == "black")
        self.assertTrue(g.get_vert("3").color == "white")
        self.assertTrue(g.get_vert("4").color == "black")
        self.assertTrue(g.get_vert("5").color == "white")

        recolor(g)  # 2

        # print("Recolor 2:")
        # print_graph_colors(g)

        self.assertTrue(g.get_vert("1").color == "black")
        self.assertTrue(g.get_vert("2").color == "black")
        self.assertTrue(g.get_vert("3").color == "black")
        self.assertTrue(g.get_vert("4").color == "white")
        self.assertTrue(g.get_vert("5").color == "black")  # Neighbor of self!

        recolor(g)  # 3

        # print("Recolor 3:")
        # print_graph_colors(g)

        self.assertTrue(g.get_vert("1").color == "black")
        self.assertTrue(g.get_vert("2").color == "black")
        self.assertTrue(g.get_vert("3").color == "black")
        self.assertTrue(g.get_vert("4").color == "black")
        self.assertTrue(g.get_vert("5").color == "black")  # So still black.

        recolor(g)  # 4

        # print("Recolor 4:")
        # print_graph_colors(g)

        self.assertTrue(g.get_vert("1").color == "black")
        self.assertTrue(g.get_vert("2").color == "black")
        self.assertTrue(g.get_vert("3").color == "black")
        self.assertTrue(g.get_vert("4").color == "black")
        self.assertTrue(g.get_vert("5").color == "black")