From ee24ead6a28113c5eb94e03540c2378eaa793d02 Mon Sep 17 00:00:00 2001 From: maxotoadese Date: Wed, 6 Sep 2017 19:52:07 -0400 Subject: [PATCH 01/11] Max Otoadese --- code/chap01mine.ipynb | 2199 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2199 insertions(+) create mode 100644 code/chap01mine.ipynb diff --git a/code/chap01mine.ipynb b/code/chap01mine.ipynb new file mode 100644 index 00000000..caf7fe2f --- /dev/null +++ b/code/chap01mine.ipynb @@ -0,0 +1,2199 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Modeling and Simulation in Python\n", + "\n", + "Chapter 1: Modeling\n", + "\n", + "Copyright 2017 Allen Downey\n", + "\n", + "License: [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Jupyter\n", + "\n", + "Welcome to Modeling and Simulation, welcome to Python, and welcome to Jupyter.\n", + "\n", + "This is a Jupyter notebook, which is a development environment where you can write and run Python code. Each notebook is divided into cells. Each cell contains either text (like this cell) or Python code (like the cell below this one).\n", + "\n", + "### Selecting and running cells\n", + "\n", + "To select a cell, click in the left margin next to the cell. You should see a blue frame surrounding the selected cell.\n", + "\n", + "To edit a code cell, click inside the cell. You should see a green frame around the selected cell, and you should see a cursor inside the cell.\n", + "\n", + "To edit a text cell, double-click inside the cell. Again, you should see a green frame around the selected cell, and you should see a cursor inside the cell.\n", + "\n", + "To run a cell, hold down SHIFT and press ENTER. If you run a text cell, it will typeset the text and display the result.\n", + "\n", + "If you run a code cell, it runs the Python code in the cell and displays the result, if any.\n", + "\n", + "To try it out, edit this cell, change some of the text, and then press SHIFT-ENTER to run it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Adding and removing cells\n", + "\n", + "You can add and remove cells from a notebook using the buttons in the toolbar and the items in the menu, both of which you should see at the top of this notebook.\n", + "\n", + "You might want to try the following exercises:\n", + "\n", + "1. From the Insert menu select \"Insert cell below\" to add a cell below this one. By default, you get a code cell, and you can see in the pulldown menu that says \"Code\".\n", + "\n", + "2. In the new cell, add a print statement like `print('Hello')`, and run it.\n", + "\n", + "3. Add another cell, select the new cell, and then click on the pulldown menu that says \"Code\" and select \"Markdown\". This makes the new cell a text cell.\n", + "\n", + "4. In the new cell, type some text, and then run it.\n", + "\n", + "5. Use the arrow buttons in the toolbar to move cells up and down.\n", + "\n", + "6. Use the cut, copy, and paste buttons to delete, add, and move cells.\n", + "\n", + "7. As you make changes, Jupyter saves your notebook automatically, but if you want to make sure, you can press the save button, which looks like a floppy disk from the 1990s.\n", + "\n", + "8. Finally, when you are done with a notebook, selection \"Close and Halt\" from the File menu." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using the notebooks\n", + "\n", + "The notebooks for each chapter contain the code from the chapter along with addition examples, explanatory text, and exercises. I recommend you read the chapter first to understand the concepts and vocabulary, then run the notebook to review what you learned and see it in action, and then attempt the exercises.\n", + "\n", + "The notebooks contain some explanatory text, but it is probably not enough to make sense if you have not read the book. If you are working through a notebook and you get stuck, you might want to re-read (or read!) the corresponding section of the book.\n", + "\n", + "If you try to work through the notebooks without reading the book, you're gonna have a bad time. If you have previous programming experience, you might get through the first few notebooks, but sooner or later, you will get to the end of your leash, and you won't like it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Importing modsim\n", + "\n", + "The following cell imports `modsim`, which is a collection of functions we will use throughout the book. Whenever you start the notebook, you will have to run the following cell. It does two things:\n", + "\n", + "1. It uses a Jupyter \"magic command\" to specify whether figures should appear in the notebook, or pop up in a new window.\n", + "\n", + "2. It imports everything defined in `modsim`.\n", + "\n", + "Select the following cell and press SHIFT-ENTER to run it." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "If this cell runs successfully, it produces no output other than this message.\n" + ] + } + ], + "source": [ + "# If you want the figures to appear in the notebook, \n", + "# and you want to interact with them, use\n", + "# %matplotlib notebook\n", + "\n", + "# If you want the figures to appear in the notebook, \n", + "# and you don't want to interact with them, use\n", + "# %matplotlib inline\n", + "\n", + "# If you want the figures to appear in separate windows, use\n", + "# %matplotlib qt5\n", + "\n", + "# To switch from one to another, you have to select Kernel->Restart\n", + "\n", + "%matplotlib qt5\n", + "\n", + "from modsim import *\n", + "\n", + "print('If this cell runs successfully, it produces no output other than this message.')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The penny myth\n", + "\n", + "The following cells contain code from the beginning of Chapter 1.\n", + "\n", + "`modsim` defines `UNITS`, which contains variables representing pretty much every unit you've ever heard of. The following to lines create new variables named `meter` and `second`." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "meter = UNITS.meter\n", + "second = UNITS.second" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To find out what units are defined, type `UNITS.` in the next cell and then press TAB. You should see a pop-up menu with a list of units." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m UNITS.\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "UNITS." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a variable named `a` and display its value:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "9.8 meter/second2" + ], + "text/latex": [ + "$9.8 \\frac{meter}{second^{2}}$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a = 9.8 * meter / second**2\n", + "a" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Create `t` and display its value:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "4 second" + ], + "text/latex": [ + "$4 second$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "t = 4 * second\n", + "t" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "If you create a variable and don't display the value, you don't get any output:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "156.8 meter" + ], + "text/latex": [ + "$156.8 meter$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h = a * t**2\n", + "h" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Add a second line to the previous cell to display the value of `h`.\n", + "\n", + "Now let's solve the falling penny problem. The following lines set `h` to the height of the Empire State Building and compute the time it would take a penny to fall, assuming constant acceleration." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "8.817885349720552 second" + ], + "text/latex": [ + "$8.817885349720552 second$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h = 381 * meter\n", + "t = sqrt(2 * h / a)\n", + "t" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Given `t`, we can compute the velocity of the penny when it lands." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "86.41527642726142 meter/second" + ], + "text/latex": [ + "$86.41527642726142 \\frac{meter}{second}$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v = a * t\n", + "v" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "We can convert from one set of units to another like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "mile = UNITS.mile\n", + "hour= UNITS.hour" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "193.30546802805438 mile/hour" + ], + "text/latex": [ + "$193.30546802805438 \\frac{mile}{hour}$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v.to(mile/hour)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** In reality, air resistance prevents the penny from reaching this velocity. At about 20 meters per second, the force of air resistance equals the force of gravity and the penny stops accelerating.\n", + "\n", + "As a simplification, let's assume that the acceleration of the penny is `a` until the penny reaches 20 meters per second, and then 0 afterwards. What is the total time for the penny to fall 381 meters?" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "20.070408163265306 second" + ], + "text/latex": [ + "$20.070408163265306 second$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tv= 20 * meter/second\n", + "t1 = tv/a \n", + "h1 = a / 2 * t1**2\n", + "td= 381 * meter\n", + "t2 = (td - h1) / tv\n", + "\n", + "tf = t1 + t2\n", + "tf\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Modeling a bikeshare system" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We'll start with a `System` object that represents the number of bikes at each station." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bikeshare = System(olin=10, wellesley=2, babson=0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you display the value of a `System` object, it lists the system variables and their values (not necessarily in the order you defined them):" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin10
wellesley2
babson0
\n", + "
" + ], + "text/plain": [ + "olin 10\n", + "wellesley 2\n", + "babson 0\n", + "dtype: int64" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can access the system variables using dot notation." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare.olin" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare.wellesley" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** What happens if you spell the name of a system variable wrong? Edit the previous cell, change the spelling of `wellesley`, and run the cell again.\n", + "\n", + "The error message uses the word \"attribute\", which is another name for what we are calling a system variable. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Add a third attribute called `babson` with initial value 0, and print the state of `bikeshare` again." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plotting\n", + "\n", + "`newfig` creates a new figure, which should appear either in the notebook or in a new window, depending on which magic command you ran in the first code cell.\n", + "\n", + "`plot` adds a data point to the figure; in this example, you should see a red square and a blue circle representing the number of bikes at each station." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "newfig()\n", + "plot(bikeshare.olin, 'rs-')\n", + "plot(bikeshare.wellesley, 'bo-')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use the operators `+=` and `-=` to increase and decrease the system variables. The following lines move a bike from Olin to Wellesley." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin9
wellesley3
babson0
\n", + "
" + ], + "text/plain": [ + "olin 9\n", + "wellesley 3\n", + "babson 0\n", + "dtype: int64" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare.olin -= 1\n", + "bikeshare.wellesley += 1\n", + "bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the following lines plot the updated state of the system. You should see two new data points with lines connecting them to the old data points." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "plot(bikeshare.olin, 'rs-')\n", + "plot(bikeshare.wellesley, 'bo-')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** In the cell below, write a few lines of code to move a bike from Wellesley to Olin and plot the updated state." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "bikeshare.olin += 1\n", + "bikeshare.wellesley -= 1\n", + "bikeshare\n", + "\n", + "plot(bikeshare.olin, 'rs-')\n", + "plot(bikeshare.wellesley, 'bo-')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Functions\n", + "\n", + "Now we can take the code we've written so far and encapsulate it in functions." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def bike_to_wellesley():\n", + " bikeshare.olin -= 1\n", + " bikeshare.wellesley += 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When you define a function, it doesn't run the statements inside the function, yet." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def plot_state():\n", + " plot(bikeshare.olin, 'rs-', label='Olin')\n", + " plot(bikeshare.wellesley, 'bo-', label='Wellesley')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now when we run the functions, it runs the statements inside." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin9
wellesley3
babson0
\n", + "
" + ], + "text/plain": [ + "olin 9\n", + "wellesley 3\n", + "babson 0\n", + "dtype: int64" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bike_to_wellesley()\n", + "plot_state()\n", + "bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You should see two more data points that represent the current state of the system. If the figure is embedded in the notebook, you might have to scroll up to see the change.\n", + "\n", + "One common error is to omit the parentheses, which has the effect of looking up the function, but not running it." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bike_to_wellesley" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The output indicates that `bike_to_wellesley` is a function defined in a \"namespace\" called `__main__`, but you don't have to understand what that means." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Define a function called `bike_to_olin` that moves a bike from Wellesley to Olin. Run the new function and print or plot the results to confirm that it works." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin11
wellesley1
babson0
\n", + "
" + ], + "text/plain": [ + "olin 11\n", + "wellesley 1\n", + "babson 0\n", + "dtype: int64" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def bike_to_olin():\n", + " bikeshare.olin += 1\n", + " bikeshare.wellesley -= 1\n", + "bike_to_olin()\n", + "bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Parameters" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before we go on, let's start with a new state object and a new plot." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bikeshare = System(olin=10, wellesley=2)\n", + "newfig()\n", + "plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since we have two similar functions, we can create a new function, `move_bike` that takes a parameter `n`, which indicates how many bikes are moving, and in which direction." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def move_bike(n):\n", + " bikeshare.olin -= n\n", + " bikeshare.wellesley += n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can use `move_bike` to write simpler versions of the other functions." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def bike_to_wellesley():\n", + " move_bike(1)\n", + " \n", + "def bike_to_olin():\n", + " move_bike(-1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When we define these functions, we replace the old definitions with the new ones.\n", + "\n", + "Now we can test them and update the figure." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin9
wellesley3
\n", + "
" + ], + "text/plain": [ + "olin 9\n", + "wellesley 3\n", + "dtype: int64" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bike_to_wellesley()\n", + "plot_state()\n", + "bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Again, each time you run `plot_state` you should see changes in the figure." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin10
wellesley2
\n", + "
" + ], + "text/plain": [ + "olin 10\n", + "wellesley 2\n", + "dtype: int64" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bike_to_olin()\n", + "plot_state()\n", + "bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At this point, `move_bike` is complicated enough that we should add some documentation. The text in triple-quotation marks is in English, not Python. It doesn't do anything when the program runs, but it helps people understand what this function does and how to use it." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def move_bike(n):\n", + " \"\"\"Move bikes.\n", + " \n", + " n: number of bikes: positive moves from Olin to Wellesley;\n", + " negative moves from Wellesley to Olin\n", + " \"\"\"\n", + " bikeshare.olin -= n\n", + " bikeshare.wellesley += n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Whenever you make a figure, you should put labels on the axes to explain what they mean and what units they are measured in. Here's how:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "label_axes(title='Olin-Wellesley Bikeshare',\n", + " xlabel='Time step (min)', \n", + " ylabel='Number of bikes')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Again, you might have to scroll up to see the effect.\n", + "\n", + "And you can save figures as files; the suffix of the filename indicates the format you want. This example saves the current figure in a PDF file." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap01_fig01.pdf\n" + ] + } + ], + "source": [ + "savefig('chap01_fig01.pdf')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** The following function definitions start with print statements so they display messages when they run. Run each of these functions (with appropriate arguments) and confirm that they do what you expect.\n", + "\n", + "Adding print statements like this to functions is a useful debugging technique. Keep it in mind!" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def move_bike_debug(n):\n", + " print('Running move_bike_debug with argument', n)\n", + " bikeshare.olin -= n\n", + " bikeshare.wellesley += n\n", + " \n", + "def bike_to_wellesley_debug():\n", + " print('Running bike_to_wellesley_debug')\n", + " move_bike_debug(1)\n", + " \n", + "def bike_to_olin_debug():\n", + " print('Running bike_to_olin_debug')\n", + " move_bike_debug(-1)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running move_bike_debug with argument 1\n" + ] + } + ], + "source": [ + "move_bike_debug(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running bike_to_wellesley_debug\n", + "Running move_bike_debug with argument 1\n" + ] + } + ], + "source": [ + "bike_to_wellesley_debug()" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running bike_to_olin_debug\n", + "Running move_bike_debug with argument -1\n" + ] + } + ], + "source": [ + "bike_to_olin_debug()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conditionals" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The function `flip` takes a probability and returns either `True` or `False`, which are special values defined by Python.\n", + "\n", + "In the following example, the probability is 0.7 or 70%. If you run this cell several times, you should get `True` about 70% of the time and `False` about 30%." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flip(0.7)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Modify the argument in the previous cell and see what effect it has.\n", + "\n", + "In the following example, we use `flip` as part of an if statement. If the result from `flip` is `True`, we print `heads`; otherwise we do nothing." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "if flip(0.7):\n", + " print('heads')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With an else clause, we can print heads or tails depending on whether `flip` returns `True` or `False`." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "heads\n" + ] + } + ], + "source": [ + "if flip(0.7):\n", + " print('heads')\n", + "else:\n", + " print('tails')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's get back to the bikeshare system. Again let's start with a new `System` object and a new plot." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bikeshare = System(olin=10, wellesley=2)\n", + "newfig()\n", + "plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Suppose that in any given minute, there is a 70% chance that a student picks up a bike at Olin and rides to Wellesley. We can simulate that like this." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Moving a bike to Wellesley\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin9
wellesley3
\n", + "
" + ], + "text/plain": [ + "olin 9\n", + "wellesley 3\n", + "dtype: int64" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "if flip(0.7):\n", + " bike_to_wellesley()\n", + " print('Moving a bike to Wellesley')\n", + "\n", + "plot_state()\n", + "bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And maybe at the same time, there is also a 60% chance that a student at Wellesley rides to Olin." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Moving a bike to Olin\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin10
wellesley2
\n", + "
" + ], + "text/plain": [ + "olin 10\n", + "wellesley 2\n", + "dtype: int64" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "if flip(0.6):\n", + " bike_to_olin()\n", + " print('Moving a bike to Olin')\n", + "\n", + "plot_state()\n", + "bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can wrap that code in a function called `step` that simulates one time step. In any given minute, a student might ride from Olin to Wellesley, from Wellesley to Olin, or both, or neither, depending on the results of `flip`." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def step():\n", + " if flip(0.7):\n", + " bike_to_wellesley()\n", + " print('Moving a bike to Wellesley')\n", + " \n", + " if flip(0.6):\n", + " bike_to_olin()\n", + " print('Moving a bike to Olin')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you run `step` a few times, it should update the current figure. In each time step, the number of bikes at each location might go up, down, or stay the same." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Moving a bike to Wellesley\n", + "Moving a bike to Olin\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin10
wellesley2
\n", + "
" + ], + "text/plain": [ + "olin 10\n", + "wellesley 2\n", + "dtype: int64" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step()\n", + "plot_state()\n", + "bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following function labels the axes and adds a legend to the figure." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def decorate(): \n", + " legend(loc='random string')\n", + " label_axes(title='Olin-Wellesley Bikeshare',\n", + " xlabel='Time step (min)', \n", + " ylabel='Number of bikes')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As always, when you define a function, it has no effect until you run it." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\ProgramData\\Miniconda3\\lib\\site-packages\\matplotlib\\legend.py:326: UserWarning: Unrecognized location \"random string\". Falling back on \"best\"; valid locations are\n", + "\tbest\n", + "\tupper right\n", + "\tupper left\n", + "\tlower left\n", + "\tlower right\n", + "\tright\n", + "\tcenter left\n", + "\tcenter right\n", + "\tlower center\n", + "\tupper center\n", + "\tcenter\n", + "\n", + " six.iterkeys(self.codes))))\n" + ] + } + ], + "source": [ + "plot_state()\n", + "decorate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Change the argument of `legend` to `'random string'` and run `decorate` again. You should get an error message that lists the valid location where you can put the legend." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Optional parameters" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Again let's start with a new `System` object and a new plot." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bikeshare = System(olin=10, wellesley=2)\n", + "newfig()\n", + "plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can make `step` more general by adding parameters. Because these parameters have default values, they are optional." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def step(p1=0.5, p2=0.5):\n", + " print('p1 ->', p1)\n", + " print('p2 ->', p2)\n", + " if flip(p1):\n", + " bike_to_wellesley()\n", + " \n", + " if flip(p2):\n", + " bike_to_olin()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I added print statements, so each time we run `step` we can see the arguments.\n", + "\n", + "If you provide no arguments, you get the default values:" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "p1 -> 0.5\n", + "p2 -> 0.5\n" + ] + } + ], + "source": [ + "step()\n", + "plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you provide one argument, it overrides the first parameter." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "p1 -> 0.4\n", + "p2 -> 0.5\n" + ] + } + ], + "source": [ + "step(0.4)\n", + "plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you provide two arguments, they override both." + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "p1 -> 0.4\n", + "p2 -> 0.2\n" + ] + } + ], + "source": [ + "step(0.4, 0.2)\n", + "plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can specify the names of the parameters you want to override." + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "p1 -> 0.4\n", + "p2 -> 0.2\n" + ] + } + ], + "source": [ + "step(p1=0.4, p2=0.2)\n", + "plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Which means you can override the second parameter and use the default for the first." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "p1 -> 0.5\n", + "p2 -> 0.2\n" + ] + } + ], + "source": [ + "step(p2=0.2)\n", + "plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can combine both forms, but it is not very common:" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "p1 -> 0.4\n", + "p2 -> 0.2\n" + ] + } + ], + "source": [ + "step(0.4, p2=0.2)\n", + "plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One reason it's not common is that it's error prone. The following example causes an error." + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "positional argument follows keyword argument (, line 4)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m4\u001b[0m\n\u001b[1;33m step(p1=0.4, 0.2)\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n" + ] + } + ], + "source": [ + "# If you remove the # at the beginning of the next line and run it, you get\n", + "# SyntaxError: positional argument follows keyword argument\n", + "\n", + "step(p1=0.4, 0.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From the error message, you might infer that arguments like `step(0.4, 0.2)` are called \"positional\" and arguments like `step(p1=0.4, p2=0.2)` are called \"keyword arguments\"." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Write a version of `decorate` that takes an optional parameter named `loc` with default value `'best'`. It should pass the value of `loc` along as an argument to `legend.` Test your function with different values of `loc`. [You can see the list of legal values here](https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.legend)." + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def decorate(loc='best'): \n", + " legend(loc=loc)\n", + " label_axes(title='Olin-Wellesley Bikeshare',\n", + " xlabel='Time step (min)', \n", + " ylabel='Number of bikes')" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "plot_state()\n", + "decorate(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## For loop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before we go on, I'll redefine `step` without the print statements." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def step(p1=0.5, p2=0.5):\n", + " if flip(p1):\n", + " bike_to_wellesley()\n", + " \n", + " if flip(p2):\n", + " bike_to_olin()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And let's start again with a new `System` object and a new figure." + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bikeshare = System(olin=10, wellesley=2)\n", + "newfig()\n", + "plot_state()\n", + "decorate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use a for loop to move 4 bikes from Olin to Wellesley." + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "for i in range(4):\n", + " bike_to_wellesley()\n", + " plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or we can simulate 4 random time steps." + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "for i in range(4):\n", + " step()\n", + " plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If each step corresponds to a minute, we can simulate the rest of the hour like this." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "for i in range(52):\n", + " step(p1=0.4, p2=0.2)\n", + " plot_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Combine the examples from the previous two sections to write a function named `run_steps` that takes three parameters, named `num_steps`, `p1`, and `p2`. It should use a for loop to run `step` the number of times specified by `num_steps`, passing along the specified values of `p1` and `p2`. After each step, it should plot the updated state.\n", + "\n", + "Test your function by creating a new `System` object, creating a new figure, and running `run_steps`." + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here\n", + "def run_steps(num_steps,p1,p2):\n", + " for i in range(num_steps):\n", + " step(p1,p2)\n", + " plot_state()\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [], + "source": [ + "bikeshare = System(olin = 10, wellesley = 2)\n", + "newfig()\n", + "run_steps(2,.7,.3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "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.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} From d695b280ed757f136b9d294b43a2bb23188701a4 Mon Sep 17 00:00:00 2001 From: maxotoadese Date: Wed, 13 Sep 2017 21:34:55 -0400 Subject: [PATCH 02/11] Adding chap02mine --- code/chap02mine.ipynb | 9297 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 9297 insertions(+) create mode 100644 code/chap02mine.ipynb diff --git a/code/chap02mine.ipynb b/code/chap02mine.ipynb new file mode 100644 index 00000000..85219a35 --- /dev/null +++ b/code/chap02mine.ipynb @@ -0,0 +1,9297 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Modeling and Simulation in Python\n", + "\n", + "Chapter 2: Simulation\n", + "\n", + "Copyright 2017 Allen Downey\n", + "\n", + "License: [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We'll start with the same code we saw last time: the magic command that tells Jupyter where to put the figures, and the import statement that gets the functions defined in the `modsim` module." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# If you want the figures to appear in the notebook, \n", + "# and you want to interact with them, use\n", + "# %matplotlib notebook\n", + "\n", + "# If you want the figures to appear in the notebook, \n", + "# and you don't want to interact with them, use\n", + "# %matplotlib inline\n", + "\n", + "# If you want the figures to appear in separate windows, use\n", + "# %matplotlib qt5\n", + "\n", + "%matplotlib notebook\n", + "\n", + "from modsim import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## More than one System object\n", + "\n", + "Here's the code from the previous chapter, with two changes:\n", + "\n", + "1. I've added DocStrings that explain what each function does, and what parameters it takes.\n", + "\n", + "2. I've added a parameter named `system` to the functions so they work with whatever `System` object we give them, instead of always using `bikeshare`. That will be useful soon when we have more than one `System` object." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run_steps(system, num_steps=1, p1=0.5, p2=0.5):\n", + " \"\"\"Simulate the given number of time steps.\n", + " \n", + " system: bikeshare System object\n", + " num_steps: number of time steps\n", + " p1: probability of an Olin->Wellesley customer arrival\n", + " p2: probability of a Wellesley->Olin customer arrival\n", + " \"\"\"\n", + " for i in range(num_steps):\n", + " step(system, p1, p2)\n", + " plot_system(system)\n", + " \n", + "def step(system, p1=0.5, p2=0.5):\n", + " \"\"\"Simulate one minute of time.\n", + " \n", + " system: bikeshare System object\n", + " p1: probability of an Olin->Wellesley customer arrival\n", + " p2: probability of a Wellesley->Olin customer arrival\n", + " \"\"\"\n", + " if flip(p1):\n", + " bike_to_wellesley(system)\n", + " \n", + " if flip(p2):\n", + " bike_to_olin(system)\n", + " \n", + "def bike_to_wellesley(system):\n", + " \"\"\"Move one bike from Olin to Wellesley.\n", + " \n", + " system: bikeshare System object\n", + " \"\"\"\n", + " move_bike(system, 1)\n", + " \n", + "def bike_to_olin(system):\n", + " \"\"\"Move one bike from Wellesley to Olin.\n", + " \n", + " system: bikeshare System object\n", + " \"\"\"\n", + " move_bike(system, -1)\n", + " \n", + "def move_bike(system, n):\n", + " \"\"\"Move a bike.\n", + " \n", + " system: bikeshare System object\n", + " n: +1 to move from Olin to Wellesley or\n", + " -1 to move from Wellesley to Olin\n", + " \"\"\"\n", + " system.olin -= n\n", + " system.wellesley += n\n", + " \n", + "def plot_system(system):\n", + " \"\"\"Plot the current system of the bikeshare system.\n", + " \n", + " system: bikeshare System object\n", + " \"\"\"\n", + " plot(system.olin, 'rs-', label='Olin')\n", + " plot(system.wellesley, 'bo-', label='Wellesley')\n", + " \n", + "def decorate_bikeshare():\n", + " \"\"\"Add a title and label the axes.\"\"\"\n", + " decorate(title='Olin-Wellesley Bikeshare',\n", + " xlabel='Time step (min)', \n", + " ylabel='Number of bikes')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can create more than one `System` object:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin10
wellesley2
\n", + "
" + ], + "text/plain": [ + "olin 10\n", + "wellesley 2\n", + "dtype: int64" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare1 = System(olin=10, wellesley=2)\n", + "bikeshare1" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin10
wellesley2
\n", + "
" + ], + "text/plain": [ + "olin 10\n", + "wellesley 2\n", + "dtype: int64" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare2 = System(olin=10, wellesley=2)\n", + "bikeshare2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And whenever we call a function, we indicate which `System` object to work with:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bike_to_olin(bikeshare1)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'bikeshare2' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mbike_to_wellesley\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbikeshare2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;31mNameError\u001b[0m: name 'bikeshare2' is not defined" + ] + } + ], + "source": [ + "bike_to_wellesley(bikeshare2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And you can confirm that the different systems are getting updated independently:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin11
wellesley1
\n", + "
" + ], + "text/plain": [ + "olin 11\n", + "wellesley 1\n", + "dtype: int64" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare1" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'bikeshare2' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mbikeshare2\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;31mNameError\u001b[0m: name 'bikeshare2' is not defined" + ] + } + ], + "source": [ + "bikeshare2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Negative bikes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the code we have so far, the number of bikes at one of the locations can go negative, and the number of bikes at the other location can exceed the actual number of bikes in the system.\n", + "\n", + "If you run this simulation a few times, it happens quite often." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "IOPub data rate exceeded.\n", + "The notebook server will temporarily stop sending output\n", + "to the client in order to avoid crashing it.\n", + "To change this limit, set the config variable\n", + "`--NotebookApp.iopub_data_rate_limit`.\n" + ] + } + ], + "source": [ + "bikeshare = System(olin=10, wellesley=2)\n", + "newfig()\n", + "plot_system(bikeshare)\n", + "decorate_bikeshare()\n", + "run_steps(bikeshare, 60, 0.4, 0.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The variables `olin` and `wellesley` are created inside `move_bike`, so they are local. When the function ends, they go away.\n", + "\n", + "If you try to access a local variable from outside its function, you get an error:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# If you remove the # from the last line in this cell and run it, you'll get\n", + "# NameError: name 'olin' is not defined\n", + "\n", + "#olin" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Add print statements in `move_bike` so it prints a message each time a customer arrives and doesn't find a bike. Run the simulation again to confirm that it works as you expect. Then you might want to remove the print statements before you go on." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comparison operators" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `if` statements in the previous section used the comparison operator `<`. The other comparison operators are listed in the book.\n", + "\n", + "It is easy to confuse the comparison operator `==` with the assignment operator `=`.\n", + "\n", + "Remember that `=` creates a variable or gives an existing variable a new value." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "x = 5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Whereas `==` compared two values and returns `True` if they are equal." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x == 5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can use `==` in an `if` statement." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "yes, x is 5\n" + ] + } + ], + "source": [ + "if x == 5:\n", + " print('yes, x is 5')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But if you use `=` in an `if` statement, you get an error." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# If you remove the # from the if statement and run it, you'll get\n", + "# SyntaxError: invalid syntax\n", + "\n", + "#if x = 5:\n", + "# print('yes, x is 5')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Add an `else` clause to the `if` statement above, and print an appropriate message.\n", + "\n", + "Replace the `==` operator with one or two of the other comparison operators, and confirm they do what you expect." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Metrics" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have a working simulation, we'll use it to evaluate alternative designs and see how good or bad they are. The metric we'll use is the number of customers who arrive and find no bikes available, which might indicate a design problem." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we'll make a new `System` object that creates and initializes the system variables that will keep track of the metrics." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bikeshare = System(olin=10, wellesley=2, \n", + " olin_empty=0, wellesley_empty=0, clock=0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next we need a version of `move_bike` that updates the metrics." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def move_bike(system, n):\n", + " olin_temp = system.olin - n\n", + " if olin_temp < 0:\n", + " system.olin_empty += 1\n", + " return\n", + " \n", + " wellesley_temp = system.wellesley + n\n", + " if wellesley_temp < 0:\n", + " system.wellesley_empty += 1\n", + " return\n", + " \n", + " system.olin = olin_temp\n", + " system.wellesley = wellesley_temp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now when we run a simulation, it keeps track of unhappy customers." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n", + "10\n", + "11\n", + "12\n", + "13\n", + "14\n", + "15\n", + "16\n", + "17\n", + "18\n", + "19\n", + "20\n", + "21\n", + "22\n", + "23\n", + "24\n", + "25\n", + "26\n", + "27\n", + "28\n", + "29\n", + "30\n", + "31\n", + "32\n", + "33\n", + "34\n", + "35\n", + "36\n", + "37\n", + "38\n", + "39\n", + "40\n", + "41\n", + "42\n", + "43\n", + "44\n", + "45\n", + "46\n", + "47\n", + "48\n", + "49\n", + "50\n", + "51\n", + "52\n", + "53\n", + "54\n", + "55\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "IOPub data rate exceeded.\n", + "The notebook server will temporarily stop sending output\n", + "to the client in order to avoid crashing it.\n", + "To change this limit, set the config variable\n", + "`--NotebookApp.iopub_data_rate_limit`.\n" + ] + } + ], + "source": [ + " newfig()\n", + "plot_system(bikeshare)\n", + "decorate_bikeshare()\n", + "bikeshare.clock=0\n", + "run_steps(bikeshare, 60, 0.4, 0.2)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After the simulation, check the final value of `clock`." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "60\n" + ] + } + ], + "source": [ + " print(bikeshare.clock)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Now suppose we'd like to know how long it takes to run out of bikes at either location. Modify `move_bike` so the first time a student arrives at Olin and doesn't find a bike, it records the value of `clock` in a system variable.\n", + "\n", + "Hint: create a system variable named `t_first_empty` and initialize it to `-1` to indicate that it has not been set yet.\n", + "\n", + "Test your code by running a simulation for 60 minutes and checking the metrics." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'system' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0msystem\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mt_first_empty\u001b[0m\u001b[1;33m=\u001b[0m \u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;31mNameError\u001b[0m: name 'system' is not defined" + ] + } + ], + "source": [ + " system.t_first_empty= -1" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After the simulation, check the final value of `t_first_empty`." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'System' object has no attribute 't_first_empty'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbikeshare\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mt_first_empty\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32mC:\\ProgramData\\Miniconda3\\lib\\site-packages\\pandas\\core\\generic.py\u001b[0m in \u001b[0;36m__getattr__\u001b[1;34m(self, name)\u001b[0m\n\u001b[0;32m 3079\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mname\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_info_axis\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3080\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 3081\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mobject\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__getattribute__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3082\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3083\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m__setattr__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mAttributeError\u001b[0m: 'System' object has no attribute 't_first_empty'" + ] + } + ], + "source": [ + "print(bikeshare.t_first_empty)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before we go on, let's put `step` and `move_bike` back the way we found them, so they don't break the examples below." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def step(system, p1=0.5, p2=0.5):\n", + " if flip(p1):\n", + " bike_to_wellesley(system)\n", + " \n", + " if flip(p2):\n", + " bike_to_olin(system)\n", + "\n", + "def move_bike(system, n):\n", + " olin_temp = system.olin - n\n", + " if olin_temp < 0:\n", + " system.olin_empty += 1\n", + " return\n", + " \n", + " wellesley_temp = system.wellesley + n\n", + " if wellesley_temp < 0:\n", + " system.wellesley_empty += 1\n", + " return\n", + " \n", + " system.olin = olin_temp\n", + " system.wellesley = wellesley_temp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Returning values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here's a simple function that returns a value:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def add_five(x):\n", + " return x + 5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And here's how we call it." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y = add_five(3)\n", + "y" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you run a function on the last line of a cell, Jupyter displays the result:" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "add_five(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "But that can be a bad habit, because usually if you call a function and don't assign the result in a variable, the result gets discarded.\n", + "\n", + "In the following example, Jupyter shows the second result, but the first result just disappears." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "add_five(3)\n", + "add_five(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "When you call a function that returns a variable, it is generally a good idea to assign the result to a variable." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8 10\n" + ] + } + ], + "source": [ + "y1 = add_five(3)\n", + "y2 = add_five(5)\n", + "\n", + "print(y1, y2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Write a function called `make_system` that creates a `System` object with the system variables `olin=10` and `wellesley=2`, and then returns the new `System` object.\n", + "\n", + "Write a line of code that calls `make_system` and assigns the result to a variable." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin10
wellesley2
\n", + "
" + ], + "text/plain": [ + "olin 10\n", + "wellesley 2\n", + "dtype: int64" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def make_system():\n", + " system = System(olin=10, wellesley=2)\n", + " return system\n", + "\n", + "system = make_system()\n", + "system" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Running simulations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before we go on, I want to update `run_steps` so it doesn't always plot the results. The new version takes an additional parameter, `plot_flag`, to indicate whether we want to plot.\n", + "\n", + "\"flag\" is a conventional name for a boolean variable that indicates whether or not a condition is true.\n", + "\n", + "This version of `run_steps` works even if `num_steps` is not an integer. It uses the `int` function to round down. See https://docs.python.org/3/library/functions.html#int" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run_steps(system, num_steps=1, p1=0.5, p2=0.5, plot_flag=True):\n", + " \"\"\"Simulate the given number of time steps.\n", + " \n", + " `num_steps` should be an integer; if not, it gets rounded down.\n", + " \n", + " system: bikeshare System object\n", + " num_steps: number of time steps\n", + " p1: probability of an Olin->Wellesley customer arrival\n", + " p2: probability of a Wellesley->Olin customer arrival\n", + " plot_flag: boolean, whether to plot\n", + " \"\"\"\n", + " for i in range(int(num_steps)):\n", + " step(system, p1, p2)\n", + " if plot_flag:\n", + " plot_system(system)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now when we run a simulation, we can choose not to plot the results:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bikeshare = System(olin=10, wellesley=2, \n", + " olin_empty=0, wellesley_empty=0)\n", + "run_steps(bikeshare, 60, 0.4, 0.2, plot_flag=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But after the simulation, we can still read the metrics." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare.olin_empty" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's wrap all that in a function." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run_simulation():\n", + " system = System(olin=10, wellesley=2, \n", + " olin_empty=0, wellesley_empty=0)\n", + " run_steps(system, 60, 0.4, 0.2, plot_flag=False)\n", + " return system" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And test it." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "system = run_simulation()" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0\n" + ] + } + ], + "source": [ + "print(system.olin_empty, system.wellesley_empty)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we generalize `run_simulation` to take `p1` and `p2`, we can use it to run simulations with a range of values for the parameters." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run_simulation(p1=0.4, p2=0.2):\n", + " bikeshare = System(olin=10, wellesley=2, \n", + " olin_empty=0, wellesley_empty=0)\n", + " run_steps(bikeshare, 60, p1, p2, plot_flag=False)\n", + " return bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When `p1` is small, we probably don't run out of bikes at Olin." + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "system = run_simulation(p1=0.2)\n", + "system.olin_empty" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When `p1` is large, we probably do." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "24" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "system = run_simulation(p1=0.6)\n", + "system.olin_empty" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "**Exercise:** Write a version of `run_simulation` that takes all five model parameters as function parameters." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0\n" + ] + } + ], + "source": [ + "def run_simulation(p1=0.4, p2=0.2, olin=10, wellesley=2, num_steps=60):\n", + " bikeshare = System(olin=olin, wellesley=wellesley, \n", + " olin_empty=0, wellesley_empty=0)\n", + " run_steps(bikeshare, num_steps, p1, p2, plot_flag=False)\n", + " return bikeshare\n", + "\n", + "system = run_simulation(p1=0.2, p2=0.4, olin=3, wellesley=9, num_steps=30)\n", + "print(system.olin_empty, system.wellesley_empty)" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## More for loops" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`linspace` creates a NumPy array of equally spaced numbers." + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0. , 0.25, 0.5 , 0.75, 1. ])" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "p1_array = linspace(start=0, stop=1, num=5)\n", + "p1_array" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use an array in a `for` loop, like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0\n", + "0.25\n", + "0.5\n", + "0.75\n", + "1.0\n" + ] + } + ], + "source": [ + "for p1 in p1_array:\n", + " print(p1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This will come in handy in the next section." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** The function `linspace` is part of NumPy. [You can read the documentation here](https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html).\n", + "\n", + "Use `linspace` to make an array of 10 equally spaced numbers from 1 to 10 (including both)." + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "linspace(1,10,10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** The `modsim` library provides a related function called `linrange`. You can view the documentation by running the following cell:" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on function linrange in module modsim:\n", + "\n", + "linrange(start=0, stop=None, step=1, **kwargs)\n", + " Returns an array of evenly-spaced values in the interval [start, stop].\n", + " \n", + " This function works best if the space between start and stop\n", + " is divisible by step; otherwise the results might be surprising.\n", + " \n", + " By default, the last value in the array is `stop` (at least approximately).\n", + " If you provide the keyword argument `endpoint=False`, the last value\n", + " in the array is `stop-step`. \n", + " \n", + " start: first value\n", + " stop: last value\n", + " step: space between values\n", + " \n", + " Also accepts the same keyword arguments as np.linspace. See\n", + " https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html\n", + " \n", + " returns: array or Quantity\n", + "\n" + ] + } + ], + "source": [ + "help(linrange)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Use `linrange` to make an array of numbers from 1 to 11 with a step size of 2." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1., 3., 5., 7., 9., 11.])" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "linrange(1,11,2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## Sweeping parameters" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following example runs simulations with a range of values for `p1`; after each simulation, it prints the number of unhappy customers at the Olin station:" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "p1_array = linspace(0, 1, 11)\n", + "p1_array" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0 0\n", + "0.1 0\n", + "0.2 0\n", + "0.3 0\n", + "0.4 9\n", + "0.5 9\n", + "0.6 18\n", + "0.7 22\n", + "0.8 20\n", + "0.9 35\n", + "1.0 38\n" + ] + } + ], + "source": [ + "for p1 in p1_array:\n", + " system = run_simulation(p1=p1)\n", + " print(p1, system.olin_empty)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can do the same thing, but plotting the results instead of printing them.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "newfig()\n", + "p1_array = linspace(0, 1, 101)\n", + "parameter_sweep(p1_array)\n", + "decorate_bikeshare(xlabel='Arrival rate at Olin (p1 in customers/min)')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "**Exercise:** Write a function called `parameter_sweep2` that runs simulations with `p1=0.2` and a range of values for `p2`.\n", + "\n", + "Note: If you run `parameter_sweep2` a few times without calling `newfig`, you can plot multiple runs on the same axes, which will give you a sense of how much random variation there is from one run to the next. " + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def parameter_sweep2(p2_array):\n", + " for p2 in p2_array:\n", + " system = run_simulation(p1=0.2, p2=p2)\n", + " plot(p2, system.olin_empty, 'rs', label='Olin')\n", + " plot(p2, system.wellesley_empty, 'bo', label='Wellesley')" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "newfig()\n", + "num_steps_array = linrange(1, 101)\n", + "parameter_sweep3(num_steps_array)\n", + "decorate_bikeshare('Number of time steps (minutes)')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "**Exercise:** The code below runs a simulation with the same parameters 10 times and computes the average number of unhappy customers.\n", + "\n", + "1. Wrap this code in a function called `run_simulations` that takes `num_runs` as a parameter.\n", + "\n", + "2. Test `run_simulations`, and increase `num_runs` until the results are reasonably consistent from one run to the next.\n", + "\n", + "3. Generalize `run_simulations` so it also takes the initial value of `olin` as a parameter.\n", + "\n", + "4. Run the generalized version with `olin=12`. How much do the two extra bikes decrease the average number of unhappy customers.\n", + "\n", + "5. Make a plot that shows the average number of unhappy customers as a function of the initial number of bikes at Olin." + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.3999999999999999" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "num_runs = 10\n", + "total = 0\n", + "for i in range(num_runs):\n", + " system = run_simulation(p1=0.4, p2=0.2, olin=10, wellesley=2, num_steps=60)\n", + " total += system.olin_empty + system.wellesley_empty\n", + "total / num_runs" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run_simulations(olin, num_runs=1000):\n", + " total = 0\n", + " for i in range(num_runs):\n", + " system = run_simulation(p1=0.4, p2=0.2, olin=olin, wellesley=2, num_steps=60)\n", + " total += system.olin_empty + system.wellesley_empty\n", + " return total / num_runs" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.8119999999999998" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "run_simulations(olin=10)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2.4529999999999998" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "run_simulations(olin=12)" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.0 11.022\n", + "4.0 9.06\n", + "6.0 6.818\n", + "8.0 5.101\n", + "10.0 3.658\n", + "12.0 2.284\n", + "14.0 1.357\n", + "16.0 0.783\n", + "18.0 0.357\n" + ] + } + ], + "source": [ + "for olin in linrange(2, 18, 2):\n", + " avg = run_simulations(olin=olin)\n", + " print(olin, avg)" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "newfig()\n", "plot(xs, label='x')\n", @@ -310,7 +1206,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": { "collapsed": true }, @@ -322,9 +1218,799 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "newfig()\n", "plot(xs, ys, label='trajectory')\n", @@ -363,11 +2839,801 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "animate2d(system.results.x, system.results.y)" ] From 7a5f0306871733865b982f6c643f0acc2eae70ba Mon Sep 17 00:00:00 2001 From: maxotoadese Date: Mon, 27 Nov 2017 02:18:04 -0500 Subject: [PATCH 11/11] 9 --- code/Project 3.ipynb | 1552 ++++++++++++++++++++++++++++++++++ code/chap09-fig01.pdf | Bin 0 -> 10619 bytes code/chap09-fig02.pdf | Bin 0 -> 10434 bytes code/chap09mine.ipynb | 1845 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 3397 insertions(+) create mode 100644 code/Project 3.ipynb create mode 100644 code/chap09-fig01.pdf create mode 100644 code/chap09-fig02.pdf create mode 100644 code/chap09mine.ipynb diff --git a/code/Project 3.ipynb b/code/Project 3.ipynb new file mode 100644 index 00000000..94c52d58 --- /dev/null +++ b/code/Project 3.ipynb @@ -0,0 +1,1552 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# If you want the figures to appear in the notebook, \n", + "# and you want to interact with them, use\n", + "# %matplotlib notebook\n", + "\n", + "# If you want the figures to appear in the notebook, \n", + "# and you don't want to interact with them, use\n", + "# %matplotlib inline\n", + "\n", + "# If you want the figures to appear in separate windows, use\n", + "# %matplotlib qt5\n", + "\n", + "# tempo switch from one to another, you have to select Kernel->Restart\n", + "\n", + "%matplotlib inline\n", + "\n", + "\n", + "\n", + "\n", + "from modsim import *" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
t0
\n", + "
" + ], + "text/plain": [ + "t 0\n", + "dtype: int64" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "init = State(t=0)\n", + "init" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
initt 0\n", + "dtype: int64
cod0.72
\n", + "
" + ], + "text/plain": [ + "init t 0\n", + "dtype: int64\n", + "cod 0.72\n", + "dtype: object" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "downforce = System(init=init,\n", + " cod=.72\n", + " )\n", + "downforce" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def update(state, system):\n", + " \"\"\"Update the thermal transfer model.\n", + " \n", + " state: State (temp)\n", + " system: System object\n", + " \n", + " returns: State (temp)\n", + " \"\"\"\n", + " unpack(system)\n", + " T = state.t\n", + " #T += 1\n", + " df= (0.5*(T**2)*0.72)\n", + "\n", + " return df" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "update(init, downforce)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run_simulation(system, update_func):\n", + " \"\"\"Runs a simulation of the system.\n", + " \n", + " Add a TimeFrame to the System: results\n", + " \n", + " system: System object\n", + " update_func: function that updates state\n", + " \"\"\"\n", + " unpack(system)\n", + " \n", + " frame = TimeFrame(columns=init.index)\n", + " frame.loc[0] = init\n", + " ts = linrange(0, 130, 1)\n", + " \n", + " for t in ts:\n", + " frame.loc[t+1] = df= (0.5*(t**2)*0.72)\n", + " \n", + " system.results = frame" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
t
00.00
10.00
20.36
31.44
43.24
55.76
69.00
712.96
817.64
923.04
1029.16
1136.00
1243.56
1351.84
1460.84
1570.56
1681.00
1792.16
18104.04
19116.64
20129.96
21144.00
22158.76
23174.24
24190.44
25207.36
26225.00
27243.36
28262.44
29282.24
......
1023672.36
1033745.44
1043819.24
1053893.76
1063969.00
1074044.96
1084121.64
1094199.04
1104277.16
1114356.00
1124435.56
1134515.84
1144596.84
1154678.56
1164761.00
1174844.16
1184928.04
1195012.64
1205097.96
1215184.00
1225270.76
1235358.24
1245446.44
1255535.36
1265625.00
1275715.36
1285806.44
1295898.24
1305990.76
1316084.00
\n", + "

132 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " t\n", + "0 0.00\n", + "1 0.00\n", + "2 0.36\n", + "3 1.44\n", + "4 3.24\n", + "5 5.76\n", + "6 9.00\n", + "7 12.96\n", + "8 17.64\n", + "9 23.04\n", + "10 29.16\n", + "11 36.00\n", + "12 43.56\n", + "13 51.84\n", + "14 60.84\n", + "15 70.56\n", + "16 81.00\n", + "17 92.16\n", + "18 104.04\n", + "19 116.64\n", + "20 129.96\n", + "21 144.00\n", + "22 158.76\n", + "23 174.24\n", + "24 190.44\n", + "25 207.36\n", + "26 225.00\n", + "27 243.36\n", + "28 262.44\n", + "29 282.24\n", + ".. ...\n", + "102 3672.36\n", + "103 3745.44\n", + "104 3819.24\n", + "105 3893.76\n", + "106 3969.00\n", + "107 4044.96\n", + "108 4121.64\n", + "109 4199.04\n", + "110 4277.16\n", + "111 4356.00\n", + "112 4435.56\n", + "113 4515.84\n", + "114 4596.84\n", + "115 4678.56\n", + "116 4761.00\n", + "117 4844.16\n", + "118 4928.04\n", + "119 5012.64\n", + "120 5097.96\n", + "121 5184.00\n", + "122 5270.76\n", + "123 5358.24\n", + "124 5446.44\n", + "125 5535.36\n", + "126 5625.00\n", + "127 5715.36\n", + "128 5806.44\n", + "129 5898.24\n", + "130 5990.76\n", + "131 6084.00\n", + "\n", + "[132 rows x 1 columns]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "run_simulation(downforce,update)\n", + "downforce.results" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot(downforce.results)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Torque
RPM
8756.147541220.693752
8807.377049223.237408
8838.114754224.509979
8868.852459224.514433
8899.590164227.055120
8909.836066227.056605
8971.311475228.333630
8971.311475228.333630
9053.278689232.149857
9073.770492232.152827
9155.737705232.164707
9186.475410234.705393
9186.475410235.973509
9278.688525235.986873
9278.688525235.986873
9391.393443241.075671
9391.393443241.075671
9534.836066244.900808
9616.803279246.180803
9668.032787247.456344
9739.754098248.734854
9831.967213248.748218
9842.213115248.749703
9913.934426248.760097
9985.655738248.770492
10057.377050250.049002
10098.360660250.054942
10180.327870251.334937
10211.065570252.607508
10231.557380253.878593
......
16040.983610337.148076
16051.229510337.149561
16112.704920337.158470
16122.950820337.159955
16122.950820337.159955
16194.672130335.902233
16235.655740333.371941
16266.393440333.376396
16286.885250333.379366
16338.114750333.386790
16338.114750333.386790
16409.836070332.129069
16461.065570332.136493
16471.311480332.137978
16471.311480332.137978
16532.786890332.146888
16532.786890332.146888
16532.786890332.146888
16584.016390329.618080
16594.262300329.619565
16665.983610328.361844
16665.983610328.361844
16727.459020328.370753
16727.459020328.370753
16788.934430328.379663
16819.672130328.384117
16850.409840328.388572
16911.885250325.861250
16963.114750323.332442
17014.344260322.071751
\n", + "

184 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " Torque\n", + "RPM \n", + "8756.147541 220.693752\n", + "8807.377049 223.237408\n", + "8838.114754 224.509979\n", + "8868.852459 224.514433\n", + "8899.590164 227.055120\n", + "8909.836066 227.056605\n", + "8971.311475 228.333630\n", + "8971.311475 228.333630\n", + "9053.278689 232.149857\n", + "9073.770492 232.152827\n", + "9155.737705 232.164707\n", + "9186.475410 234.705393\n", + "9186.475410 235.973509\n", + "9278.688525 235.986873\n", + "9278.688525 235.986873\n", + "9391.393443 241.075671\n", + "9391.393443 241.075671\n", + "9534.836066 244.900808\n", + "9616.803279 246.180803\n", + "9668.032787 247.456344\n", + "9739.754098 248.734854\n", + "9831.967213 248.748218\n", + "9842.213115 248.749703\n", + "9913.934426 248.760097\n", + "9985.655738 248.770492\n", + "10057.377050 250.049002\n", + "10098.360660 250.054942\n", + "10180.327870 251.334937\n", + "10211.065570 252.607508\n", + "10231.557380 253.878593\n", + "... ...\n", + "16040.983610 337.148076\n", + "16051.229510 337.149561\n", + "16112.704920 337.158470\n", + "16122.950820 337.159955\n", + "16122.950820 337.159955\n", + "16194.672130 335.902233\n", + "16235.655740 333.371941\n", + "16266.393440 333.376396\n", + "16286.885250 333.379366\n", + "16338.114750 333.386790\n", + "16338.114750 333.386790\n", + "16409.836070 332.129069\n", + "16461.065570 332.136493\n", + "16471.311480 332.137978\n", + "16471.311480 332.137978\n", + "16532.786890 332.146888\n", + "16532.786890 332.146888\n", + "16532.786890 332.146888\n", + "16584.016390 329.618080\n", + "16594.262300 329.619565\n", + "16665.983610 328.361844\n", + "16665.983610 328.361844\n", + "16727.459020 328.370753\n", + "16727.459020 328.370753\n", + "16788.934430 328.379663\n", + "16819.672130 328.384117\n", + "16850.409840 328.388572\n", + "16911.885250 325.861250\n", + "16963.114750 323.332442\n", + "17014.344260 322.071751\n", + "\n", + "[184 rows x 1 columns]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data1 = pd.read_csv('Torque_curve.csv',index_col='RPM')\n", + "data1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nGGZrAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot(data1, 'bo', label='Torque')\n", + "decorate(xlabel='RPM (min)',\n", + " ylabel='Torque (mg/dL)')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAD8CAYAAACb4nSYAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X9cVGW+B/DPmWH4NSgw/P4tojAKCAiiJq5slrW2bZZr\nuWmbWJslKtEtpS7c66bX6xVTSzOt+9q7L2W7Vit1t7RryXbZtEQhNEV+CAqiwMAMyO8Z5sdz/xg5\ncAQcwMEB5vt+ZXF+8pwTfnjmOc95Ho4xxkAIIcQqiCxdAEIIIfcPhT4hhFgRCn1CCLEiFPqEEGJF\nbCxdgIGo1WpcunQJHh4eEIvFli4OIYSMCXq9Hg0NDYiIiIC9vX2f7aM29C9duoQVK1ZYuhiEEDIm\n/eUvf0FcXFyf9aM29D08PAAYC+7t7W3h0hBCyNhQV1eHFStW8Bl6p1Eb+t1NOt7e3vD397dwaQgh\nZGwZqFl81IY+IWRsaWpV4+TZ62AMeGROEJyd7CxdJNIP6r1DCLlnzW0a/E9uBRSNHahv6sB3BTdg\njpf9GWNgjMFgYNAbGPR6A3R6A7Q6A7Q6PXR6gxlKb12opk8IGRTGGArLGlBa1QS9wQAwgN1er+7S\no0ur5/e9Ud+KytoWBPs63/WcP16swZXqW5g1zRvTgmX8+lMXbuJiuRJ6w91/cXAch/BgGRJjA+7p\n2qwJhT4hZFDyixXIK6ob9P6nLtQg0GsCxOL+GxTUXTr8VNoAxhhy8q/Dx10Klwl2aG7T4HxZw6C+\nB2MMl66qEDXVA64T+3ZPJH1R6BMyBjS2qFF2vQlaXXcNm4HdrmmDMXTXh43NIYCDnQ3CJ7v1266u\n1xtQUFIPVXPn7Zp6zznY7XOje/3t/+r1BtSq2u9aRomNCAtm+uP78zeh6dKjuU2Dv5wogY1Y1HPe\nXp8O2ju1giag0z/X4LF5wWi41Sk4L8dxxv8CuP0lOI6DwcBguH18VV0Lhf4gUegTMsqV37iFb/Oq\nTDZ13OnSVRV+GeuPqQGugvXfX6jBpQrlsMsT4DUB86P9wHEAB44PYkd7G0hsxOjS6vGPwpsAgJb2\nrkGf91pNM6oVrSitauLXxYR5Yt4M3373L7qqwncF1QCAqrpWRId6DvOKrAuFPiGjFGMM58sa8MPF\n2mE9FO3S6nHiTBXKq29B6iABY8Z1pdebTB88AD8PJyx+IBgSm4H7gERMdkd5dTNqlG1DPv///lgJ\nTa9nA1MDXAbcN8hnIv/1zYY2aHV6SGzo7X1TKPQJGYXqGzvwj/M3UderScXFyQ4RIW7gwAEc+Jr2\n7X/4ZhADYygsredr2RU3m/v9HsG+zpAHuYLjOEGzCQcYTwhA1L0BxuYbT1dHiERcn3P1JhJxWLIg\nBM1tGr75pfd5e3864DgOOr0Bn+WUQaszCAJfHiSDp6vjgN/HyUECdxcHKG91wmBguFihwswwqu2b\nQqFPiIV1qLW42dAGw+3mm5sNbSiubBLU7n3cpHhsXjDs7Qb3VzY00BX/V1CNK9W3+t3uOsEeD8cH\nwlYyMjVjkYgbUht7QpQf31QDGAN9bqSPyeOmB8v4pqT8YgVCA13h5CAZeoGtCIU+IRZUfK0R/yi8\nAe0A/c1FIg7RUz0QH+4NmwF6wfTHTiLGotlBiAhxh7KpU/DJQCzmMNnXecQCfzjCJ7thks9EqLt0\nAIyfagbq9SM8zh2XKlRobFGjS6vHl/+owJLEKXAY5C9Ha0R3hhAL0Or0yP3pJkqqGgfcJ9hnIuZF\n+cFlwvDebOU4Dn4eTvDzcBpuMe8rqYME0iHW0sUiDr+I8cPf/nEVBsagalHjk29L+fP07TUEvqeS\np6sDEmMDhvTLdDwYVOjX1dVh27ZtOHPmDAwGA+bPn4+0tDR4eXkJ9tNqtVi2bBnkcjm2b9/Or1ep\nVHj77bdx+vRpSCQSPPXUU0hNTYWNDf3OIdZH1dyJE2eq0Nii5te5ONnBw9URIg4Qi0UI8XdGkPfE\nu5yFdPP3nICH4gPx7dnrYIyhrVOLtk6tyeMaW9TwlDlixpT+ByYbr0ymLmMML730EmQyGQ4dOgQA\n2Lp1K1555RVkZ2cL9n3vvfdQXFwMuVwuWL9+/XpwHIesrCwoFAqkpaXBxsYGqampZrwUQkY3xhhK\nKpuQW3hDMHyAPEiGBTP9qOfJPQgNdIVez/BdQTX/8HgwapUdmDFlBAs2CpkMfaVSiZCQEPzTP/0T\nP9rlqlWrkJycjObmZjg7G1+zLigowNGjRxEaGio4vrCwEAUFBTh58iQCAgIgl8uxceNGbNmyBcnJ\nybC1tR2ByyJkdGGM4fTPNYI3TW3EIiyI8RcMP0CGb1qwDP5eTmjr0PbbG6m711Bjixrf5FUBAKoV\nrehQa+Fobz0Pf002Znl4eGD37t184NfV1eGTTz5BZGQkH/jt7e3YtGkT0tPT4ebmJjg+Pz8ffn5+\nCAjoGRsjPj4e7e3tKC4uNue1EDIqGQwMp84LA1820R7LFk6lwDezCY628HGXwtvN+MdL5ghPmSM8\nXR3h4eoAdxcHhPi7YIKjsbKp7tIh9yfzDA43VgzpCcbatWuxYMECXLhwAVu3buXXb9u2DZGRkVi8\neHGfYxQKBTw9hX1nu5dra2uHU2ZCxoxaZTsOfP4zLpT3BH6InzOWLZwKN2cHC5bMeolFHB6M66mE\nVtxsRtk9vLA21gwp9FNSUvDZZ59h5syZSEpKgkKhQE5ODnJzc/Gv//qv/R7T2dkJOzth7wOJRAKO\n46DRaIZfckJGOb2B4e/51Xz/e8DYI2fR7CBqv7ewAK8JiJjc0yrxj/M30dYx+CEjxrIhhX5YWBhm\nzJiB3bt3w2Aw4LPPPkNGRga2bt0KF5f+X5e2t7dHV5fwZmq1xoGWHB0HftuOkLHuUrkSTa09PXRC\n/F3wyNxJg+p/TkbeAzN8MVFqbObRdOnxac4VVCtaLVyqkTeoB7l5eXl47LHH+HUODg4ICAhAdnY2\nVCqVoBeORqMBx3E4ceIECgsL4e3tjdzcXME56+vrAaBPl09CxotOjQ5ni3uGIX5ghi8NETDK2ErE\nWDgrEP+TWwEDY+hQa/G3768iNMAFdrbiAUcxdXdxQHiw25j95W0y9GtqavDaa68hMDAQkZGRAIDW\n1lZcu3YNGzZsQGJiomD/TZs2wcPDA6+//joAIDY2Fjt37kRtbS18fIyvVefl5UEqlfbp2knIePHj\nxVpouozjyLg42SFqiruFS0T64+fhhMfnT8Y3eVXo1OjAGBvUgHTFlY14ZPakYb84Z0kmf1VFREQg\nLi4O6enp+Pnnn3H58mW8+uqrkMlk+O1vf4ugoCDBH3t7e0ilUgQFBQEAYmJiEB0djdTUVBQVFSE3\nNxeZmZlISkqi7ppkXCooUeDyNRW/PC/Kd8zWCq1BgNcE/G5RGAK8Jgz6mIamTnxyshTlA4xtNJqZ\nrOmLRCLs3bsXO3bswJo1a6DRaJCQkICsrCxIpVKT34DjOOzbtw+bN2/GihUrIJVKsWzZMiQnJ5vl\nAgixJHWXDqcv1MDOVow5ET4oqWzEjxd7eqVN9nPGJB96s3a0c7SX4DfzJ6OqrhXNrZoBRzFt6+hC\nQWk9DAYGrc6Ab/KqIHO2h2wMTeAyqHEQZDKZYFiFu/nzn//cZ52Hhwfef//9IRWMkLHg1Pkafvwc\nxiCo4ft7OmHR7CB+yGMyunEcZ/wFbWJwz2BfZ5zIq+KHjr58TYWEKL/7U0gzoM+chAxTW6cWZdU9\n7b8XrjQYpzMEMFFqi8fmBVvdYF7WwFPmiF/E9IR8aVUT9AOMkjoa0YhnhAzTxXKloA9+b5P9nKkv\n/jgW4DkBTg4StHVq0anR4YeLtXB2Mj6jtJOIETzKhq7ujUKfkGHQ6vS4dHXgeWZphMzxTSTiMG2S\nDOeKFQCMn/J6myi1xSNzJsFLNvreRaLQJ2QYSiqb+C6Zzk528JY58l39JDYi+Lqb7uRAxrZpwW74\nqbS+3wnrW9q7cPTvVzBT7glnqR0YGLqH93F3cbDoLwMKfUKGyGBgON+rZhc11R0hfi642dCGtk4t\npo/hF3fI4E2U2uLXCZNx9WYzGIw9fBiAK9eboNHqYWAM+bc/CfTGcRx+M3/ykLqImhOFPiFDoNbo\nkHPuOprbjONG2dmKMW2SDBIbMZ5+KBTNbV3wHIUf6cnICPCa0Ce8Y0I98E1eFRSNHf0ewxhDXlEd\n/D2dLNKzi0KfkH4wxlBZ24LW24NwMQNgYAw/lyv5dQAQNdWDf2DraC+xqnHZSf+cnezw1C+n4vJV\nFRSNHcb+/rezvbSqCXoDQ52qHTcb2uDvef9r+xT6hNyBMYZ/FN7ExYqBH9QCQHSoB+LkNH4U6Uss\n4hA5xR2Rd6znOA5FV43vcpw8ex3PPzb9vtf2qeGRkF4YY/jhYu1dA9/OVozH5gUjIcoPIhG9eEUG\nb2aYJ0S3Q76tU4u//v0K2gcxn685UU2fkNsMBoZTF27i5/KewPf3dOJfsec4Dg52NpAHucLJkcaN\nIkPn7GSH0EAXlFQZe3opGjtw5NtS/CLGDxOldvwMXoyB/9pWIoabs73ZPhFQ6BMC8OOoXKtp5tdN\n9nPGI3MmQUy1eWJGCVF+0GgN/M9ap0aHE2eq7npMTJgn5s3wNcv3p+YdYvUUjR34a06ZIPBD/F3w\nyOwgCnxidvZ2NnhsXjCWLAiBdJAP/s+XNUB5q9Ms359q+sRq6fQG5BXV4XxZg2Bi7JgwTzwQ6UMD\npZER5e85Ac88HIqzRXWobzIGurGnj/HnjgPQ2tGFtk7jTIPfn7+JJQtC7vnnkkKfWKXuWZJ6154k\nYhESov0Q3mvuVEJGkqO9BImxAQNub2xR48g3pTAwhpsNbai42Ywp/v1PTTtY1LxDrI66S4cv7wh8\nf88JWL4ojAKfjCqyifaI7DXr2g8/10B3jyN6UugTq9LYosb/5Fag4Vb3x2kOC2L88cQvJsPZaexN\nfUfGv1nTveBgZ2yUaWnvQnFl4z2dj0KfWAW9wTgOyifflvKBDwAPxgYgcoo7td+TUcve1gaxck9+\nuXCAQd4Gi9r0yZjQqdHh5NnraGpVA4BgHHvGjANdCfo4w7iyez1jEHwsFomMNfxpwbL7eRmEDEv4\nZDcUlNSjU6NDS3sXyqqahv2zS6FPxoTiykZU1bWY5VxeMkc8GBcAN2cHs5yPkJEmsREjaqoHzlwy\nzr9cUKLA1ECXYc3MRs07ZEywt733WYjsbMV4YIYvlv5yKgU+GXMip7jD7vZsXLfaNDj+w7VhTdM4\nqJp+XV0dtm3bhjNnzsBgMGD+/PlIS0uDl5dxsKmsrCxkZWWhrq4Ovr6+SEpKwrJly/jjVSoV3n77\nbZw+fRoSiQRPPfUUUlNTYWNDHzTI4LhOsOe/tpWIsfzhMPDvTXEcOPSMZMjdXsbt5e6xTmzEIhor\nh4xZdhIx5kT4ILfwBgDgel0rTp6rxiNzgoZ0HpOpyxjDSy+9BJlMhkOHDgEAtm7dildeeQXZ2dn4\n+OOP8c4772Dz5s2IiYlBXl4e/vjHP0IikWDJkiUAgPXr14PjOGRlZUGhUCAtLQ02NjZITU0d6nUT\nK1Wraue/9nOXYqKUxr4h1idyijs6NTqcvVwHALhS3YT50b5DGtLbZPOOUqlESEgItm7dCrlcDrlc\njlWrVqGoqAjNzc04cuQInn32WTzxxBMIDAzEsmXL8Jvf/AbZ2dkAgMLCQhQUFGD79u2Qy+VYsGAB\nNm7ciMOHD6Orq8vEdyfE6OrN3mPi3NvLKYSMZbOme2F2uDdsxCIE+0zku3MOlsm9PTw8sHv3bn65\nrq4On3zyCSIjI+Hs7Iz09HT4+PgIjhGJRGhpMT50y8/Ph5+fHwICet46i4+PR3t7O4qLixEVFTWk\nAhPr09apRd3tmr6I4zDJlyYdJ9aL4zjMmu6NmWGew5qWc0i/ItauXYucnBw4OzvzTT3x8fGCfWpq\nanDs2DGsXLkSAKBQKODp6SnYp3u5traWQp+YdK1XLd/Xw2nINRtCxqPhzsM8pL89KSkpePnll7F/\n/34kJSXhiy++4B/mAkBjYyPWrFkDd3d3vPTSSwCAzs5O2NkJ33SUSCTgOA4ajWZYhSbji/JWJypr\nW2AwMBhu96kHevrdX6vp6aoZ4udsiSISMm4MKfTDwsIAALt370ZiYiI+//xzvPzyywCA6upqvPji\ni1Cr1cjKysKECca5H+3t7fu03Wu1xlHjHB1pAmlrd7OhDV9+f3XQ44kEU+gTck9Mhr5SqUReXh4e\ne+wxfp2DgwMCAgKgUCgAAEVFRfjDH/4AZ2dnHDlyRNDG7+3tjdzcXME56+vrAUDwKYGMb1qdHlV1\nrejS6vmavE5nwJmi2kEHfpD3RDg50MTjhNwLk6FfU1OD1157DYGBgYiMNE7z29raimvXruHJJ59E\nRUUFVq9ejcDAQHz44YdwdXUVHB8bG4udO3eitraW/2WQl5cHqVQKuVw+ApdERqMTZ6pQWTvwG7VS\newnCJ7sJxxPnAA4cwBn7KIf4Uy2fkHtlMvQjIiIQFxeH9PR0bNmyBTY2NnjnnXcgk8mwZMkSPP/8\n87C1tcWOHTug0+nQ0NAAABCLxZDJZIiJiUF0dDRSU1ORkZEBpVKJzMxMJCUlwdaW+lpbg8YW9V0D\n38HOBk8sCOHnoiWEjByToS8SibB3717s2LEDa9asgUajQUJCArKyslBfX4+LFy8CAB599FHBcYGB\ngfj222/BcRz27duHzZs3Y8WKFZBKpVi2bBmSk5NH5orIqNN7KFjZRHt4uznytXkbsQgRIW6CN24J\nISNnUA9yZTIZtm/f3u+20tJSk8d7eHjg/fffH1rJyLigNzCUVjXxyw/M8MUkH+pnT4il0IBrZMQw\nxpB/uQ4dai0AwMlBgkCvCRYuFSHWjd5yISOiQ63FyXPXcb2ulV8XFiSjAc8IsTAKfWJ2Wp0e2d+V\n41Zbz8t3Pm5SxE3zvMtRhJD7gUKfmF15dbMg8GeGeWJ2hA/EVMsnxOIo9InZ3WzoadKZNc0LsyN8\n7rI3IeR+oge5xKwYY7hR38YvT/KlF6oIGU0o9IlZNbd1oa3T2FvHViKGhwtNS0jIaEKhT8zqZkNP\nLd/PXUq9dQgZZSj0iVndqO9pz/fzdLJgSQgh/aHQJ2aj1xtwXdEr9D3oRSxCRhsKfWI2V2uaoenS\nAwAmSm3h7kLj6RAy2lDoE7O5Un2L/1o+ScYPqkYIGT0o9IlZMMZQ09DOL0/xd7FgaQghA6HQJ2bR\n2KKGuksHwDg+vusEOxNHEEIsgUKfmEWtsqeW7+supaYdQkYpCn1iFjd7Ne34uEstWBJCyN1Q6JN7\nxhhDrbLnpSxfd+qfT8hoRaFP7llLe8/QCxIbEdxp6AVCRi0KfXLPalXCph0aeoGQ0YtCn9wTnd6A\nogoVv0xNO4SMbhT6ZNj0egP+98dKQU0/yJsmPSdkNBtU6NfV1WHDhg2Ij49HXFwcUlNToVAo+O2n\nTp3CE088gRkzZuDxxx9Hbm6u4HiVSoWUlBTExcVh7ty5yMzMhE6nM++VkPuuoLQelbUt/PKcCB94\nuFJ7PiGjmcnQZ4zhpZdeQktLCw4dOoSsrCw0NDTglVdeAQCUl5fjlVdewaOPPorPP/8cCxcuRHJy\nMq5cucKfY/369VAqlcjKysL27duRnZ2NvXv3jtxVkfvi6s1m/uuZYZ6Im+ZlwdIQQgbDZOgrlUqE\nhIRg69atkMvlkMvlWLVqFYqKitDc3IxDhw4hOjoar7zyCkJCQvDqq68iJiYGhw4dAgAUFhaioKAA\n27dvh1wux4IFC7Bx40YcPnwYXV1dI36BZGRotHqomtUAAI7jKPAJGSNMhr6Hhwd2794Nf39/AMam\nnk8++QSRkZFwdnZGfn4+4uPjBcfMnj0b+fn5AID8/Hz4+fkhICCA3x4fH4/29nYUFxeb81rIfVSn\nagdjDADg7mwPW4nYwiUihAzGkCZGX7t2LXJycuDs7MzX5Ovq6uDlJazleXp6oq6uDgCgUCjg6enZ\nZzsA1NbWIioqatiFJ5ZTp6Q3cAkZi4bUeyclJQWfffYZZs6ciaSkJCgUCqjVatja2gr2s7W1hUaj\nAQB0dnbCzk44+JZEIgHHcfw+ZOypVXXwX3u7UegTMlYMKfTDwsIwY8YM7N69GwaDAZ9//jns7Oyg\n1WoF+3V1dcHBwdiLw97evk/bvVarBWMMjo6O91h8YgkGA4OiUTjAGiFkbBjUg9xjx44J1jk4OCAg\nIAAKhQI+Pj6or68XbK+vr+ebfLy9vdHQ0NBnO4A+zUJkbFDe6oRWZwAAODlI4ORoa+IIQshoYTL0\na2pq8Nprr+HixYv8utbWVly7dg1TpkxBbGwszp07JzgmLy8PcXFxAIDY2FhUV1ejtrZWsF0qlUIu\nl5vrOsh9JBx2gd7AJWQsMRn6ERERiIuLQ3p6On7++WdcvnwZr776KmQyGZYsWYKVK1ciPz8f7733\nHioqKvDuu+/iwoULeP755wEAMTExiI6ORmpqKoqKipCbm4vMzEwkJSX1eRZAxoY6QehTEx0hY4nJ\n0BeJRNi7dy+mTZuGNWvWYOXKlZBKpcjKyoJUKkVYWBj27duHEydOYMmSJfj73/+OAwcOICQkBICx\nD/e+ffvg5uaGFStW4K233sKyZcuQnJw84hdHzM84jHKv0Hejmj4hY8mgumzKZDJs3759wO2JiYlI\nTEwccLuHhwfef//9IReOjD7KW2rBMMpuzvYWLhEhZChowDUyJMWVPSNqTvJxpmGUCRljKPTJoOn0\nBpReb+KXpwfLLFgaQshwUOiTQbtW0wxNlx4AMFFqC39Pas8nZKyh0CeDVnytkf9aPkkGjqOmHULG\nGgp9MiitHV2orjdOfs5xHORB1LRDyFhEoU8GpaSykR9V09/TCROl9I4FIWMRhT4xiTGG4sqepp1p\nk6iWT8hYRaFPTLpR34aWduOgeXa2Ykz2c7ZwiQghw0WhT0wq6VXLDwt0hY2YfmwIGavoby+5K61O\nj4pec+FOm+RmwdIQQu4VhT65qxplO3R64zDKson28HB1sHCJCCH3gkKf3NXN2900AdDLWISMAxT6\n5K5uNvQO/QkWLAkhxBwo9MmANFo96ps6ARhfyPL1oGkRCRnrKPTJgGoa2vgXstxd7GFvO6iRuAkh\noxiFPhkQNe0QMv5Q6JMB3ej9ENeDHuISMh5Q6JN+qTU6KG8Z2/NFHAcfd2rPJ2Q8oNAn/brRq2nH\nU+YIW4nYgqUhhJgLhT7pV+/++X7UtEPIuEGhT/olfIhLoU/IeDGo0Fcqldi0aRMSEhIQFxeHF154\nAWVlZfz2r7/+Go8//jiio6OxePFiHD16VHC8SqVCSkoK4uLiMHfuXGRmZkKn05n3SojZ3GrVoLFF\nDQAQi6g9n5DxxGTHa4PBgHXr1oExhv3798PR0RF79+7FqlWrcOzYMVRUVOD1119HRkYG5s2bh9On\nTyMjIwNubm5ITEwEAKxfvx4cxyErKwsKhQJpaWmwsbFBamrqSF8fGQLGGNo7tfjy1FV+nbeblEbV\nJGQcMRn6JSUlKCwsxPHjxxESEgIAyMzMRHx8PHJzc1FaWoqwsDAsX74cALB8+XL89a9/xalTp5CY\nmIjCwkIUFBTg5MmTCAgIgFwux8aNG7FlyxYkJyfD1pZmYBoNSqoa8X3hTWi0en6dWMRhdri3BUtF\nCDE3k1U4Hx8fHDx4EMHBwfy67gmxm5ub4erqiitXruDMmTNgjOHcuXO4cuUKIiIiAAD5+fnw8/ND\nQEAAf3x8fDza29tRXFxs7ushw3TmYq0g8EUch0fnToIvPcQlZFwxWdN3dXXlm2m6HT58GGq1GgkJ\nCfD29kZhYSGef/55iMVi6PV6rF69GkuWLAEAKBQKeHp6Co7vXq6trUVUVJSZLoUMV4dai7ZOLb9s\nb2uDxFh/BPvSDFmEjDdDHkwlJycHu3btQlJSEkJCQlBdXQ2lUok33ngD8+bNQ35+Pnbu3ImQkBD8\n9re/RWdnJ+zs7ATnkEgk4DgOGo3GbBdChq/h9ktYgLEN/7cPTrVgaQghI2lIoZ+dnY2MjAwsXrwY\nb7zxBgAgPT0d06ZNw4svvggAmDZtGhobG5GZmYmlS5fC3t4eXV1dgvNotVowxuDo6GimyyD3oqGp\nJ/TdXWiSFELGs0F3y/jggw/w5ptvYvny5dixYwdEIuOhFy5cQGRkpGDfqKgo3Lp1Cy0tLfD29kZD\nQ4Nge319PQDAy8vrXstP7pFOb0BpVRO/7EGhT8i4NqjQ/+ijj7Bnzx5s2LABGRkZ/INcwBjcpaWl\ngv3Lysrg4uICZ2dnxMbGorq6GrW1tfz2vLw8SKVSyOVyM10GGa68ojo0tRr75EtsRAj2nWjhEhFC\nRtKgumzu3r0bS5cuxdNPPy2otUulUvz+97/Hv//7vyMkJAQJCQk4f/48Dh48iOTkZABATEwMoqOj\nkZqaioyMDCiVSmRmZiIpKYm6a1pYrbId58t6/n/Om+ELR3uJBUtECBlpJkP/+PHj0Ov1OHr0aJ83\nbVNSUrB27VrY2tri0KFD+I//+A/4+vritddew7PPPgvA2L1z37592Lx5M1asWAGpVIply5bxvxSI\nZej0BuTkX+cnSQnwmoDwyW4WLhUhZKRxrPtv/Shz48YNLFy4EDk5OfD397d0ccad0qpGfHv2OgDA\nViLG7xaFYYIjffIiZKwzlZ30fr2Valf3jH0kD3KlwCfESlDoE4hpbB1CrAb9bSeEECtCoW+lunqN\ns0MIsR4U+lZIrdHhUoWKX3ZxsrvL3oSQ8YRC3wqdu6yAusv4IHei1BZhQa4WLhEh5H6h0LcyjS1q\nXKxQ8svzZvjSJCmEWBH6225FGGM4deEmDLdfzfDzcMJkPxo+mRBrQqFvRarqWnG9rhWA8U3p+dF+\ngnGUCCHj35DH0ydjj05vwMVyJfJLFPy68GAZDaNMiBWi0B/H9AaGkspGnLtcJ5gZy04iRjzNfUuI\nVaLQH6cYYzh2+irfnNNtotQWC2cF0miahFgpCv1xqriyURD4jvYSzJrmhenBMhp2gRArRqE/DnVp\n9ThzqY5fbiRxAAAXJ0lEQVRfDp/shoQoX0hsxBYsFSFkNKAq3ziUX6xAh9rYhu/kIKHAJ4TwKPTH\nmeY2DS5c6ZkNa26kDwU+IYRHoT/O/PBzDfQG48tXXjJHhAbSEAuEkB4U+uPIjfpWVNxs5pfp5StC\nyJ0o9MeRoquN/Ndhga7wdpNasDSEkNGIQn8cabjVwX8dOcXdgiUhhIxWFPrjREGJArdaNQAAEcfR\nEAuEkH4NKvSVSiU2bdqEhIQExMXF4YUXXkBZWRm/vby8HKtXr0ZUVBTmz5+PPXv2wGAw8NtVKhVS\nUlIQFxeHuXPnIjMzEzqdrr9vRYbgWk0z/vZ9BY7+/Qp+vFjLrw8NdKXhkgkh/TL5cpbBYMC6devA\nGMP+/fvh6OiIvXv3YtWqVTh27BgYY3juuecwZ84cfP7557h69SrS0tIwYcIEvPDCCwCA9evXg+M4\nZGVlQaFQIC0tDTY2NkhNTR3xCxyvOtRa/O+PlXxPnW7+nhOQGOtvmUIRQkY9k6FfUlKCwsJCHD9+\nHCEhIQCAzMxMxMfHIzc3F9evX4eTkxN27NgBiUSCyZMnY9WqVSgsLAQAFBYWoqCgACdPnkRAQADk\ncjk2btyILVu2IDk5Gba2tiN7heOQVmfAn74s6rPe112Kx+ZNolo+IWRAJkPfx8cHBw8eRHBwML+u\nuxtgc3MzTp06hYceeggSSc8AXuvWreO/zs/Ph5+fHwICAvh18fHxaG9vR3FxMaKiosxyIdbk4Oc/\nC5bnRPjA39MJHq6OEIuoiyYhZGAmq4Surq5ITEyESNSz6+HDh6FWq5GQkIDKykq4u7tjy5YtmD9/\nPh599FEcPHgQer0eAKBQKODp6Sk4Z/dybW0tyNCUXW/qsy4mzBPeblIKfEKISUNuB8jJycGuXbuQ\nlJSEkJAQtLW14cCBAxCLxThw4ABefvllfPTRR9i3bx8AoLOzE3Z2doJzSCQScBwHjUZjnquwEgYD\nwzd5VYJ1cyJ8KOwJIYM2pFE2s7OzkZGRgcWLF+ONN94wnsDGBmFhYXjrrbcAAOHh4VCpVNi/fz9S\nUlJgb2+Prq4uwXm0Wi0YY3B0dDTTZViHi+XKPuumB8ssUBJCyFg16Jr+Bx98gDfffBPLly/Hjh07\n+OYeLy8vhIaGCvadMmUK2tra0NTUBG9vbzQ0NAi219fX88eSwdFo9fj+wk3BOnmQK02GQggZkkGF\n/kcffYQ9e/Zgw4YNyMjIEIznEhcXh4sXLwr2Lysrg4uLC5ydnREbG4vq6mpB+31eXh6kUinkcrmZ\nLmP8O3e5rs+6qKme/exJCCEDMxn6JSUl2L17N5YuXYqnn34aDQ0N/J+Ojg6sXr0apaWl2LZtG6qq\nqvDNN9/gww8/xHPPPQeRSISYmBhER0cjNTUVRUVFyM3NRWZmJpKSkqi75iDdatXgfJnw05KHqwM8\nXOmtW0LI0Jhs0z9+/Dj0ej2OHj2Ko0ePCralpKRg7dq1+K//+i9kZmbiv//7vyGTybB69WqsWbMG\ngLF75759+7B582asWLECUqkUy5YtQ3Jy8shc0Th0+o5mHQCIn04TmxNCho5jjDHTu91/N27cwMKF\nC5GTkwN/f+t9w7Ra0Yr/+UcFv+wlc8SMKe4IC6IHuISQvkxlJ82RO0rp9AbUN3Xgy++v8uumTZJh\n4axAC5aKEDLWUeiPQl1aPY58W4qW9p6urhIbEeZE+FiwVISQ8YAGaRmFSquaBIEPAHHTvCB1oO6Z\nhJB7Q6E/yjDGcPmaSrAuOtQD0aHUPZMQcu+oeWeUKb9xCw23OgEAYhGHpMfDYW9L/5sIIeZBNf1R\npL6xA6cv1PDLkVPcKfAJIWZFiTIK6PQGnC2qQ2FZA7p70DrY2SBuGg1TQQgxLwp9C9HpDfjxYi3K\nrjdBo9XD0GsGLIlYhAfjAqiWTwgxO0oVC2hqVePEmSoob7fd9+bv6YRfxgbA2cmunyMJIeTeUOib\nSYdai7NFdVA0doABYLf/1f01A8Ptf9DeqYVObxAc72gvQfx0L4RPdhMMaEcIIeZEoW8GNxva8M2Z\nKrSrtUM6TizikBDtB3mQDDZijsKeEDLiKPTvAWMMhaUN+PFSLYY6hJFsoj0ejg+ikTIJIfcVhf49\nOFeswNminnHuHexs8IsYP7g42YPjgO6Ke3cNvntZxHGYKLWlmj0h5L6j0B8Gxhh+Kq0XBL6vuxSL\nZgfByZHmCCCEjF4U+kPU0t6F7wqqUa1o5dcFek3AY/OCIRbTu26EkNGNQn+QGGMouqrC6Z9roNX1\n9LzxdXfCrx6gwCeEjA0U+oP0U2k9frzYM88vx3GInuqB2RHesKHAJ4SMERT6g1BS1SgIfNlEezwY\nFwBvN6kFS0UIIUNHoW9CVV0L/n6uml/293TCrxMmU+2eEDImUXLdRX1jB/73x0oYbvfBd3dxwK8e\nCKbAJ4SMWYNKL6VSiU2bNiEhIQFxcXF44YUXUFZW1mc/rVaLJUuWIC0tTbBepVIhJSUFcXFxmDt3\nLjIzM6HT6cxzBSOkuU2DL09d5R/aTnC0xa8TJsNOIrZwyQghZPhMhr7BYMC6detQWVmJ/fv348iR\nI3BycsKqVavQ1NQk2Pe9995DcXFxn3OsX78eSqUSWVlZ2L59O7Kzs7F3717zXYWZdai1+PL7q+jU\nGH8x2dmK8fj8yXCi6QoJIWOcydAvKSlBYWEhtm3bhhkzZmDKlCnIzMxER0cHcnNz+f0KCgpw9OhR\nhIaGCo4vLCxEQUEBtm/fDrlcjgULFmDjxo04fPgwurq67vx2FscYw4kzVbjVpgEA2IhFeGxeMGQT\n7S1cMkIIuXcmQ9/HxwcHDx5EcHAwv657+IDm5mYAQHt7OzZt2oT09HS4ubkJjs/Pz4efnx8CAgL4\ndfHx8Whvb+/3U4GlVda24GZDGwDjdT4cHwhfdycLl4oQQszDZOi7uroiMTERIlHProcPH4ZarUZC\nQgIAYNu2bYiMjMTixYv7HK9QKODpKZzUu3u5tra2z/6WZDAwnOnVNXPGFHeE+LtYsESEEGJeQ+6y\nmZOTg127diEpKQkhISHIyclBbm4uvvrqq3737+zshJ2dcEIQiUQCjuOg0WiGV+oRUlbdBFWLGgAg\nsREhVu5p4ghCCBlbhtT3MDs7Gxs2bMCvfvUrvPHGG2hsbERGRga2bt0KF5f+a8T29vZ92u61Wi0Y\nY3B0dBx+yc1Mf3ue2m4xoZ5wtKcHt4SQ8WXQNf0PPvgAe/bswcqVK5Geng6O45CbmwuVSoXU1FR+\nP41GA47jcOLECRQWFsLb21vwwBcA6uvrAQBeXqNn4u/L1xrR0m785WRva4PoUA8Ll4gQQsxvUKH/\n0UcfYc+ePdiwYQOSk5P59Q8//DBmzpwp2HfTpk3w8PDA66+/DgCIjY3Fzp07UVtbCx8fHwBAXl4e\npFIp5HK5ua7jnmh1epwrVvDLsXJP2FJ/fELIOGQy9EtKSrB7924sXboUTz/9NBoaGvhtUqkUQUFB\ngv3t7e0F62NiYhAdHY3U1FRkZGRAqVQiMzMTSUlJsLUdHWPPX7iiRMftqQ6dHCSInOJu4RIRQsjI\nMBn6x48fh16vx9GjR3H06FHBtpSUFKxdu/aux3Mch3379mHz5s1YsWIFpFIpli1bJvjEcL+VXW/C\n2ct10HTpAYD/LwDMmk6jZhJCxi+ODXVy1/vkxo0bWLhwIXJycuDv72/Wc//5qyK0dfadxNzFyQ7P\nPiKHSETTGBJCxiZT2WmVVVp1r5p9N4mNCAtm+lPgE0LGNasbWlmvN8Bg6Plw8/xj02EjFsHWRkSz\nXxFCxj2rC/0aZTs/VPJEqS0m0ETmhBArYnVV26q6Fv7rST4TLVgSQgi5/8Z9Tf9aTTMqbtyC3gAA\nDDfq2/htQd4U+oQQ6zKuQ1/V3Imvf+iZ+ao3G7EIfp40eiYhxLqM6+ads5cV/QY+AIQFuVJ/fEKI\n1Rm3Nf2Gpk5U3LjFLy+I8YedrRgcZxxbx9eDavmEEOszbkP/7OWeETND/JxpaAVCCME4bd5RNHbg\nWo1xVi+O4xAf7m3hEhFCyOgwLkM/r6hn9qsp/s5wc3awYGkIIWT0GFfNO4wxnC9rwPW6VgC3a/nT\nqZZPCCHdxk3oq7t0yP3pBq5U9zy8DQt0getEewuWihBCRpdxEfo6vQF/zbmCW209c+76uEmREO1n\nwVIRQsjoMy5C/0Z9myDwpwa4YOGsQOqHTwghdxgXoV9V2zOejoOdDRbNDgLH0RDJhBBypzFfFdbq\n9LhYoeSXH5lDgU8IIQMZ0zX9WmU7jn53hV+2lYjh4ya1YIkIIWR0G7M1fb2B4buCasG6AK8JNBEK\nIYTcxZhNyKKrSjS2qPllL5kj5kb4WLBEhBAy+o3J5h2d3oD84np++YFIX8yUe1qwRIQQMjYMqqav\nVCqxadMmJCQkIC4uDi+88ALKysr47VlZWXj00UcRHR2NxYsX47PPPhMcr1KpkJKSgri4OMydOxeZ\nmZnQ6XTDLnRxZSM61FoAgJODBDOm0mBqhBAyGCZr+gaDAevWrQNjDPv374ejoyP27t2LVatW4dix\nY/j666/xzjvvYPPmzYiJiUFeXh7++Mc/QiKRYMmSJQCA9evXg+M4ZGVlQaFQIC0tDTY2NkhNTR1y\ngfUGhsLSnlp+dKgH9ccnhJBBMhn6JSUlKCwsxPHjxxESEgIAyMzMRHx8PHJzc3HkyBE8++yzeOKJ\nJwAAgYGBKCwsRHZ2NpYsWYLCwkIUFBTg5MmTCAgIgFwux8aNG7FlyxYkJyfD1nZoE5NfqW5CS3sX\nAOO4+OGT3YZ6zYQQYrVMhr6Pjw8OHjyI4OBgfl13P/jm5makp6fDx0f4AFUkEqGlxfjCVH5+Pvz8\n/BAQEMBvj4+PR3t7O4qLixEVFTWkAt/sNcdtdKgHJDbiIR1PCCHWzGS7iKurKxITEyES9ex6+PBh\nqNVqJCQkID4+XhDoNTU1OHbsGObPnw8AUCgU8PQUPmTtXq6trcVQTfKZCBHHwUvmiBk0MQohhAzJ\nkHvv5OTkYNeuXUhKSuKbe7o1NjZizZo1cHd3x0svvQQA6OzshJ2dnWA/iUQCjuOg0WgwVCH+Lnhl\nqTMYA0QievOWEEKGYkhPQLOzs7Fhwwb86le/whtvvCHYVl1djd/97ndoaWnBn/70J0yYMAEAYG9v\nj66uLsG+Wq0WjDE4OjoOq9Acx1HgE0LIMAy6pv/BBx9gz549WLlyJdLT0wXj2xQVFeEPf/gDnJ2d\nceTIEUEbv7e3N3JzcwXnqq839r7x8vIa8Pvp9XoAQF1d3YD7EEIIEerOzO4MvdOgQv+jjz7Cnj17\nsGHDBiQnJwu2VVRUYPXq1QgMDMSHH34IV1dXwfbY2Fjs3LkTtbW1/C+DvLw8SKVSyOXyAb9nQ0MD\nAGDFihWDKSIhhJBeGhoaEBQU1Gc9xxhjdzuwpKQETz31FJYsWdKnX71UKsXvf/97KBQKHDp0CE5O\nTvw2sVgMmUwGxhiWL18OjuOQkZEBpVKJtLQ0PPvss1i/fv2A31etVuPSpUvw8PCAWEw9dAghZDD0\nej0aGhoQEREBe/u+MweaDP1du3bh4MGD/W5bv3499u7d2++2wMBAfPvttwCMv3E2b96M06dPQyqV\nYunSpXj11VcFPYIIIYSMPJOhTwghZPygqjYhhFgRCn1CCLEiFPqEEGJFKPQJIcSKUOgP07/8y7/g\nn//5nwXrTp06hSeeeAIzZszA448/3ueltMHMK/DnP/8Zv/zlLxEVFYWkpCRUVlYKtl+8eBHLly9H\nVFQUFi1ahC+++GJErm+k9HffzDEfgzXet25arRZLlixBWlqaYD3dt/7vW3l5OVavXo2oqCjMnz8f\ne/bsgcFg4LeP+/vGyJAYDAa2Z88eFhoayt566y1+/ZUrV1hERATbv38/Ky8vZ7t372bh4eGsrKyM\n3+d3v/sde/bZZ1lxcTH7v//7PzZnzhy2a9cufvunn37KYmJi2Ndff81KSkrYmjVr2MKFC5lGo2GM\nMaZSqVh8fDx7++23WXl5OTt06BCbPn06+/777+/fDRimge7bX/7yFxYdHc2++OILVlVVxT799FMW\nHh7OPv/8c34fum9971tvO3fuZKGhoWzTpk2C9XTf+t43lUrF5syZw1599VVWUVHBvv32WxYbG8v+\n8z//k99nvN83Cv0huH79Olu5ciWbPXs2S0xMFPwwZWRksJUrVwr2X7lyJUtPT2eMMfbTTz+x0NBQ\ndv36dX57dnY2i4mJ4X9YFi1axN577z1+e1tbG4uOjmZ/+9vfGGOMHThwgD344INMr9fz+6SlpbGk\npCTzX6wZ3e2+Pf7442zHjh2C/d9880323HPPMcbovg1037rl5+ezuXPnsl//+teC0Kf71v99e/fd\nd9lDDz3Eurq6+HV79+5lycnJjDHruG/UvDMEP/30E3x8fPDll1/C399fsC0/Px/x8fGCdbNnz0Z+\nfj6//W7zCqhUKlRWVgrOIZVKERERITjHrFmzBC+1xcfH46effgIbxa9b3O2+paenY/ny5YJ1Q5mP\nwVrvGwC0t7dj06ZNSE9Ph5ubcDIhum/937dTp07hoYcegkQi4detW7cO+/btA2Ad921MToxuKU88\n8QQ/Q9id6urq+gwg5+npyQ9+ZGpeARsb4/+Ku52jrq4O06dP77O9s7MTTU1NkMlkw7yykXW3+3bn\nL8ru+RhWrlwJgO7bQPcNALZt24bIyEgsXrwYn376qWAb3bf+71tlZSUeeeQRbNmyBd988w2kUime\nfPJJvPjiixCLxVZx3yj0zUStVveZ+tHW1pafM8DUvAKdnZ0A0Gef3ucY6HsA6DN89Vg0nPkYrPW+\n5eTkIDc3F1999VW/2+m+9a+trQ0HDhzAk08+iQMHDuDKlSvYunUr1Go1UlJSrOK+UeibiZ2dHbRa\nrWBdV1cXHBwcAJieV6B7YKQ79zF1ju7l7n3Gqurqarz44otQq9XIysoa9HwM1njfGhsbkZGRgW3b\ntsHFxaXffei+9c/GxgZhYWF46623AADh4eFQqVTYv38/UlJSrOK+UZu+mfj4+PDzBHSrr6/nPwZ6\ne3vzw0X33g4YPyp2Dzvd3z6mzuHo6MiH5FhUVFSEZ555BiKRCEeOHBG0p9J96ys3NxcqlQqpqamI\niYlBTEwMzp49iy+//BIxMTEA6L4NxMvLC6GhoYJ1U6ZMQVtbG5qamqzivlHom0lsbCzOnTsnWJeX\nl4e4uDh+e3V1tWBe4N7zCri5uWHSpEk4e/Ysv729vR2XLl3CrFmz+HPk5+cLHgbl5eVh5syZY3bE\n0u75GPz8/PDxxx8LJuAB6L715+GHH8Y333yDL774gv8zY8YMPPjgg3x/cLpv/YuLi8PFixcF68rK\nyuDi4gJnZ2fruG+W6TQ09q1cuVLQFaykpISFh4ezd999l5WXl7M9e/awyMhIVl5ezhgz9ht++umn\n2TPPPMMuXbrE9//t3fXr448/ZtHR0eyrr75ipaWlbM2aNWzRokV8V7GGhgYWGxvLMjIy+P6/4eHh\n7Icffri/F38P7rxvS5cuZQkJCezq1ausvr6e/6NSqRhjdN+63Xnf7vT8888LumzSfTO6876VlZWx\nyMhI9m//9m+ssrKSnThxgsXFxbG9e/cyxqzjvlHoD1N/fwm/++47tnjxYhYREcF+85vfsNOnTwu2\n19fXs7Vr17KoqCj2wAMPsHfeeUfQl5cxYx/fefPmsejoaLZ69WpBf2HGGCssLGRLly5lERERbNGi\nReyrr74amQscIb3v29WrV1loaGi/fx566CH+GLpvQw99xui+Mdb/fcvPz2fPPPMMi4iIYL/4xS/Y\n/v37BfdlvN83Gk+fEEKsyChoYCKEEHK/UOgTQogVodAnhBArQqFPCCFWhEKfEEKsCIU+IYRYEQp9\nQgixIhT6hBBiRf4fhvozeoTUqI0AAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot(data)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "I1 = interpolate(data1.Torque, kind ='linear')" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ts = linrange(8500, 18000, 2000)\n", + "\n", + "plot(data1.Torque, 'go', label='Torque data')\n", + "plot(ts, I1(ts), color='green', label='interpolated')\n", + "\n", + "decorate(xlabel='RPM (min)',\n", + " ylabel='Torque ($\\mu$U/mL)')\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "I = interpolate(downforce.results.t,kind='cubic')" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nQghv/gc1Zw908bT+oAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ts = linrange(1, 100, 1000)\n", + "\n", + "plot(downforce.results, 'go', label='downforce data')\n", + "plot(ts, I(ts), color='green', label='interpolated')\n", + "\n", + "decorate(xlabel='Time (min)',\n", + " ylabel='Torque ($\\mu$U/mL)')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
RPM
Speed
0.1224486388.837401
1.6272086420.745921
1.9299586452.548344
1.9299586452.548344
2.8393296563.843564
2.8415766595.619463
3.7487016675.138784
4.9540826722.908729
6.1605866786.566624
7.3704616897.888368
8.5780896977.434212
9.4874607088.729432
10.0929597152.334279
11.3005877231.880123
11.9038397263.709071
12.8087177311.452492
14.3190957422.800760
15.2239737470.544181
15.8305957550.036978
17.6459687724.963568
18.8547207820.397363
19.4579727852.226310
20.6644767915.884205
21.2688527963.601102
22.4776038059.034896
23.6852308138.580741
24.8939828234.014535
26.4032358329.474854
27.3114848424.882124
28.2163628472.625545
......
287.29294813357.175400
287.89507713373.116400
290.00533613468.629760
291.20959413500.511760
292.41385113532.393760
294.51961713564.355320
296.02437713596.263840
298.73676513707.718210
300.54652213803.205050
302.05352913866.889470
303.86103913930.600410
305.97017414010.225830
308.37869014073.989820
310.18395314105.924860
311.69096014169.609280
314.40447114296.951600
315.90923114328.860120
317.11461214376.630060
318.31887014408.512060
320.42800614488.137480
321.63451014551.795370
322.83989114599.565320
323.74364614631.420790
326.75429014711.125780
327.65916814758.869200
328.86454914806.639140
331.27194114854.515190
332.47619914886.397180
334.28483214965.996070
335.78846914982.016640
\n", + "

409 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " RPM\n", + "Speed \n", + "0.122448 6388.837401\n", + "1.627208 6420.745921\n", + "1.929958 6452.548344\n", + "1.929958 6452.548344\n", + "2.839329 6563.843564\n", + "2.841576 6595.619463\n", + "3.748701 6675.138784\n", + "4.954082 6722.908729\n", + "6.160586 6786.566624\n", + "7.370461 6897.888368\n", + "8.578089 6977.434212\n", + "9.487460 7088.729432\n", + "10.092959 7152.334279\n", + "11.300587 7231.880123\n", + "11.903839 7263.709071\n", + "12.808717 7311.452492\n", + "14.319095 7422.800760\n", + "15.223973 7470.544181\n", + "15.830595 7550.036978\n", + "17.645968 7724.963568\n", + "18.854720 7820.397363\n", + "19.457972 7852.226310\n", + "20.664476 7915.884205\n", + "21.268852 7963.601102\n", + "22.477603 8059.034896\n", + "23.685230 8138.580741\n", + "24.893982 8234.014535\n", + "26.403235 8329.474854\n", + "27.311484 8424.882124\n", + "28.216362 8472.625545\n", + "... ...\n", + "287.292948 13357.175400\n", + "287.895077 13373.116400\n", + "290.005336 13468.629760\n", + "291.209594 13500.511760\n", + "292.413851 13532.393760\n", + "294.519617 13564.355320\n", + "296.024377 13596.263840\n", + "298.736765 13707.718210\n", + "300.546522 13803.205050\n", + "302.053529 13866.889470\n", + "303.861039 13930.600410\n", + "305.970174 14010.225830\n", + "308.378690 14073.989820\n", + "310.183953 14105.924860\n", + "311.690960 14169.609280\n", + "314.404471 14296.951600\n", + "315.909231 14328.860120\n", + "317.114612 14376.630060\n", + "318.318870 14408.512060\n", + "320.428006 14488.137480\n", + "321.634510 14551.795370\n", + "322.839891 14599.565320\n", + "323.743646 14631.420790\n", + "326.754290 14711.125780\n", + "327.659168 14758.869200\n", + "328.864549 14806.639140\n", + "331.271941 14854.515190\n", + "332.476199 14886.397180\n", + "334.284832 14965.996070\n", + "335.788469 14982.016640\n", + "\n", + "[409 rows x 1 columns]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = pd.read_csv('Gear_ratios.csv',index_col='Speed')\n", + "data" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "I = interpolate(data.RPM,kind='linear')" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaEAAAEPCAYAAADrvntcAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXl8VOW9uJ8zW2ZLJpiFBEgCQkuwKCEYqL2gtWgNXhXb\naqt1AdrcevmhVeq9UOQqaq2iXGoFtN4SWgHr2ku1iHGtRbQWJwS5oCwGBUPIQBaSkFkyc+ac3x/D\nOcxkIdtk5X385CM558x533cy837Pd5dUVVURCAQCgaAfMPT3BAQCgUBw9iKEkEAgEAj6DSGEBAKB\nQNBvCCEkEAgEgn7D1N8TGCwEAgH27NlDWloaRqOxv6cjEAgEg4JwOEx1dTUTJ07EarW2Oi+EUCfZ\ns2cPN910U39PQyAQCAYlf/rTn7jwwgtbHRdCqJOkpaUBkTcyIyOjn2cjEAgEgwOPx8NNN92k76Et\nEUKok2gmuIyMDEaNGtXPsxEIzi7Wf7Ke9bvWc6zpGMOdw5kzaQ5z8ub097TOetyVborLiimrKgMJ\n8jPyKcovomBkQatr23NjCCEkEAxyhvIG7a50859v/ScfVX6EoioYJANHm47yxYkvAHplnX39fror\n3ZSUl1B1sorMxExmjZvV5iY+0HBXunl428Psq92nH3v/q/ep9lWzZPqSTq9BCCHBWUNXntriQV9s\nZus/Wc/yD5frv1c1Vem/99bGuey9ZWz4vw00BBpwWV3cesGtPHDpA3EfZ/0n61n+wXI+r/scRVUA\nUCSFpmATsiKz5uM1vfJ+Lvv7MrwhL7Iic9x3nGV/Xwb0nsBb/fFqfCEfdrOdbFc2lY2VAANaELkr\n3Sx+ZzG7j+8GwGlxYjVFgg4qGip4o/wNIYQEgmi0p7adnp36BnOo/hAHag/w2OWPxf0L3xfCYf0n\n67nrzbtoCjYhIWE2mLFb7DjMDjbs2hD3TdNd6ea2zbfxf8f/DwCjwUhICbHq41UAcRVE7ko3qz9e\nTY2/BkVVUIlUF1NVFVVVCYaDHG44HNfxSspLWL19NU2hJkwGEyaDCVmRaWhu6BWBp6/RV6N/Jg83\nHGZi2sQubeJ9jSY4D544SEAO6O9TsjUZq8mKN+Tl6Mmjnb6fEEKCs4LismK2fbWNk8GTGCQDJkPk\no7+neg/rytbFXwjtWt/m8XgJh2XvLeOp0qdoCDTox8JqGIIgKzJfnviyx2NEownxPdV7dK0kHA4j\nKzIJxgQ2/t/GuAqh4rJiDjccprG5URdAGioqsiLHbSx3pZtHPniErxq+4kTgRETISUH9c2IymOIq\n8DSKy4opryvHL/tbfSbPsZ0T9/F6imZJ2LRvU8zxYDgIQFOwCavJisPsYETiiE7fVwghwZDHXelm\n21fb8Ia8KKpCWAkTDAcxGUxYjBbKPGVxH/NQ/SFOBk8iKzImg0k3V3iaPD2+t7vSzdqytciKjCRJ\nulBAjWwIFpMFpB4PE0NxWTHbK7cTUkIxxzWtpMZXE5dxtI3upc9e0je3lkin/ku1p8ZlzEc+eIRt\nX21DVuTTWtcpuaeoCsFwEJvJFpexNLTPZEgJtfmZrA/Ux3W8nqJpP4cbDtMUbNIFpnTqgyYrsv5g\nkOXKonBcYafvLYSQYMhTUl6C3WxHUZXTGzYQVsLIkkxTsCmu463/ZD3VvmoCckA/1hRsYph1GBNS\nJ/To3u5KN/O3zOe49zgQEQIaKiphNaKdjE4e3aNxWo657att+GU/ElKMZqKe+s9o6HkCt6aR/PPI\nPwnIAX1zbjkmRHwQPX0vIfK3erP8TWRVxiDFFpCJfm/jJfA0tM+kqqptfiajj/U3mtlQMxnCqYcd\nowWL0QJAc7gZh9nBJTmX8NPJP+2SZUEIIcGQp+pkFVlJWew5vkffWFRU/YnaYXHEbSx3pZtHP3wU\nOSzHmIwUVaHWX8v07Ok9uvfD2x7m4ImDugbUcnOWJIlESyJfP+fr3R6nJcVlxdQH6mOEagwqjB02\ntkdjaMJV8zNoT9iSJCGpp4WQAQMWkwW72U6ave28k66Mufrj1SicCnposfGrRPxPSQlJcRF40Wif\nyb01ezFIhoiv69Qah1mHtRKI/YlmGpUVmWA4GKP9mEwmMpwZOM1OnvrXp7pl1hZCSDDkyUzMRFEV\nnBYnJ/wndAFkkAwYDUacZmfcxiouK6aqqQoFJeYJXlVVTJKJY03HenTv7ZXbdWHQshWYhITdbI88\nncbBHKeZYHYf331aKLTQSiQkEhMSuTCzdSZ8V8f5tPpT4LQwMEpGDJKBoBLEKBkxGozYzXYA/LKf\n477j3RpPM/m9duA16gJ1uoZskAz6+iQkzEYzSQlJOC3OHgu86LFLyksoPVqKiordFNHQZUXWP5Oa\niW4goGnBGtF/DxUVs8GM0+zk9qm3d9uvKoSQYEjjrnRT2VjJtq+20Rxuxmw0E1bDKKqC2Wgm0ZIY\nt6dOd6Wb1z5/jYAcIBQO6ZuZtmmbjeZu+5+iTWImgymiBUkR85uGQTLoPoxqb3WP1qJF99X4avT7\nKqqCJEm6v8QoGUlMSMSV4Oq20NM0x2pfNaHwaX+TJEU2ZKvJiqzImA1mVFR8IR8mgwlXgosjjUe6\nNZ6W2+KTfUBE6KmqGlmDBKiR9zLBmABw+lwP0YQfwKikUZH8GgkcZgcngycJK2GQIhrGsaZjuCvd\n/RIhF53KcLTpKMFwELPBrPs3IfKeOc1Ovj/h+102v7VECCHBkCX6Sz8+ZTwVDRUEw5GoJ03wnAye\njMtTpzaW5lwOcEpb4bT5zy/7uyUctJyMal+1Pn+L0RLxHcgRk5ymKSiqwsngSb5q+Krba9FCv30h\nH4qi6P4eg2QgrIQxSkZdIAXDwR4JvUc+eIQv6788nQd06r5S1K6vrU3bACGiCXXVl6eZ/PbW7NXH\n07QPJHThLiFhM9v0dUuS1COhrmk/m/dvRkUl25VNuiMdgP3qfr6o/yLyNzVb9DX6w/5eidrszFyj\nE1B9IR+yIhMgQKIlUQ9MMRlMrLh8RVwiPYUQEgxZSspL9H+nO9JJMCXgl/26/V0zgcQjMEEbK9WW\nisfr0bWHaMJKmBOBE116wtWc9buP7yYgB/QILqvJitVkpVlujni2pMimrWlC3Y1W0zQgXyiiJaio\nhJQQZoM5InQIYsSI2WiOMY11R+i1NPVEa1mqqnKO9RymjpzK/tr9VDRW6MEKWjhzV3x5WuLrF/Vf\nRIIdpNNCTtOyLEYLRsmIxWhBkiTdp6eqarej1aIfhLwhLyoqe2v2QmrkM5nuSKfKW4WqqjSHm5EV\nGavJiqqqvRK12RGayVfTuCEicFQ1otWn2dNwmB1MyZwSt7wpIYQEQ5aqk1UxvzfLzRHN5NRTL0Ry\na3oaXuyudLP5wGa8QS8ANpMNX9BHUI0NMVaJhDN35Qm3uKyYnZ6d+hOphqzI2Ey2mHXISiTCy2ww\ntwql7ixa8qRuojpFWAnjTHAih2UMBoMeFaXhDXm7NI6mldQH6lEUBSR0Hx1E/j5Xj7+an07+KYve\nXkRFY0Wre3TWl7f+k/UseXcJJwIn9GAOVVV1jViSJJxmJ+enn09DcwP7a/frwt4gGQjIAcYkj+nS\n+jSKy4rZUbUDX8hHfaCeBFMCVpOVioYK3c+kJXtqFQcAGpobdCHfV6z/ZD2b9m2isbkxJm9Jm6PL\n6mJG9gwAfpr/07iNO3BCMASCOJOZmBnzuxYsgIq+yRglY7c3bIh8cedvmc+h+kORsOxwAIvRQpI1\nKcaZrznZVVTe/+r9Tt9/21fbqA/Ux/itNF/J93K/hyvBpfuFtGtCSghVUdu8X0dr+bT6UxqbGwH0\nDTvar+VMcGI2mPVNtbG5EVVVcVo6JxC0qgs/fPmHeiACEjGhyiaDiVljZ/H0VU9TMLIASYrkBDkt\nTuxmO06Lk1R7aqd8eVoEnF/26/fXqi5oQtZitDA9ezrLL4tUtAgrYT3vRVZkwkq4W9pydH6apmlp\nUYbRQjvNnhYxeckBfCGfrvHGM2qzM3Nd/fFqINa3CBFzqN0Ued9HJY2Ke6krIYQEQ5ZZ42bF/G7g\nlInslCVGVSOmJovB0sarOyY6f8JhdiArMvWBeiRJIs2WhtFgxHDqKxZWw4SVMKqq6pt8Z+5/pPGI\nrgVpggwiG2VRfhFmoxlU9MABRVUiJq0ufrO1tWj317WEU29WYkIiv73it4xxjcEX8p0OdT+1nrAS\nbvfe0WMsensRz+95norGCoJyEFU5HakoIWExWhjjGsOSGUv01w2zDsNqspJqTyXDmUGqPRWryUqy\nNbnD8Ra/s5iDJw7qG6qmbWnrNEkmxg0bpxfcrPXVElbDuiZgkAzd0paj/Xg1vhoCcgCb2YYrwUVQ\nDsZs6MMdw9u8RzyjNjsz14MnDhIKh2L8cVpC9LRR03jyyie595J74+6nEuY4wZAjuioxoDu6rSYr\n/pA/5gnfgAGruXW3x85QUl6i+05s5khGvTfkxRv0kpYcsZ1rZWe0L3ZntRQtbLk53ExYCaNIih6Q\nYDKYyHRmUjCygFA4pOe5aCgoBOW2qw20RfQmJCHpZihts7aarPz2it8yJ28Od791d6tkVYCvGjv2\nCf3n2//J9srtBMPBmLwYzcekqAp2s53F0xfHbHSTMiZR56/jQO0BfLIPu8nO11O+Tl5GXofvnyaA\nojUtLRAhKSGJGdkzYio+a+HHWph0d8ybmh/I0+TBYXbQ0NxAfaCeZGsyNrMNu9nOk1c+qY+p5XY1\nNDfoY8YzavNMtHyftL+7EaNu/o0W0r2BEEKCIUW0I1hDVVV+mv9T3ih/gzp/XUzEmqqq+EP+bo2z\n+cBmqn2RqCmnxYnNbMNmtiEhcfXXr+Z3pb+jKdgUI/QkpA61lOiwZW3+2pwVVcGV4OLi7IsBCIRP\nJ3ZGC7tAuJ3E0jbG0jbM6PBbFVXfEC/NuVR3Qp8MnmzzPh1pd+s/Wc+HFR/qvqaWgsxqsmI32bn6\n61e3cnjnuHLweD0kWZNIIgkAj9dDtiu7zbGWvbeMx//5OM3hZt33o+W0aNF3BgytBBCAxWDRNSFd\n61TDndaWNYHuafLoPiBXgkt/OEm1pTIlc0rMmKqqxkRpahGOvZkr1FYdOINk0CshaJpnT5JQO4sQ\nQoIhRXREXDRvlL8RKU4Z5ePQ/t/VyCftC6yqaqsnXa2AY+G4Qp4ufbrtG3SgCGkJrxDxV2gbt0Ey\nYDfbmZwxWXcMR5tOomnveFtj7ajaoefphNUwCaYETAaTvglFm8ba2xjPtGFqgQGaya5lsquERIYz\ngwmpE9p0eB9uOMyE1AlUNFTops8sV1abEXnL3lvGf3/03zFVF8JqWI/us5lsjBs2jtun3t5mdFeK\nPYUaf01MYILJYCLFkdLu+uD0Z2LbV9uo9lXjtDh1H1CyNZlUeyoSEvmZ+a3WqOUIRY8Zr6jNtmiv\nDhyc/rzJitzjJNTOIoSQYMgQHaWm9WbRIpCOnjxKSAkhSZIebqoJIr/cNU1I27hrfbV4Q15sJhsh\nJaQ/6WpfXBVVf+rWNSHpzMIhOuEVIk56LWET4IL0C7hnxj36xpBgSsAX9BHm9AZvxBgTaXWmsbZ9\ntQ2VU8JUadAFZHubUMsqDR0djw4M0PwrLUkwJpyx5ljVyaoY7UnTYKPbBWj5LVs+33I6tPrU+6+Z\nGG1GG/kZ+Sy/bHm7G2uOK4ejJ4+2Mo1lJ7WtdWlja58JbY6a8NF8QDaTjUxnZptO/VpfbcRMG+Vn\nCymhuBWFbTnX9urAGaWIWVRW5A7fp3gihJBgSKDl01Q2Vuo5DrX+WiZnTCbNnsaIxBFYjBaa5eYY\nH4pW9LOzuTtaGKuWPa75CxItiaTaU2Ns/XDalKYJIINkIMGU0O4aohNetURQzTxiNphbbQxOs5Na\namOEqoKCw9xxZJVWE057vzRhKiFxfvr5bW5CXdWENL+ZVh06uv6cQTLgtDh5ovCJM+acKKoS073T\nG/Kyr3af7tDXBNAHFR/oQk7XttRTPkFJYtywcR1urKn2VBJMCdgVu/43TjAlnLFsj6Z9a/5BTTtu\nCjaRak/FbrYzI3tGu1FlTaG2NZ6uhr13hmg/ptamIhgO6nXgNO23rwQQiOg4wRChuKyYvTV79fwV\nLVJtX01k8yocV8jYYWPb1EQMkoF1Zes6HCM6jFUbwy/7cVqcpNhSuPrrV+tfXHelm5ASIsGYoGtC\nqOjCqr017KjaQSgciomG0zbD6VnT29wY9PsT2XwNnfhaa8L0ZPAkATlAQA7oa0m1p7a7CbUsmHqm\n49F+s1A4hNEQ0dCMBiOSFKlzd+e0OzuV9OgP+anx1eBp8lDjq4n48U79KbUES80v1Vb/oQRjQqdN\nSy21ujOV7dHWqIXSR0fBQcTc2J4GFI0WEGAymGKi9+KFu9LNg1sf5MU9L+rzdJgd+sMBEJc6cN1B\naEKCIYGWXR4dpSYrMo3NjfoGcMfUOyjaXNTqtRJSp3J3tKdI7UlXoynYhM1ki+mhUlJegsPsoCnY\nhMFgwCRFnjolKeIXaEm0aSzZmkytv1avmZZgSmB61vQY34w+dqgJJPRK0xISSO0/RUc7pH0hn+7z\n0KpHBOUgV5x7RY83oVZ+s1OmvgRTAgkkYDfZeXjmw50SQDW+mlYPD1opneiaetEh5YCufVpNVhZ+\nc2GPx2prfZrwSTAlxPiAbGYbafY08jM7biGfZk/DG/S2isiLV9HU6Bbimv8z2lzoDXmRkOJSB647\n9KsQuu+++wiHw/z6179udS4UCnH99deTm5vL8uWn2yTX1tby4IMP8uGHH2I2m/n+97/PwoULMZlO\nL+WZZ55h/fr11NXVkZ+fz7Jlyxg9erR+fvfu3fz6179m7969DB8+nP/3//4f1157ba+uVdDLRD28\nalFqENE8tC/VnLw53F5yO96gV9+wtWrAHdnfW0bDaaYrza5+cfbFMV/eXZ5dBMNBvSdOmEjR1CRL\nEj+d3Nr53tI0ptXp0kxj0X6gaELh1hWXFVWJKQYavQZN29KqK0Sb+7Ss+J5mw0dHiKlqxC8Tvdnl\nuHLaDQxoC63baTRaKZ3oNhNa5JsRo/73tZvtLPzmwk53fT0ROKGXRIqmPlCvh/7v8uzicMPhSL5U\nVBJqSx/QlBFTOrWpj08ZT0VjRUxEotFgZHzq+E7NuT1aRsBpwRINzQ3YTDaCchCX1UWaPa1Lf494\n0y9CSFVVVq1axYsvvsh1113X5jWrVq1i79695Obmxhy/4447kCSJZ599lmPHjvHLX/4Sk8nEwoUL\nAXj55ZdZtWoVDz/8MGPGjOHxxx+nqKiI119/HYvFQl1dHUVFRVx11VX8+te/5h//+AdLly4lNTWV\n6dO73+tF0H+4K92oqHqYsdbFFCA/I1brsJqsBOSA7qvRvvgd3b9lNJysyHo0nNPsbLVxH2443GY4\ns8vqarUpaU/zFqMFv+zXM/WTrcnYTLYO7fNt5e20hSaAonNCtGgojZbCtCVtNZjTjmtr0UK+tRJJ\nqqpiN9v1agct/WYdoaqqrhlGl9JJsaXo75vm2wD00j9jh41l8b8s7tLmOsw6jC9OfKFr0iaDCYfZ\ngaIqeuj/4YbDeENePE0eXesB9E3d6ejaGtMd6aTaU2kKNsV04tWKnHaHlg8cEKv9hMIhkq3J3DDx\nBgrHFfZLtW6NPhdCFRUV3HPPPXz++eeMGNF2H/IdO3bwv//7v3z967GNuXbu3MmOHTt45513yMrK\nIjc3l0WLFvGrX/2KBQsWYLFYKC4uZt68eRQWRkwjK1euZPr06bz55ptcffXVvPzyyzidTpYuXYrB\nYGDs2LF89tln/OEPfxBCaBCifdmykrKo8dXgDXmpD9ST6cxkfMr4VsLBaY70FGqZsNpedvqZnupb\nRsNFU+urjRF2WoRWy5yk6Mx6iNWwOmsaaytPqK11aOY+zfwW3R1Ta0zWkRbUkRDSnPR2s103CdrM\nNhxmB/mZ+YxKGtXlDa+9EGZPk4fMxExUVFJIoT5QT3O4GQMGzks7r1v5Lan21FbmuGA4yIHaAxzz\nHsNutlPnr9PD2JuCTVhNVj0JdUb2jC6v0SAZGO0azYHaA8iKjMVgYbRrdKfD7FsS/ZnVPlca0cES\nN0y8gXsvubdbY8STPg9MKCsrIzMzk82bNzNq1KhW571eL4sXL+a//uu/SEmJjc0vLS1l5MiRZGVl\n6cemTp2K1+tl79691NbWcujQIaZOnaqfdzgcTJw4kdLSUv0eBQUFGAyGmHuUlZW1G2YqGLhoT3v7\na/djM0Xs8JnOTDKdmW2asNoLXW6rasKZnurT7GmMTh7NU//6VJtP2p2JeNLqzu307CQUDsUEB2Q4\nMzplGjMbza2c2AbJECnnE7WO6BIyZoNZd0grqtIlh7TJ2PZzq8Fg0B3fO6p2kGhJbHPd0X6zztJe\nKZ2TwZNkJUX2ApvZRmZiJqOTR5OTnNOjBMvoEkEOswO/7McnR0xv3pBXD+bQSjVpaBGJXV2joip6\nMm6GM4MkaxIer6db+1GrzyzomrX2b22u3flb9AZ9rgnNnj2b2bNnt3v+4Ycf5vzzz+fKK6/kpZde\nijl37Ngx0tNjVVTt96qqKt0vNHz48FbXeDweADweD+edd16r836/nxMnTnDOOed0b2GCPif66R6I\nCAlUJqROYLhjeJubUHstqtuqmtAbT/XRc9fyNTTNRFtGe5n1baFpdm0d18ZpWUJGq8CtaVxdcUjb\nzXbd7BWNqqq8sOcF6gP1+GQf3pCXDEcGTcEmvCFvpyLE2iOoRDS26M0UoDncjCRJ5KbkcqTxiJ7I\n2pn3rT0MkoEMRwYHag/QGGyMhMtLJpAinx0tGVnXKEx2HGYH3pC30z6g9vCH/DFmwK52jm2rWoMm\nKFU1ogFLSP0SAXcmBlR03LvvvsvWrVt57bXX2jzv9/tJSIjNsTCbI5nQzc3N+P2RjaTlNRaLhebm\nZgACgQAWi6XVeYBgsPP1tgT9T0tnvuYLqmioYHLG5DZf05WcDM0BXeurpSnUpN+/M0/1HZn9isuK\nOdxwWN8gwmpYz9tItae2mVnfFh1pdtGCVBPW2kY32jWaKZlTePqqdio7tEFyQjInAyf15FgNrTRO\ntJO+KdikRwL2pPKyK8FFY3Pj6e6up6LeLEYLe2v2MiF1QkzEYU8CKxRV4cv6L2lobtCDHWRkEkwJ\nMZFv2mae7comLyOvR34VTfDtqd4T4xPaV7OvU/lrHVVr0MzHafY0Ls65uF8i4M7EgBFCdXV13Hvv\nvTz88MMkJ7ddHddqtbYSFKFQJNPYbrdjtUa+eC2vCQaD2Gy2du+h/a5dIxj4tOXM1750ElK7AqKz\n0WTuSrfugLaaraioNAWbkJAYkzymw03VarK2WS3BarbqOTpaWZbosimyIndJawjIgTbH8Yf8MRUk\nVFUlEA7E1LfrrKBrtS6DhFE16gJWew+1HBmIOOl9IR+jkkb12PE9PmU8h+oP6T4hTaCn2lPJTcml\nIdDAcMdwRiSO6PFYx73HqfWf8udpa0MhpIRINiXrkW/nDjs3bgmdmYmZuI+6W+WPOcwO3ih/44xj\ndKZag8vqYuywsX2agNoVBowQ2rp1K7W1tXqUG0Bzc0TdfvPNN9m5cycZGRls3bo15nXHj0dU1uHD\nh5OZGekfU11dTU5OTsw1Y8eOBSAjI4Pq6upW97Db7SQmxtqxBQOXkvKSNp/uO+PM70w0WXFZMd6g\nF4/3dMRdV7LJJUnSqyloAQ1mgxl/yK8nvLasimAymBjtGt2lzSKoBPWyPtG1zrwhrx7RF+3P0pzd\n3TWPaesIhoOt3seWlaLj6fg2GoxI4dMtH7TggXRHOhnODH531e/iMs6RxiMxDwV60MepUjpp9rQz\nVj/oDrPGzeKFPS+0Op7lyoopTdQW0RGPWgUPWZE7Xa1hIDBgKiZcfvnlvPXWW7zyyiv6zwUXXMB3\nvvMdXnnlFQCmTJlCRUUFVVWnO2Zu374dh8NBbm4uKSkpjB49mo8//lg/7/V62bNnDwUFBfo9SktL\nY5x+27dvJz8/PyZYQTBw0Z7wa321enKh5kjujDNfr2bd4t/R99/21TaQ0DPf6wP1SEhku7J79GVu\nCjXpCa9acIBWFQHosq3eleDSzXjRzchONp+MNFQLenU/mObPmpE9o8dPxe0Jb027i6fj+0jjEb2c\njslgwmw0R8yipzrZjkhsO8q2W5z6KJiNkeANk9GkV3joqpbaWQpGFjAjewZOs1M3801InaCXm2qP\n6KZ5ml/RL/uxmWynltK5ag39zYDZdZ1OJzk5OTE/VqsVh8OhazWTJ08mLy+PhQsX8umnn7J161ZW\nrFjBvHnzdL/O3LlzWbt2LVu2bOHAgQPcfffdpKenc/nllwNw3XXXUVdXx7Jlyzh48CAbN27ktdde\no6iodSa9YOARnbNjNZ92EjfLzTjNzg7zXDoTTab5mjxNHrwhrx6t5jA7ztjDJhrtybllUcpmuZn6\nQD0NzQ26s9hqsuK0OPlB7g+6nDA4I3sGNpNN14TgVIM7lEhh1igNSNMgerIpaetoadKUkPSNMO6O\nbyliBkyzp2E32/XEWo14RnnlZ+TrQl1Dq3HXmdpz3aUovwiH2UF9oJ7yE+X888g/2V+zv921tRXx\nqBFSQox2jY7Lw0ZfMGDMcZ1BkiTWrFnD/fffz0033YTD4eD6669nwYIF+jU33ngjjY2NPPLII3i9\nXvLz8ykuLtaFVGpqKsXFxTz00ENce+21jBgxgkcffZSLLrqov5Yl6ALRFay1YAHNTNYZH0dnosm6\n42tqiZYjFO03QY2YDbUQY22jS7Ymk2pL7ZZDvSi/iG1fbcMX8tEcbtYrIViMlpgclnhE9GnrUpTW\nyb0qKomWRMYkj4n7xpefkc/7X73fqiRTTnJO3J/yi/KLOFB7gD3VewD0FvCZzsxejSj7rPozDtQd\n0KMXg+EgB+oO8Fn1Z20mN3cU8djTSL2+pF+F0MaNG894/plnnml1LC0tjSeffPKMr7vtttu47bbb\n2j2fl5fHn//8507NUTBwiA7JbhkskGhJ7NSGdKaAAYiNuNN8OUCXa6q1F4WnVXWOtmYF5WC3N7iC\nkQUMdwzjxKw7AAAgAElEQVTn6MmjeokgRVJQlMgP9sh1PcnTiUarVdfSGichkWJL6ZUn76L8Iqp9\n1VQ0VCAhkWZPI8uV1SvdPgtGFvDY5Y+xrmydXo8wPzO/1zf01R+vbrOx3ZqP17TSjuMd8djfDCpN\nSHB201ZItqYFRVewPhPtBQxAay1IE0Ba+ZyuaCqhcAitn02kgPbpSCvNDGc2mMlx5ZDtyu5R3a6T\nwZMEw8HTTeNUlTBhZFXucSBCexgkw2lT46l19tRf1h4FIwtYMn0Jb5S/wdGTR+MSBdfReH2tQRys\nOxiTf6X59srryoHT2k9ZVRmHGw6TYk8hw5ER6WfVw4jH/kYIIcGgIF5mMohEWrUsFgk9i7hrieZ7\nUlU1pn9RdGSXw3LaRNYTan21MdFq0WHTmhkuXgIozZ5GY3NjROBJp9fjtDg77S/rDv0hGPqSsBqO\naX2uva/BcJDbNt/GWwff0s3PWp3EgBxgtGt0XBKC+xMhhASDgngJCLvZ3srxrKFF3EX7miCy0Xb1\n6TLNnkZADkQ0lPDpxM7oSLygHHny7amJLKgE9Y6x0eNoml48N6YZ2TOoD9RzInAiJiQ805k5YMrA\nDEYSLYkxCdMqKmEljIQU03ZD8/1oYdjxSgjuTwZMdJxA0B49DcmOJseVQ7I1WRdCWkdRzQfUnYi7\ntpiRPYNES+LpvJZT/0WnAbisrrhsHK4Elx7xp3VvlSQJo8FIfmZ+3B333xz1Tca4xpCUkESiJZGs\npCwW/8viQbkBDhQyEzOxGq2nGxKq6EVvm4JNej6ZrMiElJCeOqAlBA9WAQRCExIMcFqGZEcHI6TY\nUrpcJ2xSxiTq/HUxFYubw82cDJ6kxleDoii4rK4uRdy1RXTUmqzIKEqk143FYMFusjN15NS4CYgZ\n2TOoaKwgrIRjTDl2s71VAEFP6Wv/zNlCjiuHoyeP0tDcEOlDhXI6iAV0s65WP09rmnfN+GsGRCXs\nniCEkGBAo0UCZSVlsa92n+6E7a6AyHHl6BWLk0ii3h8xLVmNViwmCzIyJwInuhRx1xZa1Fq1rxqr\natVrgpkMJiwmC+mO9LiZr4ryi3j7i7ep89fRHI7USLSarOQNz2uznXlPGer+mf5AM/2GlbD+MKGh\n5V9pIf+aFp/lyhoSJlAhhAQDlujaZ3azPaYqc3d9HYcbDutVkn2yT8+6bw43o6DoyaNApyPu2kMz\nG0JshWSJ+PppCkYWcPm5l1NWVaZXks5yZXWYcS8YOBz3Hqc+UB8RNlECSIt4tJqskYreBhPp9nRm\n5MwYNHlAHSGEkGBAEm2G0/q4eENevZxJd5Mud3l28WX9lwSVoG7aiG46p4XJ+mRfj58yh1mHUdUU\nKTEV3XL8vNTzeiWXRuv8Gc1QeFI+G9hfs5+wGhE4LRsHKqqCxWghyZLEwzMf7rc23L2FEEKCAUlL\nM5xGRUMFafa0bm+uhxsO09DcAJxu8AWRL75We01RFcYNG9djQTEpYxIqKhUNFTEaSm+EMmtzFb6a\nwUlDMPKZNBqMSKqkh2trLSvGDRvH7VNvH3ICCIQQEgxQtF4+vpAvxkHb05BjX8hHs9yslzfRkWJ7\n89w+9fYezR8i1ZErGytJs6fFHO8t7UT4agYvrgQXdf46PewdImHaRoOR/Iz8QVEDrrsIISQYcET3\n8gFiOqZOzpjcoy+jP+Q/XS1BK9PP6X/bTXamjZwWlydOoZ0IOkvL/CstiCUrKWtICyAQQkgwAGmr\nl4/WMXXJ9CU9undzuDnypCmhmz0kJBJMCfzwvB8CEf9KvBDaiaAzaPXx9lXvo9pfjUQkqOVsyL8S\nQkgwoGjZy8cb8lIfqCfTmRmX2mRWkxWL0aKb4jTTh1EyxqULqEDQHc7m/CshhAQDCq08T3RhRqBL\nvXzOxOjk0XrCq5a747Q4OTf53EGf9CcY3JytWrMo2yMYMLQsz6N1BIVIrbh4OPTnTJqD1WTVy/6k\n2lOxmqzcOunWHt9bIBB0HaEJCQYE8S7P0x5awMGGXRvwNHnIcGZw66Rbh2Toq0AwGBBCSDAgiHd5\nnjMxJ2+OEDoCwQBBCCHBgKC38oIEAsHARgghQb/Tm3lBAoFgYCMCEwT9Tkl5CVlJWa2OVzRUiNpn\nAsEQR2hCgn4lulJ2tBnOYXbEJS9IIBAMbIQQEvQbLStlR5vhtErZAoFgaCPMcYJ+o7ismB1VO1rl\nBVU0VACiDYFAcDYgNCFBv7D+k/Vs2rdJr1pgNpj1vKCedDQVCASDCyGEBH2Ou9LN6o9X679rzeWS\nrcmk2FJ63NFUIBAMHoQ5TtDnlJSX4Av5cJgdMce11t3CDCcQnD0ITUjQ5+zy7KI+UI9f9uvdIzUu\nzr5YaEECwVmEEEKCPkVLTLUYLfhlvy6Akq3JpNpS41qeRyAQDHyEOU7Qp2gN6xqaG1BVVT8elIPc\nPvV2oQUJBGcZQhMS9BltNayTFZlMZyYTUieIoqICwVmIEEKCPqO4rFj3BUW37Y5XwzqBQDD4EOY4\nQZ+gaUEWowWIhGXXB+oJyAEREScQnMUITUjQJ2htu1UifiDNFBeUg1xx7hXCFyQQnKUIISTodaLb\ndjeFmnBanKTaUwGQkEREnEBwFiOEkKBX6au23QKBYHAifEKCXiW6bTeAzWwj1Z5Kii0l7m27BQLB\n4ENoQoJeRbTtFggEZ6JfNaH77ruPpUuXxhx79tlnKSwsJC8vjyuvvJKXX3455nxtbS133nknF154\nIRdddBErVqxAluWYa5555hkuvfRSJk2axLx58zh06FDM+d27d3PDDTcwadIkvvvd7/LKK6/0yvrO\ndqLbdkf3C8pNzRVFSgUCAdBPQkhVVZ544glefPHFmOPPPfccK1euZP78+fz1r39l3rx5PPDAAzFC\n4o477qCmpoZnn32W5cuXs2nTJlavPl2R+eWXX2bVqlUsXryYl156iYSEBIqKiggGgwDU1dVRVFTE\nN77xDTZt2sQtt9zC0qVL+eCDD/pm8WcRom23QCDoiD4XQhUVFdx66608//zzjBgxIubcCy+8wI9/\n/GNmz55NdnY2119/Pddccw2bNm0CYOfOnezYsYPly5eTm5vLJZdcwqJFi9i4caMuZIqLi5k3bx6F\nhYWMHz+elStXUltby5tvvglEhJTT6WTp0qWMHTuWW265hWuuuYY//OEPfftGnAXs8uyiorGCQChA\nY6CRZrkZp9kp2nYLBAKdPhdCZWVlZGZmsnnzZkaNim3f/F//9V/ccMMNMccMBgONjY0AlJaWMnLk\nSLKyTj9dT506Fa/Xy969e6mtreXQoUNMnTpVP+9wOJg4cSKlpaX6PQoKCjAYDDH3KCsri6llJugZ\n6z9Zz0dHPuLgiYM0hZqwmCwkmBLIcmWJ6ggCgUCnzwMTZs+ezezZs9s8Fy08AI4ePcqWLVu4+eab\nATh27Bjp6ekx12i/V1VVYTJFljN8+PBW13g8HgA8Hg/nnXdeq/N+v58TJ05wzjnndHNlAo31n6xn\nybtLOBk8qXdO1ZrWVTRUsGT6kv6eokAgGCAM2Oi4uro6brvtNlJTU/nZz34GgN/vJyEhIeY6s9mM\nJEk0Nzfj9/sBWl1jsVhobm4GIBAIYLFYWp0HdJOeoPtoXVO1+nAQKdEjIRGUg8IUJxAIYhiQQqii\nooKioiICgQDPPvssiYmJAFit1laCIhQKoaoqdrsdq9UKtBYmwWAQm83W7j2037VrBN1H65qqaT8m\ng0n/cVldwhQnEAhiGHDJqp9++ik/+tGPMBgMvPDCCzH+n4yMDKqrq2OuP378OBAxwWVmZgK0eY1m\nomvvHna7XRd2gu6jdU0NyAECcgBZiYTPy4qMw+wQUXECgSCGASWEDh48yE9+8hNGjhzJc889pwsV\njSlTplBRUUFVVZV+bPv27TgcDnJzc0lJSWH06NF8/PHH+nmv18uePXsoKCjQ71FaWhoThLB9+3by\n8/NjghUEXSe6a6qm/ciKTFgJYzfZRdM6gUDQigG16y5evBiLxcJjjz2GLMtUV1dTXV1NXV0dAJMn\nTyYvL4+FCxfy6aefsnXrVlasWMG8efN0v87cuXNZu3YtW7Zs4cCBA9x9992kp6dz+eWXA3DddddR\nV1fHsmXLOHjwIBs3buS1116jqKio39Y9VNDygmxmG64EF1aTFavJSqIlkYdnPiya1gkEglYMGJ/Q\nl19+ye7duwEoLIw12WRnZ/P2228jSRJr1qzh/vvv56abbsLhcHD99dezYMEC/dobb7yRxsZGHnnk\nEbxeL/n5+RQXF+tCKjU1leLiYh566CGuvfZaRowYwaOPPspFF13Ud4sdgmiVsr1BL6hgN9uxm+04\nzA6yXdlCAAkEgjaRVJEc0ymOHDnCzJkzeffdd1vlN53taJWyd1TtwBvy6scnpE4gzZ7GqKRR3HvJ\nvf04Q4FA0F90tHcOKHOcYHDSslK2RkVDBYAIRhAIBO0yYMxxgsFL1clIoEi6I5I4fKTxCN6QV1TK\nFggEHSKEkKBHuCvd7K/dj6fJg91sJ9uVTX5mPgCjkkYJASQQCM6IMMcJuo3mC3IluFBR8Ya87K3Z\nS7UvkoclzHACgaAjhBASdBvNF5TuSCc3JRen2YmEREOgQZjhBAJBpxDmOEG3iA7JbmmGM0gGIYAE\nAkGnEJqQoMtoZjhVVds0w41IHNHBHQQCgSCCEEKCLiNCsgUCQbwQ5jhBlxEh2QKBIF4IISToMpmJ\nmVQ2VgIRQaQJIxGSLRAIusoZhdArr7zSpZtde+21PZqMYODirnRTUl5C1ckqFFWh2ldNmj0t5hph\nhhMIBF3ljELol7/8JZIkAdBRiTlJkoQQGqJogQjRqKqKJElISIxIHEHhuEKhBQkEgi5zRiGUkZGB\nx+PhvPPOY9asWcycOROHw9FXcxMMELRAhGjSHemMTBwpCpMKBIIecUYh9Pe//52dO3fy+uuvs2HD\nBp588kkuvvhirrrqKr797W/r7REEQ5tdnl0cbjiML+TTc4LS7GkcPXm0v6cmEAgGOR2GaE+ePJml\nS5fy/vvv8/vf/57U1FQeeOABLrroIv7jP/6D9957D1mW+2Kugn5A65bqDXlb5QSJfCCBQNBTOp0n\nJEkSU6dO5b777mPbtm2sWbMGu93O0qVL+da3vsXSpUt7c56CfqK4rBhv0IunyUONr4aAHAAiOUEi\nEEEgEPSUbiWrGgwGpk2bxqxZs7jsssvw+Xxs2rQp3nMT9DPuSjfbvtoGErgSXADUB+qRkMh2ZYtA\nBIFA0GO6lCekKAofffQRb7zxBu+88w719fXk5uby85//nFmzZvXWHAX9REl5CXazHW/Ii81sw2a2\nAeAwO8jLyOvn2QkEgqFAh0JIlmX+8Y9/8MYbb/C3v/1NFzxz585l1qxZZGdn98U8Bf3ALs+uiCnO\n68FkMOG0OLGarHhDXmGKEwgEcaHDPKH33nuPxsZGxo8fz9y5cyksLGT06NF9ND1Bf6EFJGimOG/I\nS32gnkxnJhdnXyxMcQKBIC50WDHBYDAwZcoUxowZQ2VlJevWrWvzWkmSePDBB3tlkoK+p6S8hKyk\nLPbV7mtlivtp/k/7eXYCgWCocEYhNGJEJAT36NGjHD165pwQrbKCYGhQdbKqVYFSh9khAhIEAkFc\nOaMQ+tvf/tZX8xAMINyVbvbX7sfT5IlJToVIkVKBQCCIF50K0Q6Hw9TV1fX2XAQDAK1OnCvB1WbD\nOhGQIBAI4skZhZCqqvzmN79h2rRp/Mu//AtTpkxh5cqVBIPBvpqfoI/R6sSlO9LJTcnFaXYiIdEQ\naBC9ggQCQdw5ozlu7dq1/P73v+db3/oW5513Hl9++SXFxcU0NjbywAMP9NUcBX2I1rAOYnsFGSSD\nEEACgSDudBgdd8stt8SU5Fm3bh2rVq3i3nvvxWQSPfGGGoqqsKNqR6tipaJOnEAg6A3OaI47cuQI\nM2fOjDl21VVX0dzczJEjR3p1YoK+x13p5rj3eJvFSoUvSCAQ9AZnVGWCwSB2uz3mWEpKCgA+n6/3\nZiXoF0rKS9oMy063pwtTnEAg6BW6bE/rbKdVweCjZd+g3NRc0uxpIgdMIBD0Gt126oiNaWjhrnTr\npjdZkTEZTNT6a5mcMZnJGZP7e3oCgWCI0qEQ+p//+R/OOecc/XdNA3rqqacYNmxYzLW/+tWv4jw9\nQV/xyAePcPTkUfyyH4NkwGQwISsy+2r2sWT6kv6enkAgGKJ0WLZn7969bR7/7LPPYo4JzWjwovUN\nkiQJi9GCrMgEw0FMhsjHQ/iDBAJBbxGXsj2KovD888/HZUKCvqe4rBhfyIesyLoWpP04Lc7+np5A\nIBjCdGiOe//99/nLX/6CwWDgmmuu4ZJLLok5X1paykMPPcT+/fu56aabem2igt5B04LMBjOyIqOo\nCsHw6YoY+Rn5/Tg7gUAw1DmjEPrrX//KokWLMJvNWCwWXn/9dVatWsXll19OfX09Dz30EFu2bMFo\nNDJv3ry+mrMgTrgr3Sx+Z7FeF84oGVFRUVQFRVXIdGSKtg0CgaBXOWOy6vr165k0aRIfffQRH330\nEVdeeSVPPfUUhw4d4nvf+x6vvfYa06dPZ/PmzSxatKjLg993330x1RgAPvjgA2bPns0FF1zA1Vdf\nzdatW2PO19bWcuedd3LhhRdy0UUXsWLFCmRZjrnmmWee4dJLL2XSpEnMmzePQ4cOxZzfvXs3N9xw\nA5MmTeK73/0ur7zySpfnPtjRCpV6mjw4zA4kScJoMGI1WbGb7djNdhZPXyz8QQKBoFc5oxA6dOgQ\nc+bMwel0YrFYWLBgAfv27WPBggUEg0GeeOIJ1q5dy5gxY7o0qKqqPPHEE7z44osxx8vLy5k/fz6F\nhYX85S9/YebMmSxYsIDPP/9cv+aOO+6gpqaGZ599luXLl7Np0yZWr16tn3/55ZdZtWoVixcv5qWX\nXiIhIYGioiK96GpdXR1FRUV84xvfYNOmTXpZog8++KBLaxjsFJcVs6NqB9W+arwhLzaTDavJitlg\nZtywcfwg9wfMyZvT39MUCARDnDMKIZ/PR2Zmpv77qFGjUFUVo9HIX//6V6644oouD1hRUcGtt97K\n888/rzfN09iwYQN5eXnMnz+fsWPHctdddzF58mQ2bNgAwM6dO9mxYwfLly8nNzeXSy65hEWLFrFx\n40ZdyBQXFzNv3jwKCwsZP348K1eupLa2ljfffBOICCmn08nSpUsZO3Yst9xyC9dccw1/+MMfuryW\nwcr6T9azad8mDp44SCgcIiAH8Mt+nBYnqfZU8jPzhRlOIBD0CR22cjAajfrv2r/vuusuvXxPVykr\nKyMzM5PNmzczalRsg7TS0lKmTp0ac2zatGmUlpbq50eOHElWVpZ+furUqXi9Xvbu3UttbS2HDh2K\nuYfD4WDixIkx9ygoKMBgMMTco6ys7KyoAuGudLP649OaY3RovTfoJdOZKVo2CASCPqNbFROGDx/e\n7QFnz57N7Nmz2zzn8Xha3Ts9PR2PxwPAsWPHSE9Pb3UeoKqqSq/qfaZ7eDwezjvvvFbn/X4/J06c\niEnMHYoUlxVzuOEwATmgV0bQflLtqSy/bLkQQAKBoM/olhDqrcTUQCCAxWKJOWaxWGhubgbA7/eT\nkJAQc95sNiNJEs3Nzfj9foBW10Tfo70xgCHfrE8Lxwb0RFRZkZGQMBlMXJx9sRBAAoGgT+lQCD30\n0EM4nZGERc1c9cADD+BwOGKukySJdevW9WgyCQkJhEKhmGPBYBCbzQaA1WptJShCoRCqqmK327Fa\nrfprunIP7XftmqFKcVkx9YH6GC3IarJiMpgY7Rot/EACgaDPOaNPqKCgQBcMoVAIWZYpKCjAYrHo\nx7SfeGgRmZmZHD9+PObY8ePHdfNaRkYG1dXVrc5DxASnBVG0dU1H97Db7SQmJvZ4DQMVTQuyGC26\n+U1WZMJKGIDbp94utCCBQNDnnFET2rhxY1/NA4ApU6bgdrtjjm3fvp0LL7xQP//f//3fVFVV6QJn\n+/btOBwOcnNzsVgsjB49mo8//lh/jdfrZc+ePdxwww36PTZt2oSqqrpZcfv27eTn58cEKww1SspL\nsJvtqES0WW/Ii6zI2E12rv761SIcWyAQ9AsDate9+eabKS0tZdWqVRw8eJAnnniCXbt2MWdOZIOc\nPHkyeXl5LFy4kE8//ZStW7eyYsUK5s2bp/t15s6dy9q1a9myZQsHDhzg7rvvJj09ncsvvxyA6667\njrq6OpYtW8bBgwfZuHEjr732GkVFRf227r6g6mQVWUmRqEKb2UaqPZUMZwYuq0uY4QQCQb/R7X5C\nvcH48eNZs2YNK1asYO3atZx77rk8/fTTjB07Foj4ndasWcP999/PTTfdhMPh4Prrr2fBggX6PW68\n8UYaGxt55JFH8Hq95OfnU1xcrAup1NRUiouLeeihh7j22msZMWIEjz76KBdddFG/rLkvcFe62V+7\nH0+TB9TTgSUOs4MpmVOEGU4gEPQbkno2JMfEgSNHjjBz5kzefffdVvlNAxmtPM9x73H21e7Tj09I\nnUCaPU3kBAkEgl6lo71zQGlCgviiFSj1NHmwm+1kODJoCjbhDXlpCDSwZPoSIYAEAkG/IoTQECW6\nQKmKijfkxRvy6hqQQTIIASQQCPqdARWYIIgfJeUlANjN9pjjFQ0VAIxIHNHqNQKBQNDXCE1oiLLL\ns4vDDYep9dXSFGrCaXFiNVnxhrwAFI4r7OcZCgQCgRBCQxJ3pZvDDYfxhrxYzVZUVJqCTUhIjEke\nI4IRBALBgEEIoSFIcVkx3qAXj9eDyWDSWzQ4zU5RoFQgEAwohE9oiKEXKZXAleACoD5Qj4REtitb\nCCCBQDCgEJrQEEMrz+MNebGZbdjMkaKsDrODvIy8fp6dQCAQxCKE0BBjl2dXK1OcFpAgghEEAsFA\nQ5jjhhBaQEJbpjjRK0ggEAxEhCY0hGgrIMFqsuIwO0SRUoFAMCARmtAQQQQkCASCwYjQhIYIIiBB\nIBAMRoQQGiKIgASBQDAYEea4IYAISBAIBIMVIYSGACXlJW12TRUBCQKBYKAjzHGDHHelm80HNuMN\nelt1TRUBCQKBYKAjhNAgRusZpKoqKipIoKLqPYNGJQ2eDrACgeDsRAihQYq70s38LfM53HCYUDiE\nJEkkW5OxmqxUNFSQZk8TAQkCgWDAI3xCg5D1n6zn1r/cyu7ju2kKNhFWw8iKTH2gnma5GUmSRLsG\ngUAwKBBCaJDhrnSz+uPV1PhrMEgGFFUhGA4CYDKYSLGlcPXXrxYCSCAQDAqEEBpklJSX4Av5kBUZ\nk+G0NVVWZGRFFnlBAoFgUCF8QoOMqpNVAATDQWRF1o8rqoLdZBd5QQKBYFAhNKFBhqIq+EI+DFLs\nn85utjNt1DSRFyQQCAYVQggNQmxmGym2FGwmGwbJgEEykOnIZMn0JUILEggEgwphjhtEuCvdlHnK\nCIQChMIhzrGdQ4othVFJo8hwZggBJBAIBh1CCA0SohNTrWYrVrMVgCxXFmn2NEYkjujnGQoEAkHX\nEea4QUJxWTE7qnZQ66ulxldDQA4AUNFQASAi4gQCwaBEaEKDAHelm7e/eJuTwZPIioyqqtQH6hlm\nHUaiJVEkpgoEgkGL0IQGAcVlxboAgtNFSq0mq0hMFQgEgxohhAYBZZ4yHGZHq+M1vhphhhMIBIMa\nYY4bBHiDXrwhL7Iio6gKRslIgimBVHuq0IIEAsGgRgihAY670o2qqq3K9DgtTi7OvrgfZyYQCAQ9\nR5jjBjDuSjeL31lMQA6gqqp+3GQwYTPaRHUEgUAw6BGa0ABFywvyNHmwmq0kk4w35CXRkkiKLUV0\nTRUIBEMCIYQGKFpeULWvGoiY31LtqTjNTvIz80XXVIFAMCQQQmgA4q50s+2rbaioOMwOGpobqA/U\nk2xNRiISni2i4gQCwVBgwPmEfD4fv/rVr5g+fToXXnghRUVFlJeX6+c/+OADZs+ezQUXXMDVV1/N\n1q1bY15fW1vLnXfeyYUXXshFF13EihUrkGU55ppnnnmGSy+9lEmTJjFv3jwOHTrUF0vrNMVlxdQH\n6vE0efCGvNhMNkwGE96gl0xnpkhOFQiGIE899RTf+c53Yo41NTUxefJkmpqauOWWWxg/fnzMz/nn\nn8/MmTN5/PHHCYfD+uu+853vxFw3YcIEfT/dt29fq+uee+65NudUVFTE+PHjefXVV3tn0QxAIfTr\nX/+af/zjHzzxxBO8+OKLJCQkUFRURHNzM+Xl5cyfP5/CwkL+8pe/MHPmTBYsWMDnn3+uv/6OO+6g\npqaGZ599luXLl7Np0yZWr16tn3/55ZdZtWoVixcv5qWXXtLvHwwG+2O5rdC0IIvRAkSa1fllv26O\nW37ZciGABIKzhI8++oiJEyfidDoBuOqqq/jggw/0n1dffZXrrruOp59+mnXr1sW89t/+7d/06/7+\n97+zfv16mpqamDdvHk1NTfp1ZrOZN998s9XY9fX1/POf/+zdBTIAhdA777zDj3/8Y6ZMmcLYsWNZ\nuHAhVVVVlJeXs2HDBvLy8pg/fz5jx47lrrvuYvLkyWzYsAGAnTt3smPHDpYvX05ubi6XXHIJixYt\nYuPGjbqQKS4uZt68eRQWFjJ+/HhWrlxJbW1tm3+E/kDTghqaG2Ii4oJyUDSsEwxJ3JVuHtz6IPNf\nm8+DWx/EXenu7ykNGLZt28bFF59OxbBaraSlpek/5557LvPnz+eb3/wmJSUlMa+12+36dcOHD+cb\n3/gGixcvpq6uLka4fPOb38TtdlNXVxfz+rfffptJkyb17gIZgELonHPO4fXXX6e2tpZgMMif//xn\nXC4XWVlZlJaWMnXq1Jjrp02bRmlpKQClpaWMHDmSrKws/fzUqVPxer3s3buX2tpaDh06FHMPh8PB\nxIkT9Xv0Jy21IK08T7I1GZfVJUKyBUMOLQq0srESRVWobKykuKy4TwTRpk2bmDVrFhMnTuTSSy9l\n1SxV374AACAASURBVKpVKIrC6tWrmTt3Lo8//jgFBQVMmzaNhx56KMZaUlVVxc9//nPy8/P51re+\nxcKFCzl27Jh+XlEUnn76aS699FLy8vL4wQ9+0Mp18PrrrzNr1iwuuOACioqKOHHiRKs5btu2jRkz\nZnS4FovFgtFo7PA67RqLxaIfmzx5Mqmpqbzzzjsx15aUlHDllVd2eM+eMuCE0K9+9Ss8Hg/f+ta3\nyMvL46WXXuL3v/89SUlJeDwehg8fHnN9eno6Ho8HgGPHjpGent7qPEQ+NNp1Z7pHfyK0IMHZRkl5\nSZvH3yh/o1fH3bdvH/fddx8LFy7krbfe4p577mHdunX89a9/BSIPtDt37mTjxo089thjvPHGGzz0\n0ENAxG99yy23kJCQwAsvvMC6desIhULMmTNHF1QrV65k06ZNPPjgg7z66qt873vf4/bbb2f79u0A\nuN1ufvGLX/C9732PV199lenTp/OnP/0pZo7l5eXIskxubm676wgGg7zyyit8+OGHXHPNNWdcc0VF\nBStXriQtLY38/Hz9uCRJfPe7342xBtXV1eF2u7niiiu68K52jwEXHXf48GFSU1O5//77SU5OZt26\ndfz85z/npZdeIhAIxEhwiEj05uZmAPx+PwkJCTHnzWYzkiTR3NyM3+8HaHVN9D36i/WfrGfTvk0E\n5IBeHcEkmUi2JmMzicRUwdCk6mRVm8ePnjzaq+NWVFQgSRIjRozQf/74xz+SkZFBRUUFRqORxx9/\nnJSUFHJzc7nrrru4//77WbRoESUlJfj9fpYvX65rFr/5zW+YNm0ab731FpdeeikbNmxg9erVuhaT\nk5PDvn37+P3vf8+0adP405/+xLRp0/jZz34GwJgxY9i5cye7d+/W59iWFvTKK6/w+uuv678HAgFy\ncnJYsmQJN998c8y1Tz31FGvXrgUgFAohyzLnnXcea9as0X1MGoWFhcydO5eGhgZcLhdvvfUW+fn5\npKamxukdb58BJYQqKiq49957ee6558jLywMiTxRXXnklzzzzDAkJCYRCoZjXBINBbDYbELGXtgww\nCIVCqKqK3W7HarXqr2nvHv3B+k/Ws+TdJTQFI85CCQlZkZGQCMpBrjj3CqEFCYYkmYmZVDZWtjre\n200aZ8yYwaRJk/jBD35ATk4O06dPp7CwkBEjIuOee+65pKSk6Nfn5eURCoX48ssv+eyzz6irq+PC\nCy+Muaff7+fgwYNkZ2cTDAa58847MRhOG5tCoZC+qX/++edccsklMa/Py8uLEULvv/8+P/zhD2Ou\nueyyy/jFL36BoiiUlpby6KOPctlll3HLLbe0WuNNN93Ej3/8YyBihktOTm4lfDSmTJnCsGHDePfd\nd/n+97/fZ6Y4GGBCaM+ePYTDYSZOnKgfM5vNTJgwgcOHD5OZmcnx48djXnP8+HHdvJaRkdHK7qpd\nP3z4cDIzMwGorq4mJycn5pqxY8f2ypo6wl3pZvXHq/HLfkwGE8FwREBajBYSTAnCFyQY0swaN4vi\nsuJWx3s7D85qtfLss8+ye/du3n//fbZt28af/vQn7rjjDgBMptitUQt/NhgMmM1mxo0bx5o1a1rd\nNzExUd9zVq9eHbPPaK+HiAks2uQOkb1Ow+/388knn/DEE0/EXON0OvV7jhkzhsTERO68806SkpJ0\nrUrD5XK1Gr89JEniiiuu4M033+Tb3/42ZWVlPP744516bU8ZUD6hjIwMAPbv368fU1WVgwcPMnr0\naKZMmYLbHeuw3L59u/5EMmXKFCoqKqiqqoo573A4yM3NJSUlhdGjR/Pxxx/r571eL3v27KGgoH80\njeKyYg43HNbNcEbJiEEy6L2DhC9IMJQpGFlAUX4Ro5JGYZAMjEoa1Sd5cB9++CFPPvkk559/PgsW\nLOCFF17gxhtv1E1dX3zxBV6vV79+165dWK1Wzj33XL72ta9x5MgRkpOTycnJIScnh5SUFB555BEO\nHDhATk4OZrOZY8eO6edzcnLYvHkzmzZtAiA3N5edO3fGzGnPnj36v7dv305ubi5JSUlnXEdhYSFX\nXXUVq1atitk3u0NhYSH/+Mc/eOWVV5g6dSrnnHNOj+7XWQaUELrgggvIy8vjl7/8JaWlpRw8eJBl\ny5Zx9OhRbr75Zm6++WZKS0tZtWoVBw8e5IknnmDXrl3MmTMHiER55OXlsXDhQj799FO2bt3KihUr\nmDdvnu5Lmjt3LmvXrmXLli0cOHCAu+++m/T0dC6//PI+X68WDQeRoqSKqhBWw5gMJqwmK6Ndo4UW\nJBjyFIws4N5L7uV3V/2Oey+5t08eusxmM08++SQbNmygoqKCnTt3sn37dj0kuampiXvuuYfy8nLe\ne+89fvvb3/LjH/8Ym83G1VdfzbBhw7jrrrvYvXu3vo/s2rWLr33ta9hsNubOncvKlSt5/fXXqaio\nYMOGDTz55JN65O6cOXPYvXs3jz/+OF9++SUvvPACW7Zs0ef3/vvvdyoqDmDp0qU4HA7uu+8+FEXp\n9nuSn5+Py+VizZo1fWaKgwEmhIxGI7/73e+YNGkSv/jFL/jRj37EV199xXPPPcfIkSMZP348a9as\n4c033+Taa6/lb3/7G08//bRuSpMkiTVr1pCSksJNN93EPffcw/XXX8+CBQv0MW688Ub+/d//nUce\neYQf/ehHhEIhiouLWwU89AUl5SXYzXYcZgcmgwmL0aJrQXaTndun3i60IIGgF5g6dSoPP/wwL730\nEv/6r//KggULKCgoYOnSpQCMGjWK7OxsfvjDH3Lvvffyox/9iP/4j/8AIqa8P/7xj1itVubMmcON\nN96ILMusX79e9yPddddd3HjjjTz22GPMmjWL559/ngcffJDvf//7AJx//vn87ne/4+9//zvXXHMN\nr776Kj/5yU/0+XU2NBsiaS1Llizhk08+4dlnn+32e2IwGLjiiisIBoN9+lAuqS0Nk4I2OXLkCDNn\nzuTdd99l1Kj4FA+d/9p8PE0e9tXu4/+3d+dRTV7pH8C/CQECgSJiUFywCoLKNhEFRFo9Kp5RwaVH\ncQPX0TljR4S6YtXR0Yq4gK22Utdax2V0Rqb2OM4ZjlvFaRWkRBBkE5SggIAWjAGSvPf3Bz/eGgFx\nAd5Qn885nFPf+yb55sLJ0/e+N/dqtBp+4zqJWIIdgTsw53dzWuV1CCGvbvfu3Th79iwSExOFjvKb\n0NJnp1FNTHjXcIxDUVURarQ10Oq1/DYN3g7eVIAIIe8EKkICSS5ORpm6DGqtGlJTKaSm9dPHe9n0\novtAhJB3hlHdE3qXHEg9wF8FVdVUoVZXCytTK9hb2tN9IEIEtGTJEhqKa0d0JSSA5/cLevEqqGG9\nOEIIeRfQlZAAnt8vqPxZOWp0NQCAol+K2vyb4oQQYkyoCLWzpvYLelLzBDW6Gqi1atoxlRDyTqEi\n1M5opWxCCPkV3RNqR7RSNiGEGKIroXby/ErZDStk6zgd9JyeroIIIe8sKkLt4MWVsp9fI45WyiZE\nGK6urvjuu+9e+fzLly8jLy+vDRO1TKVSwdXV9ZV3gtbpdPjmm2/e6jVLSkrg6urKb8jX2qgItQNa\nKZsQ45OUlITf//7VJgKVlpbij3/8IyoqKto4Vev697//jejoaKFjvBTdE2pjL66U/fx+QRKxhFbK\nJkQgcrn8lc/tqEtsdoTcdCXUxhpmwzV1FUQrZRMinOeH41avXo01a9Zg8+bN8PX1hUKhwLJly/D0\naf1uxw27oM6ePRurV68GADx8+BDh4eEYNGgQ/P39ERkZidLSUv75w8LCsH79enz00UcYMmQILl68\niLCwMGzbtg1LliyBp6cnRo4ciRMnThjkSklJQWhoKBQKBfz9/bF582ZoNJom38OTJ08QFRWFgIAA\nuLm5ISAgADExMeA4DtevX8fKlSv599qwl1FKSgqmT58OT09PjBo1Cjt37kRtbS3/nMXFxVi0aBEU\nCgVGjhyJq1evtkZ3N4uuhNrQ898Jkojru1rH6WAqNoW5xBxbRm2hhUrJb0ZifiK+z/ketbralk9u\nZeYScwS7BCPQ6c23IDh79iymTp2KkydP4v79+4iIiICTkxMWL16MhIQETJ48Gbt378bQoUPx7Nkz\nhIWFQaFQ4OTJk9Dr9fjyyy8xZ84cnD17lt8a5vTp04iLi8P777+Pnj174vDhw/j2228xY8YMJCQk\n4KeffsKmTZtgbW2NoKAgKJVKzJ07F2FhYdi4cSNUKhU2bNgAlUqF+Pj4RplXrVqFx48fY+/evejU\nqRN++OEHbNq0Cd7e3vjwww+xfv16/PWvf0VSUhKsra2RlZWFBQsWIDw8HDExMXjw4AE+++wzlJeX\nIzo6GlqtFn/4wx/QpUsXnDhxAk+ePMG6deveuE9fBRWhNnQ+7zwA8Fs0cIyDqdgU1mbWCHYJpgJE\nflMS7yYKUoAAoFZXi8S7iW9VhDp16oS1a9fCxMQEffr0gb+/P9LS0gCA32XUxsYG1tbWOH36NDQa\nDbZu3QoTExMAQGxsLHx9ffHf//4XQUFBAOo36nzxvpOLiwu/b5GTkxOUSiWOHj2KoKAgHDp0CO7u\n7li1ahXfvmHDBixatAi5ubmwsLAweK4PPvgAvr6+6NevHwBg1qxZOHDgALKzszF69GhYWVkB+HXo\n8eDBgxg+fDgWLKi/BdC7d29s3LgRM2fORGRkJLKyslBQUICDBw+ie/f61VvWrl3baOvw1kRFqA0p\nS5R4pn3GfyeogZnEjO4Dkd+cwL6Bgl4JBfZ9u43YHB0d+YICANbW1gbDa8/LzMxEZWUlBg8ebHBc\no9EgPz+f/3dT++cMGWI4/O7l5cUvmJqbm8sP/TVoeI3c3Fx4enoatM2YMQMXLlzA6dOnUVhYiOzs\nbJSUlDS7w2pWVhbu3bsHhULBH2u4b5Sfn4/c3FzY2tryBaghX1uiItRGkouTkVqSyq+M0LAwqUQs\nQReLLnQfiPzmBDoFvtWViNCa2l25uRv7pqamcHZ2xp49exq1WVtb8/8tlUobtUskhh+7HMfxnw9N\nnd+QoanHLVq0CAUFBQgODsbEiRPh6emJOXOaH2ExNTXFpEmTsHDhwkZtcrkcmZmZjd6zqalps8/X\nGmhiQhtILk7GgdQDwP//Lhv+wDpJO6GLZRc42jgKmI4Q8rpeXN2+X79+UKlU6NSpE3r37o3evXvD\nzs4O0dHRyMnJeelzZWRkGPw7LS0NAwcOBFA//Pbzzz8btN+8eZNve15mZiaSkpKwe/duREZGYvz4\n8bC1tcWjR4/4QvJibmdnZ+Tn5/OZe/fujcrKSsTExECtVmPAgAF4/PgxCgsLm83b2qgItYGGe0F2\nlnawMbfhh+LqdHXob9cfv+v2OyHjEUJek0wmAwBkZ2fj8ePHCA4Ohq2tLSIiIpCeno6cnBwsW7YM\nSqWSvz/TnJ9++gnx8fEoKCjAt99+i/Pnz2P+/PkAgIULFyI9PR0xMTG4e/curl69io0bN2L48OGN\nipBcLodEIsH58+ehUqnw888/Y/Hixairq0NdXZ1B7vT0dKjVaixcuBC3bt1CdHQ08vPzcePGDaxa\ntQrV1dWQy+Xw9fWFm5sbVqxYgfT0dKSmpmLz5s2t3Z0GqAi1AWWJEjcf3kTFswqotWpYmVmhm1U3\n2EhtYC+zp5WyCelgrKysEBYWhh07dmDt2rWQSqU4fPgwpFIp5syZgxkzZkCn0+HIkSOws7N76XON\nGTMGt27dwsSJE3HixAls374dI0eOBFA/aSE+Ph43btzAhAkTEBUVhcDAQHz++eeNnqdr167YsmUL\n/vOf/2Ds2LFYsWIFvLy8MGHCBKSnpwMAfH194ePjgxkzZuDUqVNwdXXF119/jdTUVEyaNAkREREY\nMmQIP6xoYmKC/fv3w8HBAbNnz8bSpUsxd+7c1u3MF4hYR/g2kxFQqVQYNWoULly40OTNxgbJxcn4\n07k/Qa1VAwA0Wg3UWjWszazRp1MfbB29le4HEfKOCgsLg6OjIz777DOho7Sblj47aWJCKzuQegDq\nOjVK1CWQiCWwMrNCF8susDK1ogJECCEvoOG4VtSwVUOJugSMMX7DOhFEcLRxpAJECCEvoCuhVtKw\nUnaD52fEyUxlNBmBEIKjR48KHcHoUBFqJdFJ0ch6lIU6rg5g9QuUmknM8LTuKSwkFjQZgRBCmkDD\nca3gSNoRXCq8BA4cxCIxIAJq9bWo09VPk6StGgghpGlUhFrBEeWR+q26///7QGKRGCbi+uU/aKsG\nQghpHg3HtYLsimxU11ZDy2khYiKIxWKIRCJw4GirBkIIeQkqQm/pSNoRVGoqoeN0YIyBgYHjOMjM\nZOhv159WyiaEkJeg4bi3FHMtBjpOBz3T88dEIhF0nA5/9vmzgMkIIcT4URF6C8nFySh4UlB/D0hU\nfw+IgUEEESQiCV0FEUJIC2g47i2czzsPsUgMjnEwEZvABPWFSCwSw0ZqI3A6QggxfnQl9BYeVj+E\n3FLe6DjHOPh09xEgESGEdCxUhN6Cg7UDFN0U6CztzE/Plogl6G7VHVEfRAmcjhBCjB8Nx72Fsc5j\nUVxVDL+eflBVqaDWqiEzldG0bEIIeUVUhF6RXl8/+62kpIQ/5gAHTOw+EVcKr8BGaoOudl0x/P3h\n8OziCZVKJVRUQggxGg2fmQ2foS+iIvSKHj16BACYNWvWS8/7F/7VHnEIIaRDefToEXr37t3oOG1q\n94pqamqQkZEBuVwOExMToeMQQkiHoNfr8ejRI7i7u0MqlTZqpyJECCFEMDQ7jhBCiGCoCBFCCBEM\nFSFCCCGCoSJECCFEMFSECCGECIaK0FvQ6/XYuXMnAgICoFAoEB4ejvLycqFjNSsvLw+urq6NflJS\nUgAASUlJmDhxIjw9PREcHIwrV64InLje+vXr8emnnxocaylrRUUFli5disGDB2Po0KHYvn07dDpd\ne8bmNZV/ypQpjX4Pz58jdP7y8nKsWrUKAQEBGDx4MBYsWICcnBy+3dj7v6X8xt7/JSUlCA8Ph4+P\nDwYPHozIyEiUlpby7cbe/6+FkTcWFxfHhg0bxpKSklhGRgabOnUqmz59utCxmnXu3Dnm6+vLysrK\nDH7q6upYbm4uc3d3Z1999RXLy8tjcXFxzM3NjeXk5AiWl+M4tmvXLubi4sLWrFnDH3+VrDNmzGAz\nZ85kWVlZ7PLly8zPz4/FxsYaRX6O45iXlxc7e/aswe+hurraKPLr9Xo2bdo0FhISwpRKJcvNzWXh\n4eFs6NChrLKy0uj7v6X8xt7/HMex4OBgNmfOHJaVlcWysrLYrFmz2OTJkxljHefv/1VREXpDtbW1\nTKFQsH/+85/8saKiIubi4sJu3rwpYLLmxcXFsVmzZjXZtm7dOhYaGmpwLDQ0lK1du7Y9ojVy//59\nFhoaynx9fdmIESMMPsRbypqamspcXFzY/fv3+fYzZ84whULBamtrBc9/7969RvmeJ3T+27dvMxcX\nF5aXl8cfq62tZV5eXiwhIcHo+7+l/Mbe/2VlZSwiIoIVFRXxxxITE5mLiwt78uSJ0ff/66LhuDd0\n584dqNVq+Pj8umVDz5490aNHD354y9jk5uaib9++TbalpKQYvBcA8PX1Fey9pKamwsHBAd9//z16\n9uxp0NZS1pSUFPTo0QO9evXi2318fKBWq5GVldX24fHy/Dk5OZBKpejRo0eTjxU6v4ODA77++mv0\n6dOHPyYSiQAAv/zyi9H3f0v5jb3/5XI54uLi+L+bkpIS/P3vf4eHhwdsbGyMvv9fFxWhN9SwKF/X\nrl0Njtvb2xsscmpMcnNz8eDBA4SEhGDYsGGYO3cubt26BaD+/RjTe5k4cSK2bdsGubzxfk0tZS0t\nLYW9vX2jdgB4+PBhGyU29LL8ubm5sLa2xvLlyxEQEIDg4GAcPnwYHMcBED6/ra0tRowYAbH414+H\no0ePoqamBgEBAUbf/y3lN/b+f97ixYsxfPhwKJVKbN68GUDH+Pt/HVSE3pBGo4FYLIapqanBcTMz\nM9TW1gqUqnk1NTUoKirC06dPsXLlSuzduxf29vYIDQ1Ffn4+ampqYGZmZvAYY34vL8uq0Whgbm5u\n0G5qagqRSGQU7ycvLw/Pnj1DQEAADh48iJkzZ+KLL77Anj17ABhf/gsXLiA2Nhbz5s2Dk5NTh+v/\nF/N3pP5funQpTp8+jUGDBmHevHkoLS3tcP3fElpF+w1JpVJwHAedTgeJ5NdurKurg4WFhYDJmiaV\nSpGcnAwzMzP+D3jr1q24ffs2jh8/DnNzc2i1WoPHGOt7aSmrVCpFXV2dQbtWqwVjDJaWlu2Wszkx\nMTF49uwZ3nvvPQCAq6srqqurER8fjyVLlhhV/jNnzmDdunUYN24cVqxYAaBj9X9T+TtS/7u6ugIA\n4uLiMGLECCQkJHSo/n8VdCX0hhwcHAD8usVDg7KyskaXysbCysrK4P+gxGIxnJ2d8fDhQzg4OKCs\nrMzgfGN9Ly1l7datW5O/F6Dx8KkQJBIJ/wHYwNXVFWq1GtXV1UaTf+/evYiKisL06dOxbds2fnir\no/R/c/mNvf/Ly8tx7tw5g2MWFhbo1asXSktLO0z/vyoqQm+of//+kMlkuHHjBn9MpVKhuLgYQ4YY\n366qGRkZGDRoEDIyMvhjer0ed+7cQb9+/eDt7Y3k5GSDx1y/fh2DBw9u76gtaimrt7c3ioqKDMa/\nr1+/DplMhv79+7dr1qaEhITw4/sN0tPTYW9vj/fee88o8u/fvx+7du1CeHg41q1bx9/YBzpG/78s\nv7H3/4MHD/DJJ58gPT2dP1ZdXY2CggI4Ozt3iP5/LYLOzevgtm/fzvz9/dmVK1f47wm9OHXSWGi1\nWhYUFMQmT57M0tLSWE5ODluxYgUbMmQIKy8vZ3fu3GFubm7s888/Z3l5eWzXrl3Mw8PDYJqrUEJD\nQw2mOLeUleM4FhISwqZNm8YyMjL470l88cUXRpF/3759zN3dnZ8ufOrUKebl5cVOnTplFPmzsrLY\ngAEDWFRUVKPvlKnVaqPv/5byG3v/6/V6NnPmTDZhwgSmVCrZ7du32fz589no0aPZ06dPjb7/XxcV\nobeg1WpZdHQ08/HxYYMGDWJLly5lFRUVQsdqVklJCfvkk0+Yn58f8/LyYvPmzWPZ2dl8+6VLl9i4\nceOYu7s7mzBhArt27ZqAaX/14oc4Yy1nLSsrY4sXL2ZeXl7M39+f7dy5k+n1+vaMzXsxP8dx7NCh\nQ2zMmDHM3d2djRkzhp08edLgMULm37lzJ3NxcWny58svv2SMGXf/t5Tf2PufMcYqKirYqlWrmJ+f\nH1MoFGzJkiWspKSEbzfm/n9dtKkdIYQQwdA9IUIIIYKhIkQIIUQwVIQIIYQIhooQIYQQwVARIoQQ\nIhgqQoQQQgRDRYiQdpadnY3IyEgMGzYM7u7uCAgIQEREBO7cuSN0NAOrV69GYGCg0DHIbxwVIULa\n0Z07dzB9+nRUVVVh3bp1OHToEFauXAmVSoWQkBCkpaUJHZGQdkWraBPSjo4cOQI7Ozvs27cPJiYm\n/PFRo0Zh7Nix+Oqrr7Bv3z4BExLSvqgIEdKOKioqwBgDx3EGRUgmk2HNmjXQaDQAgLCwMDg6OsLe\n3h7Hjx+HXq/Hhx9+iLVr16Jz587845KTk7Fr1y5kZGRAKpUiMDAQK1euNFgluri4GNu3b8e1a9eg\n1Wrh7e2NqKgoODs78+f88ssv2Lp1Ky5cuADGGEJCQvhN3ghpS7RsDyHt6G9/+xs2bdoEd3d3fPTR\nR/Dz84OTk1Oj88LCwpCVlQW5XI7IyEhUV1dj27Zt6NGjB/7xj39ALBYjOTkZ8+bNg7+/P2bOnImK\nigrExcXBwcEBJ06cgEQiQWVlJSZNmgRLS0ssWbIE5ubmOHDgAO7evYuEhAT06NEDHMdh2rRpKC4u\nxrJly9CpUyccOHAA6enpcHBwQGJiogA9Rd4ZQi5cR8i7huM4Fhsbyzw8PPhFNf38/Njy5cuZUqnk\nzwsNDWVubm7swYMH/LGLFy8yFxcXdunSJcYYY9OmTWMTJkwwWJgyMzOTubq6su+++44xxlhsbCzz\n9PRkDx8+5M/RaDQsICCAffrpp4yx+sUwXVxc2A8//MCfo1arma+vLxs9enSb9AMhDWhiAiHtSCQS\nITIyElevXsXOnTsxZcoUyGQynD17FiEhITh27Bh/rre3N795IgCMGDECZmZmSElJgUajgVKpxIgR\nI/gdfnU6Hfr164fu3bvjf//7HwDgxx9/hJubG7p06cKfI5FIMGzYMP6clJQUmJub44MPPuBfy9LS\nEsOHD2+nXiHvMronRIgAbGxsEBQUhKCgIABAZmYmVqxYgZiYGP6Yvb29wWNEIhE6d+6MqqoqVFVV\ngeM4xMfHIz4+vtHzN+yk+eTJE9y7dw9ubm6NzjE1NQVQfz/I1ta2UbtcLn+7N0nIK6AiREg7KSkp\nwZQpU7B06VJMnTrVoG3gwIGIjIzExx9/DJVKBaC+gDyPMYaKigp07twZMpkMIpEI8+fPx9ixYxu9\nlkwmA1C/pbufnx+WL1/ebC5bW1tUVlaCMWawA+mLr09IW6DhOELaiVwuh4mJCY4fP47a2tpG7Xfv\n3oWFhQUcHR0BAKmpqaiqquLbL168CK1WCz8/P1hZWWHgwIEoLCyEh4cH/9OnTx/s2rULSqUSAODj\n44OCggI4OTkZnHfq1CmcO3cOADB06FDU1dXhwoUL/GvV1dXh2rVrbdkdhAAATDZs2LBB6BCEvAvE\nYjEcHR1x9OhRJCYmQiQSQaPRIC8vD8ePH8f+/fsREREBPz8/JCQkoLCwEMnJybCzs0NKSgo2bdoE\nb29vfPzxxwCAbt26Yc+ePVCpVDAzM0Nubi7+8pe/ICMjA4sXL4adnR369euHY8eO4cqVK7CyskJZ\nWRl2796NM2fOYNq0aRgwYAB69eqFtLQ0nDhxAtbW1qioqMCWLVuQn58PmUyG2bNnC9xz5LeM/Vag\nlAAAAOBJREFUpmgT0s4yMjJw8OBBpKamoqKiAubm5hg4cCBmz57NL5MTFhYGkUgEhUKBY8eOQSKR\nYPz48Vi+fDksLCz457p27Rr27NmDzMxMmJubw8PDAxEREfDw8ODPKSwsRGxsLH788UdotVr07dsX\nCxYswPjx4/lzNBoNduzYgXPnzqG2thbjxo2DpaUlLl++TFO0SZuiIkSIEQoLC4OJiQm++eYboaMQ\n0qbonhAhhBDBUBEihBAiGBqOI4QQIhi6EiKEECIYKkKEEEIEQ0WIEEKIYKgIEUIIEQwVIUIIIYL5\nP0DH/ykcJviuAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ts = linrange(1, 300, 1000)\n", + "\n", + "plot(data, 'go', label='speed/RPM')\n", + "plot(ts, I(ts), color='green', label='interpolated')\n", + "\n", + "decorate(xlabel='Speed',\n", + " ylabel='RPM')\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(14973.6158648135)" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "I(335)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nrkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ts = linrange(1, 300, 1000)\n", + "\n", + "plot(data, 'go', label='Torque')\n", + "plot(ts, I1(I(ts)), color='green', label='interpolated')\n", + "\n", + "decorate(xlabel='Speed',\n", + " ylabel='Torque')\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "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.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/code/chap09-fig01.pdf b/code/chap09-fig01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fc5eca3a8af4a4fe258ffab84cc12c021619de27 GIT binary patch literal 10619 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 Sg*x?RfVmD46;;zc2>E|+IT!K( literal 0 HcmV?d00001 diff --git a/code/chap09mine.ipynb b/code/chap09mine.ipynb new file mode 100644 index 00000000..a86aba4f --- /dev/null +++ b/code/chap09mine.ipynb @@ -0,0 +1,1845 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Modeling and Simulation in Python\n", + "\n", + "Chapter 9: Projectiles\n", + "\n", + "Copyright 2017 Allen Downey\n", + "\n", + "License: [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# If you want the figures to appear in the notebook, \n", + "# and you want to interact with them, use\n", + "# %matplotlib notebook\n", + "\n", + "# If you want the figures to appear in the notebook, \n", + "# and you don't want to interact with them, use\n", + "# %matplotlib inline\n", + "\n", + "# If you want the figures to appear in separate windows, use\n", + "# %matplotlib qt5\n", + "\n", + "# tempo switch from one to another, you have to select Kernel->Restart\n", + "\n", + "%matplotlib inline\n", + "\n", + "from modsim import *" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "### Dropping pennies\n", + "\n", + "I'll start by getting the units we'll need from Pint." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "m = UNITS.meter\n", + "s = UNITS.second\n", + "kg = UNITS.kilogram" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "And defining the initial state." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
y381 meter
v0.0 meter / second
\n", + "
" + ], + "text/plain": [ + "y 381 meter\n", + "v 0.0 meter / second\n", + "dtype: object" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "init = State(y=381 * m, \n", + " v=0 * m/s)\n", + "init" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Acceleration due to gravity is about 9.8 m / s$^2$." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "g = 9.8 * m/s**2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "When we call `odeint`, we need an array of timestamps where we want to compute the solution.\n", + "\n", + "I'll start with a duration of 10 seconds." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.] second" + ], + "text/latex": [ + "$[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.] second$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "duration = 10 * s\n", + "ts = linspace(0, duration, 11)\n", + "ts" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Now we make a `System` object." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "system = System(init=init, g=g, ts=ts)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "And define the slope function." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def slope_func(state, t, system):\n", + " \"\"\"Compute derivatives of the state.\n", + " \n", + " state: position, velocity\n", + " t: time\n", + " system: System object containing `g`\n", + " \n", + " returns: derivatives of y and v\n", + " \"\"\"\n", + " y, v = state\n", + " unpack(system) \n", + "\n", + " dydt = v\n", + " dvdt = -g\n", + " \n", + " return dydt, dvdt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "It's always a good idea to test the slope function with the initial conditions." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0 meter / second\n", + "-9.8 meter / second ** 2\n" + ] + } + ], + "source": [ + "dydt, dvdt = slope_func(init, 0, system)\n", + "print(dydt)\n", + "print(dvdt)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Now we're ready to run `odeint`" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "run_odeint(system, slope_func)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Here's what the results look like." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
yv
0.0381.00.0
1.0376.1-9.8
2.0361.4-19.6
3.0336.9-29.4
4.0302.6-39.2
\n", + "
" + ], + "text/plain": [ + " y v\n", + "0.0 381.0 0.0\n", + "1.0 376.1 -9.8\n", + "2.0 361.4 -19.6\n", + "3.0 336.9 -29.4\n", + "4.0 302.6 -39.2" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "system.results.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
yv
6.0204.6-58.8
7.0140.9-68.6
8.067.4-78.4
9.0-15.9-88.2
10.0-109.0-98.0
\n", + "
" + ], + "text/plain": [ + " y v\n", + "6.0 204.6 -58.8\n", + "7.0 140.9 -68.6\n", + "8.0 67.4 -78.4\n", + "9.0 -15.9 -88.2\n", + "10.0 -109.0 -98.0" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "system.results.tail()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "The following function plots the results." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def plot_position(results):\n", + " \"\"\"Plot the results.\n", + " \n", + " results: DataFrame with position, `y`\n", + " \"\"\"\n", + " newfig()\n", + " plot(results.y, label='y')\n", + " \n", + " decorate(xlabel='Time (s)',\n", + " ylabel='Position (m)')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Here's what it looks like." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap09-fig01.pdf\n" + ] + }, + { + "data": { + "image/png": "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\nYBs/fryTKxFCiJbn113Cv6ayyBwugPVm0H379hEYGIhGo3F2OUII0SKYTCaKioro0aOHci/kpUjY\nCCGEsLsW1/oshBCi5ZGwEUIIYXcSNkIIIexOwkYIIYTdSdgIIYSwOwmbyzCZTLz66qsMHDiQxMRE\nZsyYQXFxsbPLcpji4mKeeOIJBg4cSFJSEn/+8585cuSIs8tyij179tCtWzcyMjKcXYrDffzxx4wY\nMYL4+HjGjh3LDz/84OySHKqmpobnn39e+XcwZcoUjh075uyyHGLevHnMmTPHZmzr1q2MHj2a+Ph4\nRo0aRXp6epOeS8LmMhYtWkRaWhovv/wyK1asID8/n4ceesjZZTmE2WzmwQcf5MSJE/zrX//io48+\nwtPTk0mTJlFaWurs8hyqpqaGxx9//Ip3SLdGaWlpPPvss9x7772sWbOG5ORkHnjgAfLy8pxdmsP8\n7W9/Y9u2bbzxxhusXLkSnU7HlClTlAUbWyOLxaJ8v7907Ngxpk2bxsiRI0lLS2PYsGFMnz6do0eP\nNulJxSXU19dbEhMTLZ988okylpuba4mJibHs3LnTiZU5xv79+y0xMTGWY8eOKWP19fWWXr16WdLS\n0pxYmeM9/fTTlgkTJlhiYmIsP/74o7PLcRiz2WwZMmSIZcGCBcqYyWSy3HrrrZbPP//ciZU5VkpK\nimXZsmXK46NHj1piYmIs+/btc2JV9nPy5EnLhAkTLH379rUMHjzY8tRTTynbzv9b+KUJEyZY5s6d\ne8XnlTObRhw6dIjq6mpSUlKUsYiICMLDw8nMzHRiZY4RGhrKW2+9RadOnZSx81OLl5eXO6ssh0tP\nT2fLli3MnTvX2aU43PHjxzl16hS33HKLMqZWq/nss88YNWqUEytzLD8/P9atW0dJSQkGg4FVq1bh\n7e1NZGSks0uzi127dhEaGsqaNWuIiIiw2ZaZmWnzngjQt2/fJr0nytxojTg/uVxwcLDNeFBQUJuY\nrNPX15fBgwfbjC1fvpy6ujoGDhzonKIc7OzZs8yZM4e///3veHt7O7schztx4gQAFRUV/OlPf+Lo\n0aNERUUxa9Ysevfu7dziHOj5559n9uzZ3HDDDWg0GvR6Pe+++y5eXl7OLs0uRo8ezejRoy+5LT8/\n/5rfE+XMphG1tbWo1Wq0Wq3NuKura6u+VtuYTZs28dprrzF58uTftLR3S/LMM88wdOhQUlNTnV2K\nU1RVVQHw5JNPcscdd7B06VK6dOnCxIkTycrKcnJ1jpOTk0NAQAD//ve/+fDDDxk4cCAzZsxoE790\n/lpdXZ2ydth5TX1PlLBphF6vx2w2YzQabcYNBgNubm5Oqso5Vq9ezYwZM7j55puZPXu2s8txiLS0\nNA4cOMATTzzh7FKc5vwvWvfffz+jRo2ie/fuPPPMM3Ts2JEPP/zQydU5Rm5uLk8//TRz5sxh0KBB\n9OrVi1dffRWdTsd7773n7PIcTqfT0dDQYDPW1PdEuYzWiNDQUMA6bfb5PwMUFhZedBrZmi1ZsoQF\nCxYwYcIE5s6de81LwrY0q1evpqCgQLlkaDk3X+29997LmDFjeO6555xZnkMEBQUBEBMTo4ypVCqi\noqLaTDfavn37MJlM9OjRQxnTarV07dqVnJwcJ1bmHKGhoRQWFtqMNfU9UcKmEXFxcXh4eLB9+3bl\n+mVeXh6nTp0iOTnZydU5xttvv82CBQuYMWMG06dPd3Y5DvXKK69QV1enPC4qKmL8+PG88MILDBgw\nwImVOU737t1xd3fn559/pmfPnoA1dLOystrMMushISGAddXg7t27Axd+Bm3x8mqfPn3YsWOHzVhG\nRgZJSUlXPFbCphGurq7cfffd/OMf/8DX1xd/f3+effZZUlJSSEhIcHZ5dnfo0CFef/11br/9du68\n805lcTkADw8P3N3dnVid/f36NzWdTqeM+/v7O6Mkh3Nzc2PixIksWLCAgIAAYmJi+OCDDzh58iQL\nFy50dnkOER8fT0JCAk8++STPPPMMvr6+/Pe//+X06dNMmDDB2eU53IQJE7j99ttZuHAhv//97/ni\niy/46aef+Otf/3rFYyVsLuORRx7BaDQye/ZsjEYjN954I/PmzXN2WQ6xbt06TCYTn3zyCZ988onN\ntocffpgHHnjASZUJR3r44Ydxc3Pj73//OyUlJXTt2pV3332XqKgoZ5fmEBqNhiVLlvDaa68xc+ZM\nampq6NGjBx988AHh4eHOLs/hYmNjWbx4MfPnz+ftt98mKiqKN998s0lNQ7J4mhBCCLuTbjQhhBB2\nJ2EjhBDC7iRshBBC2J2EjRBCCLuTsBFCCGF3EjZCCCHsTu6zEeIqPPnkk6SlpV12n5SUFJYvX849\n99yDRqNx6hxaZWVljB07lv/85z906NDhivsvXryY4uLiJt2kJ8TVkPtshLgKJ0+e5OzZs8rjZ599\nFo1GY7PejaenJ507d+bYsWOoVCqnzpI9a9YsgoODefzxx5u0f11dHSNHjuTFF19sM1PSCMeQMxsh\nrkL79u1p37698tjT0xONRnPJKYw6d+7syNIusnfvXtavX8+3337b5GP0ej2TJk3ixRdf5PPPP7dj\ndaKtkc9shLCTe+65h0mTJimPY2NjWblyJY899hiJiYn069ePxYsXU1VVxV/+8hf69OnDgAEDmD9/\nPr+84FBaWsrcuXPp378/8fHx3HXXXezcufOKr7906VJuuOEG/Pz8lLF9+/YxceJE+vTpQ2JiIpMm\nTWLPnj02x91yyy0cPXqULVu2/OafgRDnSdgI4UAvv/wyvr6+/Otf/2LIkCEsWrSIcePG4ebmxuLF\ni7nppptYunQpGzZsAKC+vp5JkyaxZcsWZs6cycKFC/H29mbSpEns3bu30deprq5m8+bNDB8+XBmr\nqqpiypQp+Pr6smjRIl5//XVqa2uZMmWKslAaWJcWSExMZM2aNfb7QYg2Ry6jCeFA3bt3Z86cOYB1\nGYvVq1fj7++vTPDar18/1qxZw549exgxYgSfffYZhw8f5uOPP1am+U9NTWXcuHG8/vrr/Oc//7nk\n62RmZtLQ0EB8fLwyduzYMUpLS/nTn/6kLOscFRXFypUrqa6uxtPTU9m3R48erFu3zi4/A9E2yZmN\nEA70yzd/X19fNBqNzZhKpcLb25uKigoAfvjhB4KDg+natStGoxGj0YjZbGbIkCHs2LEDg8Fwydc5\nv7hZRESEMtalSxf8/Py4//77mTdvHhs3biQgIIDZs2dftKRCeHg4RUVFjT6/EFdLzmyEcCAPD4+L\nxi63NlBZWRn5+fnKwl2/VlpaeslVEisrKwFsluv18PDg/fffZ8mSJXz55ZesXLkSvV7P6NGjmTt3\nrs3a8udrqqqqsvnMR4hrJWEjRDPWrl07oqOjefnlly+53dfX97LjlZWVeHl5KeNRUVHMnz8fk8nE\n3r17+eyzz/jwww/p2LEj/+///T9lv/LyctRqNd7e3tfxuxFtmVxGE6IZS05O5vTp0wQFBdGzZ0/l\na9OmTSxfvhytVnvJ48LCwgDIz89XxjZu3Ei/fv0oKipCo9GQmJjIX//6V7y8vDhz5ozN8fn5+QQF\nBaHRaOz3zYk2RcJGiGZs7NixBAcHM3nyZD777DN+/PFHXnrpJZYsWUJkZCQqleqSxyUlJaHX621a\npHv37o3FYmH69Ol8/fXX/PDDD8ybN4+qqiqbrjWAXbt2MXDgQLt+b6JtkbARohk7/zlLr169eOml\nl7jvvvv47rvvePrpp3nooYcaPc7NzY3U1FSbGzr9/f155513aNeuHXPmzGHq1Kns37+fRYsWkZyc\nrOxXVFTEoUOHLgogIX4Lma5GiFZq79693HXXXWzevPmSTQSNWbJkCevXryctLa3RMychrpac2QjR\nSsXHxzNs2DDefffdJh9TU1PDBx98wMyZMyVoxHUlYSNEK/bXv/6V9evXk5OT06T933nnHYYMGUJq\naqqdKxNtjVxGE0IIYXdyZiOEEMLuJGyEEELYnYSNEEIIu5OwEUIIYXcSNkIIIezu/wOZ2dHwQBbM\n6wAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_position(system.results)\n", + "savefig('chap09-fig01.pdf')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "**Exercise:** Add a print statement to `slope_func` to print the value of `t` each time it's called. What can we infer about how `odeint` works, based on the results?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "**Exercise:** Change the value of `dt` and run the solver again. What effect does it have on the results?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Onto the sidewalk\n", + "\n", + "Here's the code again to set up the `System` object." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def make_system(duration, v_init=0):\n", + " \"\"\"Make a system object.\n", + " \n", + " duration: time of simulation in seconds\n", + " v_init: initial velocity, dimensionless\n", + " \n", + " returns: System object\n", + " \"\"\"\n", + " init = State(y=381 * m, v=v_init * m / s)\n", + "\n", + " g = 9.8 * m/s**2\n", + " ts = linspace(0, duration, 11)\n", + " return System(init=init, g=g, ts=ts)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And run the simulation." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
yv
0.0381.00.0
1.0376.1-9.8
2.0361.4-19.6
3.0336.9-29.4
4.0302.6-39.2
5.0258.5-49.0
6.0204.6-58.8
7.0140.9-68.6
8.067.4-78.4
9.0-15.9-88.2
10.0-109.0-98.0
\n", + "
" + ], + "text/plain": [ + " y v\n", + "0.0 381.0 0.0\n", + "1.0 376.1 -9.8\n", + "2.0 361.4 -19.6\n", + "3.0 336.9 -29.4\n", + "4.0 302.6 -39.2\n", + "5.0 258.5 -49.0\n", + "6.0 204.6 -58.8\n", + "7.0 140.9 -68.6\n", + "8.0 67.4 -78.4\n", + "9.0 -15.9 -88.2\n", + "10.0 -109.0 -98.0" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "system = make_system(10)\n", + "run_odeint(system, slope_func)\n", + "system.results" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "To figure out when the penny hit the sidewalk, we use `interp_inverse`, which return a function that maps from height to time." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "y = system.results.y\n", + "T = interp_inverse(y, kind='cubic')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "`T(0)` interpolates the time when the height was 0." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(8.81792826905006)" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "T_sidewalk = T(0)\n", + "T_sidewalk" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "We can compare that to the exact result. Without air resistance, we have\n", + "\n", + "$v = -g t$\n", + "\n", + "and\n", + "\n", + "$y = 381 - g t^2 / 2$\n", + "\n", + "Setting $y=0$ and solving for $t$ yields\n", + "\n", + "$t = \\sqrt{\\frac{2 y_{init}}{g}}$" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "8.817885349720552 second" + ], + "text/latex": [ + "$8.817885349720552 second$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sqrt(2 * init.y / g)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "The estimate is accurate to 4 decimal places." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "We can double-check by running the simulation for the estimated flight time." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "system = make_system(duration=T_sidewalk)\n", + "run_odeint(system, slope_func)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "And checking the final state." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def final_state(results):\n", + " \"\"\"Returns the final position and velocity, with units.\n", + " \n", + " results: TimeFrame with y and v.\n", + " \n", + " returns: y, v at t_end\n", + " \"\"\"\n", + " t_end = results.index[-1]\n", + " y, v = results.loc[t_end]\n", + " return y*m, v*m/s" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "As expected, the final height is close to 0." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "-0.003708896250259386 meter" + ], + "text/latex": [ + "$-0.003708896250259386 meter$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_final, v_final = final_state(system.results)\n", + "y_final" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "And we can check the final velocity." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "-86.41569703669059 meter/second" + ], + "text/latex": [ + "$-86.41569703669059 \\frac{meter}{second}$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v_final" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "And convert to km/h" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "-311.0965093320861 kilometer/hour" + ], + "text/latex": [ + "$-311.0965093320861 \\frac{kilometer}{hour}$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "km = UNITS.kilometer\n", + "h = UNITS.hour\n", + "v_final.to(km / h)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "If there were no air resistance, the penny would hit the sidewalk (or someone's head) at more than 300 km/h.\n", + "\n", + "So it's a good thing there is air resistance." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Try changing the initial velocity and see what effect it has on the time to hot the sidewalk. Sweep a range of values for the initial velocity, from 0 to 25 m/s, and plot `T_sidewalk` as a function of initial velocity. You might find the following function useful.\n", + "\n", + "Things might go horribly wrong for the larger initial velocities. What's going on?" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def flight_time(system):\n", + " \"\"\"Simulates the system and computes flight time.\n", + " \n", + " Uses cubic interpolation.\n", + " \n", + " system: System object\n", + " \n", + " returns: flight time in seconds\n", + " \"\"\"\n", + " run_odeint(system, slope_func)\n", + " y = system.results.y\n", + " inverse = Series(y.index, index=y.values)\n", + " T = interpolate(inverse, kind='cubic')\n", + " T_sidewalk = T(0)\n", + " return T_sidewalk * s" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "duration = 10\n", + "vs = linrange(0, 25, 1)\n", + "\n", + "for v_init in vs:\n", + " system = make_system(duration, v_init)\n", + " run_odeint(system, slope_func)\n", + " y = system.results.y\n", + " inverse = Series(y.index, index=y.values)\n", + " T = interpolate(inverse, kind='cubic')\n", + " T_sidewalk = T(0)\n", + " plot(v_init, T_sidewalk, 'b-')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### With air resistance" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next we'll add air resistance using the [drag equation](https://en.wikipedia.org/wiki/Drag_equation)\n", + "\n", + "First I'll create a `Condition` object to contain the quantities we'll need." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "condition = Condition(height = 381 * m,\n", + " v_init = 0 * m / s,\n", + " g = 9.8 * m/s**2,\n", + " mass = 2.5e-3 * kg,\n", + " diameter = 19e-3 * m,\n", + " rho = 1.2 * kg/m**3,\n", + " v_term = 18 * m / s,\n", + " duration = 30 * s)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Now here's a version of `make_system` that takes a `Condition` object as a parameter.\n", + "\n", + "`make_system` uses the given value of `v_term` to compute the drag coefficient `C_d`." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def make_system(condition):\n", + " \"\"\"Makes a System object for the given conditions.\n", + " \n", + " condition: Condition with height, g, mass, diameter, \n", + " rho, v_term, and duration\n", + " \n", + " returns: System with init, g, mass, rho, C_d, area, and ts\n", + " \"\"\"\n", + " unpack(condition)\n", + " \n", + " init = State(y=height, v=v_init)\n", + " area = np.pi * (diameter/2)**2\n", + " C_d = 2 * mass * g / (rho * area * v_term**2)\n", + " ts = linspace(0, duration, 101)\n", + " \n", + " return System(init=init, g=g, mass=mass, rho=rho,\n", + " C_d=C_d, area=area, ts=ts)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Let's make a `System`" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
inity 381 meter\n", + "v 0.0 meter / secon...
g9.8 meter / second ** 2
mass0.0025 kilogram
rho1.2 kilogram / meter ** 3
C_d0.4445009981135434 dimensionless
area0.0002835287369864788 meter ** 2
ts[0.0 second, 0.3 second, 0.6 second, 0.8999999...
\n", + "
" + ], + "text/plain": [ + "init y 381 meter\n", + "v 0.0 meter / secon...\n", + "g 9.8 meter / second ** 2\n", + "mass 0.0025 kilogram\n", + "rho 1.2 kilogram / meter ** 3\n", + "C_d 0.4445009981135434 dimensionless\n", + "area 0.0002835287369864788 meter ** 2\n", + "ts [0.0 second, 0.3 second, 0.6 second, 0.8999999...\n", + "dtype: object" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "system = make_system(condition)\n", + "system" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Here's the slope function, including acceleration due to gravity and drag." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def slope_func(state, t, system):\n", + " \"\"\"Compute derivatives of the state.\n", + " \n", + " state: position, velocity\n", + " t: time\n", + " system: System object containing g, rho,\n", + " C_d, area, and mass\n", + " \n", + " returns: derivatives of y and v\n", + " \"\"\"\n", + " y, v = state\n", + " unpack(system)\n", + " \n", + " f_drag = rho * v**2 * C_d * area / 2\n", + " a_drag = f_drag / mass\n", + " \n", + " dydt = v\n", + " dvdt = -g + a_drag\n", + " \n", + " return dydt, dvdt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "As always, let's test the slope function with the initial conditions." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(, )" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "slope_func(system.init, 0, system)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "And then run the simulation." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "run_odeint(system, slope_func)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "First check that the simulation ran long enough for the penny to land." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(,\n", + " )" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "final_state(system.results)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Then compute the flight time." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(22.439794207078908)" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y = system.results.y\n", + "inverse = Series(y.index, index=y.values)\n", + "T = interpolate(inverse, kind='cubic')\n", + "T_sidewalk = T(0)\n", + "T_sidewalk" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Setting the duration to the computed flight time, we can check the final conditions." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "condition.set(duration=T_sidewalk)\n", + "system = make_system(condition)\n", + "run_odeint(system, slope_func)\n", + "y_final, v_final = final_state(system.results)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "The final height is close to 0, as expected. And the final velocity is close to the given terminal velocity." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(,\n", + " )" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_final, v_final" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Here's the plot of position as a function of time." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap09-fig02.pdf\n" + ] + }, + { + "data": { + "image/png": "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\nASKEEKJD/j8VNerOzMcPPgAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_position(system.results)\n", + "savefig('chap09-fig02.pdf')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And velocity as a function of time:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def plot_velocity(results):\n", + " \"\"\"Plot the results.\n", + " \n", + " results: DataFrame with velocity, v\n", + " \"\"\"\n", + " newfig()\n", + " plot(results.v, label='v')\n", + " \n", + " decorate(xlabel='Time (s)',\n", + " ylabel='Velocity (m/2)')" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_velocity(system.results)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "From an initial velocity of 0, the penny accelerates downward until it reaches terminal velocity; after that, velocity is constant." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Run the simulation with an initial velocity, downward, that exceeds the penny's terminal velocity. Hint: use `condition.set`.\n", + "\n", + "What do you expect to happen? Plot velocity and position as a function of time, and see if they are consistent with your prediction." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAEPCAYAAABsj5JaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlclOXaB/DfMDAMiyAiO7iwCG4IiKiJK8e0Th5zPZX2\nqm+e0jiaWVZaemw7qVSm8qYd9a0XzfJoUpp20DAxy9QRxFCRRZRFBgZEZIcZ5v0DZ2AEdCSG2X7f\nz4fPR+7nGeaCprnmuZ7rvm+BUqlUgoiI6CFZ6DsAIiIyTkwgRETUIUwgRETUIUwgRETUIZb6DqAr\n1NbWIi0tDS4uLhAKhfoOh4jIKCgUCshkMgwaNAhisbjVcbNIIGlpaZgzZ46+wyAiMkpffvklwsPD\nW42bRQJxcXEB0PRHcHd313M0RETGQSqVYs6cOer30HuZRQJRla3c3d3h7e2t52iIiIxLe6V/s0gg\n7bl1pxZHz9yAo50If4roDStL9hQQEWnLrN8xL+eUouR2DbILypGaKdN3OERERsWsE0jP7jbqf6dm\nyiBXNOoxGiIi42LWCSTAuzvsbawAADV1cqRfv6XniIiIjIdZJxCh0AIh/Zq7Cy5kyNDYyLUliYi0\nYdYJBAAG9HWGtaipw+B2ZR2u3SzXc0RERMbB7BOIyEqIQb491d8npxeDK9wTET2Y2ScQABgS0BNC\nCwEAoLisGvnFlXqOiIjI8DGBALAVW6F/nx7q73++UAAFO7KIiO6LCeSuof3d1BMJb92pxfn0Yj1H\nRERk2JhA7upmK8KIQR7q7yXpRSgtr9FjREREho0JpIXBfj3h7mwHAGhsVOK4JI9tvURE7WACacHC\nQoDxQ71hcfeGetGtai5xQkTUDiaQezg72iC8v5v6+9O/F6JAxq4sIqJ7MYG0YWigK1ydbAEAjUol\n/nP6Ou5U1es3KCIiA8ME0gah0AKPP9IHtuLmdbKO/JqDBrlCz5EREbXv/fffx5///GeNsdzcXAQG\nBuLKlSud/nxmvR/I/djbivDYyD6IT8pCY6MSJbdr8OPZXEwa0Ud9j4SITF/K1WKcvSxFg7zr54ZZ\nWVogYoA7QgNdtTp/2rRpiIuLw+XLlzFgwAAAwMGDBxEUFIT+/ft3eny8ArkPj552GBvavINhdkE5\njkvyuNQJkRm5kCHTS/IAgAZ5Iy5kaN/IM2DAAAQGBuLgwYPqsYMHD2LatGm6CI8J5EEG+jpjSEDz\nir3pN24hKaWASYTITIT0c9HbbqVWlporhmtj+vTp+P7779HY2IiUlBQUFBRgypQpOomPJSwtRA7x\nRINcgcs5TfuFpGWXwEpogUeCPSAQsJxFZMpCA121LiEZgilTpiAmJgZnzpzB0aNHMWbMGDg7O+vk\nuXgFogWBQIBxYT4I8HFSj6VkFCMpOZ8TDYnIoDg7O2PMmDE4evQoEhMTdVa+AphAtGZhIcCfInrB\n18tRPZZ2rRTHzt7gwotEZFCmT5+OAwcOoK6uDuPGjdPZ8zCBPAShhQCTRvRBv17NVyKZebdx+Jcc\n1DewxZeIDMO4ceMgFovxxBNPQCQS6ex5mEAektBCgIkRvRDs37wJVW5RBb75KYuTDYnIIFRWVqKq\nqgrTp0/X6fMwgXSAQCDA6BAvRAx0V4+VltdgX2IGCkuq9BgZEZmzsrIyJCQkYNWqVRg0aBAGDhyo\n0+djAukggUCAiAHuiArvpZ5YWFMnx7dJWbhyt1uLiKgryeVyvPnmm7hx4wbef/99nT8f23j/oP59\ne8DRXoQjv15Hbb0cikYlEiW5kN6qwugQL1gKmaOJqGu4uLhAIpF02fPx3a0TeLrYY1ZUAJwdxOqx\nS9dKcYD3RYjIhDGBdBJHe2vMjArQmCtSXFaNvT9eRXb+bT1GRkSkG0wgncjKUohHh/fC6BAvWNyd\noV5Xr8APp68jKTkfcs4XISITwgTSyQQCAYYEuGDaOH90s23uv/49uwT7EjO5zzoRmQwmEB3x6GmH\nv07sB78WM9dLy2vw7x8zkJoh42KMRGT0mEB0SCyyxOSRfTA21FvdjaVoVOLn1AIc/PkaKqt5g52I\njBcTiI4JBAIM9u+J2X/qB5fuNurxvKIKfHX0KtJv3OLVCBEZJSaQLtLDQYyZEwIQFuiqXgK+rkGB\nH8/m4siv11Fd26DnCImIHg4TSBcSCi3wSLAnpo3zg4Nd8w32nJvl2JNwFVd5NUJERqTLE4hUKsXS\npUsRERGB8PBwvPzyyygqKlIfP3XqFKZOnYrg4GBMmTIFSUlJGo8vLS3FSy+9hPDwcIwcORIxMTGQ\ny+Vd/Wv8IZ497fH0o4EY7Ne8IGNtvRzHzubiyC85qKzh1QgRGb4uTSBKpRLPP/887ty5g7i4OOze\nvRsymQyLFy8GAGRlZWHx4sWYPHky4uPjERUVhejoaGRmZqp/xpIlS1BSUoLdu3dj3bp1OHDgALZs\n2dKVv0ansLIUYmyYN6aOuedqpPAOvkpIx6VrpbwaISKD1qUJpKSkBH5+fnjvvfcQFBSEoKAgzJ8/\nH5cuXUJ5eTni4uIQEhKCxYsXw8/PD8uWLUNoaCji4uIAACkpKTh//jzWrVuHoKAgjB07Fq+99hp2\n7dqF+nrj7GjyceuGpyZqXo3UNSjw0/k8fHcyG+WVdXqMjoiofV2aQFxcXLBx40Z4e3sDaCpn7d27\nF4MHD4ajoyMkEgkiIiI0HjN8+HD14mASiQReXl7w8fFRH4+IiEBVVRWuXLnSdb9IJxNZNV2NTBvn\nj+721urx/OJKfHX0KpLTi7l1LhEZHL3dRH/xxRcxduxYpKam4r333gPQlFDc3Nw0znN1dYVUKgUA\nFBUVwdXVtdVxACgsLOyCqHXLy8Uef50YiNAWnVpyRSN+/f0m9iVmoPhWtZ4jJCJqprcE8tJLL2Hf\nvn0ICwvDggULUFRUhNra2lbbL4pEItTVNZVxampqYG1trXHcysoKAoFAfY6xs7K0wKhgT8yaEKAx\nb0R2uwb7jmfi5wsFaJBz+1wi0j+9JZDAwEAEBwdj48aNaGxsRHx8PKytrdHQoNmBVF9fDxubpjdS\nsVjc6l5HQ0MDlEolbG1tuyz2ruDawxYzo/rhkcGe6lnsSqUSqZkyfPmfdOTcLNdzhERk7rr8Jvrh\nw4c1xmxsbODj44OioiJ4eHiguLhY43hxcbG6rOXu7g6ZTNbqOIBWpS9TILQQICzIFU8/Gggft27q\n8cqaBhz+JQc//JrD5VCISG+6NIHcvHkTy5cvx++//64eq6ioQE5ODvz9/TF06FCcO3dO4zFnzpxB\neHg4AGDo0KHIy8vTuN9x5swZ2NnZISgoqGt+CT1wtLfGX0b7YmJEL9hYN28imV1Qji8T0pGaIeNN\ndiLqcl2aQAYNGoTw8HC89dZbuHjxIi5fvoxly5ahR48eePLJJzF37lxIJBJs3rwZ2dnZ2LRpE1JT\nUzFv3jwAQGhoKEJCQvDyyy/j0qVLSEpKQkxMDBYsWNDq3ompEQgECOzdA3MmBaF/nx7q8QZ5I35O\nLcC+47zJTkRdq0sTiIWFBbZs2YL+/fvjhRdewNy5c2FnZ4fdu3fDzs4OgYGBiI2NRUJCAp588kkc\nP34c27Ztg5+fH4CmN9HY2Fg4Oztjzpw5WLVqFWbNmoXo6Oiu/DX0SmxtiahhvTB9nD+cujVvoSsr\na7rJfjIlH3UNvMlORLonUJrBdOf8/HxERUUhMTFRPQfFFCgUjUjJkEFypUhjt0NbsRUih3giwKe7\nuh2YiOhhPei9k4spGjGh0ALh/d3w9KOB6NXiJnt1bQOOnrmBgz9fQ1lFrR4jJCJTxgRiAhztrTFl\ntC8mjegNO7GVejyvqAJfH72KM2mF3I+diDodE4iJEAgECPBxwpzJQRgS4KIuXSkalTh3pQh7EtJx\no/COnqMkIlPCBGJiRFZCjA7xwuyofnDr0Ty58k5VPQ6dusa5I0TUaZhATJSLkw1mTgjA+KE+sBYJ\n1eOquSPJV4uh4NwRIvoDmEBMmEAgwEBf5zbnjvx68Sb+fewqCmSVeoyQiIwZE4gZsBVbqeeOODs0\nzx0pvVOL+BNZOHbmBvdkJ6KHxgRiRjxd7DF7YiBGBXvCyrL5P/3V3DLs/k86LmZxSRQi0h4TiJkR\nWggQGuiKOZP7I8Cnu3q8vkGBkykF2JeYAWlplR4jJCJjwQRipuxtrDBpRB9MHeOH7t2a91iR3a7B\n/uOZOC7JZVmLiO6LCcTM+bh1w9MTAzFikId63xEAuJxzC18mpCMtu4RlLSJqExMIqZdEeWZSEPp6\nOqrH6+oVOJGcj/3HM1HElX6J6B5MIKTmYCfCn0f1xRORvnCwa14ev7isGvuPZ+LE+TzU1sn1GCER\nGRLLB59C5qaPhwO8XYOQnF6M8+lFUDQqoVQqkXatFFn55Xgk2AP9+/TgSr9EZo5XINQmS6EFIga6\n45lJQejt7qAer62X47gkD9/8lIXiMpa1iMwZEwjdl6O9NZ6I7IvHH+mrUdaSllZhX2ImkpLzUVvP\nshaROdK6hJWbm4szZ84gPz8flZWVcHJygoeHByIjI+Hm5qbLGEnPBAIBfL0c4ePWDefTi5Bydx0t\npVKJ37NLkJV/G48M9kRQHyeWtYjMyAMTyI8//ojPPvsMaWlpUCqVcHBwgI2NDe7cuYOamhoIBAIE\nBwfjhRdewIQJE7oiZtITK0sLjBjkgcDeTvg5pQC5RRUAgJo6ORIlubicU4oxod5wcbLRc6RE1BXa\nTSAFBQV44403kJ2djUcffRTLly/H4MGDYW9vrz7nzp07OH/+PE6ePInXX38d/v7+2LBhA3x8fLok\neNIPp25iTBnti+yCcpy6UIDKmqYJh4WlVfh3YgYG+zkjYqA7xCL2aBCZsnb3RJ8wYQKee+45zJ49\nG1ZWVm2doqG2thZff/014uLicPz48U4P9I8w1T3RDUGDXAHJlSKkZGiuo2VjbYlRQzwR2ItlLSJj\n9aD3znY/In777bdwcHBo73ArYrEY8+fPx7Rp0zoWKRklK0shRg72RFCfHjiZUoC8FmWtH8/m4vK1\nprJWz+4saxGZmna7sB4mebTk6Oj44JPI5Dh1E+Mvo30xeUQf2Ns0X7HeLKnCv3/MwM8XClDXoNBj\nhETU2bQqUtfX12PPnj1ISUlBRUVFq+MCgQA7d+7s9ODIuAgEAvj7dEdvj244d7kIFzJkaFQq0ahU\nIjVThsy823gk2INlLSIToVUCeeedd7B//34EBASge/fuD34AmTUrSyEeCW4ua+UXN33oqK5tuFvW\nuoWxYV5wdmRZi8iYaZVAjh07hqVLl+LFF1/UdTxkQno4iDF1jC+y8m/jl9Sb6m6tmyWV2HssA4P9\neyJioDusrYQP+ElEZIi0SiACgQAhISG6joVMkEAgQICPE3q7O+DclSKktlHWGhXsgX4saxEZHa2W\nMpk2bRr279+PxsZGXcdDJkpkJcSoYE889WggvF2b5xJV1zbg2NlcxJ/IRml5jR4jJKKHpdUVyEsv\nvYRp06Zh0qRJGDhwIGxsNGvXAoEA//znP3USIJmWprKWHzLzmspaVbWty1rDB7pDxLIWkcHTKoF8\n+OGHyMnJQbdu3XD58uVWx1l6oIchEAjQr5cT+ng44NzlIqRmsqxFZIy0SiDffvst/va3v2H58uX8\nH5o6jchKiFFDmhZhPJlSgAJZJYDmstYldmsRGTSt7oEIhUKMGjWKyYN0wtnRBk+O9cOjw3vDTtxy\nEmJTWetUagHqOQmRyOBolUCmTJmC/fv36zoWMmOqstacyUEI7ecKi7sfVhqVSlzIkOHL/6QjI7cM\n7SzdRkR6oFUJy9nZGfHx8Zg4cSIGDx4MOzs7jeMCgQDvvPOOTgIk89JeWauqtgFHz9zApWulGBPK\nshaRIdAqgezbtw+Ojo5QKBS4cOFCq+MsbVFnU5W17u3WKpA1lbWCA3oiYgC7tYj0SasEYmjLs5N5\naNmtdfayFBczS9TdWhcyZMjMvY1RQzwR4NOdH2KI9KDdeyB5eXkd+oEPelxJSQlef/11REZGIjw8\nHM899xwyMjLUx0+dOoWpU6ciODgYU6ZMQVJSksbjS0tL8dJLLyE8PBwjR45ETEwM5HLuyW3KRFZC\nRA7xwl8n9oOXS/MkRFVZ69skTkIk0od2E8i8efPw0Ucf4fbt21r9oOLiYqxbtw7z5s1r95zGxkb8\n/e9/x/Xr1/Hpp5/i66+/hr29PebPn4+ysjJkZWVh8eLFmDx5MuLj4xEVFYXo6GhkZmaqf8aSJUtQ\nUlKC3bt3Y926dThw4AC2bNnyEL8yGStVWWtiRC/YtujWUpW1fkm9yW4toi7UbgI5cOAAbt68idGj\nR2PRokWIj49HVlYWamtrAQCVlZXIysrC3r17ER0djQkTJkAqld63Wys9PR0pKSn45z//ieDgYPj7\n+yMmJgbV1dVISkpCXFwcQkJCsHjxYvj5+WHZsmUIDQ1FXFwcACAlJQXnz5/HunXrEBQUhLFjx+K1\n117Drl27UF9f38l/GjJEAoEAgb17YO7kIIT0c9Ho1krJKMaeBHZrEXWVdu+BdO/eHR999BEuXryI\nHTt2YPXq1VAoWn+6s7a2xpgxY7Bnzx4EBwff98k8PDzw2WefoW/fvuoxVe26vLwcEokEjz32mMZj\nhg8fjsOHDwMAJBIJvLy8NPZcj4iIQFVVFa5cuYIhQ4Zo8SuTKVCVtfrfXTJe1a1VWcNuLaKu8sCb\n6MHBwdi8eTOqq6shkUiQl5eHyspKODk5wdPTE+Hh4RCLxVo9mZOTE8aNG6cxtmvXLtTW1iIyMhKb\nNm2Cm5ubxnFXV1dIpVIAQFFREVxdXVsdB4DCwkImEDPUslvrVOpNVN/TrTUkwAXDBrixW4tIB7Tq\nwgIAW1tbjBkzplOfPDExER9//DEWLFgAPz8/1NbWQiQSaZwjEolQV1cHAKipqYG1tbXGcSsrKwgE\nAvU5ZH7u162VklGMzLwyPBLMbi2izqbVTHRdOHDgAJYuXYrHHnsMK1asANBUDmtoaNA4r76+Xr36\nr1gsbnWvo6GhAUqlEra2tl0TOBmslt1anj2bu7VUZa3vTrJbi6gz6SWBbN26FStXrsRTTz2FDRs2\nwMKiKQwPDw8UFxdrnFtcXKwua7m7u0Mmk7U6DqBV6YvMl7OjDaaNa92tlV98t1vrIru1iDpDlyeQ\n7du345NPPsHSpUuxevVqjZLC0KFDce7cOY3zz5w5g/DwcPXxvLw8FBYWahy3s7NDUFBQ1/wCZBRU\n3VpzJgdhSMA93VpX2a1F1Bm6NIGkp6dj48aNmDFjBmbPng2ZTKb+qq6uxty5cyGRSLB582ZkZ2dj\n06ZNSE1NVc8tCQ0NRUhICF5++WVcunQJSUlJiImJwYIFC1rdOyECAGsrIUaH3L+sdetOrR4jJDJe\nXZpAjhw5AoVCgW+++QaRkZEaX1988QUCAwMRGxuLhIQEPPnkkzh+/Di2bdsGPz8/AE2fKmNjY+Hs\n7Iw5c+Zg1apVmDVrFqKjo7vy1yAjdL+y1tdHr7KsRdQBAqUW1/BKpRIHDhzAiRMnUF1d3eqyXyAQ\nYOfOnToL8o/Kz89HVFQUEhMT4e3tre9wSM/qGxQa3Voq9jZW7NYiauFB751atfF+/PHH2L59O7y9\nveHu7s7/uciotZyEmJRcgJslmpMQL+eUYkyoN3o4aDe/ichcaZVA4uPjsWDBArz++uu6joeoy6jK\nWhm5ZfjlYqF6EqKqrDWknwuG9eckRKL2aJVAKisrMX78eF3HQtTlVN1afTwdcfaSFL9ntZiEeLUY\nmbllGDXEE/7eLGsR3Uurm+ihoaFITk7WdSxEeqPq1pr9p37w7Nm842ZlTQMSfruB705eY7cW0T20\nugJZtGgRXnnlFcjlcoSFhbW59lVYWFinB0fU1Xp2t8G0cf5tlLUq1GWtiAFusLJkWYtIqwSimocR\nGxsLQHMLW6VSCYFAgCtXruggPKKux7IWkXa0SiCq/TiIzImqrKVaMr5lt1bCbzdwyfUWxoR6sVuL\nzJZWCSQiIkLXcRAZrKayVlvdWhXs1iKzpvVy7tnZ2diyZQvOnj2LiooKODk5ITw8HC+++CL8/f11\nGSOR3t1b1rqYVQIly1pk5rRKIFevXsXTTz8NGxsbREVFwdnZGTKZDD/99BN++uknfP311wgMDNR1\nrER6p1nWysfNkioALGuRedIqgXz44Yfw9fVFXFycxr4b1dXVmD9/Pj755BNs3bpVZ0ESGRpVt9bV\n3DL82kZZK6Rf006I7NYiU6bVPBCJRIJFixa12rTJ1tYWCxcuhEQi0UlwRIZMIBAgqMWS8YIWS8Yn\nXy3Gl/9JR2Yel4wn06VVAlHtCNgWgUAAhYKrmJL5Ui8Zz0mIZGa0SiAhISHYvn17q33Ha2trsWPH\nDoSGhuokOCJjoipr/anVkvFNZa1fL95Eg5wftsh0aHUP5JVXXsHMmTMRFRWFCRMmoGfPnigpKcHx\n48dRVVWFL7/8UtdxEhkFVVmrr6cjzqZJcTG7uVsr+WoxMtitRSZEqwTi5+eHr7/+Gv/zP/+DxMRE\nlJeXw8HBAcOGDUN0dDT69eun6ziJjIq1lRCjQ73Qv2/73VpjQ73gxG4tMmJazwMJDAzE5s2bdRkL\nkclp2a31S+pN1NTJATSVtb46dhUhAezWIuPVbgI5dOgQRo8eje7du+PQoUMP/EFTpkzp1MCITIWq\nrNXHwwHnLhU1l7Uam8takUO84OftyLIWGZV2E8iKFSvw73//G927d8eKFSvu+0MEAgETCNEDiEWW\n7Za1/vPbdfi4dcOYEJa1yHi0m0ASExPh4uKi/jcRdY72ylp5RSxrkXFpt43Xy8sLIpEIAHDu3DnY\n2trCy8ur1ZdIJEJCQkKXBUxkClpOQgz279k8CbGxeRJiVt5tTkIkg6bVPJCVK1ciLy+vzWNXrlzB\nxo0bOzUoInMhFlliTKg3/vqnfvBw1pyE+J/fruPgz9dQxkmIZKDaLWG98MILyMrKAtC0aVR0dLT6\niqSl0tJS9OrVS3cREpmBnt1tMH28P67eKMMvF1nWIuPQbgJZvHgx9u/fDwDYv38/Bg8ejB49emic\nY2FhAQcHB0ybNk23URKZAYFAgKA+PdDH06FpJ8TsUnZrkUFrN4GEhIQgJCQEAKBQKPDiiy/Cx8en\nywIjMleqslb/Ps44mZKPwlJ2a5Fh0uoeyAcffMDkQdTFXJyaylp/GtYLNtbNn/VUZS2urUX61u4V\nyKBBg7Bnzx4EBwdj4MCBD7xkTktL6/TgiMwdy1pkyNpNIIsWLYKbm5v633xxEukPy1pkiNpNIH//\n+9/V/16yZEmXBENE96cqa7XXrRXazwXh/dmtRV1D68UU8/LyUF9fDz8/P1RUVGDTpk2QSqWYPHky\nnnjiCV3GSEQt3K+sdT69GFdvlCEyxAt+XixrkW5pdRM9KSkJjz32mLqtd82aNfjqq69QUFCAFStW\nqMeJqOuoylqzo9qYhHj67iTECk5CJN3RKoFs3boVkZGRiI6Oxp07d3Ds2DE8//zziI+Px/PPP4//\n+7//03WcRNSO+3ZrHb2K07+zW4t0Q6sEkp6ejnnz5sHe3h4nT56EQqHApEmTAACjRo3CjRs3dBok\nEd2fqqzV1tpa59Pvrq2Vz7W1qHNplUCsra2hUDR9gjl16hScnZ0RFBQEACgpKYGDg4PuIiQirbGs\nRV1JqwQSFhaGnTt34vDhw0hISMCjjz4KoGnuR2xsLIYOHarTIIno4ajKWlHh7ZW1ClnWoj9MqwSy\natUqSKVSvPLKK/Dy8sLixYsBNC24KJfL8eqrr+o0SCJ6eAKBAP37NpW1BvvdW9YqYlmL/jCt2nh9\nfHxw5MgRlJaWomfPnurxrVu3on///rCysurQk69ZswYKhQLvv/++euzUqVOIiYlBTk4OevfujVdf\nfRVjx45VHy8tLcU777yDX375BVZWVpg+fTpefvllWFpq3ZFMZFbEIkuMDfPGgL5tTEI8fR293Lph\ndKgXnLpxEiI9HK2uQICmTzO3b9/Gnj178K9//Qv79u2DnZ1dh5KHUqnEpk2bsHfvXo3xrKwsLF68\nGJMnT0Z8fDyioqIQHR2NzMxM9TlLlixBSUkJdu/ejXXr1uHAgQPYsmXLQ8dAZG7aK2vlsqxFHaTV\nx/bGxkasWbMG33zzjcblrkAgwNSpU/HBBx9oPWEpLy8Pq1atQmZmJjw9PTWOxcXFISQkRF0iW7Zs\nGc6fP4+4uDi8++67SElJwfnz5/Hjjz/Cx8cHQUFBeO211/Duu++2u18JETVTlbX6erU1CbEIV2/c\n4iRE0ppWVyD/+te/8O233+KVV15BUlISLl26hBMnTmD58uU4fPgwduzYofUTJicnw8PDA4cOHYK3\nt7fGMYlEgoiICI2x4cOHQyKRqI97eXlprAwcERGBqqoqXLlyResYiMxdy24td3ZrUQdplUD279+P\nRYsWYeHChXBzc4NQKIS7uzv+9re/4YUXXniomehTp07Fhg0b4OLi0uqYVCpVL+Co4urqCqlUCgAo\nKiqCq6trq+MAUFhYqHUMRNTExckGM9itRR2kVQKRyWTttuqGhYV12pt3bW1tqzKUSCRCXV0dAKCm\npgbW1tYax62srCAQCNTnENHD0aZbK5vdWtQGrRKIj48PUlJS2jyWkpLS5tVER1hbW6OhoUFjrL6+\nHjY2NgAAsViM+vp6jeMNDQ1QKpWwtbXtlBiIzJWqW6utstYPp6/jEMtadA+tEsjMmTOxbds2fPHF\nFyguLkZjYyOKi4vx+eef47PPPsP06dM7JRgPDw8UFxdrjBUXF6vLWu7u7pDJZK2OA2hV+iKijmmv\nrMVuLbqXVl1Yzz77LK5cuYJ169Zh/fr16nGlUom//OUv6q6pP2ro0KE4d+6cxtiZM2cQHh6uPv7h\nhx+isLAQHh4e6uN2dnbqpVWI6I9jtxZpQ6sEIhQKsX79eixcuBASiQTl5eVwcHDAsGHDEBAQ0GnB\nzJ07FzNmzMDmzZvx5z//Gd9//z1SU1Oxdu1aAEBoaChCQkLw8ssvY/Xq1SgpKUFMTAwWLFjAFl4i\nHWi5E2KH8WUAAAASmUlEQVRSSj6knIRILTwwgZSUlODmzZvo1asXAgICOjVh3CswMBCxsbGIiYnB\n9u3b4evri23btsHPzw9A06ei2NhYrF27FnPmzIGdnR1mzZqF6OhoncVERM1lrfTrZfj19+adEFVl\nrdB+rgjv78qdEM2MQNlOa0V9fT1WrlyJH374Qd198dhjj+Ef//gHHB0duzTIPyo/Px9RUVFITExs\nNfeEiB5Obb0cZ9KkSLtWqtGZZW9jhdEhXvBlWctkPOi9s90rkE2bNuGHH37AjBkzMGDAAOTk5GDv\n3r1obGzEJ598otOgichwqbq1+vftgZMpBRplrR9OX0cv924YE+KN7t2s7/+DyOi1m0COHj2K6Oho\njfJQYGAg/vGPf6Curq7VfAwiMi+uTraYMd4fV67fwunfC5vLWtIKfHU0HSEsa5m8dtt4pVJpq2VF\nxo4dC7lcjvz8fJ0HRkSGTyAQYEBf51aTEBV3u7X2JFzlJEQT1m4CaWhoaHWV4eTkBACc9U1EGlRl\nrVlRARqTECuq65smIZ66htsVfN8wNVov594SP00QUVtUZa0J4T6akxDvlrU4CdG0dCiBsMOCiNrD\nspb5uO88kPfeew/29vbq71X/wd9++23Y2TVfpgoEAuzcuVNHIRKRMVJ3a/XpgaSUfBTdqgbQXNZi\nt5bxa/cKZNiwYerFDVVfcrkcw4YNg0gk0hi/d4FDIiIV1x62mDkhgGUtE9TuFciuXbu6Mg4iMmGq\nspavpyPOXGqehKgqa2XkliFyiCcnIRqZDt0DISLqCLE1u7VMCRMIEXW5B3Vr/ZZWiAZ5ox4jJG0w\ngRCRXqi7tSYFYdA93VqSK0XYk8CdEA0dEwgR6ZXY2hLjwrwxa0IA3Ho07yzKspbhYwIhIoPwoG4t\nlrUMDxMIERmMB5W1vjqajmsF5SxrGQgmECIyOO2Vte5U1ePIrzn4/lQOy1oGgAmEiAxWy7KWWNRc\n1rohvcOylgFgAiEig6Yqa82dzLKWoWECISKjwLKW4WECISKjwrKW4WACISKjo1HW8nVus6yVc5Nl\nLV1jAiEioyW2tsS4oT5tlrUO/8Kylq4xgRCR0VOVtcYPZVmrKzGBEJFJEAgEGOh7/7IWu7U6FxMI\nEZmU+5W12K3VuZhAiMgkPaisdYZlrT+MCYSITNb9ylrn2K31hzGBEJHJY7eWbjCBEJHZYFmrczGB\nEJFZYVmr8zCBEJFZ0qasVV7Jstb9MIEQkVm7X1lrT0I6zl6SQq5gWastTCBEZPbuV9Y6e1mKPQks\na7WFCYSI6C6WtR4OEwgR0T1Y1tIOEwgRURtY1nowo0wgCoUCH330ESIjIxEaGoqlS5eipKRE32ER\nkQlSlbVmTgiAq1PrstbhX8y3rGWUCWTLli2Ij4/H+vXrsXv3bkilUixZskTfYRGRCXNrp6x1vdB8\ny1pGl0Dq6+sRFxeH5cuXY9SoURg4cCA+/vhjJCcnIzk5Wd/hEZEJs7BoLmsNZFnL+BJIeno6qqqq\nEBERoR7z9vaGl5cXJBKJHiMjInMhtrbE+LtlLXPu1jK6BCKVSgEAbm5uGuOurq7qY0REXcGthy1m\njDffbi2jSyA1NTWwsLCAlZWVxrhIJEJdnelnfCIyLNqWtUyR0SUQsViMxsZGyOVyjfH6+nrY2Njo\nKSoiMncty1ptdWt9f+qayZW1jC6BeHh4AABkMpnGeHFxcauyFhFRVzOnbi2jSyBBQUGws7PD2bNn\n1WP5+fkoKCjAsGHD9BgZEVETVVlrjomXtSwffIphEYlEeOaZZ7BhwwY4OTnB2dkZb7/9NiIiIhAS\nEqLv8IiI1GzulrUG9HVGUnI+isuqATSXtfp6OCAyxAuO9tZ6jrRjjC6BAMCyZcsgl8uxYsUKyOVy\njB49GmvWrNF3WEREbVKVta5cv4XTvxeitr7pHm5O4R3kFlVgaJAbwoJcYSk0rqKQUSYQS0tLvPHG\nG3jjjTf0HQoRkVZUZS0/L0ecTivE5ZxbUCqV6rJW+o1bGB3ihb6ejvoOVWvGle6IiIzcg7q1DhtR\ntxYTCBGRHqjKWuPCvDW6tXJU3VqXDb9biwmEiEhPLCwEGOTXs+1urUuG363FBEJEpGc2RlrWYgIh\nIjIQ7U1CNNSyFhMIEZEBaTkJcUBfwy5rMYEQERkgG2tLTAj3wYzx/gZb1mICISIyYO7OdupuLWuR\nUD1uCGUtJhAiIgOn6taaO7m/QXVrMYEQERkJQ+vWYgIhIjIyLSch6rOsxQRCRGSEWpa1BvR1Vo+3\nLGtdL7yj2xh0+tOJiEinVN1abZW1vj91TadlLSYQIiITcL9ura+OXtVJWYsJhIjIRLRX1pIrGnVS\n1mICISIyMS3LWi5ONupxdVnrl5xOKWsxgRARmSh3ZzvMmtCvdVnrZnmnlLWYQIiITJguy1pMIERE\nZuBBZa3jklwolcqH+plMIEREZkRV1hp7T1nrcs4t3H7I+yKWDz6FiIhMiYWFAIP9esLPyxG/pRXi\n6o0y9Oxug262oof6OUwgRERmylZshQnhvTAuzAdAU2J5GEwgRERm7mETh4pZJBCFQgEAkEqleo6E\niMh4qN4zVe+h9zKLBCKTyQAAc+bM0XMkRETGRyaToXfv3q3GBcqH7dsyQrW1tUhLS4OLiwuEQuGD\nH0BERFAoFJDJZBg0aBDEYnGr42aRQIiIqPNxHggREXUIEwgREXUIEwgREXUIEwgREXUIEwgREXWI\n2SYQhUKBjz76CJGRkQgNDcXSpUtRUlKi77AMRlZWFgIDA1t9SSQSfYemd2vWrMGbb76pMXbq1ClM\nnToVwcHBmDJlCpKSkvQUnX619beZOXNmq9fRveeYspKSErz++uuIjIxEeHg4nnvuOWRkZKiPG/Vr\nR2mmNm7cqBw1apTy1KlTyrS0NOWsWbOUTz31lL7DMhiHDx9WDh8+XFlcXKzxVV9fr+/Q9KaxsVH5\nySefKPv166dctWqVejwzM1M5aNAg5aeffqrMyspSbty4UTlw4EBlRkaGHqPtWu39bRobG5VDhgxR\nHjx4UON1VFFRocdou45CoVD+9a9/Vc6ePVuZmpqqzMzMVC5dulQ5cuRI5a1bt4z+tWMWM9HvVV9f\nj7i4OLz11lsYNWoUAODjjz9GVFQUkpOTERYWpucI9S8jIwP+/v5wcXHRdygGIS8vD6tWrUJmZiY8\nPT01jsXFxSEkJASLFy8GACxbtgznz59HXFwc3n33XX2E26Xu97fJy8tDTU0NQkJCzPK1lJ6ejpSU\nFBw5cgR+fn4AgJiYGERERCApKQnJyclG/doxyxJWeno6qqqqEBERoR7z9vaGl5cXSzR3ZWZmwtfX\nV99hGIzk5GR4eHjg0KFD8Pb21jgmkUg0XksAMHz4cLN5Ld3vb5ORkQGxWAwvLy89RadfHh4e+Oyz\nz9C3b1/1mEDQtHBheXm50b92zPIKRLVAmJubm8a4q6srF1y8KzMzE3V1dZg9ezYKCgoQEBCA5cuX\nIzg4WN+h6cXUqVMxderUNo9JpVKzfi3d72+TmZmJbt264dVXX8XZs2fh5OSE6dOnY968ebCwMP3P\nr05OThg3bpzG2K5du1BbW4vIyEhs2rTJqF87pv9fsA01NTWwsLCAlZWVxrhIJEJd3cPtyGWKamtr\nkZeXh8rKSrz22mvYunUrXF1dMXfuXGRnZ+s7PINTW1sLkUhzIx6+lppkZWWhuroakZGR2LlzJ555\n5hls3rwZsbGx+g5NLxITE/Hxxx9jwYIF8PPzM/rXjllegYjFYjQ2NkIul8PSsvlPUF9fDxsbm/s8\n0jyIxWKcO3cOIpFI/eJet24dLl26hD179mD16tV6jtCwWFtbo6GhQWOMr6Um69evR3V1NRwcHAAA\ngYGBqKiowLZt27BkyRJ1OcccHDhwAKtXr8bjjz+OFStWADD+145ZXoF4eHgAaF7mXaW4uLjV5aS5\nsre31/hkZGFhAX9/fxQWFuoxKsPk4eGB4uJijTG+lppYWlqqk4dKYGAgqqqqUFFRoaeout7WrVux\ncuVKPPXUU9iwYYO6fGfsrx2zTCBBQUGws7PD2bNn1WP5+fkoKCjAsGHD9BiZYUhLS0NYWBjS0tLU\nYwqFAunp6QgICNBjZIZp6NChOHfunMbYmTNnEB4erqeIDMfs2bPx3nvvaYz9/vvvcHV1bZVYTNX2\n7dvxySefYOnSpVi9erXGVZexv3bMMoGIRCI888wz2LBhA06ePIlLly5h+fLliIiIQEhIiL7D07ug\noCB4eXlhzZo1SE1NRWZmJlauXImysjL813/9l77DMzhz586FRCLB5s2bkZ2djU2bNiE1NRXz5s3T\nd2h6N3HiROzduxfffvstcnNzsW/fPuzYsQNLly7Vd2hdIj09HRs3bsSMGTMwe/ZsyGQy9Vd1dbXR\nv3bM8h4I0NRvLZfLsWLFCsjlcowePRpr1qzRd1gGwdLSEjt27MCGDRuwaNEi1NTUICwsDLt374az\ns7O+wzM4gYGBiI2NRUxMDLZv3w5fX19s27ZN3fdvzhYuXAhLS0ts3boVN2/ehKenJ1auXIlZs2bp\nO7QuceTIESgUCnzzzTf45ptvNI699NJLePHFF436tcMNpYiIqEPMsoRFRER/HBMIERF1CBMIERF1\nCBMIERF1CBMIERF1CBMIERF1iNnOAyG61xtvvIH4+Pj7nhMREYFdu3bh2WefhVAoxBdffNE1wbXh\n9u3bmD59Oj7//HP07t37gefHxsaipKQEa9eu1X1wZBY4D4TortzcXNy6dUv9/dtvvw2hUIi33npL\nPWZvbw9/f39kZWVBIBDodcLXK6+8Ajc3N7z22mtanV9bW4vJkyfjgw8+wMiRI3UcHZkDXoEQ3dWr\nVy/06tVL/b29vT2EQmGby9v4+/t3ZWitXLx4EQkJCTh58qTWjxGLxZg/fz4++OADHDx4UIfRkbng\nPRCiDnj22Wcxf/589feBgYHYu3cvXn31VYSGhmLEiBGIjY1FZWUlVq5ciaFDh2LUqFGIiYlBy4v+\nsrIyvPXWWxg5ciSCg4Px9NNP4/z58w98/h07duCRRx5Bjx491GNpaWmYN28ehg4ditDQUMyfPx8X\nLlzQeNzjjz+OzMxMnDhx4g//DYiYQIg6yfr16+Hk5IRPP/0U48ePx5YtWzBz5kzY2NggNjYWEydO\nxI4dO3D06FEAQF1dHebPn48TJ05g+fLl2Lx5MxwdHTF//nxcvHix3eepqqrC8ePH8eijj6rHKisr\nsXDhQjg5OWHLli3YuHEjampqsHDhQlRWVqrPc3V1RWhoKA4dOqS7PwSZDZawiDrJwIED8eabbwJo\nWtH4wIEDcHZ2Vi/SOWLECBw6dAgXLlzApEmT8N133+Hq1avYt28fBg8eDAAYM2YMZs6ciY0bN+Lz\nzz9v83kkEgkaGho0thfOyspSr5YcFhYGAPD19cXevXtRVVUFe3t79bmDBg3CkSNHdPI3IPPCKxCi\nTtLyDd3JyQlCoVBjTCAQwNHREXfu3AEAnD59Gm5ubujfvz/kcjnkcjkaGxsxfvx4nDt3DvX19W0+\nT35+PgDA29tbPRYQEIAePXpg0aJFWLNmDY4dO4aePXtixYoVrTYn8vLygkwma/fnE2mLVyBEncTO\nzq7VmK2tbbvn3759G1KpFAMHDmzzeFlZWZs706l28mu57amdnR2+/PJLbN26FT/88AP27t0LsViM\nqVOn4q233tLYXVIVU2VlpcY9FKKHxQRCpCfdunWDn58f1q9f3+ZxJyen+45XVFRo7Orn6+uLmJgY\nKBQKXLx4Ed999x2++uor9OnTB//93/+tPq+8vBwWFhZwdHTsxN+GzBFLWER6MmzYMNy8eROurq4Y\nPHiw+isxMRG7du2ClZVVm4/z9PQEAEilUvXYsWPHMGLECMhkMgiFQoSGhmLt2rVwcHBotY+9VCqF\nq6srhEKh7n45MgtMIER6Mn36dLi5uWHBggX47rvv8Ntvv2HdunXYunUrfHx8NPbObik8PBxisVij\n3TcsLAxKpRLR0dH48ccfcfr0aaxZswaVlZUa3VoAkJycjMjISJ3+bmQemECI9ER132LIkCFYt24d\nnn/+efz8889YvXo1lixZ0u7jbGxsMGbMGI1JhM7Ozti5cye6deuGN998Ey+88AIuXbqELVu2YNiw\nYerzZDIZ0tPTWyUVoo7gUiZERujixYt4+umncfz48TZvtLdn69atSEhIQHx8fLtXOETa4hUIkREK\nDg5GVFQU/vd//1frx1RXV2PPnj1Yvnw5kwd1CiYQIiO1du1aJCQk4MaNG1qdv3PnTowfPx5jxozR\ncWRkLljCIiKiDuEVCBERdQgTCBERdQgTCBERdQgTCBERdQgTCBERdcj/AwobLu83AIMOAAAAAElF\nTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "condition.set(v_init = -80 * m / s)\n", + "system = make_system(condition)\n", + "run_odeint(system, slope_func)\n", + "plot_position(system.results)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nk/w/z6EMxJvxCDgAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_velocity(system.results)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Dropping quarters" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Suppose we drop a quarter from the Empire State Building and find that its flight time is 19.1 seconds. We can use this measurement to estimate the coefficient of drag.\n", + "\n", + "Here's a `Condition` object with the relevant parameters from\n", + "https://en.wikipedia.org/wiki/Quarter_(United_States_coin)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "condition = Condition(height = 381 * m,\n", + " v_init = 0 * m / s,\n", + " g = 9.8 * m/s**2,\n", + " mass = 5.67e-3 * kg,\n", + " diameter = 24.26e-3 * m,\n", + " rho = 1.2 * kg/m**3,\n", + " duration = 19.1 * s)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And here's a modified version of `make_system`" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def make_system(condition):\n", + " \"\"\"Makes a System object for the given conditions.\n", + " \n", + " condition: Condition with height, v_init, g, mass, diameter, \n", + " rho, C_d, and duration\n", + " \n", + " returns: System with init, g, mass, rho, C_d, area, and ts\n", + " \"\"\"\n", + " unpack(condition)\n", + " \n", + " init = State(y=height, v=v_init)\n", + " area = np.pi * (diameter/2)**2\n", + " ts = linspace(0, duration, 101)\n", + " \n", + " return System(init=init, g=g, mass=mass, rho=rho,\n", + " C_d=C_d, area=area, ts=ts)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can run the simulation with an initial guess of `C_d=0.4`." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nr2LpAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "condition.set(C_d=0.4)\n", + "system = make_system(condition)\n", + "run_odeint(system, slope_func)\n", + "plot_position(system.results)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The final height is -11 meters, which means our guess was too low (we need more drag to slow the quarter down)." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(,\n", + " )" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "final_state(system.results)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`height_func` takes a hypothetical value of `C_d` and returns the height after 19.1 seconds." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def height_func(C_d, condition):\n", + " \"\"\"Final height as a function of C_d.\n", + " \n", + " C_d: drag coefficient\n", + " condition: Condition object\n", + " \n", + " returns: height in m\n", + " \"\"\"\n", + " condition.set(C_d=C_d)\n", + " system = make_system(condition)\n", + " run_odeint(system, slope_func)\n", + " y, v = final_state(system.results)\n", + " return y" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we run it with `C_d=0.4`, we get -11 meters again." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "-11.034779626277231 meter" + ], + "text/latex": [ + "$-11.034779626277231 meter$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "height_func(0.4, condition)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can use `fsolve` to find the value of `C_d` that makes the final height 0." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0.42587017])" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solution = fsolve(height_func, 0.4, condition)\n", + "solution" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plugging in the estimated value, we can run the simulation again to get terminal velocity." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(,\n", + " )" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "condition.set(C_d=solution)\n", + "system = make_system(condition)\n", + "run_odeint(system, slope_func)\n", + "final_state(system.results)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this example, the terminal velocity of the quarter is higher than that of the penny, but we should not take this result seriously because the measurements we used are not real; I made them up." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "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.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +}