{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "KIrAZtEDttb7" }, "source": [ "# A few python, `numpy`, and `matplotlib` examples\n", "\n", "(M. Ligare Aug. 2020; modified by K. Vollmayr-Lee Jan. 2022, J. Villadsen Jan. 2023 & 2024)" ] }, { "cell_type": "markdown", "metadata": { "id": "xSbpXFwuttb-" }, "source": [ "### Cells\n", "\n", "This is a markdown cell. Markdown cells are for for formatted comments. See the [Markdown Cheat-Sheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) for more information.\n", "\n", "If you single-click on a cell you can get a box around the cell, and you can see what\n", "kind of cell it is in the menu bar above (Markdown, code, etc.), and you can change it. (Feature not available in Colab.)\n", "\n", "Double click on this cell, then you can make changes. Let's add math: $e^{i\\pi} = -1$\n", "\n", "To add a cell use Insert from the menu bar above.\n", "\n", "`Shift+Enter` to execute cells." ] }, { "cell_type": "markdown", "source": [ "**Task 1:** Create a markdown cell below this one, with a title, text, and a Latex equation." ], "metadata": { "id": "t_jVIN8CUCuv" } }, { "cell_type": "markdown", "metadata": { "id": "RgMIlgKsttb_" }, "source": [ "### Importing modules\n", "Functions from modules imported in this manner must be preceded by the \"name\" given to the module (`np`, `plt`), e.g., `np.zeros()` below." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "DH_9m8o5ttcA" }, "outputs": [], "source": [ "import numpy as np # lots of useful math commands\n", "import matplotlib.pyplot as plt # commands for making graphs" ] }, { "cell_type": "markdown", "metadata": { "id": "UExqffFZttcB" }, "source": [ "**If not using Google Colab:** The following is an `Ipython` \"magic\" command that places plots into notebooks, and makes the plots interactive. Do not run this command in Google Colab - it will cause your plots to not appear." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "B_-_5E4VttcB" }, "outputs": [], "source": [ "%matplotlib notebook # don't run this in Google Colab!" ] }, { "cell_type": "markdown", "source": [ "**If using Google Colab:** Run the following commands to install and import libraries needed for interactive plots in Google Colab. I recommend using the \"Light\" display theme (click the Settings gear icon in the top right of this window), otherwise plots maybe hard to see." ], "metadata": { "id": "TYSDyWCnuglJ" } }, { "cell_type": "code", "source": [ "!pip install ipympl # don't run this if not in Google Colab!\n", "%matplotlib widget\n", "from google.colab import output\n", "output.enable_custom_widget_manager()" ], "metadata": { "id": "HhTHhO41uyOT" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "### Discuss\n", "\n", "As you work through this document, predict what each code cell will print **before** you run it. Any surprises? Feel free to change the code or variable values to see what will happen.\n", "\n", "Your main goal is to get an idea for where to find this information again when you need it - you don't need to memorize!" ], "metadata": { "id": "MWy130DEB6B9" } }, { "cell_type": "markdown", "metadata": { "id": "a45mXMonttcB" }, "source": [ "### Simple loops" ] }, { "cell_type": "markdown", "source": [ "Here are four example loops. **Before** running each one, predict what it will print. Any surprises?" ], "metadata": { "id": "AFnXYOHkUcvc" } }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "CvKAAR74ttcC" }, "outputs": [], "source": [ "for i in range(5):\n", " print(i)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "rSMwbtlgttcC" }, "outputs": [], "source": [ "for i in range(4,10):\n", " print(i)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "6p9ieWHOttcD" }, "outputs": [], "source": [ "for i in range(4,10,2):\n", " print(i)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "eh2IWTzPttcD" }, "outputs": [], "source": [ "i = -2\n", "while i < 5:\n", " print(i)\n", " i += 1" ] }, { "cell_type": "markdown", "source": [ "**Task:** Write a loop to print the numbers 0, 10, 20, ..., 100 (inclusive)." ], "metadata": { "id": "tvXFzRiJUqoD" } }, { "cell_type": "markdown", "source": [ "### Getting help with functions\n", "\n", "Put a ? before the function name. It will show you what arguments (variables) you can pass to the function, and describe what it does. For example, run the following command to get a description of how range works." ], "metadata": { "id": "yNp_50JGAd9y" } }, { "cell_type": "code", "source": [ "?range" ], "metadata": { "id": "rnVniX1roZX1" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "KaveS3PpttcE" }, "source": [ "### Conditionals" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "oTdo6o4CttcE" }, "outputs": [], "source": [ "i = 6\n", "\n", "if i<4:\n", " print(\"ok\")\n", "\n", "elif i == 4:\n", " print(\"better\")\n", "\n", "else:\n", " print('not ok')\n" ] }, { "cell_type": "code", "source": [ "x = (i==4)\n", "print(x)" ], "metadata": { "id": "okK0YBkjpcL5" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [], "metadata": { "id": "jQsFnxNwpb05" } }, { "cell_type": "markdown", "source": [ "**Task:** Write a loop that prints:\n", "\n", "1 odd\n", "\n", "2 even\n", "\n", "3 odd\n", "\n", "4 even\n", "\n", "etc up through 10." ], "metadata": { "id": "nUYqOuaJU8uV" } }, { "cell_type": "markdown", "metadata": { "id": "6XGUALp9ttcE" }, "source": [ "### Constructing arrays\n", "Numpy arrays are easy-to-use \"containers\" for data that are computationally efficient." ] }, { "cell_type": "markdown", "metadata": { "id": "D8TbQAGqttcE" }, "source": [ "#### Constructing 1-D arrays \"by hand\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "eomVL3JVttcF" }, "outputs": [], "source": [ "a = np.array([10, 20, 30, 4.e1])\n", "print(a)" ] }, { "cell_type": "markdown", "source": [ "**Task:** Try changing the last number in the array to 40. and to 40 (no period). Which of these gives the same result and which is different?" ], "metadata": { "id": "OVxkfG8yVofn" } }, { "cell_type": "markdown", "source": [ "#### Lists vs. arrays\n", "\n", "A list is created just using brackets, whereas an array is created by putting np.array() around a list. Arrays are typically better for the mathematical functions you'll be using for data analysis in this class. If an np function isn't working, make sure you're using an array!" ], "metadata": { "id": "VPgjxrJwA-hb" } }, { "cell_type": "code", "source": [ "x = [1,2,3]\n", "x" ], "metadata": { "id": "eP1ConfEqqlK" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "Note: putting \"x\" on the last line causes it to display what is in the variable x - this only works if no other lines afterwards in that cell." ], "metadata": { "id": "I8IpjxuXBamW" } }, { "cell_type": "code", "source": [ "x+x" ], "metadata": { "id": "5QnH_dSDrK7K" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "y = np.array([1,2,3])\n", "y" ], "metadata": { "id": "-nOOfgJJqxIP" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "y+y" ], "metadata": { "id": "xQgOS9pVrPrH" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "**Task:** Discuss - what happened differently when you added two lists vs. two arrays?" ], "metadata": { "id": "T_KO6qCrBk62" } }, { "cell_type": "markdown", "metadata": { "id": "PqQcmA4KttcF" }, "source": [ "#### Constructing arrays using numpy \"built-ins\" (see the [numpy array tip sheet](https://valecs.gitlab.io/resources/numpy.pdf))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Rb4Rj9z1ttcF" }, "outputs": [], "source": [ "b = np.zeros(10)\n", "print(b)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "7dALFGxwttcF" }, "outputs": [], "source": [ "b = np.zeros((3,7))\n", "print(b)" ] }, { "cell_type": "code", "source": [ "# copy the shape of another array (# creates a text comment in a code cell)\n", "print('Shape of array b:',b.shape)\n", "c = np.ones(b.shape)\n", "print(c)" ], "metadata": { "id": "02HZ5qNcDmPN" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "H3Wc1YTIttcG" }, "outputs": [], "source": [ "d = np.eye(4,4)\n", "print(d)" ] }, { "cell_type": "markdown", "source": [ "**Task:** Create an array with 3 columns and 6 rows, containing all ones. Print it to make sure it has the right shape." ], "metadata": { "id": "iSuNP32DWMgl" } }, { "cell_type": "markdown", "metadata": { "id": "-_NshI61ttcG" }, "source": [ "#### Constructing arrays using numpy looping features (similar to Mathematica `Table` command)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "pdO_yjiKttcG" }, "outputs": [], "source": [ "d = np.array([i**2 for i in range(100) if i%2==1])\n", "print(d)" ] }, { "cell_type": "markdown", "source": [ "**Task:** Describe what the above code created and why." ], "metadata": { "id": "PhBncVPkWft5" } }, { "cell_type": "markdown", "metadata": { "id": "bJguvY1DttcG" }, "source": [ "#### Constructing arrays using the numpy `linspace` function\n", "Especially useful in making points along independent axis in graphs." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "GG7qZYB1ttcG" }, "outputs": [], "source": [ "np.linspace(4,6,11)" ] }, { "cell_type": "markdown", "source": [ "**Task:** Use linspace to create an array x_i containing labels for the x-axis of 0,10,20,...,100 (inclusive)." ], "metadata": { "id": "ekbQDFXCWwKB" } }, { "cell_type": "markdown", "metadata": { "id": "r4UTOi7MttcH" }, "source": [ "### Manipulating arrays" ] }, { "cell_type": "markdown", "source": [ "Define some 1D and 2D arrays to play with" ], "metadata": { "id": "m-vrGHsBI7c_" } }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "k1d_Q8eJttcH" }, "outputs": [], "source": [ "a = np.array([1,2,3,4])\n", "b = np.array([5,6,7,8])\n", "a1 = np.array([[1,2,3],[4,5,6]])\n", "b1 = np.array([[11,12,13],[14,15,16]])" ] }, { "cell_type": "markdown", "metadata": { "id": "nLSYnkgWttcH" }, "source": [ "#### Notice the element-wise behaviour of operators -- No need for loops" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "obDWgsYqttcH" }, "outputs": [], "source": [ "a**2" ] }, { "cell_type": "markdown", "metadata": { "id": "07XZ7o-TttcH" }, "source": [ "#### The `*` gives element-by-element multiplication" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "9lfVRpQJttcH" }, "outputs": [], "source": [ "a*b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "_3MTtyyittcH" }, "outputs": [], "source": [ "a1*b1" ] }, { "cell_type": "markdown", "metadata": { "id": "hOQ0NdHDttcI" }, "source": [ "#### The `@` operator gives matrix multiplication\n", "\n", "For two 1D arrays of same length, this is the dot product\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "xSkzGBRMttcI" }, "outputs": [], "source": [ "a@b" ] }, { "cell_type": "markdown", "metadata": { "id": "QQB5YqKKttcI" }, "source": [ "#### array indexing starts at 0; negative indices wrap around \"to the left\"\n", "\n", "An index of -1 can be quite useful - what does it do?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "1zN3opoSttcI" }, "outputs": [], "source": [ "a[0], a[-1]" ] }, { "cell_type": "code", "source": [ "a[[0,-1]]" ], "metadata": { "id": "Ja7YkhHnH9Gi" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "Look carefully at the indices: which element of a1 do you think this will extract?" ], "metadata": { "id": "szk4P3jYJZ9d" } }, { "cell_type": "code", "source": [ "a1[1,0]" ], "metadata": { "id": "TGG96dAdJQys" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "RynkTziNttcI" }, "source": [ "#### \"Slice\" arrays using colons (`:`)\n", "\n", "Notice: is a[3] included in the second and third list?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "4kIXihVIttcI" }, "outputs": [], "source": [ "a[1:], a[:3], a[1:3]" ] }, { "cell_type": "markdown", "metadata": { "id": "OL1qmczlttcI" }, "source": [ "#### Combine arrays into higher-dimensional arrays" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "L3NyZctattcI" }, "outputs": [], "source": [ "c = np.array([a,b])\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": { "id": "0PHkJl3TttcI" }, "source": [ "#### Extract the second column of the 2-d array `c` (Take the transpose of `c` and extract 2nd element)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "vl3by7E9ttcJ" }, "outputs": [], "source": [ "np.transpose(c)[1]" ] }, { "cell_type": "markdown", "source": [ "An alternative way to get the same result: ( \":\" means \"all indices\", so this is all rows and only the column indexed 1)" ], "metadata": { "id": "oLuvycKjG_2_" } }, { "cell_type": "code", "source": [ "c[:,1]" ], "metadata": { "id": "thO9mwr3HDzx" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "**Task:** Add a code cell below to extract an array containing only the 2nd through 4th columns of array c." ], "metadata": { "id": "OGgvR7XqHcyN" } }, { "cell_type": "markdown", "source": [ "### Mean and standard deviation\n", "\n", "I open 7 bags of M&Ms. In the various bags, the number of blue M&Ms I count is: 32, 44, 33, 39, 28, 31, 35. Calculate the mean and standard deviation of the distribution. You can use np.mean and np.std, and it may also be good to practice writing equations based on the definition of mean and standard deviation. Then, calculate the uncertainty on the mean, and write the mean with the uncertainty with correct sig figs." ], "metadata": { "id": "Hb5Q20DuZPfL" } }, { "cell_type": "markdown", "metadata": { "id": "mJUT0HGEttcJ" }, "source": [ "### Defining functions\n", "#### Simple function of two variables" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Vf9zS-WattcJ" }, "outputs": [], "source": [ "def multiply_function(x,y):\n", " '''Comments about a function go here; they are called a 'docstring'.\n", " I strongly recommend writing a docstring for each function you write,\n", " and giving the function a descriptive name.\n", " This function returns the product of x and y.'''\n", " return x*y" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Q_mseUkKttcJ" }, "outputs": [], "source": [ "multiply_function(3,4)" ] }, { "cell_type": "markdown", "metadata": { "id": "INJj9g9JttcJ" }, "source": [ "#### Getting help, i.e., reading contents of a `docstring`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "qiZRkBz7ttcJ" }, "outputs": [], "source": [ "multiply_function?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "0613-ctkttcJ" }, "outputs": [], "source": [ "np.linspace?" ] }, { "cell_type": "markdown", "metadata": { "id": "3BCaTpu_ttcJ" }, "source": [ "#### Functions can act on arrays too!" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "rPu2nZKlttcJ" }, "outputs": [], "source": [ "a = np.linspace(1,10,10)\n", "multiply_function(a,.5)" ] }, { "cell_type": "markdown", "metadata": { "id": "PdGwfImuttcK" }, "source": [ "### Making simple graphs" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "ygzGeIMJttcK" }, "outputs": [], "source": [ "plt.figure()\n", "x = np.linspace(0,5,201) # Make a pseudo-continuous set of x-values\n", "y = x**2 # y values for smooth function\n", "plt.plot(x,y)\n", "xdata = np.array([1,2,3,4,5]) # Discrete x-values\n", "ydata = xdata**2 # y-values for discrete data set\n", "plt.scatter(xdata,ydata);\n", "# the semi-colon stops the last line of code from printing some text that you don't need" ] }, { "cell_type": "markdown", "metadata": { "id": "wIo34QVHttcK" }, "source": [ "### Adding features to graphs" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "GDluU6HdttcK" }, "outputs": [], "source": [ "plt.figure()\n", "\n", "# Add horizontal/vertical lines to the plot\n", "# Useful for emphasizing zero, or showing the mean value or standard deviation of data\n", "plt.axhline(0, color='magenta')\n", "plt.axvline(0, color='magenta')\n", "\n", "# Add text labels to the plot (a must for your lab notebooks!)\n", "plt.title(\"My theory\")\n", "plt.xlabel(\"$x$ (cm)\")\n", "plt.ylabel('$\\sigma$ (g)') # using the dollar signs allows you to use Latex characters\n", "\n", "# Add a grid to the plot background\n", "plt.grid()\n", "\n", "x = np.linspace(0,5,201)\n", "y = x**2\n", "plt.plot(x,y, label=\"theory\") # label names the plotted lines/data for the legend\n", "xdata = np.array([1,2,3,4,5])\n", "ydata = xdata**2\n", "plt.scatter(xdata,ydata, label=\"data pts\")\n", "plt.legend() # the legend command extracts the names that you previously labeled\n", "\n", "plt.xlim(-2,7); # change the x-axis range displayed (useful to help data show up on edges or fit the legend)" ] }, { "cell_type": "markdown", "metadata": { "id": "wAAFp8OXttcK" }, "source": [ "### Graphs with error bars" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "J5HzSraIttcK" }, "outputs": [], "source": [ "plt.figure()\n", "plt.axhline(0, color='magenta')\n", "plt.axvline(0, color='magenta')\n", "plt.title(\"My theory\")\n", "plt.xlabel('$x$ (cm)')\n", "plt.ylabel('$\\sigma$ (g)')\n", "plt.grid()\n", "x = np.linspace(0,5,201)\n", "y = x**2\n", "plt.plot(x,y, label=\"theory\")\n", "xdata = np.array([1,2,3,4,5])\n", "ydata = np.array([1.3, 3.5, 9.4, 15.5, 24])\n", "\n", "# the values for the errors (one per data point - same length array as xdata, ydata)\n", "u = np.ones(len(xdata))*0.8\n", "\n", "# like the plot command but with error bars\n", "plt.errorbar(xdata, ydata, yerr=u, fmt='o',label='data')\n", "plt.legend()\n", "plt.axis([-2,8,-2,27]);" ] }, { "cell_type": "markdown", "source": [ "Try out the icons on the interactive plot! You should be able to save a PNG figure, zoom, and more. Due to an update to Chrome, if you're running Jupyter in Chrome then the interactive figure may [not download](https://github.com/matplotlib/matplotlib/issues/9117) (Colab doesn't seem to have this problem). If this happens, you can click the X or Power symbol in the top right of the figure to turn it from an interactive figure into an image, then right click and save the image." ], "metadata": { "id": "HOkyoNCqQgFV" } }, { "cell_type": "markdown", "metadata": { "id": "uybOasqZttcK" }, "source": [ "### Writing arrays to a data file; reading in a data file as an array" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "bIKttsSxttcK" }, "outputs": [], "source": [ "a = np.loadtxt('sample.dat')\n", "print(a)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "0fhNE7wfttcK" }, "outputs": [], "source": [ "b = a**2\n", "print(b)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "fjBY137xttcK" }, "outputs": [], "source": [ "np.savetxt('output.dat',b)" ] }, { "cell_type": "markdown", "source": [ "Find output.dat and verify that it contains what you expect." ], "metadata": { "id": "1dpi9qUUND7i" } }, { "cell_type": "markdown", "source": [], "metadata": { "id": "kS2PD3cIZIWI" } }, { "cell_type": "markdown", "metadata": { "id": "_re46ODUttcL" }, "source": [ "### Version Information" ] }, { "cell_type": "markdown", "metadata": { "id": "LReSyagFttcL" }, "source": [ "`version_information` is from J.R. Johansson (jrjohansson at gmail.com);\n", "see Introduction to scientific computing with Python:\n", "http://nbviewer.jupyter.org/github/jrjohansson/scientific-python-lectures/blob/master/Lecture-0-Scientific-Computing-with-Python.ipynb\n", "for more information and instructions for package installation.\n", "\n", "If version_information has been installed system wide (as it has been on Bucknell linux computers with shared file systems), continue with next cell as written, skip the pip install line. On a personal computer, you should only need to run the pip install line once, whereas you may need to run it once per session in Colab." ] }, { "cell_type": "code", "source": [ "!pip install version_information" ], "metadata": { "id": "COAiRAN_8Ml9" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "CIMholJBttcL" }, "outputs": [], "source": [ "%load_ext version_information" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "id": "nKhxisk1ttcL" }, "outputs": [], "source": [ "version_information numpy, matplotlib" ] }, { "cell_type": "markdown", "source": [ "### Clean-up & prep for turning in assignments" ], "metadata": { "id": "MJE3PTRbwJS6" } }, { "cell_type": "markdown", "source": [ "#### Clean-Up\n", "\n", "Try out the following three menu-bar commands in order. After each one, you should scroll down the page to see its effect.\n", "\n", "| Command | Jupyter | Colab |\n", "| --- | --- | --- |\n", "| Clear all output | `Cell > All Output > Clear` | `Edit > Clear all outputs` |\n", "| Delete all variables & imports | `Kernel > Restart` | `Runtime > Restart runtime` |\n", "| Run all cells | `Cell > Run all` | `Runtime > Run all` |\n", "\n", "Before submitting .ipynb files to your instructors, please take these 3 steps in order to \"clean up\" your notebook and make sure the instructor can run it. (You may also want to delete unnecessary outputs before printing to PDF.) If \"run all\" doesn't work, this means you may have deleted a variable definition, etc.\n", "\n", "These commands are also useful as you work, such as if you import two conflicting modules or have some weird error and want a refresh.\n", "\n", "**Discuss:** What is the difference between clearing all output, vs. restarting the kernel/runtime?" ], "metadata": { "id": "sqbaoGeMA-fr" } } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.8" }, "colab": { "provenance": [], "collapsed_sections": [ "KaveS3PpttcE", "D8TbQAGqttcE", "VPgjxrJwA-hb", "r4UTOi7MttcH", "nLSYnkgWttcH", "07XZ7o-TttcH", "mJUT0HGEttcJ", "3BCaTpu_ttcJ", "PdGwfImuttcK", "wIo34QVHttcK", "wAAFp8OXttcK", "uybOasqZttcK", "_re46ODUttcL" ] } }, "nbformat": 4, "nbformat_minor": 0 }