{ "cells": [ { "cell_type": "markdown", "metadata": { "toc": "true" }, "source": [ "# Table of Contents\n", "

1  Introduction to Python
1.1  Installation of a Python distribution:
1.2  Installing packages:
1.3  Spyder
2  First steps
3  Types
4  Control structures
5  Containers
5.1  Lists
5.2  Tuples
5.3  Dictionaries
5.4  String
6  Files
7  Functions
8  Variables and objects
9  Package importation
" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Introduction to Python\n", "\n", "Often there already is an installed version of Python on MacOs and Linux operating systems.\n", "Whatever the case it is advised to always only one version of Python; preferably the one installed\n", "by the package manager.\n", "\n", "There still is the possibility to install a *distribution* coming with the most used packages.\n", "This the recommended method for Windows user.\n", "\n", "## Installation of a Python distribution:\n", "\n", "There are several Python distributions aimed at scientists:\n", "* [Anaconda](https://store.continuum.io/cshop/anaconda/)\n", "* [Canopy](https://www.enthought.com/products/canopy/)\n", "* [Python(x,y)](https://code.google.com/p/pythonxy/)\n", "\n", "Each of these is available for wide range of architectures (32/64 bits, Linux, Windows, Mac OS...).\n", "At the time of writing Anaconda seems to be the simplest to install and offering a very good compatibility multi-platform.\n", "\n", "## Installing packages: \n", "\n", "Each of these distributions comes with a set of scientific modules (numpy, scipy, pandas...) and developer tools (spyder, ipython). Python is an open language, it is possible to install other modules developed by the community or co-worker.\n", "\n", "Several tools for the package management exist. Either the package manager of your system (if Python is installed this way). Or by the manager of your python distribution. For example, to install *vtk* with the Anaconda distribution, a terminal must be opened and run in it:\n", "```bash \n", "conda install vtk\n", "```\n", "\n", "If a desired module is not available by the system/distribution manager, there exist a Python module called *pypi* allowing to install a wider range of modules.\n", "\n", "Those tools connect to on-line repositories and usually manage from the downloading to installation.\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Spyder\n", "\n", "Spyder is graphical user interface (gui) copied from the Matlab interface.\n", "\n", "\n", "\n", "It allows the:\n", "\n", "* Edition and execution of source files\n", "* Exploration of files and variables\n", "* Code profiling\n", "* Display the help\n", "* Management of environment variables\n", "* ..." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# First steps\n", "\n", "* Comments\n", "* Print\n", "* Assignation\n", "* Variables/values\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# Comments start with '#'\n", "# All this is thus ignored\n", "\n", "print(\"World !\") # Parenthesis are a must with Python 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "a = 1\n", "print(a, 'a')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "A variable is a name, chosen by the programmer, used to store a value (numerical, literal, etc).\n", "\n", "A new variable is created only by assigning it a value, i.e by putting the variable name chosen on the left hand side of the ```= ```. This is the assignment operator, which is completely different form the comparison operator ```==``` which would return true if the value on both sides of the operator are equals.\n", "\n", "Python is case sensitive and will return an error if a variable is used before it is initialized:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "print(A)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "slideshow": { "slide_type": "slide" } }, "source": [ "# Types\n", "\n", "Variables themselves are not typed. But the values tied to them are.\n", "\n", "Basic types are:\n", "* Integers\n", "* Reals\n", "* Booleans\n", "\n", "* Complexes... which will not be treated here." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "a = 1 # an integer\n", "print(type(a))\n", "a = 1. # a real\n", "print(type(a))\n", "print(type(1))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "The operations available (or used) depend on the involved types:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "print(1+1)\n", "print(1.+1)\n", "print(1/2)\n", "print(1//2)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Booleans are a subset of the integers. ```True``` is 1 and ```False``` is 0.\n", "To convert any nondescript value to a boolean, the rule is: 0 and ```None``` are ```False```, everything else ```True```." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "a = 1; b = 1.\n", "print(a == b)\n", "print(a is b)\n", "c = -1\n", "print(bool(c))\n", "c = 0.\n", "print(bool(c))\n", "print(True and not (True or False))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Why:\n", "```\n", "a == b\n", "```\n", "is true whereas:\n", "```\n", "a is b\n", "```\n", "returns false?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Control structures\n", "\n", "Python provides a syntax allowing to repeat or conditionally execute a block of instructions.\n", "\n", "The main structures are:\n", "* if\n", "* for\n", "* while\n", "\n", "The text indent (the number of white spaces at the beginning of the line) which defines the scope of the control structure.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "a = 1+0j\n", "if a == 1:\n", " print('a == 1')\n", " if type(a) == type(1):\n", " print('a is an integer')\n", " elif type(a) == type(1.):\n", " print('a is a real')\n", " else:\n", " print('a is neither integer nor real ', type(a))\n", "else:\n", " print('a <> 1')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "for i in [1,2,3.,'totor']:\n", " print(i)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "i = 0\n", "while i < 4:\n", " i = i+1\n", " print(i,end='')\n", " if i%2 :\n", " print(' is odd')\n", " else:\n", " print(' is even')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "**Exercise:**\n", "\n", "Write the multiple of 5 and 7 from 0 to 50\n", "\n", "Hints:\n", " * use ```range(n)``` to generate ```[1,2,...,n-1]```\n", " * ```a%b``` give the left of the integer division of a by b\n", " * use ```or``` as the boolean operator" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "for i in range(51):\n", " if i%5==0 or i%7==0:\n", " print(i)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Containers\n", "\n", "The containers allow to store a collection of values. The containers can be ordered or not.\n", "The fundamental containers are:\n", "* Lists\n", "* Tuples\n", "* Dictionaries\n", "* String\n", "\n", "There is an other subtlety to describe a container: is the container `mutable` or `immutable` which describe if the content of the container can be modified after its creation." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Lists\n", "\n", "* Contain other objects, whatever their types.\n", "* Are ordered.\n", "* Lists are *mutable* object, after the creation elements of the list can be removed/replaced/appended...\n", "* No arithmetic operations, it is not a vector (contrary to numpy array which will be introduced later)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "g = [1.,2,[\"three\",\"half\", 4]] # creation\n", "h = list( range(1,4) )\n", "print(g)\n", "print(h)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "print(g[0]) # Like in C, list index starts at 0\n", "g[1]='two' # lists are mutable\n", "print(g)\n", "print(g[1][0]) # access to the first element of the element number 2 of the list\n", "print(g[-1])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "print(g+g)\n", "print(g*3)\n", "g.append(4)\n", "print(g)\n", "g.extend(h)\n", "h.sort()\n", "print(h)\n", "h.reverse()\n", "print(h)\n", "print(len(h))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Tuples\n", "\n", "The tuples are like but without the possibility to modify them." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "t = (1,2,3) # parenthesis are used for the creation instead of bracket\n", "print(t)\n", "print(t[0]) # but index in the same way" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "t[1]='test' # tuples are immutable" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "print(t+t)\n", "print(t*3)\n", "print(t == [1,2,3])\n", "print(t == (1,2,3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "t.sort()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Dictionaries\n", "\n", "Are mapped array. Instead of accessing the values by integer increasing indices starting at 0, values are indexed by any other immutable value.\n", "\n", "The keys are the elements allowing to index the content of the dictionary and the associated variable are the values.\n", "\n", "In a dictionary, if a key does not exist when assigning it, it is created, otherwise only the value is replaced." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "k = {} # empty dictionary\n", "k['A'] = [0,1,2,'three',['toto']]\n", "k[\"text\"] = 'zen'\n", "k[(0,1)] = 'tuple' \n", "print(k)\n", "k['A'] = [0]\n", "print(k)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "k[[0,1]] = 'list' # returns an error" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# Creation with constructor\n", "k2 = {1:'A',\n", " 2:'B',\n", " 3:'C'}\n", "print(k2)\n", "\n", "# or from a list of tuples (key, value)\n", "\n", "k3 = dict( [('T','Temperature'),\n", " ('P','Power'),\n", " ('H','Humidity')])\n", "print(k3)\n", "\n", "print('T' in k3 ) # T is a key of k3\n", "print('t' in k3 )" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "print(k2[1]) # get the value associated to key 'A'\n", "print(k2.keys()) # get the list of all keys\n", "print(k2.values()) # get the list of all values\n", "print(k2.items()) # get the list of pairs (key,value) in a list of tuples" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## String\n", "\n", "Character and strings are defined with quotes (simple or doubles).\n", "Concatenation is done thanks to the operator ```+```.\n", "\n", "There are a lot of methods manipulating string making it easy to search, replace, etc.\n", "\n", "Strings are used in the same way than the list except that they are immutable." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "a = 'a'+4*'b'\n", "print(a)\n", "b = 'banana'\n", "print(b[2], b[-1], len(b))\n", "print(b.split('a'))\n", "print(b.replace('n','l'))\n", "print(b.capitalize())\n", "print(b.upper())\n", "print('--'.join(['1','2','3','4']))\n", "print('banana'.count('na'))\n", "print(\"Python\".find('on'))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "b[0] = 'l'" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "**Exercise:** \n", "\n", "Create a dictionary which matches for any number from 0 to 25 the corresponding letter.\n", "\n", "Hints: use\n", "* ```from string import ascii_lowercase```\n", "* the function enumerate on ```ascii_lowercase```\n", "* a ```for``` loop" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "from string import ascii_lowercase\n", "d = {}\n", "for n, l in enumerate(ascii_lowercase):\n", " d[n] = l\n", "print(d)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Files\n", "\n", "Files must be opened before being modified and then closed, would it be for reading or writing.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "### Reading a file line by line\n", "f = open('zen.txt','r')\n", "print('Ligne 0: '+ f.readline(), end='')\n", "print('Ligne 1: '+ f.readline(), end='')\n", "print('Ligne 2: '+ f.readline(), end='')\n", "print('Ligne 3: '+ f.readline(), end='')\n", "f.close() # closing the file\n", "# If the file is left open, it will be unavailable for the other programs of the OS" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "\n", "A moore efficient version of the reading of file it to use the statement *with*.\n", "It creates a scope which, whatever the reason, always execute an action before going out of the scope.\n", "Used with the *open* statement, *with* will always close the file at the end of the block." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "with open('zen.txt','r') as f : \n", " s = f.read()\n", " print(s)\n", " # at the end f.__exit__() is called, which close the file" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "f.read()" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "source": [ "The writing of numerical values into strings can be done in several ways. Once this is done, the strings can be written to a file." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "print(\"%d\"%42)\n", "print(\"The variable %s is %2.3f at iteration %d\"%('toto',3.14159,12.)) # positional arguments\n", "print('{0}, {1}, {2}'.format('a', 'b', 'c'))\n", "f = open('toto.txt','w')\n", "f.write('Coordinates: {latitude}N, {longitude}W {text}'.format(latitude=37.24, longitude=-115.81,text='Zen'))\n", "f.close()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Functions\n", "\n", "Functions allows to save a block of instruction making it dependent on input variables.\n", "Often, even if it is optional, they return new values of modify the input variables.\n", "\n", "In a function, variables can be declared, but they will exist only during the function call. Beware, the same variable name can be used in and out of a function!" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "c = 1\n", "def mult(a,b):\n", " c = 2\n", " print(c)\n", " return a*b\n", "\n", "print(mult(2,'to'))\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "The argument list is only a set of local variables of which the initial value is provided at the function call.\n", "It is possible to provide default values, but in this case every following argument must have an default value.\n", "\n", "When running the function, the arguments are called in order of definition, except if the name of the argument is\n", "also provided." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def fun(p0, p1 = 1, p2 = 3.14 ): \n", " return p0*p1*p2, p0*p1\n", "\n", "res1, res2 = fun(2) # p0 = 1\n", "print(res1, res2)\n", "print(fun(p1=2, p0=1))\n", "print(fun(p0=2, p1 = 1, p2 = 3.14 ))\n", "# All the previous lines are strictly equivalent" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def fun2(p0, p1=1, p2): # does not work\n", " return p0*p1*p2" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "It is really important to well document a function at its creation.\n", "Python provides tools to helps with the documentations: the `docstrings`.\n", "They allow to get the documentation whenever needed in an interactive way." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def pipo():\n", " \"\"\"\n", " Function pipo by molo !\n", " Do things about stuff\n", " \"\"\"\n", " print(\"molo\")\n", "\n", "pipo()\n", "help(pipo)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Variables and objects\n", "\n", "Variables can \"reference\" objects in the \"Object Oriented Programming\" sense.\n", "An object is a structure sheltering:\n", "* attributes: other variables\n", "* methods: functions which can use in an implicit manner the attributes of the object.\n", "\n", "To access to the attributes or methods of an object the ```.``` is used. The `type` of an object is called its `class`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = \"abc\" # creation of an object of the class 'string'\n", "print(s.__doc__ )# attribute holding the documentation of the string object\n", "s.count('a') # calling the 'count' method which count the number of characters" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "\n", "Variables in Python are always references, which means that several variables can reference the same memory in the RAM of the computer.\n", "\n", "This can be a trap when using `mutable` variables." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "g = list( range(4) )\n", "print(g)\n", "g2 = g\n", "g2[0] = 'one'\n", "print(g2)\n", "print(g )# changing the list g2 implies a change in list g\n", "# ... g and g2 both point to the same value" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "To be sure to create a new object, the 'copy' module must be used." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Package importation\n", "\n", "A *module* or *package* provides to the user a set of functions and/or classes.\n", "There are a lot of default module coming with Python (`math`, `sys`, `os`, etc).\n", "\n", "Other modules are installed through the package manager, of the system(*macport*, *apt-get*, etc) or the Python distribution (*conda*, *pypi*, etc). These package are usually supported by the Python Software Foundation.\n", "\n", "Finally, you can install packages not officially supported by Python. The installation process depends on the developers. It there is any intent to share developments, it will be critical to take an interest in how to properly package sources.\n", "\n", "The statement allowing to import a module is `import`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "import math\n", "print(math.sin(0.))\n", "import math as m\n", "print(m.cos(0.))\n", "from math import tan\n", "print(tan(0.))\n", "from math import sinh as st\n", "print(st(0.))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "g = list( range(4) )\n", "print(g)\n", "from copy import deepcopy\n", "g2 = deepcopy(g)\n", "g2[0] = 'un'\n", "print(g2)\n", "print(g ) # changing the list g2 no longer implies a change in list g\n", "# ... g and g2 point to the different values" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "import re\n", "m = re.search(\"[a-c]*\",\"abcdefabc\")\n", "m.group(0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is a short list of common modules used depending on the field:\n", "* Matrix, linear algebra, optimization:\n", " * numpy http://wiki.scipy.org/NumPy_for_Matlab_Users\n", " * scipy https://docs.scipy.org/doc/scipy-0.14.0/reference/tutorial/index.html\n", "* Temporal series, tabular data: Pandas http://pandas.pydata.org/pandas-docs/dev/tutorials.html\n", "* Statistics: statsmodels http://statsmodels.sourceforge.net/\n", "* Machine learning: scikitlearn http://scikit-learn.org/stable/\n", "* Graphs : \n", " * matplotlib http://matplotlib.org/gallery.html\n", " * seaborn http://stanford.edu/~mwaskom/software/seaborn/examples/index.html\n", " * bokeh http://bokeh.pydata.org/en/latest/tutorial/\n", " * plotly (online) https://plot.ly/python/\n", "* Mapping: \n", " * basemap http://matplotlib.org/basemap/\n", " * folium http://bl.ocks.org/wrobstory/5609856\n", "* Sensitivity analysis: OpenTurns (outils EDF) http://www.openturns.org/\n", "* Bayesian inversion: Pymc http://nbviewer.ipython.org/github/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers/blob/master/Chapter1_Introduction/Chapter1.ipynb\n", "* Symbolic calculus: Sympy http://docs.sympy.org/latest/tutorial/intro.html\n", "* XML file handling: lxml http://lxml.de/tutorial.html\n", "* http : requests http://docs.python-requests.org/en/latest/user/quickstart/\n", "* html : beautifulSoup http://www.crummy.com/software/BeautifulSoup/bs4/doc/" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "celltoolbar": "Slideshow", "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.4" }, "latex_envs": { "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 0 }, "toc": { "toc_cell": true, "toc_number_sections": true, "toc_threshold": "3", "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 1 }