Faire un rapport de TP avec Jupyter (v 1.0)

Laurent Signac -

In [1]:
from IPython.display import HTML
HTML(url="https://deptinfo-ensip.univ-poitiers.fr/FILES/NB/files/nb.css")
Out[1]:

Cette année, vous aurez quelques rapports de TP à rendre sous forme d'un Notebook. Il ne s'agira pas uniquement de donner du code, mais aussi de le rendre limpide, réutilisable, et d'interpréter les résultats. Une particularité très intéressante des notebook et qu'on peut méler du code exécutable, et du texte. Il est ainsi possible de mélanger les explications, et les programmes.

Les cellules dans lesquelles vous écrivez peuvent être de type Code ou Makdown (le format de balisage utilisé pour le texte). On passe d'un type à l'autre avec les raccourcis clavier y et m (remarquez que les cellules de types Code sont précédées de In[.]). Un autre raccourci clavier utile est h : il vous donne la liste des raccourcis clavier (vérifiez... h est dans cette liste).

Langage Markdown pour les cellules de texte

Le langage de balisage Markdown est très simple à utiliser. Vous trouverez une référence ici.

Pour démarrer, voici quelques indications :

### Titre 3

donne :

Titre 3

On peut utiliser du **gras** ou de *l'italique* dans le texte 

donne : On peut utiliser du gras ou de l'italique dans le texte

Il est possible de faire des liens hypertextes, par exemple vers le [site officiel de Python](http://python.org)

donne : Il est possible de faire des liens hypertextes, par exemple vers le site officiel de Python

On peut même écrire des formules au format LaTeX : $$\sum_{i=0}^{i=n} i^2 = \frac{n(n+1)(n+2)}{6}$$

donne : On peut même écrire des formules au format LaTeX : $$\sum_{i=0}^{i=n} i^2 = \frac{n(n+1)(2n+1)}{6}$$

Que mettre dans un rapport de TP ?

Le rapport final que vous rendez doit être :

  • pédagogique
  • instructif
  • agréable à lire

Placez-vous dans la situation suivante : votre employeur vous a commandé une étude sur un sujet particulier. Le rapport de TP que vous rendez est cette étude. Il doit se suffire à lui même, être compréhensible par la personne qui va relire, lui être utile (c'est à dire apporter des réponses), et être agréable à lire.

Voici un exemple de rapport de TP fictif : les dés d'Efron. Le sujet (plus court que les sujets habituels) est donné dans les 3 premiers paragraphes. La suite est le rapport de TP.

Les dés d'Efron

Ces dés ont été inventés par Bradley Efron, et sont à l’honneur dans la rubrique Logique et Calcul du magazine Pour la Science d’avril 2013 (n°426). Ils sont aussi utilisés dans une nouvelle de Colin Bruce, dans l’ouvrage Élémentaire mon cher Watson (Flammarion).

Ce jeu se joue avec 3 dés. Le dé A a été imprimé 6 fois avec un 4 (les 6 faces sont identiques). Le dé B a 2 fois le chiffre 10 et 4 fois le chiffre 1. Et enfin le dé C a 4 fois le chiffre 6 et 2 fois le chiffre 0. Le total sur chaque dé vaut donc 24, ce qui implique que la moyenne des tirages pour n’importe lequel de ces dés tendra vers 4 si on réalise beaucoup de tirages. Dans ce jeu, deux joueurs prennent chacun un dé et celui qui obtient la plus grande valeur gagne.

Bien que chaque dé produise en moyenne un 4 (tous les dés ont donc l’air équivalents en moyenne), le joueur qui choisit le dé en dernier dispose d’une stratégie qui lui permet de remporter la victoire pratiquement deux fois sur trois. Pensez-vous que ce soit possible ?

Pour vérifier expérimentalement l'intransitivité des dés, on va, pour chaque couple de dés possible (il ya en a 3 : AB, AC, BC), réaliser 10000 tirages et regarder si le nombre de victoires pour chaque dé est d'environ la moitié (comme on pourrait s'y attendre) ou non (comme le laisse penser l'énoncé).

Voici une première fonction qui prend en paramètre la liste des faces des deux dés ainsi que le nombre de tirage à réaliser et renvoie le nombre de victoires du premier et du second dé (le total doit donc donner le nombre de tirages).

In [2]:
import random
def simulation(de1, de2, n):
    victoires = [0, 0]
    for k in range(n):
        if random.choice(de1) > random.choice(de2):
            victoires[0] += 1
        else:
            victoires[1] += 1
    return victoires

On peut tester cette fonction avec les dés A et B :

In [3]:
simulation([4, 4, 4, 4, 4, 4], [10, 10, 1, 1, 1, 1], 10000)
Out[3]:
[6727, 3273]

L'écart semble important : environ $\frac{2}{3}$ de victoires pour de dé A

Refaisons plusieurs fois le test pour vérifier que l'écart est toujours dans le même sens :

In [4]:
for i in range(10):
    print(simulation([4, 4, 4, 4, 4, 4], [10, 10, 1, 1, 1, 1], 10000))
[6707, 3293]
[6638, 3362]
[6691, 3309]
[6725, 3275]
[6703, 3297]
[6696, 3304]
[6694, 3306]
[6666, 3334]
[6635, 3365]
[6646, 3354]

Le résultat est sans appel. Le dé A gagne 2 fois plus souvent que le dé B. Vérifions avec tous les couples de dés

In [5]:
des = {"A": [4] * 6, "B": [10] * 2 + [1] * 4, "C": [6] * 4 + [0] * 2}

import itertools

for de1, de2 in itertools.combinations(des, 2):
    res1, res2 = simulation(des[de1], des[de2], 50000)
    if res2 > res1:
        res1, res2, de1, de2 = res2, res1, de2, de1
    print("{} gagne contre {} dans {:.1f} % des cas".format(de1, de2, res1 / (res1+res2) * 100))
A gagne contre B dans 66.7 % des cas
C gagne contre A dans 66.6 % des cas
B gagne contre C dans 55.6 % des cas

Le test précédent montre expérimentalement que pour chaque dé A, B ou C, il y a forcément un autre dé qui le bat plus souvent qu'une fois sur 2 (d'où l'autre nom des dés d'Efron : dés intransitifs).

On peut vérifier (même si c'est assez évident) que chaque dé donne pourtant en moyenne le même résultat (4) :

In [6]:
N = 10000
des = {"A": [4] * 6, "B": [10] * 2 + [1] * 4, "C": [6] * 4 + [0] * 2}
for nom, vals in des.items():
    res = sum(random.choice(vals) for _ in range(N))
    print("Moyenne obtenue avec le dé {} : {}".format(nom, res / N))
Moyenne obtenue avec le dé A : 4.0
Moyenne obtenue avec le dé B : 4.0726
Moyenne obtenue avec le dé C : 3.99

En conclusion, on a pu vérifier expérimentalement que les 3 dés A, B et C, bien que donnant en moyenne une valeur de 4 chacun ne sont pas équivalent. Pour chaque choix de dé, il existe un autre dé qui le bat avec une probabilité strictement supérieure à 0.5 (et non pas égale à 0.5 comme on aurait pu le supposer) :

  • A > B
  • B > C
  • C > A

Si le joueur 1 demande au joueur 2 de choisir avec quel dé joueur, il a donc toujours la possiblité de prendre un dé qui lui est supérieur. Le choix le moins mauvais que peut faire le joueur 2 est le C. Dans ce cas, le joueur 1 choisira B, et gagnera avec une probabilité de 0.55 seulement (contre 0.66 si le joueur 2 choisit A ou B).