.. _introcoderst: ============= Leçon de code ============= .. only:: html **Links:** :download:`notebook `, :downloadlink:`html `, :download:`PDF `, :download:`python `, :downloadlink:`slides `, :githublink:`GitHub|_doc/notebooks/2020/ensae/introcode.ipynb|*` La programmation est devenue un outil essentiel du datascientist mais pas seulement. Beaucoup d’outils pointus sont open source mais uniquement accessibles à ceux qui savent programmer. Après la mise au point d’un modèle statistique, économique, il se pose souvent la question de la mise à jour fréquente des résultats, c’est à dire leur automatisation via la programmation. .. code:: ipython3 from jyquickhelper import add_notebook_menu add_notebook_menu() .. contents:: :local: Après la prépas --------------- Programmation, ENSAE, automatisation, emplois ENSAE ~~~~~ - statistique, finance, économie, actuariat, data science - utilisation massive des données - plus de logiciel passe partout Excel, Matlab, SAS, Python, Notebook ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - tableur : difficile de passer à l’échelle - SAS, Matlab : onéreux - Python : open source, langage accessible sans être un expert, effort de design comme avec `scikit-learn `__ (`INRIA `__) - `notebook `__ : outils permettant de mélanger texte, formules, code et de le partager Python, R : Python ~~~~~~~~~~~~~~~~~~ - tous deux open sources - python plus complet - attire les développeurs, pas seulement les chercheurs - R plus proche de matlab Installation ~~~~~~~~~~~~ - `Anaconda `__ A distance ~~~~~~~~~~ - `colab `__ Après la prépa ~~~~~~~~~~~~~~ - code efficace - test unitaires, exceptions :math:`\longrightarrow` à connaître pour un entretien d’embauche - packaging : exemple avec `2048 `__ - manipulation de données, dataframes, graphes. Un exemple : coût de l’algorithme ? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: ipython3 def position_max(tableau): for i in range(0, len(tableau)): if tableau[i] == max(tableau): return i mx = position_max([6, 7, 4, 11, -5, 4]) mx .. parsed-literal:: 3 Ressource ~~~~~~~~~ - contenus en ligne `xavierdupre.fr `__ - Google, Bing, Duck Duck Go, Qwant, Baidu, Yandex - `Stackoverflow `__ - `openclassroom `__ - mail au professeur COVID ~~~~~ - apprentissage pour tout le monde y compris pour les encadrants - vidéo, pédagogie inversée - projet en groupe : application Flask Cours ----- Objectif du cours ~~~~~~~~~~~~~~~~~ - `Test unitaire `__ - Calcul matriciel avec `numpy `__ - `Culture algorithmique `__ - Etre capable de réaliser une application `Flask `__ (web) qui récupère des données pour faire des statistiques. - Etre capable de reproduire ou réutiliser l’algorithme décrit dans un article ou implémenté sur github Organisation ~~~~~~~~~~~~ - Répartition en TDs - Le chemin vers les objectifs du cours sont différents selon les TDs Quizz 1 ------- affectation ~~~~~~~~~~~ .. code:: ipython3 a = 3 types ~~~~~ .. code:: ipython3 a = 3 p = 4.56 b = 'r' c = (4, 6) g = [5, 4] d = {'a': 0, 'b': 1} test ~~~~ .. code:: ipython3 h = 7 if h % 2 == 0: msg = 'pair' else: msg = 'impair' print(msg) .. parsed-literal:: impair boucle ~~~~~~ .. code:: ipython3 for element in [4, 5, 8]: print(element) .. parsed-literal:: 4 5 8 .. code:: ipython3 it = 0 while it < 24: print(it) it += 5 .. parsed-literal:: 0 5 10 15 20 fonction ~~~~~~~~ .. code:: ipython3 def area(l, w): return l * w print(area(4, 5)) .. parsed-literal:: 20 print / return ? ~~~~~~~~~~~~~~~~ .. code:: ipython3 def area(l, w): print(l * w) print(area(4, 5)) .. parsed-literal:: 20 None import ~~~~~~ .. code:: ipython3 import math from math import cos cos(5) + math.sin(5) .. parsed-literal:: -0.6752620891999122 classes ? ~~~~~~~~~ .. code:: ipython3 class Vase: def __init__(self, hauteur, diametre): self.hauteur = hauteur self.diametre = diametre def area(self): return self.hauteur * self.diametre * math.pi v = Vase(5, 3) print(v.area()) .. parsed-literal:: 47.12388980384689 Quizz 2 : array, dataframe, graphe ---------------------------------- On ne code plus le produit matriciel. Il est très difficile d’être plus rapide que `numpy `__ qui utilise des libraires telles que `BLAS `__ qui savent tirer parti des optimisations processeurs `AVX `__, voire de processeurs différents `GPU `__. Produit matriciel ~~~~~~~~~~~~~~~~~ .. code:: ipython3 import numpy mat1 = numpy.array([[1, 2, 3], [4, 5, 6]]) mat2 = numpy.array([[1, -1], [-1, 1], [0, 0]]) mat1 @ mat2 .. parsed-literal:: array([[-1, 1], [-1, 1]]) .. code:: ipython3 mat2 @ mat1 .. parsed-literal:: array([[-3, -3, -3], [ 3, 3, 3], [ 0, 0, 0]]) Dataframe ~~~~~~~~~ .. code:: ipython3 import pandas df = pandas.DataFrame([{'col1': 4.5, 'col2': "legend"}, {'col1': 4.5, 'col3': -8}, {'col1': 14.5, 'col3': -80, 'col2': 'note'}]) df .. raw:: html
col1 col2 col3
0 4.5 legend NaN
1 4.5 NaN -8.0
2 14.5 note -80.0
.. code:: ipython3 df.isna() .. raw:: html
col1 col2 col3
0 False False True
1 False True False
2 False False False
.. code:: ipython3 df.isna().astype(numpy.int64) .. raw:: html
col1 col2 col3
0 0 0 1
1 0 1 0
2 0 0 0
.. code:: ipython3 df[df['col1'] >= 10] .. raw:: html
col1 col2 col3
2 14.5 note -80.0
Graphes ~~~~~~~ .. code:: ipython3 rnd = numpy.random.randn(50, 3) @ numpy.array([[1, 0, 1], [0, 1, 0], [0, -3, 1]]) rnd[:5] .. parsed-literal:: array([[ 0.06607333, 4.74896639, -1.11535865], [-1.28671779, 1.2653011 , -2.10633038], [-0.40579191, -0.85452334, -0.34367823], [-1.10590692, 1.92898689, -1.25570647], [ 0.43969349, 4.22563223, -1.25008265]]) .. code:: ipython3 %matplotlib inline .. code:: ipython3 import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 3, figsize=(12, 4), sharex=True, sharey=True) ax[0].plot(rnd[:, 0], rnd[:, 1], '.') ax[0].set_title("Axes 1 et 2") ax[1].plot(rnd[:, 1], rnd[:, 2], '.') ax[1].set_title("Axes 2 et 3") ax[2].plot(rnd[:, 0], rnd[:, 1], '.', label="Axes 1 et 2") ax[2].plot(rnd[:, 1], rnd[:, 2], '.', label="Axes 2 et 3") ax[2].set_title("Axes 1 et 2 et 3") ax[2].legend(); .. image:: introcode_46_0.png Quizz 3 : algorithme -------------------- .. code:: ipython3 from IPython.display import SVG, Image Recherche dichotomique ~~~~~~~~~~~~~~~~~~~~~~ .. code:: ipython3 Image("https://upload.wikimedia.org/wikipedia/commons/f/f7/Binary_search_into_array.png") .. image:: introcode_50_0.png Tri fusion ~~~~~~~~~~ .. code:: ipython3 Image("https://upload.wikimedia.org/wikipedia/commons/6/60/Mergesort_algorithm_diagram.png") .. image:: introcode_52_0.png Tas ~~~ .. code:: ipython3 SVG("https://upload.wikimedia.org/wikipedia/commons/3/38/Max-Heap.svg") .. image:: introcode_54_0.svg Plus court chemin dans un graphe ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: ipython3 SVG("https://upload.wikimedia.org/wikipedia/commons/2/29/DijkstraBis01.svg") .. image:: introcode_56_0.svg Voygeur de commerce ~~~~~~~~~~~~~~~~~~~ .. code:: ipython3 Image("tsp.png", width=400) .. image:: introcode_58_0.png :width: 400px distance d’édition ~~~~~~~~~~~~~~~~~~ .. code:: ipython3 Image("https://upload.wikimedia.org/wikipedia/commons/d/d1/Levenshtein_distance_animation.gif") .. parsed-literal:: Problème du sac-à-dos ~~~~~~~~~~~~~~~~~~~~~ .. code:: ipython3 SVG("https://upload.wikimedia.org/wikipedia/commons/f/fd/Knapsack.svg") .. image:: introcode_62_0.svg Simplexe ~~~~~~~~ .. code:: ipython3 Image('https://upload.wikimedia.org/wikipedia/commons/2/25/Tetrahedron.png', width=400) .. image:: introcode_64_0.png :width: 400px Postier chinois ~~~~~~~~~~~~~~~ .. code:: ipython3 Image("postier.png") .. image:: introcode_66_0.png Arbre de décision ~~~~~~~~~~~~~~~~~ .. code:: ipython3 Image("dectree.png") .. image:: introcode_68_0.png Quizz 4 : génie logiciel ------------------------ Les exceptions ~~~~~~~~~~~~~~ Les programmes qui plantent mais en fait c’est pas grave. .. code:: ipython3 try: y = 1 / 0 except Exception as e: print(type(e), e) .. parsed-literal:: division by zero Ou des fois-ci .. code:: ipython3 try: x = -1 if x < 0: raise ValueError("La racine carrée d'un nombre positif est inconnue de ce programme.") except Exception as e: print(type(e), e) .. parsed-literal:: La racine carrée d'un nombre positif est inconnue de ce programme. Les expressions régulières ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: ipython3 import re reg = re.compile("[A-Z]{2,}") texte = "Etrange ces acronymes comme ENSAE ou CPU qui ressortent comme par magie." reg.findall(texte) .. parsed-literal:: ['ENSAE', 'CPU'] Les tests unitaires ~~~~~~~~~~~~~~~~~~~ Ou comment protéger son code contre l’intrusion d’un codeur distrait. .. code:: ipython3 def return_sept(n): return int('7' * n) def test_unitaire(): # Si ça plante, c'est de votre faute. assert return_sept(4) == 7777 test_unitaire() Le packaging… ~~~~~~~~~~~~~ Il y a plusieurs façons de passer à la postérité. C’est l’une d’elle. Problèmes, Exercices -------------------- Enumérer les permutations ~~~~~~~~~~~~~~~~~~~~~~~~~ `enumerate_permutations_recursive `__. Suggestions ~~~~~~~~~~~ .. code:: ipython3 Image("suggestion.png") .. image:: introcode_82_0.png Le **trie** .. code:: ipython3 SVG('https://upload.wikimedia.org/wikipedia/commons/b/be/Trie_example.svg') .. image:: introcode_84_0.svg Récupérer des mails automatiquement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … Calculer des statistiques et les envoyer automatiquement au format PDF par mail ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … Ecrire un système qui note automatiquement les présences ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ par reconnaissance faciale mais qui échoue pour cause de masques qui passe alors par la voix en demandant de chanter du Johnny. A suivre. ---------