{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Getting started with Python and the Jupyter Notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Welcome to this tutorial! The jupyter-notebook is an excellent tool that originated from the python language but has since been extended to other languages (it was previously called \"ipython notebook\", you will find it often with this name on the internet). The advantage of notebooks is that they can include text, code, and plots in the same document. \n", "\n", "This makes it an ideal playground for learning python without having to jump between several documents!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Start the notebook interface" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Type the following command in a terminal window:\n", " \n", " $ jupyter-notebook\n", "\n", "This opens a new tab in your default web browser. This is the notebook \"**explorer**\". From this window you can navigate through your folders, open existing notebooks like this one or create new ones (\"New\" button on the upper right panel).\n", "\n", "**Note**: do not close the terminal where you started the notebook. This is where python is \"actually\" running." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## First steps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use the notebook explorer tab to create a new empty notebook. This notebook is called \"Untitled\" for now, but you can change its name in the \"File\" menu. Here you can also save your changes and close it.\n", "\n", "At first sight the notebook looks like a text editor. Below the toolbar you can see a **cell**. The default purpose of a cell is to write code:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = 'Hello'\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can write one or more lines of code in a cell. You can run this code by clicking on the \"Play\" button from the toolbar. However it is much faster to use the keybord shortcut: `[Shift+Enter]`. Once you have executed a cell, a new cell should appear below. You can also insert cells with the \"Insert\" menu. Again, it is much faster to learn the keybord shortcut for this: `[Ctrl+m]` to enter in command mode then press `[a]` for \"above\" or `[b]` for \"below\". \n", "\n", "You can click on a cell or type `[Enter]` to edit it. Create a few empty cells above and below the current one and try to create some variables. You can delete a cell by clicking \"delete\" in the \"edit\" menu, or you can use the shortcut: `[Ctrl+m]` to enter in command mode then press `[d]` two times!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The variables created in one cell can be used (or overwritten) in subsequent cells:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = 'Hello'\n", "print(s)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = s + ' Python!'\n", "# Note that lines starting with # are not executed. These are for comments.\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that I ommited the `print` commmand above (this is OK if you want to print something at the end of the cell only)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic Python syntax " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In python, the **case** is important: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Var = 2\n", "var = 3\n", "print(Var + var)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In python, the **indentation** is important:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "var = 1 \n", " var += 1 # this will raise an IndentationError" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Why is it important? Because Python uses whitespace indentation instead of curly braces or keywords to delimit blocks:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "if True:\n", " print(\"I'm here!\")\n", "else:\n", " print(\"Am I?\")\n", "print(\"Now I'm there\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's much less typing! Most beginners don't like Python because of this, but almost everybody end up agreeing that this is a great idea." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In Python, you can call functions, like for example `abs()`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "abs(-1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you feel like it, you can even make your own functions:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def square(x):\n", " # Be carefull: the indentation!!!\n", " return x**2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And use it afterwards:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "square(4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The \"import\" mechanism in Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some python functions like `print` are always available per default: they are called **built-in functions**. `sorted()` is another example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sorted([2, 4, 1, 5, 3])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However, there are only a few dozens of available [built-in functions](https://docs.python.org/3.4/library/functions.html) in python. Definitely not enough to do serious data-crunching and make of Python a concurrent of Matlab or R. So what?\n", "\n", "Python has a particular mechanism to give access to other functions. This is the **import** mechanism and is one of the greatest strengths of the Python language (just believe me on this one for now)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is called **importing a module**. With this simple command we have just \"imported\" the entire [Numpy](http://www.numpy.org/) library. This means that the numpy functions are now available to us. For example, numpy's [arange()](http://docs.scipy.org/doc/numpy/reference/generated/numpy.arange.html) function can be called like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = numpy.arange(10)\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get an idea of all the new functions available to us, you can write \"`numpy.`\" (\"numpy\" followed by a dot) in a free cell, then type `tab` (`tab` is the **autocompletion** shortcut of ipython, it is very helpful when writing code)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Because writing \"`numpy.function()`\" can be time consuming (especially if one uses numpy often), there is the possibility to give an **alias** to the imported module. The convention for numpy is following: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now the functions can be called like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = np.arange(10)\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variables and arrays" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A **variable** in Python is very similar to a variable in Matlab or in other languages. A variable can be initialised, used and re-initialised:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 10\n", "y = x**2\n", "print(y)\n", "y = 'Hi!'\n", "print(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are several variable types in Python. We are going to need only very few of them:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Numbers: integers and floats" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "i = 12\n", "f = 12.5\n", "print(f - i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Strings:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = 'This is a string.'\n", "s = \"This is also a string.\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Srings can be concatenated:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "answer = '42'\n", "s = 'The answer is: ' + answer\n", "print(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "answer = 42\n", "s = 'The answer is: ' + answer\n", "print(s) # this will raise a TypeError" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numbers can be converted to strings like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = 'Pi is equal to ' + str(np.pi)\n", "print(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or they can be formated at whish:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = 'Pi is equal to {:.2f} (approximately).'.format(np.pi) # the {:.2f} means: print the number with two digits precision\n", "print(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Lists" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A list is simply a sequence of things:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "l = [1, 2, 'Blue', 3.14]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It has a length and can be indexed:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(len(l))\n", "print(l[2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Note: in python the indexes start at zero and not at 1 like in Matlab!!!**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lists are **not** like Matlab arrays:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "l = [1, 2, 'Blue', 3.14] + ['Red', 'Green'] # adding lists together concatenates them\n", "print(l)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For Matlab-like arrays we will need Numpy:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Arrays" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = np.array([1, 2, 3, 4])\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can do element-wise operations on them like in matlab:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(a + 1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(a * 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is possible to index arrays like lists:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a[2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or using for example a range of values:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a[1:3] # the index values from 1 (included) to 3 (excluded) are selected" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a[1:] # the index values from 1 (included) to the end are selected" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Multidimensional arrays" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In science, most of the data is multidimensional. Numpy (like Matlab) has been designed for such data arrays: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b = np.array([[0, 1, 2, 3], [4, 5, 6, 7]])\n", "b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The **shape** of an array is simply its dimensions:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(b.shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The same kind of elementwise arithmetic is possible on multidimensional arrays:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(b + 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And indexing:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b[:, 1:3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Getting help about python variables and functions " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The standard way to get information about python things is to use the built-in function help(). I am not a big fan of it because its output is quite long, but at least it's complete:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = 3\n", "help(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A somewhat more user-friendly solution is to use the ? operator provided by the notebook:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also ask for help about functions. Let's ask what numpy's arange is doing:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.arange?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I paresonnaly dont use these tools often, because most of the time they don't provide examples on how to do things. They are useful mostly if you would like to know how the arguments of a function are named, or what a variable is. Especially in the begining, the best help you can get is with a search machine and espically on the documentation pages of the libraries we are using. For example, I rely mostly on three components:\n", "- [numpy](http://docs.scipy.org/doc/numpy/reference/): this is the base on which any scientific python project is built. \n", "- [matplotlib](http://matplotlib.org/index.html): plotting tools\n", "- [xarray](http://xarray.pydata.org/en/stable/): working with multidimensional data\n", "\n", "It's always useful to have their documentation webpage open on your browser for easy reference." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plotting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The most widely used plotting tool for Python is [Matplotlib](http://matplotlib.org/). Its syntax is directly inspired from Matlab so you should be able to recognise some commands. First, import it:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Don't worry about why we've imported \"matplotlib.pyplot\" and not just \"matplotlib\", this is not important. The command `%matplotlib inline` is specific to the notebook and should always be used for these exercises. It is simply a way to tell the notebook: \"display the plots in the notebook\". \n", "\n", "Now we will plot the function $f(x) = x^2$:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = np.arange(11)\n", "plt.plot(x, x**2)\n", "plt.xlabel('x')\n", "plt.ylabel('f(x)')\n", "plt.title('x square'); # the semicolon (;) is optional. Try to remove it and see what happens" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is possible to save the figure to a file by adding for example `plt.savefig('test.png')` *at the end of the cell*. This will create an image file in the same directory as the notebook." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also make a plot with several lines and a legend, if needed:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = np.linspace(0, 2)\n", "plt.plot(x, x, label='f(x) = x')\n", "plt.plot(x, x**2, label='f(x) = x$^{2}$')\n", "plt.xlabel('x')\n", "plt.ylabel('f(x)')\n", "plt.legend(loc='best');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Formatting your notebook with text, titles and formulas." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The default role of a cell is to run code, but you can tell the notebook to format a cell as \"text\" by clicking on \"Cell $\\rightarrow$ Cell Type $\\rightarrow$ Markdown\". The current cell will now be transformed to a normal text. Try it out in your testing notebook. \n", "\n", "Again, there is a shortcut for this: press `[ctrl+m]` to enter in command mode and then press `[m]`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A text cell can also be a title if you add one or more # at the begining" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A text cell can be formatted using the [Markdown](https://en.wikipedia.org/wiki/Markdown) format. No need to learn too many details about it right now but remember that it is possible to write lists:\n", "- item 1\n", "- item 2\n", "\n", "or formulas:\n", "\n", "$$ E = m c^2$$\n", "\n", "for example. I can also write text in **bold** or *cursive*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# What next?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is an excellent Python tutorial provided by the Software Carpentry:\n", "\n", "http://swcarpentry.github.io/python-novice-inflammation/\n", "\n", "I strongly recommend it." ] } ], "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.5.3" } }, "nbformat": 4, "nbformat_minor": 0 }