diff --git a/module2/exo1/toy_document_orgmode_python_fr.org b/module2/exo1/toy_document_orgmode_python_fr.org index 944b26e4a78d12c5e26bf352a8425da45aa1a0c7..582da9a5f986155bb0cd073f73f257572c3a5f2c 100644 --- a/module2/exo1/toy_document_orgmode_python_fr.org +++ b/module2/exo1/toy_document_orgmode_python_fr.org @@ -12,10 +12,65 @@ * En demandant à la lib maths -Mon ordinateur m'indique que π vaut approximativement: -#+begin_src python :results output :exports both -from math import * +Mon ordinateur m'indique que $\pi$ vaut /approximativement/: + +#+begin_src python :results value :session *python* :exports both +from math import pi pi #+end_src #+RESULTS: +: 3.141592653589793 + +* En utilisant la méthode des aiguilles de Buffon + +Mais calculé avec la *méthode* des _aiguilles de Buffon_, on obtiendrait comme *approximation* : + +#+begin_src python :results value :session *python* :exports both +import numpy as np +np.random.seed(seed=42) +N = 10000 +x = np.random.uniform(size=N, low=0, high=1) +theta = np.random.uniform(size=N, low=0, high=pi/2) +2/(sum((x+np.sin(theta))>1)/N) +#+end_src + +#+RESULTS: +: 3.128911138923655 + +* Avec un argument "fréquentiel" de surface +Sinon, une méthode plus simple à comprendre et ne faisant pas intervenir d'appel à la fonction sinus se base sur le fait que si $X∼U(0,1) et Y∼U(0,1) alors P[X2+Y2≤1]=\pi/4$ (voir méthode de Monte Carlo sur Wikipedia). Le code suivant illustre ce fait : + + +#+begin_src python :results output file :var matplot_lib_filename="figure_pi_mc2.png" :exports both :session *python*y +import matplotlib.pyplot as plt + +np.random.seed(seed=42) +N = 1000 +x = np.random.uniform(size=N, low=0, high=1) +y = np.random.uniform(size=N, low=0, high=1) + +accept = (x*x+y*y) <= 1 +reject = np.logical_not(accept) + +fig, ax = plt.subplots(1) +ax.scatter(x[accept], y[accept], c='b', alpha=0.2, edgecolor=None) +ax.scatter(x[reject], y[reject], c='r', alpha=0.2, edgecolor=None) +ax.set_aspect('equal') + +plt.savefig(matplot_lib_filename) +print(matplot_lib_filename) +#+end_src + + +Il est alors aisé d'obtenir une approximation (pas terrible) de $\pi$ en +comptant combien de fois, en moyenne, $X^2 + Y^2$ est inférieur à 1 : + +#+begin_src python :results output :session *python* :exports both +4*np.mean(accept) +#+end_src + +#+RESULTS: +: 3.112 +: +: diff --git a/module2/exo2/exercice_python_en.org b/module2/exo2/exercice_python_en.org index 5782f493934678ba782fb65634a4d86e5f3adefc..9931d50dca4696cd3844f3687b67465afb2c56ca 100644 --- a/module2/exo2/exercice_python_en.org +++ b/module2/exo2/exercice_python_en.org @@ -60,7 +60,7 @@ print(x) #+end_example Finally, an example for graphical output: -#+begin_src python :results output file :session :var matplot_lib_filename="./cosxsx.png" :exports results +#+begin_src python :results value :session :var matplot_lib_filename="./cosxsx.png" :exports results import matplotlib.pyplot as plt plt.figure(figsize=(10,5)) @@ -72,7 +72,8 @@ print(matplot_lib_filename) #+end_src #+RESULTS: -[[file:./cosxsx.png]] +[[./cosxsx.png]] + Note the parameter ~:exports results~, which indicates that the code will not appear in the exported document. We recommend that in the diff --git a/module2/exo2/exercice_python_fr.org b/module2/exo2/exercice_python_fr.org index c7157ba42216cf2e1d291112bb351ce48811115c..aed29a2889564ef0eee114a6af2fc2bae981c746 100644 --- a/module2/exo2/exercice_python_fr.org +++ b/module2/exo2/exercice_python_fr.org @@ -1,4 +1,4 @@ -#+TITLE: Votre titre +#+TITLE: Exo2 #+AUTHOR: Votre nom #+DATE: La date du jour #+LANGUAGE: fr @@ -11,83 +11,108 @@ #+HTML_HEAD: #+HTML_HEAD: -* Quelques explications - -Ceci est un document org-mode avec quelques exemples de code -python. Une fois ouvert dans emacs, ce document peut aisément être -exporté au format HTML, PDF, et Office. Pour plus de détails sur -org-mode vous pouvez consulter https://orgmode.org/guide/. - -Lorsque vous utiliserez le raccourci =C-c C-e h o=, ce document sera -compilé en html. Tout le code contenu sera ré-exécuté, les résultats -récupérés et inclus dans un document final. Si vous ne souhaitez pas -ré-exécuter tout le code à chaque fois, il vous suffit de supprimer -le # et l'espace qui sont devant le ~#+PROPERTY:~ au début de ce -document. - -Comme nous vous l'avons montré dans la vidéo, on inclue du code -python de la façon suivante (et on l'exécute en faisant ~C-c C-c~): - -#+begin_src python :results output :exports both -print("Hello world!") +* Donnée +#+begin_src python :results value :exports both :session +data = [14.0, 7.6, 11.2, 12.8, 12.5, 9.9, 14.9, 9.4, 16.9, 10.2, 14.9, 18.1, 7.3, 9.8, 10.9,12.2, 9.9, 2.9, 2.8, 15.4, 15.7, 9.7, 13.1, 13.2, 12.3, 11.7, 16.0, 12.4, 17.9, 12.2, 16.2, 18.7, 8.9, 11.9, 12.1, 14.6, 12.1, 4.7, 3.9, 16.9, 16.8, 11.3, 14.4, 15.7, 14.0, 13.6, 18.0, 13.6, 19.9, 13.7, 17.0, 20.5, 9.9, 12.5, 13.2, 16.1, 13.5, 6.3, 6.4, 17.6, 19.1, 12.8, 15.5, 16.3, 15.2, 14.6, 19.1, 14.4, 21.4, 15.1, 19.6, 21.7, 11.3, 15.0, 14.3, 16.8, 14.0, 6.8, 8.2, 19.9, 20.4, 14.6, 16.4, 18.7, 16.8, 15.8, 20.4, 15.8, 22.4, 16.2, 20.3, 23.4, 12.1, 15.5, 15.4, 18.4, 15.7, 10.2, 8.9, 21.0] +data #+end_src #+RESULTS: -: Hello world! +| 14.0 | 7.6 | 11.2 | 12.8 | 12.5 | 9.9 | 14.9 | 9.4 | 16.9 | 10.2 | 14.9 | 18.1 | 7.3 | 9.8 | 10.9 | 12.2 | 9.9 | 2.9 | 2.8 | 15.4 | 15.7 | 9.7 | 13.1 | 13.2 | 12.3 | 11.7 | 16.0 | 12.4 | 17.9 | 12.2 | 16.2 | 18.7 | 8.9 | 11.9 | 12.1 | 14.6 | 12.1 | 4.7 | 3.9 | 16.9 | 16.8 | 11.3 | 14.4 | 15.7 | 14.0 | 13.6 | 18.0 | 13.6 | 19.9 | 13.7 | 17.0 | 20.5 | 9.9 | 12.5 | 13.2 | 16.1 | 13.5 | 6.3 | 6.4 | 17.6 | 19.1 | 12.8 | 15.5 | 16.3 | 15.2 | 14.6 | 19.1 | 14.4 | 21.4 | 15.1 | 19.6 | 21.7 | 11.3 | 15.0 | 14.3 | 16.8 | 14.0 | 6.8 | 8.2 | 19.9 | 20.4 | 14.6 | 16.4 | 18.7 | 16.8 | 15.8 | 20.4 | 15.8 | 22.4 | 16.2 | 20.3 | 23.4 | 12.1 | 15.5 | 15.4 | 18.4 | 15.7 | 10.2 | 8.9 | 21.0 | -Voici la même chose, mais avec une session python, donc une -persistance d'un bloc à l'autre (et on l'exécute toujours en faisant -~C-c C-c~). -#+begin_src python :results output :session :exports both -import numpy -x=numpy.linspace(-15,15) -print(x) +#+begin_src python :results value :session :var matplot_lib_filename="fig1.png" :exports both +from numpy import mean, min, max, median, std +import matplotlib +import matplotlib.pyplot as plt +d_mean = mean(data) +d_min = min(data) +d_max = max(data) +d_median = median(data) +d_std = std(data, ddof=1) +f"Mean : {d_mean}\nMin: {d_min}\nMax: {d_max}\nMediane: {d_median}\nEcart Type: {d_std}" #+end_src #+RESULTS: -#+begin_example -[-15. -14.3877551 -13.7755102 -13.16326531 -12.55102041 - -11.93877551 -11.32653061 -10.71428571 -10.10204082 -9.48979592 - -8.87755102 -8.26530612 -7.65306122 -7.04081633 -6.42857143 - -5.81632653 -5.20408163 -4.59183673 -3.97959184 -3.36734694 - -2.75510204 -2.14285714 -1.53061224 -0.91836735 -0.30612245 - 0.30612245 0.91836735 1.53061224 2.14285714 2.75510204 - 3.36734694 3.97959184 4.59183673 5.20408163 5.81632653 - 6.42857143 7.04081633 7.65306122 8.26530612 8.87755102 - 9.48979592 10.10204082 10.71428571 11.32653061 11.93877551 - 12.55102041 13.16326531 13.7755102 14.3877551 15. ] -#+end_example - -Et enfin, voici un exemple de sortie graphique: -#+begin_src python :results output file :session :var matplot_lib_filename="./cosxsx.png" :exports results +: Mean : 14.113000000000001 +: Min: 2.8 +: Max: 23.4 +: Mediane: 14.5 +: Ecart Type: 4.334094455301447 + +#+BEGIN_SRC python :session :results file +import matplotlib import matplotlib.pyplot as plt - -plt.figure(figsize=(10,5)) -plt.plot(x,numpy.cos(x)/x) -plt.tight_layout() - -plt.savefig(matplot_lib_filename) -print(matplot_lib_filename) -#+end_src - +fig=plt.figure(figsize=(3,2)) +plt.hist(data) +plt.savefig('test.png') +'./test.png' +#+END_SRC #+RESULTS: -[[file:./cosxsx.png]] - -Vous remarquerez le paramètre ~:exports results~ qui indique que le code -ne doit pas apparaître dans la version finale du document. Nous vous -recommandons dans le cadre de ce MOOC de ne pas changer ce paramètre -(indiquer ~both~) car l'objectif est que vos analyses de données soient -parfaitement transparentes pour être reproductibles. - -Attention, la figure ainsi générée n'est pas stockée dans le document -org. C'est un fichier ordinaire, ici nommé ~cosxsx.png~. N'oubliez pas -de le committer si vous voulez que votre analyse soit lisible et -compréhensible sur GitLab. - -Enfin, n'oubliez pas que nous vous fournissons dans les ressources de -ce MOOC une configuration avec un certain nombre de raccourcis -claviers permettant de créer rapidement les blocs de code python (en -faisant ~", line 7, in + File "", line 4, in + File "/Library/Python/3.7/site-packages/matplotlib/pyplot.py", line 2610, in hist + if data is not None else {}), **kwargs) + File "/Library/Python/3.7/site-packages/matplotlib/__init__.py", line 1565, in inner + return func(ax, *map(sanitize_sequence, args), **kwargs) + File "/Library/Python/3.7/site-packages/matplotlib/axes/_axes.py", line 6559, in hist + cbook._check_in_list(['left', 'mid', 'right'], align=align) + File "/Library/Python/3.7/site-packages/matplotlib/cbook/__init__.py", line 2145, in _check_in_list + .format(v, k, ', '.join(map(repr, values)))) +ValueError: 'edge' is not a valid value for align; supported values are 'left', 'mid', 'right' +]] +[[file:Traceback (most recent call last): + File "", line 7, in + File "", line 4, in + File "/Library/Python/3.7/site-packages/matplotlib/pyplot.py", line 2610, in hist + if data is not None else {}), **kwargs) + File "/Library/Python/3.7/site-packages/matplotlib/__init__.py", line 1565, in inner + return func(ax, *map(sanitize_sequence, args), **kwargs) + File "/Library/Python/3.7/site-packages/matplotlib/axes/_axes.py", line 6559, in hist + cbook._check_in_list(['left', 'mid', 'right'], align=align) + File "/Library/Python/3.7/site-packages/matplotlib/cbook/__init__.py", line 2145, in _check_in_list + .format(v, k, ', '.join(map(repr, values)))) +ValueError: 'edge' is not a valid value for align; supported values are 'left', 'mid', 'right' +]] + File "", line 7, in + File "", line 2, in +ModuleNotFoundError: No module named 'hist' +]] + File "", line 7, in + File "", line 4, in +TypeError: bar() missing 1 required positional argument: 'height' +]] + File "", line 7, in + File "", line 4, in +TypeError: bar() missing 1 required positional argument: 'height' +]] + File "", line 7, in + File "", line 4, in +TypeError: bar() missing 1 required positional argument: 'height' +]] + File "", line 7, in + File "", line 4, in +TypeError: bar() missing 1 required positional argument: 'height' +]] + File "", line 7, in + File "", line 3, in +TypeError: bar() missing 1 required positional argument: 'height' +]] + File "", line 7, in + File "", line 3, in +TypeError: ba .r() missing 1 required positional argument: 'height' +]] + File "", line 7, in + File "", line 3, in +TypeError: bar() missing 1 required positional argument: 'height' +]] + File "", line 7, in + File "", line 3, in +NameError: name 'data' is not defined +]] + File "", line 7, in + File "", line 1, in +NameError: name 'plt' is not defined +]] +[[file:./test.png]] diff --git a/module2/exo5/exo5_python_fr.org b/module2/exo5/exo5_python_fr.org index afff5e05bdb366128291b42847d9bd44d1f8bf04..588159da4fcac4e1e66c55de0cd8e02449d32bc2 100644 --- a/module2/exo5/exo5_python_fr.org +++ b/module2/exo5/exo5_python_fr.org @@ -171,7 +171,7 @@ La température prévue le jour du décollage est de 31°F. Essayons d'estimer la probabilité de dysfonctionnement des joints toriques à cette température à partir du modèle que nous venons de construire: -#+begin_src python :results output file :var matplot_lib_filename="proba_estimate_python.png" :exports both :session *python* +#+begin_src python :results output file :var matplot_lib_filename="proba_estimate_python.png" :exports both :session *python* import matplotlib.pyplot as plt data_pred = pd.DataFrame({'Temperature': np.linspace(start=30, stop=90, num=121), 'Intercept': 1}) diff --git a/module2/exo5/freq_temp_python.png b/module2/exo5/freq_temp_python.png index 93cb9e626441d23f6dff59ed252d7b14eb37abdb..60368ff57389cd4cfc5aa439d8dd53685bb9fe79 100644 Binary files a/module2/exo5/freq_temp_python.png and b/module2/exo5/freq_temp_python.png differ diff --git a/module2/exo5/proba_estimate_python.png b/module2/exo5/proba_estimate_python.png index 77fc4b275dd8815b1ab91cd3b67b1beb93e00748..046603e2dde7c4ad7cff92729121c427f3b5e393 100644 Binary files a/module2/exo5/proba_estimate_python.png and b/module2/exo5/proba_estimate_python.png differ diff --git a/module3/exo1/analyse-syndrome-grippal.org b/module3/exo1/analyse-syndrome-grippal.org index 1720b70df3a93009c79592b68d1dcf57a53f6341..6430b78f8162df4aba5a4f307a0db671211ea98e 100644 --- a/module3/exo1/analyse-syndrome-grippal.org +++ b/module3/exo1/analyse-syndrome-grippal.org @@ -27,11 +27,18 @@ if sys.version_info.major < 3 or sys.version_info.minor < 6: print("Veuillez utiliser Python 3.6 (ou plus) !") #+END_SRC +#+RESULTS: +: Python 3.8.2 (default, Mar 11 2020, 00:29:50) +: [Clang 11.0.0 (clang-1100.0.33.17)] on darwin +: Type "help", "copyright", "credits" or "license" for more information. + #+BEGIN_SRC emacs-lisp :results output (unless (featurep 'ob-python) (print "Veuillez activer python dans org-babel (org-babel-do-languages) !")) #+END_SRC +#+RESULTS: + ** R 3.4 Nous n'utilisons que des fonctionnalités de base du langage R, une version antérieure devrait suffire. @@ -40,6 +47,14 @@ Nous n'utilisons que des fonctionnalités de base du langage R, une version ant (print "Veuillez activer R dans org-babel (org-babel-do-languages) !")) #+END_SRC +#+RESULTS: + +#+begin_src R :results output graphics :file (org-babel-temp-file "figure" ".png") :exports both :width 600 :height 400 :session *R* +test +#+end_src + +#+RESULTS: + * Préparation des données Les données de l'incidence du syndrome grippal sont disponibles du site Web du [[http://www.sentiweb.fr/][Réseau Sentinelles]]. Nous les récupérons sous forme d'un fichier en format CSV dont chaque ligne correspond à une semaine de la période d'observation. Nous téléchargeons toujours le jeu de données complet (rien d'autre n'est proposé), qui commence en 1984 et se termine avec une semaine récente. L'URL est: @@ -80,6 +95,13 @@ Regardons ce que nous avons obtenu: table[:5] #+END_SRC +#+RESULTS: +| week | indicator | inc | inc_low | inc_up | inc100 | inc100_low | inc100_up | geo_insee | geo_name | +| 202011 | 3 | 101704 | 93652 | 109756 | 154 | 142 | 166 | FR | France | +| 202010 | 3 | 104977 | 96650 | 113304 | 159 | 146 | 172 | FR | France | +| 202009 | 3 | 110696 | 102066 | 119326 | 168 | 155 | 181 | FR | France | +| 202008 | 3 | 143753 | 133984 | 153522 | 218 | 203 | 233 | FR | France | + ** Recherche de données manquantes Il y a malheureusement beaucoup de façon d'indiquer l'absence d'un point de données. Nous testons ici seulement pour la présence de champs vides. Il faudrait aussi rechercher des valeurs non-numériques dans les colonnes à priori numériques. Nous ne le faisons pas ici, mais une vérification ultérieure capterait des telles anomalies. @@ -94,6 +116,9 @@ for row in table: valid_table.append(row) #+END_SRC +#+RESULTS: +: ['198919', '3', '0', '', '', '0', '', '', 'FR', 'France'] + ** Extraction des colonnes utilisées Il y a deux colonnes qui nous intéressent: la première (~"week"~) et la troisième (~"inc"~). Nous vérifions leurs noms dans l'en-tête, que nous effaçons par la suite. Enfin, nous créons un tableau avec les deux colonnes pour le traitement suivant. #+BEGIN_SRC python :results silent @@ -101,7 +126,7 @@ week = [row[0] for row in valid_table] assert week[0] == 'week' del week[0] inc = [row[2] for row in valid_table] -assert inc[0] == 'inc +assert inc[0] == 'inc' del inc[0] data = list(zip(week, inc)) #+END_SRC @@ -111,6 +136,21 @@ Regardons les premières et les dernières lignes. Nous insérons ~None~ pour in [('week', 'inc'), None] + data[:5] + [None] + data[-5:] #+END_SRC +#+RESULTS: +| week | inc | +|--------+--------| +| 202011 | 101704 | +| 202010 | 104977 | +| 202009 | 110696 | +| 202008 | 143753 | +| 202007 | 183610 | +|--------+--------| +| 198448 | 78620 | +| 198447 | 72029 | +| 198446 | 87330 | +| 198445 | 135223 | +| 198444 | 68422 | + ** Vérification Il est toujours prudent de vérifier si les données semblent crédibles. Nous savons que les semaines sont données par six chiffres (quatre pour l'année et deux pour la semaine), et que les incidences sont des nombres entiers positifs. #+BEGIN_SRC python :results output @@ -121,6 +161,8 @@ for week, inc in data: print("Valeur suspecte dans la colonne 'inc': ", (week, inc)) #+END_SRC +#+RESULTS: + Pas de problème ! ** Conversions @@ -140,6 +182,21 @@ str_data = [(str(date), str(inc)) for date, inc in converted_data] [('date', 'inc'), None] + str_data[:5] + [None] + str_data[-5:] #+END_SRC +#+RESULTS: +| date | inc | +|------------+--------| +| 1984-10-29 | 68422 | +| 1984-11-05 | 135223 | +| 1984-11-12 | 87330 | +| 1984-11-19 | 72029 | +| 1984-11-26 | 78620 | +|------------+--------| +| 2020-02-10 | 183610 | +| 2020-02-17 | 143753 | +| 2020-02-24 | 110696 | +| 2020-03-02 | 104977 | +| 2020-03-09 | 101704 | + ** Vérification des dates Nous faisons encore une vérification: nos dates doivent être séparées d'exactement une semaine, sauf autour du point manquant. #+BEGIN_SRC python :results output @@ -149,6 +206,9 @@ for date1, date2 in zip(dates[:-1], dates[1:]): print(f"Il y a {date2-date1} entre {date1} et {date2}") #+END_SRC +#+RESULTS: +: Il y a 14 days, 0:00:00 entre 1989-05-01 et 1989-05-15 + ** Passage Python -> R Nous passons au langage R pour inspecter nos données, parce que l'analyse et la préparation de graphiques sont plus concises en R, sans nécessiter aucune bibliothèque supplémentaire. @@ -164,17 +224,30 @@ data$date <- as.Date(data$date) summary(data) #+END_SRC +#+RESULTS: +: +: date inc +: Min. :1984-10-29 Min. : 0 +: 1st Qu.:1993-09-06 1st Qu.: 5018 +: Median :2002-07-08 Median : 16002 +: Mean :2002-07-07 Mean : 62071 +: 3rd Qu.:2011-05-09 3rd Qu.: 50759 +: Max. :2020-03-09 Max. :1001824 + ** Inspection Regardons enfin à quoi ressemblent nos données ! -#+BEGIN_SRC R :results output graphics :file inc-plot.png + +< plot(data, type="l", xlab="Date", ylab="Incidence hebdomadaire") -#+END_SRC + Un zoom sur les dernières années montre mieux la situation des pics en hiver. Le creux des incidences se trouve en été. #+BEGIN_SRC R :results output graphics :file inc-plot-zoom.png plot(tail(data, 200), type="l", xlab="Date", ylab="Incidence hebdomadaire") #+END_SRC +#+RESULTS: + * Étude de l'incidence annuelle ** Calcul de l'incidence annuelle @@ -201,6 +274,9 @@ inc_annuelle = data.frame(annee = annees, head(inc_annuelle) #+END_SRC +#+RESULTS: +: org_babel_R_eoe + ** Inspection Voici les incidences annuelles en graphique. #+BEGIN_SRC R :results output graphics :file annual-inc-plot.png @@ -213,7 +289,19 @@ Une liste triée par ordre décroissant d'incidence annuelle permet de plus faci head(inc_annuelle[order(-inc_annuelle$incidence),]) #+END_SRC +#+RESULTS: +: Error in head(inc_annuelle[order(-inc_annuelle$incidence), ]) : +: objet 'inc_annuelle' introuvable + Enfin, un histogramme montre bien que les épidémies fortes, qui touchent environ 10% de la population française, sont assez rares: il y en eu trois au cours des 35 dernières années. #+BEGIN_SRC R :results output graphics :file annual-inc-hist.png hist(inc_annuelle$incidence, breaks=10, xlab="Incidence annuelle", ylab="Nb d'observations", main="") #+END_SRC + + +#+NAME: test +#+BEGIN_SRC R :file "test1.png" :results output graphics silent +x <- seq(-pi, pi, 0.1) +plot(x, sin(x)) +#+END_SRC +[[file:test.svg]] diff --git a/module3/exo3/exercice_python_fr.org b/module3/exo3/exercice_python_fr.org index c7157ba42216cf2e1d291112bb351ce48811115c..3343e8c30cca4016a827145e10dd75fb92c37472 100644 --- a/module3/exo3/exercice_python_fr.org +++ b/module3/exo3/exercice_python_fr.org @@ -1,6 +1,6 @@ -#+TITLE: Votre titre -#+AUTHOR: Votre nom -#+DATE: La date du jour +#+TITLE: Sujet 4 : Estimation de la latence et de la capacité d’une connexion à partir de mesures asymétriques +#+AUTHOR: Samuel MEYNARD +#+DATE: <2020-06-06 Sat> #+LANGUAGE: fr # #+PROPERTY: header-args :eval never-export @@ -11,83 +11,124 @@ #+HTML_HEAD: #+HTML_HEAD: -* Quelques explications +* Énoncé +Un modèle simple et fréquemment utilisé pour décrire la performance d'une connexion de réseau consiste à supposer que le temps d'envoi T pour un message dépend principalement de sa taille $S$ (nombre d'octets) et de deux grandeurs propres à la connexion : la latence $L$ (en secondes) et la capacité $C$ (en octets/seconde). La relation entre ces quatre quantités est $T(S) = L + S/C$. Ce modèle néglige un grand nombre de détails. D'une part, $L$ et $C$ dépendent bien sûr du protocole de communication choisi mais aussi dans une certaine mesure de $S$. D'autre part, la mesure de $T(S)$ comporte en général une forte composante aléatoire. Nous nous intéressons ici au temps moyen qu'il faut pour envoyer un message d'une taille donnée. -Ceci est un document org-mode avec quelques exemples de code -python. Une fois ouvert dans emacs, ce document peut aisément être -exporté au format HTML, PDF, et Office. Pour plus de détails sur -org-mode vous pouvez consulter https://orgmode.org/guide/. +Votre tâche est d'estimer $L$ et $C$ à partir d'une série d'observations de $T$ pour des valeurs différentes de $S$. Préparez votre analyse sous forme d'un document computationnel réplicable qui commence avec la lectures des données brutes, disponibles pour deux connexions différentes, qui ont été obtenues avec l'outil ping : +- Le premier jeu de données examine une connexion courte à l'intérieur d'un campus : http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/liglab2.log.gz +- Le deuxième jeu de données mesure la performance d'une connexion vers un site Web éloigné assez populaire et donc chargé : http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/stackoverflow.log.gz -Lorsque vous utiliserez le raccourci =C-c C-e h o=, ce document sera -compilé en html. Tout le code contenu sera ré-exécuté, les résultats -récupérés et inclus dans un document final. Si vous ne souhaitez pas -ré-exécuter tout le code à chaque fois, il vous suffit de supprimer -le # et l'espace qui sont devant le ~#+PROPERTY:~ au début de ce -document. -Comme nous vous l'avons montré dans la vidéo, on inclue du code -python de la façon suivante (et on l'exécute en faisant ~C-c C-c~): +Les deux fichiers contiennent la sortie brute de l'outil ping qui a été exécuté dans une boucle en variant de façon aléatoire la taille du message. Chaque ligne a la forme suivante: -#+begin_src python :results output :exports both -print("Hello world!") -#+end_src +#+BEGIN_SRC +[1421761682.052172] 665 bytes from lig-publig.imag.fr (129.88.11.7): icmp_seq=1 ttl=60 time=22.5 ms +#+END_SRC + +Au début, entre crochet, vous trouvez la date à laquelle la mesure a été prise, exprimée en secondes depuis le 1er janvier 1970. La taille du message en octets est donnée juste après, suivie par le nom de la machine cible et son adresse IP, qui sont normalement identiques pour toutes les lignes à l'intérieur d'un jeu de données. À la fin de la ligne, nous trouvons le temps d'envoi (aller-retour) en millisecondes. Les autres indications, =icmp_seq= et =ttl=, n'ont pas d'importance pour notre analyse. Attention, il peut arriver qu'une ligne soit incomplète et il faut donc vérifier chaque ligne avant d'en extraire des informations ! + +_Votre mission si vous l'acceptez :_ + +1. Commencez par travailler avec le premier jeu de données (liglab2). Représentez graphiquement l'évolution du temps de transmission au cours du temps (éventuellement à différents instants et différentes échelles de temps) pour évaluer la stabilité temporelle du phénomène. Ces variations peuvent-elles être expliquées seulement par la taille des messages ? +2. Représentez le temps de transmission en fonction de la taille des messages. Vous devriez observer une "rupture", une taille à partir de laquelle la nature de la variabilité change. Vous estimerez (graphiquement) cette taille afin de traiter les deux classes de tailles de message séparément. +3. Effectuez une régression linéaire pour chacune des deux classes et évaluez les valeurs de L et de C correspondantes. Vous superposerez le résultat de cette régression linéaire au graphe précédent. +4. (Optionnel) La variabilité est tellement forte et asymétrique que la régression du temps moyen peut être considérée comme peu pertinente. On peut vouloir s'intéresser à caractériser plutôt le plus petit temps de transmission. Une approche possible consiste donc à filtrer le plus petit temps de transmission pour chaque taille de message et à effectuer la régression sur ce sous-ensemble de données. Cela peut également être l'occasion pour ceux qui le souhaitent de se familiariser avec la régression de quantiles (implémentée en R dans la bibliothèque quantreg et en Python dans la bibliothèque statsmodels). +5. Répétez les étapes précédentes avec le second jeu de données (stackoverflow) +6. Déposer dans FUN votre résultat + +* Récupération du 1^er jeu de donnée +** Téléchargement +#+BEGIN_SRC python :session :file step1.txt :results file +from urllib.request import urlretrieve +from os import path +liglab_file = "liglab2.log" +liglab_filegz = liglab_file + ".gz" +url = "http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/liglab2.log.gz" +if not path.exists(liglab_file): + urlretrieve(url, liglab_filegz) +#+END_SRC #+RESULTS: -: Hello world! +[[file:step1.txt]] +** Lecture du fichier +#+BEGIN_SRC python :session :results output +import gzip +f = gzip.open(liglab_filegz) +data = f.read().decode('latin-1').strip().splitlines() +f.close() +#+END_SRC -Voici la même chose, mais avec une session python, donc une -persistance d'un bloc à l'autre (et on l'exécute toujours en faisant -~C-c C-c~). -#+begin_src python :results output :session :exports both -import numpy -x=numpy.linspace(-15,15) -print(x) -#+end_src +#+RESULTS: + +#+BEGIN_SRC python :session :results replace +table = [row.split(' ') for row in data] +cleantable = [] +for row in table: + if len(row) == 10: + cleantable.append(row) +cleantable[:4] +#+END_SRC + +#+RESULTS: +| [1421761682.052172] | 665 | bytes | from | lig-publig.imag.fr | (129.88.11.7): | icmp_seq=1 | ttl=60 | time=22.5 | ms | +| [1421761682.277315] | 1373 | bytes | from | lig-publig.imag.fr | (129.88.11.7): | icmp_seq=1 | ttl=60 | time=21.2 | ms | +| [1421761682.502054] | 262 | bytes | from | lig-publig.imag.fr | (129.88.11.7): | icmp_seq=1 | ttl=60 | time=21.2 | ms | +| [1421761682.729257] | 1107 | bytes | from | lig-publig.imag.fr | (129.88.11.7): | icmp_seq=1 | ttl=60 | time=23.3 | ms | + +#+BEGIN_SRC python :session :results output replace +from datetime import datetime +date = [datetime.utcfromtimestamp(float(row[0][1:-1])) for row in cleantable] +donnee = [int(row[1]) for row in cleantable] +source = [str(row[4]) for row in cleantable] +ip = [str(row[5][1:-1]) for row in cleantable] +ltime = [float(row[8].split('=')[1]) for row in cleantable] + +dataset = list(zip(date,donnee, ltime)) +print(dataset[:4]) +#+END_SRC #+RESULTS: -#+begin_example -[-15. -14.3877551 -13.7755102 -13.16326531 -12.55102041 - -11.93877551 -11.32653061 -10.71428571 -10.10204082 -9.48979592 - -8.87755102 -8.26530612 -7.65306122 -7.04081633 -6.42857143 - -5.81632653 -5.20408163 -4.59183673 -3.97959184 -3.36734694 - -2.75510204 -2.14285714 -1.53061224 -0.91836735 -0.30612245 - 0.30612245 0.91836735 1.53061224 2.14285714 2.75510204 - 3.36734694 3.97959184 4.59183673 5.20408163 5.81632653 - 6.42857143 7.04081633 7.65306122 8.26530612 8.87755102 - 9.48979592 10.10204082 10.71428571 11.32653061 11.93877551 - 12.55102041 13.16326531 13.7755102 14.3877551 15. ] -#+end_example - -Et enfin, voici un exemple de sortie graphique: -#+begin_src python :results output file :session :var matplot_lib_filename="./cosxsx.png" :exports results +: [(datetime.datetime(2015, 1, 20, 13, 48, 2, 52172), 665, 22.5), (datetime.datetime(2015, 1, 20, 13, 48, 2, 277315), 1373, 21.2), (datetime.datetime(2015, 1, 20, 13, 48, 2, 502054), 262, 21.2), (datetime.datetime(2015, 1, 20, 13, 48, 2, 729257), 1107, 23.3)] + +#+BEGIN_SRC python :session :results silent :file test.png +import matplotlib import matplotlib.pyplot as plt +# Create figure and plot space +fig, ax = plt.subplots(figsize=(12, 12)) + +# Add x-axis and y-axis +ax.scatter(date, + ltime, + color='purple') -plt.figure(figsize=(10,5)) -plt.plot(x,numpy.cos(x)/x) -plt.tight_layout() +# Set title and labels for axes +ax.set(xlabel="Date", + ylabel="Latence", + title="Evolution de la latence dans le temps") -plt.savefig(matplot_lib_filename) -print(matplot_lib_filename) -#+end_src +plt.savefig('test.png') +#+END_SRC #+RESULTS: -[[file:./cosxsx.png]] - -Vous remarquerez le paramètre ~:exports results~ qui indique que le code -ne doit pas apparaître dans la version finale du document. Nous vous -recommandons dans le cadre de ce MOOC de ne pas changer ce paramètre -(indiquer ~both~) car l'objectif est que vos analyses de données soient -parfaitement transparentes pour être reproductibles. - -Attention, la figure ainsi générée n'est pas stockée dans le document -org. C'est un fichier ordinaire, ici nommé ~cosxsx.png~. N'oubliez pas -de le committer si vous voulez que votre analyse soit lisible et -compréhensible sur GitLab. - -Enfin, n'oubliez pas que nous vous fournissons dans les ressources de -ce MOOC une configuration avec un certain nombre de raccourcis -claviers permettant de créer rapidement les blocs de code python (en -faisant ~