     },
     "outputs": [],
     "source": [
      "class Node:\n",
      "\n",
      "    def __init__(self, key):\n",
      "        self.key = key\n",
 
</s> remove     "    def __init__(self, id):\n",
    "        # TODO: Implement me\n",
    "        self.adjacent = {}  # key = node, val = weight\n",
 </s> add     "    def __init__(self, key):\n",
    "        self.key = key\n",
    "        self.visit_state = State.unvisited\n",
    "        self.incoming_edges = 0\n",
    "        self.adj_nodes = {}  # Key = key, val = Node\n",
    "        self.adj_weights = {}  # Key = Node, val = weight\n", </s> remove     "    def __init__(self, id):\n",
    "        self.id = id\n",
 </s> add     "    def __init__(self, key):\n",
    "        self.key = key\n", </s> remove     "        self.nodes = {}  # key = node id, val = node\n",
    "\n",
    "    def add_node(self, id):\n",
    "        node = Node(id)\n",
    "        self.nodes[id] = node\n",
    "        return node\n",
    "\n",
    "    def add_edge(self, id_source, id_dest, weight=0):\n",
    "        if id_source not in self.nodes:\n",
    "            self.add_node(id_source)\n",
    "        if id_dest not in self.nodes:\n",
    "            self.add_node(id_dest)\n",
    "        self.nodes[id_source].add_neighbor(self.nodes[id_dest], weight)\n",
    "\n",
    "    def add_undirected_edge(self, source, dest, weight=0):\n",
    "        self.add_edge(source, dest, weight)\n",
    "        self.nodes[dest].add_neighbor(self.nodes[source], weight)"
 </s> add     "        self.nodes = {}  # Key = key, val = Node\n",
    "\n",
    "    def add_node(self, key):\n",
    "        if key is None:\n",
    "            raise Exception('Invalid key')\n",
    "        if key in self.nodes:\n",
    "            return self.nodes[key]\n",
    "        self.nodes[key] = Node(key)\n",
    "        return self.nodes[key]\n",
    "\n",
    "    def add_edge(self, source_key, dest_key, weight=0):\n",
    "        if source_key is None or dest_key is None:\n",
    "            raise Exception('Invalid key')\n",
    "        if source_key not in self.nodes:\n",
    "            self.add_node(source_key)\n",
    "        if dest_key not in self.nodes:\n",
    "            self.add_node(dest_key)\n",
    "        self.nodes[source_key].add_neighbor(self.nodes[dest_key],\n",
    "                                            weight)\n",
    "\n",
    "    def add_undirected_edge(self, source_key, dest_key, weight=0):\n",
    "        if source_key is None or dest_key is None:\n",
    "            raise Exception('Invalid key')\n",
    "        self.add_edge(source_key, dest_key, weight)\n",
    "        self.nodes[dest_key].add_neighbor(self.nodes[source_key],\n",
    "                                          weight)" </s> remove     "    def __str__(self):\n",
    "        return str(self.id)\n",
 </s> add     "    def __lt__(self, other):\n",
    "        return self.key < other.key\n", </s> remove     "    def __str__(self):\n",
 </s> add     "    def __repr__(self):\n",
    "from enum import Enum  # Python 2 users: Run pip install enum34\n",
    "\n",
    "\n",
    "class State(Enum):\n",
    "    unvisited = 0\n",
    "    visiting = 1\n",
    "    visited = 2\n",
    "\n",
    "\n",
     },
     "outputs": [],
     "source": [
    "from enum import Enum  # Python 2 users: Run pip install enum34\n",
    "\n",
    "\n",
    "class State(Enum):\n",
    "    unvisited = 0\n",
    "    visiting = 1\n",
    "    visited = 2\n",
    "\n",
    "\n",
      "class Node:\n",
      "\n",
      "    def __init__(self, key):\n",
      "        self.key = key\n",
keep keep add keep keep keep keep
 Rework graph challenge and solution (#90) 
graphs_trees/graph/graph_challenge.ipynb