      "            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)"
     ]
    },
    {
     "cell_type": "code",
     "execution_count": 2,
 
</s> remove     def add_undirected_edge(self, source_key, dest_key, weight=0):
        if source_key is None or dest_key is None:
            raise Exception('Invalid key')
        self.add_edge(source_key, dest_key, weight)
        self.nodes[dest_key].add_neighbor(self.nodes[source_key],
                                          weight) </s> add  </s> remove     "        if neighbor is None:\n",
    "            raise Exception('Invalid neighbor')\n",
 </s> add     "        if neighbor is None or weight is None:\n",
    "            raise TypeError('neighbor or weight cannot be None')\n", </s> remove     "            raise Exception('Invalid key')\n",
 </s> add     "            raise TypeError('key cannot be None')\n", </s> remove     "        if neighbor is None or neighbor.key not in self.adj_nodes:\n",
    "            raise Exception('Invalid neighbor')\n",
 </s> add     "        if neighbor is None:\n",
    "            raise TypeError('neighbor cannot be None')\n",
    "        if neighbor.key not in self.adj_nodes:\n",
    "            raise KeyError('neighbor not found')\n",
    "    def add_undirected_edge(self, src_key, dst_key, weight=0):\n",
    "        if src_key is None or dst_key is None:\n",
    "            raise TypeError('key cannot be None')\n",
    "        self.add_edge(src_key, dst_key, weight)\n",
    "        self.add_edge(dst_key, src_key, weight)"
      "            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, src_key, dst_key, weight=0):\n",
    "        if src_key is None or dst_key is None:\n",
    "            raise TypeError('key cannot be None')\n",
    "        self.add_edge(src_key, dst_key, weight)\n",
    "        self.add_edge(dst_key, src_key, weight)"
    "    def add_undirected_edge(self, src_key, dst_key, weight=0):\n",
    "        if src_key is None or dst_key is None:\n",
    "            raise TypeError('key cannot be None')\n",
    "        self.add_edge(src_key, dst_key, weight)\n",
    "        self.add_edge(dst_key, src_key, weight)"
    "    def add_undirected_edge(self, src_key, dst_key, weight=0):\n",
    "        if src_key is None or dst_key is None:\n",
    "            raise TypeError('key cannot be None')\n",
    "        self.add_edge(src_key, dst_key, weight)\n",
    "        self.add_edge(dst_key, src_key, weight)"
    "    def add_undirected_edge(self, src_key, dst_key, weight=0):\n",
    "        if src_key is None or dst_key is None:\n",
    "            raise TypeError('key cannot be None')\n",
    "        self.add_edge(src_key, dst_key, weight)\n",
    "        self.add_edge(dst_key, src_key, weight)"
    "    def add_undirected_edge(self, src_key, dst_key, weight=0):\n",
    "        if src_key is None or dst_key is None:\n",
    "            raise TypeError('key cannot be None')\n",
    "        self.add_edge(src_key, dst_key, weight)\n",
    "        self.add_edge(dst_key, src_key, weight)"
    "    def add_undirected_edge(self, src_key, dst_key, weight=0):\n",
    "        if src_key is None or dst_key is None:\n",
    "            raise TypeError('key cannot be None')\n",
    "        self.add_edge(src_key, dst_key, weight)\n",
    "        self.add_edge(dst_key, src_key, weight)"
     ]
    },
    {
     "cell_type": "code",
     "execution_count": 2,
keep keep keep keep replace replace replace replace replace replace keep keep keep keep keep
 Update graph challenge (#117)

Use more specific exception types. Update constraints. Update add_undirected_edge to use add_edge. 
graphs_trees/graph/graph_solution.ipynb