Last active
August 29, 2015 14:11
-
-
Save kwinkunks/80fcecf23fafc173b9f9 to your computer and use it in GitHub Desktop.
Simple seismic acquisition modeling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"metadata": { | |
"name": "", | |
"signature": "sha256:ffb7ce02668782de200cbc78628f62ac3bb79f85bd98ec0805be9c8c10c520a9" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Seismic acquisition fiddling" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The idea is to replicate what we've done so far but with 2 enhancements:\n", | |
"\n", | |
"- With a Survey object to hold the various features of a survey\n", | |
"- With more GeoPandas stuff, and less fussing with (x,y)'s directly" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We'll start with the usual prelims..." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import numpy as np\n", | |
"import matplotlib.pyplot as plt\n", | |
"from shapely.geometry import Point, LineString\n", | |
"import geopandas as gpd\n", | |
"import pandas as pd\n", | |
"\n", | |
"%matplotlib inline" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"I'm trying `mplleaflet`. To install...\n", | |
"\n", | |
"- `git clone https://github.com/jwass/mplleaflet.git`\n", | |
"- `cd mplleaflet`\n", | |
"- `sudo python setup.py install`\n", | |
"- `cd -`\n", | |
"- `git clone https://github.com/mpld3/mplexporter.git`\n", | |
"- `cd mplexporter`\n", | |
"- `sudo python setup.py install`" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Then you can do this..." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import mplleaflet" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We need CRS control for real maps..." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"from fiona.crs import from_epsg" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"Survey object" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Survey:\n", | |
" \"\"\"\n", | |
" A seismic survey.\n", | |
" \"\"\"\n", | |
"\n", | |
" def __init__(self, corner, size, line_spacing, point_spacing, epsg):\n", | |
" self.corner = corner # x,y tuple\n", | |
" self.xmi = corner[0]\n", | |
" self.ymi = corner[1]\n", | |
" \n", | |
" self.size = size # x,y tuple\n", | |
" self.x = size[0]\n", | |
" self.y = size[1]\n", | |
" \n", | |
" self.line_spacing = line_spacing # SL,RL tuple\n", | |
" self.SL = line_spacing[0]\n", | |
" self.RL = line_spacing[1]\n", | |
" \n", | |
" self.point_spacing = point_spacing # si,ri tuple\n", | |
" self.si = point_spacing[0]\n", | |
" self.ri = point_spacing[1]\n", | |
" \n", | |
" self.shiftx = -self.si/2.\n", | |
" self.shifty = -self.ri/2.\n", | |
" \n", | |
" self.epsg = epsg\n", | |
" \n", | |
" @property\n", | |
" def lines(self):\n", | |
" \"\"\"\n", | |
" Returns number of (src, rcvr) lines\n", | |
" \"\"\"\n", | |
" slines = int(self.x/self.SL) + 1\n", | |
" rlines = int(self.y/self.RL) + 1\n", | |
" return slines, rlines\n", | |
"\n", | |
" @property\n", | |
" def points_per_line(self):\n", | |
" \"\"\"\n", | |
" Returns number of (src, rcvr) points per line\n", | |
" \"\"\"\n", | |
" spoints = int(self.y/self.si) + 2\n", | |
" rpoints = int(self.x/self.ri) + 2\n", | |
" return spoints, rpoints\n", | |
" \n", | |
" @property\n", | |
" def src(self):\n", | |
" s = [Point(self.xmi+line*self.SL, self.ymi+s*self.si)\n", | |
" for line in range(self.lines[0])\n", | |
" for s in range(self.points_per_line[0])\n", | |
" ]\n", | |
" S = gpd.GeoSeries(s)\n", | |
" S.crs = from_epsg(26911)\n", | |
" return S\n", | |
"\n", | |
" @property\n", | |
" def rcvr(self):\n", | |
" r = [Point(self.xmi + r*self.ri + self.shiftx, self.ymi + line*self.RL - self.shifty)\n", | |
" for line in range(self.lines[1])\n", | |
" for r in range(self.points_per_line[1])\n", | |
" ]\n", | |
" R = gpd.GeoSeries(r)\n", | |
" R.crs = from_epsg(self.epsg)\n", | |
" return R\n", | |
" \n", | |
" @property\n", | |
" def layout(self):\n", | |
" \"\"\"\n", | |
" Provide a GeoDataFrame of all points,\n", | |
" labelled as columns and in hierarchical index.\n", | |
" \"\"\"\n", | |
" \n", | |
" # Feels like there might be a better way to do this...\n", | |
" sgdf = gpd.GeoDataFrame({'geometry': self.src, 'station': 'src'})\n", | |
" rgdf = gpd.GeoDataFrame({'geometry': self.rcvr, 'station': 'rcvr'})\n", | |
"\n", | |
" # Concatenate with a hierarchical index\n", | |
" layout = pd.concat([sgdf,rgdf], keys=['sources','receivers'])\n", | |
" layout.crs = from_epsg(self.epsg)\n", | |
"\n", | |
" return layout" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Perhaps s and r should be objects too. I think you might want to have survey.receivers.x for the list of x locations, for example." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Instantiate and plot" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"corner = (594186,3677043)\n", | |
"size = (3000,1800)\n", | |
"line_spacing = (600,600)\n", | |
"point_spacing = (100,100)\n", | |
"epsg = 26911 # http://spatialreference.org/ref/epsg/26911/\n", | |
"\n", | |
"survey = Survey(corner=corner,\n", | |
" size=size,\n", | |
" line_spacing=line_spacing,\n", | |
" point_spacing=point_spacing,\n", | |
" epsg=epsg\n", | |
" )" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"s = survey.src\n", | |
"r = survey.rcvr\n", | |
"r[:10]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 7, | |
"text": [ | |
"0 POINT (594136 3677093)\n", | |
"1 POINT (594236 3677093)\n", | |
"2 POINT (594336 3677093)\n", | |
"3 POINT (594436 3677093)\n", | |
"4 POINT (594536 3677093)\n", | |
"5 POINT (594636 3677093)\n", | |
"6 POINT (594736 3677093)\n", | |
"7 POINT (594836 3677093)\n", | |
"8 POINT (594936 3677093)\n", | |
"9 POINT (595036 3677093)\n", | |
"dtype: object" | |
] | |
} | |
], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"layout = survey.layout\n", | |
"layout[:10]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": [ | |
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th>geometry</th>\n", | |
" <th>station</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th rowspan=\"10\" valign=\"top\">sources</th>\n", | |
" <th>0</th>\n", | |
" <td> POINT (594186 3677043)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1</th>\n", | |
" <td> POINT (594186 3677143)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2</th>\n", | |
" <td> POINT (594186 3677243)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3</th>\n", | |
" <td> POINT (594186 3677343)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4</th>\n", | |
" <td> POINT (594186 3677443)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>5</th>\n", | |
" <td> POINT (594186 3677543)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>6</th>\n", | |
" <td> POINT (594186 3677643)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>7</th>\n", | |
" <td> POINT (594186 3677743)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>8</th>\n", | |
" <td> POINT (594186 3677843)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>9</th>\n", | |
" <td> POINT (594186 3677943)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>10 rows \u00d7 2 columns</p>\n", | |
"</div>" | |
], | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 8, | |
"text": [ | |
" geometry station\n", | |
"sources 0 POINT (594186 3677043) src\n", | |
" 1 POINT (594186 3677143) src\n", | |
" 2 POINT (594186 3677243) src\n", | |
" 3 POINT (594186 3677343) src\n", | |
" 4 POINT (594186 3677443) src\n", | |
" 5 POINT (594186 3677543) src\n", | |
" 6 POINT (594186 3677643) src\n", | |
" 7 POINT (594186 3677743) src\n", | |
" 8 POINT (594186 3677843) src\n", | |
" 9 POINT (594186 3677943) src\n", | |
"\n", | |
"[10 rows x 2 columns]" | |
] | |
} | |
], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"With a hierarchical index you can do cool things, e.g. show the last five sources:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"layout.ix['sources'][-5:]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": [ | |
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>geometry</th>\n", | |
" <th>station</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>115</th>\n", | |
" <td> POINT (597186 3678543)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>116</th>\n", | |
" <td> POINT (597186 3678643)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>117</th>\n", | |
" <td> POINT (597186 3678743)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>118</th>\n", | |
" <td> POINT (597186 3678843)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>119</th>\n", | |
" <td> POINT (597186 3678943)</td>\n", | |
" <td> src</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5 rows \u00d7 2 columns</p>\n", | |
"</div>" | |
], | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 9, | |
"text": [ | |
" geometry station\n", | |
"115 POINT (597186 3678543) src\n", | |
"116 POINT (597186 3678643) src\n", | |
"117 POINT (597186 3678743) src\n", | |
"118 POINT (597186 3678843) src\n", | |
"119 POINT (597186 3678943) src\n", | |
"\n", | |
"[5 rows x 2 columns]" | |
] | |
} | |
], | |
"prompt_number": 9 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"layout.crs" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 10, | |
"text": [ | |
"{'init': 'epsg:26911', 'no_defs': True}" | |
] | |
} | |
], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"ax = layout.plot() # column='station' doesn't seem to help\n", | |
"plt.show()\n", | |
"\n", | |
"# mplleaflet seems to break nbviewer.org\n", | |
"#mplleaflet.display(fig=ax.figure, crs=layout.crs)\n", | |
"\n", | |
"# To display a separate window instead:\n", | |
"#mplleaflet.show(fig=ax.figure, crs=layout.crs)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "display_data", | |
"png": "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\nuKGD3GJQAAAAAElFTkSuQmCC\n", | |
"text": [ | |
"<matplotlib.figure.Figure at 0x10d1f9950>" | |
] | |
} | |
], | |
"prompt_number": 12 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Export GeoDataFrames to GIS shapefile." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# gdf.to_file('src_and_rcvr.shp')" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 13 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"Midpoint calculations" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We need midpoints. There is a midpoint between every source-receiver pair.\n", | |
"\n", | |
"Hopefully it's not too inelegant to get to the midpoints now that we're using this layout object thing." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"midpoints = [LineString([r, s]).interpolate(0.5, normalized=True)\n", | |
" for r in layout.ix['receivers']['geometry']\n", | |
" for s in layout.ix['sources']['geometry']]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"As well as knowing the (x,y) of the midpoints, we'd also like to record the distance from each *s* to each live *r* (each *r* in the live patch). This is easy enough to compute:\n", | |
"\n", | |
" Point(x1, y1).distance(Point(x2, y2))\n", | |
" \n", | |
"Then we can make a list of all the offsets when we count the midpoints into the bins. " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"offsets = [r.distance(s)\n", | |
" for r in layout.ix['receivers']['geometry']\n", | |
" for s in layout.ix['sources']['geometry']]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 15 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"azimuths = [(180.0/np.pi) * np.arctan((r.x - s.x)/(r.y - s.y))\n", | |
" for r in layout.ix['receivers']['geometry']\n", | |
" for s in layout.ix['sources']['geometry']]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 16 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"midpoints[6].coords.xy" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 17, | |
"text": [ | |
"(array('d', [594161.0]), array('d', [3677368.0]))" | |
] | |
} | |
], | |
"prompt_number": 17 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"offsetx = np.array(offsets)*np.cos(np.array(azimuths)*np.pi/180.)\n", | |
"offsety = np.array(offsets)*np.sin(np.array(azimuths)*np.pi/180.)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 18 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Make a Geoseries of the midpoints, offsets and azimths:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"midpt = gpd.GeoDataFrame({\n", | |
" 'geometry' : midpoints,\n", | |
" 'offset' : offsets,\n", | |
" 'azimuth': azimuths,\n", | |
" 'offsetx' : offsetx,\n", | |
" 'offsety' : offsety\n", | |
" })\n", | |
"midpt[:5]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": [ | |
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>azimuth</th>\n", | |
" <th>geometry</th>\n", | |
" <th>offset</th>\n", | |
" <th>offsetx</th>\n", | |
" <th>offsety</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>-45.000000</td>\n", | |
" <td> POINT (594161 3677068)</td>\n", | |
" <td> 70.710678</td>\n", | |
" <td> 50</td>\n", | |
" <td>-50</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1</th>\n", | |
" <td> 45.000000</td>\n", | |
" <td> POINT (594161 3677118)</td>\n", | |
" <td> 70.710678</td>\n", | |
" <td> 50</td>\n", | |
" <td> 50</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2</th>\n", | |
" <td> 18.434949</td>\n", | |
" <td> POINT (594161 3677168)</td>\n", | |
" <td> 158.113883</td>\n", | |
" <td> 150</td>\n", | |
" <td> 50</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3</th>\n", | |
" <td> 11.309932</td>\n", | |
" <td> POINT (594161 3677218)</td>\n", | |
" <td> 254.950976</td>\n", | |
" <td> 250</td>\n", | |
" <td> 50</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4</th>\n", | |
" <td> 8.130102</td>\n", | |
" <td> POINT (594161 3677268)</td>\n", | |
" <td> 353.553391</td>\n", | |
" <td> 350</td>\n", | |
" <td> 50</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5 rows \u00d7 5 columns</p>\n", | |
"</div>" | |
], | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 19, | |
"text": [ | |
" azimuth geometry offset offsetx offsety\n", | |
"0 -45.000000 POINT (594161 3677068) 70.710678 50 -50\n", | |
"1 45.000000 POINT (594161 3677118) 70.710678 50 50\n", | |
"2 18.434949 POINT (594161 3677168) 158.113883 150 50\n", | |
"3 11.309932 POINT (594161 3677218) 254.950976 250 50\n", | |
"4 8.130102 POINT (594161 3677268) 353.553391 350 50\n", | |
"\n", | |
"[5 rows x 5 columns]" | |
] | |
} | |
], | |
"prompt_number": 19 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"#midpt.to_file('CMPs.shp')" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 20 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"ax = midpt.plot(column=\"azimuth\")\n", | |
"\n", | |
"# mplleaflet is super slow for this dataset\n", | |
"#mplleaflet.display(fig=ax.figure, crs=s.crs)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "display_data", | |
"png": "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\n", | |
"text": [ | |
"<matplotlib.figure.Figure at 0x10d25dd90>" | |
] | |
} | |
], | |
"prompt_number": 21 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"More plotting..." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"midx, midy = zip(*[(point.x,point.y) for point in midpoints])" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 22 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Tkaing a break to ask for help..." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [] | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment