{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# [NTDS'19] tutorial 1: introduction\n", "[ntds'19]: https://github.com/mdeff/ntds_2019\n", "\n", "[Michaƫl Defferrard](https://deff.ch), [EPFL LTS2](https://lts2.epfl.ch)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Content\n", "\n", "1. [Conda and Anaconda](#conda)\n", "1. [Python](#python)\n", "1. [Jupyter notebooks](#jupyter)\n", "1. [Version control with git](#git)\n", "1. [Scientific Python](#scipy)\n", "1. [Ressources to improve your Python skills](#improve)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 1 Conda and Anaconda\n", "\n", "![conda](figures/conda.jpg)\n", "\n", "[Conda](https://conda.io) is a package and environment manager. It allows you to create environments, ideally one per project, and install packages into them. It is available for Windows, macOS and Linux.\n", "\n", "[Anaconda](https://anaconda.org/download) is a commercial distribution that comes with many of the packages used by data scientists. [Miniconda](https://conda.io/miniconda.html) is a lighter open distribution. Both install `conda`, from which you'll be able to install many packages.\n", "\n", "[conda-forge](https://conda-forge.org) is a community-driven collection of recipes to build conda packages. It contains many more packages than the official defaults channel." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get basic information from your conda installation:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\r\n", " active environment : ntds_2019\r\n", " active env location : /home/michael/.conda/envs/ntds_2019\r\n", " shell level : 1\r\n", " user config file : /home/michael/.condarc\r\n", " populated config files : /home/michael/.condarc\r\n", " conda version : 4.7.2\r\n", " conda-build version : not installed\r\n", " python version : 3.7.4.final.0\r\n", " virtual packages : \r\n", " base environment : /usr (read only)\r\n", " channel URLs : https://conda.anaconda.org/conda-forge/linux-64\r\n", " https://conda.anaconda.org/conda-forge/noarch\r\n", " https://repo.anaconda.com/pkgs/main/linux-64\r\n", " https://repo.anaconda.com/pkgs/main/noarch\r\n", " https://repo.anaconda.com/pkgs/r/linux-64\r\n", " https://repo.anaconda.com/pkgs/r/noarch\r\n", " package cache : /home/michael/.conda/pkgs\r\n", " envs directories : /home/michael/.conda/envs\r\n", " /usr/envs\r\n", " platform : linux-64\r\n", " user-agent : conda/4.7.2 requests/2.22.0 CPython/3.7.4 Linux/5.2.6-arch1-1-ARCH arch/ glibc/2.29\r\n", " UID:GID : 1000:1000\r\n", " netrc file : None\r\n", " offline mode : False\r\n", "\r\n" ] } ], "source": [ "!conda info" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "List your environments:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "# conda environments:\r\n", "#\r\n", "complexes /home/michael/.conda/envs/complexes\r\n", "eeg_denoising /home/michael/.conda/envs/eeg_denoising\r\n", "ntds_2019 * /home/michael/.conda/envs/ntds_2019\r\n", "osmnx /home/michael/.conda/envs/osmnx\r\n", "python2 /home/michael/.conda/envs/python2\r\n", "scnn /home/michael/.conda/envs/scnn\r\n", "snn /home/michael/.conda/envs/snn\r\n", "base /usr\r\n", "\r\n" ] } ], "source": [ "!conda env list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "List the packages in an environment:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "# packages in environment at /home/michael/.conda/envs/ntds_2019:\r\n", "#\r\n", "# Name Version Build Channel\r\n", "_libgcc_mutex 0.1 main \r\n", "attrs 19.1.0 py_0 conda-forge\r\n", "backcall 0.1.0 py_0 conda-forge\r\n", "bleach 3.1.0 py_0 conda-forge\r\n", "bzip2 1.0.8 h516909a_1 conda-forge\r\n", "ca-certificates 2019.9.11 hecc5488_0 conda-forge\r\n", "certifi 2019.9.11 py37_0 conda-forge\r\n", "cffi 1.12.3 py37h8022711_0 conda-forge\r\n", "cpuonly 1.0 0 pytorch\r\n", "curl 7.65.3 hf8cf82a_0 conda-forge\r\n", "cycler 0.10.0 py_1 conda-forge\r\n", "decorator 4.4.0 py_0 conda-forge\r\n", "defusedxml 0.5.0 py_1 conda-forge\r\n", "dgl 0.3.1 py37_0 dglteam\r\n", "entrypoints 0.3 py37_1000 conda-forge\r\n", "expat 2.2.5 he1b5a44_1003 conda-forge\r\n", "freetype 2.10.0 he983fc9_1 conda-forge\r\n", "gettext 0.19.8.1 hc5be6a0_1002 conda-forge\r\n", "git 2.23.0 pl526hce37bd2_2 conda-forge\r\n", "icu 64.2 he1b5a44_1 conda-forge\r\n", "intel-openmp 2019.4 243 \r\n", "ipykernel 5.1.2 py37h5ca1d4c_0 conda-forge\r\n", "ipython 7.8.0 py37h5ca1d4c_0 conda-forge\r\n", "ipython_genutils 0.2.0 py_1 conda-forge\r\n", "jedi 0.15.1 py37_0 conda-forge\r\n", "jinja2 2.10.1 py_0 conda-forge\r\n", "joblib 0.13.2 py_0 conda-forge\r\n", "json5 0.8.5 py_0 conda-forge\r\n", "jsonschema 3.0.2 py37_0 conda-forge\r\n", "jupyter_client 5.3.1 py_0 conda-forge\r\n", "jupyter_core 4.4.0 py_0 conda-forge\r\n", "jupyterlab 1.1.3 py_0 conda-forge\r\n", "jupyterlab_server 1.0.6 py_0 conda-forge\r\n", "kiwisolver 1.1.0 py37hc9558a2_0 conda-forge\r\n", "krb5 1.16.3 h05b26f9_1001 conda-forge\r\n", "libblas 3.8.0 12_openblas conda-forge\r\n", "libcblas 3.8.0 12_openblas conda-forge\r\n", "libcurl 7.65.3 hda55be3_0 conda-forge\r\n", "libedit 3.1.20170329 hf8c457e_1001 conda-forge\r\n", "libffi 3.2.1 he1b5a44_1006 conda-forge\r\n", "libgcc-ng 9.1.0 hdf63c60_0 \r\n", "libgfortran-ng 7.3.0 hdf63c60_0 \r\n", "libiconv 1.15 h516909a_1005 conda-forge\r\n", "liblapack 3.8.0 12_openblas conda-forge\r\n", "libopenblas 0.3.7 h6e990d7_1 conda-forge\r\n", "libpng 1.6.37 hed695b0_0 conda-forge\r\n", "libsodium 1.0.17 h516909a_0 conda-forge\r\n", "libssh2 1.8.2 h22169c7_2 conda-forge\r\n", "libstdcxx-ng 9.1.0 hdf63c60_0 \r\n", "markupsafe 1.1.1 py37h14c3975_0 conda-forge\r\n", "matplotlib-base 3.1.1 py37he7580a8_1 conda-forge\r\n", "mistune 0.8.4 py37h14c3975_1000 conda-forge\r\n", "mkl 2019.4 243 \r\n", "nbconvert 5.6.0 py37_1 conda-forge\r\n", "nbformat 4.4.0 py_1 conda-forge\r\n", "ncurses 6.1 hf484d3e_1002 conda-forge\r\n", "networkx 2.3 py_0 conda-forge\r\n", "ninja 1.9.0 h6bb024c_0 conda-forge\r\n", "notebook 6.0.1 py37_0 conda-forge\r\n", "numpy 1.15.4 py37h8b7e671_1002 conda-forge\r\n", "openssl 1.1.1c h516909a_0 conda-forge\r\n", "pandas 0.25.1 py37hb3f55d8_0 conda-forge\r\n", "pandoc 2.7.3 0 conda-forge\r\n", "pandocfilters 1.4.2 py_1 conda-forge\r\n", "parso 0.5.1 py_0 conda-forge\r\n", "pcre 8.41 hf484d3e_1003 conda-forge\r\n", "perl 5.26.2 h516909a_1006 conda-forge\r\n", "pexpect 4.7.0 py37_0 conda-forge\r\n", "pickleshare 0.7.5 py37_1000 conda-forge\r\n", "pip 19.2.3 py37_0 conda-forge\r\n", "prometheus_client 0.7.1 py_0 conda-forge\r\n", "prompt_toolkit 2.0.9 py_0 conda-forge\r\n", "ptyprocess 0.6.0 py_1001 conda-forge\r\n", "pycparser 2.19 py37_1 conda-forge\r\n", "pygments 2.4.2 py_0 conda-forge\r\n", "pygsp 0.5.1 py_0 conda-forge\r\n", "pyparsing 2.4.2 py_0 conda-forge\r\n", "pyrsistent 0.15.4 py37h516909a_0 conda-forge\r\n", "python 3.7.3 h33d41f4_1 conda-forge\r\n", "python-dateutil 2.8.0 py_0 conda-forge\r\n", "pytorch 1.2.0 py3.7_cpu_0 [cpuonly] pytorch\r\n", "pytz 2019.2 py_0 conda-forge\r\n", "pyzmq 18.1.0 py37h1768529_0 conda-forge\r\n", "readline 8.0 hf8c457e_0 conda-forge\r\n", "scikit-learn 0.21.3 py37hcdab131_0 conda-forge\r\n", "scipy 1.3.1 py37h921218d_2 conda-forge\r\n", "send2trash 1.5.0 py_0 conda-forge\r\n", "setuptools 41.2.0 py37_0 conda-forge\r\n", "six 1.12.0 py37_1000 conda-forge\r\n", "sqlite 3.29.0 hcee41ef_1 conda-forge\r\n", "terminado 0.8.2 py37_0 conda-forge\r\n", "testpath 0.4.2 py_1001 conda-forge\r\n", "tk 8.6.9 hed695b0_1003 conda-forge\r\n", "tornado 6.0.3 py37h516909a_0 conda-forge\r\n", "traitlets 4.3.2 py37_1000 conda-forge\r\n", "wcwidth 0.1.7 py_1 conda-forge\r\n", "webencodings 0.5.1 py_1 conda-forge\r\n", "wheel 0.33.6 py37_0 conda-forge\r\n", "xz 5.2.4 h14c3975_1001 conda-forge\r\n", "zeromq 4.3.2 he1b5a44_2 conda-forge\r\n", "zlib 1.2.11 h516909a_1006 conda-forge\r\n" ] } ], "source": [ "!conda list -n ntds_2019" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Install packages in an environment. The package will be installed in the activated environment if an environment name is not given." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting package metadata (current_repodata.json): - \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\bdone\r\n", "Solving environment: \\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\b- \b\b\\ \b\b| \b\b/ \b\bdone\r\n", "\r\n", "# All requested packages already installed.\r\n", "\r\n" ] } ], "source": [ "!conda install -n ntds_2019 git" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Want to know more?** Look at the [conda user guide](https://conda.io/docs/user-guide/overview.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 2 Python\n", "\n", "[Python](https://python.org) is one of the main programming languages used by data scientists, along [R](https://www.r-project.org) and [Julia](https://julialang.org). As an open and general purpose language, it is replacing [MATLAB](https://mathworks.com/products/matlab.html) in many scientific and engineering fields. Python is the most popular language used for machine learning.\n", "\n", "Below are very basic examples of Python code. **Want to learn more?** Look at the [Python Tutorial](https://docs.python.org/3/tutorial/index.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Control flow" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello\n" ] } ], "source": [ "if 1 == 1:\n", " print('hello')" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n" ] } ], "source": [ "for i in range(5):\n", " print(i)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n", "3\n" ] } ], "source": [ "a = 4\n", "while a > 2:\n", " print(a)\n", " a -= 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data structures" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lists are mutable, i.e., we can change the objects they store." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 'hello', 3.2]\n", "[1, 2, 'world', 3.2]\n" ] } ], "source": [ "a = [1, 2, 'hello', 3.2]\n", "print(a)\n", "a[2] = 'world'\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tuples are not mutable." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 'hello')" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(1, 2, 'hello')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sets contain unique values." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{1, 2, 3, 4}\n", "{2, 4}\n" ] } ], "source": [ "a = {1, 2, 3, 3, 4}\n", "print(a)\n", "print(a.intersection({2, 4, 6}))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dictionaries map keys to values." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = {'one': 1, 'two': 2, 'three': 3}\n", "a['two']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Functions" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def add(a, b):\n", " return a + b\n", "\n", "add(1, 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Classes" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "30" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class A:\n", " d = 10\n", " \n", " def add(self, c):\n", " return self.d + c\n", "\n", "a = A()\n", "a.add(20)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "30\n", "-10\n" ] } ], "source": [ "class B(A):\n", " def sub(self, c):\n", " return self.d - c\n", "\n", "b = B()\n", "print(b.add(20))\n", "print(b.sub(20))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Dynamic typing" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'abc'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 1\n", "x = 'abc'\n", "x" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'hello'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "add('hel', 'lo')" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4, 5]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "add([1, 2], [3, 4, 5])" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "130\n", "120 items\n" ] } ], "source": [ "print(int('120') + 10)\n", "print(str(120) + ' items')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 3 Jupyter notebooks\n", "\n", "[Jupyter](https://jupyter.org) notebooks allow to mix text, math, code, and results (numerical or figures) in a **single document**. It is intended for interactive computing and is very useful to explore data, teach concepts, create reports. Code can be written in many programming languages, including Python, Julia, R, MATLAB, C++." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Markdown text (and Latex math)\n", "\n", "A list:\n", "\n", "* item\n", "* item\n", "\n", "Text in a paragraph. Text can be *italic*, **bold**, `verbatim`. We can define [hyperlinks](https://github.com/mdeff/ntds_2019).\n", "\n", "A numbered list:\n", "\n", "1. item\n", "1. item\n", "\n", "Some inline math: $x = \\frac12$\n", "\n", "Some display math:\n", "$$ f(x) = \\frac{e^{-x}}{4} $$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Code and results" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6.0" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "20 / 100 * 30" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Inline figures" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "y = np.random.uniform(size=100)\n", "plt.plot(y);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Want to learn more?** Look at the [documentation](https://jupyter.org/documentation)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 4 Version control with git\n", "\n", "![git](figures/git.jpg)\n", "\n", "[git](https://git-scm.com) is an open-source distributed version control system. It allows users to collaborate on projects (not only software!), synchronize and track their changes. It is most often used with an hosting service such as [GitHub](https://github.com) or [GitLab](https://about.gitlab.com). Those services add many tools to facilitate issue tracking, code review, continuous integration, etc.\n", "\n", "* Decentralized: draw on black board. Make it clear that all repos are the same.\n", "* Commit are local. We push / pull to sync with other repos.\n", "* Git is often used in a centralized fashion, with github / gitlab being the syncing point for everybody. It does not have to be, but github is easier to access than my laptop.\n", "* **Want to learn more?** Try this [interactive guide](https://try.github.io) or look at the more involved [user manual](https://git-scm.com/docs).\n", "\n", "### Basic usage\n", "\n", "1. Install with `conda install git`.\n", "1. Everybody make a clean clone (to be erased afterwards). Use HTTPS if not logged on GitHub.\n", "1. I add a fake file.\n", "1. I commit. It is not on github.\n", "1. I push. It is on github.\n", "1. They pull. They see it on their machines.\n", "\n", "Two kinds of users:\n", "* Those who don't want to use git, just do `git pull` before every lab. **Do not modify the content of the folder.** That is like your inbox, you only copy files from there and modify them outside.\n", "* The power users make a branch for each of their solutions!\n", "\n", "### Power users\n", "\n", "* Make a branch: `git branch assignment1_solution`\n", "* Work on that branch: `git checkout assignment1_solution`\n", "* Do and commit your modifications. You get a history of your changes!\n", "* Come back to master with `git checkout master` and get new stuff from the TAs with `git pull`. Again, you should never modify master (you could do it locally, but only the TAs have write access to the github repo).\n", "\n", "### Super-power users\n", "\n", "Those who want to backup or share their work on github.\n", "\n", "1. Create a github account.\n", "1. Create a repository (you could have forked mdeff/ntds_2019).\n", "1. Add a remote repo: `git remote add my_repo git@github.com:username/ntds_2019.git`\n", "1. Push your own branches to your repo: `git push -u my_repo milestone1_solution`.\n", "1. Go on your github and see your changes.\n", "\n", "### Contributors\n", "\n", "Same as before, except that you can now make a pull request for your changes to be integrated into master and be available to all of us.\n", "\n", "### Collaborate with git and github\n", "\n", "All the code for your projects will have to be handled as a repository on GitHub.\n", "While you don't have to collaborate with git (i.e., you can create a single commit at the end with all of your code), we highly recommend you to use it.\n", "It is a very good way to manage your project, as it allows you to come back to previous states, synchronize your changes without being lost with versions, track who did what, discuss issues and code, etc.\n", "As such, we recommend you to use git from the start to get the basics. Once you feel ready, create a repository for your project and start working on an assignment there." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 5 Scientific Python\n", "\n", "Below are the basic packages used for scientific computing and data science.\n", "* [NumPy](https://www.numpy.org): N-dimensional arrays\n", "* [SciPy](https://www.scipy.org/scipylib/index.html): scientific computing\n", "* [matplotlib](https://matplotlib.org): powerful visualization\n", "* [pandas](https://pandas.pydata.org): data analysis\n", "\n", "**Want to learn more?** Look at the [Scipy Lecture Notes](https://www.scipy-lectures.org/).\n", "\n", "Finally, the below packages will be useful to work with networks and graphs.\n", "* [NetworkX](https://networkx.github.io): network science\n", "* [graph-tool](https://graph-tool.skewed.de): network science\n", "* [scikit-learn](https://scikit-learn.org): graph embedding (dimensionality reduction)\n", "* [PyGSP](https://github.com/epfl-lts2/pygsp): graph signal processing\n", "* [Deep Graph Library](https://www.dgl.ai): deep learning on graphs with [PyTorch](https://pytorch.org)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 6 Ressources to improve your Python skills (for experienced Python users)\n", "\n", "We provide a non exhaustive list of tools and concepts that can help you improve your Python coding skills.\n", "They are by no means things that you need to master immediately.\n", "\n", "* Numpy and pytorch indexing and broadcasting rules.\n", " They take some time to understand, but are really essential.\n", " They will help you avoid writing loops, which are considerably slower and sometimes memory inefficient.\n", " * \n", " * \n", " * \n", " * \n", "\n", "\n", "* Some common Python built-in functions.\n", " * [`enumerate`](https://docs.python.org/3/library/functions.html#enumerate)\n", " * [`zip`](https://docs.python.org/3/library/functions.html#zip)\n", " * [`itertools.product`](https://docs.python.org/3/library/itertools.html#itertools.product)\n", "\n", "\n", "* Scipy functions.\n", " * `pdist` and `cdist` are considerably faster than loops to compute pairwise distances between objects (e.g., to build a nearest neighbors graph).\n", " * \n", " * \n", "\n", "\n", "* Object-oriented programming.\n", " * Classes.\n", " * \n", " * Read the source code of libraries you commonly use, and try to understand how they organize it. In particular, we advise you to write your methods as in the scikit-learn API.\n", " * \n", " * Inheritance.\n", " When you implement different models that have the same role (such as different machine learning classifiers), base methods allow you to avoid writing the same code several times.\n", " * \n", " * Abstract methods.\n", " They allow you to tell which methods subclassses (of the base class) should implement.\n", " * \n", " * \n", "\n", "\n", "* Google python style guide.\n", " Not essential, but following these rules make things easier when you work in a group.\n", " * \n", " \n", "\n", "* Unit tests.\n", " * \n", " * " ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 4 }