Leçon de code

Links: notebook, html, python, slides, GitHub

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.

from jyquickhelper import add_notebook_menu
add_notebook_menu()

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

Après la prépa

  • code efficace

  • test unitaires, exceptions \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 ?

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
3

Ressource

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

types

a = 3
p = 4.56
b = 'r'
c = (4, 6)
g = [5, 4]
d = {'a': 0, 'b': 1}

test

h = 7
if h % 2 == 0:
    msg = 'pair'
else:
    msg = 'impair'
print(msg)
impair

boucle

for element in [4, 5, 8]:
    print(element)
4
5
8
it = 0
while it < 24:
    print(it)
    it += 5
0
5
10
15
20

fonction

def area(l, w):
    return l * w

print(area(4, 5))
20

import

import math
from math import cos
cos(5) + math.sin(5)
-0.6752620891999122

classes ?

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())
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

import numpy
mat1 = numpy.array([[1, 2, 3], [4, 5, 6]])
mat2 = numpy.array([[1, -1], [-1, 1], [0, 0]])
mat1 @ mat2
array([[-1,  1],
       [-1,  1]])
mat2 @ mat1
array([[-3, -3, -3],
       [ 3,  3,  3],
       [ 0,  0,  0]])

Dataframe

import pandas
df = pandas.DataFrame([{'col1': 4.5, 'col2': "legend"},
                       {'col1': 4.5, 'col3': -8},
                       {'col1': 14.5, 'col3': -80, 'col2': 'note'}])
df
col1 col2 col3
0 4.5 legend NaN
1 4.5 NaN -8.0
2 14.5 note -80.0
df.isna()
col1 col2 col3
0 False False True
1 False True False
2 False False False
df.isna().astype(numpy.int64)
col1 col2 col3
0 0 0 1
1 0 1 0
2 0 0 0
df[df['col1'] >= 10]
col1 col2 col3
2 14.5 note -80.0

Graphes

rnd = numpy.random.randn(50, 3) @ numpy.array([[1, 0, 1], [0, 1, 0], [0, -3, 1]])
rnd[:5]
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]])
%matplotlib inline
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();
../_images/introcode_46_0.png

Quizz 3 : algorithme

from IPython.display import SVG, Image

Recherche dichotomique

Image("https://upload.wikimedia.org/wikipedia/commons/f/f7/Binary_search_into_array.png")
../_images/introcode_50_0.png

Tri fusion

Image("https://upload.wikimedia.org/wikipedia/commons/6/60/Mergesort_algorithm_diagram.png")
../_images/introcode_52_0.png

Tas

SVG("https://upload.wikimedia.org/wikipedia/commons/3/38/Max-Heap.svg")
../_images/introcode_54_0.svg

Plus court chemin dans un graphe

SVG("https://upload.wikimedia.org/wikipedia/commons/2/29/DijkstraBis01.svg")
../_images/introcode_56_0.svg

Voygeur de commerce

Image("tsp.png", width=400)
../_images/introcode_58_0.png

distance d’édition

Image("https://upload.wikimedia.org/wikipedia/commons/d/d1/Levenshtein_distance_animation.gif")
<IPython.core.display.Image object>

Problème du sac-à-dos

SVG("https://upload.wikimedia.org/wikipedia/commons/f/fd/Knapsack.svg")
../_images/introcode_62_0.svg

Simplexe

Image('https://upload.wikimedia.org/wikipedia/commons/2/25/Tetrahedron.png', width=400)
../_images/introcode_64_0.png

Postier chinois

Image("postier.png")
../_images/introcode_66_0.png

Arbre de décision

Image("dectree.png")
../_images/introcode_68_0.png

Quizz 4 : génie logiciel

Les exceptions

Les programmes qui plantent mais en fait c’est pas grave.

try:
    y = 1 / 0
except Exception as e:
    print(type(e), e)
<class 'ZeroDivisionError'> division by zero

Ou des fois-ci

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)
<class 'ValueError'> La racine carrée d'un nombre positif est inconnue de ce programme.

Les expressions régulières

import re
reg = re.compile("[A-Z]{2,}")
texte = "Etrange ces acronymes comme ENSAE ou CPU qui ressortent comme par magie."
reg.findall(texte)
['ENSAE', 'CPU']

Les tests unitaires

Ou comment protéger son code contre l’intrusion d’un codeur distrait.

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

Suggestions

Image("suggestion.png")
../_images/introcode_82_0.png

Le trie

SVG('https://upload.wikimedia.org/wikipedia/commons/b/be/Trie_example.svg')
../_images/introcode_84_0.svg

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.