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)
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)
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")
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
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")