{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### 5. Libraries\n", "\n", "#### Libraries\n", "\n", "Remember when we were trying to get a robot to make tea in the first lesson? Now that we know about functions, we can imagine putting all of the actions (putting water in a kettle, boiling it, etc.) into one function, `make_tea`.\n", "\n", "As far as \"things to have a robot do for you\" go, making tea is probably pretty high up on the list. It's a bit wasteful if everyone had to individually write a `make_tea` function. To get around this we can install libraries which allow us to extend functionality.\n", "\n", "Once the library is installed, we can import it into our program with the syntax:\n", "\n", " import module\n", " \n", "Any function in the module can now be used in the following way:\n", "\n", " module.function()\n", " \n", "Furthermore, we can `import as`, which allows us to give nicknames to libraries.\n", "\n", "A very useful library for physics is NumPy, which allows us to operate on arrays of values very efficiently. \n", "\n", "NumPy provides us with a new basic type called array which can be used to represent vectors and matrices. Let's look at an example:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 3. 5. 7.]\n" ] } ], "source": [ "import numpy as np\n", "\n", "vector_1 = np.array([1.0, 2.0, 3.0])\n", "vector_2 = np.array([2.0, 3.0, 4.0])\n", "vector_3 = vector_1 + vector_2\n", "print(vector_3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can access elements in a numpy array in the same way we access an element in a list.\n", "\n", " vector_3[0]\n", " \n", "Is equal to 3.0.\n", "\n", "We can make functions using these as well. For example, we could make a function to calculate the dot product:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "20.0\n" ] } ], "source": [ "def dot(vector_1, vector_2):\n", " total = 0.0\n", " for index, element in enumerate(vector_1):\n", " total += vector_1[index] * vector_2[index]\n", " return total\n", "\n", "print(dot(vector_1, vector_2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We've also introduced a new function here, `enumerate`, which gives us the index and element we're at when using a for loop.\n", "\n", "Now try writing a function for the cross product:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#your cross product" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "NumPy actually provides these functions \"for free\", so instead of writing those, we could have done the following:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "20.0\n", "[-1. 2. -1.]\n" ] } ], "source": [ "import numpy as np\n", "\n", "print(np.dot(vector_1, vector_2))\n", "print(np.cross(vector_1, vector_2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also check which one is faster. There is a built in library called `datetime` that allows us to do this, so we can use it as follows:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Numpy took: 0:00:00\n", "Our function took: 0:00:00\n" ] } ], "source": [ "import numpy as np\n", "import datetime\n", "\n", "t0 = datetime.datetime.now() \n", "# Class method which returns a datetime object giving the current time\n", "np.dot(vector_1, vector_2)\n", "t1 = datetime.datetime.now()\n", "t2 = datetime.datetime.now()\n", "dot(vector_1, vector_2)\n", "t3 = datetime.datetime.now()\n", "print(\"Numpy took:\", str(t1-t0))\n", "print(\"Our function took:\", str(t3-t2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Try this with the cross product as well. Chances are you'll find that your implementation is faster. This is because the NumPy function can be used for different dimensions, and also checks whether the two NumPy arrays are valid. This results in it being slower, but safer." ] } ], "metadata": { "anaconda-cloud": {}, "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.5.1" } }, "nbformat": 4, "nbformat_minor": 0 }