summaryrefslogtreecommitdiff
path: root/Data_Structures_and_Algorithms_in_Java/ch14.ipynb
diff options
context:
space:
mode:
Diffstat (limited to 'Data_Structures_and_Algorithms_in_Java/ch14.ipynb')
-rw-r--r--Data_Structures_and_Algorithms_in_Java/ch14.ipynb314
1 files changed, 306 insertions, 8 deletions
diff --git a/Data_Structures_and_Algorithms_in_Java/ch14.ipynb b/Data_Structures_and_Algorithms_in_Java/ch14.ipynb
index 7895bf4f..46aa59dc 100644
--- a/Data_Structures_and_Algorithms_in_Java/ch14.ipynb
+++ b/Data_Structures_and_Algorithms_in_Java/ch14.ipynb
@@ -1,6 +1,7 @@
{
"metadata": {
- "name": "ch14"
+ "name": "",
+ "signature": "sha256:2dd04a4aee1b7409691d218147433fe56bcbf7998733e71f7ca224eaa4cea307"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -11,18 +12,174 @@
"cell_type": "heading",
"level": 1,
"metadata": {},
- "source": "Chapter 14 : Weighted Graphs"
+ "source": [
+ "Chapter 14 : Weighted Graphs"
+ ]
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
- "source": "Example 14.1 Page no: 681"
+ "source": [
+ "Example 14.1 Page no: 681"
+ ]
},
{
"cell_type": "code",
"collapsed": false,
- "input": "'''\nexample 14.1\ndemonstrates minimum spanning tree with weighted graphs\n'''\nclass Edge:\n def __init__(self,sv,dv,d): # constructor\n self.srcVert = sv\n self.destVert = dv\n self.distance = d\n\nclass PriorityQ:\n def __init__(self):\n # constructor\n self.queArray = []\n self.size = 0\n def insert(self,item): # insert item in sorted order\n self.queArray.append(item)\n b = self.size\n for j in range(self.size): # find place to insert\n if( item.distance >= self.queArray[j].distance ):\n b = j\n break\n for k in range(self.size-1,b-1,-1):#=self.size-1 k>=j k--) # move items up\n self.queArray[k+1] = self.queArray[k]\n self.queArray[b] = item\n # insert item\n self.size += 1\n\n def removeMin(self): # remove minimum item\n self.size -= 1\n return self.queArray[self.size] \n\n def removeN(self,n): # remove item at n\n for j in range(n,self.size-1): # move items down\n self.queArray[j] = self.queArray[j+1]\n self.size -= 1\n\n def peekMin(self): # peek at minimum item\n return self.self.queArray[self.size-1] \n\n def size(self): # return number of items\n return self.size\n\n def isEmpty(self): # true if queue is empty\n return (self.size==0) \n\n def peekN(self,n): # peek at item n\n return self.queArray[n]\n\n def find(self,findDex): # find item with specified\n # self.destVert value\n for j in range(self.size-1):\n if(self.queArray[j].destVert == findDex):\n return j\n return -1\n\nclass Vertex:\n def __init__(self,lab): # constructor\n self.label = lab\n self.isInTree = False\n\nclass Graph:\n def __init__(self):\n self.vertexList = [] # adjacency matrix\n self.adjMat = []\n self.nVerts = 0\n for j in range(20): # set adjacency\n l = []\n for k in range(20):\n l.append(1000000)\n self.adjMat.append(l)\n self.thePQ = PriorityQ()\n self.nTree = 0\n self.currentVert = 0\n\n def addVertex(self,lab):\n self.vertexList.append( Vertex(lab))\n self.nVerts += 1\n\n def addEdge(self,start, end,weight):\n self.adjMat[start][end] = weight\n self.adjMat[end][start] = weight\n\n\n def displayVertex(self,v):\n print self.vertexList[v].label ,\n\n def mstw(self):\n self.currentVert = 0 # minimum spanning tree\n # start at 0\n while(self.nTree < self.nVerts-1): # while not all verts in tree\n # put self.currentVert in tree\n self.vertexList[self.currentVert].isInTree = True\n self.nTree += 1\n # insert edges adjacent to self.currentVert into PQ\n for j in range(self.nVerts): # for each vertex,\n if(j==self.currentVert): # skip if its us\n continue\n if(self.vertexList[j].isInTree): # skip if in the tree\n continue\n self.distance = self.adjMat[self.currentVert][j]\n if( self.distance == 1000000): # skip if no edge\n continue\n self.putInPQ(j, self.distance) # put it in PQ (maybe)\n if(self.thePQ.size==0): # no vertices in PQ?\n print 'GRAPH NOT CONNECTED',\n return\n # remove edge with minimum self.distance, from PQ\n theEdge = self.thePQ.removeMin()\n sourceVert = theEdge.srcVert\n self.currentVert = theEdge.destVert\n # display edge from source to current\n print self.vertexList[sourceVert].label ,self.vertexList[self.currentVert].label, \" \",\n\n for j in range(self.nVerts): # unmark vertices\n self.vertexList[j].isIsTree = False\n\n def putInPQ(self,newVert,newDist): # is there another edge with the same destination vertex?\n queueIndex = self.thePQ.find(newVert)\n if(queueIndex != -1): # got edges index\n tempEdge = self.thePQ.peekN(queueIndex) # get edge\n oldDist = tempEdge.distance\n if(oldDist > newDist): # if new edge shorter,\n self.thePQ.removeN(queueIndex) # remove old edge\n theEdge = Edge(self.currentVert, newVert, newDist)\n self.thePQ.insert(theEdge)# insert new edge\n # else no action just leave the old vertex there\n else: # no edge with same destination vertex\n # so insert new one\n theEdge = Edge(self.currentVert, newVert, newDist)\n self.thePQ.insert(theEdge)\n\n\ntheGraph = Graph()\ntheGraph.addVertex('A') # 0 (start for mst)\ntheGraph.addVertex('B') # 1\ntheGraph.addVertex('C') # 2\ntheGraph.addVertex('D') # 3\ntheGraph.addVertex('E') # 4\ntheGraph.addVertex('F') # 5\ntheGraph.addEdge(0, 1, 16) # AB\ntheGraph.addEdge(0, 3, 24) # AD\n\ntheGraph.addEdge(1,2,1)\ntheGraph.addEdge(1,3,5)\ntheGraph.addEdge(1,4,2)\ntheGraph.addEdge(2,3,6)\ntheGraph.addEdge(2,4,8)\ntheGraph.addEdge(2,5,26)\ntheGraph.addEdge(3,4,142)\ntheGraph.addEdge(4,5,17)\n\nprint 'Minimum spanning tree: ',\ntheGraph.mstw() # minimum spanning tree",
+ "input": [
+ " \n",
+ "class Edge:\n",
+ " def __init__(self,sv,dv,d): # constructor\n",
+ " self.srcVert = sv\n",
+ " self.destVert = dv\n",
+ " self.distance = d\n",
+ "\n",
+ "class PriorityQ:\n",
+ " def __init__(self):\n",
+ " # constructor\n",
+ " self.queArray = []\n",
+ " self.size = 0\n",
+ " def insert(self,item): # insert item in sorted order\n",
+ " self.queArray.append(item)\n",
+ " b = self.size\n",
+ " for j in range(self.size): # find place to insert\n",
+ " if( item.distance >= self.queArray[j].distance ):\n",
+ " b = j\n",
+ " break\n",
+ " for k in range(self.size-1,b-1,-1):#=self.size-1 k>=j k--) # move items up\n",
+ " self.queArray[k+1] = self.queArray[k]\n",
+ " self.queArray[b] = item\n",
+ " # insert item\n",
+ " self.size += 1\n",
+ "\n",
+ " def removeMin(self): # remove minimum item\n",
+ " self.size -= 1\n",
+ " return self.queArray[self.size] \n",
+ "\n",
+ " def removeN(self,n): # remove item at n\n",
+ " for j in range(n,self.size-1): # move items down\n",
+ " self.queArray[j] = self.queArray[j+1]\n",
+ " self.size -= 1\n",
+ "\n",
+ " def peekMin(self): # peek at minimum item\n",
+ " return self.self.queArray[self.size-1] \n",
+ "\n",
+ " def size(self): # return number of items\n",
+ " return self.size\n",
+ "\n",
+ " def isEmpty(self): # true if queue is empty\n",
+ " return (self.size==0) \n",
+ "\n",
+ " def peekN(self,n): # peek at item n\n",
+ " return self.queArray[n]\n",
+ "\n",
+ " def find(self,findDex): # find item with specified\n",
+ " # self.destVert value\n",
+ " for j in range(self.size-1):\n",
+ " if(self.queArray[j].destVert == findDex):\n",
+ " return j\n",
+ " return -1\n",
+ "\n",
+ "class Vertex:\n",
+ " def __init__(self,lab): # constructor\n",
+ " self.label = lab\n",
+ " self.isInTree = False\n",
+ "\n",
+ "class Graph:\n",
+ " def __init__(self):\n",
+ " self.vertexList = [] # adjacency matrix\n",
+ " self.adjMat = []\n",
+ " self.nVerts = 0\n",
+ " for j in range(20): # set adjacency\n",
+ " l = []\n",
+ " for k in range(20):\n",
+ " l.append(1000000)\n",
+ " self.adjMat.append(l)\n",
+ " self.thePQ = PriorityQ()\n",
+ " self.nTree = 0\n",
+ " self.currentVert = 0\n",
+ "\n",
+ " def addVertex(self,lab):\n",
+ " self.vertexList.append( Vertex(lab))\n",
+ " self.nVerts += 1\n",
+ "\n",
+ " def addEdge(self,start, end,weight):\n",
+ " self.adjMat[start][end] = weight\n",
+ " self.adjMat[end][start] = weight\n",
+ "\n",
+ "\n",
+ " def displayVertex(self,v):\n",
+ " print self.vertexList[v].label ,\n",
+ "\n",
+ " def mstw(self):\n",
+ " self.currentVert = 0 # minimum spanning tree\n",
+ " # start at 0\n",
+ " while(self.nTree < self.nVerts-1): # while not all verts in tree\n",
+ " # put self.currentVert in tree\n",
+ " self.vertexList[self.currentVert].isInTree = True\n",
+ " self.nTree += 1\n",
+ " # insert edges adjacent to self.currentVert into PQ\n",
+ " for j in range(self.nVerts): # for each vertex,\n",
+ " if(j==self.currentVert): # skip if its us\n",
+ " continue\n",
+ " if(self.vertexList[j].isInTree): # skip if in the tree\n",
+ " continue\n",
+ " self.distance = self.adjMat[self.currentVert][j]\n",
+ " if( self.distance == 1000000): # skip if no edge\n",
+ " continue\n",
+ " self.putInPQ(j, self.distance) # put it in PQ (maybe)\n",
+ " if(self.thePQ.size==0): # no vertices in PQ?\n",
+ " print 'GRAPH NOT CONNECTED',\n",
+ " return\n",
+ " # remove edge with minimum self.distance, from PQ\n",
+ " theEdge = self.thePQ.removeMin()\n",
+ " sourceVert = theEdge.srcVert\n",
+ " self.currentVert = theEdge.destVert\n",
+ " # display edge from source to current\n",
+ " print self.vertexList[sourceVert].label ,self.vertexList[self.currentVert].label, \" \",\n",
+ "\n",
+ " for j in range(self.nVerts): # unmark vertices\n",
+ " self.vertexList[j].isIsTree = False\n",
+ "\n",
+ " def putInPQ(self,newVert,newDist): # is there another edge with the same destination vertex?\n",
+ " queueIndex = self.thePQ.find(newVert)\n",
+ " if(queueIndex != -1): # got edges index\n",
+ " tempEdge = self.thePQ.peekN(queueIndex) # get edge\n",
+ " oldDist = tempEdge.distance\n",
+ " if(oldDist > newDist): # if new edge shorter,\n",
+ " self.thePQ.removeN(queueIndex) # remove old edge\n",
+ " theEdge = Edge(self.currentVert, newVert, newDist)\n",
+ " self.thePQ.insert(theEdge)# insert new edge\n",
+ " # else no action just leave the old vertex there\n",
+ " else: # no edge with same destination vertex\n",
+ " # so insert new one\n",
+ " theEdge = Edge(self.currentVert, newVert, newDist)\n",
+ " self.thePQ.insert(theEdge)\n",
+ "\n",
+ "\n",
+ "theGraph = Graph()\n",
+ "theGraph.addVertex('A') # 0 (start for mst)\n",
+ "theGraph.addVertex('B') # 1\n",
+ "theGraph.addVertex('C') # 2\n",
+ "theGraph.addVertex('D') # 3\n",
+ "theGraph.addVertex('E') # 4\n",
+ "theGraph.addVertex('F') # 5\n",
+ "theGraph.addEdge(0, 1, 16) # AB\n",
+ "theGraph.addEdge(0, 3, 24) # AD\n",
+ "\n",
+ "theGraph.addEdge(1,2,1)\n",
+ "theGraph.addEdge(1,3,5)\n",
+ "theGraph.addEdge(1,4,2)\n",
+ "theGraph.addEdge(2,3,6)\n",
+ "theGraph.addEdge(2,4,8)\n",
+ "theGraph.addEdge(2,5,26)\n",
+ "theGraph.addEdge(3,4,142)\n",
+ "theGraph.addEdge(4,5,17)\n",
+ "\n",
+ "print 'Minimum spanning tree: ',\n",
+ "theGraph.mstw() # minimum spanning tree"
+ ],
"language": "python",
"metadata": {},
"outputs": []
@@ -31,19 +188,160 @@
"cell_type": "heading",
"level": 3,
"metadata": {},
- "source": "Example 14.2 Page 703"
+ "source": [
+ "Example 14.2 Page 703"
+ ]
},
{
"cell_type": "code",
"collapsed": false,
- "input": "'''\nexample 14.2\ndemonstrates shortest path with weighted, directed graphs\n'''\nclass DistPar:\n def __init__(self,pv,d): # constructor\n self.distance = d\n self.parentVert = pv\n\nclass Vertex:\n def __init__(self,lab): # constructor\n self.label = lab\n self.isInTree = False\n\nclass Graph:\n def __init__(self): # constructor\n self.vertexList = [] # adjacency matrix\n self.adjMat = []\n self.nVerts = 0\n self.nTree = 0\n for j in range(20): # set adjacency\n l = []\n for k in range(20):\n l.append(1000000)\n self.adjMat.append(l)\n self.currentVert = 0\n self.sPath = [] # shortest paths\n self.startToCurrent = 0\n\n def addVertex(self,lab):\n self.vertexList.append( Vertex(lab))\n self.nVerts += 1\n\n def addEdge(self,start, end,weight):\n self.adjMat[start][end] = weight\n\n\n def displayVertex(self,v):\n print self.vertexList[v].label ,\n\n def path(self): # find all shortest paths\n startTree = 0 # start at vertex 0\n self.vertexList[startTree].isInTree = True\n self.nTree = 1 # put it in tree\n # transfer row of distances from adjMat to sPath\n for j in range(self.nVerts):\n tempDist = self.adjMat[startTree][j]\n try:\n self.sPath[j] = DistPar(startTree, tempDist)\n except:\n self.sPath.append(DistPar(startTree, tempDist))\n # until all vertices are in the tree\n while(self.nTree < self.nVerts):\n indexMin = self.getMin() # get minimum from sPath\n minDist = self.sPath[indexMin].distance\n if(minDist == 1000000): # if all infinite\n # or in tree,\n print 'There are unreachable vertices'\n break # sPath is complete\n else:\n # reset self.currentVert\n self.currentVert = indexMin # to closest vert\n self.startToCurrent = self.sPath[indexMin].distance\n # minimum distance from startTree is\n # to self.currentVert, and is self.startToCurrent\n # put current vertex in tree\n self.vertexList[self.currentVert].isInTree = True\n self.nTree += 1\n self.adjust_sPath() # update sPath[] array\n\n self.displayPaths() # display sPath[] contents\n self.nTree = 0 # clear tree\n for j in range(self.nVerts):\n self.vertexList[j].isInTree = False \n\n def getMin(self): # get entry from sPath\n minDist = 1000000 # assume minimum\n indexMin = 0\n for j in range(self.nVerts): # for each vertex,\n # if its in tree and\n if( not self.vertexList[j].isInTree and self.sPath[j].distance < minDist ):\n minDist = self.sPath[j].distance\n indexMin = j # update minimum\n return indexMin\n\n def adjust_sPath(self):\n # adjust values in shortest-path array sPath\n column = 1\n # skip starting vertex\n while(column < self.nVerts): # go across columns\n # if this columns vertex already in tree, skip it\n if( self.vertexList[column].isInTree ):\n column += 1\n continue\n # calculate distance for one sPath entry get edge from self.currentVert to column\n currentToFringe = self.adjMat[self.currentVert][column]\n # add distance from start\n startToFringe = self.startToCurrent + currentToFringe\n # get distance of current sPath entry\n sPathDist = self.sPath[column].distance\n # compare distance from start with sPath entry\n if(startToFringe < sPathDist): # if shorter,\n # update sPath\n self.sPath[column].parentVert = self.currentVert\n self.sPath[column].distance = startToFringe\n column += 1\n\n def displayPaths(self):\n for j in range(self.nVerts): # display contents of sPath[]\n print self.vertexList[j].label ,' =' \n if(self.sPath[j].distance == 1000000):\n print 'inf', # inf\n else:\n print self.sPath[j].distance , # 50\n parent = self.vertexList[ self.sPath[j].parentVert ].label\n print '(' , parent , ')' , # (A)\n print ''\n \ntheGraph = Graph()\ntheGraph.addVertex('A') # 0 (start)\ntheGraph.addVertex('C') # 2\ntheGraph.addVertex('B') # 1\ntheGraph.addVertex('D') # 3\ntheGraph.addVertex('E') # 4\ntheGraph.addEdge(0,1,50)\ntheGraph.addEdge(0,3,80)\ntheGraph.addEdge(1,2,60)\ntheGraph.addEdge(1,3,90)\ntheGraph.addEdge(2,4,40)\ntheGraph.addEdge(3,2,20)\ntheGraph.addEdge(3,4,70)\ntheGraph.addEdge(4,1,50)\nprint 'Shortest paths' ,\ntheGraph.path() # shortest paths",
+ "input": [
+ " \n",
+ "class DistPar:\n",
+ " def __init__(self,pv,d): # constructor\n",
+ " self.distance = d\n",
+ " self.parentVert = pv\n",
+ "\n",
+ "class Vertex:\n",
+ " def __init__(self,lab): # constructor\n",
+ " self.label = lab\n",
+ " self.isInTree = False\n",
+ "\n",
+ "class Graph:\n",
+ " def __init__(self): # constructor\n",
+ " self.vertexList = [] # adjacency matrix\n",
+ " self.adjMat = []\n",
+ " self.nVerts = 0\n",
+ " self.nTree = 0\n",
+ " for j in range(20): # set adjacency\n",
+ " l = []\n",
+ " for k in range(20):\n",
+ " l.append(1000000)\n",
+ " self.adjMat.append(l)\n",
+ " self.currentVert = 0\n",
+ " self.sPath = [] # shortest paths\n",
+ " self.startToCurrent = 0\n",
+ "\n",
+ " def addVertex(self,lab):\n",
+ " self.vertexList.append( Vertex(lab))\n",
+ " self.nVerts += 1\n",
+ "\n",
+ " def addEdge(self,start, end,weight):\n",
+ " self.adjMat[start][end] = weight\n",
+ "\n",
+ "\n",
+ " def displayVertex(self,v):\n",
+ " print self.vertexList[v].label ,\n",
+ "\n",
+ " def path(self): # find all shortest paths\n",
+ " startTree = 0 # start at vertex 0\n",
+ " self.vertexList[startTree].isInTree = True\n",
+ " self.nTree = 1 # put it in tree\n",
+ " # transfer row of distances from adjMat to sPath\n",
+ " for j in range(self.nVerts):\n",
+ " tempDist = self.adjMat[startTree][j]\n",
+ " try:\n",
+ " self.sPath[j] = DistPar(startTree, tempDist)\n",
+ " except:\n",
+ " self.sPath.append(DistPar(startTree, tempDist))\n",
+ " # until all vertices are in the tree\n",
+ " while(self.nTree < self.nVerts):\n",
+ " indexMin = self.getMin() # get minimum from sPath\n",
+ " minDist = self.sPath[indexMin].distance\n",
+ " if(minDist == 1000000): # if all infinite\n",
+ " # or in tree,\n",
+ " print 'There are unreachable vertices'\n",
+ " break # sPath is complete\n",
+ " else:\n",
+ " # reset self.currentVert\n",
+ " self.currentVert = indexMin # to closest vert\n",
+ " self.startToCurrent = self.sPath[indexMin].distance\n",
+ " # minimum distance from startTree is\n",
+ " # to self.currentVert, and is self.startToCurrent\n",
+ " # put current vertex in tree\n",
+ " self.vertexList[self.currentVert].isInTree = True\n",
+ " self.nTree += 1\n",
+ " self.adjust_sPath() # update sPath[] array\n",
+ "\n",
+ " self.displayPaths() # display sPath[] contents\n",
+ " self.nTree = 0 # clear tree\n",
+ " for j in range(self.nVerts):\n",
+ " self.vertexList[j].isInTree = False \n",
+ "\n",
+ " def getMin(self): # get entry from sPath\n",
+ " minDist = 1000000 # assume minimum\n",
+ " indexMin = 0\n",
+ " for j in range(self.nVerts): # for each vertex,\n",
+ " # if its in tree and\n",
+ " if( not self.vertexList[j].isInTree and self.sPath[j].distance < minDist ):\n",
+ " minDist = self.sPath[j].distance\n",
+ " indexMin = j # update minimum\n",
+ " return indexMin\n",
+ "\n",
+ " def adjust_sPath(self):\n",
+ " # adjust values in shortest-path array sPath\n",
+ " column = 1\n",
+ " # skip starting vertex\n",
+ " while(column < self.nVerts): # go across columns\n",
+ " # if this columns vertex already in tree, skip it\n",
+ " if( self.vertexList[column].isInTree ):\n",
+ " column += 1\n",
+ " continue\n",
+ " # calculate distance for one sPath entry get edge from self.currentVert to column\n",
+ " currentToFringe = self.adjMat[self.currentVert][column]\n",
+ " # add distance from start\n",
+ " startToFringe = self.startToCurrent + currentToFringe\n",
+ " # get distance of current sPath entry\n",
+ " sPathDist = self.sPath[column].distance\n",
+ " # compare distance from start with sPath entry\n",
+ " if(startToFringe < sPathDist): # if shorter,\n",
+ " # update sPath\n",
+ " self.sPath[column].parentVert = self.currentVert\n",
+ " self.sPath[column].distance = startToFringe\n",
+ " column += 1\n",
+ "\n",
+ " def displayPaths(self):\n",
+ " for j in range(self.nVerts): # display contents of sPath[]\n",
+ " print self.vertexList[j].label ,' =' \n",
+ " if(self.sPath[j].distance == 1000000):\n",
+ " print 'inf', # inf\n",
+ " else:\n",
+ " print self.sPath[j].distance , # 50\n",
+ " parent = self.vertexList[ self.sPath[j].parentVert ].label\n",
+ " print '(' , parent , ')' , # (A)\n",
+ " print ''\n",
+ " \n",
+ "theGraph = Graph()\n",
+ "theGraph.addVertex('A') # 0 (start)\n",
+ "theGraph.addVertex('C') # 2\n",
+ "theGraph.addVertex('B') # 1\n",
+ "theGraph.addVertex('D') # 3\n",
+ "theGraph.addVertex('E') # 4\n",
+ "theGraph.addEdge(0,1,50)\n",
+ "theGraph.addEdge(0,3,80)\n",
+ "theGraph.addEdge(1,2,60)\n",
+ "theGraph.addEdge(1,3,90)\n",
+ "theGraph.addEdge(2,4,40)\n",
+ "theGraph.addEdge(3,2,20)\n",
+ "theGraph.addEdge(3,4,70)\n",
+ "theGraph.addEdge(4,1,50)\n",
+ "print 'Shortest paths' ,\n",
+ "theGraph.path() # shortest paths"
+ ],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
- "text": "Shortest paths A =\ninf ( A ) C =\n50 ( A ) B =\n100 ( D ) D =\n80 ( A ) E =\n140 ( B ) \n"
+ "text": [
+ "Shortest paths A =\n",
+ "inf ( A ) C =\n",
+ "50 ( A ) B =\n",
+ "100 ( D ) D =\n",
+ "80 ( A ) E =\n",
+ "140 ( B ) \n"
+ ]
}
],
"prompt_number": 2
@@ -51,7 +349,7 @@
{
"cell_type": "code",
"collapsed": false,
- "input": "",
+ "input": [],
"language": "python",
"metadata": {},
"outputs": []