Leçon de code#

Links: notebook, html, PDF, 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

Installation#

A distance#

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#

affectation#

a = 3

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#

Enumérer les permutations#

enumerate_permutations_recursive.

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

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.#