...
 
Commits (435)
......@@ -9,4 +9,6 @@
*.tex
_minted*
svg-inkscape*
*-svg.pdf
\ No newline at end of file
*-svg.pdf
.Rhistory
.snakemake
image: brospars/pandoc-gitlab-ci:latest
pages:
stage: deploy
script:
- pandoc --version
# - pandoc --help
# - pandoc --list-input-formats # Broken as pandoc dates from 2013 on this image! :(
- bin/pandoc_fixer.pl html_src_files.lst;
- for file in `cat html_src_files.lst | sed 's/#.*//g' `; do
mkdir -p public/`dirname ${file}`;
mv ${file%.*}.html public/`dirname ${file}`/;
done
- cd module2/ressources/; tar zcf rr_org_archive.tgz rr_org/init.el rr_org/journal.org rr_org/init.org ; cd ../.. ; mv module2/ressources/rr_org_archive.tgz public/module2/ressources/
- cd module2/ressources/; tar zcf replicable_article.tgz replicable_article/Makefile replicable_article/article.org replicable_article/biblio.bib ; cd ../.. ; mv module2/ressources/replicable_article.tgz public/module2/ressources/
artifacts:
paths:
- public
only:
- master
Les ressources de cet entrepôt sont, sauf mention contraire, diffusées sous Licence Creative Commons CC-BY 3.0 : Attribution.
Le titulaire des droits autorise toute exploitation de l’œuvre, y compris à des fins commerciales, ainsi que la création d’œuvres dérivées, dont la distribution est également autorisée sans restriction, à condition de l’attribuer à son auteur en citant son nom.
Except otherwise specified, this repository resources are provided under Creative Commons Licence CC-BY 3.0: Attribution.
The licensor permits others to copy, distribute, display, and perform the work. In return, licenses must give the original author credit.
\ No newline at end of file
ressources-md:
for i in module1/ressources module2/ressources module2/slides module3/ressources \
module4/ressources module5/ressources module6/ressources; do \
make -C $$i ressources-md; \
done
%.md: %.org
rm -f $@
LANG=C ; pandoc -s -f org -t gfm -o $@ $^
mv $@ $@.bak
echo '---' > $@
grep -i -e "#+TITLE:" -e "#+AUTHOR:" $^ | sed 's/#+//' >> $@ # -e "#+DATE:" ## echo "DATE: `date '+%B %e, %Y'`" >> $@
git log $^ | grep Date | head -n 1 | sed 's/+.*//' >> $@
sed -i -e 's/TITLE:/title:/i' -e 's/AUTHOR:/author:/i' -e 's/Date:/date:/i' $@
echo "---\\n" >> $@
cat $@.bak >> $@
rm $@.bak
chmod a-wx $@
# %.html: %.org
# emacs -batch $^ --funcall org-html-export-to-html
# sed -i -e 's/<pre /<pre style="padding-left: 30px; background-color: #f6f8fa;" /g' \
# -e 's/<li>/<li style="margin-bottom:0;">/g' \
# -e 's/<ul>/<ul style="margin:0 0;">/g' $@
# mv $@ $@.bak
# html_png_inliner.pl < $@.bak | grep -A $(NLINES) -e '<body>' | grep -B $(NLINES) -e '<div id="postamble" class="status">' | grep -v -e '<body>' -e '<div id="postamble" class="status">' > $@
# rm $@.bak
clean:
rm -f *~
# Ressources du Mooc Recherche reproductible / Reproducible research Mooc resources
[English version below]
Cet entrepôt contient toutes les ressources du Mooc "Recherche reproductible : principes méthodologiques pour une science transparente" au format orgmode ou markdown.
Sur [cette page](https://learninglab.gitlabpages.inria.fr/mooc-rr/mooc-rr-ressources/), vous trouverez les liens vers les pages html générées automatiquement ainsi que les liens vers FUN (session 02)
-----------------------------------------------------------------
This repository contains all the resources of the Mooc "Reproducible Research: Methodological Principles for Transparent Science" in orgmode or markdown format.
On[this page] (https://learninglab.gitlabpages.inria.fr/mooc-rr/mooc-rr-ressources/), you will find links to automatically generated html pages as well as links to FUN (session 02)
\ No newline at end of file
#!/usr/bin/perl -w
use strict;
my($usage) = "Usage: pandox_fixer.pl org_md_files.lst";
($#ARGV==0) or die $usage;
sub pandoc_export {
my($input)=shift(@_);
########### Git date #################
my($gitdate)=`git log --date=short $input | grep Date | head -n 1`;
chomp($gitdate);
$gitdate =~ s/Date: *//g;
$gitdate =~ s/\s*\+.*$//g;
########### Input file ###############
my($type) = "";
my($output) = $input;
if($input =~ /.md$/) {
$type = "gfm";
$output =~ s/.md$/.html/;
} elsif ($input =~ /.org$/) {
$type = "org";
$output =~ s/.org$/.html/;
} else {
die "Usage: pandox_fixer.pl input.md";
}
my($output_temp) = $output."tmp";
########### URL Fixing ###############
my($input_path)=$input;
$input_path =~ s|/[^/]*$||g;
my($raw_path) = "https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/raw/master/".$input_path;
my($raw_path_percent) = $raw_path; $raw_path_percent =~ s/^http/%/g;
my($tree_path) = "https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/tree/master/".$input_path;
my($pages_path) = "https://learninglab.gitlabpages.inria.fr/mooc-rr/mooc-rr-ressources/".$input_path;
my($pages_path_percent) = $pages_path; $pages_path_percent =~ s/^http/%/g;
my($gitlab_origin)= "https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/";
########### Pandoc #################
print "Exporting $input\n";
my($pandoc_output) = `LANG=C ; pandoc -s --mathjax -f $type -t html -o $output_temp $input`;open INPUT, $output_temp or die;
open OUTPUT, "> ".$output or die;
while(defined(my $line=<INPUT>)) {
if($line =~ /<p class="author"/) { next; }
# if($line =~ /<h1 class="title"/) { next; }
if($line =~ /<p class="date"/) { next; }
if($line =~ /<p>.*broken-links:nil/) { next; }
# $line =~ s|https://gitlab.inria.fr/learninglab/|https://learninglab.gitlabpages.inria.fr/|g; ## Not such a good idea!
if($line =~ /<body>/) {
if($output=~ /_fr.html/) {
$line =~ s|<body>|<body>Les <a href='$gitlab_origin/$input'>sources de ce document sont disponibles sur gitlab</a>.|g;
$line .= "<br><i>Version du $gitdate.</i><br><hr/>\n"
} else {
$line =~ s|<body>|<body>The <a href='$gitlab_origin/$input'>source of this document is available on gitlab</a>.|g;
$line .= "<br><i>Last version: $gitdate</i><br><hr/>\n"
}
}
$line =~ s|<span class="smallcaps">TOC</span>||g;
$line =~ s|---</p>|<hr/>|g;
# $line =~ s|Date:.*<br|<i>Date: $gitdate</i><br|g;
# $line =~ s|<p>TITLE:\(.*\)<br|<b>TITLE:$1</b><br|g;
#### Processing links to images, org files, archives, ...
$line =~ s|img src="http|img src="%|g;
$line =~ s|img src="([^%][^"]*)"|img src="$raw_path/$1"|g; # ?inline=false
$line =~ s|img src="%|img src="http|g;
$line =~ s|href="http|href="%|g;
$line =~ s|href="([^%#][^"]*.tgz)"|href="$pages_path_percent/$1"|g;
$line =~ s|href="([^%#][^"]*)"|href="$tree_path/$1"|g; # ?inline=false
$line =~ s|href="(#[^"]*)-"|href="$1"|g;
$line =~ s|href="(#[^"]*)--([^"]*)"|href="$1-$2"|g;
$line =~ s|href="(#[^"]*)--([^"]*)"|href="$1-$2"|g;
$line =~ s|href="(#[^"]*)--([^"]*)"|href="$1-$2"|g;
$line =~ s|href="%|href="http|g;
# if($line =~ /img src="([^%][^"]*)"/) {
# $line = "\t".$line;
# }
#### Changing headers
foreach my $i (4,3,2,1) {
my($j)=$i+1;
$line =~ s|<h$i|<h$j|g;
$line =~ s|</h$i|</h$j|g;
}
print OUTPUT $line;
}
close OUTPUT;
close INPUT;
unlink($output_temp);
}
sub main() {
my($input_list)=shift(@ARGV);
open LIST, $input_list or die;
open INDEX, "> public/index.org" or die;
my($f);
print INDEX "| Gitlab Origin | Pandoc HTML (Gitlab pages) | FUN Outcome |
|---+---+---|\n";
while(defined($f = <LIST>)) {
chomp($f);
if($f =~ /^#/) { warn "Skipping $f"; next;}
if($f =~ /^\s*$/) {
print INDEX "|---+---+---|\n";
next;
}
my($file,$url) = split(/\s*#\s*/,$f);
if($file eq "" || !defined($url)) { warn "Malformed line"; next;}
# print "'$file' --- '$url'\n";
pandoc_export($file);
my($html)=$file; $html=~ s/\.[^\.]*$/.html/g;
my($url_id) = $url; $url_id =~ s|^.*jump_to_id/||g;
print INDEX "| [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/tree/master/$file][$file]] | [[$html]] | [[$url][$url_id]] |\n";
}
print INDEX "|---+---+---|\n";
close INDEX;
close LIST;
my($pandoc_output) = `LANG=C ; pandoc -s -c readtheorg.css -f org -t html -o public/index.html public/index.org`;
}
main()
"","speed","dist"
"1",4,2
"2",4,10
"3",7,4
"4",7,22
"5",8,16
"6",9,10
"7",10,18
"8",10,26
"9",10,34
"10",11,17
"11",11,28
"12",12,14
"13",12,20
"14",12,24
"15",12,28
"16",13,26
"17",13,34
"18",13,34
"19",13,46
"20",14,26
"21",14,36
"22",14,60
"23",14,80
"24",15,20
"25",15,26
"26",15,54
"27",16,32
"28",16,40
"29",17,32
"30",17,40
"31",17,50
"32",18,42
"33",18,56
"34",18,76
"35",18,84
"36",19,36
"37",19,46
"38",19,68
"39",20,32
"40",20,48
"41",20,52
"42",20,56
"43",20,64
"44",22,66
"45",23,54
"46",24,70
"47",24,92
"48",24,93
"49",24,120
"50",25,85
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Notebook Python R\n",
"\n",
"## Import des données dans Python"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Unnamed: 0</th>\n",
" <th>speed</th>\n",
" <th>dist</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>4</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2</td>\n",
" <td>4</td>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3</td>\n",
" <td>7</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>4</td>\n",
" <td>7</td>\n",
" <td>22</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>5</td>\n",
" <td>8</td>\n",
" <td>16</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Unnamed: 0 speed dist\n",
"0 1 4 2\n",
"1 2 4 10\n",
"2 3 7 4\n",
"3 4 7 22\n",
"4 5 8 16"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"# data_url = \"https://forge.scilab.org/index.php/p/rdataset/source/file/master/csv/datasets/cars.csv\"\n",
"data_url = \"cars.csv\"\n",
"df_python = pd.read_csv(data_url)\n",
"df_python.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Supression de la première colonne"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>speed</th>\n",
" <th>dist</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>4</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>4</td>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>7</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>7</td>\n",
" <td>22</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>8</td>\n",
" <td>16</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" speed dist\n",
"0 4 2\n",
"1 4 10\n",
"2 7 4\n",
"3 7 22\n",
"4 8 16"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_python.drop(df_python.columns[[0]], axis=1, inplace=True)\n",
"df_python.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Summary avec Python"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>speed</th>\n",
" <th>dist</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>50.000000</td>\n",
" <td>50.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>15.400000</td>\n",
" <td>42.980000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>5.287644</td>\n",
" <td>25.769377</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>4.000000</td>\n",
" <td>2.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>12.000000</td>\n",
" <td>26.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>15.000000</td>\n",
" <td>36.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>19.000000</td>\n",
" <td>56.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>25.000000</td>\n",
" <td>120.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" speed dist\n",
"count 50.000000 50.000000\n",
"mean 15.400000 42.980000\n",
"std 5.287644 25.769377\n",
"min 4.000000 2.000000\n",
"25% 12.000000 26.000000\n",
"50% 15.000000 36.000000\n",
"75% 19.000000 56.000000\n",
"max 25.000000 120.000000"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_python.describe()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Summary avec R"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"from rpy2.robjects import pandas2ri\n",
"pandas2ri.activate()\n",
"from rpy2.robjects.packages import importr"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" speed dist \n",
"\r\n",
" Min. : 4.0 Min. : 2.00 \n",
"\r\n",
" 1st Qu.:12.0 1st Qu.: 26.00 \n",
"\r\n",
" Median :15.0 Median : 36.00 \n",
"\r\n",
" Mean :15.4 Mean : 42.98 \n",
"\r\n",
" 3rd Qu.:19.0 3rd Qu.: 56.00 \n",
"\r\n",
" Max. :25.0 Max. :120.00 \n",
"\n"
]
}
],
"source": [
"base = importr('base')\n",
"print(base.summary(df_python))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\r\n",
" Numeric \n",
"\r\n",
" mean median var sd valid.n\n",
"\r\n",
"speed 15.40 15 27.96 5.29 50\n",
"\r\n",
"dist 42.98 36 664.06 25.77 50\n",
"\n"
]
}
],
"source": [
"prettyR = importr('prettyR')\n",
"print(prettyR.describe(df_python))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Liens utiles\n",
"\n",
"- http://rpy.sourceforge.net/rpy2/doc-2.4/html/introduction.html\n",
"- https://rpy2.readthedocs.io/en/version_2.8.x/"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Notebook Python SAS\n",
"\n",
"## Import des données dans Python"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Unnamed: 0</th>\n",
" <th>speed</th>\n",
" <th>dist</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>4</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2</td>\n",
" <td>4</td>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3</td>\n",
" <td>7</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>4</td>\n",
" <td>7</td>\n",
" <td>22</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>5</td>\n",
" <td>8</td>\n",
" <td>16</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Unnamed: 0 speed dist\n",
"0 1 4 2\n",
"1 2 4 10\n",
"2 3 7 4\n",
"3 4 7 22\n",
"4 5 8 16"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"# data_url = \"https://forge.scilab.org/index.php/p/rdataset/source/file/master/csv/datasets/cars.csv\"\n",
"data_url = \"cars.csv\"\n",
"df_python = pd.read_csv(data_url)\n",
"df_python.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Supression de la première colonne"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>speed</th>\n",
" <th>dist</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>4</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>4</td>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>7</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>7</td>\n",
" <td>22</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>8</td>\n",
" <td>16</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" speed dist\n",
"0 4 2\n",
"1 4 10\n",
"2 7 4\n",
"3 7 22\n",
"4 8 16"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_python.drop(df_python.columns[[0]], axis=1, inplace=True)\n",
"df_python.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Summary avec Python"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>count</th>\n",
" <th>mean</th>\n",
" <th>std</th>\n",
" <th>min</th>\n",
" <th>25%</th>\n",
" <th>50%</th>\n",
" <th>75%</th>\n",
" <th>max</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>speed</th>\n",
" <td>50.0</td>\n",
" <td>15.40</td>\n",
" <td>5.287644</td>\n",
" <td>4.0</td>\n",
" <td>12.0</td>\n",
" <td>15.0</td>\n",
" <td>19.0</td>\n",
" <td>25.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>dist</th>\n",
" <td>50.0</td>\n",
" <td>42.98</td>\n",
" <td>25.769377</td>\n",
" <td>2.0</td>\n",
" <td>26.0</td>\n",
" <td>36.0</td>\n",
" <td>56.0</td>\n",
" <td>120.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" count mean std min 25% 50% 75% max\n",
"speed 50.0 15.40 5.287644 4.0 12.0 15.0 19.0 25.0\n",
"dist 50.0 42.98 25.769377 2.0 26.0 36.0 56.0 120.0"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_python.describe().transpose()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Summary avec SAS"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"SAS Connection established. Subprocess id is 4708\n",
"\n"
]
},
{
"data": {
"text/plain": [
"Libref = WORK\n",
"Table = _df\n",
"Dsopts = {}\n",
"Results = Pandas"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import saspy\n",
"session_sas = saspy.SASsession(cfgname='winlocal')\n",
"df_sas = session_sas.df2sd(df_python)\n",
"df_sas"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- La fonction `df2sd()` produit un objet Python, ici `df_sas`, qui contient une table SAS nommée `_df`.\n",
"- `SASPy` fournit des objets Python de haut niveau pour les principales procédures SAS.\n",
"- Toutes les fonctions SAS sont exécutables à l'aide de la commande magique `%%SAS`.\n",
"- On applique les fonctions Python sur l'objet `df_sas` et les fonctions SAS sur l'objet `_df`."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Variable</th>\n",
" <th>N</th>\n",
" <th>NMiss</th>\n",
" <th>Median</th>\n",
" <th>Mean</th>\n",
" <th>StdDev</th>\n",
" <th>Min</th>\n",
" <th>P25</th>\n",
" <th>P50</th>\n",
" <th>P75</th>\n",
" <th>Max</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>speed</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" <td>15</td>\n",
" <td>15.40</td>\n",
" <td>5.287644</td>\n",
" <td>4</td>\n",
" <td>12</td>\n",
" <td>15</td>\n",
" <td>19</td>\n",
" <td>25</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>dist</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" <td>36</td>\n",
" <td>42.98</td>\n",
" <td>25.769377</td>\n",
" <td>2</td>\n",
" <td>26</td>\n",
" <td>36</td>\n",
" <td>56</td>\n",
" <td>120</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Variable N NMiss Median Mean StdDev Min P25 P50 P75 Max\n",
"0 speed 50 0 15 15.40 5.287644 4 12 15 19 25\n",
"1 dist 50 0 36 42.98 25.769377 2 26 36 56 120"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_sas.describe()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<!DOCTYPE html>\r\n",
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n",
"<head>\r\n",
"<meta charset=\"utf-8\"/>\r\n",
"<meta content=\"SAS 9.4\" name=\"generator\"/>\r\n",
"<title>Sortie SAS</title>\r\n",
"<style>\r\n",
"/*<![CDATA[*/\r\n",
".body.c section > table, .body.c section > pre, .body.c div > table,\r\n",
".body.c div > pre, .body.c article > table, .body.c article > pre,\r\n",
".body.j section > table, .body.j section > pre, .body.j div > table,\r\n",
".body.j div > pre, .body.j article > table, .body.j article > pre,\r\n",
".body.c p.note, .body.c p.warning, .body.c p.error, .body.c p.fatal,\r\n",
".body.j p.note, .body.j p.warning, .body.j p.error, .body.j p.fatal,\r\n",
".body.c > table.layoutcontainer, .body.j > table.layoutcontainer { margin-left: auto; margin-right: auto }\r\n",
".layoutregion.l table, .layoutregion.l pre, .layoutregion.l p.note,\r\n",
".layoutregion.l p.warning, .layoutregion.l p.error, .layoutregion.l p.fatal { margin-left: 0 }\r\n",
".layoutregion.c table, .layoutregion.c pre, .layoutregion.c p.note,\r\n",
".layoutregion.c p.warning, .layoutregion.c p.error, .layoutregion.c p.fatal { margin-left: auto; margin-right: auto }\r\n",
".layoutregion.r table, .layoutregion.r pre, .layoutregion.r p.note,\r\n",
".layoutregion.r table, .layoutregion.r pre, .layoutregion.r p.note,\r\n",
".layoutregion.r p.warning, .layoutregion.r p.error, .layoutregion.r p.fatal { margin-right: 0 }\r\n",
"article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block }\r\n",
"html{ font-size: 100% }\r\n",
".body { margin: 1em; font-size: 13px; line-height: 1.231 }\r\n",
"sup { position: relative; vertical-align: baseline; bottom: 0.25em; font-size: 0.8em }\r\n",
"sub { position: relative; vertical-align: baseline; top: 0.25em; font-size: 0.8em }\r\n",
"ul, ol { margin: 1em 0; padding: 0 0 0 40px }\r\n",
"dd { margin: 0 0 0 40px }\r\n",
"nav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0 }\r\n",
"img { border: 0; vertical-align: middle }\r\n",
"svg:not(:root) { overflow: hidden }\r\n",
"figure { margin: 0 }\r\n",
"table { border-collapse: collapse; border-spacing: 0 }\r\n",
".layoutcontainer { border-collapse: separate; border-spacing: 0 }\r\n",
"p { margin-top: 0; text-align: left }\r\n",
"span { text-align: left }\r\n",
"table { margin-bottom: 1em }\r\n",
"td, th { text-align: left; padding: 3px 6px; vertical-align: top }\r\n",
"td[class$=\"fixed\"], th[class$=\"fixed\"] { white-space: pre }\r\n",
"section, article { padding-top: 1px; padding-bottom: 8px }\r\n",
"hr.pagebreak { height: 0px; border: 0; border-bottom: 1px solid #c0c0c0; margin: 1em 0 }\r\n",
".stacked-value { text-align: left; display: block }\r\n",
".stacked-cell > .stacked-value, td.data > td.data, th.data > td.data, th.data > th.data, td.data > th.data, th.header > th.header { border: 0 }\r\n",
".stacked-cell > div.data { border-width: 0 }\r\n",
".systitleandfootercontainer { white-space: nowrap; margin-bottom: 1em }\r\n",
".systitleandfootercontainer > p { margin: 0 }\r\n",
".systitleandfootercontainer > p > span { display: inline-block; width: 100%; white-space: normal }\r\n",
".batch { display: table }\r\n",
".toc { display: none }\r\n",
".proc_note_group, .proc_title_group { margin-bottom: 1em }\r\n",
"p.proctitle { margin: 0 }\r\n",
"p.note, p.warning, p.error, p.fatal { display: table }\r\n",
".notebanner, .warnbanner, .errorbanner, .fatalbanner,\r\n",
".notecontent, .warncontent, .errorcontent, .fatalcontent { display: table-cell; padding: 0.5em }\r\n",
".notebanner, .warnbanner, .errorbanner, .fatalbanner { padding-right: 0 }\r\n",
".body > div > ol li { text-align: left }\r\n",
".c { text-align: center }\r\n",
".r { text-align: right }\r\n",
".l { text-align: left }\r\n",
".j { text-align: justify }\r\n",
".d { text-align: right }\r\n",
".b { vertical-align: bottom }\r\n",
".m { vertical-align: middle }\r\n",
".t { vertical-align: top }\r\n",
".aftercaption {\r\n",
" background-color: #fafbfe;\r\n",
" border-spacing: 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
" padding-top: 4pt;\r\n",
"}\r\n",
".batch > colgroup {\r\n",
" border-left: 1px solid #c1c1c1;\r\n",
" border-right: 1px solid #c1c1c1;\r\n",
"}\r\n",
".batch > tbody, .batch > thead, .batch > tfoot {\r\n",
" border-top: 1px solid #c1c1c1;\r\n",
" border-bottom: 1px solid #c1c1c1;\r\n",
"}\r\n",
".batch { border: hidden; }\r\n",
".batch {\r\n",
" background-color: #fafbfe;\r\n",
" border: 1px solid #c1c1c1;\r\n",
" border-collapse: separate;\r\n",
" border-spacing: 1px;\r\n",
" color: #000000;\r\n",
" font-family: 'SAS Monospace', 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" padding: 7px;\r\n",
" }\r\n",
".beforecaption {\r\n",
" background-color: #fafbfe;\r\n",
" border-spacing: 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".body {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" margin-left: 8px;\r\n",
" margin-right: 8px;\r\n",
"}\r\n",
".bodydate {\r\n",
" background-color: #fafbfe;\r\n",
" border-spacing: 0;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" text-align: right;\r\n",
" vertical-align: top;\r\n",
" width: 100%;\r\n",
"}\r\n",
".bycontentfolder {\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: none;\r\n",
" margin-left: 6pt;\r\n",
"}\r\n",
".byline {\r\n",
" background-color: #fafbfe;\r\n",
" border-spacing: 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".bylinecontainer > col, .bylinecontainer > colgroup > col, .bylinecontainer > colgroup, .bylinecontainer > tr, .bylinecontainer > * > tr, .bylinecontainer > thead, .bylinecontainer > tbody, .bylinecontainer > tfoot { border: none; }\r\n",
".bylinecontainer {\r\n",
" background-color: #fafbfe;\r\n",
" border: none;\r\n",
" border-spacing: 1px;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" width: 100%;\r\n",
"}\r\n",
".caption {\r\n",
" background-color: #fafbfe;\r\n",
" border-spacing: 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".cell, .container {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".contentfolder, .contentitem {\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: none;\r\n",
" margin-left: 6pt;\r\n",
"}\r\n",
".contentproclabel, .contentprocname {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".contents {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: decimal;\r\n",
" margin-left: 8px;\r\n",
" margin-right: 8px;\r\n",
"}\r\n",
".contentsdate {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" width: 100%;\r\n",
"}\r\n",
".contenttitle {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".continued {\r\n",
" background-color: #fafbfe;\r\n",
" border-spacing: 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
" width: 100%;\r\n",
"}\r\n",
".data, .dataemphasis {\r\n",
" background-color: #ffffff;\r\n",
" border-color: #c1c1c1;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".dataemphasisfixed {\r\n",
" background-color: #ffffff;\r\n",
" border-color: #c1c1c1;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".dataempty {\r\n",
" background-color: #ffffff;\r\n",
" border-color: #c1c1c1;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".datafixed {\r\n",
" background-color: #ffffff;\r\n",
" border-color: #c1c1c1;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" font-family: 'Courier New', Courier;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".datastrong {\r\n",
" background-color: #ffffff;\r\n",
" border-color: #c1c1c1;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".datastrongfixed {\r\n",
" background-color: #ffffff;\r\n",
" border-color: #c1c1c1;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #000000;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".date {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" width: 100%;\r\n",
"}\r\n",
".document {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".errorbanner {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".errorcontent {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".errorcontentfixed {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".extendedpage {\r\n",
" background-color: #fafbfe;\r\n",
" border-style: solid;\r\n",
" border-width: 1pt;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: normal;\r\n",
" text-align: center;\r\n",
"}\r\n",
".fatalbanner {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".fatalcontent {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".fatalcontentfixed {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".folderaction {\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: none;\r\n",
" margin-left: 6pt;\r\n",
"}\r\n",
".footer {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".footeremphasis {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".footeremphasisfixed {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".footerempty {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".footerfixed {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".footerstrong {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".footerstrongfixed {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".frame {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".graph > colgroup {\r\n",
" border-left: 1px solid #c1c1c1;\r\n",
" border-right: 1px solid #c1c1c1;\r\n",
"}\r\n",
".graph > tbody, .graph > thead, .graph > tfoot {\r\n",
" border-top: 1px solid #c1c1c1;\r\n",
" border-bottom: 1px solid #c1c1c1;\r\n",
"}\r\n",
".graph { border: hidden; }\r\n",
".graph {\r\n",
" background-color: #fafbfe;\r\n",
" border: 1px solid #c1c1c1;\r\n",
" border-collapse: separate;\r\n",
" border-spacing: 1px;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" }\r\n",
".header {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".headeremphasis {\r\n",
" background-color: #d8dbd3;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".headeremphasisfixed {\r\n",
" background-color: #d8dbd3;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #000000;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".headerempty {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".headerfixed {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".headersandfooters {\r\n",
" background-color: #edf2f9;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".headerstrong {\r\n",
" background-color: #d8dbd3;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".headerstrongfixed {\r\n",
" background-color: #d8dbd3;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #000000;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".index {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".indexaction, .indexitem {\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: none;\r\n",
" margin-left: 6pt;\r\n",
"}\r\n",
".indexprocname {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".indextitle {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".layoutcontainer, .layoutregion {\r\n",
" border-width: 0;\r\n",
" border-spacing: 30px;\r\n",
"}\r\n",
".linecontent {\r\n",
" background-color: #fafbfe;\r\n",
" border-color: #c1c1c1;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".list {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: disc;\r\n",
"}\r\n",
".list10 {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: square;\r\n",
"}\r\n",
".list2 {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: circle;\r\n",
"}\r\n",
".list3, .list4, .list5, .list6, .list7, .list8, .list9 {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: square;\r\n",
"}\r\n",
".listitem {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: disc;\r\n",
"}\r\n",
".listitem10 {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: square;\r\n",
"}\r\n",
".listitem2 {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: circle;\r\n",
"}\r\n",
".listitem3, .listitem4, .listitem5, .listitem6, .listitem7, .listitem8, .listitem9 {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: square;\r\n",
"}\r\n",
".note {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".notebanner {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".notecontent {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".notecontentfixed {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".output > colgroup {\r\n",
" border-left: 1px solid #c1c1c1;\r\n",
" border-right: 1px solid #c1c1c1;\r\n",
"}\r\n",
".output > tbody, .output > thead, .output > tfoot {\r\n",
" border-top: 1px solid #c1c1c1;\r\n",
" border-bottom: 1px solid #c1c1c1;\r\n",
"}\r\n",
".output { border: hidden; }\r\n",
".output {\r\n",
" background-color: #fafbfe;\r\n",
" border: 1px solid #c1c1c1;\r\n",
" border-collapse: separate;\r\n",
" border-spacing: 1px;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" }\r\n",
".pageno {\r\n",
" background-color: #fafbfe;\r\n",
" border-spacing: 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
" text-align: right;\r\n",
" vertical-align: top;\r\n",
"}\r\n",
".pages {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: decimal;\r\n",
" margin-left: 8px;\r\n",
" margin-right: 8px;\r\n",
"}\r\n",
".pagesdate {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" width: 100%;\r\n",
"}\r\n",
".pagesitem {\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" list-style-type: none;\r\n",
" margin-left: 6pt;\r\n",
"}\r\n",
".pagesproclabel, .pagesprocname {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".pagestitle {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".paragraph {\r\n",
" background-color: #fafbfe;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".parskip > col, .parskip > colgroup > col, .parskip > colgroup, .parskip > tr, .parskip > * > tr, .parskip > thead, .parskip > tbody, .parskip > tfoot { border: none; }\r\n",
".parskip {\r\n",
" border: none;\r\n",
" border-spacing: 0;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
" }\r\n",
".prepage {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" text-align: left;\r\n",
"}\r\n",
".proctitle {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".proctitlefixed {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".rowfooter {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".rowfooteremphasis {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".rowfooteremphasisfixed {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".rowfooterempty {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".rowfooterfixed {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".rowfooterstrong {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".rowfooterstrongfixed {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".rowheader {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".rowheaderemphasis {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".rowheaderemphasisfixed {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: italic;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".rowheaderempty {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".rowheaderfixed {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".rowheaderstrong {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".rowheaderstrongfixed {\r\n",
" background-color: #edf2f9;\r\n",
" border-color: #b0b7bb;\r\n",
" border-style: solid;\r\n",
" border-width: 0 1px 1px 0;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier, monospace;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".systemfooter, .systemfooter10, .systemfooter2, .systemfooter3, .systemfooter4, .systemfooter5, .systemfooter6, .systemfooter7, .systemfooter8, .systemfooter9 {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".systemtitle, .systemtitle10, .systemtitle2, .systemtitle3, .systemtitle4, .systemtitle5, .systemtitle6, .systemtitle7, .systemtitle8, .systemtitle9 {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: small;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".systitleandfootercontainer > col, .systitleandfootercontainer > colgroup > col, .systitleandfootercontainer > colgroup, .systitleandfootercontainer > tr, .systitleandfootercontainer > * > tr, .systitleandfootercontainer > thead, .systitleandfootercontainer > tbody, .systitleandfootercontainer > tfoot { border: none; }\r\n",
".systitleandfootercontainer {\r\n",
" background-color: #fafbfe;\r\n",
" border: none;\r\n",
" border-spacing: 1px;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" width: 100%;\r\n",
"}\r\n",
".table > col, .table > colgroup > col {\r\n",
" border-left: 1px solid #c1c1c1;\r\n",
" border-right: 0 solid #c1c1c1;\r\n",
"}\r\n",
".table > tr, .table > * > tr {\r\n",
" border-top: 1px solid #c1c1c1;\r\n",
" border-bottom: 0 solid #c1c1c1;\r\n",
"}\r\n",
".table { border: hidden; }\r\n",
".table {\r\n",
" border-color: #c1c1c1;\r\n",
" border-style: solid;\r\n",
" border-width: 1px 0 0 1px;\r\n",
" border-collapse: collapse;\r\n",
" border-spacing: 0;\r\n",
" }\r\n",
".titleandnotecontainer > col, .titleandnotecontainer > colgroup > col, .titleandnotecontainer > colgroup, .titleandnotecontainer > tr, .titleandnotecontainer > * > tr, .titleandnotecontainer > thead, .titleandnotecontainer > tbody, .titleandnotecontainer > tfoot { border: none; }\r\n",
".titleandnotecontainer {\r\n",
" background-color: #fafbfe;\r\n",
" border: none;\r\n",
" border-spacing: 1px;\r\n",
" color: #000000;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
" width: 100%;\r\n",
"}\r\n",
".titlesandfooters {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".usertext {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".warnbanner {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: bold;\r\n",
"}\r\n",
".warncontent {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: Arial, 'Albany AMT', Helvetica, Helv;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
".warncontentfixed {\r\n",
" background-color: #fafbfe;\r\n",
" color: #112277;\r\n",
" font-family: 'Courier New', Courier;\r\n",
" font-size: normal;\r\n",
" font-style: normal;\r\n",
" font-weight: normal;\r\n",
"}\r\n",
"/*]]>*/\r\n",
"</style>\r\n",
"</head>\r\n",
"<body class=\"l body\">\r\n",
"<h1 class=\"body toc\">Sortie SAS</h1>\r\n",
"<section data-name=\"Means\" data-sec-type=\"proc\">\r\n",
"<h1 class=\"contentprocname toc\">La MEANS Procédure</h1>\r\n",
"<article id=\"IDX\">\r\n",
"<h1 class=\"contentitem toc\">Statistiques descriptives</h1>\r\n",
"<table class=\"table\" style=\"border-spacing: 0\">\r\n",
"<colgroup><col/></colgroup><colgroup><col/><col/><col/><col/><col/></colgroup>\r\n",
"<thead>\r\n",
"<tr>\r\n",
"<th class=\"b header\" scope=\"col\">Variable</th>\r\n",
"<th class=\"r b header\" scope=\"col\">N</th>\r\n",
"<th class=\"r b header\" scope=\"col\">Moyenne</th>\r\n",
"<th class=\"r b header\" scope=\"col\">Ecart-type</th>\r\n",
"<th class=\"r b header\" scope=\"col\">Minimum</th>\r\n",
"<th class=\"r b header\" scope=\"col\">Maximum</th>\r\n",
"</tr>\r\n",
"</thead>\r\n",
"<tbody>\r\n",
"<tr>\r\n",
"<th class=\"data\">\r\n",
"<div class=\"stacked-cell\">\r\n",
"<div>speed</div>\r\n",
"<div>dist</div>\r\n",
"</div>\r\n",
"</th>\r\n",
"<td class=\"r data\">\r\n",
"<div class=\"stacked-cell\">\r\n",
"<div>50</div>\r\n",
"<div>50</div>\r\n",
"</div>\r\n",
"</td>\r\n",
"<td class=\"r data\">\r\n",
"<div class=\"stacked-cell\">\r\n",
"<div>15.40</div>\r\n",
"<div>42.98</div>\r\n",
"</div>\r\n",
"</td>\r\n",
"<td class=\"r data\">\r\n",
"<div class=\"stacked-cell\">\r\n",
"<div>5.29</div>\r\n",
"<div>25.77</div>\r\n",
"</div>\r\n",
"</td>\r\n",
"<td class=\"r data\">\r\n",
"<div class=\"stacked-cell\">\r\n",
"<div>4.00</div>\r\n",
"<div>2.00</div>\r\n",
"</div>\r\n",
"</td>\r\n",
"<td class=\"r data\">\r\n",
"<div class=\"stacked-cell\">\r\n",
"<div>25.00</div>\r\n",
"<div>120.00</div>\r\n",
"</div>\r\n",
"</td>\r\n",
"</tr>\r\n",
"</tbody>\r\n",
"</table>\r\n",
"</article>\r\n",
"</section>\r\n",
"</body>\r\n",
"</html>\r\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%SAS session_sas\n",
"ods title;\n",
"ods noproctitle;\n",
"proc means data=_df maxdec=2;\n",
"run;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Liens utiles\n",
"\n",
"**Code SAS dans notebook Jupyter :**\n",
"\n",
"- https://blogs.sas.com/content/sasdummy/2016/04/24/how-to-run-sas-programs-in-jupyter-notebook/\n",
"- https://blogs.sas.com/content/sasdummy/2017/04/08/python-to-sas-saspy/\n",
"- https://sassoftware.github.io/saspy/\n",
"\n",
"**Export vers pdf :**\n",
"\n",
"- https://github.com/sassoftware/sas_kernel/issues/13\n",
"- https://stackoverflow.com/questions/43965823/convert-notebook-generated-html-snippet-to-latex-and-pdf\n",
"- https://github.com/jupyter/nbconvert/issues/474\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
\ No newline at end of file
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Notebook R"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
" speed dist \n",
" Min. : 4.0 Min. : 2.00 \n",
" 1st Qu.:12.0 1st Qu.: 26.00 \n",
" Median :15.0 Median : 36.00 \n",
" Mean :15.4 Mean : 42.98 \n",
" 3rd Qu.:19.0 3rd Qu.: 56.00 \n",
" Max. :25.0 Max. :120.00 "
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"summary(cars)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\nGMU0FVKti2PVToxiWgqp4u2aaidGIW2FBJUSEgQICQKEBAFCggAhQYCQIEBIECAkCBASBAgJ\nAoQEAUKCACFBgJAgQEgQICQIEBIECAkChAQBQvoc0/cv4XZCeh/Rd9TiHkI6H1FI3EhI3wZU\nErcR0rcBhcRthPRtQCFxGyGdj6gjbiSk9xGt2nEPIX2OKSNuJyQIaCskzxpUqqWQXMdQraZC\nKjU8/FZDIdnroV5CggAhQUBDIblGol5NhWTVjlq1FJJ9JKrVVkhQqaIhvTyuuqPV+mWoIWAU\nBUPaL7ovy0GGgJEUDGnd9c/b06Pdpu/WQwwBIykYUt9tPx9vu36IIWAkBUP6tuL29/Jbd+7G\nIWAknpEgoOw10mZ3euQaiakpufy9PHvtttgPMgSMo+w+0vq0j9SvHu0jMS3ubIAAIUGAkCBA\nSBAgJAgQEgQICQKEBAGVhgSNueGrPB9OSq1Tq3Ve1U5sFvOq9YM81Du1WudV7cRmMa9aP8hD\nvVOrdV7VTmwW86r1gzzUO7Va51XtxGYxr1o/yEO9U6t1XtVObBbzqvWDPNQ7tVrnVe3EZjGv\nWj/IQ71Tq3Ve1U5sFvOq9YM81Du1WudV7cRmMa9aP8hDvVOrdV7VTmwW86r1gzzUO7Va51Xt\nxGYxr1o/yEO9U6t1XtVObBbzqvWDPNQ7tVrnVe3EZjGvWj9IaIqQIEBIECAkCBASBAgJAoQE\nAUKCACFBgJAgQEgQICQIEBIECAkChAQBQoKASkO6+XuZD+rpY0LrvuvX+1Hn8s3HxOo6bU+L\nz7NU1Qn7mlfwfNVy0r/b1vUV8W77MaHlaXKLcWdz5mNidZ229Wku/fErtqoT9jWv5Pmq5KT/\nYdutxp7C37b9+yl/6frt8XcvI0/ow+fEqjpt2+5hf3yufKjshJ3NK3m+6gzpqXscewp/eeqW\n71+v627z+utzLXP8mlhVp231Nqfj1Ko6YWfzSp6vWkN6GnsKf+nWh/ev11W3O1T0z//XxKo8\nbV11J+zkLaTc+aozpFW3eXi9IBx7Gt9sDx9fr9//M7qviVV42vbdsroTdnSaV/J8VfSxnVm9\nXQQux57HH+oM6XAWUnWn7en4qq6+E/Y2r+T5quhjO9N1z6//aKxre6VSe0j1nbZdf3w5V98J\n+5hX7nzV87H9bV/LgumH2kN6U9Fp2/enf+2rO2Hv83r/TeR8VfOx/Us9Z/7N+3z62r4u/phK\nPRNbvn2JVnfClt/Sicyrmo/tX+o582++rdrtKlqEqjOk3WK5Oz2o7IR9zuvdhEPqu+N+eDVn\n/sP7GX88bYtsunqWxz6fKms6bZvPq/i6TtjXvJLnq86Q1sdzvn/bx6tIpXc2fE6sqtO2+1oN\nq+qEnc0reb7qDGnfn9Yl6/gX7MvHa4BFbavM7xOr6rQ9dF93stV0ws7mlTxfdYb0+s9E3y3q\nWcV99xHS/nQz87hz+eZ8YrWctu4spJpO2J/zCp2vSkOCtggJAoQEAUKCACFBgJAgQEgQICQI\nEBIECAkChAQBQoIAIUGAkCBASBAgJAgQEgQICQKEBAFCggAhQYCQIEBIECAkCBASBAgJAoQE\nAUKCACFBgJAgQEgQICQIEBIECGl6avmp5rPinE+PkEbgnE+PkEbgnE+PkEbgnFdvs+y65eZw\nCmT9+cPBnxZd//TXw3XfrYU0Bue8dk9vP8z+6RjS4/HR8vh/V92/Hi6Pj1ZCGoFzXru+2x4O\nz93iGFK/PWz77vn1Wapb7g/7Zbf59vD5/Q/4pJbnnNeuOyZy9mjTrY7PQvvXh/u/Hr6c/oBP\nannOee3Wry/Wttvjo/dAjv/pPvzx8HD25yjJOa/e4+trta7fCalqznkDNuvF2zXS6XdnyXz8\n9vtDIY3AOW/DWz1vl0APx6uhjwunvx++CGkEznntFsdVum+rdh/rc4en4wrD2cONVbvROOe1\ne367Ano5hvS2T3T8v6dHpyun84enLaUHIY3AOa/e6c6G44u610BW3eLrdobuYffnw0d3NozE\nOW+HQCrmc9MOIVXM56YdQqqYz007hFQxnxsIEBIECAkChAQBQoIAIUGAkCBASBAgJAgQEgQI\nCQKEBAFCggAhQYCQIEBIECAkCBASBAgJAoQEAUKCACFBgJAgQEgQICQIEBIECAkC/gNzeDUu\n0A6vdAAAAABJRU5ErkJggg==",
"text/plain": [
"plot without title"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot(cars)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "R",
"language": "R",
"name": "ir"
},
"language_info": {
"codemirror_mode": "r",
"file_extension": ".r",
"mimetype": "text/x-r-source",
"name": "R",
"pygments_lexer": "r",
"version": "3.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<h3>Hello</h3>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from IPython.display import display, HTML\n",
"display(HTML('<h3>Hello</h3>'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Liens utiles :\n",
"\n",
"- https://stackoverflow.com/questions/43965823/convert-notebook-generated-html-snippet-to-latex-and-pdf\n",
"- https://github.com/jupyter/nbconvert/issues/474"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
SASmarkdown notebook
====================
Reference manual
================
[SASmarkdown.pdf](https://cran.r-project.org/web/packages/SASmarkdown/SASmarkdown.pdf)
Configuration
=============
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
require(SASmarkdown)
saspath <- "C:/Program Files/SASHome/SASFoundation/9.4/sas.exe"
sasopts <- "-nosplash -ls 75"
knitr::opts_chunk$set(engine='sas', engine.path=saspath,
engine.opts=sasopts, comment="")
```
Listing output
==============
```{r, engine='sas', collectcode=TRUE, error=FALSE}
proc means data=sashelp.class;
run;
ods listing gpath='D:\figures';
ods graphics / imagename="fig" imagefmt=png;
title 'Student Weight by Student Height';
proc sgplot data=sashelp.class noautolegend;
pbspline y=weight x=height;
run;
```
Procédure MEANS
Variable N Moyenne Ecart-type Minimum Maximum
-------------------------------------------------------------------------
Age 19 13.3157895 1.4926722 11.0000000 16.0000000
Height 19 62.3368421 5.1270752 51.3000000 72.0000000
Weight 19 100.0263158 22.7739335 50.5000000 150.0000000
-------------------------------------------------------------------------
`![figure](D:\figures\fig.png)`
![figure](images/fig.png)
HTML output (vue du fichier pdf)
===========
```{r, engine='sashtml', collectcode=TRUE, error=FALSE}
proc means data=sashelp.class;
run;
```
Tableau mal converti en pdf
Variable
N
Moyenne
Ecart-type
Minimum
Maximum
Age
Height
Weight
19
19
19
13.3157895
62.3368421
100.0263158
1.4926722
5.1270752
22.7739335
11.0000000
51.3000000
50.5000000
16.0000000
72.0000000
150.0000000
```{r, engine='sashtml', echo=FALSE, collectcode=TRUE, error=FALSE}
title 'Student Weight by Student Height';
proc sgplot data=sashelp.class noautolegend;
pbspline y=weight x=height;
run;
```
Pas de sortie graphique dans le fichier pdf.
\ No newline at end of file
1. [Installation et configuration des différents outils](#1-installation-et-configuration-des-diff%C3%A9rents-outils)
1. [Installer et configurer Emacs](#11-installer-et-configurer-emacs)
2. [Ajouter les chemins de R et Python dans dans la variable PATH de Windows](#12-ajouter-les-chemins-de-r-et-python-dans-dans-la-variable-path-de-windows)
3. [Installer et configurer matplotlib (librairie graphique Python)](#13-installer-et-configurer-matplotlib-librairie-graphique-python)
2. [Utilisation d'Emacs](#2-utilisation-demacs)
1. [Exécuter des commandes dos](#21-exécuter-des-commandes-dos)
2. [Exécuter du code R](#22-exécuter-du-code-r)
3. [Exécuter du code Python](#23-exécuter-du-code-python)
4. [Écrire dans le journal](#24-écrire-dans-le-journal)
# 1 Installation et configuration des différents outils
## 1.1 Installer et configurer Emacs
- Installer [Emacs modifié pour Windows](https://vigou3.github.io/emacs-modified-windows/)
- version 26.1 pour Windows 64 bits
- version 25.2 pour Windows 32 bits
- Télécharger le fichier [rr_org_archive.tgz](https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/raw/master/module2/ressources/rr_org_archive.tgz)
*NB : Avec 7z il faut décompresser l'archive deux fois : une première fois crée une archive `rr_org_archive.tar` et une deuxième fois crée un dossier `rr_org` contenant les fichiers `init.el` et `journal.org`.*
- Lancer Emacs
![emacs](documents/tuto_emacs_windows/images/emacs.png)
- Emacs crée le répertoire `C:\Users\***\.emacs.d`
*NB : Le répertoire est créé au premier lancement d'Emacs.*
- Placer le fichier `init.el` dedans
- Lancer Emacs
![scratch](documents/tuto_emacs_windows/images/scratch.png)
- Exécuter la commande suivante pour installer `htmlize`
```
M-x package-install RET htmlize RET
```
- Créer un dossier `C:\Users\***\org` dans l'explorateur Windows
- Placer le fichier `journal.org` dedans
---
## 1.2 Ajouter les chemins de R et Python dans dans la variable PATH de Windows
La façon de procéder est très bien expliquée [ici](http://sametmax.com/ajouter-un-chemin-a-la-variable-denvironnement-path-sous-windows/).
---
## 1.3 Installer et configurer matplotlib (librairie graphique Python)
- Installer la librairie `matplotlib`
- Ouvrir une invite de commande dos
- Exécuter la commande suivante
```
python -m pip install -U matplotlib
```
![install_matplotlib](documents/tuto_emacs_windows/images/install_matplotlib.png)
- Désactiver les plots interactifs dans matplotlib
Pour ce faire, il faut d'abord savoir où se trouve le fichier de configuration de matplotlib sous Windows.
Exécuter le code suivant sous Python
```
import matplotlib
matplotlib.matplotlib_fname()
```
![matplotlib](documents/tuto_emacs_windows/images/matplotlib.png)
Ouvrir le fichier `matplotlibrc` et ajouter un `#` devant la ligne qui commence par `backend`, ce qui correspond à utiliser la valeur par défaut `Agg`
---
## 1.4 Installer MiKTeX
Télécharger et installer [MiKTeX](https://miktex.org/download) en choisissant le bon système d'exploitation.
Vous serez amené à installer différents packages lors du premier export pdf.
---
---
# 2 Utilisation d'Emacs
## 2.1 Exécuter des commandes dos
- Lancer Emacs
- Créer un fichier toto.org dans l'explorateur Windows
- Ouvrir le fichier toto.org dans Emacs et saisir `<b` + `tab`.
![shell](documents/tuto_emacs_windows/images/shell.png)
- Le raccourci `C-g` permet de sortir d'une commande
---
## 2.2 Exécuter du code R
- Le raccourci `<r` + `tab` permet d'exécuter une commande R
![commandeR1](documents/tuto_emacs_windows/images/commandeR1.png)
Emacs demande le dossier de démarrage. Garder le dossier par défaut (`Entrée`)
![commandeR2](documents/tuto_emacs_windows/images/commandeR2.png)
- Le raccourci `<R` + `tab` permet d'exécuter une commande graphique R
(org-babel-temp-file \"figure\" \".png\") génère un nom de fichier temporaire.
Il faut indiquer un nom de fichier pour que l'image soit chargée lors de la réouverture du fichier Emacs.
![graphiqueR](documents/tuto_emacs_windows/images/graphiqueR.png)
Remarque : Il peut être pratique de remplacer `(org-babel-temp-file \"figure\" \".png\")` par `"D:/temp/figure.png\"` dans dans le fichier `init.el` (raccourci `<R` et `<PP`).
---
## 2.3 Exécuter du code Python
- Voir la page [Python Source Code Blocks in Org Mode](https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-python.html)
- Le raccourci `<p` + `tab` permet d'exécuter du code Python en mode "non-session"
![python1](documents/tuto_emacs_windows/images/python1.png)
- Le raccourci `<P` + `tab` permet d'exécuter du code Python en mode "session" pour conserver les valeurs d'un bloc de code à l'autre.
![python2](documents/tuto_emacs_windows/images/python2.png)
- Le raccourci `<PP` + `tab` permet d'exécuter un graphique Python
![python4](documents/tuto_emacs_windows/images/python4.png)
- Si cette commande échoue, essayer de mettre la librairie `numpy` à jour
Exécuter le code suivant dans une invite de commande dos
```
python -m pip install -U numpy
```
---
## 2.4 Écrire dans le journal
- Ouvrir le fichier `journal.org`
- Le raccourci `C-c c` ouvre un menu demandant si on veut écrire dans la todo list ou dans le journal
![ctrl_c_c](documents/tuto_emacs_windows/images/ctrl_c_c.png)
- On appuie sur `j` pour écrire dans le journal. Un mini buffer est ouvert et Emacs modifie le fichier `journal.org` pour créer une entrée à la bonne date. On peut commencer à écrire dans le journal.
![org_mode](documents/tuto_emacs_windows/images/org_mode.png)
`C-c C-c` pour enregistrer les modifications.
- La combinaison `Alt`+ `flèche gauche` ou `flèche droite` permet de décaler les puces à gauche ou à droite.
- Penser à enregistrer avant de quitter !
# Configurer Gitlab
- Accéder à [Gitlab](https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/xblock/block-v1:inria+41016+session01bis+type@lti+block@05a0ce425f1741e5bee5049040f70529/handler/preview_handler)
![sign_in](documents/tuto_git_gtlab/images/sign_in.png)
- NB : Il faut accéder à Gitlab depuis la plateforme FUN. On obtient une erreur 405 en accédant directement à la page https://app-learninglab.inria.fr/gitlab/users/sign_in.
![erreur 405](documents/tuto_git_gtlab/images/erreur405.png)
- Cliquer sur le premier **Sign in**. L'authentification est automatique à cette étape.
![projects](documents/tuto_git_gtlab/images/projects.png)
La grande chaîne de caractères remplacée ici par xxx est le login qu'il faudra utiliser dans Git pour accéder à Gitlab.
- Pour récupérer le mot de passe prédéfini, il faut utiliser le [Gitlab credentials retrieval
tool](https://app-learninglab.inria.fr/jupyterhub/services/password). On retrouve alors le login et le mot de passe.
![settings](documents/tuto_git_gtlab/images/password_retrieval.png)
- Il est possible de modifier le mot de passe dans `Account / Paramètres / Mot de passe`. NB : Cela empêchera d'utiliser les notebook Jupyter du MOOC.
![settings](documents/tuto_git_gtlab/images/password.png)
---
# Configurer Git
## Opérations de configuration à faire sur Git (parcours RStudio et OrgMode)
- Enregistrer l'email et le nom de l'utilisateur
```
git config --global --user.email you@example.com
git config --global --user.name Your Name
```
NB : Ne pas mettre de guillemets.
Ces deux paramètres sont obligatoire pour pouvoir commiter sinon on obtient le message suivant
![commit3](documents/tuto_git_gtlab/images/commit3.png)
- Si vous êtes derrière un proxy, il faut le définir dans Git
```
git config --global http.proxy http://proxy.server.com:port
```
On peut aussi définir le proxyUsername pour n'avoir que le mot de passe à saisir
```
git config --global http.proxy http://proxyUsername@proxy.server.com:port
```
- Option pour que le login et mot de passe soient enregistrés pendant 1 heure
```
git config --global credential.helper "cache --timeout=3600"
```
## Commandes pour afficher et effacer des options de configuration (parcours RStudio et OrgMode)
- Afficher les paramètres
```
git config --list
```
- Effacer les mots de passe enregistrés
```
git config --system --unset credential.helper
```
- Effacer le proxy
```
git config --global --unset http.proxy
```
- Effacer le message "git: 'credential-cache' is not a git command."
```
git config --global --unset credential.helper
```
## Opérations de transfert entre Git et Gitlab (parcours OrgMode)
- Récupérer l'adresse du dépôt
![adresse_depot](documents/tuto_git_gtlab/images/adresse_depot.png)
- Cloner le dépôt
```
git clone https://app-learninglab.inria.fr/gitlab/xxx/mooc-rr.git
```
On peut aussi définir l'identifiant pour n'avoir que le mot de passe à saisir
```
git clone https://xxx@app-learninglab.inria.fr/gitlab/xxx/mooc-rr.git
```
Un répertoire `mooc-rr` est créé sur votre ordinateur.
- Se placer dans le répertoire mooc-rr
```
cd mooc-rr
```
- Lister les fichiers du répertoire
```
ls (Unix)
dir (Windows)
```
- Synchroniser Git vers Gitlab
Il faut suivre les fichiers (commande `git add`) et les commiter (commande `git commit`) en local pour pouvoir les transférer sur serveur. La commande `git status` indique le statut des fichiers.
Soit un fichier `fichier.txt` à la racine du répertoire mooc-rr.
```
git status
```
![status1](documents/tuto_git_gtlab/images/status1.png)
```
git add fichier.txt
git status
```
![status2](documents/tuto_git_gtlab/images/status2.png)
```
git commit -m "message commit"
```
![commit_git](documents/tuto_git_gtlab/images/commit_git.png)
```
git status
```
![status3](documents/tuto_git_gtlab/images/status3.png)
On peut alors faire le `git push`pour transférer le fichier sur Gitlab.
```
git push
```
Demande le mot de passe
- NB : Il n'est pas possible de synchroniser vers Gitlab si des modifications ont été faites sur Gitlab et n'ont pas été répercupées en local
![rejected](documents/tuto_git_gtlab/images/rejected.png)
- Synchroniser Gitlab vers Git
```
git pull
```
# Liens utiles
- [Installer Git et Gitlab](https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/courseware/66bc811404b8481da5f794de54681c5e/f6580ad8e997400faeffe9af4fd37063/)
- [Définir un proxy dans Git](https://gist.github.com/evantoli/f8c23a37eb3558ab8765)
- [Mémoriser son mot de passe](http://blog.lecacheur.com/2015/11/05/git-le-b-a-ba-memoriser-son-mot-de-passe/)
- [Livre Pro Git](https://git-scm.com/book/fr/v2/)
\ No newline at end of file
1. [Installer Python](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#1-installer-python)
2. [Installer le package Jupyter](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#2-installer-le-package-jupyter)
3. [Installer les modules complémentaires](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#3-installer-les-modules-compl%C3%A9mentaires)
4. [Lancer Jupyper](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#4-lancer-jupyper)
5. [Autres langages](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#5-autres-langages)
1. [Le package R IRKernel](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#51-le-package-r-irkernel-permet-dex%C3%A9cuter-du-code-r-dans-un-notebook-r)
2. [Le package Python rpy2](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#52-le-package-python-rpy2-permet-dex%C3%A9cuter-du-code-r-dans-un-notebook-python)
3. [Le package Python SASPy](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#53-le-package-python-saspy-permet-dex%C3%A9cuter-du-code-sas-dans-un-notebook-python)
4. [Le package Python SASKernel](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#54-le-package-python-saskernel-permet-dex%C3%A9cuter-du-code-sas-dans-un-notebook-sas)
# 1 Installer Python
- Installer Python
- Ajouter les chemins de Python et Python\Scripts dans dans la variable PATH de Windows
La façon de procéder est très bien expliquée [ici](http://sametmax.com/ajouter-un-chemin-a-la-variable-denvironnement-path-sous-windows/).
---
# 2 Installer le package Jupyter
- Méthode pour installer un package
- Ouvrir une invite de commande dos
- Exécuter la commande suivante
```
pip install jupyter
```
NB : Le raccourci `^v` ne fonctionne pas dans l'invite de commande dos. La fonction "coller" est disponible avec le bouton droit de la souris.
---
# 3 Installer les modules complémentaires
- Ouvrir une invite de commande dos
- Exécuter les commandes suivantes
## **jupyter_contrib_nbextensions** pour replier le code à l'affichage
```
pip install jupyter_contrib_nbextensions
```
## **hide_code** pour choisir ce qui est exporté
```
pip install hide_code
jupyter-nbextension install --py hide_code
jupyter-nbextension enable --py hide_code
jupyter-serverextension enable --py hide_code
```
Choisir `Hide_code` dans le menu
![menu_hide_code](documents/tuto_jupyter_windows/images/menu_hide_code.png)
On obtient ceci
![hide_code](documents/tuto_jupyter_windows/images/hide_code.png)
Utiliser les icônes ci-dessous pour l'export
![export_hide_code](documents/tuto_jupyter_windows/images/export_hide_code.png)
NB : L'export semble mal fonctionner sous Windows (cf. [discussion](https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/discussion/forum/0c40378f778710ac14c97e2f0d8e7bb6c9d8d0c2/threads/5bd1685da0241eb2d5005bc7)).
# 4 Lancer Jupyper
- Ouvrir une invite de commande dos
- Exécuter la commande suivante
```
jupyter notebook
```
---
# 5 Autres langages
Jupyper permet par défaut d'exécuter du code Python. Des packages permettent d'exécuter d'autres langages.
## 5.1 Le package R [IRKernel](https://cran.r-project.org/web/packages/IRkernel/IRkernel.pdf) permet d'exécuter du code R dans un notebook R
- Lancer R ou RStudio
- Installer le package `IRkernel`
```
install.packages('IRkernel',dep=TRUE)
IRkernel::installspec() # to register the kernel in the current R installation
```
- On peut alors créer un notebook R
![new_notebook](documents/tuto_jupyter_windows/images/new_notebook.png)
![notebook_R](documents/tuto_jupyter_windows/images/notebook_R.png)
On remarque l'icône du logiciel R en haut à droite.
- [Exemple de notebook R](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/notebooks_jupyter/notebook_R/notebook_R.ipynb)
- Lien utile : https://irkernel.github.io/installation/
---
## 5.2 Le package Python **rpy2** permet d'exécuter du code R dans un notebook Python
- Le package `rpy2` s'installe difficilement par méthode standard.
- Télécharger le fichier binaire qui correspond au système d'exploitation [ici](https://www.lfd.uci.edu/~gohlke/pythonlibs/#rpy2)
- Ouvrir une invite de commande dos
- Se placer dans le dossier de téléchargement
- Exécuter la commande suivante
```
python -m pip install rpy2‑2.9.4‑cp37‑cp37m‑win_amd64.whl # adapter le nom du fichier
```
- Lancer Jupiter et créer un notebook Python
- Exécuter la commande suivante
```
%load_ext rpy2.ipython
```
- Installer le package `tzlocal` à l'aide de la commande `pip`
- [Exemple de notebook Python/R](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/notebooks_jupyter/notebook_Python_R/notebook_Python_R.ipynb)
- Lien utile : https://stackoverflow.com/questions/14882477/rpy2-install-on-windows-7
NB : Je n'ai pas eu besoin de définir les variables d'environnement R_HOME et R_USER.
---
## 5.3 Le package Python [SASPy](https://sassoftware.github.io/saspy/) permet d'exécuter du code SAS dans un notebook Python
- Installer le package `saspy` à l'aide de la commande `pip`
- Modifier le fichier C:\Program Files\Python\Python37\Lib\site-packages\saspy\sascfg_sav.py pour l'adapter à votre système
Dans les deux images ci-dessous, la fenêtre de gauche correspond au fichier initial et celle de droite au fichier modifié.
![sascfg1](documents/tuto_jupyter_windows/images/sascfg1.png)
![sascfg2](documents/tuto_jupyter_windows/images/sascfg2.png)
- [Exemple de notebook Python/SAS] (https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/notebooks_jupyter/notebook_Python_SAS/notebook_Python_SAS.ipynb)
- NB : L'export Jupyter vers pdf ne fonctionne pas pour les sorties HTML et donc SAS. Il est possible de faire l'export depuis pandoc.
- Exporter le document au format HTML
- Exécuter la commande suivante
```
pandoc --variable=geometry:a4paper --variable=geometry:margin=1in notebook_sas.html -o notebook_sas.pdf
```
mais ça ne marche pas pour tous les tableaux et on perd la coloration syntaxique.
---
## 5.4 Le package Python [SASKernel](https://sassoftware.github.io/sas_kernel/) permet d'exécuter du code SAS dans un notebook SAS
- Le package `sas_kernel` est basé sur le package `saspy`. Installer `saspy` en suivant les instructions de la section 4.3 si ce n'est déjà fait.
- Installer le package `sas_kernel` à l'aide de la commande `pip`
- On peut alors créer un notebook SAS
![new_notebook](documents/tuto_jupyter_windows/images/new_notebook.png)
![notebook_SAS](documents/tuto_jupyter_windows/images/notebook_SAS.png)
On remarque l'icône du logiciel SAS en haut à droite.
- [Exemple de notebook SAS](https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/notebooks_jupyter/notebook_SAS/notebook_SAS.ipynb)
- NB : L'export Jupyter vers pdf ne fonctionne pas pour les sorties HTML et donc SAS. Il est possible de faire l'export depuis pandoc.
- Exporter le document au format HTML
- Exécuter la commande suivante
```
pandoc --variable=geometry:a4paper --variable=geometry:margin=1in notebook_sas.html -o notebook_sas.pdf
```
mais ça ne marche pas pour tous les tableaux et on perd la coloration syntaxique.
- Lien utile : https://sassoftware.github.io/sas_kernel/install.html
# 1 Installer Magit
Plusieurs méthodes sont proposées [ici] (https://magit.vc/manual/magit/Installing-from-an-Elpa-Archive.html).
Celle-ci a été testée sur Windows :
- Ajouter le code suivant dans le fichier `.emacs.d/init.el`
```
(require 'package)
(add-to-list 'package-archives
'("melpa" . "http://melpa.org/packages/") t)
```
- Lancer Emacs et exécuter les commandes suivantes
```
M-x package-refresh-contents RET
M-x package-install RET magit RET
```
NB : `M-` correspond à la touche `<Alt>`, `RET` à la touche `<Entrée>`
# 2 Lancer Magit
- Ouvrir un fichier et exécuter le racourci `C-x g`
- Magit demande le chemin du répertoire Git
- Indiquer le chemin du répertoire mooc-rr
![git1](documents/tuto_magit/images/git1.png)
\ No newline at end of file
# Dans Git
- Enregistrer l'email et le nom de l'utilisateur
```
git config --global --user.email you@example.com
git config --global --user.name Your Name
```
NB : Ne pas mettre de guillemets.
Ces deux paramètres sont obligatoire pour pouvoir commiter sinon on obtient le message suivant
![commit3](documents/tuto_rstudio_gitlab/images/commit3.png)
- Si vous êtes derrière un proxy, il faut le définir dans Git
```
git config --global http.proxy http://proxy.server.com:port
```
On peut aussi définir le proxyUsername pour n'avoir que le mot de passe à saisir
```
git config --global http.proxy http://proxyUsername@proxy.server.com:port
```
- Option pour que le login et mot de passe soient enregistrés pendant 1 heure
```
git config --global credential.helper "cache --timeout=3600"
```
# Dans RStudio
- File / New Project / Version Control
![new_project](documents/tuto_rstudio_gitlab/images/new_project.png)
![git](documents/tuto_rstudio_gitlab/images/git.png)
- Récupérer l'adresse du dépôt
![adresse_depot](documents/tuto_rstudio_gitlab/images/adresse_depot.png)
- Indiquer l'adresse du dépôt dans le champ "Repository URL"
- Il est possible de faire précéder l'adresse du dépôt par `xxx@`, xxx étant l'identifiant Gitlab, pour ne pas avoir à le renseigner par la suite
![clone](documents/tuto_rstudio_gitlab/images/clone.png)
- Si vous êtes derrière un proxy, il faut le définir dans Git
- Git demande le mot de passe du proxy
![password_proxy](documents/tuto_rstudio_gitlab/images/password_proxy.png)
- Git se connecte à Gitlab et récupère l'ensemble des données
- RStudio redémarre pour se placer dans un mode lié à Git
![rstudio](documents/tuto_rstudio_gitlab/images/rstudio.png)
- Module2 / exo1 / toy_document.Rmd
- Modifier le fichier
- Sauvegarder
- Aller dans Git pour effectuer le commit
![commit](documents/tuto_rstudio_gitlab/images/commit.png)
![commit2](documents/tuto_rstudio_gitlab/images/commit2.png)
- Sélectionner les lignes à commiter puis cliquer sur "commit"
![commit5](documents/tuto_rstudio_gitlab/images/commit5.png)
Les modifications sont pour l'instant uniquement sur la machine. Elles n'ont pas été propagées sur Gitlab.
- Cliquer sur "push" pour les propager sur Gitlab
![push](documents/tuto_rstudio_gitlab/images/push.png)
![push2](documents/tuto_rstudio_gitlab/images/push2.png)
![push3](documents/tuto_rstudio_gitlab/images/push3.png)
- NB : Il n'est pas possible de synchroniser vers Gitlab si des modifications ont été faites sur Gitlab et n'ont pas été répercupées en local
![push4](documents/tuto_rstudio_gitlab/images/push4.png)
- Cliquer sur "pull" pour synchroniser Gitlab vers Git
\ No newline at end of file
* GitLab CI configuration
Here is the manually filtered list of org and md files that need to be
exported to html with the gitlab pages CI mechanism. Have a look at
file:html_src_files.lst to know which files are exported.
Here is the yaml file used for CI. All the work is done in a single
perl script.
#+BEGIN_SRC yaml :tangle .gitlab-ci.yml
image: brospars/pandoc-gitlab-ci:latest
pages:
stage: deploy
script:
- pandoc --version
# - pandoc --help
# - pandoc --list-input-formats # Broken as pandoc dates from 2013 on this image! :(
- bin/pandoc_fixer.pl html_src_files.lst;
- for file in `cat html_src_files.lst | sed 's/#.*//g' `; do
mkdir -p public/`dirname ${file}`;
mv ${file%.*}.html public/`dirname ${file}`/;
done
- cd module2/ressources/; tar zcf rr_org_archive.tgz rr_org/init.el rr_org/journal.org rr_org/init.org ; cd ../.. ; mv module2/ressources/rr_org_archive.tgz public/module2/ressources/
- cd module2/ressources/; tar zcf replicable_article.tgz replicable_article/Makefile replicable_article/article.org replicable_article/biblio.bib ; cd ../.. ; mv module2/ressources/replicable_article.tgz public/module2/ressources/
artifacts:
paths:
- public
only:
- master
#+END_SRC
* Update script =html_src_files.lst=
Once the content of the MOOC has been exported from FUN into =/tmp/course/=:
#+begin_src shell :results output :exports both
for file in `cat html_src_files.lst | sed -e 's/#.*//g'`; do
FILE=`echo $file | sed -e 's|^\./||' -e 's|.org$||' -e 's|.md$||'`
URL=`grep -l "gitlabpages.*$FILE" /tmp/course/html/*.html | sed -e 's|.html$||' -e 's|/tmp/course/html/|https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/|'`
echo "$file # $URL"
done
#+end_src
#+RESULTS:
#+begin_example
./module1/ressources/introduction_to_markdown_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/ecbcbd8bfafd48e9a912f66237b76c92
./module1/ressources/introduction_to_markdown.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/ecbcbd8bfafd48e9a912f66237b76c92
./module1/ressources/sequence1_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/9719a1f5b81a4f2d89c27e54ce81f498
./module1/ressources/sequence2_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/565a72fe3c8b464f8ec3e31b56cd4c57
./module1/ressources/sequence3_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/d85eb783ff884ff8b1306b680326b198
./module1/ressources/sequence5_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/c96bfaf3804847a38d2a8850ee0baf54
./module1/ressources/sequence1.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/9719a1f5b81a4f2d89c27e54ce81f498
./module1/ressources/sequence2.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/565a72fe3c8b464f8ec3e31b56cd4c57
./module2/ressources/maintaining_a_journal.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/0af0b6bf03194c1bb2798c29d7375a76
./module2/ressources/maintaining_a_journal_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/0af0b6bf03194c1bb2798c29d7375a76
./module2/ressources/jupyter.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/8dcce91be83c4ece834abfa98b8bbfb1
./module2/ressources/jupyter_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/8dcce91be83c4ece834abfa98b8bbfb1
./module2/ressources/rstudio.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/09d339f009cd4b45a468583ab7730221
./module2/ressources/rstudio_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/09d339f009cd4b45a468583ab7730221
./module2/ressources/gitlab.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/448cd6f9018545d1a67405551add6fda
./module2/ressources/gitlab_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/448cd6f9018545d1a67405551add6fda
./module2/ressources/emacs_orgmode.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/954f94ce4f9a4d858d47b41793cc96c8
./module2/ressources/emacs_orgmode_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/954f94ce4f9a4d858d47b41793cc96c8
./module2/ressources/sequence6_examples/README.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/827b36e10ddd49239f1c62cc1903951a
./module2/ressources/sequence6_examples/README_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/827b36e10ddd49239f1c62cc1903951a
./module2/exo4/stat_activity.org #
./module2/slides/ressources.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/36723edefc72488ab44e269501cfc9f8
./module2/slides/ressources_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/36723edefc72488ab44e269501cfc9f8
./module3/ressources/iso_date_format.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/316fc24edc1b44278ada4ca531c705be
./module3/ressources/iso_date_format_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/316fc24edc1b44278ada4ca531c705be
./module3/ressources/influenza-like-illness-analysis-orgmode+R.org #
./module3/ressources/influenza-like-illness-analysis-orgmode+Lisp+Python+R.org #
./module3/ressources/influenza-like-illness-analysis-orgmode.org #
./module3/ressources/analyse-syndrome-grippal-orgmode.org #
./module3/ressources/analyse-syndrome-grippal-orgmode+R.org #
./module3/ressources/analyse-syndrome-grippal-orgmode+Lisp+Python+R.org #
./module4/ressources/resources_refs.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/3c3c8cb2160d44e09a087b825beb92b8
./module4/ressources/resources_refs_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/3c3c8cb2160d44e09a087b825beb92b8
./module4/ressources/exo1.org #
./module4/ressources/exo2.org #
./module4/ressources/exo3.org #
./module4/ressources/resources_environment.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/4be922aa6b8c471ab1addcdbddb4e487
./module4/ressources/resources_environment_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/jump_to_id/4be922aa6b8c471ab1addcdbddb4e487
./documents/notebooks/notebook_RStudio_SASmarkdown.md #
./documents/tuto_git_gtlab/tuto_git_gitlab.md #
./documents/tuto_rstudio_gitlab/tuto_rstudio_gitlab.md #
./documents/tuto_magit/tuto_magit.md #
./documents/tuto_emacs_windows/tuto_emacs_windows.md #
./documents/tuto_jupyter_windows/tuto_jupyter_windows.md #
#+end_example
* Local Testing
Having to go through a commit/push all the time to check whether it
works or not is a pain. Here a simple mechanism that allows to test
the CI script locally.
#+begin_src perl :results output :file gitlab-ci.sh :exports both
open INPUT, ".gitlab-ci.yml";
my($line);
my($script_found)=0;
while(defined($line=<INPUT>)) {
if($line=~/\s*script:/) { $script_found=1; next;}
if($line=~/\s*artifacts:/) { $script_found=0; }
if($script_found) {
if($line =~ /^\s*#\s/) { next; }
# if($line =~ /mv.*public/) { next; }
$line =~ s/^\s*-\s//g;
print($line);
}
}
#+end_src
#+RESULTS:
[[file:gitlab-ci.sh]]
#+begin_src shell :results output :exports both
chmod +x ./gitlab-ci.sh
./gitlab-ci.sh
#+end_src
./module1/ressources/introduction_to_markdown_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/ecbcbd8bfafd48e9a912f66237b76c92
./module1/ressources/introduction_to_markdown.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/ecbcbd8bfafd48e9a912f66237b76c92
./module1/ressources/sequence0_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/a1b9841f7ff34f83a637c56897ac8439
./module1/ressources/sequence1_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9719a1f5b81a4f2d89c27e54ce81f498
./module1/ressources/sequence2_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/565a72fe3c8b464f8ec3e31b56cd4c57
./module1/ressources/sequence3_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/d85eb783ff884ff8b1306b680326b198
./module1/ressources/sequence4_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/27b18e9ea3c14a77942eaa7cd00b8506
./module1/ressources/sequence5_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/c96bfaf3804847a38d2a8850ee0baf54
./module1/ressources/sequence0.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/a1b9841f7ff34f83a637c56897ac8439
./module1/ressources/sequence1.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9719a1f5b81a4f2d89c27e54ce81f498
./module1/ressources/sequence2.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/565a72fe3c8b464f8ec3e31b56cd4c57
./module1/ressources/sequence3.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/d85eb783ff884ff8b1306b680326b198
./module1/ressources/sequence4.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/27b18e9ea3c14a77942eaa7cd00b8506
./module1/ressources/sequence5.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/c96bfaf3804847a38d2a8850ee0baf54
./module1/ressources/gitlab_interface_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/27b18e9ea3c14a77942eaa7cd00b8506
./module1/ressources/gitlab_interface.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/27b18e9ea3c14a77942eaa7cd00b8506
./module1/ressources/version_control_other_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/27b18e9ea3c14a77942eaa7cd00b8506
./module1/ressources/version_control_other.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/27b18e9ea3c14a77942eaa7cd00b8506
./module1/ressources/InterviewJoelZaffran.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/4158e12691754dcca7fdf729647361e4
./module1/ressources/InterviewFrancoisPellegrini.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/62065b725a9b4b5ea3342ea1a035a032
./module1/ressources/InterviewValerieOrozcoChristopheBontemps.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/53a4f15ad6e143bf9056d05943f20052
./module1/ressources/ResearchTransparency_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/ad899222989849fa96bb5d4dd3d178c3
./module1/ressources/SourcesAndBiblio_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/63fabae2022c4abba5a24a74ca2d951f
./module1/ressources/TEIIntroduction_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/4158e12691754dcca7fdf729647361e4
./module2/ressources/maintaining_a_journal.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/0af0b6bf03194c1bb2798c29d7375a76
./module2/ressources/maintaining_a_journal_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/0af0b6bf03194c1bb2798c29d7375a76
./module2/ressources/jupyter.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/8dcce91be83c4ece834abfa98b8bbfb1
./module2/ressources/jupyter_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/8dcce91be83c4ece834abfa98b8bbfb1
./module2/ressources/rstudio.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/09d339f009cd4b45a468583ab7730221
./module2/ressources/rstudio_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/09d339f009cd4b45a468583ab7730221
./module2/ressources/rstudio-install-doc.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/09d339f009cd4b45a468583ab7730221
./module2/ressources/rstudio-install-doc_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/09d339f009cd4b45a468583ab7730221
./module2/ressources/rstudio-git.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/09d339f009cd4b45a468583ab7730221
./module2/ressources/rstudio-git_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/09d339f009cd4b45a468583ab7730221
./module2/ressources/gitlab.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/448cd6f9018545d1a67405551add6fda
./module2/ressources/gitlab_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/448cd6f9018545d1a67405551add6fda
./module2/ressources/emacs_orgmode.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/954f94ce4f9a4d858d47b41793cc96c8
./module2/ressources/emacs_orgmode_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/954f94ce4f9a4d858d47b41793cc96c8
./module2/ressources/emacs_newbie.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/b031e4067cf8410c86adbeba2f30c92f
./module2/ressources/emacs_newbie_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/b031e4067cf8410c86adbeba2f30c92f
./module2/ressources/sequence6_examples/README.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/827b36e10ddd49239f1c62cc1903951a
./module2/ressources/sequence6_examples/README_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/827b36e10ddd49239f1c62cc1903951a
./module2/ressources/python_r_latex.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/19c2b1de7766484bae73f3ab133463c6
./module2/ressources/python_r_latex_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/19c2b1de7766484bae73f3ab133463c6
./module2/exo4/stat_activity.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/b52e4bd2198947a8b28b5e648184048c
./module2/exo4/stat_activity_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/b52e4bd2198947a8b28b5e648184048c
./module2/slides/ressources_S1.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/48ea451c3ed047f5992cb1528dc9aad2
./module2/slides/ressources_S1_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/48ea451c3ed047f5992cb1528dc9aad2
./module2/slides/ressources_S2.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7db97e9e046743a7a581e370a26b8c1a
./module2/slides/ressources_S2_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7db97e9e046743a7a581e370a26b8c1a
./module2/slides/ressources_S5.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/6fe2237725c448e18e0f917f7ee96255
./module2/slides/ressources_S5_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/6fe2237725c448e18e0f917f7ee96255
./module2/slides/ressources_S7.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/b957267a6c7240f7a0765a4b2863f3ce
./module2/slides/ressources_S7_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/b957267a6c7240f7a0765a4b2863f3ce
./module3/ressources/iso_date_format.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/316fc24edc1b44278ada4ca531c705be
./module3/ressources/iso_date_format_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/316fc24edc1b44278ada4ca531c705be
# ./module3/ressources/influenza-like-illness-analysis-orgmode+R.org #
# ./module3/ressources/influenza-like-illness-analysis-orgmode+Lisp+Python+R.org #
# ./module3/ressources/influenza-like-illness-analysis-orgmode.org #
# ./module3/ressources/analyse-syndrome-grippal-orgmode.org #
# ./module3/ressources/analyse-syndrome-grippal-orgmode+R.org #
# ./module3/ressources/analyse-syndrome-grippal-orgmode+Lisp+Python+R.org #
./module4/ressources/resources_refs.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/3c3c8cb2160d44e09a087b825beb92b8
./module4/ressources/resources_refs_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/3c3c8cb2160d44e09a087b825beb92b8
./module4/ressources/exo1.org #
./module4/ressources/exo2.org #
./module4/ressources/exo3.org #
./module4/ressources/resources_environment.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/4be922aa6b8c471ab1addcdbddb4e487
./module4/ressources/resources_environment_fr.org # https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/4be922aa6b8c471ab1addcdbddb4e487
#+TITLE: Interview de François Pellegrini : recherche reproductible et utilisation de données à caractère personnel
#+Date: <déc 2019>
#+Author: François Pellegrini
#+LANGUAGE: fr
** Biographie
*François Pellegrini*, est informaticien, professeur des universités à
l’Université de Bordeaux et chercheur au Laboratoire bordelais de
recherche en informatique1 (LaBRI) et à Inria. Il est l'auteur du
logiciel [[https://gforge.inria.fr/projects/scotch/][Scotch2]], un logiciel de partitionnement généraliste.
Il est commissaire à la Commission nationale de l’informatique et des libertés (CNIL).
** Interview
*** Comment concilier la logique de transparence inhérente à celle de la recherche reproductible avec le respect de contraintes de confidentialité, dans le cas d'utilisation de données personnelles ?
La personne ayant collecté les données à caractère personnel acquiert, de par le
Règlement Général sur la Protection des Données (RGPD), le statut de
"*responsable de traitement*", qui est le "gardien" des données en question. Il
est soumis à un *principe de* "*redevabilité*" (en anglais : "*accountability*")
quant aux moyens et procédures qu'il met en place pour administrer le traitement
en question.
De fait, *sauf consentement explicite des personnes lors de la collecte*, il ne
peut placer ces données en libre accès pour les personnes inconnues souhaitant
reproduire les recherches.
Il doit leur accorder un *accès au cas par cas*, encadré par des clauses de non
divulgation, afin que les scientifiques en questions puissent mener, sur le
site du responsable de traitement (ou, à tout le moins, seulement dans le
périmètre de l'Union Européenne), des traitements compatibles avec les finalités
de recueil initial.
De fait, ils peuvent (tenter de) reproduire les résultats, mais pas mener
d'autres recherches qui seraient trop différentes de celles pour lesquelles le
consentement des personnes avait été recueilli.
Dans le cas de *données confidentielles non à caractère personnel*, la situation
est somme toute similaire, avec en moins la contrainte du respect strict de la
loi "Informatique et Libertés".
*** En tant que lecteur.rice d'articles scientifiques, sur quels critères puis-je évaluer la robustesse du protocole de constitution des données si elles sont confidentielles ?
*Le processus et les données sont deux choses différentes*.
Tu peux très bien *auditer un processus sans regarder /in concreto/ les données
qui y seront soumises*.
Il est également possible de *tester le processus avec des données synthétiques*,
afin d'en vérifier la conformité des résultats attendus, par rapport aux
caractéristiques des jeux de données qui ont été générées.
** Ressources complémententaires
Site web de la CNIL : [[https://www.cnil.fr/fr/comprendre-le-rgpd]["Comprendre le RGPD"]]
Nguyen, Benjamin. 2019. ‘Anonymization Techniques: Theory and Practice’. presented at the Cinquième École d’Hiver é-EGC, sur le thème «Privacy Preserving, Reasoning, Explaining», Metz, January 21. [[https://egc2019.sciencesconf.org/resource/page/id/12]].
Nilsonne, Gustav. 2019. ‘Hack- Finding Value in Anonymized Data: Exploring Scenarios for Secondary Use’, June. [[https://osf.io/2n8b6/]].
#+TITLE: Interview de Joël Zaffran, chercheur en sociologie
#+Date: <déc 2019>
#+Author: Joël Zaffran
#+LANGUAGE: fr
** Biographie
*Joël Zaffran* est Professeur de sociologie à
l’université de Bordeaux et chercheur au Centre Émile Durkheim qui est
une UMR dont la particularité est de regrouper des chercheurs en
science politique et en sociologie.
** Interview
*** Quel est votre domaine de recherche ? Quelles méthodes utilisez-vous pour traiter vos données ?
Mes domaines de recherche sont d’une part l’école et la jeunesse,
d’autre part le handicap. Sur le plan méthodologique, j’utilise aussi bien des
approches quantitatives que des approches qualitatives. Souvent, j’essaie
d’articuler les deux approches pour faire en sorte que la mixed method éclaire
sous plusieurs angles l’objet de recherche. C’est dans ce cadre que j’utilise
plusieurs logiciels, parfois simultanément.
*** Sur quels types de données travaillez-vous (ex. données d’enquête, etc.) et quelles sont les contraintes associées à ce type de données (ex. confidentialité) ? Comment gérez-vous ces contraintes ?
Les données quantitatives sur lesquelles je travaille soit sont issues d’un
questionnaire *ad hoc* que j’élabore en fonction de mes hypothèses puis
diffuse généralement sous Sphinx, soit sont issues d’une analyse secondaire.
Dans les deux cas, le problème de la confidentialité se pose conjointement avec
la contrainte de la CNIL.
Cela suppose donc d’une part une autorisation préalable de la CNIL après qu’une
demande a été déposée sur leur site, d’autre part une anonymisation des
individus lors de la production des résultats. À cela s’ajoute que le fait
d’utiliser Sphinx me permet de déposer mes données sur le serveur de
l’université, ce qui a l’avantage de bénéficier d’une sécurisation d’accès à
ces données.
*** Dans votre domaine, quelles ont été les évolutions majeures en termes de traitement de données ? il peut s’agir de méthodes (ex. new statistics) comme d’outils (ex. utilisation plus massive de R, etc.)
L’évolution majeure pour ce qui me concerne a été de passer de SPSS à R. Ce
passage a été contraint puisqu’il est dû à des restrictions budgétaires de
l’université. Or, j'enseignais SPSS à mes étudiants, et il a fallu que je passe
à R (qui a l’avantage d’être un logiciel libre) pour assurer la continuité de
mes enseignements. Cela étant, j’ai une licence SPSS sur mon ordinateur privé,
de sorte qu’il n’est pas rare que je passe de Sphinx à SPSS, et de SPSS à R
lorsque j’exploite les données de mes enquêtes.
Cette manière de faire présente plusieurs avantages. Tout d’abord, R me permet
de passer d’une analyse statistique des données quantitatives à une analyse
statistique des données lexicales (ce que permet de faire iramuteq). Ensuite,
j’ai dû faire récemment une analyse de survie pour des données de parcours. Or,
SPSS ne fournit (du moins à ma connaissance) ni la table des “Hazard ratio” ni
les graphiques du Schoenfeld test, alors qu’il existe un script R pour cela.
*** Comment se traduit la question de la transparence dans votre domaine de recherche ? Quels sont les points critiques dans votre discipline ? Toutes les données n’ont pas vocation à être partagées, mais comment gérez-vous le fait de pouvoir retracer votre processus de recherche ? Quelles pratiques avez-vous adoptées ?
Comme je l’ai dit, mon champ est les sciences humaines et sociales, plus
précisément la sociologie. Dans ce domaine, la question de la transparence ne
se pose pas dans des termes identiques aux sciences dures, où les enjeux
scientifiques et académiques sont différents. *En revanche, le problème de la capacité
à retracer le processus de recherche est le même, quelle que soit la discipline.*
Pour ce qui me concerne, il s’agit surtout de *garder une trace des scripts et des
tableaux construits avant de publier les résultats sous la forme d’un article*.
Je dois dire que ce n’est pas une mince affaire puisque l’on sait bien qu’
*un article reflète mal le processus de recherche en amont de sa publication*.
J’ai deux manières de faire : la première est de préciser l’approche et la
méthode dans un *encart méthodologique* figurant dans le corps de l’article,
la deuxième est de toujours *nommer chaque tableau ou script avant de l’enregistrer*.
Cela permet de s’y retrouver dans la masse des fichiers créés.
*** Quels outils utilisez-vous ? par exemple, le recours aux logiciels propriétaires (SAS, SPSS, etc.) soulève de nombreuses difficultés dans une perspective de recherche reproductible car le code source n’est pas disponible.
Sur le plan de la traçabilité, *le recours à R est plus aisé dans la mesure où
tous les scripts utilisés sont enregistrés chronologiquement*, et qu’il suffit
d’attribuer un titre à chacun d’eux (en veillant au préalable à bien mettre le
signe #). Cela est plus difficile avec SPSS. C’est la raison pour laquelle,
comme je le disais, j’ai opté avec SPSS pour des enregistrements pas à pas du
listing des résultats.
*** Pourriez-vous décrire une histoire d'horreur ? i.e. un gros raté (ex. : données non disponibles ; impossibilité de reproduire une figure en obtenant le même résultat, impossibilité de fournir des données à un reviewer, etc.)
Mon plus grand raté est lorsqu’il s’est agi de *refaire un modèle de régression
à la demande de reviewers*. Le drame est que j’ai été dans *l’impossibilité de retrouver
les variables qui furent recodées et l’horreur a été de refaire tous les recodages*,
puis de refaire tous les tableaux avant de pouvoir refaire l’analyse dans le
sens attendu par les reviewers. Ma plus grande déception a été de voir que les
résultats initialement présentés n'étaient guère différents des résultats
produits après avoir retravaillé les données dans le sens indiqué par les reviewers.
#+TITLE: Interview croisée de Valérie Orozco et Christophe Bontemps
#+Date: <déc 2019>
#+Author: Valérie Orozco et Christophe Bontemps
#+Language: fr
** Biographie
*Valérie Orozco* est ingénieure en statistique/économétrie à l’INRAE
depuis 2004 et membre du groupe Industrial Organization de TSE
(Toulouse School of Economics à Toulouse). Elle participe principalement aux
travaux de recherche sur l’économie des firmes agro-alimentaires, et les
relations alimentation et santé.
*Christophe Bontemps* est ingénieur économètre à l’INRAE et membre du
groupe Food Economics and Policy dans TSE
(Toulouse School of Economics à Toulouse). Il participe aux travaux de
recherche sur l’économie des firmes agro-alimentaires, l’environnement
et les relations alimentation et santé.
** Interview
*** Pourriez-vous vous présenter : votre identité, votre domaine de recherche et vos centres d’intérêts scientifiques hors discipline (ex. R, Python, etc.) ?
Nous travaillons à la croisée de deux mondes : celui des *mathématiques (statistique)*
et celui de l'*économie*, en particulier l’économie de l’alimentation et de
l’environnement.
En tant qu’ingénieurs-économètres, nous sommes appelés à collaborer sur des
projets scientifiques, et agissons comme des interfaces entre ces deux mondes.
Nous devons donc interpréter les notions économiques très formalisées pour les
tester en pratique sur des jeux de données.
Nous utilisons donc les outils des deux mondes, nous privilégions l’écriture
d’articles en LaTeX et l’utilisation de R, mais nous utilisons également Stata,
logiciel propriétaire incontournable en économétrie.
*** Comment se traduit la question de la reproductibilité et de la transparence dans votre domaine de recherche ?
Les recherches auxquelles nous participons comportent de *fortes parties empiriques*.
Le plus souvent, un problème est observé et soulève des questions. Les
comportements des acteurs (entreprises, consommateurs, décideurs) sont modélisés
à l’aide de la théorie économique, puis une hypothèse est émise qui viendrait
expliquer le phénomène observé.
Cette hypothèse est ensuite confrontée aux données. Si l’hypothèse est vérifiée
sur un jeu de données pertinent, des recommandations peuvent être émises et il
s’agit là d’un résultat. Les « résultats » correspondent donc pour nous à
l’ensemble des éléments illustrant la réponse à la question de recherche et ils
s’appuient souvent sur des résultats (au sens outputs) empiriques (statistiques
descriptives, estimations de modèles économétriques).
Contrairement à d’autres disciplines, *nous ne construisons pas d’expérience
pour collecter les données ou répliquer un phénomène*. Nous utilisons des
*données observées* (par exemple les achats par des ménages) sur lesquelles
*nous testons des hypothèses* et *estimons les paramètres du modèle économique*
(par exemple une élasticité-prix).
La reproductibilité des résultats peut s’exprimer soit comme la capacité à
reproduire tous les résultats depuis les données originales, soit comme la
possibilité de retrouver le même type de résultats sur un autre jeu de données.
Dans le premier cas, la chaîne de traitements assure que le résultat est
reproductible dans la lignée d’une démarche qualité, dans le second que le
résultat est transposable et généralisable à d’autres situations.
Le terme « robuste » renvoie plutôt à ce 2e cas. D’ailleurs, souvent, pour une
question de recherche donnée, on teste la robustesse des résultats obtenus soit
en testant le modèle sur un autre jeu de données, soit en modifiant une
hypothèse du modèle.
*** Quelles sont vos pratiques de recherche pour qu'elles soient plus reproductibles et plus transparentes ? (quand vous travaillez seul, quand vous travaillez en groupe)
Le plus important, pour nous, est de *maîtriser l'enchaînement des tâches et
des programmes (le workflow)*. Évidemment, cela est plus simple lorsque nous
sommes seuls en charge du code et des données (cela signifie que nous
collaborons avec d’autres chercheurs, mais que nous sommes « responsables »
des codes et données).
Nous utilisons alors des outils simples et une organisation structurée en
scripts maîtres et sous-programmes. Nous utilisons aussi des makefile et des
outils de représentation du workflow comme Graphviz. Évidemment, si le projet
et le chercheur s’y prêtent, nous utilisons R (et les notebooks/Markdown) et
git. Pour l’écriture d’articles, nous privilégions Overleaf pour une écriture
collaborative et Zotero (ou bibTex/JabRef) pour le partage de bibliographies.
*** Quels outils utilisez-vous ?
Même si nous pouvons mettre en avant les atouts d’un logiciel libre auprès de
nos chercheurs, nous ne pouvons pas changer brutalement leurs pratiques.
*En économie, nombreux sont ceux qui utilisent des logiciels propriétaires*
(Stata, SAS, Matlab, Mathematica, Gams…) même si l’utilisation de R se répand.
*Nous pensons que l’utilisation de ces logiciels, même si elle freine la réutilisation par quelqu’un
d’autre, n’empêche pas de mener une recherche reproductible, à condition d’utiliser de bonnes pratiques*.
Lorsque nous utilisons le logiciel Stata, rien ne nous empêche de diffuser un
code lisible, et structuré permettant de retrouver toutes les étapes et tous
les résultats ! Certes, il faudra une licence Stata pour réutiliser ce code,
mais ce n’est pas forcément très compliqué à comprendre ni à lire puisque le
code est en format texte.
*** Utilisez-vous des cahiers de notes, des outils de balisage ?
Nous essayons de *documenter le plus possible nos projets* (données, choix de
modélisation, pistes abandonnées, hypothèses prises…) et d’améliorer nos
pratiques d’échanges d’informations (notamment éviter les mails relatifs aux
avancées des projets).
Nous utilisons par exemple des *outils de TMS (Tasks Management System)* comme
Trello.
Concernant Markdown, il s’est clairement imposé dans nos pratiques surtout pour
générer des documents reproductibles automatiquement à partir du code (dans R
bien sûr, dans Stata également), mais aussi pour les notebooks Jupyter que nous
avons testés.
*** Quels sont workflows, comment articulez-vous les différents outils que vous utilisez au quotidien ? Quelles étapes de préparation des données (codage, documentation) suivez-vous ?
*** Quelles bonnes pratiques de modélisation (packages, fonctions, etc.) avez-vous appris à mettre en oeuvre ? Comment assurez-vous le suivi des versions de vos scripts, de votre code, de vos textes, etc. ?
Il faudrait un article entier pour décrire tout cela et d’ailleurs nous en avons
co-écrit un à paraître bientôt ! *Les données sont souvent des tables*, que l’on
appariera parfois, mais la structure des données est souvent simple chez nous.
On a pris l'habitude d’une *structure de répertoires* bien claire, séparant
données originales, programmes, données de travail, et documentation. Nous
avons aussi des *conventions de nomenclature pour les fichiers et les variables*,
ce qui simplifie la vie.
Ensuite, pour être franc, *cela commence souvent par un programme un peu
brouillon qui devient trop long pour s’y retrouver*. Alors on prend *un bout de
papier sur lequel on écrit un début de workflow, avec des flèches*. Puis on
ré-écrit le programme plus proprement en utilisant des fonctions et des
sous-programmes. À la suite on modifie le workflow à mesure que le projet avance
et on le dessine sous Graphviz.
*Si on a la chance d’être sous R, on utilise git/GitHub pour le suivi des
versions des programmes*, sinon, c’est *gestion des versions à la main*
(conventions de nommage, documentations au sein des programmes et des données),
même si l’on peut aussi se servir de git/Github pour des programmes Stata.
On est tout le temps en train de « penser automatique » notamment pour exporter
directement toutes les sorties générées (tables, graphiques) automatiquement et
pour insertion directe dans le papier final.
Concernant le partage de l’écriture du papier, Overleaf permet un suivi des
versions (version payante). *Au final, c’est beaucoup de bon sens, un peu
d’organisation et quelques bons outils* que l’on trouve en restant ouverts à de
nouvelles pratiques - et fermés à des outils de type tableurs, MS-Word, etc.
qui sont encore très utilisés en économie.
*** Qu'est-ce que ça a changé dans votre pratique de la publication ?
Cela a surtout changé *notre façon de travailler avec les chercheurs*. À force
de montrer des exemples - et des contre-exemples dramatiques - certains
chercheurs nous ont laissé la maîtrise des travaux empiriques.
Quel bonheur que de lancer un programme et de voir l’écran clignoter, des
graphiques s'afficher furtivement, des lignes défiler dans la console pour
enfin retrouver l'ensemble des outputs bien rangés dans leurs dossiers !
Nos pratiques ont évolué au fur et à mesure, en utilisant de nouveaux outils et
en maîtrisant l'ensemble du workflow. Après, ce ne sont que des expériences sur
des outils de plus en plus performants et utiles, du bon sens et l’envie
permanente d’améliorer nos pratiques.
*** À quel moment vous avez été sensible à cette question ? Quels conseils donneriez-vous aux jeunes étudiants ? (Et aux moins jeunes ?)
*** Quels seraient vos conseils en termes de formation et d’accompagnement des chercheurs pour une recherche plus transparente ? Quels sont les défis actuels dans votre domaine ?
Assez tôt (2005) puisque nous manipulons des données que nous achetons
régulièrement (une fois par an) pour lesquelles de nouvelles versions peuvent
nous être envoyées. *Il a donc été nécessaire de penser automatisation très vite*.
Travaillant à 2 ingénieurs sur ces données, il a été nécessaire de penser
reproductibilité sur nos 2 PCs puis sur n’importe quel autre.
Bref, ça a été progressif et le partage de nos pratiques, la confrontation de
nos idées et l’évolution des outils ont été de vrais moteurs. L’arrivée de
Sweave en 2008, très prôné par J. Racine en visite dans notre laboratoire, a
été un nouveau déclencheur.
Côté formations, il serait nécessaire de mieux former les chercheurs - les
jeunes surtout - si possible pendant leur formation. Évidemment, aujourd’hui
on peut citer le MOOC ainsi que plusieurs papiers (Gentzkow et Shapiro 2014,
Stodden 2013…).
Les journaux ont aussi un rôle à jouer en montant en exigences concernant la
vérification de la reproductibilité à partir des données et codes fournis (avec
un referee spécialiste ou en sollicitant des tiers comme CASCAD), et aussi en
donnant les moyens de progresser (en proposant un repository interne à la revue ou
en en suggérant un externe).
Évidemment, le point crucial reste celui des données confidentielles, mais avec
de bonnes métadonnées, un DOI et l’arrivée récente de CASCAD, une
[[https://www.cascad.tech/][plateforme de certification de la reproductibilité]],
la reproductibilité avance là aussi.
*** Pourriez-vous décrire une histoire d'horreur ? i.e. un gros raté (ex. : données non disponibles ; impossibilité de reproduire une figure en obtenant le même résultat, impossibilité de fournir des données à un referee, etc.)
*Nous vivons dans un film d’horreur !* “Nos” chercheurs, à de rares exceptions
près, ne sont pas des programmeurs et n’ont pas (encore) de trop fortes
incitations à publier et diffuser leurs programmes.
En outre, nos données étant très souvent confidentielles, les revues, à de très
rares exceptions près, ne demandent pas à tester les programmes même sur des
données fictives.
C’est donc parfois l’horreur absolue lorsqu’un referee demande à refaire une
estimation et que le chercheur ne retrouve pas le même résultat et n’est pas
complètement sûr des programmes utilisés !
Il faut dire aussi, que *les estimations économétriques reposent souvent sur
la maximisation d’une vraisemblance*, une fonction souvent complexe à maximiser
et il arrive qu’un changement de version de logiciel (Stata par exemple, mais
une mise à jour d’un package R ou un package R obsolète peuvent aussi réserver
de belles surprises) vienne perturber la délicate mécanique mise au point.
*** Pourriez-vous donner des cas concrets où des pratiques visant à rendre votre recherche reproductible et transparente vous ont aidé à résoudre un problème ?
*Nous avons probablement fait de la recherche reproductible sans le savoir, à
nos débuts, en 2003*. Pour un programme de recherche sur l'essor des marques de
distributeurs (MDD), nous avons été amenés à répliquer une analyse économétrique
effectuée sur une catégorie de produit (les yaourts), sur quelques autres.
Nous avons donc commencé à mettre en place un workflow, puis des sorties
automatiques en LaTeX et finalement avons construit une “moulinette” qui prenait
n’importe quel produit alimentaire et produisait automatiquement un document pdf
(via LaTeX) avec l’analyse économétrique complète. Le tout était programmé sous
Stata, une prouesse !
Ce processus nous a permis d’envisager l’écriture d’un premier article, suivi
d’un second, plus complexe et portant sur plus d’une centaine de produits et de
montrer l’impact de l’introduction des MDD sur les prix des marques nationales.
Un projet très sympa qui a forgé notre façon de travailler par la suite.
Un autre exemple très positif est celui récent d’un papier à paraître :
*avoir anticipé la demande de la revue de fournir les codes et données et d’avoir ainsi été capable de les fournir en 2 jours (codes
propres et commentés, données, workflow documenté, un seul programme à lancer générant une page web avec toutes les sorties du papier)*.
*** Quelle question souhaiteriez-vous ajouter à cette interview ? Qu’auriez-vous envie d’évoquer ?
Il n’est *jamais trop tard pour changer ses pratiques* et *s’organiser différemment*.
On nous reproche souvent de vouloir compliquer une organisation bien établie qui
a fait ses preuves (de non-reproductibilité).
*Pour reprendre des notions économiques, pour certains, les coûts semblent
nettement supérieurs aux bénéfices. Cela ne nous semble pas vrai.* Certes tout
changement à un coût, surtout à court terme, mais nous restons persuadés que
*les bénéfices individuels et collectifs sont grands et que ce coût peut être minime*.
Il y a espoir que ce discours soit donc entendu par des économistes… par
contre pour que cela fonctionne, il nous semble important *d’inciter chaque
amélioration et de ne pas chercher à modifier toutes les pratiques en même temps*.
Certains outils sont plus simples que d’autres et tout dépend du point de départ
de chacun.
all: introduction_to_markdown.html
ressources-md: Module1_1_MaterielSupplementaire_fr.md Module1_2_MaterielSupplementaire_fr.md\
Module1_3_MaterielSupplementaire_fr.md Module1_5_MaterielSupplementaire_fr.md\
Module1_1_SupplementaryMaterial.md Module1_2_SupplementaryMaterial.md
NLINES=10000000
%.html: %.org
emacs -batch $^ --funcall org-html-export-to-html
sed -i -e 's/<pre /<pre style="padding-left: 30px; background-color: #f6f8fa;" /g' \
-e 's/<li>/<li style="margin-bottom:0;">/g' \
-e 's/<ul>/<ul style="margin:0 0;">/g' $@
mv $@ $@.bak
cat $@.bak | grep -A $(NLINES) -e '<body>' | grep -B $(NLINES) -e '<div id="postamble" class="status">' | grep -v -e '<body>' -e '<div id="postamble" class="status">' > $@
rm $@.bak
include ../../Makefile.ressources
# -*- coding: utf-8 -*-
# -*- mode: org -*-
#+TITLE: Au-delà de la reproductibilité : la transparence de la recherche
#+AUTHOR: Sabrina Granger
#+STARTUP: overview indent inlineimages logdrawer
#+LANGUAGE: fr
** Introduction
Si l'on définit la reproductibilité comme le fait d'aboutir à des
résultats similaires à partir des mêmes données et des mêmes méthodes
que celles de l'étude initiale, plusieurs domaines de recherche semblent
exclus de la problématique. Lorsque l'objet d'étude est un phénomène
climatique rare, un événement historique ou lorsque le travail consiste
à interpréter des textes ou à énoncer des théorèmes, ce sont davantage
les *enjeux de transparence* qui prédominent. Janz distingue 3 types de
transparence (Janz 2018). Les objectifs à atteindre dans chaque domaine
vont se traduire différemment selon que l'on travaille avec des méthodes
quantitatives ou qualitatives :
- /data transparency/ : "/Providing full access to data itself/" ; il
s'agit là de fournir les jeux de données sur lesquels se fonde
l'analyse, mais Janz précise que la mise à disposition ne peut être
que partielle si on utilise des transcriptions d'entretiens, des vidéos.
- /analytic transparency/ : "/Information about data analysis/" ; il peut
s'agir de fournir les codes informatiques mais aussi d'indiquer
précisement sur quelles sources l'analyse s'appuie ou encore d'apporter des
commentaires complémentaires à l'analyse.
- /production transparency/ : "/Process of data collection/" ; il peut
s'agir de fournir ou de décrire les données brutes, de documenter
les variables. Mais l'objectif de transparence peut aussi consister
à expliquer selon quels protocoles les données ont été
collectées. On peut par exemple détailler les critères de sélection
des participants à une étude.
*Toutes les techniques de reproductibilité n'auront donc pas la même
importance en fonction des disciplines et des méthodes employées*.
** Quelques exemples de pratiques favorables à une recherche reproductible...
:PROPERTIES:
:CUSTOM_ID: quelques-exemples-de-pratiques-favorables-à-une-recherche-reproductible
:END:
La recherche reproductible ne constitue pas un ensemble prédéterminé de
techniques et de méthodes. Si le *partage de données* et/ou de *code
informatique* participe à une recherche plus reproductible, la pratique
émergente de la */pre-registration/* (Nosek /et al./ 2017) peut également
y concourir. L'une de ses finalités est de prévenir les risques de
HARKing - /Hypothesizing After the Results are Known/. La
/pre-registration/ intervient en amont du travail d'analyse. Un.e
chercheur.euse va ainsi formaliser ses hypothèses de recherche, ses
données, son /study design/ et son plan d'analyse ; on va par exemple
décrire la manière dont une variable va être mesurée, enregistrée. Ces
informations peuvent être sauvegardées /via/ des plateformes numériques
pour s'assurer par la suite que la démarche initialement décrite est
bien appliquée. La tenue d'un *cahier de laboratoire* classique peut
jouer un rôle similaire.
Il ne s'agit pas d'amputer la recherche de sa dimension exploratoire car
il est possible de documenter tout changement, mais d'indiquer en début
de processus la manière dont l'analyse sera conduite afin de mieux
distinguer post-diction et prédiction. En d'autres termes, l'un des
objectifs de la /pre-registration/ est d'aider le.a chercheur.euse à se
prémunir contre des biais, des erreurs de méthode.
Gardons à l'esprit que *la /pre-registration/ représente au mieux une
aide* et ne constitue pas un rempart contre la fraude. Par ailleurs,
*ce type de modalité de travail ne se substitue pas à la maîtrise des
concepts et des méthodes statistiques*.
Mais il existe également de nombreux cas où aucune de ces techniques ne
s'applique (données ne pouvant être partagées, absence de dimension
calculatoire ou informatique, etc.).
** ... qui appellent d'autres réponses : la transparence, une notion centrale de la recherche reproductible. Mais de quoi parle-t-on alors ?
:PROPERTIES:
:CUSTOM_ID: qui-appellent-dautres-réponses-la-transparence-une-notion-centrale-de-la-recherche-reproductible.-mais-de-quoi-parle-t-on-alors
:END:
Tout d'abord, *transparence n'est pas synonyme de mise à disposition, et
réciproquement* ! D'une part, il est courant de travailler sur des
données qui ne sont accessibles qu'à une poignée d'individus pour des
raisons matérielles (i.e. manuscrit ancien ou tout autre document unique
à consulter sur place) comme pour des raisons juridiques (i.e. données
de santé ou données personnelles plus généralement, données soumises à
des droits patrimoniaux). Est-on alors condamné.e à ignorer les
questions de reproductibilité et faut-il pour autant ne pas se
préoccuper de transparence ? Certainement pas. Ainsi, même lorsqu'on
utilise des données confidentielles, il s'avère nécessaire de les gérer
méthodiquement en les décrivant précisément, en documentant le protocole
de collecte, en assurant leur préservation. L'objectif est de conserver
ces informations pour soi, mais aussi à des fins de réfutabilité par un
tiers sous réserve de respecter un dispositif juridique précis. On
s'attachera alors à travailler en gardant à l'esprit que ces travaux
seront peut-être amenés à être accessibles à un plus grand nombre de
personnes dans le futur. Le *module 4 du Mooc* comporte quelques pistes
de réflexion sur ce sujet très vaste.
D'autre part, dans le cadre d'une recherche conduite avec des méthodes
qualitatives, le code (dans ce contexte, l'étiquetage appliqué aux
données) peut jouer un rôle majeur, mais son partage ne fournira qu'un
niveau d'information limité puisque l'intérêt des travaux réside dans
leur dimension interprétative. La mise à disposition des données est
donc très loin d'être suffisante pour garantir une compréhension des
travaux effectués. Nous vous invitons à vous reporter au Sujet 3 du
*module 3 du Mooc* ("L'épidémie de choléra à Londres en 1854") car il
illustre pleinement l'importance d'une analyse plus qualitative des
données (FIXME, ajouter la correction et le lien vers la correction).
*Le terme "transparence" renvoie donc plutôt au fait de rendre accessibles
à son lectorat les éléments sur lesquels s'est construit le raisonnement* :
sources citées, données analysées ou description des données, /corpus/, /etc/.
La notion de traçabilité occupe donc une place centrale. L'accent n'est pas
mis sur le fait d'aboutir aux mêmes conclusions.
L'importance de *donner accès aux éléments constitutifs de son
raisonnement* n'est pas une idée nouvelle et réside au cœur de la
démarche scientifique, indépendamment des outils et méthodes utilisées
(analyse quantitative, analyse qualitative, /etc/.). Mais la
démultiplication des données disponibles (/corpus/ numérisés, catalogues
de références, sources en texte intégral, données obtenues grâce à des
logiciels, /etc/.) et leur fragilité (obsolescence des supports, des
formats et des logiciels) constituent autant d'*atteintes potentielles à
la traçabilité de la recherche*.
À tous les stades du travail, l'objectif de transparence peut être mis à
mal : recherche des sources et analyse de la littérature ; saisie et
traitement des données ; constitution des /corpus/ ; présentation des
résultats ; rédaction.
Par ailleurs, *nul besoin de travailler avec des bases de données, des données d'enquêtes
ou encore des jeux de données massifs pour être concerné.e par ces problématiques*.
Par exemple, il peut être difficile pour un.e chercheur.euse d'évaluer la
robustesse d'une hypothèse de recherche fondée sur la présence d'une expression
donnée dans un /corpus/ si celui-ci n'est pas interrogeable de manière
automatisée. On s'expose alors à des déconvenues. L'exemple est tiré de
l'ouvrage de Bernard et Bohet cité dans la bibliographie (Bernard and Bohet 2017) :
un chercheur affirme qu'il n'y a pas d'occurrence de l'expression
"illusions perdues" dans le roman éponyme de Balzac. Si l'expression est
en effet absente du roman, une recherche dans le document permet de
faire émerger plusieurs occurrences du terme "illusions", notamment un
passage d'une lettre de Lucien : "Paris est à la fois toute la gloire et
toute l'infamie de la France, j'y ai déjà perdu bien des illusions, et
je vais en perdre encore d'autres". Ce résultat appelle dès lors une
analyse bien plus nuancée que l'hypothèse initiale.
Cette anecdote n'est évidemment pas à considérer comme un argument
susceptible de discréditer les approches qualitatives par rapport aux
approches quantitatives ou l'inverse. Ces approches sont complémentaires
et cet exemple illustre avant tout le fait qu'un biais de confirmation
dont on n'a pas conscience ou une visualisation de données inadaptée
peuvent conduire à des erreurs d'interprétation majeures, et ce même si
les chiffres sont corrects. Seul le fait de garder une trace rigoureuse
de la démarche et de l'automatiser autant que possible permet de
débusquer et de corriger les erreurs potentielles.
*Le recours au numérique est ici considéré comme un outil parmi d'autres
au service d'un cadre méthodologique*, permettant entre autres de
limiter les risques d'oubli et d'erreurs, de disposer d'outils de
vérification. De fait, se pose la question du degré de contrôle possible
de ces outils : *sous quelles conditions est-il raisonnable de s'en remettre à
des traitements automatisés dès lors qu'on veut s'assurer d'une recherche transparente ?*
Autant que faire se peut, le recours à des *logiciels /open source/* constitue
une première étape dans ce sens : le code source des logiciels commerciaux
demeure en effet inaccessible. Ensuite, acquérir progressivement un socle de compétences
techniques permet d'appréhender le fonctionnement général d'un logiciel.
*Il ne s'agit pas forcément d'en comprendre le paramétrage dans le détail, mais d'avoir suffisamment
de notions pour comprendre ce qu'on obtient en sortie et le crédit qu'on peut lui apporter*.
Les ingénieur.e.s en traitement et analyse de données et les
statisticien.ne.s des équipes de recherche peuvent vous aider à
appréhender ces aspects techniques, mais aussi culturels car les
logiciels naissent dans un environnement épistémologique donné.
** Le /codebook/, un exemple d'outil pour les méthodes qualitatives
:PROPERTIES:
:CUSTOM_ID: le-codebook-un-exemple-doutil-pour-les-méthodes-qualitatives
:END:
Que l'on décide de partager ou non ce type de données, concevoir un
*/codebook/* (Saldaña 2016) peut être utile aux chercheurs.euses
recourant aux *méthodes qualitatives*. Le terme "code" s'entend ici de
la sorte : "/A code in qualitative inquiry is most often a word or short phrase that symbolically assigns a summative, salient, essence-capturing, and/or evocative attribute for a portion of language-based
or visual data. The data can consist of interview transcripts, participant observation field notes, journals, documents, literature, artifacts, photographs, video, websites, e-mail correspondence, and so on./" (Saldaña 2016)
*Que l'on code les données à l'aide d'un logiciel CAQDAS (Computer Assisted qualitative Data Analysis
Software) ou manuellement, le processus de codage ou d'étiquetage des données est itératif* :
une première étape exploratoire permet d'aboutir à une seconde phase où
l'étiquetage devient plus sélectif, théorique. L'étape de codage appelle souvent
plusieurs cycles d'adaptation, ainsi que le rappelle Saldaña :
"/As you code and recode, expect -- or rather, strive for -- your codes and categories to become more refined. Some of your First Cycle codes may be later subsumed by other codes, relabeled,
or dropped all together. As you progress toward Second Cycle coding, there may be some rearrangement and reclassification of coded data into different and even new categories./"
(Saldaña 2016) Par ailleurs, non seulement les codes évoluent au fil de l'analyse,
mais leur nombre peut aussi augmenter. La figure ci-dessous illustre le cycle de
conception des codes (Roberts, Dowell, and Nie 2019).
[[file:ROBERTS-cycle-codebook.png]]
De fait, la nécessité de suivre ces évolutions s'impose tout du long du
processus de recherche. Un /codebook/ peut répondre au besoin de suivi
des évolutions puisqu'il s'agit d'*un document permettant d'une part, de recenser tous les codes appliqués, d'autre part, de consigner ses
choix et de suivre leur évolution*. Ainsi, un /codebook/ représente plus qu'un
simple index. Il existe différents types de /codebooks/ : certains se
focalisent sur la description des données. Le /codebook/ constitue un
outil de suivi au service de la dimension interprétative du travail
d'analyse.
Les rubriques principales d'un /codebook/ sont les suivantes :
- intitulé du code
- courte description des finalités du code
- critères d'inclusion, i.e. sur quelles données ou quel phénomène
utiliser le code. Il s'agit de formaliser les critères à réunir pour
recourir au code
- critères d'exclusion, i.e. critères, cas particulier de données où le
code ne doit pas être utilisé
- exemples typiques : sélection de quelques cas qui illustrent le mieux
les critères d'utilisation
- exemples atypiques : sélection de cas extrêmes, atypiques pour
lesquels l'usage du code est requis
- "presque, mais non" ("/close, but no/") : des cas où l'on serait
tenté.e d'utiliser le code, alors que les données ne correspondent pas
Ci-dessous, un exemple de /codebook/ (Roberts, Dowell, and Nie 2019) :
[[file:ROBERTS_codebook.png]]\\
Enfin, *le /codebook/ lui-même constitue un document à gérer* : il faut
gérer ses versions successives.
Ce type de travail peut sembler fastidieux, mais tenter de se souvenir
de son propre étiquetage peut l'être encore davantage, /a fortiori/ en
cas de travail collaboratif. D'ailleurs, lorsque le codage est conçu
collectivement, il peut être utile de désigner un /codebook editor/
chargé de coordonner les ajouts, les suppressions, les évolutions.
Concevoir et gérer un /codebook/ nécessite du temps, mais cette démarche
de documentation apporte des garanties : "/It was thought that the codebook improved the potential
for inter-coder agreement and reliability testing and ensured an accurate description of analyses/."
(Roberts, Dowell, and Nie 2019)
** /Quid/ des aspects non computationnels de la recherche ?
:PROPERTIES:
:CUSTOM_ID: quid-des-aspects-non-computationnels-de-la-recherche
:END:
Dans le cas des *disciplines ne faisant pas appel à des méthodes fondées
sur le numérique*, la question de la transparence se pose en d'autres
termes. Par exemple, les techniques de traitement de /corpus/ numériques
n'offrent qu'un intérêt limité pour un.e chercheur.euse en lettres
travaillant sur la manière dont une œuvre est interprétée en fonction
des époques car ce type de recherche appelle une autre forme
d'exploitation du texte. En revanche, la rigueur dans l'utilisation des
sources bibliographiques (revue de littérature, constitution de
l'appareil bibliographique, /etc/.) constitue le critère déterminant
d'une recherche transparente. Dès lors, le recours à un *gestionnaire de
références bibliographiques* est très adapté. Une autre famille d'outils
peut également devenir utile quand on travaille uniquement sur des
textes : les *outils de contrôle de versions*. Il peut en effet être
difficile de garder le suivi des évolutions du texte quand on rédige une
monographie, une thèse ou lorsque la rédaction est collective. Un
logiciel de forge tel que GitLab n'est par exemple pas seulement utile à
des développeurs : il peut aider à gérer tout type de contenu, pas
seulement du code.
** Sources et compléments
:PROPERTIES:
:CUSTOM_ID: sources-et-compléments
:END:
Bernard, Michel, and Baptiste Bohet. 2017. Littérométrie: outils
numériques pour l'analyse des textes littéraires. Paris, France: Presses
Sorbonne nouvelle.
Freelon, Deen. 2010. 'ReCal: Intercoder Reliability Calculation as a Web
Service'. International Journal of Internet Science 5 (1): 20--33.
[[http://dfreelon.org/utils/recalfront/][Recal]] : "ReCal (“Reliability
Calculator") is an online utility that computes intercoder/interrater
reliability coefficients for nominal, ordinal, interval, or ratio-level
data. It is compatible with Excel, SPSS, STATA, OpenOffice, Google Docs,
and any other database, spreadsheet, or statistical application that can
export comma-separated (CSV), tab-separated (TSV), or
semicolon-delimited data files. ReCal consists of three independent
modules each specialized for different types of data. The following
table will help you select the module that best fits your data. (If you
do not know whether your data are considered nominal, ordinal, interval,
or ratio, please consult this Wikipedia article to find out more about
these levels of measurement.)"
Heimburger, Franziska, and Émilien Ruiz. 2011. 'Faire de l'histoire à
l'ère numérique : retours d'expériences'. Revue dhistoire moderne
contemporaine n° 58-4bis (5): 70--89.
Janz, Nicole. 2018. 'Research Reproducibility in Political Science'.
presented at the NCRM Research Methods Festival, University of Bath,
July 5. https://www.ukdataservice.ac.uk/media/622140/janz_rmf_qualtransperency_bath2018.pdf.
Nosek, Brian A., Charles R. Ebersole, Alexander DeHaven, and David
Mellor. 2017. 'The Preregistration Revolution'. Open Science Framework,
June. https://doi.org/10.17605/OSF.IO/2DXU5.
Roberts, Kate, Anthony Dowell, and Jing-Bao Nie. 2019. 'Attempting
Rigour and Replicability in Thematic Analysis of Qualitative Research
Data; a Case Study of Codebook Development'. BMC Medical Research
Methodology 19 (1): 66. https://doi.org/10.1186/s12874-019-0707-y.
Saldaña, Johnny. 2016. The Coding Manual for Qualitative Researchers.
Third Edition. Los Angeles: SAGE.
*Ressources complémentaires*
Dymond-Green, Neil, and UK Data Service. 2018. 'Show Me the Data:
Research Reproducibility in Qualitative Research -- Data Impact Blog'.
Data Impact Blog (blog). 18 September 2018.
http://blog.ukdataservice.ac.uk/show-me-the-data/.
[[https://programminghistorian.org/en/][The Programming Historian]] :
"We publish novice-friendly, peer-reviewed tutorials that help humanists
learn a wide range of digital tools, techniques, and workflows to
facilitate research and teaching. We are committed to fostering a
diverse and inclusive community of editors, writers, and readers."
*Ressources sur la gestion de données (dont données personnelles) :
gestion, partage*
Andreassen, Helene N. 2019. 'How to Share Research Data'. University
Library : The Arctic University of Norway, November 5. http://site.uit.no/rdmtraining/files/2019/11/En_share_2019-11-05.pdf.
Andreassen, Helene N., and Erik Axel Vollan. 2018. 'Research Data
Management Part 2: (Qualitative) Data Containing Personal/Sensitive
Information'. University Library : The Arctic University of Norway,
October 11.
http://site.uit.no/rdmtraining/files/2018/10/TakeControlResearchData_PART_2_Qualitative.pdf.
Beagrie, Neil. 2019. 'What to Keep : A Jisc Research Data
Study'. JISC. https://repository.jisc.ac.uk/7262/1/JR0100_WHAT_RESEARCH_DATA_TO_KEEP_FEB2019_v5_WEB.pdf.
Boistel, Romain, Frédérique Bordignon, and Lionel Maurel. 2019. 'Aspects
Juridiques de La Gestion et Du Partage Des Données'. In Journées
Nationales de La Science Ouverte 2019. Paris, France.
https://hal-enpc.archives-ouvertes.fr/hal-02372271.
Caporali, Arianna, Amandine Morisset, and Stéphane Legleye. 2015. 'La
mise à disposition des enquêtes quantitatives en sciences sociales :
l'exemple de l'Ined'. Population (édition française) 70 (3): 567--97.
https://doi.org/10.3917/popu.1503.0567.
National Science Foundation, Center for Qualitative and Multi-Method
Inquiry, and Syracuse University. n.d. 'Qualitative Data Repository'.
Accessed 22 January 2020. https://qdr.syr.edu/discover.
# -*- coding: utf-8 -*-
# -*- mode: org -*-
#+TITLE: Les références bibliographiques, un autre vecteur de transparence
#+AUTHOR: Sabrina Granger
#+STARTUP: overview indent inlineimages logdrawer
#+LANGUAGE: fr
** Introduction
Il ne s'agit pas ici de traiter des questions de normes de présentation
bibliographique : chaque discipline, voire chaque revue possède ses
critères formels.
En outre, le degré de formalisme des références bibliographiques diffère
selon les pratiques disciplinaires : dans certains domaines, il faut
citer la pagination, voire le paragraphe concerné alors que dans
d'autres champs, cette précision n'est pas requise. En fonction du degré
de précision requis dans sa discipline, on adaptera ses modalités de
prise de notes pour retrouver les informations requises lors de la
rédaction.
** En quoi la question des références bibliographiques a-t-elle trait à la question de la reproductibilité ?
:PROPERTIES:
:CUSTOM_ID: en-quoi-la-question-des-références-bibliographiques-a-t-elle-trait-à-la-question-de-la-reproductibilité
:END:
Une gestion rigoureuse de l'appareil bibliographique constitue un gage
majeur de transparence, qu'on travaille en sciences dites dures comme en
lettres, langues, sciences humaines et sociales.
Dans la perspective des sciences humaines et plus particulièrement des
disciplines recourant à des méthodes qualitatives ou reposant
essentiellement sur de l'interprétation de textes, l'enjeu principal est
moins de reproduire des résultats que de donner à d'autres
chercheurs.euses la possibilité d'étayer comme de réfuter le propos
défendu. Or, les références bibliographiques donnent à voir les étapes
de la construction du raisonnement et des hypothèses.
La bibliographie constitue donc un faisceau d'indices de transparence
pour un lectorat de chercheurs.euses : *la liste des sources est-elle
exhaustive et représentative de l'ensemble des points de vue sur la question ou au contraire, présente-t-elle d'importants biais de sélection ?*
** Gérer de la manière la plus systématique possible ses sources participe à réduire les erreurs de /reporting/
:PROPERTIES:
:CUSTOM_ID: gérer-de-la-manière-la-plus-systématique-possible-ses-sources-participe-à-réduire-les-erreurs-de-reporting
:END:
Par erreur de /reporting/, on n'entend pas le fait d'aboutir à des
conclusions différentes voire divergentes de celles de l'auteur.e de la
référence citée. Il est question ici d'une erreur d'interprétation du
propos initial. La pratique des citations dites de seconde main (ou
citations secondaires) peut ainsi induire l'auteur.e en erreur dans la
mesure où le texte cité n'est pas appréhendé dans son contexte original,
mais à travers le filtre d'un.e autre auteur.e.
/Quid/ du cas où *le texte original s'avère inaccessible* ? Votre
lectorat doit disposer des références précises de la source citant le
passage que vous reprenez. Par exemple : (Brown, 2010 cité par Jamison,
2012). Afin de ne pas laisser entendre de manière erronée que vous avez
consulté directement la source :
- soit la bibliographie mentionne uniquement le document citant la source
- soit la référence est incluse dans la bibliographie dans une liste
séparée ou signalée comme source non consultée au moyen d'un signe distinctif (un astérisque par ex.)
*Le respect d'un formalisme dans la rédaction de la citation et de la
bibliographie offre ainsi des repères à votre lectorat*. En cas
d'impossibilité d'accéder à la source, une bonne connaissance de
l'auteur.e citant le passage que vous souhaitez reprendre vous permet
d'évaluer le degré de fiabilité de la référence utilisée.
** Adopter un style bibliographique pour identifier plus facilement les sources citées
Que votre document fasse quatre ou mille pages, appliquer un style
bibliographique vous permet d'éviter d'oublier de mentionner des
éléments nécessaires à l'identification d'un document. Un style
bibliographique fournit en effet une trame des informations à compléter
en fonction des types de documents cités : article de revue
scientifique, monographie, billet de blog, article d'encyclopédie,
présentation, /etc/. Certains champs sont facultatifs. La
[[http://www.sudoc.fr/146773233][norme ISO 690]] vous permet
d'identifier les éléments à mentionner obligatoirement selon le type de
document cité. En effet, même si l'import du descriptif dans votre
gestionnaire de références est automatisé, la notice obtenue peut
s'avérer inexploitable. Tout va dépendre de la qualité du gisement
d'informations consulté pour importer la notice. Ci-dessous, nous
pouvons constater que pour une même référence, la qualité des
descriptions varie selon le type d'outil consulté (moteur de recherche
généraliste vs catalogue de bibliothèque).
[[./comparatif-biblio.png]]
Dans l'exemple ci-dessus, la mention de l'édition est une donnée
importante pour identifier le document cité. Enfin, il est plus facile
pour votre lectorat d'appréhender les références bibliographiques
lorsque leur présentation est standardisée. Les gestionnaires de
références bibliographiques permettent d'appliquer des éléments formels
de manière homogène et automatisée.
** Automatiser la gestion de ses références : qu'en attendre ou pas ?
:PROPERTIES:
:CUSTOM_ID: automatiser-la-gestion-de-ses-références-quen-attendre-ou-pas
:END:
Il existe plusieurs solutions. Parmi elles,
[[https://www.zotero.org/][Zotero]] constitue une solution gratuite et
/open source/ utilisée par une communauté d'utilisateurs grandissante et
dynamique. Les fonctionnalités décrites ci-dessous reprennent grandement
celles de Zotero.
Un gestionnaire de références bibliographiques permet entre autres
de :
- *importer des descriptions bibliographiques* depuis des catalogues, des moteurs de recherche, des sites web, des plateformes d'éditeurs
- *centraliser* les références collectées et constituer ainsi sa base
de données personnelle, à la différence des outils proposés dans les
traitement de texte. Word permet par exemple de créer une base de
données de références bibliographiques, mais celle-ci est propre à
un document. Ainsi, pour citer dans plusieurs documents une même référence, je dois la créer dans chaque document.
- *exporter des références bibliographiques sous différents formats* : .html, .ris, .rtf
- *partager ses références* soit de manière récurrente en créant des
bibliothèques de groupes, soit de manière ponctuelle en exportant
des références
- *citer* des sources dans du texte en leur appliquant un style donné
- éditer les descriptions collectées pour les corriger et les
améliorer
- *annoter les références bibliographiques* : vous pouvez
par exemple associer à une description des passages que vous trouvez
particulièrement intéressants ; les notes prises sur des supports
extérieurs à votre gestionnaire (cahiers, fichiers, etc.) peuvent
ainsi être associées au descriptif du document. Ces notes sont à
usage internes et non visibles lors de la citation de la référence.
- *organiser* des volumes importants de données ; vous pouvez créer des
dossiers et des sous-dossiers ; classer les descriptifs dans
plusieurs dossiers sans pour autant occasionner de doublons ;
étiqueter des références pour indiquer celles que vous jugez
fondamentales ou signaler les références en attente de lecture ;
faire des renvois de références internes à sa bibliothèque ; créer
des dossiers "dynamiques" : en sauvegardant une requête, vous créez
un dossier où seront automatiquement classées toutes les références
répondant aux critères enregistrés, indépendamment du classement manuel effectué. La liste n'est pas exhaustive.
- *dédoublonner* les références ; on parle ici des descriptifs importés
plusieurs fois et pas des références classées dans plusieurs
dossiers
- *naviguer dans ses références* grâce aux outils d'interrogation
- travailler sur plusieurs postes sans problème de synchronisation de la base de références bibliographiques
Un outil comme Zotero dispose même
d'[[https://www.zotero.org/blog/retracted-item-notifications/][un plugin
dédié au suivi des articles rétractés]].
Les gestionnaires de références bibliographiques automatisent la plupart
des tâches, mais resteront toujours à la charge de l'utilisateur :
- une étape d'*amélioration et de correction des données importées* : la
qualité des sorties dépend en premier lieu de la qualité des données
d'entrée. Or, si le gestionnaire peut identifier quelles sont les
données importables dans une page web, il n'est pas en mesure
d'évaluer leur qualité descriptive. Le problème peut être d'ordre
quantitatif (i.e. : tous les champs obligatoires ne sont pas
complétés), comme qualitatif (i.e. : les données comportent des
inexactitudes, on constate des problèmes de graphie). Les pages de
résultats d'un moteur de recherche généraliste offrent par exemple des
descriptifs d'une qualité inférieure à celles d'un catalogue de
bibliothèque et pour le lecteur, il peut être difficile d'identifier
précisément la source citée.\\
- une *méthode de tri et d'organisation des données* ; ex. : il s'agit
de prévoir régulièrement un nettoyage de sa base en dédoublonnant les
références, revoir l'arborescence de ses dossiers, /etc/. Certes, les
gestionnaires de références disposent de fonctionnalités de recherche,
mais le problème des doublons reste par exemple entier sans nettoyage
régulier. La difficulté est majeure : comme évoqué ci-dessus, la
qualité des notices descriptives peut varier fortement. Or, si des
doublons d'une même référence sont présents dans la base, tantôt vous
utiliserez la notice A, tantôt la notice A' pour renvoyer à une même
source. Or, ces 2 notices peuvent ne pas être équivalentes du tout :
certes, elles sont censées renvoyer vers un même document, mais leur
niveau d'information peut varier. Enfin, au moment de créer la
bibliographie qui recense l'ensemble des références citées dans le
texte, les notices A et A' apparaîtront toutes les deux alors qu'elles
renvoient à la même source car le gestionnaire de références considère
qu'il s'agit de 2 notices.
- l'*enrichissement des informations /via/ l'annotation des notices* :
on pourrait considérer cette étape comme facultative. Techniquement,
rien n'empêche en effet de citer une source même si sa notice n'est
pas accompagnée d'annotations. Mais retrouver facilement les extraits
majeurs d'une source /via/ les annotations participe à fiabiliser
votre gestion des références : descriptifs bibliographiques et
extraits citables sont ainsi associés et les risques d'attribuer à
tort une citation à une source s'amoindrissent. Ce type d'erreur est
d'autant plus présent si vous vous appuyez sur plusieurs références
d'un même auteur. Enfin, en annotant vos notices /via/ le gestionnaire
de références, vous pouvez facilement retrouver les extraits
sélectionnés grâce aux fonctionnalités de recherche.
[[https://github.com/jkitchin/org-ref][Si vous travaillez avec Emacs,
org-ref vous permet d'annoter vos références]].
La puissance et la facilité d'utilisation d'un gestionnaire de
références constituent une arme à double tranchant : encore plus
rapidement qu'avec une méthode manuelle, l'utilisateur.rice est
confronté.e à une masse importante de références potentielles. L'étape
de revue de la littérature peut dès lors devenir envahissante dans le
processus de recherche, surtout dans le cadre d'un travail de thèse.
Analyser sa bibliothèque de références à la lumière de sa question de
recherche constitue une méthode de tri non automatisable, mais plus
efficace que la mise en place de filtres.
** /Quid/ du texte intégral ?
:PROPERTIES:
:CUSTOM_ID: quid-du-texte-intégral
:END:
Quand on interroge une plateforme d'éditeur, il est aussi possible de
collecter le texte intégral des articles (sous réserve des abonnements
aux revues souscrits par votre institution) au moment où l'on charge son
descriptif bibliographique dans son gestionnaire. Mais ces imports
soulèvent rapidement la question du quota de stockage gratuit pour
l'utilisateur.
Sans entrer dans le détail des alternatives, vous êtes invité.e à considérer
cette fonctionnalité avant tout comme une option de confort car la pertinence
des gestionnaires de références réside avant tout dans l'aide qu'ils apportent
dans la gestion et la citation des références bibliographiques. En d'autres
termes, *mieux vaut un descriptif complet sans texte intégral plutôt qu'une
référence lacunaire accompagnée de son texte intégral* : lors de l'étape de la
citation, c'est le descriptif et non pas le fichier joint qui est exploité.
** Compléments
:PROPERTIES:
:CUSTOM_ID: compléments
:END:
Le [[https://zotero.hypotheses.org/][blog Zotero francophone]] pour des
conseils, l'actualité des développements
Le [[https://www.zotero.org/][site Zotero]] comporte de la documentation
et des [[https://forums.zotero.org/discussions][forums]]
L'[[https://www.zotero.org/styles][entrepôt des styles Zotero]],
gratuitement téléchargeables
Les usages de la communauté des *juristes francophones* présentent des
spécificités jusqu'à présent peu ou mal gérées par les styles existant
dans l'entrepôt Zotero. L'exemple du style conçu pour l'école doctorale
"Droit" de l'Université de Bordeaux apporte des pistes de réflexion :
Flamerie de Lachapelle, Frédérique. 2019. 'Créer un style pour Zotero
correspondant à une norme bibliographique juridique : retour
d'expérience bordelais. Billet invité'. Billet. UrfistInfo (blog). 2
July 2019. [[https://urfistinfo.hypotheses.org/3305]].
Muller, Caroline. 2018. 'Cinq ans d'usage de Zotero, un bilan'. Billet.
Acquis de conscience (blog). 9 March 2018.
[[https://consciences.hypotheses.org/1184]].
Sergiadis, Ashley. 2019. 'Evaluating Zotero, SHERPA/RoMEO, and Unpaywall
in an Institutional Repository Workflow'. Journal of Electronic
Resources Librarianship, September. [[https://dc.etsu.edu/etsu-works/4739]].
# -*- coding: utf-8 -*-
# -*- mode: org -*-
#+TITLE: Exploiter des textes avec la TEI
#+Author: Sabrina Granger
#+STARTUP: overview indent inlineimages logdrawer
#+LANGUAGE: fr
** Introduction
La question de la reproductibilité, pour soi comme pour les autres,
soulève entre autres celle de la pérennité de l'information
scientifique. Or, les données produites avec des logiciels propriétaires
et/ou sous des formats spécifiques à un outil offrent encore moins de
garantie d'accessibilité sur le long terme. La Text Encoding Initiative
(TEI) constitue un exemple de format de balisage standard.
** A quels besoins de recherche la TEI répond-elle ?
Si vous utilisez des textes (littéraires, législatifs, archives,
/etc/.), une technique de balisage de données peut vous permettre
d'aller au-delà du seul décompte brut d'occurrences : la Text Encoding
Initiative (TEI). Lou Burnard, l'un des fondateurs de la TEI, prend
l'exemple du mot "Paris" : s'agit-il de la ville du Texas, de la
capitale fraçaise, voire du prénom d'une héritière américaine ? Si trier
manuellement le bon grain de l'ivraie est possible - mais non sans
risque d'erreur - à l'échelle d'un petit /corpus/, il s'avère nettement
plus complexe de travailler sur *une masse de documents plus importante
et/ou plus hétérogène*. La TEI permet de résoudre ce problème.
Dans ce cas, /quid/ des /corpus/ peu volumineux ? *Le balisage en TEI
permet de rendre vos données textuelles "intelligentes"*: il est
possible de *baliser des personnages, des langues de citation, des
catégories grammaticales, des passages barrés*, /etc/. Qui peut le plus
peut le moins : s'il existe plus de 500 éléments combinables entre eux,
il est possible de travailler avec un jeu de balises réduit. Pour
traiter un roman, 5 ou 6 balises peuvent suffire.
** Quelles garanties de pérennité ?
L'encodage des données en TEI permet de concevoir des /corpus/ à très
forte valeur ajoutée. Dès lors se posent les questions de l'*accès*, de
la *conservation* voire du *partage* de cette plus-value. Si le recours
à certains logiciels proposant des outils d'encodage de données est
commode, sur le long terme, leur utilisation peut nuire à la
reproductibilité de vos travaux. En effet, l'un des avantages de la TEI
est d'offrir un *codage standard, affranchissant ainsi ses utilisateurs
de toute dépendance logicielle*.
Si certains logiciels intègrent le codage en TEI, d'autres reposent sur
des codages qui leur sont propres (ex. Alceste, Lexico3, /etc/.) ainsi
que le souligne Burnard : "Si vous souhaitez partager les ressources
textuelles que vous créez avec d'autres personnes (ou avec vous-même à
quelques décennies de distance), vous devriez vous préoccuper de la
tendance de nombreux systèmes informatiques à appliquer leur propre
façon de stocker l'information" (Burnard 2014).
*Normalisation n'est pas synonyme de fermeture* : l'un des enjeux de la
TEI est d'offrir un système de balise évolutif grâce à son
extensibilité.
** La TEI en pratique
Bernard et Bohet définissent ainsi la TEI (Bernard and Bohet 2017) : "Il
s'agit d'un balisage s'appuyant sur le langage XML et qui se présente
comme un dictionnaire de balises couvrant à peu près toutes les
situations". Il s'agit de permettre à une machine de lire ces données.
La TEI permet d'*introduire dans le texte des informations allant bien
au-delà des éléments formels* comme le montre
[[https://fr.wikipedia.org/wiki/Text_Encoding_Initiative][ce comparatif
tiré de Wikipédia]] entre d'une part, un encodage en HTML, où l'on prend
en compte uniquement les aspects de présentation, et d'autre part, un
encodage en TEI, où l'on peut introduire des informations sur les
personnages, la versification des éléments.
Le travail s'effectue sur des données numériques ; si les données sont
issues d'une numérisation, elles doivent au préalable être traitées avec
un logiciel de reconnaissance optique des caractères (OCR) (Humanum
2015).
Il existe des *éditeurs* tels que
[[https://framalibre.org/content/xml-copy-editor][XML Copy Editor]].
Certains logiciels incluent un *convertisseur* ; on peut citer :
- le [[http://textometrie.ens-lyon.fr/spip.php?rubrique96][logiciel TXM]]
- le [[http://obvil.sorbonne-universite.site/developpements/odette][logiciel Odette]] permet de passer d'un document en traitement de texte à des
données en XML/TEI
Exemple de texte encodé : Oscar Wilde. /The Importance of Being Earnest/
[[https://teibyexample.org/examples/TBED05v00.htm?target=wilde][disponible
sur le site web TEI by example]]
** Sources
Bernard, Michel, and Baptiste Bohet. 2017. Littérométrie: outils
numériques pour l'analyse des textes littéraires. Paris, France: Presses
Sorbonne nouvelle.
Burnard, Lou. 2014. What Is the Text Encoding Initiative? : How to Add
Intelligent Markup to Digital Resources. Encyclopédie Numérique.
Marseille: OpenEdition Press. http://books.openedition.org/oep/426.
Humanum. 2015. 'Le Guide Des Bonnes Pratiques Numériques'. TGIR des
humanités numériques.
https://www.huma-num.fr/ressources/guide-des-bonnes-pratiques-numeriques.
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Interface de Gitlab dans ce Mooc
#+DATE: <2019-03-26 mar.>
#+AUTHOR: Arnaud Legrand, Laurence Farhi
#+EMAIL: arnaud.legrand@imag.fr
#+LANGUAGE: fr
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
** Access your Gitlab repository
This section describes the successive steps involved to access your
Gitlab repository after from the FUN platform after clicking on the
button "*Accéder à Gitlab / Access to Gitlab*".
- You reach the following form:
#+BEGIN_CENTER
[[file:gitlab_images/sign_in_gitlab.png]]
#+END_CENTER
- Click on **Sign in**. below "*Connexion*" label. The "Connexion Admin" frame is reserved for
Gitlab interface administrators. Authentication is automatic at that
stage.
#+BEGIN_CENTER
[[file:gitlab_images/projects.png]]
#+END_CENTER
The long string replaced here by =xxx= is the login you will have to
use in Git to synchronize with GitLab.
- *NB* : You must reach GitLab from the FUN platform. You are likely to get a "405 error" if you are using the following address: https://app-learninglab.inria.fr/gitlab/users/sign_in.
#+BEGIN_CENTER
[[file:gitlab_images/erreur405.png]]
#+END_CENTER
** Recover your password
To recover a predefined password you must use [[https://app-learninglab.inria.fr/jupyterhub/services/password][Gitlab
credentials retrieval tool]]. One gets then the login and password.
#+BEGIN_CENTER
[[file:gitlab_images/password_retrieval.png]]
#+END_CENTER
** Modify your password
You can change this password in "Account / Parameters / Password". We do not recommend doing it since that will block you from using the Jupyter notebooks of this MOOC.
#+BEGIN_CENTER
[[file:gitlab_images/password.png]]
#+END_CENTER
** To go learn more about git/Gitlab
If you want to go further, few tutorial videos are gathered in [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][sequence "7. Installations, configurations, references" of module 2]]
of this MOOC.
** In case of problems with Gitlab
In case of problem, contact us via the forum. In order to help you
solve any problems, please give us your LTI identifier (external
identifier automatically assigned for GitLab and Jupyter)
that you can find on your GitLab account (see capture below).
#+BEGIN_CENTER
[[file:gitlab_images/gitlab_id_lti.jpg]]
#+END_CENTER
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Interface de GitLab dans ce Mooc
#+DATE: <2019-03-26 mar.>
#+AUTHOR: Arnaud Legrand, Laurence Farhi
#+EMAIL: arnaud.legrand@imag.fr
#+LANGUAGE: fr
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
** Accéder à son espace GitLab
Cette section décrit étape par étape comment accéder à votre espace GitLab depuis la
plateforme FUN après avoir cliqué sur le bouton "*Accéder à GitLab / Access to GitLab*".
- Vous arrivez sur le formulaire suivant :
#+BEGIN_CENTER
[[file:gitlab_images/sign_in_gitlab.png]]
#+END_CENTER
- Connectez-vous en cliquant sur le bouton "*Sign in*" situé sous
"*Connexion*". Le cadre "Connexion Admin" est réservé aux
administrateurs de l'interface GitLab. L'authentification est automatique à cette étape.
#+BEGIN_CENTER
[[file:gitlab_images/projects.png]]
#+END_CENTER
La grande chaîne de caractères remplacée ici par =xxx= est le login
qu'il faudra utiliser dans git pour accéder à GitLab.
- *NB* : Il faut accéder à GitLab depuis la plateforme FUN. Vous risquez
d'obtenir une erreur 405 en accédant directement à la page [[https://app-learninglab.inria.fr/gitlab/users/sign_in]].
#+BEGIN_CENTER
[[file:gitlab_images/erreur405.png]]
#+END_CENTER
** Récupérer son mot de passe
Pour récupérer le mot de passe prédéfini, il faut utiliser le [[https://app-learninglab.inria.fr/jupyterhub/services/password][GitLab
credentials retrieval tool]]. On retrouve alors le login et le mot de
passe.
#+BEGIN_CENTER
[[file:gitlab_images/password_retrieval.png]]
#+END_CENTER
** Modifier son mot de passe
Il est possible de modifier ce mot de passe dans "Account / Paramètres / Mot de passe". Mais nous vous déconseillons de le faire
car cela vous empêchera d'utiliser les notebook Jupyter du MOOC.
#+BEGIN_CENTER
[[file:gitlab_images/password.png]]
#+END_CENTER
** En savoir plus sur git/GitLab
Enfin, pour ceux qui veulent aller plus plus loin et en savoir plus
sur l'outil de gestion de version git sur lequel s'appuie GitLab,
quelques vidéos de démonstration sur git et GitLab sont proposées dans
la [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][séquence "7. Installations, configurations, references" du module 2]]
de ce Mooc ainsi que des ressources pour apprivoiser git en ligne de commandes.
** Que faire en cas de problème
En cas de problème, contactez-nous via le forum. Afin de pouvoir vous
aider à résoudre vos problèmes éventuels,
merci de nous communiquer votre identifiant LTI (identifiant externe
attribué automatiquement pour GitLab et Jupyter) que vous pouvez
retrouver sur votre compte GitLab (cf. capture ci-dessous).
#+BEGIN_CENTER
[[file:gitlab_images/gitlab_id_lti.jpg]]
#+END_CENTER
<div id="content">
<h1 class="title">Introduction à Markdown</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org99b4a98">Syntaxe</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org28d66f2">Headers</a></li>
<li style="margin-bottom:0;"><a href="#orgc27acce">Emphasis</a></li>
<li style="margin-bottom:0;"><a href="#org50640c4">Lists</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org11d3314">Unordered</a></li>
<li style="margin-bottom:0;"><a href="#org0453134">Ordered</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#orgda3d80b">Images</a></li>
<li style="margin-bottom:0;"><a href="#org7cb67aa">Links</a></li>
<li style="margin-bottom:0;"><a href="#orge09365f">Blockquotes</a></li>
<li style="margin-bottom:0;"><a href="#orgfa4914a">Inline code</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#org8737c71">Écrire des Maths</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org6dc05c1">Lettres grecques</a></li>
<li style="margin-bottom:0;"><a href="#org2d8310d">Fonctions et opérateurs</a></li>
<li style="margin-bottom:0;"><a href="#org69729f8">Exposants et indices</a></li>
<li style="margin-bottom:0;"><a href="#org39a711a">Fractions, coefficients binomiaux, racines, &#x2026;</a></li>
<li style="margin-bottom:0;"><a href="#org4b11fa4">Sommes et intégrales</a></li>
<li style="margin-bottom:0;"><a href="#org55cc222">Déguisements</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#org5bb515f">Autour de <code>markdown</code></a></li>
</ul>
</div>
</div>
<p>
Voici un aperçu rapide de la syntaxe Markdown repris d'une
<a href="https://guides.github.com/features/mastering-markdown/">présentation de Github</a> ainsi que de celles d'<a href="http://csrgxtu.github.io/2015/03/20/Writing-Mathematic-Fomulars-in-Markdown/">Archer Reilly</a>.
</p>
<div id="outline-container-org99b4a98" class="outline-2">
<h2 id="org99b4a98">Syntaxe</h2>
<div class="outline-text-2" id="text-org99b4a98">
</div>
<div id="outline-container-org28d66f2" class="outline-3">
<h3 id="org28d66f2">Headers</h3>
<div class="outline-text-3" id="text-org28d66f2">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
# This is an &lt;h1&gt; tag
## This is an &lt;h2&gt; tag
###### This is an &lt;h6&gt; tag
</pre>
</div>
</div>
<div id="outline-container-orgc27acce" class="outline-3">
<h3 id="orgc27acce">Emphasis</h3>
<div class="outline-text-3" id="text-orgc27acce">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
*This text will be italic*
_This will also be italic_
**This text will be bold**
__This will also be bold__
_You **can** combine them_
</pre>
</div>
</div>
<div id="outline-container-org50640c4" class="outline-3">
<h3 id="org50640c4">Lists</h3>
<div class="outline-text-3" id="text-org50640c4">
</div>
<div id="outline-container-org11d3314" class="outline-4">
<h4 id="org11d3314">Unordered</h4>
<div class="outline-text-4" id="text-org11d3314">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
- Item 1
- Item 2
- Item 2a
- Item 2b
</pre>
</div>
</div>
<div id="outline-container-org0453134" class="outline-4">
<h4 id="org0453134">Ordered</h4>
<div class="outline-text-4" id="text-org0453134">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
1. Item 1
2. Item 2
3. Item 3
1. Item 3a
2. Item 3b
</pre>
</div>
</div>
</div>
<div id="outline-container-orgda3d80b" class="outline-3">
<h3 id="orgda3d80b">Images</h3>
<div class="outline-text-3" id="text-orgda3d80b">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
![GitHub Logo](/images/logo.png)
Format: ![Alt Text](url)
</pre>
</div>
</div>
<div id="outline-container-org7cb67aa" class="outline-3">
<h3 id="org7cb67aa">Links</h3>
<div class="outline-text-3" id="text-org7cb67aa">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
http://github.com - automatic!
[GitHub](http://github.com)
</pre>
</div>
</div>
<div id="outline-container-orge09365f" class="outline-3">
<h3 id="orge09365f">Blockquotes</h3>
<div class="outline-text-3" id="text-orge09365f">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
As Kanye West said:
&gt; We're living the future so
&gt; the present is our past.
</pre>
</div>
</div>
<div id="outline-container-orgfa4914a" class="outline-3">
<h3 id="orgfa4914a">Inline code</h3>
<div class="outline-text-3" id="text-orgfa4914a">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
To print some text with python, you should use the `print()` function.
```
print("Hello world!")
```
</pre>
</div>
</div>
</div>
<div id="outline-container-org8737c71" class="outline-2">
<h2 id="org8737c71">Écrire des Maths</h2>
<div class="outline-text-2" id="text-org8737c71">
<p>
Il est possible d'écrire des formules en Markdown, soit en mode <b>inline</b>
soit en mode <b>displayed formulas</b>. Dans le premier cas, les formules
sont inclues directement à l'intérieur du paragraphe courant alors
que dans le second, elles apparaissent centrées et mises en exergue.
</p>
<p>
Le formatage de la formule est légèrement différent dans les deux cas
car pour qu'une formule s'affiche joliment sur une seule ligne, il
faut la "tasser" un peu plus que lorsqu'elle est mise en valeur.
</p>
<p>
Pour écrire une formule en mode <b>inline</b>, il faut la délimiter par un <code>$</code>
(du coup, pour écrire le symbole dollar, il faut le préfixer par un
backslash, comme ceci: <code>\$</code>) alors que pour écrire en mode <b>displayed</b>, il
faut la délimiter par un <code>$$</code>. Un petit exemple valant mieux qu'un long
discours, voici concrètement comment cela fonctionne:
</p>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
Cette expression $\sum_{i=1}^n X_i$ est inlinée.
</pre>
<p>
Cette expression \(\sum_{i=1}^n X_i\) est inlinée.
</p>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
Cette expression est mise en valeur:
$$\sum_{i=1}^n X_i$$
</pre>
<p>
Cette expression est mise en valeur:
</p>
<p>
\[\sum_{i=1}^n X_i\]
</p>
<p>
Nous vous présentons par la suite une sélection de symboles et de
commandes courantes. En fait, à peu près tout ce qui est classique
dans le langage LaTeX peut être utilisé pourvu que vous délimitiez
bien avec un <code>$</code>. Pour d'autres exemples plus complets jetez un coup
d'œil à ces <a href="http://www.statpower.net/Content/310/R%20Stuff/SampleMarkdown.html">exemples de James H. Steiger</a>.
</p>
</div>
<div id="outline-container-org6dc05c1" class="outline-3">
<h3 id="org6dc05c1">Lettres grecques</h3>
<div class="outline-text-3" id="text-org6dc05c1">
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Symbole</th>
<th scope="col" class="org-left">Commande</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">\(\alpha\)</td>
<td class="org-left"><code>$\alpha$</code></td>
</tr>
<tr>
<td class="org-left">\(\beta\)</td>
<td class="org-left"><code>$\beta$</code></td>
</tr>
<tr>
<td class="org-left">\(\gamma\)</td>
<td class="org-left"><code>$\gamma$</code></td>
</tr>
<tr>
<td class="org-left">\(\Gamma\)</td>
<td class="org-left"><code>$\Gamma$</code></td>
</tr>
<tr>
<td class="org-left">\(\pi\)</td>
<td class="org-left"><code>$\pi$</code></td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org2d8310d" class="outline-3">
<h3 id="org2d8310d">Fonctions et opérateurs</h3>
<div class="outline-text-3" id="text-org2d8310d">
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Symbole</th>
<th scope="col" class="org-left">Commande</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">\(\cos\)</td>
<td class="org-left"><code>$\cos$</code></td>
</tr>
<tr>
<td class="org-left">\(\sin\)</td>
<td class="org-left"><code>$\sin$</code></td>
</tr>
<tr>
<td class="org-left">\(\lim\)</td>
<td class="org-left"><code>$\lim$</code></td>
</tr>
<tr>
<td class="org-left">\(\exp\)</td>
<td class="org-left"><code>$\exp$</code></td>
</tr>
<tr>
<td class="org-left">\(\to\)</td>
<td class="org-left"><code>$\to$</code></td>
</tr>
<tr>
<td class="org-left">\(\in\)</td>
<td class="org-left"><code>$\in$</code></td>
</tr>
<tr>
<td class="org-left">\(\forall\)</td>
<td class="org-left"><code>$\forall$</code></td>
</tr>
<tr>
<td class="org-left">\(\exists\)</td>
<td class="org-left"><code>$\exists$</code></td>
</tr>
<tr>
<td class="org-left">\(\equiv\)</td>
<td class="org-left"><code>$\equiv$</code></td>
</tr>
<tr>
<td class="org-left">\(\sim\)</td>
<td class="org-left"><code>$\sim$</code></td>
</tr>
<tr>
<td class="org-left">\(\approx\)</td>
<td class="org-left"><code>$\approx$</code></td>
</tr>
<tr>
<td class="org-left">\(\times\)</td>
<td class="org-left"><code>$\times$</code></td>
</tr>
<tr>
<td class="org-left">\(\le\)</td>
<td class="org-left"><code>$\le$</code></td>
</tr>
<tr>
<td class="org-left">\(\ge\)</td>
<td class="org-left"><code>$\ge$</code></td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org69729f8" class="outline-3">
<h3 id="org69729f8">Exposants et indices</h3>
<div class="outline-text-3" id="text-org69729f8">
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Symbole</th>
<th scope="col" class="org-left">Commande</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">\(k_{n+1}\)</td>
<td class="org-left"><code>$k_{n+1}$</code></td>
</tr>
<tr>
<td class="org-left">\(n^2\)</td>
<td class="org-left"><code>$n^2$</code></td>
</tr>
<tr>
<td class="org-left">\(k_n^2\)</td>
<td class="org-left"><code>$k_n^2$</code></td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org39a711a" class="outline-3">
<h3 id="org39a711a">Fractions, coefficients binomiaux, racines, &#x2026;</h3>
<div class="outline-text-3" id="text-org39a711a">
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Symbole</th>
<th scope="col" class="org-left">Commande</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">\(\frac{4z^3}{16}\)</td>
<td class="org-left"><code>$\frac{4z^3}{16}$</code></td>
</tr>
<tr>
<td class="org-left">\(\frac{n!}{k!(n-k)!}\)</td>
<td class="org-left"><code>$\frac{n!}{k!(n-k)!}$</code></td>
</tr>
<tr>
<td class="org-left">\(\binom{n}{k}\)</td>
<td class="org-left"><code>$\binom{n}{k}$</code></td>
</tr>
<tr>
<td class="org-left">\(\frac{\frac{x}{1}}{x - y}\)</td>
<td class="org-left"><code>$\frac{\frac{x}{1}}{x - y}$</code></td>
</tr>
<tr>
<td class="org-left">\(^3/_7\)</td>
<td class="org-left"><code>$^3/_7$</code></td>
</tr>
<tr>
<td class="org-left">\(\sqrt{k}\)</td>
<td class="org-left"><code>$\sqrt{k}$</code></td>
</tr>
<tr>
<td class="org-left">\(\sqrt[n]{k}\)</td>
<td class="org-left"><code>$\sqrt[n]{k}$</code></td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org4b11fa4" class="outline-3">
<h3 id="org4b11fa4">Sommes et intégrales</h3>
<div class="outline-text-3" id="text-org4b11fa4">
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Symbole</th>
<th scope="col" class="org-left">Commande</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">\(\sum_{i=1}^{10} t_i\)</td>
<td class="org-left"><code>$\sum_{i=1}^{10} t_i$</code></td>
</tr>
<tr>
<td class="org-left">\(\int_0^\infty \mathrm{e}^{-x}\,\mathrm{d}x\)</td>
<td class="org-left"><code>$\int_0^\infty \mathrm{e}^{-x}\,\mathrm{d}x$</code></td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org55cc222" class="outline-3">
<h3 id="org55cc222">Déguisements</h3>
<div class="outline-text-3" id="text-org55cc222">
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Symbole</th>
<th scope="col" class="org-left">Commande</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">\(\hat{a}\)</td>
<td class="org-left"><code>$\hat{a}$</code></td>
</tr>
<tr>
<td class="org-left">\(\bar{a}\)</td>
<td class="org-left"><code>$\bar{a}$</code></td>
</tr>
<tr>
<td class="org-left">\(\dot{a}\)</td>
<td class="org-left"><code>$\dot{a}$</code></td>
</tr>
<tr>
<td class="org-left">\(\ddot{a}\)</td>
<td class="org-left"><code>$\ddot{a}$</code></td>
</tr>
<tr>
<td class="org-left">\(\overrightarrow{AB}\)</td>
<td class="org-left"><code>$\overrightarrow{AB}$</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="outline-container-org5bb515f" class="outline-2">
<h2 id="org5bb515f">Autour de <code>markdown</code></h2>
<div class="outline-text-2" id="text-org5bb515f">
<p>
Tout d'abord, pour aller plus loin avec <code>markdown</code> et ses extensions / ramifications :
</p>
<ul class="org-ul">
<li style="margin-bottom:0;">Le didacticiel « <a href="https://enacit1.epfl.ch/markdown-pandoc/">Élaboration et conversion de documents avec Markdown et Pandoc</a> » de Jean-Daniel Bonjour (EPFL), précis, complet, concis, en français ; un vrai bonheur !</li>
<li style="margin-bottom:0;">L'article <a href="https://en.wikipedia.org/wiki/Markdown#Example">Markdown</a> de wikipedia en anglais contient un bon pense-bête sur la syntaxe <code>markdown</code>.</li>
<li style="margin-bottom:0;">Github propose un court et efficace didacticiel (en anglais) : <a href="https://guides.github.com/features/mastering-markdown/">Mastering Markdown</a>.</li>
</ul>
<p>
Comme nous l'illustrons dans la « film d'écran » (<i>screencast</i>), l'éditeur de texte des dépôts <code>github</code> et <code>gitlab</code> permet d'interpréter / transformer à la demande un fichier <code>mardown</code> en un fichier <code>html</code>. C'est à la fois agréable et pratique, mais ce n'est pas une solution pour une utilisation quotidienne de <code>markdown</code>, pour cela, il est plus efficace d'éditer son texte, avec un éditeur de texte, sur son ordinateur, avant de « l'exporter » dans un format comme <code>html</code>, <code>pdf</code>, <code>docx</code>, <code>epub</code>, etc. Il existe des éditeurs plus ou moins spécialisés pour <code>markdown</code>, certains sont indiqués sur la page <a href="https://github.com/jgm/pandoc/wiki/Pandoc-Extras#editors">Editors</a> du site de <code>pandoc</code>, mais nous préconisons clairement l'emploi d'un éditeur de texte « généraliste » capable de reconnaître la syntaxe <code>markdown</code>. Nous en avons indiqué en début de séquence et on pourra trouver des informations complémentaires dans la section <a href="https://enacit1.epfl.ch/markdown-pandoc/#editeurs_markdown">Quelques éditeurs adaptés à l'édition Markdown</a> du didacticiel de Jean-Daniel Bonjour.
</p>
<p>
Pour convertir un fichier <code>markdown</code> en un format « arbitraire », la solution à ce jour la plus complète est <a href="http://pandoc.org/">Pandoc</a>, logiciel développé par John MacFarlane, un philosophe de Berkeley (le site <a href="https://github.com/jgm/pandoc">github</a>). En plus du site de <code>Pandoc</code>, le didacticiel de J.-D. Bonjour donne de nombreuses explications sur comment installer et utiliser <code>pandoc</code> dans la section <a href="https://enacit1.epfl.ch/markdown-pandoc/#commande_pandoc">Utilisation du convertisseur Pandoc</a>. Comme <code>pandoc</code> &#x2013; écrit en Haskell &#x2013; peut être parfois un peu difficile à installer, nous indiquons maintenant quelques solutions alternatives :
</p>
<ul class="org-ul">
<li style="margin-bottom:0;">Des sites comme <a href="http://www.markdowntopdf.com/">http://www.markdowntopdf.com/</a> et <a href="http://markdown2pdf.com/">http://markdown2pdf.com/</a> permettent de convertir en ligne un fichier <code>markdown</code> en un fichier <code>pdf</code>.</li>
<li style="margin-bottom:0;">Le projet <a href="http://commonmark.org/">CommonMark</a> propose, en plus d'une spécifications plus rigoureuse de la syntaxe <code>markdown</code>, des convertisseurs <code>markdown</code><code>html</code> / <code>LaTeX</code> (et plus) écris en <code>C</code> et en <code>JavaScript</code> (<a href="https://github.com/CommonMark/CommonMark">https://github.com/CommonMark/CommonMark</a>).</li>
<li style="margin-bottom:0;">Le site de <a href="https://daringfireball.net/projects/markdown/">John Gruber</a>, le créateur de <code>markdown</code>, fournit un convertisseur <code>markdown</code><code>html</code> écrit en <code>perl</code>.</li>
<li style="margin-bottom:0;"><a href="http://fletcherpenney.net/multimarkdown/">MultiMarkdown</a> est une autre extension de <code>markdown</code> qui vient avec son convertisseur <code>markdown</code><code>html</code> écrit en <code>C</code>.</li>
<li style="margin-bottom:0;"><a href="https://github.com/joeyespo/grip">grip</a> est un serveur écrit en <code>python</code> qui permet de convertir et visualiser à la volée des fichiers <code>markdown</code> avec son navigateur (très utile pour éviter d'avoir à faire des « commits » en grande quantité lorsqu'on écrit de tels fichiers pour un dépôt <code>github</code> ou <code>gitlab</code>).</li>
</ul>
<p>
La conversion en <code>pdf</code> passe toujours par <a href="https://fr.wikipedia.org/wiki/LaTeX">LaTeX</a> ce qui nécessite d'avoir une version complète et à jour de ce logiciel sur sa machine.
</p>
<p>
Dans la petite démonstration, nous montrons comment générer un fichier <code>docx</code> à partir d'un fichier <code>md</code> avec <code>Pandoc</code> et nous soulignons qu'il est alors possible d'utiliser un traitement de texte comme <code>LibreOffice</code> pour modifier le fichier obtenu. Il est clair que si des modifications sont apportées au <code>docx</code> elle en seront pas (automatiquement) propagées au <code>md</code>. Il faudra utiliser <code>Pandoc</code> pour cela et effectuer une conversion de <code>docx</code> vers <code>md</code> (et seules les éléments du format <code>docx</code> qui existent en <code>md</code> seront conservés).
</p>
<p>
Une stratégie qui est souvent employée et qui fonctionne bien en pratique consiste à faire le gros du travail de rédaction d'un article ou d'un mémoire en <code>Markdown</code>. La rédaction terminée, le fichier est exporté au format <code>docx</code> (ou <code>LaTeX</code>) et des ajustements de mise en page sont alors effectués avec un logiciel de traitement de texte (ou un éditeur <code>LaTeX</code>).
</p>
</div>
</div>
</div>
# -*- mode: org -*-
#+TITLE: Introduction à Markdown
#+AUTHOR: Arnaud Legrand
#+TITLE: Introduction to Markdown
#+DATE: June, 2018
#+LANG: fr
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
Voici un aperçu rapide de la syntaxe Markdown repris d'une
[[https://guides.github.com/features/mastering-markdown/][présentation de Github]] ainsi que de celles d'[[http://csrgxtu.github.io/2015/03/20/Writing-Mathematic-Fomulars-in-Markdown/][Archer Reilly]].
* Syntaxe
This document presents a brief overview of the Markdown syntax and
builds on a [[https://guides.github.com/features/mastering-markdown/][presentation from the Github team]] and [[http://csrgxtu.github.io/2015/03/20/Writing-Mathematic-Fomulars-in-Markdown/][blog post from
Archer Reilly]].
* Table of Contents :TOC:
- [[#syntax][Syntax]]
- [[#headers][Headers]]
- [[#emphasis][Emphasis]]
- [[#lists][Lists]]
- [[#images][Images]]
- [[#links][Links]]
- [[#blockquotes][Blockquotes]]
- [[#inline-code][Inline code]]
- [[#writing-math][Writing Math]]
- [[#greek-letters][Greek Letters]]
- [[#usual-functions-and-operators][Usual functions and operators]]
- [[#exponents-and-indices][Exponents and indices]]
- [[#fractions-binomial-coefficients-square-roots-][Fractions, binomial coefficients, square roots, ...]]
- [[#summations-and-integrals][Summations and integrals]]
- [[#outfits][Outfits]]
- [[#about-markdown][About =markdown=]]
- [[#markdown-and-pandoc-resources-in-english][Markdown/Pandoc Resources in english]]
* Syntax
** Headers
#+BEGIN_EXAMPLE
# This is an <h1> tag
......@@ -68,75 +86,74 @@ To print some text with python, you should use the `print()` function.
print("Hello world!")
```
#+END_EXAMPLE
* Écrire des Maths
Il est possible d'écrire des formules en Markdown, soit en mode *inline*
soit en mode *displayed formulas*. Dans le premier cas, les formules
sont inclues directement à l'intérieur du paragraphe courant alors
que dans le second, elles apparaissent centrées et mises en exergue.
Le formatage de la formule est légèrement différent dans les deux cas
car pour qu'une formule s'affiche joliment sur une seule ligne, il
faut la "tasser" un peu plus que lorsqu'elle est mise en valeur.
Pour écrire une formule en mode *inline*, il faut la délimiter par un =$=
(du coup, pour écrire le symbole dollar, il faut le préfixer par un
backslash, comme ceci: =\$=) alors que pour écrire en mode *displayed*, il
faut la délimiter par un =$$=. Un petit exemple valant mieux qu'un long
discours, voici concrètement comment cela fonctionne:
* Writing Math
Math formulas are easy to write using Markdown, either using the
*inline* mode or the *displayed formulas* mode. With the inline mode,
formulas are inlined in the current paragraph whereas with the
displayed mode, they appear as centered and emphasized.
The formatting generally slightly differs in both cases since, to
display nicely on a single line, it is generally required to pack them
a bit more than when they are emphasized.
To write formulas using the *inline* mode, they should be surrounded by
a single =$= (as a consequence, whenever you need to use the original
dollar symbol, you should prefix it with a backslash: =\$=). To write
formulas using the *displayed* mode, they should be surrounded by a =$$=. Here are a few examples:
#+BEGIN_EXAMPLE
Cette expression $\sum_{i=1}^n X_i$ est inlinée.
This expression $\sum_{i=1}^n X_i$ is inlined.
#+END_EXAMPLE
Cette expression $\sum_{i=1}^n X_i$ est inlinée.
This expression $\sum_{i=1}^n X_i$ is inlined.
#+BEGIN_EXAMPLE
Cette expression est mise en valeur:
This expression is emphasized:
$$\sum_{i=1}^n X_i$$
#+END_EXAMPLE
Cette expression est mise en valeur:
This expression is emphasized:
$$\sum_{i=1}^n X_i$$
Nous vous présentons par la suite une sélection de symboles et de
commandes courantes. En fait, à peu près tout ce qui est classique
dans le langage LaTeX peut être utilisé pourvu que vous délimitiez
bien avec un =$=. Pour d'autres exemples plus complets jetez un coup
d'œil à ces [[http://www.statpower.net/Content/310/R%2520Stuff/SampleMarkdown.html][exemples de James H. Steiger]].
** Lettres grecques
| Symbole | Commande |
|---------+----------|
| $\alpha$ | =$\alpha$= |
| $\beta$ | =$\beta$= |
| $\gamma$ | =$\gamma$= |
| $\Gamma$ | =$\Gamma$= |
| $\pi$ | =$\pi$= |
** Fonctions et opérateurs
| Symbole | Commande |
|---------+----------|
| $\cos$ | =$\cos$= |
| $\sin$ | =$\sin$= |
| $\lim$ | =$\lim$= |
| $\exp$ | =$\exp$= |
| $\to$ | =$\to$= |
| $\in$ | =$\in$= |
| $\forall$ | =$\forall$= |
| $\exists$ | =$\exists$= |
| $\equiv$ | =$\equiv$= |
| $\sim$ | =$\sim$= |
| $\approx$ | =$\approx$= |
| $\times$ | =$\times$= |
| $\le$ | =$\le$= |
| $\ge$ | =$\ge$= |
** Exposants et indices
| Symbole | Commande |
In the rest of this section we present a brief selection of common
symbols and commands. Actually, almost any classical LaTeX command
can used as such in Markdown, provided it is surrounded by a =$=. For
more complete examples, please have a look at these ces [[http://www.statpower.net/Content/310/R%2520Stuff/SampleMarkdown.html][examples by
James H. Steiger]].
** Greek Letters
| Symbol | Command |
|--------+---------|
| $\alpha$ | =$\alpha$= |
| $\beta$ | =$\beta$= |
| $\gamma$ | =$\gamma$= |
| $\Gamma$ | =$\Gamma$= |
| $\pi$ | =$\pi$= |
** Usual functions and operators
| Symbol | Command |
|--------+---------|
| $\cos$ | =$\cos$= |
| $\sin$ | =$\sin$= |
| $\lim$ | =$\lim$= |
| $\exp$ | =$\exp$= |
| $\to$ | =$\to$= |
| $\in$ | =$\in$= |
| $\forall$ | =$\forall$= |
| $\exists$ | =$\exists$= |
| $\equiv$ | =$\equiv$= |
| $\sim$ | =$\sim$= |
| $\approx$ | =$\approx$= |
| $\times$ | =$\times$= |
| $\le$ | =$\le$= |
| $\ge$ | =$\ge$= |
** Exponents and indices
| Symbol | Command |
|---------+-----------|
| $k_{n+1}$ | =$k_{n+1}$= |
| $n^2$ | =$n^2$= |
| $k_n^2$ | =$k_n^2$= |
** Fractions, coefficients binomiaux, racines, ...
| Symbole | Commande |
** Fractions, binomial coefficients, square roots, ...
| Symbol | Command |
|-----------------------------+-----------------------------|
| $\frac{4z^3}{16}$ | =$\frac{4z^3}{16}$= |
| $\frac{n!}{k!(n-k)!}$ | =$\frac{n!}{k!(n-k)!}$= |
......@@ -145,13 +162,13 @@ d'œil à ces [[http://www.statpower.net/Content/310/R%2520Stuff/SampleMarkdown.
| $^3/_7$ | =$^3/_7$= |
| $\sqrt{k}$ | =$\sqrt{k}$= |
| $\sqrt[n]{k}$ | =$\sqrt[n]{k}$= |
** Sommes et intégrales
| Symbole | Commande |
** Summations and integrals
| Symbol | Command |
|---------------------------------+--------------------------------------|
| $\sum_{i=1}^{10} t_i$ | =$\sum_{i=1}^{10} t_i$= |
| $\sum_{i=1}^{10} t_i$ | =$\sum_{i=1}^{10} t_i$= |
| $\int_0^\infty \mathrm{e}^{-x}\,\mathrm{d}x$ | =$\int_0^\infty \mathrm{e}^{-x}\,\mathrm{d}x$= |
** Déguisements
| Symbole | Commande |
** Outfits
| Symbol | Command |
|-----------------------+-----------------------|
| $\hat{a}$ | =$\hat{a}$= |
| $\bar{a}$ | =$\bar{a}$= |
......@@ -159,22 +176,37 @@ d'œil à ces [[http://www.statpower.net/Content/310/R%2520Stuff/SampleMarkdown.
| $\ddot{a}$ | =$\ddot{a}$= |
| $\overrightarrow{AB}$ | =$\overrightarrow{AB}$= |
* Autour de =markdown=
Tout d'abord, pour aller plus loin avec =markdown= et ses extensions / ramifications :
- Le didacticiel « [[https://enacit1.epfl.ch/markdown-pandoc/][Élaboration et conversion de documents avec Markdown et Pandoc]] » de Jean-Daniel Bonjour (EPFL), précis, complet, concis, en français ; un vrai bonheur !
- L'article [[https://en.wikipedia.org/wiki/Markdown#Example][Markdown]] de wikipedia en anglais contient un bon pense-bête sur la syntaxe =markdown=.
- Github propose un court et efficace didacticiel (en anglais) : [[https://guides.github.com/features/mastering-markdown/][Mastering Markdown]].
Comme nous l'illustrons dans la « film d'écran » (/screencast/), l'éditeur de texte des dépôts =github= et =gitlab= permet d'interpréter / transformer à la demande un fichier =mardown= en un fichier =html=. C'est à la fois agréable et pratique, mais ce n'est pas une solution pour une utilisation quotidienne de =markdown=, pour cela, il est plus efficace d'éditer son texte, avec un éditeur de texte, sur son ordinateur, avant de « l'exporter » dans un format comme =html=, =pdf=, =docx=, =epub=, etc. Il existe des éditeurs plus ou moins spécialisés pour =markdown=, certains sont indiqués sur la page [[https://github.com/jgm/pandoc/wiki/Pandoc-Extras#editors][Editors]] du site de =pandoc=, mais nous préconisons clairement l'emploi d'un éditeur de texte « généraliste » capable de reconnaître la syntaxe =markdown=. Nous en avons indiqué en début de séquence et on pourra trouver des informations complémentaires dans la section [[https://enacit1.epfl.ch/markdown-pandoc/#editeurs_markdown][Quelques éditeurs adaptés à l'édition Markdown]] du didacticiel de Jean-Daniel Bonjour.
Pour convertir un fichier =markdown= en un format « arbitraire », la solution à ce jour la plus complète est [[http://pandoc.org/][Pandoc]], logiciel développé par John MacFarlane, un philosophe de Berkeley (le site [[https://github.com/jgm/pandoc][github]]). En plus du site de =Pandoc=, le didacticiel de J.-D. Bonjour donne de nombreuses explications sur comment installer et utiliser =pandoc= dans la section [[https://enacit1.epfl.ch/markdown-pandoc/#commande_pandoc][Utilisation du convertisseur Pandoc]]. Comme =pandoc= -- écrit en Haskell -- peut être parfois un peu difficile à installer, nous indiquons maintenant quelques solutions alternatives :
- Des sites comme [[http://www.markdowntopdf.com/]] et [[http://markdown2pdf.com/]] permettent de convertir en ligne un fichier =markdown= en un fichier =pdf=.
- Le projet [[http://commonmark.org/][CommonMark]] propose, en plus d'une spécifications plus rigoureuse de la syntaxe =markdown=, des convertisseurs =markdown= → =html= / =LaTeX= (et plus) écris en =C= et en =JavaScript= ([[https://github.com/CommonMark/CommonMark]]).
- Le site de [[https://daringfireball.net/projects/markdown/][John Gruber]], le créateur de =markdown=, fournit un convertisseur =markdown= → =html= écrit en =perl=.
- [[http://fletcherpenney.net/multimarkdown/][MultiMarkdown]] est une autre extension de =markdown= qui vient avec son convertisseur =markdown= → =html= écrit en =C=.
- [[https://github.com/joeyespo/grip][grip]] est un serveur écrit en =python= qui permet de convertir et visualiser à la volée des fichiers =markdown= avec son navigateur (très utile pour éviter d'avoir à faire des « commits » en grande quantité lorsqu'on écrit de tels fichiers pour un dépôt =github= ou =gitlab=).
La conversion en =pdf= passe toujours par [[https://fr.wikipedia.org/wiki/LaTeX][LaTeX]] ce qui nécessite d'avoir une version complète et à jour de ce logiciel sur sa machine.
* About =markdown=
First of all, to know more about =markdown= and its extensions, you may want to read:
- The « [[https://enacit1.epfl.ch/markdown-pandoc/][Élaboration et conversion de documents avec Markdown et Pandoc]] » tutorial by Jean-Daniel Bonjour (EPFL). A must-read in French...
- The wikipedia article on [[https://en.wikipedia.org/wiki/Markdown#Example][Markdown]] provides a good overview of the =markdown= syntax.
- Github proposes a short and efficient introduction: [[https://guides.github.com/features/mastering-markdown/][Mastering Markdown]].
As we explain in the video, =github= and =gitlab= allow you to easily edit =mardown= documents and to render them in =html=. This is quite convenient but may be a bit cumbersome for a daily use. You may prefer to edit these documents with a real editor and later to export them in whichever format you may like (=html=, =pdf=, =docx=, =epub=, etc). There are a few editors specifically designed for =markdown= (see for example the [[https://github.com/jgm/pandoc/wiki/Pandoc-Extras#editors][Editors]] page of the =pandoc= website) but we rather advise you to use a general-purpose editor that is capable of handling the =markdown= syntax. A few ones were mentioned in the beginning of the video and additional information are available in the [[https://enacit1.epfl.ch/markdown-pandoc/#editeurs_markdown]["Quelques éditeurs adaptés à l'édition Markdown"]] section of Jean-Daniel Bonjour's tutorial.
To convert =markdown= in an "arbitrary" other format, the best solution today is [[http://pandoc.org/][Pandoc]], a software developed by John MacFarlane, a philosopher from de Berkeley, and whose [[https://github.com/jgm/pandoc][main page is on github]]. J.-D. Bonjour's tutorial provides many explanations on how to install and use =pandoc= in the [[https://enacit1.epfl.ch/markdown-pandoc/#commande_pandoc][Utilisation du convertisseur Pandoc]] section. =pandoc= is written in Haskell and may be a bit cumbersome to install. Therefore, we provide here a few alternative solutions:
- Some websites like [[http://www.markdowntopdf.com/]] or [[http://markdown2pdf.com/]] allow you to convert online =markdown= files into =pdf= files without having to install anything on your computer.
- The [[http://commonmark.org/][CommonMark]] project proposes a rigorous specification of the =markdown= syntax and converters =markdown= → =html= / =LaTeX= written in =C= and =JavaScript= ([[https://github.com/CommonMark/CommonMark]]).
- You will find on the website of [[https://daringfireball.net/projects/markdown/][John Gruber]], the creator of =markdown=, a =markdown= → =html= converter written in =perl=.
- [[http://fletcherpenney.net/multimarkdown/][MultiMarkdown]] is another =markdown= extension that provides its own =markdown= → =html= converter written in =C=.
- [[https://github.com/joeyespo/grip][grip]] is a =python=-based server that allows you to convert on the fly =markdown= documents and to preview them with your favorite browser (this is quite useful to avoid useless commits just for the sake of previewing when using =github= ou =gitlab=).
The =pdf= conversion always relies on [[https://fr.wikipedia.org/wiki/LaTeX][LaTeX]], which requires a full-fledged and running LaTeX installation on your computer.
Dans la petite démonstration, nous montrons comment générer un fichier =docx= à partir d'un fichier =md= avec =Pandoc= et nous soulignons qu'il est alors possible d'utiliser un traitement de texte comme =LibreOffice= pour modifier le fichier obtenu. Il est clair que si des modifications sont apportées au =docx= elle en seront pas (automatiquement) propagées au =md=. Il faudra utiliser =Pandoc= pour cela et effectuer une conversion de =docx= vers =md= (et seules les éléments du format =docx= qui existent en =md= seront conservés).
In the demo, we show how to generate a =docx= from a =markdown= document with =Pandoc= and we explain that it is then possible to use a word processor like =LibreOffice= to edit the resulting file. Obviously the modifications will not be back-propagated to the original =markdown= document. You may however want to use =Pandoc= again to convert your new =docx= document to a new =markdown= document.
Another common strategy consists in doing most of the editing of an article/report in =Markdown= and to export it into a =docx= (or =LaTeX=) only in the end so as to prepare it for a camera-ready version with a standard word processing environment (or a =LaTeX= editor).
* Markdown and Pandoc Resources in english
** Mardown et pandoc
- [[https://programminghistorian.org/en/lessons/sustainable-authorship-in-plain-text-using-pandoc-and-markdown][Sustainable Authorship in Plain Text using Pandoc and Markdown by Dennis Tenen and Grant Wythoff]]: in this tutorial, you will first learn the basics of Markdown—an easy to read and write markup syntax for plain text—as well as Pandoc, a command line tool that converts plain text into a number of beautifully formatted file types: PDF, .docx, HTML, LaTeX, slide decks, and more.
- The « [[https://github.com/jgm/pandoc/wiki/Documentation-and-Tutorials][Documentation and Tutorials]] » page of the github Pandoc project provides many links to resources about Pandoc.
** Markdown syntax
- [[https://programminghistorian.org/en/lessons/getting-started-with-markdown][Programming Historian : Getting Started with Markdown]] is very usefull to understand why this language is used, how to format Markdown files, and how to preview Markdown-formatted documents on the web (in spanish [[https://programminghistorian.org/es/lecciones/introduccion-a-markdown][Introducción a Markdown]])
- To write equations with Markdown: [[http://pandoc.org/MANUAL.html#math][see the relevant part of the Pandoc documentation]]
- Writing equations requires a basic knowledge of TeX / LaTeX: [[https://en.wikibooks.org/wiki/LaTeX][see wikibooks.org documentation about LaTeX]]
** Others
The resources listed under the [[https://programminghistorian.org/en/lessons/?activity=sustaining][Sustain section of "The Programming Historian"]] are all relevant for Module 1 (in particular the tutorial on Git/GitHub).
Une stratégie qui est souvent employée et qui fonctionne bien en pratique consiste à faire le gros du travail de rédaction d'un article ou d'un mémoire en =Markdown=. La rédaction terminée, le fichier est exporté au format =docx= (ou =LaTeX=) et des ajustements de mise en page sont alors effectués avec un logiciel de traitement de texte (ou un éditeur =LaTeX=).
# -*- mode: org -*-
#+TITLE: Introduction à Markdown
#+DATE: June, 2018
#+LANG: fr
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
Voici un aperçu rapide de la syntaxe Markdown repris d'une
[[https://guides.github.com/features/mastering-markdown/][présentation de GitHub]] ainsi que de celles d'[[http://csrgxtu.github.io/2015/03/20/Writing-Mathematic-Fomulars-in-Markdown/][Archer Reilly]].
* Table des matières :TOC:
- [[#syntaxe][Syntaxe]]
- [[#headers][Headers]]
- [[#emphasis][Emphasis]]
- [[#lists][Lists]]
- [[#images][Images]]
- [[#links][Links]]
- [[#blockquotes][Blockquotes]]
- [[#inline-code][Inline code]]
- [[#écrire-des-maths][Écrire des Maths]]
- [[#lettres-grecques][Lettres grecques]]
- [[#fonctions-et-opérateurs][Fonctions et opérateurs]]
- [[#exposants-et-indices][Exposants et indices]]
- [[#fractions-coefficients-binomiaux-racines-][Fractions, coefficients binomiaux, racines...]]
- [[#sommes-et-intégrales][Sommes et intégrales]]
- [[#déguisements][Déguisements]]
- [[#autour-de-markdown][Autour de Markdown]]
* Syntaxe
** Headers
#+BEGIN_EXAMPLE
# This is an <h1> tag
## This is an <h2> tag
###### This is an <h6> tag
#+END_EXAMPLE
** Emphasis
#+BEGIN_EXAMPLE
*This text will be italic*
_This will also be italic_
**This text will be bold**
__This will also be bold__
_You **can** combine them_
#+END_EXAMPLE
** Lists
*** Unordered
#+BEGIN_EXAMPLE
- Item 1
- Item 2
- Item 2a
- Item 2b
#+END_EXAMPLE
*** Ordered
#+BEGIN_EXAMPLE
1. Item 1
2. Item 2
3. Item 3
1. Item 3a
2. Item 3b
#+END_EXAMPLE
** Images
#+BEGIN_EXAMPLE
![GitHub Logo](/images/logo.png)
Format: ![Alt Text](url)
#+END_EXAMPLE
** Links
#+BEGIN_EXAMPLE
http://github.com - automatic!
[GitHub](http://github.com)
#+END_EXAMPLE
** Blockquotes
#+BEGIN_EXAMPLE
As Kanye West said:
> We're living the future so
> the present is our past.
#+END_EXAMPLE
** Inline code
#+BEGIN_EXAMPLE
To print some text with Python, you should use the `print()` function.
```
print("Hello world!")
```
#+END_EXAMPLE
* Écrire des Maths
Il est possible d'écrire des formules en Markdown, soit en mode *inline*
soit en mode *displayed formulas*. Dans le premier cas, les formules
sont incluses directement à l'intérieur du paragraphe courant alors
que dans le second, elles apparaissent centrées et mises en exergue.
Le formatage de la formule est légèrement différent dans les deux cas
car pour qu'une formule s'affiche joliment sur une seule ligne, il
faut la "tasser" un peu plus que lorsqu'elle est mise en valeur.
Pour écrire une formule en mode *inline*, il faut la délimiter par un =$=
(du coup, pour écrire le symbole dollar, il faut le préfixer par un
backslash, comme ceci : =\$=) alors que pour écrire en mode *displayed*, il
faut la délimiter par un =$$=. Un petit exemple valant mieux qu'un long
discours, voici concrètement comment cela fonctionne :
#+BEGIN_EXAMPLE
Cette expression $\sum_{i=1}^n X_i$ est inlinée.
#+END_EXAMPLE
Cette expression $\sum_{i=1}^n X_i$ est inlinée.
#+BEGIN_EXAMPLE
Cette expression est mise en valeur :
$$\sum_{i=1}^n X_i$$
#+END_EXAMPLE
Cette expression est mise en valeur :
$$\sum_{i=1}^n X_i$$
Nous vous présentons par la suite une sélection de symboles et de
commandes courants. En fait, à peu près tout ce qui est classique
dans le langage LaTeX peut être utilisé pourvu que vous délimitiez
bien avec un =$=. Pour d'autres exemples plus complets jetez un coup
d'œil à ces [[http://www.statpower.net/Content/310/R%2520Stuff/SampleMarkdown.html][exemples de James H. Steiger]].
** Lettres grecques
| Symbole | Commande |
|---------+----------|
| $\alpha$ | =$\alpha$= |
| $\beta$ | =$\beta$= |
| $\gamma$ | =$\gamma$= |
| $\Gamma$ | =$\Gamma$= |
| $\pi$ | =$\pi$= |
** Fonctions et opérateurs
| Symbole | Commande |
|---------+----------|
| $\cos$ | =$\cos$= |
| $\sin$ | =$\sin$= |
| $\lim$ | =$\lim$= |
| $\exp$ | =$\exp$= |
| $\to$ | =$\to$= |
| $\in$ | =$\in$= |
| $\forall$ | =$\forall$= |
| $\exists$ | =$\exists$= |
| $\equiv$ | =$\equiv$= |
| $\sim$ | =$\sim$= |
| $\approx$ | =$\approx$= |
| $\times$ | =$\times$= |
| $\le$ | =$\le$= |
| $\ge$ | =$\ge$= |
** Exposants et indices
| Symbole | Commande |
|---------+-----------|
| $k_{n+1}$ | =$k_{n+1}$= |
| $n^2$ | =$n^2$= |
| $k_n^2$ | =$k_n^2$= |
** Fractions, coefficients binomiaux, racines...
| Symbole | Commande |
|-----------------------------+-----------------------------|
| $\frac{4z^3}{16}$ | =$\frac{4z^3}{16}$= |
| $\frac{n!}{k!(n-k)!}$ | =$\frac{n!}{k!(n-k)!}$= |
| $\binom{n}{k}$ | =$\binom{n}{k}$= |
| $\frac{\frac{x}{1}}{x - y}$ | =$\frac{\frac{x}{1}}{x - y}$= |
| $^3/_7$ | =$^3/_7$= |
| $\sqrt{k}$ | =$\sqrt{k}$= |
| $\sqrt[n]{k}$ | =$\sqrt[n]{k}$= |
** Sommes et intégrales
| Symbole | Commande |
|---------------------------------+--------------------------------------|
| $\sum_{i=1}^{10} t_i$ | =$\sum_{i=1}^{10} t_i$= |
| $\int_0^\infty \mathrm{e}^{-x}\,\mathrm{d}x$ | =$\int_0^\infty \mathrm{e}^{-x}\,\mathrm{d}x$= |
** Déguisements
| Symbole | Commande |
|-----------------------+-----------------------|
| $\hat{a}$ | =$\hat{a}$= |
| $\bar{a}$ | =$\bar{a}$= |
| $\dot{a}$ | =$\dot{a}$= |
| $\ddot{a}$ | =$\ddot{a}$= |
| $\overrightarrow{AB}$ | =$\overrightarrow{AB}$= |
* Autour de =Markdown=
Tout d'abord, pour aller plus loin avec =Markdown= et ses extensions / ramifications :
- Le didacticiel « [[https://enacit1.epfl.ch/markdown-pandoc/][Élaboration et conversion de documents avec Markdown et Pandoc]] » de Jean-Daniel Bonjour (EPFL), précis, complet, concis, en français ; un vrai bonheur !
- L'article [[https://en.wikipedia.org/wiki/Markdown#Example][Markdown]] de wikipedia en anglais contient un bon pense-bête sur la syntaxe =Markdown=.
- GitHub propose un court et efficace didacticiel (en anglais) : [[https://guides.github.com/features/mastering-markdown/][Mastering Markdown]].
Comme nous l'illustrons dans le « film d'écran » (/screencast/), l'éditeur de texte des dépôts =GitHub= et =GitLab= permet d'interpréter / transformer à la demande un fichier =Markdown= en un fichier =html=. C'est à la fois agréable et pratique, mais ce n'est pas une solution pour une utilisation quotidienne de =Markdown=, pour cela, il est plus efficace d'éditer son texte, avec un éditeur de texte, sur son ordinateur, avant de « l'exporter » dans un format comme =html=, =pdf=, =docx=, =epub=, etc. Il existe des éditeurs plus ou moins spécialisés pour =Markdown=, certains sont indiqués sur la page [[https://github.com/jgm/pandoc/wiki/Pandoc-Extras#editors][Editors]] du site de =Pandoc=, mais nous préconisons clairement l'emploi d'un éditeur de texte « généraliste » capable de reconnaître la syntaxe =Markdown=. Nous en avons indiqué en début de séquence et on pourra trouver des informations complémentaires dans la section [[https://enacit1.epfl.ch/markdown-pandoc/#editeurs_markdown][Quelques éditeurs adaptés à l'édition Markdown]] du didacticiel de Jean-Daniel Bonjour.
Pour convertir un fichier =Markdown= en un format « arbitraire », la solution à ce jour la plus complète est [[http://pandoc.org/][Pandoc]], logiciel développé par John MacFarlane, un philosophe de Berkeley (le site [[https://github.com/jgm/pandoc][GitHub]]). En plus du site de =Pandoc=, le didacticiel de J.-D. Bonjour donne de nombreuses explications sur comment installer et utiliser =Pandoc= dans la section [[https://enacit1.epfl.ch/markdown-pandoc/#commande_pandoc][Utilisation du convertisseur Pandoc]]. Comme =Pandoc= -- écrit en Haskell -- peut être parfois un peu difficile à installer, nous indiquons maintenant quelques solutions alternatives :
- Des sites comme [[http://www.markdowntopdf.com/]] et [[http://markdown2pdf.com/]] permettent de convertir en ligne un fichier =Markdown= en un fichier =pdf=.
- Le projet [[http://commonmark.org/][CommonMark]] propose, en plus d'une spécification plus rigoureuse de la syntaxe =Markdown=, des convertisseurs =Markdown= → =html= / =LaTeX= (et plus) écrits en =C= et en =JavaScript= ([[https://github.com/CommonMark/CommonMark]]).
- Le site de [[https://daringfireball.net/projects/markdown/][John Gruber]], le créateur de =Markdown=, fournit un convertisseur =Markdown= → =html= écrit en =Perl=.
- [[http://fletcherpenney.net/multimarkdown/][MultiMarkdown]] est une autre extension de =Markdown= qui vient avec son convertisseur =Markdown= → =html= écrit en =C=.
- [[https://github.com/joeyespo/grip][grip]] est un serveur écrit en =Python= qui permet de convertir et visualiser à la volée des fichiers =Markdown= avec son navigateur (très utile pour éviter d'avoir à faire des « commits » en grande quantité lorsqu'on écrit de tels fichiers pour un dépôt =GitHub= ou =GitLab=).
La conversion en =pdf= passe toujours par [[https://fr.wikipedia.org/wiki/LaTeX][LaTeX]] ce qui nécessite d'avoir une version complète et à jour de ce logiciel sur sa machine.
Dans la petite démonstration, nous montrons comment générer un fichier =docx= à partir d'un fichier =md= avec =Pandoc= et nous soulignons qu'il est alors possible d'utiliser un traitement de texte comme =LibreOffice= pour modifier le fichier obtenu. Il est clair que si des modifications sont apportées au =docx= elles ne seront pas (automatiquement) propagées au =md=. Il faudra utiliser =Pandoc= pour cela et effectuer une conversion de =docx= vers =md= (et seuls les éléments du format =docx= qui existent en =md= seront conservés).
Une stratégie qui est souvent employée et qui fonctionne bien en pratique consiste à faire le gros du travail de rédaction d'un article ou d'un mémoire en =Markdown=. La rédaction terminée, le fichier est exporté au format =docx= (ou =LaTeX=) et des ajustements de mise en page sont alors effectués avec un logiciel de traitement de texte (ou un éditeur =LaTeX=).
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: The Introductory Sequence (Module 1 sequence 0)
#+DATE: <2019-03-25 jeu.>
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: en
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
* Table of content :TOC:
- [[The "notebook"]]
- [[Examples of notebooks]]
* The "notebook"
"Notebook" must be here understood with a fairly general meaning; that is, depending on the context, it could more specifically be called "field book", "observations book", "journal" or "labbook". What we concentrate on is a a meduim (paper or digital) on which information get stored "as it arrives"--as opposed to a report or a scientic paper where the logic of the argument directs the structure of the content--; the information concidered is not homogeneous (different topics do show up) and multiple media can be used.
* Examples of notebooks
- Leonardo da Vinci notebooks ([[http://unesdoc.unesco.org/images/0007/000748/074877fo.pdf][in pdf format]]) and the Wikipdia page on the [[https://en.wikipedia.org/wiki/Codex_Leicester][Codex Leicester]].
- The [[https://en.wikipedia.org/wiki/Galileo_Galilei][Wikipedia page on Galileo Galilei]] gives many links to his notebooks.
- [[https://ebooks.adelaide.edu.au/c/cook/james/c77j/index.html][Captain Cook's journal]] relating his first trip is available.
- [[http://darwin-online.org.uk/][Darwin's notebooks]] are also available.
- The exhaustive collection of [[http://linnean-online.org/61332/#/0][Carl Linneaus]] paper slips can be found online.
- The complete collection of [[http://scarc.library.oregonstate.edu/coll/pauling/rnb/index.html][Linus Pauling]] labbooks can also be accesssed.
- The meridian's measure from Bunkirk to Barcelona by Delambre and Méchain is wonderfully made by Ken Alder in his book "The Measure of All Things: The Seven-Year Odyssey and Hidden Error that Transformed the World", *a must read*.
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Ressources pour la séquence 0 du module 1 : « Introduction »
#+DATE: <2019-03-25 jeu.>
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: fr
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
* Table des matières :TOC:
- [[#le-cahier-de-notes][Le « cahier de notes »]]
- [[#exemples-concrets-de-cahier-de notes][Exemples concrets de « cahier de notes ]]
* Le « cahier de notes »
Le « cahier de notes » doit être considéré ici « au sens large » ; c’est-à-dire que, suivant le contexte, il sera plus proprement appelé « cahier de terrain », « cahier d’observations », « journal » ou « cahier de laboratoire ». Ce qui nous intéresse ici est la notion de supports (papiers ou numériques) dans lesquels des informations sont stockées au fil du temps – contrairement au cas d’un mémoire ou d’un article où c’est la logique de l’argumentation qui structure le contenu – ; ces informations sont de plus de nature souvent hétérogène et leurs supports, lorsqu’ils sont multiples, aussi (par exemple, un cahier de notes associé à des fichiers textes).
* Exemples concrets de « cahier de notes »
- Les cahiers de Léonard de Vinci ([[http://unesdoc.unesco.org/images/0007/000748/074877fo.pdf][lien vers le pdf]]) et la page Wikipédia sur [[https://fr.wikipedia.org/wiki/Codex_Leicester][Le Codex Leicester]] ;
- La [[https://en.wikipedia.org/wiki/Galileo_Galilei][Page wikipedia sur Galilée]] contient de nombreux liens, certains vers ses cahiers de notes ;
- Les « [[http://gallica.bnf.fr/Search?ArianeWireIndex=index&p=1&lang=EN&f_typedoc=manuscrits&q=Louis+Pasteur+registres][registres de laboratoire]] » de Pasteur sont disponibles sur Gallica ;
- Les [[http://gallica.bnf.fr/ark:/12148/btv1b90797770/f1.image.r=Emile%20Zola][dossiers préparatoires de Zola pour les Rougon-Macquart]] sont aussi disponibles sur Gallica ;
- Le [[https://ebooks.adelaide.edu.au/c/cook/james/c77j/index.html][journal de bord de James Cook]] lors de son premier voyage sont consultables – [[http://southseas.nla.gov.au/journals/hv01/title.html][un autre exemple]] plus complet est aussi disponible –, [[https://en.wikipedia.org/wiki/James_Cook][la page Wikipedia]] contient un grand nombre de liens ;
- L’essentiel des [[http://darwin-online.org.uk/][cahiers de notes de Charles Darwin]] est consultable en ligne ;
- Les [[http://linnean-online.org/61332/#/0][fiches de Carl von Linnée]] sont consultables en ligne ;
- Les [[http://scarc.library.oregonstate.edu/coll/pauling/rnb/index.html][cahiers de laboratoire de Linus Pauling]] sont disponibles dans leur intégralité ;
- L’histoire de la [[https://fr.wikipedia.org/wiki/Figure_de_la_Terre_et_m%C3%A9ridienne_de_Delambre_et_M%C3%A9chain#M%C3%A9ridienne_de_Delambre_et_M%C3%A9chain_et_progr%C3%A8s_scientifiques_%C3%A0_la_m%C3%AAme_%C3%A9poque][mesure du méridien]] de Dunkerke à Barcelone par Delambre et Méchain est remarquablement contée dans le livre de Ken Alder, « Mesurer le monde - 1792-1799 : l’incroyable histoire de l’invention du mètre » (en poche chez Flammarion) ; les cahiers de notes y jouent un rôle tout à fait primordial.
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: We all use notebooks
#+DATE: <2019-03-21 jeu.>
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: en
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
* Table of contents :TOC:
- [[#introduction][Introduction]]
- [[#annotated-manuscripts][Annotated manuscripts]]
- [[#note-cabinets-from-placcius-and-leibniz][Note cabinets from Placcius and Leibniz]]
- [[#on-the-preface-to-penguin-island][On the preface to /Penguin Island/]]
- [[#the-logbooks][The logbooks]]
- [[#one-missing-the-classic-laboratory-notebook][One missing: the classic laboratory notebook]]
* Introduction
This sequence discusses a much wider issue than /reproducible research/ (RR). Implementing RR requires thorough note-taking and note-taking concerns everyone. The purpose of this sequence is therefore to remind the reader / auditor that he/she already knows: *note-taking concerns everyone*. Few examples are used to that end.
* Annotated manuscripts
As an introduction to the world of annotated manuscripts, I quote now a small selection of passages from the first chapter of /LA PAGE. DE L'ANTIQUITÉ À L'ÈRE DU NUMÉRIQUE/ (THE PAGE. FROM ANTIQUITY TO THE DIGITAL ERA) by Anthony Grafton (Hazan, 2012):
#+BEGIN_EXAMPLE
By the very movement of his pen on the page, it is clear that
Casaubon masters everything he reads. He constantly underlines the importance of
words and expressions, he notes in the margin key words and summaries
showing that he has read carefully, even when, he states in his
diary that he studied in one day forty to fifty pages
in-folio of Greek with many abbreviations. The most important
passages give rise to longer comments in the margin.
On the title pages, Casaubon very often carries - a little
as Montaigne - a global judgment on the value of the work.
In addition, he notes his thoughts in notebooks, or takes
notes on texts he can't buy. As they are
gathered in his library, his books represent a whole life of
reading that can be reconstructed over the pages.
#+END_EXAMPLE
Pages 32 and 33, about [[https://en.wikipedia.org/wiki/Isaac_Casaubon][Isaac Casaubon]] (1559-1614).
#+BEGIN_EXAMPLE
Yet Harvey left much more than that, including
traces of his readings in the form of more than a hundred books
covered with wonderfully written annotations of his beautiful slanted
writing - in addition to the notebooks in which he wrote extracts.
Clearly, Harvey considered reading to be his profession,
and he made it an art too. Decade after decade, he lays down his
thoughts on history in an in-folio edition of 1555 of Livy's "History
of Rome". His notes, mostly in Latin, go through
the margins, spread between chapters and fill in
loose sheets, taking on a particularly erudite aspect and
quite daunting.
#+END_EXAMPLE
Pages 35 and 36, on [[https://en.wikipedia.org/wiki/Gabriel_Harvey][Gabriel Harvey]] (1545-1630).
#+BEGIN_EXAMPLE
... But in the remaining working copy of the
text, the basic edition of 1549, he [Casaubon] introduced so many annotations
that the cataloguers of the Bodleian Library, who were only
not familiar with rhetoric, have classified this printed book as a manuscript.
#+END_EXAMPLE
Page 40.
* Note cabinets from Placcius and Leibniz
I found this example in Ann Blair's work such as [[https://dash.harvard.edu/bitstream/handle/1/4774908/blair_notetaking.pdf?sequence=1][The Rise of Note-Taking in Early Modern Europe]] and her book /TOO MUCH TO KNOW. Managing Scholarly Information before the Modern Age/, published by Yale University Press in 2011.
* On the preface to /Penguin Island/
The text can be found /legally/ at several places, the [[https://en.wikipedia.org/wiki/Project_Gutenberg][Project Gutenberg]] one is missing the "Preface", so don't use it, go to one of the versions available on [[https://archive.org/search.php?query=title%3Apenguin%20island%20AND%20-contributor%3Agutenberg%20AND%20mediatype%3Atexts][Internet Archive]]. The importance of the preface in illustrated by the following two quotations:
#+BEGIN_QUOTE
One word more if you want your book to be well
received, lose no opportunity for exalting the virtues on
which society is based — attachment to wealth, pious senti-
ments, and especially resignation on the part of the poor,
which latter is the very foundation of order. Proclaim, sir,
that the origins of property — nobility and police — are treat-
ed in your history with the respect which these institutions
deserve. Make it known that you admit the supernatural
when it presents itself. On these conditions you will succeed
in good society.
#+END_QUOTE
And more importantly for our present subject:
#+BEGIN_QUOTE
The idea occurred to me, in the month of June last year, to
go and consult on the origins and progress of Penguin art,
the lamented M. Fulgence Tapir, the learned author of the
‘Universal Annals of Painting, Sculpture and Architecture’
Having been shown into his study, I found seated before a
roll-top desk, beneath a frightful mass of papers, an amaz-
ingly short-sighted little man whose eyelids blinked behind
his gold-mounted spectacles.
To make up for the defect of his eyes his long and mobile
nose, endowed with an exquisite sense of touch, explored the
sensible world. By means of this organ Fulgence Tapir put
himself in contact with art and beauty. It is observed that in
France, as a general rule, musical critics are deaf and art
critics are blind. This allows them the collectedness neces-
sary for æsthetic ideas. Do you imagine that with eyes capable
of perceiving the forms and colours with which mysterious
nature envelops herself, Fulgence Tapir would have raised
himself, on a mountain of printed and manuscript docu-
ments, to the summit of doctrinal spiritualism, or that he
would have conceived that mighty theory which makes the
arts of all tunes and countries converge towards the Institute
of France, their supreme end?
The walls of the study, the floor, and even the ceiling were
loaded with overflowing bundles, pasteboard boxes swollen
beyond measure, boxes in which were compressed an in-
numerable multitude of small cards covered with writing. I
beheld in admiration minted with terror the cataracts of
erudition that threatened to burst forth.
‘Master,’ said I in feeling tones, ‘I throw myself upon
your kindness and your knowledge, both of which are
inexhaustible. Would you consent to guide me in my
arduous researches into the origins of Penguin art?’
‘Sir,’ answered the Master, ‘I possess all art, you under-
stand me, all art, on cards classed alphabetically and in
order of subjects. I consider it my duty to place at your dis-
posal all that relates to the Penguins. Get on that ladder and
take out that box you see above. You will find in it every-
thing you require.’
I tremblingly obeyed. But scarcely had I opened the fatal
box than some blue cards escaped from it, and slipping
through my fingers, began to rain down. Almost immediate-
ly, acting in sympathy, the neighbouring boxes opened, and
there flowed streams of pink, green, and white cards, and by
degrees, from all the boxes, differently coloured cards were
poured out murmuring like a waterfall on a mountain side
in April. In a minute they covered the floor with a thick
layer of paper. Issuing from their inexhaustible reservoirs
with a roar that continually grew in force, each second in-
creased the vehemence of their torrential fall. Swamped up
to the knees in cards, Fulgence Tapir observed the cataclysm
with attentive nose. He recognised its cause and grew pale
with fright
‘What a mass of art !’ he exclaimed.
I called to him and leaned forward to help him mount the
ladder which bent under the shower. It was too late. Over-
whelmed, desperate, pitiable, his velvet smoking-cap and his
gold-mounted spectacles having fallen from him, he vainly
opposed his short arms to the flood which had now mounted
to his arm-pits. Suddenly a terrible spurt of cards arose and
enveloped him in a gigantic whirlpool. During the space of a
second I could see in the gulf the shining skull and little fat
hands of the scholar, then it closed up and the deluge kept
on pouring over what was silence and immobility. In dread
lest I in my turn should be swallowed up ladder and all I
maae my escape through the topmost pane of the window.
#+END_QUOTE
* The logbooks
I would like to thank Joël Caselli for helping me interpret the content of Éric Tabarly's logbook.
This example is only superficially anecdotal. Ten years ago, a European project was aiming at estimating the Atlantic and Indian Oceans climates during the 18th century using logbooks from ships of the West- and East-India companies from the Kingdoms of Portugal, Spain, Holland, Britain and France. See the [[http://webs.ucm.es/info/cliwoc/][Climatological Database for the World's Oceans 1750-1850]].
In the same vein, logbooks from slave ships give a lot of quantitative information about the slave trade between Africa and the "New World" (see Marcus Rediker frightening book /The Slave Ship: A Human History/, 2007).
* One missing: the classic laboratory notebook
I quote here Sec. 6.2 =Notebooks and Records= of the highly recommended reading /An Introduction to Scientific Research/ by E. Bright Wilson (reprinted by Dover):
#+BEGIN_QUOTE
It is hard to conceive of a perfect laboratory notebook, and it is regrettably rare to find one that is even moderately
satisfactory; yet the keeping of good records of work done is a major key to efficiency. There are bound to be dissenters
to any set of fixed rules, but these will probably be rarer for the ritual of notebook keeping than elsewhere. Consequently,
a set of rules which is generally regarded as satisfactory, or even as essential, will be somewhat dogmatically stated.
Some great discoveries have been delayed because of careless record keeping. Thus it is related that the astronomer Le Monnier
observed the planet Uranus on several occasions, before its identification as a planet had been announced by Herschel, but
decided that it was a fixed star. This was probably due in part to the fact that he wrote his measurements on scraps of paper,
including a paper bag originally containing hair powder!
Laboratory notebooks should be permanently and strongly bound and of sufficient size, say roughly 8 by 10 inches, with numbered
pages. Loose-leaf pages or separate sheets are too easily lost to be satisfactory, especially since a laboratory notebook gets
rather rough handling, and perhaps an occasional dousing with acid. An exception is the case of routine, repeated measurements,
where a printed or mimeographed special blank is often useful if a good system is established for collecting and binding the
separate sheets. Ruled pages are generally used, but this is a matter of personal taste, and some prefer unruled or cross-sectional
pages. A rubber stamp may be used to provide headings for routine entries.
Data should be entered directly into the notebook at the time of observation. It is intolerable to use memory or scraps of paper
for primary recording, because of the inevitability of error and loss. Therefore, there should be a good place for the notebook
at the operating position, and the experimenter should never be without his book when in action.
Data should be recorded in ink, preferably a permanent brand, and a blotter should be handy. Otherwise the record is too ephemeral.
Notebooks get hard usage, and pencil smudges rapidly. When the notebook may be used as evidence in a patent case, ink is much
preferred.
Rough, qualitative graphs can be drawn in directly, but more careful ones are usually best prepared on graph paper of the most
appropriate type These are then carefully pasted in the notebook, a blank page being cut out in order to compensate for the bulk of
the one added.
Notebooks should carry the name of the user and the dates covered. It is convenient in a research group to agree on a standard size,
but then some sort of external identification is a great timesaver. The first eight or ten pages should be reserved for a table of
contents. This consists of a line added chronologically for each series of similar experiments, together with the page reference.
The table of contents is enormously helpful in finding items later and is very simple to keep up. An index in the back of the book
is advantageous but not indispensable.
Each entry should be dated and, if several individuals use one book (not generally recommended), initialed. The material should not
be crowded on the pages; paper is cheap compared with other research expenses. The principal difficulty is in deciding what to put in.
Obviously, one enters numerical results and those values of the independent variables such as temperature, composition, or pressure
which are directly concerned. It is also necessary to have a system of entries or references so that years later it will be possible to
tell what apparatus was used and under what circumstances. Somewhere there should be available a rather complete description of the
apparatus. Then, when modifications are made, they should be described immediately in the notebook. It should also be possible to trace
back the source of calibration curves, corrections, etc., which were appropriate to the data of a given day. It is helpful if the
requirements for writing a paper, a thesis, or a book are kept in mind. Such a task, once carried out, usually leads to solemn resolves
to keep a more careful notebook in the future. Also extremely salutary is the effect of trying to figure out something from another’s
book. All references to apparatus, places, times, books, papers, graphs, and people should be sufficiently explicit to be understandable
years later. It should be possible to take each scientific paper and show just where every figure, description, or statement in it is
backed up by original observations in the laboratory notebook, and exactly why the final and original numbers differ, if they do.
Some statement of the purpose of each experiment and a summary of the conclusions reached make the notebook vastly more useful.
Sketches, drawings, and diagrams are essential. Since so much observation is visual, it is important to record what is actually seen,
including things not fully understood at the time. Bad or unpromising experiments, even those deemed failures, should be fully recorded.
They represent an investment of effort which should not be thrown away, because often something can be salvaged, even if it is only a
knowledge of what not to do. Data should always be entered in their most primary form, not after recalculation or transformation. If it
is a ratio of two observations which is of interest but it is the two numbers which are actually observed, the two numbers should be
recorded. If the precise weight of an object is important, the individual balance weights used and their identification should be
included, i.e., the serial number of the box. Otherwise it is not possible to apply calibration corrections later or to change the
corrections if new values appear. Naturally, this detail is not necessary if only a rough weight is involved. A tabular form is best for
numerical data. Units should be noted.
Where patent questions are involved, it may be desirable to witness and even to notarize notebook pages at intervals. The witness should
be someone who understands the material but is not a coinventor. Material added to a page at a later date should be in a different-colored
ink, and any alterations should be initialed, witnessed, and dated if they are likely to be important. Industrial concerns usually enforce
their own rules concerning patent matters.
Identification Numbers. It is foolish to spend time and money making records of various kinds such as pen-and-ink recorder sheets,
photographic records, or spectra if these are then lost or mixed up. Every such record should carry indelibly on it complete identification.
A simple system of doing this which has worked well in practice is to write in ink on each record a symbol identifying the notebook and then
the page number on which the auxiliary data are recorded. If more than one record occurs on a page, letters or further numerals can be added.
Thus EBW II 85c would identify the third record discussed on page 85 of the second EBW notebook. This is better than a serial number, which
doesn’t tell without extra keying where to look for the notebook entry.
A good filing system is indispensable for all films, photographs, charts, graphs, circuit diagrams, drawings, blueprints, etc. It is hardest
to devise satisfactory filing methods for either very small or very large material. The former are easily lost and the latter very bulky.
Small envelopes are useful for tiny films and also protect them from scratching.
It is thoroughly worth while to save drawings and blueprints from which apparatus has been built, however rough these may be. These should be
dated, initialed, and labeled; in fact every piece of paper containing useful material should be so marked. When an electronic or other
similar piece of equipment is built, a careful circuit diagram should be prepared, fully labeled with all constants. The apparatus should
carry a serial number which also appears on the diagram. When changes are made, these should be indicated on the diagram and dated or a revised,
dated diagram made. The old one should not be obscured or thrown away because it may be required to explain earlier data, later found to be
peculiar. It is convenient to draw such diagrams on tracing paper with a good black pencil. Cheap ozalid or similarly processed copies can then
be made. One should be kept in the laboratory, where it will usually prove indispensable for trouble shooting. Sooner or later, however, it will
be used as scratch paper by someone with a brilliant idea to demonstrate; so the official copy and spares should be filed elsewhere. A great deal
of time is unnecessarily wasted poking around the insides of an apparatus trying to find out where some wire goes.
[...]
Labeling. Related to the question of notebooks and records is that of labeling. Naturally bottles of chemicals must carry adequate labels, which
should include not only the chemical name but also the source, or a notebook page reference if there has been any special treatment, or initials
and date. One research worker departed from a certain laboratory to take another job and left a good deal of material behind. One bottle of clear
liquid carried no label. Those assigned to clean up examined it, smelled it, finally concluded that it was water, and poured it down the drain.
It was water, all right—heavy water at $30 an ounce. Some supervisors relentlessly throw out unlabeled bottles on sight. It only needs to be done
once or twice. Labels are also essential on all kinds of specimens, pieces of apparatus, gadgets, etc. Controls on apparatus should be labeled and
the apparatus itself numbered. Every laboratory has orphaned pieces of equipment, often electronic, of which no one knows the nature and purpose.
The notebook page system is good here, provided the old notebooks can be found. Labels should be attached so that they will stay. Metal tags can
be riveted on. Paper labels should be covered with some sort of varnish.
The whole purpose of all these recording systems is to preserve values. They should be carefully thought out to fit the conditions of each
laboratory and should be adequate but not overelaborate. If too much is demanded of human nature, the system will break down.
#+END_QUOTE
** Additional links
A student of the course pointed to us a very interesting ressource on laboratory notebooks: [[https://colinpurrington.com/tips/lab-notebooks]].
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Nous utilisons tous des cahiers de notes
#+DATE: <2019-02-21 jeu.>
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: fr
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
* Table des matières :TOC:
- [[#manuscrits-annotés][Manuscrits annotés]]
- [[#armoires-à-notes-de-placcius-et-leibniz][Armoires à notes de Placcius et Leibniz]]
- [[#la-préface-de-lîle-des-pingouins-danatole-france][La préface de « L'île des pingouins » d'Anatole France]]
- [[#les-livres-de-bord][Les livres de bord]]
- [[#un-absent-le-cahier-de-laboratoire-classique][Un absent : le cahier de laboratoire classique]]
* Manuscrits annotés
En guise d'entrée dans l'univers des manuscrits annotés, je fais suivre une petite sélection de passages du premier chapitre de « LA PAGE. DE L'ANTIQUITÉ À L'ÈRE DU NUMÉRIQUE » d'Anthony Grafton (Hazan, 2012) :
#+BEGIN_EXAMPLE
Par le mouvement même de sa plume sur la page, il est clair que
Casaubon maîtrise tout ce qu'il lit. Constamment, il souligne des
mots et des expressions, il note en marge des mots clés et des résumés
montrant qu'il a lu attentivement, même quand, précise-t-il dans son
journal intime, il étudie en une journée quarante à cinquante pages
in-folio de grec émaillées de nombreuses abréviations. Les passages
plus importants donnent lieu en marge à des commentaires plus
longs. Sur les pages de titre, Casaubon porte très souvent — un peu
comme Montaigne — un jugement global sur la valeur de l'ouvrage.
Par ailleurs, il note ses réflexions dans des carnets, ou prend
des notes sur des textes qu'il ne peut pas acheter. Tels qu'ils sont
réunis dans sa bibliothèque, ses livres représentent une vie entière de
lecture que l'on peut reconstituer au fil des pages.
#+END_EXAMPLE
Pages 32 et 33, à propos d'[[https://fr.wikipedia.org/wiki/Isaac_Casaubon][Isaac Casaubon]] (1559-1614).
#+BEGIN_EXAMPLE
Pourtant, Harvey a laissé beaucoup plus que cela, et notamment
des traces des ses lectures sous forme de plus d'une centaine de livres
couverts d'annotations magnifiquement écrites de sa belle écriture
italique — en plus des cahiers dans lesquels il notait des extraits.
Manifestement, Harvey considérait la lecture comme sa profession,
et il en a fait aussi un art. Décennie après décennie, il couche ses
pensées sur l'histoire dans une édition in-folio de 1555 de l'Histoire
romaine de Tite-Live. Ses notes, en latin pour la plupart, parcourent
les marges, se répandent entre les chapitres et remplissent
des feuilles volantes, prenant un aspect particulièrement érudit et
assez rébarbatif.
#+END_EXAMPLE
Pages 35 et 36, à propos de [[https://en.wikipedia.org/wiki/Gabriel_Harvey][Gabriel Harvey]] (1545-1630).
#+BEGIN_EXAMPLE
... Mais dans l'exemplaire de travail qui subsiste du
texte, l'édition de base de 1549, il [Casaubon] introduit tant d'annotations
précises que les catalogueurs de la Bibliothèque bodléienne, qui n'étaient
pas rompus à la rhétorique, ont classé ce livre imprimé parmi les manuscrits.
#+END_EXAMPLE
Page 40.
* Armoires à notes de Placcius et Leibniz
J'ai trouvé cet exemple dans les travaux d'[[https://projects.iq.harvard.edu/ablair][Ann Blair]] comme « [[https://dash.harvard.edu/handle/1/4774908][The Rise of Note-Taking in Early Modern Europe]] » et son livre « [[https://yalebooks.yale.edu/book/9780300165395/too-much-know][TOO MUCH TO KNOW. Managing Scholarly Information before the Modern Age]] », publié chez /Yale University Press/ en 2011.
* La préface de « L'île des pingouins » d'Anatole France
Étant très loin de connaître Anatole France sur le bout des doigts, j'ai trouvé la référence citée dans le remarquable article de Keith Thomas publié par la /London Review of Books/, [[https://www.lrb.co.uk/v32/n11/keith-thomas/diary][le 10 juin 2010]]. Cet article (en anglais) décrit et discute le travail concret de prise de notes par un historien, il est de plus très bien écrit et plein d'anecdotes.
* Les livres de bord
Je remercie Joël Caselli de m'avoir aidé à interpréter le contenu du livre de bord d'Éric Tabarly.
Le projet européen de reconstruction des climats des océans atlantique et indien (et non pacifique comme je le dis dans le cours !) : [[http://webs.ucm.es/info/cliwoc/][/Climatological Database for the World's Oceans 1750-1850/]] ; dispose d'un site internet très intéressant (mais en anglais).
On trouvera des citations abondantes (et effrayantes) de livres de bord de navires négriers dans le livre de Marcus Rediker « À bord du négrier : Une histoire atlantique de la traite » (disponible en édition de poche).
* Un absent : le cahier de laboratoire classique
Je traduis ici la section 6.2 /Notebooks and Records/ du remarquable livre de E. Bright Wilson /An Introduction to Scientific Research/ réimprimé par Dover.
Il est difficile de concevoir un cahier de laboratoire parfait et il est malheureusement rare d'en trouver un qui soit même à peu près satisfaisant ; la conservation d'une trace écrite du travail effectué est néanmoins une source majeure d'efficacité. Il y aura forcément des gens opposés à un ensemble de règles fixes, mais cela sera probablement plus rare pour le rituel de garder un cahier que sur d'autres sujets. Par conséquent, un ensemble de règles qui sont généralement considérées comme satisfaisantes, voire même essentielles, seront quelque peu dogmatiquement énoncées.
De grandes découvertes ont été retardées en raison d'une négligente tenue des traces écrites. L'astronome Le Monnier est ainsi supposé avoir observé la planète Uranus à plusieurs reprises -- avant que son identification comme planète ait été annoncée par Herschel --, mais a décidé qu'elle était une étoile fixe. Cela s'explique probablement en partie par le fait qu'il a écrit ses mesures sur des morceaux de papier, y compris un sac en papier contenant à l'origine de la poudre pour cheveux !
Les cahiers de laboratoire doivent être solidement reliés, d'une taille approximative de 20 x 25 cm, avec des pages numérotées. Les feuilles séparées sont trop facilement perdues pour être satisfaisantes, d'autant plus qu'un cahier de laboratoire subit souvent un traitement un peu rude avec peut-être des projections occasionnelles d'acide [c'est un physico-chimiste qui écrit]. Le cas de mesures répétées constitue une exception où une ébauche spéciale imprimée est souvent utile si un bon système est établi pour collecter et relier les feuilles séparées. Les pages avec des lignes sont généralement utilisées, mais il s'agit d'une question de goût personnel, et certaines préfèrent des pages blanches ou à carreaux. Un tampon en caoutchouc peut être utilisé pour fournir des en-têtes pour les entrées les plus communes.
Les données doivent être entrées directement dans le cahier au moment de l'observation. Il est intolérable d'utiliser sa mémoire ou des fragments de papier pour l'enregistrement primaire, du fait de l'inévitabilité des erreurs et des pertes. Il devrait donc y avoir une bonne place pour le cahier à coté du poste de travail, et l'expérimentateur ne devrait jamais être sans son cahier lorsqu'il est en action.
Les données doivent être enregistrées à l'encre, de préférence une encre permanente, un buvard peut être pratique. Sinon, la trace écrite est trop éphémère. Les cahiers sont soumis à une utilisation intensive et les écritures au crayons se détériorent trop rapidement. Lorsque le cahier peut être utilisé comme preuve pour un brevet, l'usage de l'encre s'impose.
Des graphiques approximatifs et qualitatifs peuvent être dessinés directement, mais les graphiques précis sont généralement préparés avec le papier graphique du type le plus approprié [pensez au papier millimétré]. Ils sont ensuite soigneusement collés dans le cahier, une page vierge étant découpée afin de compenser l'épaisseur ajoutée.
Les cahiers doivent porter le nom de l'utilisateur et les dates couvertes. [...]. Les huit ou dix premières pages devraient être réservées pour une table des matières. Il s'agit de lignes ajoutées chronologiquement pour chaque série d'expériences similaires, ainsi que la référence de la page. La table des matières est extrêmement utile pour trouver des éléments plus tard et est très simple à suivre. Un index au dos du cahier est avantageux mais pas indispensable.
Chaque élément devrait être datée et, si plusieurs personnes utilisent un cahier (généralement pas recommandé), paraphé. Le contenu ne devrait pas inscrit de façon trop dense sur les pages ; le papier est bon marché par rapport aux autres dépenses de recherche.
La principale difficulté est de décider ce qu'il faut écrire dans le cahier. Évidemment, on entre les résultats numériques et les valeurs des variables indépendantes telles que la température, la composition ou la pression qui sont directement pertinentes. Il est également nécessaire d'avoir un système d'entrées ou de références afin que, plus tard, il soit possible de dire quel appareil a été utilisé et dans quelles circonstances. Une description assez complète de l'appareil devrait être conservée. Ensuite, lorsque des modifications sont apportées à l'appareil, elles doivent être décrites immédiatement dans le cahier. Il devrait également être possible de retracer la source des courbes d'étalonnage, des corrections, etc., qui étaient appropriées aux données d'un jour donné. Il est utile que les exigences relatives à l'écriture d'un article, d'une thèse ou d'un livre soient gardées à l'esprit. Une telle tâche, une fois effectuée, entraîne généralement la résolution solennelle de garder un cahier plus détaillé dans le futur. Essayer de comprendre le cahier de notes de quelqu'un d'autre constitue aussi un exercice hautement salutaire. Toutes les références aux appareils, aux lieux, aux horaires, aux livres, aux articles, aux graphiques et aux personnes devraient être suffisamment explicites pour être compréhensibles des années plus tard. *Il devrait être possible de prendre chaque article scientifique et de montrer exactement où chaque figure, description ou déclaration est justifiée par des observations originales dans le cahier de laboratoire, et exactement pourquoi les nombres final et original diffèrent, si tel est le cas*.
Un énoncé du but de chaque expérience et un résumé des conclusions obtenues rendent le cahier beaucoup plus utile.
Les croquis, dessins et diagrammes sont essentiels. Comme tant d'observations sont visuelles, /il est important de noter ce qui est réellement vu, y compris des éléments qui ne sont pas entièrement compris lors de leur observation/.
Les expériences mauvaises ou non prometteuses, même celles considérées comme des échecs, devraient être entièrement enregistrées. Elles représentent un effort qui ne doit pas être gaspillé, car souvent quelque chose peut être récupéré, même si ce n'est qu'une connaissance de ce qu'il ne faut pas faire.
Les données doivent toujours être entrées dans leur forme la plus primaire, et non après un calcul ou une transformation. Si c'est le rapport de deux observations qui est intéressant, mais si les deux nombres sont effectivement observés, les deux nombres doivent être enregistrés. Si le poids précis d'un objet est important, les poids d'équilibrage individuels utilisés et leur identification devraient être inclus, c'est-à-dire le numéro de série de leur boîte. Dans le cas contraire, il devient impossible d'appliquer ultérieurement des corrections d'étalonnage ou de modifier les corrections si de nouvelles valeurs apparaissent. Naturellement, ce détail n'est pas nécessaire si seulement un poids approximatif est impliqué. La forme tabulaire est la meilleure pour les données numériques. Les unités doivent être notées.
Lorsque des brevets sont impliquées, il peut être souhaitable d'authentifier les pages des cahiers à intervalles réguliers. Le témoin devrait être quelqu'un qui comprend le contenu mais qui n'est pas impliqué dans la recherche. Un contenu ajouté ultérieurement à une page devrait l'être dans une encre de couleur différente, et toutes les modifications devraient être paraphées, authentifiées et datées si elles sont susceptibles d'être importantes. Les entreprises industrielles font ainsi généralement respecter leurs propres règles en matière de cahiers de laboratoire.
*Numéros d'identification*. Il est stupide de consacrer du temps et de l'argent à des enregistrements de différents types [...] si ceux-ci sont ensuite perdus ou mélangés. Tout enregistrements qui ne peut être inclut directement dans le cahier de notes devraient porter une identification complète indélébile. Un système simple qui a fait ses preuves consiste à écrire à l'encre sur chaque enregistrement un symbole identifiant le cahier, puis le numéro de page sur lequel les données auxiliaires sont enregistrées. Si plus d'un enregistrement sont mentionnés sur une page du cahier, des lettres ou des chiffres supplémentaires peuvent être ajoutés. Ainsi, EBW II 85c identifie le troisième enregistrement discuté à la page 85 du deuxième cahier EBW. C'est mieux qu'un numéro de série qui ne dit pas, sans clé supplémentaire, où chercher la description le concernant dans le cahier.
Un bon système de classement est indispensable pour tous les films, les photographies, les schémas, les graphiques, les diagrammes de circuit, les dessins, les plans, etc. Il est plus difficile de concevoir des méthodes de dépôt satisfaisantes pour des matériaux très petits ou très grands. Les premiers sont facilement perdus et les dernier très volumineux. [...]
Il est important d'archiver les dessins et les plans à partir desquels les appareils utilisés ont été construits, même si ces dessins sont grossiers. Ils doivent être datés, paraphés et étiquetés ; en fait, tout morceau de papier contenant une information utile devrait être marqué de la sorte. Lorsqu'un équipement électronique ou autre est fabriqué, son diagramme doit être soigneusement préparé et entièrement étiqueté avec toutes les constantes. L'appareil doit porter un numéro de série qui apparaît également sur ce diagramme. Lorsque des modifications sont apportées, celles-ci doivent être indiquées sur le schéma et datées ou un diagramme révisé et daté doit être préparé. L'ancien ne doit pas être obscurci ou jeté, car il peut être nécessaire pour expliquer des données antérieures, considérées ultérieurement comme étranges. [...]
Le but de toute cette pratique de prise de notes est de préserver la valeur [le temps et les moyens humains et matériels investis dans la recherche]. Elle devrait être soigneusement conçus pour s'adapter aux conditions de chaque laboratoire et devraient être adéquate mais pas trop élaborés. *Si l'on exige trop de la nature humaine, le système ne fonctionnera pas*.
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: A historical survey of note taking
#+DATE: <2019-03-21 jeu.>
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: en
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
* Table of contents :TOC:
- [[#illustrations-used-in-the-first-figure][Illustrations used in the first figure]]
- [[#wax-tablet-and-stylus][Wax tablet and stylus]]
- [[#from-the-scroll-to-the-codex][From the /scroll/ to the /codex/]]
- [[#codex-significance][/Codex/ significance]]
- [[#eusebius-and-the-invention-of-cross-references][Eusebius and the invention of cross-references]]
- [[#eusebian-canons][Eusebian canons]]
- [[#let-us-not-forget-china][Let us not forget China]]
- [[#getting-organized-by-using-the-right-slot][Getting organized by using the right slot]]
- [[#constructing-a-notebook-index-the-john-locke-way][Constructing a notebook index the John Locke way]]
* Illustrations used in the first figure
All illustrations are taken from Wikimedia Commons
- Top left: A clay tablet (pre-cuneiform period, -3000).
- Top center: A fresco from Pompeii with the portrait of [[https://en.wikipedia.org/wiki/Portrait_of_Paquius_Proculo][Terentius Neo and his wife]]. She carries a [[https://en.wikipedia.org/wiki/Wax_tablet][wax tablet]] and a /stylus/ (the main medium of note-takers up to the 19th century); he carries a /volumen/ or [[https://en.wikipedia.org/wiki/History_of_scrolls][scroll]], the stuff of books until the beginning of the Common Era.
- Top right: a notebook made of paper from the 17th century with [[https://en.wikipedia.org/wiki/Commonplace_book][commonplaces]]. "Commonplace" is a translation of the Latin term locus communis (from Greek tópos koinós, see literary topos) which means "a theme or argument of general application", such as a statement of proverbial wisdom (Wikipedia).
- Bottom left: An [[https://en.wikipedia.org/wiki/Index_card][index card]], a notes medium whose use exploded with bureaucratization and the development of libraries. Still heavily used in the humanities. Apparently first used (if not created) by the father of taxonomy, [[https://en.wikipedia.org/wiki/Carl_Linnaeus][Carl Linneaus]]. You can find his cards at: [[http://linnean-online.org/61332/#/0]].
- Bottom center: A [[https://en.wikipedia.org/wiki/Post-it_note][Post-it note]] as most of us use every day.
- Bottom right: A "modern days" numerical tablet.
* Wax tablet and stylus
From the [[https://en.wikipedia.org/wiki/Wax_tablet][Wikipedia page]]:
#+BEGIN_QUOTE
A wax tablet is a tablet made of wood and covered with a layer of wax, often linked loosely to a cover tablet, as a "double-leaved" diptych.
It was used as a reusable and portable writing surface in Antiquity and throughout the Middle Ages.
Writing on the wax surface was performed with a pointed instrument, a stylus. Writing by engraving in wax required the application of much
more pressure and traction than would be necessary with ink on parchment or papyrus,[1] and the scribe had to lift the stylus in order to
change the direction of the stroke. Therefore, the stylus could not be applied with the same degree of dexterity as a pen. A straight-edged,
spatula-like implement (often placed on the opposite end of the stylus tip) would be used in a razor-like fashion to serve as an eraser.
The entire tablet could be erased for reuse by warming it to about 50 °C and smoothing the softened wax surface. The modern expression of
"a clean slate" equates to the Latin expression "tabula rasa".
#+END_QUOTE
** From the /scroll/ to the /codex/
The shift from the /scroll/ to the /codex/ is fundamental for development of written civilization.
A scroll (from the Old French escroe or escroue), is a roll of papyrus, [[https://en.wikipedia.org/wiki/Parchment][parchment]], or paper containing writing.
From [[https://en.wikipedia.org/wiki/History_of_scrolls#Replacement_by_the_Codex][Wikipedia]]:
#+BEGIN_QUOTE
The codex was a new format for reading the written word, consisting of individual pages loosely attached to each other at one
side and bound with boards or cloth. It came to replace the scroll thanks to several problems that limited the scroll's function
and readability. For one, scrolls were very long, sometimes as long as ten meters. This made them hard to hold open and read, a
difficulty not helped by the fact that most scrolls in that era were read horizontally, instead of vertically as scrolling virtual
documents are read now. The text on a scroll was continuous, without page breaks, which made indexing and bookmarking impossible.
Conversely, the codex was easier to hold open, separate pages made it possible to index sections and mark a page, and the protective
covers kept the fragile pages intact better than scrolls generally stayed. This last made it particularly attractive for important
religious texts.
#+END_QUOTE
The bottom left mosaic shows Virgil seating (70-19 BCE) holding a scroll of the /Aeneid/, with Clio, muse of history, also holding a scroll.
As explained by Frédéric Barbier (/Histoire du Livre/): "The scroll / volumen imposes a complex reading practice: one must unroll (/explicare/) and roll at the same time; that forbids working on several scrolls (the original text and its commentary) at the same time or to take notes. It imposes a continuous reading and making consultation impossible."
Scrolls are clearly unsuited to "nomadic reading"; can you imagine Ulysses embarking for his Odyssey carrying the 24 scrolls/volumen of the Iliad?
The term /volumen/ is the origin of our modern /volumes/ (a book in several volumes) as of the word for the geometrical concept.
Switching from scroll to codices required two innovations:
- The collection of wax tablets bound together with leather strands.
- The generalization of [[https://en.wikipedia.org/wiki/Parchment][parchment]] (usually sheep skin specially processed) as a replacement for [[https://en.wikipedia.org/wiki/Papyrus][papyrus]]. This generalization could be due (according to Pliny the Elder) to a rivalry between the cities of Pergamon and Alexandria for cultural hegemony: [[https://en.wikipedia.org/wiki/Ptolemy_V_Epiphanes][Ptolemy V Epiphanes]] King of Egypt wanted to block [[https://en.wikipedia.org/wiki/Eumenes_II][Eumenes II]] from developing in Pergamon a library that could compete with the one of Alexandria; he therefore imposed an embargo on papyrus export (Egypt was the sole papyrus producer). Eumenes looked for an alternative and fostered parchment development. The link between Pergamon and parchment is much clearer in German where Pergamon is written in the way as in English but where parchment is written /Pergament/.
Switching from scrolls to codices will have major consequences on books organization as well as on the reading practices, it will later on allow printing development.
The main revolution brought by the codex is the /page/. Thanks to this structural element, the reader can access directly to a specific chapter or a specific part of the text, while scrolls imposed continuous reading *at a time when there were no blanks between words*. According to Collette Sirat: "Twenty centuries will be necessary to realize the paramount importance of the codex for our civilization through the *selective reading* it made possible as opposed to the continuous reading. It opened room for the elaboration of mental structures where the text is dissociated from the speech and its rhythm."
Notice the red letters used on the codex (bottom right), an example of [[https://en.wikipedia.org/wiki/Rubrication][rubrication]] used by scribes to mark paragraphs. With printing and the high cost of colors it entailed, an empty space started to be used to that end. Thinking about it, colors don't cost anything on a numerical support and could perfectly be used again in the same way.
* /Codex/ significance
Following Frédéric Barbier (/HISTOIRE DU LIVRE/, Armand Colin, 2009):
- /Codex/ invention is crucial for the development of written civilization.
- The /codex/ lends itself to *consultation reading*.
- We can add to the /codex/ a "navigation system" making consultation easier.
- We can take notes while consulting a /codex/.
- The combination of the /codex/ with the /Carolingian minuscule/ constitutes an extremely powerful intellectual tools, never seen before.
Example of /Carolingian minuscule/ can be found on the corresponding [[https://en.wikipedia.org/wiki/Carolingian_minuscule][Wikipedia page]].
Over centuries, /codices/---that we often call /manuscripts/---will slowly evolve and gain modern days book attributes:
- separation between words (VIIth century),
- start of punctuation (VIIIth century),
- table of content,
- running title,
- paragraph marks (rubrication, XIth century),
- pagination,
- index (XIIIth century).
An interesting point: Torah's content got "fixed" before the /codex/ generalization and today Torah scrolls are still used.
* Eusebius and the invention of cross-references
From the Wikipedia page on [[https://en.wikipedia.org/wiki/Eusebius][Eusebius]]:
#+BEGIN_QUOTE
Eusebius of Caesarea (ad 260/265 – 339/340), also known as Eusebius Pamphili, was a historian of Christianity, exegete, and Christian polemicist. He became the bishop of Caesarea Maritima about 314 AD. Together with Pamphilus, he was a scholar of the Biblical canon and is regarded as an extremely learned Christian of his time. He wrote Demonstrations of the Gospel, Preparations for the Gospel, and On Discrepancies between the Gospels, studies of the Biblical text.
#+END_QUOTE
According to Anthony Grafton and Megan Williams (2006) /Christianity and the Transformation of the Book/, The Belknap Press of Harvard University Press, his writings are crucial for our knowledge of the first three centuries of Christian history. /He brought several essential innovations to the book's organization like the cross-references/.
** Eusebian canons
Quote from [[https://en.wikipedia.org/wiki/Eusebius#Biblical_text_criticism][Wikipedia]]:
#+BEGIN_QUOTE
For an easier survey of the material of the four Evangelists, Eusebius divided his edition of the New Testament into paragraphs and provided it with a synoptical table so that it might be easier to find the pericopes that belong together. These canon tables or "Eusebian canons" remained in use throughout the Middle Ages, and illuminated manuscript versions are important for the study of early medieval art, as they are the most elaborately decorated pages of many Gospel books.
#+END_QUOTE
* Let us not forget China
The link between the /codex/ generalization, on the one hand, and the apparition of "navigation guides" like the table of content, the index, the running title, on the other hand as a counterpart in the Chinese civilization.
In China, competitive examinations to become a high ranking state employee developed in the IXth century (CE). The main part of these exam was a paper on what we would now call general knowledge of the Classics where the students were asked to demonstrate their knowledge through appropriate quotations.
To fulfill the need of "textbook" appropriate for this kind of examination what is called [[https://en.wikipedia.org/wiki/Leishu][leishus]] were produced. They are described as follows on Wikipedia:
#+BEGIN_QUOTE
The leishu are composed of sometimes lengthy citations from other works and often contain copies of entire works, not just excerpts. The works are classified by a systematic set of categories, which are further divided into subcategories. Leishu may be considered anthologies, but are encyclopedic in the sense that they may comprise the entire realm of knowledge at the time of compilation.
#+END_QUOTE
The efficient use of the leishu requires an indexing system, a table of content, etc. Very interestingly, the scroll will be abandoned and the codex will generalize in China around that time, as observed by Ann Blair in her book /TOO MUCH TO KNOW/, Yale Univ. Press, 2010 (pp. 28-31).
Most of the leishus *were printed* (from the IXth century on!). The picture on the right side (a banknote printing plate) is there to remind us of who was (by far) the most advanced at that time. The Chinese were of course printing their leishus on paper that they discovered in the VIIIth century BCE.
* Getting organized by using the right slot
Now that we briefly reviewed the timeline of the main navigation elements of the books---navigation elements that can of course be applied to our lab/note-books---we come back to the paper slips and cards as notes media.
We see (again) Placcius' and Leibniz's closet since it displays both the benefits and the shortcomings of media that hold *a single note*.
Obvious shortcomings are:
- Paper slips and cards get easily lost.
- They are essentially useless if they are not *classified* in addition to being filed.
These problems are solved by Placcius' cabinet, the content of which is fundamentally accessed through the index.
Clear benefits are:
- Paper slips can be easily reorganized when they contain information on several subjects.
- Paper slips can be directly pasted in a book when composing an anthology or a compendium.
This last technique (pasting when making an anthology) was systematically used by the Renaissance polymath [[https://en.wikipedia.org/wiki/Conrad_Gessner][Conrad Gessner]] (1516-1565) who even got his paper slips by cutting parts of pages from books (don't do that with library books)!
* Constructing a notebook index the John Locke way
We will now learn about an index construction technique due to [[https://en.wikipedia.org/wiki/John_Locke][John Locke]] (1632-1704), the grand-father of liberalism and a major investor in the /Royal African Company/, the largest company in the [[https://en.wikipedia.org/wiki/John_Locke#Constitution_of_Carolina][slave-trade]] business at that time...
The indexing method is here illustrated using my own notebook. The two pages that are displayed describe the structure of a dataset in the [[https://www.hdfgroup.org/][HDF5]] format on the left side and the corresponding structure (designed to map the former one) of a =data frame= object of the [[https://www.r-project.org/][R]] language. This dataset contain *calcium* concentration measurements made in *neurons*. This notes were taken while writing some computer *code* to analyze the data.
The precise content of the pages does not matter here in order to understand how Locke's method works. The important points are:
- The pages are numbered (we are seeing here pages 86 and 87).
- Keywords are written at the bottom of the page: *code*; *neuro*; *calcium*.
This method can be applied after note-taking, you just need to have few pages left at the end of your notebook. That's in fact what I did since I had started filling my notebook before learning about the method (I learned about while preparing the French version of this lecture in September 2017).
We now the index. It is located at the end of the notebook although Locke recommends placing it at the beginning. Since I did not know about the method when I started the notebook, I had to place it at the end...
The idea is to enter the keywords used in the notebook based on their *first letter* and the *first vowel following the first letter*.
The index is therefore made of the 26 letters (you see letters "A" to "R" here, the remaining ones are on the next page) subdivided the five most common vowels ("y" goes together with "i" in that case).
Pages 86 and 87 contained the keyword *code* that goes into the entry "Co" of the index (you see "86-89" because the following pages also concern code for the same project). The keyword *Neuro* giving an entry on line "Ne", while the keyword *Calcium* gives an entry on line "Ca".
The keyword *Criquet* (not shown above) gives an entry on line "Ci".
It is also a good idea to list the set of keywords used in the notebook on the page preceding or following the index.
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Un aperçu historique de la prise de notes
#+DATE: <2019-02-21 jeu.>
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: fr
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
* Table des matières :TOC:
- [[#références-générales][Références générales]]
- [[#sur-les-tablettes-de-cires][Sur les tablettes de cires]]
- [[#sur-le-passage-du-rouleau-volumen-au-codex][Sur le passage du rouleau (/volumen/) au codex]]
- [[#sur-eusèbe-de-césarée][Sur Eusèbe de Césarée]]
- [[#parallèle-chinois][Parallèle chinois]]
- [[#retour-sur-larmoire-à-notes][Retour sur l'armoire à notes]]
- [[#lindex-et-john-locke][L'index et John Locke]]
* Références générales
En plus des deux livres déjà cités (en séquence 1) :
- « La page. De l'Antiquité à l'ère du numérique » d'Anthony Grafton (Hazan, 2012) ;
- « [[https://yalebooks.yale.edu/book/9780300165395/too-much-know][TOO MUCH TO KNOW. Managing Scholarly Information before the Modern Age]] », d'Ann Blair publié chez /Yale University Press/ en 2011 ;
j'ai utilisé :
- « L'histoire du livre » de Frédéric Barbier ;
- le remarquable site de Jacques Poitou, [[http://j.poitou.free.fr/pro/index.html][langages écritures typographies]] ;
- le site [[http://classes.bnf.fr/ecritures/][l'aventure des écritures]] de la BNF ;
- le catalogue de l'exposition de la BNF « [[http://editions.bnf.fr/tous-les-savoirs-du-monde-encyclop%C3%A9dies-et-biblioth%C3%A8ques-de-sumer-au-xxie-si%C3%A8cle][Tous les savoirs du monde : Encyclopédies et bibliothèques de Sumer au XXIe siècle, sous la direction de Roland Schaer, 1997]]» ;
- « [[http://litmedmod.ca/sites/default/files/pdf/vandendorpe-papyrusenligne_lr.pdf][Du papyrus à l'hypertexte]] » de Christian Vandendorpe (La Découverte, 1999).
* Sur les tablettes de cires
Voir le site de Jacques Poitou d'où les illustrations sont empruntées([[http://j.poitou.free.fr/pro/index.html][langages écritures typographies]]) et le livre de Frédéric Barbier (« L'histoire du livre » de Frédéric Barbier - Armand Colin, 2001).
* Sur le passage du rouleau (/volumen/) au codex
Voir le livre de Frédéric Barbier (« L'histoire du livre » de Frédéric Barbier - Armand Colin, 2001), celui d'Anthony Grafton (« La page. De l'Antiquité à l'ère du numérique » de Anthony Grafton - Hazan, 2012).
Le /volumen/ est un livre à base de feuilles de papyrus collées les unes aux autres et qui s'enroule sur lui-même. Il a été créé en Égypte vers 3000 av. J.-C. Le texte est rédigé en colonnes parallèles assez étroites. C'est le support du texte par excellence durant les trente siècles précédant notre ère, d'abord en Égypte, puis dans tout le monde méditerranéen.
Comme l'explique Frédéric Barbier : « La forme du /volumen/ impose une pratique de lecture complexe : il faut dérouler (/explicare/) et enrouler en même temps, ce qui interdit par exemple, de travailler simultanément sur plusieurs rouleaux (un texte et son commentaire) ou de prendre des notes, impose une lecture suivie et empêche la simple consultation. »
Le /volumen/ n'est clairement pas adapté à une lecture « nomade » ; imagine-t-on Ulysse partant pour son Odyssée avec les 24 /volumen/ de l'Iliade ?
Le /volumen/ est à l'origine du terme « volume » dans un « livre en plusieurs volumes » comme dans la désignation du concept géométrique.
Le passage au codex repose sur deux innovations :
- la collection des tablettes de cires en « groupes reliés » ;
- la généralisation du parchemin (peau, généralement, de mouton spécialement préparée) au détriment du papyrus. Cette généralisation résulte une lutte pour l'hégémonie culturelle entre deux descendants de généraux d'Alexandre le Grand, en effet d'après Pline l'ancien : [[https://fr.wikipedia.org/wiki/Ptol%C3%A9m%C3%A9e_V][Ptolémé Épiphane]] d'Alexandrie cherchait à empêcher [[https://fr.wikipedia.org/wiki/Eum%C3%A8ne_II][Eumène II]] d'établir une bibliothèque à Pergame (au 2e siècle avant J.-C.) et avait interdit l'exportation du papyrus (produit exclusivement en Égypte), ce qui incita Eumène à chercher un substitut qui devint le parchemin.
Le remplacement du rouleau par le codex aura des conséquences majeures sur l'organisation du livre ainsi que sur la façon de lire et il permettra le développement ultérieur de l'imprimerie.
La principale révolution introduite par le codex est la notion de page. Grâce à elle, le lecteur peut accéder de manière directe à un chapitre ou à un passage du texte, alors que le rouleau impose une lecture continue. *Les mots ne sont de plus pas séparés par des espaces*. Comme l'écrit Collette Sirat : « Il faudra vingt siècles pour qu’on se rende compte que l’importance primordiale du codex pour notre civilisation a été de permettre la lecture sélective et non pas continue, contribuant ainsi à l’élaboration de structures mentales où le texte est dissocié de la parole et de son rythme. »
Au fil des siècles, le codex — qu'on désigne le plus souvent comme un manuscrit — va évoluer et se donner peu à peu les attributs du livre moderne : séparation entre les mots (VIIe siècle), début de ponctuation (VIIIe siècle), table des matières, titre courant, marque de paragraphe (XIe siècle), pagination, index (XIIIe siècle), etc.
Un point intéressant : le contenu de la Thora est « fixé » avant l'apparition du codex et, aujourd'hui encore, la Thora est écrite sur des /volumen/ (dans les synagogues au moins). La religion chrétienne se développe en même temps que le codex, adopte ce support et le répand ; elle ne donnera jamais au /volumen/ un statut « supérieur », pas plus que ne le fera la religion musulmane.
* Sur Eusèbe de Césarée
Pour en savoir plus sur [[https://fr.wikipedia.org/wiki/Eus%C3%A8be_de_C%C3%A9sar%C3%A9e][Eusèbe de Césarée]], consultez le passionnant deuxième chapitre du livre d'Anthony Grafton.
La notion de « références croisées » apparaît aussi dans un autre contexte que celui du « canon eusébien » lorsque l’œuvre d’Eusèbe de Césarée est discutée. Eusèbe de Césarée a en effet rédigé l’[[https://fr.wikipedia.org/wiki/Histoire_eccl%C3%A9siastique ][Histoire ecclésiastique]] (IVe siècle après J.-C.) et a employé un « recoupement de sources » (comparaison de textes de différents auteurs relatifs au même événement) pour étayer sa chronologie – voir l’article de Claire Muckenstum-Poulle « [[https://www.persee.fr/doc/dha_2108-1433_2010_sup_4_1_3347?q=Muckensturm-Poulle][Exégèse et Histoire sainte dans l’Histoire ecclésiastique d’Eusèbe de Césarée (Livre I)] », Dialogues d’histoire ancienne, 2010, Suppl. 4-1, pp. 141-153 – or il n’est pas le premier à avoir utilisé ce type de recoupements, qualifiés de « références croisées » par Claire Muckenstum-Poulle (voir les deux derniers paragraphes de la page 150) : l’historien [[https://fr.wikipedia.org/wiki/Flavius_Jos%C3%A8phe][Flavius Josèphe]] (Ier siècle après J.-C.) l’avait fait avant lui.
Par la suite, Ammonius d’Alexandrie (IIIe siècle après J.-C.) a inventé un procédé consistant à reproduire intégralement les textes des quatre évangiles dans quatre colonnes, en établissant des correspondances entre eux.
Au début du IVe siècle après J.-C., Eusèbe de Césarée reprend cette idée sous forme d’un tableau simplifié, ce qui constitue le canon eusébien. Il semble que ce tableau simplifié – dont le but est de permettre un recoupement aisé des quatre évangiles mais aurait pu être étendu à d’autres sources – soit le premier exemple de ce que nous qualifions aujourd’hui communément de « références croisées ». Je remercie M.-G. Dondon pour l’intéressante discussion à l’origine de ces clarifications et sa contribution à l’écriture des ces notes.
* Parallèle chinois
Comme je le dis, mon inculture fait que je ne rends pas justice aux contributions chinoises, musulmanes, précolombienne, etc. J'essaierai de combler cette énorme lacune pour les seconde version du CLOM...
Ce que je dis sur le passage du volumen au codex accompagné d'un développement des « outils de navigation » (index, table des matières, etc) en Chine lors du développement de leishus vient du bouquin d'Ann Blair (p. 31) qui cite un article de Susan Cherniack, « Book Culture and Textual Transmission in Sung China », /Harvard Journal of Asiatic Studies/ Vol. 54, No. 1 (Jun., 1994), pp. 5-125.
* Retour sur l'armoire à notes
Nous revenons sur le « bout de papier » ou la fiche comme support de note. L'inconvénient est que le bout de papier ou la fiche se perdent facilement et ne servent à rien s'ils ne sont pas *classés* en plus d'être rangés. Problème résolu par l'armoire de Placcius. D'une certaine façon, sa conception fait qu'on accède à son contenu par l'index.
L'avantage est que les notes peuvent être réorganisées si elles contiennent des information sur plusieurs sujets. Elle peuvent aussi être directement collées dans un livre lors de la composition d'un florilège ou d'un ouvrage de synthèse.
Ce dernier procédé était très couramment employé par les humanistes et les érudit de la renaissance et du début de la période moderne. [[https://fr.wikipedia.org/wiki/Conrad_Gessner][Conrad Gessner]] (1516-1565) était un champion de cette technique ; il obtenait même parfois ses fiches en découpant les pages des livres. Encore une fois, ne faites pas cela avec les livres de bibliothèques !
* L'index et John Locke
Sur l'origine de l'index, on pourra lire l'article de Jean Berger : [[https://www.theindexer.org/files/25-2-berger.pdf][Indexation, Memoire, pouvoir et representations au seuil du XIIe siecle : La redecouverte des feuillets de tables du Liber De Honoribus, premier cartulaire de la collegiale Saint-Julien de Brioude]], /The Indexer/.
La méthode de John Lock est expliquée dans l'article /Indexing commonplace books: John Locke’s method/ d'Alan Walker, [[https://www.theindexer.org/issues/query.php?vol=22&iss=3][The Indexer]], vol. 22, p. 114-118, 2001.
Une précision manque dans mes propos de la vidéo : la deuxième lettre (la voyelle) qui constitue l’entrée d’un mot clé dans l’index est la première voyelle qui suit la première lettre. Le mot clé « Analyse » trouverait donc sa place à la ligne « Aa » de l’index.
Sur [[https://fr.wikipedia.org/wiki/John_Locke][John Locke]] (1632-1704) « papa du libéralisme » et actionnaire de la /Royal African Company/ principale compagnie négrière britannique, voir l'article [[https://en.wikipedia.org/wiki/John_Locke#Constitution_of_Carolina][Wikipedia]] (en anglais) et le livre « Contre-histoire du libéralisme » de Domenico Losurdo (La Découverte / Poche, 2014, p. 34-36).
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: From text files to lightweight markup languages
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: en
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
* Table of contents :TOC:
- [[#text-files-and-text-editors][Text files and text editors]]
- [[#the-case-of-the-pdf-file-opened-with-a-text-editor][The case of the =PDF= file opened with a text editor]]
- [[#on-tinytex][On TinyTex]]
* Text files and text editors
A more technical as well as less circular (!) definition of a text file can be found on the dedicated [[https://en.wikipedia.org/wiki/Text_file][Wikipedia article]]. For more details on text editors you can also check the [[https://en.wikipedia.org/wiki/Text_editor][corresponding Wikipedia page]].
A [[https://en.wikipedia.org/wiki/Word_processor][word processor]] software is more sophisticated than a simple text editor; it can do more and can therefore also open and work with text files. When we write "do more" we mean here work on the final layout of the document. Some text editors like [[https://en.wikipedia.org/wiki/Emacs][Emacs]] or [[https://en.wikipedia.org/wiki/Vim_(text_editor)][Vim]] provide programming aid, interaction with some of the other software installed on the machine (/e.g./ =Python, =R=), etc. giving them a quasi "Swiss army knife" status; their users can spend days or weeks without having to use a word processor (some even never use a word processor).
*Be careful*: the native format of the files generated by word processors is rarely a text format. =doc=, =docx= and =odt= files /are not text files/.
* The case of the =PDF= file opened with a text editor
In the sequence a [[https://en.wikipedia.org/wiki/Portable_Document_Format][PDF]] file opened with a text editor is shown in order to demonstrate that such a file cannot not be properly visualized with this kind of software, a "PDF specific" software is required such as =Adobe Reader=, =Evince=, =MuPDF=, =Aperçu=,... You can nevertheless see that the beginning of the file contains readable characters (readable by a text editor), the first line tells us that the file uses version 1.3 of the =PDF= format. This early part in text format contains metadata that are not shown by a visualization software like =Adobe Reader=. These metadata follow (partly) the [[https://en.wikipedia.org/wiki/Extensible_Metadata_Platform][XMP]] (/Extensible Metadata Platform/) format; we will come back to it in the fifth sequence of this module.
* On UTF-8
A table of UTF-8 symbols can be found at: [[http://www.utf8-chartable.de/]]. It is handy to insert uncommon symbols like the "TLO": Ꮰ of Cherokee, or the mathematical symbol ∀, "for all".
If you are often using Greek letters (for equations for instance),it is possible with Linux to redefine some keys combinations to generate quickly these letters. These key combinations are defined in the =.XCompose= file; the beginning of my =.XCompose= file contains:
#+BEGIN_EXAMPLE
# On charge la base de donnée de Compose la plus complète en UTF-8
include "/usr/share/X11/locale/en_US.UTF-8/Compose"
# espace insécable fine
<Multi_key> <Multi_key> <Space> : " " U202F
# Lettres greques
<Multi_key> <space> <a> : "α" Greek_alpha
<Multi_key> <space> <A> : "Α" Greek_ALPHA
<Multi_key> <space> <b> : "β" Greek_beta
<Multi_key> <space> <B> : "Β" Greek_BETA
<Multi_key> <space> <g> : "γ" Greek_gamma
<Multi_key> <space> <G> : "Γ" Greek_GAMMA
<Multi_key> <space> <d> : "δ" Greek_delta
<Multi_key> <space> <D> : "Δ" Greek_DELTA
<Multi_key> <space> <e> : "ε" Greek_epsilon
<Multi_key> <space> <E> : "Ε" Greek_EPSILON
<Multi_key> <space> <z> : "ζ" Greek_zeta
<Multi_key> <space> <Z> : "Ζ" Greek_ZETA
<Multi_key> <space> <h> : "η" Greek_eta
#+END_EXAMPLE
* On TinyTex
Yihui Xie, author of the great "bookdown" =R= package, has developed a "light LaTeX" version: TinyTex ("[[https://yihui.name/tinytex/][A lightweight, cross-platform, portable, and easy-to-maintain LaTeX distribution based on TeX Live]]").
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Du fichier texte au langage de balisage
#+DATE: <2019-02-21 jeu.>
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: fr
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
* Table des matières :TOC:
- [[#fichier-texte-et-éditeur-de-texte][Fichier texte et éditeur de texte]]
- [[#le-cas-du-fichier-pdf-ouvert-avec-un-éditeur-de-texte][Le cas du fichier =PDF= ouvert avec un éditeur de texte]]
- [[#sur-lutf-8][Sur l'UTF-8]]
* Fichier texte et éditeur de texte
Une définition plus technique (et moins circulaire !) du fichier texte se trouve sur [[https://fr.wikipedia.org/wiki/Fichier_texte][la page wikipédia]] consacrée au sujet. Pour plus de détails sur les éditeurs de texte, voir aussi la [[https://fr.wikipedia.org/wiki/%C3%89diteur_de_texte][page wikipédia correspondante]].
Un logiciel de « [[https://fr.wikipedia.org/wiki/Traitement_de_texte][traitement de texte]] » est plus sophistiqué qu'un simple éditeur de texte ; il permet de faire plus, ce qui sous entend qu'il peut aussi ouvrir et manipuler des fichiers textes. Par « faire plus », nous entendons ici travailler sur la mise en page du document final. Mais certains éditeurs de texte comme [[https://fr.wikipedia.org/wiki/Emacs][Emacs]] ou [[https://fr.wikipedia.org/wiki/Vim][Vim]] proposent des fonctionnalités – aide à la programmation, interaction avec les autres logiciels installés sur la machine, etc. – qui font de ces outils de véritables « couteaux suisses » et qui permettent de passer des journées et des semaines sans avoir besoin d’un traitement de texte.
*Attention* : le format « natif » des traitements de texte est rarement un format texte. Les fichiers =doc= et =docx= de =Word= et =odt= de =LibreOffice= /ne sont pas des fichiers textes/.
* Le cas du fichier =PDF= ouvert avec un éditeur de texte
Dans le cours filmé, j'utilise l'exemple du [[https://en.wikipedia.org/wiki/Portable_Document_Format][PDF]] — je donne l'adresse de la page wikipedia en anglais, bien plus complète que celle en français — ouvert avec un éditeur de texte pour montrer que le fichier ne peut pas être visualisé avec un tel logiciel, il faut un logiciel de rendu dédié comme =Adobe Reader=, =Evince=, =MuPDF=, =Aperçu=,... Vous remarquez néanmoins que le début du fichier contient du texte (la première ligne nous apprend que le fichier utilise la version 1.3 du format =PDF=). Cette partie au format texte du fichier contient les méta-données — qui ne sont pas montrées, en tout cas pas directement, par les logiciels de rendu. Ces méta-données sont (en partie) au format [[https://en.wikipedia.org/wiki/Extensible_Metadata_Platform][XMP]] (/Extensible Metadata Platform/), nous y reviendrons dans la cinquème séquence.
* Sur l'UTF-8
Une table des symboles UTF-8, avec leur code se trouve à l'adresse : [[http://www.utf8-chartable.de/]]. C'est pratique pour insérer un symbole pas très courant comme la lettre « TLO » : Ꮰ de la langue cherokee, ou le symbole mathématique ∀, « pour tout ».
Pour ceux qui doivent souvent utiliser des lettres grecs (par exemple pour écrire des équations), il est possible sous Linux de (re)définir des combinaisons de touches pour générer directement les dites lettres. Ces combinaisons sont définies dans le fichier =.XCompose=, le début de mon fichier contient :
#+BEGIN_EXAMPLE
# On charge la base de donnée de Compose la plus complète en UTF-8
include "/usr/share/X11/locale/en_US.UTF-8/Compose"
# espace insécable fine
<Multi_key> <Multi_key> <Space> : " " U202F
# Lettres greques
<Multi_key> <space> <a> : "α" Greek_alpha
<Multi_key> <space> <A> : "Α" Greek_ALPHA
<Multi_key> <space> <b> : "β" Greek_beta
<Multi_key> <space> <B> : "Β" Greek_BETA
<Multi_key> <space> <g> : "γ" Greek_gamma
<Multi_key> <space> <G> : "Γ" Greek_GAMMA
<Multi_key> <space> <d> : "δ" Greek_delta
<Multi_key> <space> <D> : "Δ" Greek_DELTA
<Multi_key> <space> <e> : "ε" Greek_epsilon
<Multi_key> <space> <E> : "Ε" Greek_EPSILON
<Multi_key> <space> <z> : "ζ" Greek_zeta
<Multi_key> <space> <Z> : "Ζ" Greek_ZETA
<Multi_key> <space> <h> : "η" Greek_eta
#+END_EXAMPLE
J'ai en plus redéfini la « <Multi_key> » pour qu'elle corresponde à la touche « impression d'écran » de mon clavier. Pour apprendre à redéfinir des touches, consultez : [[https://wiki.archlinux.org/index.php/Keyboard_configuration_in_Xorg#Configuring_compose_key]].
* À propos de TinyTex
Yihui Xie, auteur du remarquable package R "bookdown", a mis au point une version allégée de LaTeX, TinyTex ("[[https://yihui.name/tinytex/][A lightweight, cross-platform, portable, and easy-to-maintain LaTeX distribution based on TeX Live]]").
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Notes (and codes) that are archived but can evolve with version control systems
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: en
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
* Table of contents :TOC:
- [[#version-control-with-gitlab-and-git-in-the-Reproducible-research-mooc][Version control with GitLab and Git]]
- [[#version-control-with-libreoffice-or-dokuwiki][Version control with LibreOffice or DokuWiki]]
* Version control with GitLab and Git in the "Reproducible research" MOOC
We have created a GitLab server especially for this MOOC so that you can smoothly learn how to implement version control.
This section describes the successive steps involved. The following [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5571950188c946e790f06d4bc90fb5f6#InterfaceGitlab][video]] shows how to use GitLab. We strongly recommend that you watch it if you've never used GitLab before.
- Go to [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5571950188c946e790f06d4bc90fb5f6#FormAccesGitlab][GitLab]] from the FUN platform (click on *Accédez à
Gitlab / Access to Gitlab*)
- You reach the following form :
#+BEGIN_CENTER
[[file:gitlab_images/sign_in.png]]
#+END_CENTER
- NB : You must reach GitLab from the FUN platform. You are likely to get a "405 error" if you are using the following address: https://app-learninglab.inria.fr/gitlab/users/sign_in.
#+BEGIN_CENTER
[[file:gitlab_images/erreur405.png]]
#+END_CENTER
- Click on **Sign in**. Authentication is automatic at that stage.
#+BEGIN_CENTER
[[file:gitlab_images/projects.png]]
#+END_CENTER
The long string replaced here by =xxx= is the login you will have to use in Git to synchronize with GitLab.
- To recover a predefined password you must use [[https://app-learninglab.inria.fr/jupyterhub/services/password][Gitlab
credentials retrieval tool]]. One gets then the login and password.
#+BEGIN_CENTER
[[file:gitlab_images/password_retrieval.png]]
#+END_CENTER
- You can change this password in "Account /
Paramètres / Mot de passe". We do not recommend doing it since that will block you from using the Jupyter notebooks of this MOOC.
#+BEGIN_CENTER
[[file:gitlab_images/password.png]]
#+END_CENTER
If you want to go further, few tutorial videos are gathered in [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][sequence "7. Installations, configurations, references" of module 2]]
of this MOOC.
* Version control with LibreOffice or DokuWiki
Modification tracking in files generated and managed by =LibreOffice= is briefly described on the [[https://help.libreoffice.org/Common/Recording_Changes][wiki page]] of this software. A [[https://help.libreoffice.org/Common/Navigating_Changes][table of contents]] of the pages dedicated to this subject is available.
For DoKuWiki, the best is to check the [[https://www.dokuwiki.org/start?id=dokuwiki][wiki]].
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Pérénité et évolutivité avec la gestion de version
#+DATE: <2019-03-26 mar.>
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: fr
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
* Table des matières :TOC:
- [[#gestion-de-version-avec-gitlab-et-git-dans-le-mooc-recherche-reproductible][Gestion de version avec GitLab et Git dans le MOOC "Recherche reproductible"]]
- [[#gestion-de-version-dans-libreoffice-ou-dans-dokuwiki][Gestion de version dans LibreOffice ou dans DokuWiki]]
* Gestion de version avec GitLab et Git dans le MOOC "Recherche reproductible"
Nous avons déployé un GitLab spécialement pour ce MOOC afin que vous
puissiez vous familiariser en douceur avec la gestion de
version. Cette section décrit étape par étape comment y accéder. [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5571950188c946e790f06d4bc90fb5f6#InterfaceGitlab][Cette
vidéo]] illustre ces étapes ainsi que comment utiliser GitLab. Nous vous
incitons vivement à la regarder si vous n'êtes pas familiers avec ce
type d'environnement.
- Accéder à [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5571950188c946e790f06d4bc90fb5f6#FormAccesGitlab][GitLab]] depuis la plateforme FUN (cliquez sur *Accédez à
Gitlab / Access to Gitlab*)
- Vous arrivez sur le formulaire suivant :
#+BEGIN_CENTER
[[file:gitlab_images/sign_in.png]]
#+END_CENTER
- NB : Il faut accéder à Gitlab depuis la plateforme FUN. Vous risquez
d'obtenir une erreur 405 en accédant directement à la page https://app-learninglab.inria.fr/gitlab/users/sign_in.
#+BEGIN_CENTER
[[file:gitlab_images/erreur405.png]]
#+END_CENTER
- Cliquer sur le premier **Sign in**. L'authentification est automatique à cette étape.
#+BEGIN_CENTER
[[file:gitlab_images/projects.png]]
#+END_CENTER
La grande chaîne de caractères remplacée ici par =xxx= est le login qu'il faudra utiliser dans Git pour accéder à Gitlab.
- Pour récupérer le mot de passe prédéfini, il faut utiliser le [[https://app-learninglab.inria.fr/jupyterhub/services/password][Gitlab
credentials retrieval tool]]. On retrouve alors le login et le mot de
passe.
#+BEGIN_CENTER
[[file:gitlab_images/password_retrieval.png]]
#+END_CENTER
- Il est possible de modifier ce mot de passe dans "Account /
Paramètres / Mot de passe". Mais nous vous déconseillons de le faire
car cela vous empêchera d'utiliser les notebook Jupyter du MOOC.
#+BEGIN_CENTER
[[file:gitlab_images/password.png]]
#+END_CENTER
Enfin, pour ceux qui veulent aller plus plus loin et en savoir plus
sur l'outil de gestion de version git sur lequel s'appuie GitLab,
quelques vidéos de démonstration sur git et Gitlab sont proposées dans
la [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][séquence "7. Installations, configurations, references" du module 2]]
de ce Mooc ainsi que des ressources pour apprivoiser git en ligne de commandes.
* Gestion de version dans LibreOffice ou dans DokuWiki
L'enregistrement des modifications des fichiers générés et gérés par =LibreOffice= est succinctement décrite sur la [[https://help.libreoffice.org/Common/Recording_Changes/fr][page du Wiki]] de ce logiciel. Une espèce de [[https://help.libreoffice.org/Common/Navigating_Changes/fr][sommaire]] des pages concernant la gestion des modifications est également disponible. Le livre [[https://framabook.org/libreoffice-cest-style/][LibreOffice, c’est stylé !]] téléchargeable gratuitement (et légalement) ne semble pas aborder la question. Sa version source est disponible sur [[https://framagit.org/Framatophe/DWL/][framagit]]= (un autre serveur type GitLab) et est écrite en… =markdown= !
Pour DokuWiki, le plus simple est de consulter le [[https://www.dokuwiki.org/fr:dokuwiki][Wiki]] écrit, cette fois au moins !, en DokuWiki.
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Finding one's way with tags and desktop search application
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: en
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
* Table of contents :TOC:
- [[#leibniz-quote][Leibniz quote]]
- [[#searching-with-a-text-editor][Searching with a text editor]]
- [[#search-with-a-hand-made-index-in-a-notebook][Search with a hand-made index in a notebook]]
- [[#search-with-a-materialized-index][Search with a "materialized" index]]
- [[#towards-the-sophisticated-tools-of-computers][Towards the "sophisticated" tools of computers]]
- [[#desktop-search-engines][Desktop search engines]]
- [[#why-labels-tags?][Why labels/tags?]]
- [[#metadata][Metadata]]
- [[#image-files][Image files]]
- [[#pdf-files][=PDF= files]]
- [[#audios-files][Audios files]]
* Leibniz quote
I found the introductory quote on the [[http://www.backwordsindexing.com/index.html]] website.
Leibniz was a librarian for a fair part of his life, this partly explains is concern for classification, indexation, etc.
* Searching with a text editor
The corresponding slide is here to remind its viewer something already known and that is perceived as a huge improvement by people switching from paper to numerical note taking.
Unix/Linux users also know the [[https://en.wikipedia.org/wiki/Grep][grep]] command-line utility for searching plain-text data sets for lines that match a [[https://en.wikipedia.org/wiki/Regular_expression][regular expression]] in one or several files; we will come back to it.
* Search with a hand-made index in a notebook
Again something we already discussed (in sequence 2).
* Search with a "materialized" index
A reminder.
* Towards the "sophisticated" tools of computers
- The techniques we have just seen or reviewed only work for one "document" - search with the text editor, index of a notebook - and/or for one type of document.
- The computer tools at our disposal allow us to go further in the indexing of digital files.
- It is possible to add labels or keywords to text files as well as to image files (`jpg`, `png`) or "mixed" files (`pdf`) thanks to the metadata they contain.
- Desktop search engines make it possible to index all the text files in a given tree structure but also the metadata of the other files.
* Desktop search engines
Desktop search engines like:
- [[http://docfetcher.sourceforge.net/en/index.html][DocFetcher]] (Linux, MacOS, Windows) ;
- [[https://wiki.gnome.org/Projects/Tracker][Tracker]] (Linux) ;
- [[https://www.lesbonscomptes.com/recoll/][Recoll]] (Linux, MacOS, Windows) ;
- [[https://en.wikipedia.org/wiki/Spotlight_(software)][Spotlight]] (MacOS) ;
allow us to search for the /content/ of text files, emails, files generated by =word processors=--/i.e./ files that essentially contain text, but are stored in a standard format =doc=, =docx=, =odt=, etc. that are not text formats--, =pdf= files--when they are not /images/ of text--, but also the [[https://en.wikipedia.org/wiki/Portable_Document_Format#Metadata][metadata]] of =pdf=, etc.
Desktop search engines use [[https://fr.wikipedia.org/wiki/Indexation_automatic_documents][indexing]] techniques that significantly reduce search times, compared to the search functions built into operating systems by default. Unlike the latter, they also often support [[https://fr.wikipedia.org/wiki/M%C3%A9A9tadonn%C3%A9e][metadata]], and are able to make a [[https://fr.wikipedia.org/wiki/Analyse_syntactic][parsing]] of the files.
As an example of "integrated default search functions", we will find on Unix/Linux systems the program [[https://fr.wikipedia.org/wiki/Grep][grep]] with which we can search for occurrences of the word "Placcius" in the "module1/resources" directory of our repository [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources][mooc-rr-ressources]] (after cloning it):
#+NAME: grep-Placcius-module1/ressources
#+BEGIN_SRC sh :results output :exports both
grep -r Placcius
#+END_SRC
#+RESULTS: grep-Placcius-module1/ressources
#+begin_example
sequence1.org:- [[#note-cabinets-from-placcius-and-leibniz][Note cabinets from Placcius and Leibniz]]
sequence1.org:* Note cabinets from Placcius and Leibniz
sequence2_fr.org:Nous revenons sur le « bout de papier » ou la fiche comme support de note. L'inconvénient est que le bout de papier ou la fiche se perdent facilement et ne servent à rien s'ils ne sont pas *classés* en plus d'être rangés. Problème résolu par l'armoire de Placcius. D'une certaine façon, sa conception fait qu'on accède à son contenu par l'index.
sequence2.org:We see (again) Placcius' and Leibniz's closet since it displays both the benefits and the shortcomings of media that hold *a single note*.
sequence2.org:These problems are solved by Placcius' cabinet, the content of which is fundamentally accessed through the index.
sequence5_fr.org:- les notes manuscrites sur fiches sont généralement stockées dans un meuble dont la structure matérialise un index — comme l'armoire de Placcius et Leibniz — ;
sequence5_fr.org:: PITCHME.md:Remarquez l'avantage des « bouts de papiers classés » de Placcius et Leibniz sur le _codex_ de Galilée : les premiers peuvent être facilement réordonnées.
sequence1_fr.org:- [[#armoires-à-notes-de-placcius-et-leibniz][Armoires à notes de Placcius et Leibniz]]
sequence1_fr.org:* Armoires à notes de Placcius et Leibniz
#sequence5_fr.org#:- les notes manuscrites sur fiches sont généralement stockées dans un meuble dont la structure matérialise un index — comme l'armoire de Placcius et Leibniz — ;
#sequence5_fr.org#:module1/ressources/sequence5_fr.org:: PITCHME.md:Remarquez l'avantage des « bouts de papiers classés » de Placcius et Leibniz sur le _codex_ de Galilée : les premiers peuvent être facilement réordonnées.
#sequence5_fr.org#:module1/slides/misc/Notes_module1.org:: PITCHME.md:Remarquez l'avantage des « bouts de papiers classés » de Placcius et Leibniz sur le _codex_ de Galilée : les premiers peuvent être facilement réordonnées.
#sequence5_fr.org#:module1/slides/misc/PITCHME.md:Remarquez l'avantage des « bouts de papiers classés » de Placcius et Leibniz sur le _codex_ de Galilée : les premiers peuvent être facilement réordonnées.
#+end_example
* Why labels/tags?
A query based on a single word often returns a very large number of proposals, even though most desktop search engines allow you to filter them. An effective way to limit their number is to include in our documents labels, i.e. labelled anchor points, which will be easily indexed by the desktop search engine and whose label does not correspond to any word or phrase in the dictionary--this is a simplified version of the work of the /indexer/, the person responsible for building a book index--. To keep the label meaningful, simply frame a word with a pair of punctuation marks such as ":", "";" or "?". A label such as ":code:" will be easily memorized and will make a perfect equivalent of the keyword "code" used in the example notebook in the second sequence of this module--to illustrate Locke's method--.
We still have one more technical detail to resolve in the case of our notes taken in text format such as =Markdown=. Indeed, we do not want our labels to appear in the =html=, =pdf= or =docx= outputs of our notes. A way to do this, for light markup languages that do not have labels--for example, =Markdown= does not have them, while =org= has them--is to include them in comments. In =Markdown=, everything framed by =<!--= and =-->= is considered a comment and is not included in the =html= or =pdf= output of the notes. This allows us to use:
#+BEGIN_EXAMPLE
<!-- ;code; -->
#+END_EXAMPLE
in our notes at a location we would like to find when we are looking for material on programming.
* Metadata
** Image files
We now know how to add labels to a text file, but we often also have to work with files containing images or photos, such as [[https://fr.wikipedia.org/wiki/JPEG][JPEG]] files--digital cameras all use this format--, [[https://en.wikipedia.org/wiki/Graphics_Interchange_Format][GIF]] or [[https://en.wikipedia.org/wiki/Portable_Network_Graphics][PNG]]. The question then arises, can we add labels to our image files so that our desktop search engines index them? The answer is yes, thanks to the [[https://fr.wikipedia.org/wiki/M%C3%A9tadonn%C3%A9e][metadata]] that these files contain. Metadata, in this case, is data stored in the file but not shown by the rendering software (at least not shown by default). We all know that this metadata "exists"; it contains the date, GPS location, exposure time, etc. of our digital photos. In the =JPEG= files, they are stored according to the the [[https://fr.wikipedia.org/wiki/Exchangeable_image_file_format][exchangeable image file format]] (=EXIF=). Most image and photo manipulation software allows access to and modification of metadata content. The example illustrated in the course uses a very simple "command line" solution, [[http://owl.phy.queensu.ca/~phil/exiftool/][ExifTool]] that allows you to view and modify metadata. Other software such as [[http://www.exiv2.org/index.html][exiv2]] or [[https://imagemagick.org/script/index.php][ImageMagick]] allow you to do this (to name only free software available on Linux, Windows and MacOS). Some of the elements of the =EXIF= format are strings, i.e. text, that we are free to use as we wish; we can therefore use them to add our labels. We illustrate in the course how to do it with =ExifTool=, but we could also have done it with ImageMagick's program [[https://www.imagemagick.org/script/command-line-options.php#comment][mogrify]]. All the desktop search engines we mentioned will "look" at the metadata of the =JPEG= files during the indexing phase and thus allow us to use the labels we have inserted.
=EXIF= is not the only existing metadata format; a more recent format is the [[https://fr.wikipedia.org/wiki/Extensible_Metadata_Platform][Extensible Metadata Platform ]](=XMP=), available for a larger number of file formats--it is not currently read on =JPEG= files by =DocFetcher=, so we have highlighted the =EXIF= format, but this should evolve quite quickly--; other engines like =Tracker= and =Recoll= read it.
** =PDF= files
In addition to image files, we are all very frequently called upon to work with "composite" files--containing text, images, and more--that are the [[https://fr.wikipedia.org/wiki/Portable_Document_Format][PDF]] files. These files also contain metadata, and it was for them that Adobe initially introduced the =XMP= format that we just discussed. This metadata can be read and modified, in particular the element =Keywords= which can contain arbitrary long character strings and is perfect for hosting our labels. The program =ExifTool=, allows you to modify the metadata of the files =PDF=. The desktop search engines we mentioned above will all read the metadata from the =PDF= files during the indexing phase.
** Audios files
Audio formats like [[https://en.wikipedia.org/wiki/MP3][mp3]] and [[https://en.wikipedia.org/wiki/Ogg][ogg]] also contain metadata where the song titles, artist names, etc. are stored; these metadata can be set by us and are read by the desktop search engines during indexation.
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Les étiquettes et les logiciels d'indexation pour s'y retrouver
#+DATE: <2019-02-21 jeu.>
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: fr
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
* Table des matières :TOC:
- [[#la-structure-de-la-séquence][La structure de la séquence]]
- [[#la-citation-de-leibniz][La citation de Leibniz]]
- [[#rechercher-avec-un-éditeur-de-texte][Rechercher avec un éditeur de texte]]
- [[#recherche-avec-index-construit-à-la-main-sur-des-cahiers-de-notes][Recherche avec index construit « à la main » sur des cahiers de notes]]
- [[#recherche-avec-index-matérialisés][Recherche avec index « matérialisés »]]
- [[#vers-les-outils-sophistiqués-de-linformatique][Vers les outils « sophistiqués » de l'informatique]]
- [[#les-moteurs-de-recherche-de-bureau][Les moteurs de recherche de bureau]]
- [[#pourquoi-des-étiquettes][Pourquoi des étiquettes]]
- [[#les-métadonnées][Les métadonnées]]
- [[#fichiers-images][Fichiers images]]
- [[#fichiers-pdf][Fichiers =PDF=]]
- [[#fichiers-audios][Fichiers audios]]
* La structure de la séquence
Nous revenons ici sur le problème de l'indexation, pas tant sur l'indexation d'un document unique que sur l'indexation de documents multiples dans des formats divers :
- comme nous l'avons déjà affirmé, prendre des notes abondantes et détaillées n'est utile que si nous pouvons retrouver les informations qu'elles contiennent quand nous en avons besoin ;
- pour des notes contenues dans un seul fichier texte, la fonction de recherche de notre éditeur favori nous permet généralement d'aller assez loin ;
- pour des notes manuscrites contenues dans un cahier, la méthode de Locke — que nous avons exposée dans notre deuxième séquence — et qui repose sur des mots clé ou étiquettes, donne de bons résultats ;
- les notes manuscrites sur fiches sont généralement stockées dans un meuble dont la structure matérialise un index — comme l'armoire de Placcius et Leibniz — ;
- mais nous voulons ici aller plus loin, dans le cadre restreint des « notes » numérisées, en discutant de l'indexation de fichiers multiples qu'ils soient au format « texte » où dans d'autres format comme les images =jpg= où les fichier =pdf= ;
- cela nous amménera à introduire les « moteurs de recherche de bureau » et à expliquer comment des =étiquettes= ou =mots-clés= peuvent être ajoutés à nos fichiers.
* La citation de Leibniz
J'ai trouvé la citation introductive :
« Il me semble que l'apparat savant contemporain est comparable à un grand magasin qui contient une grande quantité de produits, stockés de façon totalement désordonnée, mélangée ; où les nombres ou lettres d'indexation manquent ; où les inventaires et livres de comptes pouvant aider à ordonner le contenu ont disparus.
Plus grande est la quantité d'objets amassés, plus petite est leur utilité. Ainsi, ne devrions nous pas seulement essayer de rassembler de nouveaux objets de toutes provenances, mais nous devrions aussi essayer d'ordonner ceux que nous avons déjà. »
sur le site [[http://www.backwordsindexing.com/index.html]], c'est donc une traduction de traduction. J'emploie ici le terme volontairement anachronique d'« [[https://fr.wikipedia.org/wiki/Apparat_savant][apparat savant]] » qui est un terme technique de l'édition désignant : citations, références et sources, notes en bas de pages, introduction, texte en langue originale (en parallèle avec la traduction), commentaire historique ou philologique, index fontium (les sources), index locorum (références avec renvoi à la page où le passage est cité ou mentionné, par ex. : Évangile selon Marc 1, 1 : p. 100), index nominum (les noms propres), index rerum (les thèmes), etc. La référence au « grand magasin » est, elle aussi anachronique !
Leibniz a, pendant une bonne partie de sa vie, « gagné celle-ci » comme [[https://www.reseau-canope.fr/savoirscdi/societe-de-linformation/le-monde-du-livre-et-des-medias/histoire-du-livre-et-de-la-documentation/biographies/leibniz-le-bibliothecaire.html][bibliothécaire]], ce qui explique en partie sont intérêt très poussé pour les questions de classifications, d'indexations, etc.
* Rechercher avec un éditeur de texte
La diapo correspondante rappelle juste au lecteur quelque chose qu'il sait déjà et qui est vue, par les gens qui passent des notes « papier » aux notes « numériques », comme le gros attrait du numérique.
Les gens de monde Unix/Linux connaissent aussi généralement le programme [[https://fr.wikipedia.org/wiki/Grep][grep]] qui permet de faire des recherches de mots et, plus généralement d'[[https://fr.wikipedia.org/wiki/Expression_r%C3%A9guli%C3%A8re][expressions régulières]], sur un ou /plusieurs/ fichiers ; nous y reviendrons.
* Recherche avec index construit « à la main » sur des cahiers de notes
Là encore, il s'agit juste d'un rappel pour les lecteurs assidus de ce cours ; à ce stade se sont des experts dans la méthode d'indexation de Locke.
* Recherche avec index « matérialisés »
Encore un rappel pour les lecteurs.
* Vers les outils « sophistiqués » de l'informatique
- les techniques que nous venons de voir ou revoir ne fonctionnent que pour un seul « document » — recherche avec l'éditeur de texte, index d'un cahier — et/ou pour un seul type de document ;
- les outils informatiques dont nous disposons nous permettent d'aller plus loin dans l'indexation des fichiers numériques ;
- il est possible de rajouter des étiquettes ou mots-clés à des fichiers textes comme à des fichiers images (`jpg`, `png`) ou des fichiers « mixtes » (`pdf`) grâce aux métadonnées qu'ils contiennent ;
- les moteurs de recherche de bureau permettent d'indexer l'ensemble des fichiers textes d'une arborescence donnée mais aussi les métadonnées des autres fichiers.
* Les moteurs de recherche de bureau
Les moteurs de recherche de bureau comme :
- [[http://docfetcher.sourceforge.net/fr/index.html][DocFetcher]] (Linux, MacOS, Windows) ;
- [[https://wiki.gnome.org/Projects/Tracker][Tracker]] (Linux) ;
- [[https://www.lesbonscomptes.com/recoll/index.html.fr][Recoll]] (Linux, MacOS, Windows) ;
- [[https://fr.wikipedia.org/wiki/Spotlight_(moteur_de_recherche)][Spotlight]] (MacOS) ;
permettent de rechercher le /contenu/ des fichiers textes, des courriels, des fichiers générés par les =traitements de texte= — c'est-à-dire des fichiers qui contiennent essentiellement du texte, mais qui sont stockés dans un format type =doc=, =docx=, =odt=, etc qui ne sont pas des formats texte —, des fichiers =pdf= — quand ceux-ci ne sont pas des /images/ de textes —, mais aussi des [[https://en.wikipedia.org/wiki/Portable_Document_Format#Metadata][métadonnées]] des fichiers =pdf=, etc.
Les moteurs de recherche de bureau « utilisent des techniques d'[[https://fr.wikipedia.org/wiki/Indexation_automatique_de_documents][indexation]] qui permettent de réduire considérablement les temps de recherche, par rapport aux fonctions de recherche intégrées par défaut aux systèmes d'exploitation. Au contraire de ces derniers, ils prennent aussi souvent en charge les [[https://fr.wikipedia.org/wiki/M%C3%A9tadonn%C3%A9e][métadonnées]], et sont capables de faire une [[https://fr.wikipedia.org/wiki/Analyse_syntaxique][analyse syntaxique]] des fichiers. » (Source : [[https://fr.wikipedia.org/wiki/Moteur_de_recherche_de_bureau][Moteur de recherche de bureau]] sur Wikipédia)
Comme exemple de « fonctions de recherche intégrées par défaut », on trouvera sur les systèmes Unix/Linux le programme [[https://fr.wikipedia.org/wiki/Grep][grep ]]avec lequel nous pouvons chercher les occurrences du mot « Placcius » dans le répertoire « module1/ressources » de notre dépôt [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources][mooc-rr-ressources]] (après l'avoir cloné) :
#+NAME: grep-Placcius-module1/ressources
#+BEGIN_SRC sh :results output :exports both
grep -r Placcius
#+END_SRC
#+RESULTS: grep-Placcius-module1/ressources
#+begin_example
sequence1.org:- [[#note-cabinets-from-placcius-and-leibniz][Note cabinets from Placcius and Leibniz]]
sequence1.org:* Note cabinets from Placcius and Leibniz
sequence2_fr.org:Nous revenons sur le « bout de papier » ou la fiche comme support de note. L'inconvénient est que le bout de papier ou la fiche se perdent facilement et ne servent à rien s'ils ne sont pas *classés* en plus d'être rangés. Problème résolu par l'armoire de Placcius. D'une certaine façon, sa conception fait qu'on accède à son contenu par l'index.
sequence2.org:We see (again) Placcius' and Leibniz's closet since it displays both the benefits and the shortcomings of media that hold *a single note*.
sequence2.org:These problems are solved by Placcius' cabinet, the content of which is fundamentally accessed through the index.
sequence5_fr.org:- les notes manuscrites sur fiches sont généralement stockées dans un meuble dont la structure matérialise un index — comme l'armoire de Placcius et Leibniz — ;
sequence5_fr.org:: PITCHME.md:Remarquez l'avantage des « bouts de papiers classés » de Placcius et Leibniz sur le _codex_ de Galilée : les premiers peuvent être facilement réordonnées.
sequence1_fr.org:- [[#armoires-à-notes-de-placcius-et-leibniz][Armoires à notes de Placcius et Leibniz]]
sequence1_fr.org:* Armoires à notes de Placcius et Leibniz
#sequence5_fr.org#:- les notes manuscrites sur fiches sont généralement stockées dans un meuble dont la structure matérialise un index — comme l'armoire de Placcius et Leibniz — ;
#sequence5_fr.org#:module1/ressources/sequence5_fr.org:: PITCHME.md:Remarquez l'avantage des « bouts de papiers classés » de Placcius et Leibniz sur le _codex_ de Galilée : les premiers peuvent être facilement réordonnées.
#sequence5_fr.org#:module1/slides/misc/Notes_module1.org:: PITCHME.md:Remarquez l'avantage des « bouts de papiers classés » de Placcius et Leibniz sur le _codex_ de Galilée : les premiers peuvent être facilement réordonnées.
#sequence5_fr.org#:module1/slides/misc/PITCHME.md:Remarquez l'avantage des « bouts de papiers classés » de Placcius et Leibniz sur le _codex_ de Galilée : les premiers peuvent être facilement réordonnées.
#+end_example
Une version plus sophistiquée de =grep= est fournie par le programme [[http://uzix.org/cgvg.html][cgvg]].
* Pourquoi des étiquettes
Une requête basée sur un simple mot renvoie souvent un très grand nombre de propositions, même si la plupart des moteurs de recherche de bureau permettent de filtrer ces dernières. Une façon efficace de limiter leur nombre est d'inclure dans nos documents des étiquettes, c'est-à-dire des points d'ancrage labelisés, qui seront aisément indexés par le moteur de recherche de bureau et dont le label ne correspond à aucun mot ou locution du dictionnaire — nous effectuons ainsi une version simplifiée du travail de l'/indexeur/, la personne chargée de construire l'index d'un livre. Pour que l'étiquette garde un sens, il suffit d'encadrer un mot par une paire de signes de ponctuation comme « : », « ; » ou « ? ». Un label comme « :code: » sera facilement mémorisé et fera un parfait équivalent du mot-clé « code » utilisé dans l'exemple du cahier de note de la deuxième séquence de ce module — pour illustrer la méthode de Locke.
Il nous reste encore nous reste encore un détail technique à régler dans le cas de nos notes prises en format texte comme =Markdown=. En effet, nous ne souhaitons pas que nos étiquettes apparaissent dans les sorties =html=, =pdf= ou =docx= de nos notes. Un façon de procéder, pour les langages de balisage légers qui ne disposent pas d'étiquettes — par exemple, =Markdown= n'en dispose pas, alors que =org= en a — et de les inclure dans des commentaires. En =Markdown=, tout ce qui est encadré par =<!--= et =-->= est considéré comme un commentaire et ne figure pas dans les sorties =html= ou =pdf= des notes. Nous pouvons ainsi utiliser :
#+BEGIN_EXAMPLE
<!-- ;code; -->
#+END_EXAMPLE
à l'endroit de nos notes où nous souhaitons aller rapidement lorsque que nous cherchons une information relative à de la programmation (production de codes).
* Les métadonnées
** Fichiers images
Nous savons à présent comment rajouter des étiquettes à un fichier au format texte, mais nous devons souvent aussi travailler avec des fichiers contenant des images ou des photos, comme les fichiers [[https://fr.wikipedia.org/wiki/JPEG][JPEG]] — les appareils photos numériques utilisent tous ce format —, [[https://fr.wikipedia.org/wiki/Graphics_Interchange_Format][GIF]] ou [[https://fr.wikipedia.org/wiki/Portable_Network_Graphics][PNG]]. La question se pose alors, peut-on ajouter des étiquettes à nos fichiers images de sorte que nos moteurs de recherche de bureau les indexent ? La réponse et oui, grâce aux [[https://fr.wikipedia.org/wiki/M%C3%A9tadonn%C3%A9e][métadonnées]] que contiennent ces fichiers. Les métadonnées, dans ce cas, sont des données stockées dans le fichier mais qui ne sont pas montrées par le logiciel de rendu (en tout cas, pas montrées par défaut). Nous savons tous que ces métadonnées « existent » ; ce sont elles qui contiennent la date, la localisation GPS, le temps d'exposition, etc. de nos photos numériques. Dans les fichiers =JPEG=, elles sont stockées suivant l'[[https://fr.wikipedia.org/wiki/Exchangeable_image_file_format][exchangeable image file format]] (=EXIF=). La plupart des logiciels de manipulations d'images et de photos permettent d'accéder au contenu des métadonnées et de les modifier. L'exemple illustré dans le cours utilise une solution très simple en « ligne de commande », [[http://owl.phy.queensu.ca/~phil/exiftool/][ExifTool]] qui permet de visualiser et de modifier les métadonnées. D'autres logiciels comme [[http://www.exiv2.org/index.html][exiv2]] ou [[https://imagemagick.org/script/index.php][ImageMagick]] permettent de le faire (pour ne citer que des logiciels libres disponibles sur Linux, Windows et MacOS). Certains des éléments du format =EXIF= sont des chaînes de caractères, c'est-à-dire du texte, que nous somme libres d'utiliser comme nous le souhaitons ; nous pouvons dès lors les utiliser pour rajouter nos étiquettes. Nous illustrons dans le cours comment le faire avec =ExifTool=, mais nous aurions aussi pu le faire avec le programme [[https://www.imagemagick.org/script/command-line-options.php#comment][mogrify]] d'ImageMagick. Tous les moteurs de recherche de bureau que nous avons mentionné vont « aller regarder » les métadonnées des fichier =JPEG= lors de la phase d'indexation et nous permettront ainsi d'exploiter les étiquettes que nous y aurons insérées.
=EXIF= n'est pas le seul format de métadonnées existant ; un format plus récent est l'[[https://fr.wikipedia.org/wiki/Extensible_Metadata_Platform][Extensible Metadata Platform ]](=XMP=), disponible pour un plus grand nombre de formats de fichiers — il n'est pour l'instant pas lu sur les fichiers =JPEG= par =DocFetcher=, c'est pourquoi nous avons mis en avant le format =EXIF=, mais cela devrait évoluer assez vite ; les autres moteurs comme =Tracker= et =Recoll= le lisent.
** Fichiers =PDF=
En plus des fichiers images, nous sommes tous très fréquemment amenés à travailler avec les fichiers « composites » — contenant textes, images, et plus — que sont les fichiers [[https://fr.wikipedia.org/wiki/Portable_Document_Format][PDF]]. Ces fichiers contiennent eux aussi des métadonnées ; c'est d'ailleurs pour eux qu'Adobe a initialement introduit le format =XMP= que nous venons de discuter. Ces métadonnées peuvent être lues et modifiées, en particulier l'élément =Keywords= (mot-clé) qui peut contenir des chaînes de caractères de longueur arbitraires et qui est parfait pour accueillir nos étiquettes. Le programme =ExifTool=, permet de modifier les métadonnées des fichiers =PDF=. Les moteurs de recherche de bureau que nous avons mentionnés, vont tous aller lire les métadonnées des fichiers =PDF= lors de la phase d'indexation.
** Fichiers audios
Les formats audio comme le [[https://fr.wikipedia.org/wiki/MPEG-1/2_Audio_Layer_III][mp3]] ou le [[https://fr.wikipedia.org/wiki/Ogg][ogg]] contiennent eux aussi des métadonnées, où sont stockés les titres, noms des interprètes, etc ; ces métadonnées peuvent être modifiées et sont lues par les moteurs de recherche de bureau lors de la phase d'indexation.
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Notes (and codes) that are archived but can evolve with version control systems
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: en
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
- [[#version-control-with-gitlab-and-git-in-the-Reproducible-research-mooc][Version control with GitLab and Git]]
- [[#version-control-with-libreoffice-or-dokuwiki][Version control with LibreOffice or DokuWiki]]
* Essai pour tester les liens relatifs
- Lien relatif [[/jump_to_id/5571950188c946e790f06d4bc90fb5f6#InterfaceGitlab][video]] shows how to use GitLab. We strongly recommend that you watch it if you've never used GitLab before.
- Autre essai lien relatif : [[./jump_to_id/5571950188c946e790f06d4bc90fb5f6#InterfaceGitlab][video]]
- Lien absolu session02 : [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5571950188c946e790f06d4bc90fb5f6#InterfaceGitlab][video]]
- Lien absolu session03 : [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5571950188c946e790f06d4bc90fb5f6#InterfaceGitlab][video]]
Test avec du code html
#+BEGIN_EXPORT html
<a href="/jump_to_id/5571950188c946e790f06d4bc90fb5f6#InterfaceGitlab"> Lien relatif avec code html dans le fic.org</a>
#+END_EXPORT
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Version control with LibreOffice or DokuWiki
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: en
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
Modification tracking in files generated and managed by =LibreOffice= is briefly described on the [[https://help.libreoffice.org/Common/Recording_Changes][wiki page]] of this software. A [[https://help.libreoffice.org/Common/Navigating_Changes][table of contents]] of the pages dedicated to this subject is available.
For DoKuWiki, the best is to check the [[https://www.dokuwiki.org/start?id=dokuwiki][wiki]].
#+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+OPTIONS: author:t broken-links:nil c:nil creator:nil
#+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS: timestamp:t title:t toc:t todo:t |:t
#+TITLE: Gestion de version dans LibreOffice ou dans DokuWiki
#+DATE: <2019-03-26 mar.>
#+AUTHOR: Christophe Pouzat
#+EMAIL: christophe.pouzat@parisdescartes.fr
#+LANGUAGE: fr
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+STARTUP: indent
L'enregistrement des modifications des fichiers générés et gérés par
=LibreOffice= est succinctement décrit sur la
[[https://help.libreoffice.org/Common/Recording_Changes/fr][page du Wiki]]
de ce logiciel. Une espèce de
[[https://help.libreoffice.org/Common/Navigating_Changes/fr][sommaire]]
des pages concernant la gestion des modifications est également disponible.
Le livre [[https://framabook.org/libreoffice-cest-style/][LibreOffice, c’est stylé !]]
téléchargeable gratuitement (et légalement) ne semble pas aborder la question.
Sa version source est disponible sur [[https://framagit.org/Framatophe/DWL/][Framagit]]
(un autre serveur type GitLab) et est écrite en… =Markdown= !
Pour DokuWiki, le plus simple est de consulter le [[https://www.dokuwiki.org/fr:dokuwiki][Wiki]]
écrit, cette fois au moins !, en DokuWiki.
#+TITLE: Démystifions Git, Github, Gitlab
#+AUTHOR:  
# @@latex:{\large Arnaud Legrand} \\ \vspace{0.2cm}Grenoble Alpes University and CNRS\\ \vspace{0.2cm} \texttt{arnaud.legrand@imag.fr}@@
#+DATE:  
#+OPTIONS: H:2 tags:nil toc:nil
#+LANGUAGE: fr
#+EXCLUDE_TAGS: noexport
#+SELECT_TAGS: export
#+TAGS: noexport(n) ignore(i)
#+LATEX_COMPILER: lualatex
#+LATEX_CLASS: beamer
#+LATEX_CLASS_OPTIONS: [presentation,xcolor=dvipsnames,bigger]
#+LATEX_HEADER: \usepackage[normalem]{ulem}
#+LATEX_HEADER: \usedescriptionitemofwidthas{}
#+LATEX_HEADER: \usepackage[francais]{babel}
#+LATEX_HEADER: \usepackage{tikz}
#+LATEX_HEADER: \usetikzlibrary{babel}
#+LATEX_HEADER: \usetikzlibrary{positioning}
#+LATEX_HEADER: \usetikzlibrary{fit}
#+LATEX_HEADER: \usepackage{gitdags}
#+LATEX_HEADER:\usepackage[strict=true,french=guillemets]{csquotes}
#+LATEX_HEADER: \setbeamertemplate{itemize items}{$\bullet$}
#+LATEX_HEADER: \usecolortheme[named=BrickRed]{structure}
#+LATEX_HEADER: %\useinnertheme{circles}
# #+LATEX_HEADER: \usetikzlibrary{arrows}
# #+LATEX_HEADER: \usetikzlibrary{graphs}
# #+LATEX_HEADER: \usetikzlibrary{trees}
# #+LATEX_HEADER: \usetikzlibrary{graphdrawing}
# #+LATEX_HEADER: \usegdlibrary{layered}
# #+LATEX_HEADER: \usetikzlibrary{arrows, graphs, graphs.standard, trees, graphdrawing, quotes, positioning, shadows, shapes, mindmap}
#+LATEX_HEADER: \let\maketitlesave=\maketitle
#+LATEX_HEADER: \def\maketitle{}
#+BEAMER_HEADER: \setbeamercovered{invisible}
#+BEAMER_HEADER: \beamertemplatenavigationsymbolsempty
#+STARTUP: beamer
#+COLUMNS: %45ITEM %10BEAMER_ENV(Env) %10BEAMER_ACT(Act) %4BEAMER_COL(Col) %8BEAMER_OPT(Opt)
#+STARTUP: indent
#+PROPERTY: header-args :eval no-export
#+LaTeX: \newcommand<>\gd[1]{\only#2{\gitDAG[grow up=1, branch right=1]{#1}};}
#+LaTeX: \newcommand<>\gc[2]{\only#3{\gitcontent{#1}{#2}}}
#+LaTeX: \newcommand<>\ga[2]{\only#3{\node[DAGref,fill = white, align=center, font = \normalsize, #2] () {#1};}}
#+LaTeX: \let\alert=\textbf
#+LaTeX: \begin{frame}\frametitle{}\centerline{\LARGE \textcolor{BrickRed}{Démystifions Git, Github, Gitlab}}\tableofcontents\end{frame}
* Notion d'historique
#+LaTeX: \AtBeginSection[]{\begin{frame}<beamer>\frametitle{}\centerline{\LARGE \textcolor{BrickRed}{Démystifions Git, Github, Gitlab}}\tableofcontents[currentsection]\end{frame}}
** Aaah... l'informatique
*** Problème
#+ATTR_BEAMER: :overlay <+->
- Mon ordinateur a planté!
- Ce document était bien mieux hier!
- Vous n'avez pas travaillé sur la bonne version du document.
- Comment fusionner?
- Mais qui a écrit ça ? Et pourquoi ?
*** Solution ?
#+ATTR_BEAMER: :overlay <+->
- Sauvegarde régulière avec une notion d'historique\smallskip
#+BEGIN_EXPORT latex
\footnotesize\enquote{\texttt{thesis\_slides\_16x9\_Template\_Arial\only<+->{\_FINAL\only<+->{\_FINAL\only<+->{\_0925}}}.pptx}}
#+END_EXPORT
- Passer son temps à (s')envoyer des mails!
** Gestionnaire de versions
Les gestionnaires de version datent du début des années 70
*** Fonctionnalités essentielles
- Conserve un historique des modifications sans dupliquer les dossiers
de sauvegardes
- Sauvegarde les données (avec l’historique) sur des ordinateurs
distants
- Fusion "automatique" des fichiers édités par plusieurs personnes
*** \includegraphics[height=.6cm]{img_git/Logo_Git.pdf}
#+LaTeX: \begin{columns}
#+LaTeX: \begin{column}{.8\linewidth}
- 2005: créé pour le développement du noyau Linux par Linus Torvalds
- $> 20$ millions de lignes de code
- $\approx 14\,000$ developeurs
# #+ATTR_LaTeX: :width .3\linewidth
# file:img_git/Logo_Git.pdf
# #+BEGIN_QUOTE
# Only wimps use tape backup: _real_ men just upload their important stuff on
# ftp, and let the rest of the world mirror it ;)\flushright
# -- Linus Torvalds
# #+END_QUOTE
#+LaTeX: \end{column}
#+LaTeX: \begin{column}{.2\linewidth}
#+ATTR_LaTeX: :width .55\linewidth
file:img_git/linus.jpg
#+LaTeX: \end{column}
#+LaTeX: \end{columns}
** Objectif de cet exposé
#+BEGIN_EXPORT latex
\begin{overlayarea}{\linewidth}{0cm}
% \begin{flushright}
\null\vspace{-2.0cm}%
\hbox{\hspace{8cm}\includegraphics[height=0.6\paperheight]{img_git/Git_Xkcd.png}}
% \end{flushright}
\end{overlayarea}
#+END_EXPORT
- +Apprendre à utiliser =git= en ligne de\newline commande+ \vspace{.6cm} \pause
=git= est "explicite" (à la différence \newline de dropbox et
autres)\medskip\newline
Heureusement, il y a des interfaces \vspace{.8cm}
- Notions essentielles pour utiliser les interfaces à =git=
- Historique distribué
- Branche
- Conflit et fusion
- L'écosystème
#+LaTeX: \raisebox{-.3em}{\includegraphics[height=.5cm]{img_git/Logo_Git.pdf}}\smallskip
#+BEGIN_EXPORT latex
\includegraphics[height=.5cm]{img_git/Logo_GitHub.pdf}
\includegraphics[height=.5cm]{img_git/Octocat.jpg} \quad
\resizebox{!}{.5cm}{GitLab} \includegraphics[height=.5cm]{img_git/Logo_GitLab.png}
#+END_EXPORT
#+LaTeX: \vfill
# * L'historique quand on est tout seul
** Son propre projet
#+LaTeX: \begin{columns}
#+LaTeX: \begin{column}{.13\linewidth}
#+LaTeX: \includegraphics<1>[width=\linewidth]{img_git/continuous_history_1.pdf}%
#+LaTeX: \includegraphics<2->[width=\linewidth]{img_git/continuous_history_2.pdf}
#+LaTeX: \end{column}
#+LaTeX: \begin{column}{.8\linewidth}
Accès à un certain nombre de fichiers.
#+ATTR_BEAMER: :overlay <+->
- Temps continu
- Checkpoint/snapshot: conserver les moments clés du projet pour
pouvoir y revenir
- git *add* pour indiquer quelles modifications on souhaite conserver
- git *commit* pour faire le checkpoint (date, commentaire)
#+LaTeX: \end{column}
#+LaTeX: \end{columns}
** Une histoire simple
#+BEGIN_EXPORT latex
\begin{overlayarea}{\linewidth}{8cm}
\begin{tikzpicture}
\useasboundingbox (0,0) rectangle (5,8);
% \draw (current bounding box.north east) -- (current bounding box.north west) -- (current bounding box.south west) -- (current bounding box.south east) -- cycle;
\tikzset{DAGcommit/.append style={minimum height = 1em, minimum width=1em},
DAGedge/.append style={thin},
DAGrefedge/.append style={thin},
special commit/.style={DAGcommit,fill= solarized-red!20}}
\node[anchor=south west](simple) at (.5,0) {\tikz{
% \node[DAGcommit, at (3,0)] (v1) {v1};
\gd<+>{ v1 }
\gc<.->{article.md img/fig1.jpg}{left=of v1}
\gd<+>{ v1 -- v2 }
\gc<.->{article.md}{left=of v2}
\gd<+>{ v1 -- v2 -- v3 }
\gc<.->{article.md img/fig2.jpg}{left=of v3}
\gd<+>{ v1 -- v2 -- v3 -- v4 }
\gc<.->{article.md}{left=of v4}
\gd<+>{ v1 -- v2 -- v3 --v4 -- v5 -- v6}
\gc<.->{article.md img/me.jpg}{left=of v5}
\gc<.>{article.md}{left=of v6}
\gd<+>{ v1 -- v2 -- v3 --v4 -- v5 -- {{[nodes=unreachable] v6}}}
\only<.>{\draw[->,-Latex] (v6) to[out=0,in=0] (v5);}
\gd<+>{ v1 -- v2 -- v3 --v4 -- v5 -- {{[nodes=unreachable] v6}, v6'}}
\gd<+->{ v1 -- v2 -- v3 --v4 -- v5 -- {{[nodes=unreachable] v6}, v6' -- v7 -- v8}}
\ga<+>{git \textbf{add} ...  \\git \textbf{commit}}{right=of v1, yshift=+1.6ex}
\ga<.>{Chaque version du projet\\ (appelée \emph{commit} ou \emph{révision})\\ est identifiée par un SHA1\\\scalebox{.55}{\texttt{4fd4d17f73d4c024fb3ef69fb336cc10f2cd9b26}}}{right=of v4} %text width=3cm,
\ga<.>{Un \textbf{historique} \\à la granularité\\ du \sout{fichier} projet}{right=of v7} %text width=3cm,
\only<+>{\draw[<->,Latex-Latex, dashed] (v8) to[out=0,in=0] (v4);}
\ga<.>{git \textbf{diff} v4..v8}{right=of v7}
\only<+>{\draw[->,-Latex] (v8) to[out=0,in=0] (v6');}
\ga<.>{git \textbf{checkout} v6'}{right=of v7}
\ga<+>{Tout ce qui a été commité\\est sauvegardé et accessible}{right=of v4}
\ga<.>{Cet historique est\\ \textbf{local}!}{right=of v2}
}};
% % HEAD reference
% \gitHEAD
% {left=of master}
% {master}
\end{tikzpicture}
\end{overlayarea}
#+END_EXPORT
# https://tikzit.github.io/
# dot2tex... bof
# https://pdfs.semanticscholar.org/bb76/d0dc3b4a38a15dcf5c4572a5cf9f121fef7e.pdf
# /usr/share/doc/texlive-doc/generic/pgf/pgfmanual.pdf
# - 5. Tutorial: Diagrams as Simple Graphs
** Backup sur un server distant
#+BEGIN_EXPORT latex
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\begin{overlayarea}{\linewidth}{5cm}
\begin{tikzpicture}
\useasboundingbox (0,0) rectangle (6cm,5cm);
% \draw (current bounding box.north east) -- (current bounding box.north west) -- (current bounding box.south west) -- (current bounding box.south east) -- cycle;
\tikzset{DAGcommit/.append style={minimum height = 1em, minimum width=1em},
DAGedge/.append style={thin},
DAGrefedge/.append style={thin},
special commit/.style={DAGcommit,fill= solarized-red!20},
every node/.style={transform shape}}
% \tikzset{res/.style={ellipse,draw,minimum height=0.5cm,minimum width=0.8cm}}
% \tikzset{literal/.style={rectangle,draw,minimum height=0.5cm,minimum width=0.8cm,text width = 1.2 cm, align = center}}
\tikzset{hfit/.style={rounded rectangle, inner xsep=0pt},
vfit/.style={rounded corners}}
\begin{scope}[scale = .5]
\gd<1>{ v1 }
\ga<1>{\LARGE git {\bf clone}}{right=of v1}
\begin{pgfonlayer}{background}
\node<1>[fit=(v1), fill=green!30, ellipse, opacity=.8] {};
\end{pgfonlayer}
\gd<2-3>{ v1 -- v2 -- v3 --v4 }
\ga<2>{\Large Alice travaille en local}{right=of v1}
\ga<3>{\LARGE git {\bf push}}{right=of v1}
\begin{pgfonlayer}{background}
\node<3>[fit=(v1)(v4), fill=green!30, ellipse] {};
\end{pgfonlayer}
\gd<4-6>{ v1 -- v2 -- v3 --v4 -- v5 -- {{[nodes=unreachable] v6}, v6' -- v7 -- v8}}
\ga<4>{\Large Alice travaille en local}{right=of v1}
\ga<5>{\LARGE git {\bf push}}{right=of v1}
\begin{pgfonlayer}{background}
\node<5>[fit=(v5)(v8), fill=green!30,ellipse,rotate=-30] {};
\end{pgfonlayer}
\node[DAGref,fill = white, below=of v1,remember picture] (alice) {\includegraphics[width=2cm]{img_git/alice.jpg}};
\end{scope}
\begin{scope}[scale = .5, xshift = 8cm, yshift = 3cm, every node/.style={transform shape}]
\gd<1-2>{ v1 }
\begin{pgfonlayer}{background}
\node<1>[fit=(v1), fill=green!30, ellipse] {};
\end{pgfonlayer}
\gd<3-4>{ v1 -- v2 -- v3 --v4 }
\begin{pgfonlayer}{background}
\node<3>[fit=(v1)(v4), fill=green!30, ellipse] {};
\end{pgfonlayer}
\gd<5-6>{ v1 -- v2 -- v3 --v4 -- v5 -- v6' -- v7 -- v8}
\begin{pgfonlayer}{background}
\node<5>[fit=(v5)(v8), fill=green!30, ellipse, opacity=.8] {};
% \filldraw<5>[fill=green!20!white, draw=green!50!black] v5.east -- v8 -- (-1,-3) -- cycle;
\end{pgfonlayer}
\node[DAGref,fill = white, below=of v1, remember picture] (gitlab) {\includegraphics[width=2cm]{img_git/Logo_GitLab.png}};
\end{scope}
\only<1>{\draw[->,-Latex] (gitlab) to[out=180,in=0] (alice);}
\only<3>{\draw[->,-Latex] (alice) to[out=0,in=180] (gitlab);}
\only<5>{\draw[->,-Latex] (alice) to[out=0,in=180] (gitlab);}
\ga<6>{On synchronise des \textbf{branches}\\ en échangeant \\des morceaux d'historiques}{right=of v7}
% \ga<6>{Changer l'ellipse d'Alice}{right=of v1}
% % HEAD reference
% \gitHEAD
% {left=of master}
% {master}
\end{tikzpicture}
\end{overlayarea}
#+END_EXPORT
*** cruft :noexport:
#+BEGIN_EXPORT latex
\begin{tikzpicture}[
rotate=180,
nodes={
text height=.7em,
text depth=.2em,
draw=black!20,
thick,
fill=white,
font=\footnotesize
},
>=stealth',
rounded corners,
semithick
]
\graph [
% simple necklace layout, % circular
% spring layout, % force
layered layout, % layered
% tree layout, % trees
% binary tree layout, % trees
level distance=1cm,
sibling sep=.5em,
sibling distance=1cm
] {
% AA -- {BB -- {CC, CC3 -- {DD1, DD2}},AAA};
"merge" -> {head -- v1,b} -- c -- d;
};
\end{tikzpicture}
\begin{tikzpicture}
% \usegdlibrary{layered}
% Commit DAG
\graph[layered layout,grow up sep = 2em]{
AA -- {BB -- {CC, CC3 -- {DD1, DD2}},AAA};
merge <- {head -- v1,b} -- c -- d;
A -- B -- {
C,
D -- E,
};
};
\draw[red, dashed] (1, 0.5) -- (1, -5);
\end{tikzpicture}
#+END_EXPORT
** Crédits
- A cropped and rotated version of an image of Linus Torvalds speaking at the LinuxCon Europe 2014 in Düsseldorf. CC BY-SA 4.0. https://fr.wikipedia.org/wiki/Linus_Torvalds#/media/Fichier:LinuxCon_Europe_Linus_Torvalds_03_(cropped).jpg
- Git. XKCD, A webcomic of romance, sarcasm, math, and language. CC BY-NC 2.5. Permanent link to this comic: https://xkcd.com/1597/
- Un grand remerciement à Benoît Vinot qui m'a fourni deux
présentations en beamer + tikz déjà très proches de ce que je
souhaitais présenter.
- Merci à Vincent Danjean pour avoir repéré les nombreuses petites
incohérences qui trainaient dans les noms de branches.
* Travailler à plusieurs
** Collaborer = gérer un historique distribué :noexport:
#+BEGIN_EXPORT latex
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\begin{overlayarea}{\linewidth}{5cm}
\begin{tikzpicture}
\useasboundingbox (0,0) rectangle (6cm,5cm);
% \draw (current bounding box.north east) -- (current bounding box.north west) -- (current bounding box.south west) -- (current bounding box.south east) -- cycle;
\tikzset{DAGcommit/.append style={minimum height = 1em, minimum width=1em},
DAGedge/.append style={thin},
DAGrefedge/.append style={thin},
special commit/.style={DAGcommit,fill= solarized-red!20},
every node/.style={transform shape}}
% \tikzset{res/.style={ellipse,draw,minimum height=0.5cm,minimum width=0.8cm}}
% \tikzset{literal/.style={rectangle,draw,minimum height=0.5cm,minimum width=0.8cm,text width = 1.2 cm, align = center}}
\tikzset{hfit/.style={rounded rectangle, inner xsep=0pt},
vfit/.style={rounded corners}}
\begin{scope}[scale = .5]
\gd<1>{ v1 }
\ga<1>{\LARGE git {\bf clone}}{right=of v1}
\begin{pgfonlayer}{background}
\node<1>[fit=(v1), fill=green!30, ellipse, opacity=.8] {};
\end{pgfonlayer}
\gd<2-3>{ v1 -- v2 -- v3 --v4 }
\ga<2>{\Large Alice working locally}{right=of v1}
\ga<3>{\LARGE git {\bf push}}{right=of v1}
\begin{pgfonlayer}{background}
\node<3>[fit=(v1)(v4), fill=green!30, ellipse] {};
\end{pgfonlayer}
\gd<4-5>{ v1 -- v2 -- v3 --v4 -- v5 -- {{[nodes=unreachable] v6}, v6' -- v7 -- v8}}
\ga<4>{\Large Alice working locally}{right=of v1}
\ga<5>{\LARGE git {\bf push}}{right=of v1}
\begin{pgfonlayer}{background}
\node<5>[fit=(v5)(v8), fill=green!30,ellipse,rotate=-30] {};
\end{pgfonlayer}
\node[DAGref,fill = white, below=of v1,remember picture] (linus) {\includegraphics[width=2cm]{img_git/alice.jpg}};
\end{scope}
\begin{scope}[scale = .5, xshift = 5cm, yshift = 5cm, every node/.style={transform shape}]
\gd<1-2>{ v1 }
\begin{pgfonlayer}{background}
\node<1>[fit=(v1), fill=green!30, ellipse] {};
\end{pgfonlayer}
\gd<3-4>{ v1 -- v2 -- v3 --v4 }
\begin{pgfonlayer}{background}
\node<3>[fit=(v1)(v4), fill=green!30, ellipse] {};
\end{pgfonlayer}
\gd<5->{ v1 -- v2 -- v3 --v4 -- {
v5 -- v6' -- v7 ,
v5'' -- v6''}
-- {Merge}
}
\begin{pgfonlayer}{background}
\node<5>[fit=(v5)(v8), fill=green!30, ellipse, opacity=.8] {};
% \filldraw<5>[fill=green!20!white, draw=green!50!black] v5.east -- v8 -- (-1,-3) -- cycle;
\end{pgfonlayer}
\node[DAGref,fill = white, below=of v1, remember picture] (gitlab) {\includegraphics[width=2cm]{img_git/Logo_GitLab.png}};
\end{scope}
\begin{scope}[scale = .5, xshift = 10cm, yshift = 0cm, every node/.style={transform shape}]
\gd<1-2>{ v1 }
\begin{pgfonlayer}{background}
\node<1>[fit=(v1), fill=green!30, ellipse] {};
\end{pgfonlayer}
\gd<3-4>{ v1 -- v2 -- v3 --v4 }
\begin{pgfonlayer}{background}
\node<3>[fit=(v1)(v4), fill=green!30, ellipse] {};
\end{pgfonlayer}
\gd<5->{ v1 -- v2 -- v3 --v4 -- { v5''[fill=blue] -- v6''}}
\begin{pgfonlayer}{background}
% \node<5>[fit=(v5)(v8), fill=green!30, ellipse, opacity=.8] {};
% \filldraw<5>[fill=green!20!white, draw=green!50!black] v5.east -- v8 -- (-1,-3) -- cycle;
\end{pgfonlayer}
\node[DAGref,fill = white, below=of v1, remember picture] (baby) {\includegraphics[width=2cm]{img_git/baby1.jpg}};
\end{scope}
\only<1>{\draw[->,-Latex] (gitlab) to[out=0,in=0] (linus);}
\only<3>{\draw[->,-Latex] (linus) to[out=0,in=0] (gitlab);}
\only<5>{\draw[->,-Latex] (linus) to[out=0,in=0] (gitlab);}
% % HEAD reference
% \gitHEAD
% {left=of master}
% {master}
\end{tikzpicture}
\end{overlayarea}
#+END_EXPORT
**  
:PROPERTIES:
:BEAMER_OPT: fragile
:END:
*** Header :ignore:
#+BEGIN_EXPORT latex
\null\vspace{-8mm}
\scalebox{.75}{
\begin{tikzpicture}[remember picture]
\tikzset{DAGcommit/.append style={minimum height = 1em, minimum width=1em},
DAGedge/.append style={thin},
DAGrefedge/.append style={thin},
special commit/.style={DAGcommit,fill= solarized-red!20}}
#+END_EXPORT
*** Chloé :ignore:
#+BEGIN_EXPORT latex
% Chloé
\node (historique de Chloe) at (0,0) {\tikz[remember picture]{
% Commit DAG
\onslide<1-3>{
\gitDAG[grow up=0.75, branch left=0.75]{
A -- B -- C
};
% Branch
\gitbranch
{master}
{left=of C}
{C}
% HEAD reference
\gitHEAD
{left=of master}
{master}
}
\onslide<4>{
\gitDAG[grow up=0.75, branch left=0.75]{
A -- B -- C -- D -- E
};
% Branch
\gitbranch
{master}
{left=of E}
{E}
% HEAD reference
\gitHEAD
{left=of master}
{master}
}
\onslide<5-9>{
\gitDAG[grow up=0.75, branch left=0.75]{
A -- B -- C -- D -- E -- F1[as=F]
};
% Branch
\gitbranch
{master}
{left=of F1}
{F1}
% HEAD reference
\gitHEAD
{left=of master}
{master}
}
\onslide<10>{
\gitDAG[grow up=0.75, branch left=0.75]{
A -- B -- C -- D -- E -- {
G,
F,
} -- H
};
% Branch
\gitbranch
{master}
{left=of H}
{H}
% HEAD reference
\gitHEAD
{left=of master}
{master}
}
% % Tag reference
% \gittag
% [v0p1]
% {v0.1}
% {left=of A}
% {A}
\node[DAGref,fill = white, below= of A] {\includegraphics[height=10mm]{img_git/alice.jpg}};
}
};
#+END_EXPORT
*** Origin/master between Chloé and Benoît :ignore:
#+BEGIN_EXPORT latex
% Origin/master commun
\onslide<1-2>{
% Remote branch
\gitremotebranch
[origmaster1]
{origin/master}
{right=of C}
{C}
}
\onslide<3>{
% Remote branch
\gitremotebranch
[origmaster1]
{origin/master}
{right=of C,opacity=0.5}
{C}
}
\onslide<4-5>{
% Remote branch
\gitremotebranch
[origmaster2]
{origin/master}
{right=of E}
{E}
}
\onslide<6-8>{
% Remote branch
\gitremotebranch
[origmaster]
{origin/master}
{right=of F1}
{F1}
}
\onslide<9>{
% Remote branch
\gitremotebranch
[origmaster]
{origin/master}
{right=of F1,opacity=0.5}
{F1}
}
\onslide<10>{
% Remote branch
\gitremotebranch
[origmaster3]
{origin/master}
{right=of H}
{H}
}
#+END_EXPORT
*** Benoît :ignore:
#+BEGIN_EXPORT latex
% Benoît
\node[right=2.25 of historique de Chloe.south east,anchor=south west] (historique de Benoit) {\tikz[remember picture]{
% Commit DAG
\onslide<1>{
\gitDAG[grow up=0.75, branch right=0.75]{
A -- B -- C
};
% Branch
\gitbranch
{master}
{right=of C}
{C}
% HEAD reference
\gitHEAD
{right=of master}
{master}
}
\onslide<2-4>{
\gitDAG[grow up=0.75, branch right=0.75]{
A -- B -- C -- D -- E
};
% Branch
\gitbranch
{master}
{right=of E}
{E}
% HEAD reference
\gitHEAD
{right=of master}
{master}
}
\onslide<5-7>{
\gitDAG[grow up=0.75, branch right=0.75]{
A -- B -- C -- D -- E -- G
};
% Branch
\gitbranch
{master}
{right=of G}
{G}
% HEAD reference
\gitHEAD
{right=of master}
{master}
}
\onslide<8-10>{
\gitDAG[grow up=0.75, branch right=0.75]{
A -- B -- C -- D -- E -- {
G,
F,
} -- H
};
% Branch
\gitbranch
{master}
{right=of H}
{H}
% HEAD reference
\gitHEAD
{right=of master}
{master}
}
% % Tag reference
% \gittag
% [v0p1]
% {v0.1}
% {right=of A}
% {A}
%
\node[DAGref,fill = white, below= of A] {\includegraphics[height=10mm]{img_git/bob.jpg}};
}
};
#+END_EXPORT
*** Origin/master between Chloé and Benoît :ignore:
#+BEGIN_EXPORT latex
% Liens de Benoît avec Origin/master
\draw<1-2>[DAGrefedge] (C) -- (origmaster1);
\onslide<3>{
% Remote branch
\gitremotebranch
[origmaster2]
{origin/master}
{left=of E}
{E}
}
\draw<4-5>[DAGrefedge] (E) -- (origmaster2);
\onslide<6-7>{
% Remote branch
\gitremotebranch
[origmaster2]
{origin/master}
{left=of E, opacity=0.5}
{E}
}
\draw<8>[DAGrefedge] (F) -- (origmaster);
\onslide<9>{
% Remote branch
\gitremotebranch
[origmaster3]
{origin/master}
{left=of H}
{H}
}
\draw<10>[DAGrefedge] (H) -- (origmaster3);
#+END_EXPORT
*** Gitlab :ignore:
#+BEGIN_EXPORT latex
% Dépôt origin
\node[font=\fontfamily{lmtt}\selectfont\small, above=0.35 of current bounding box.north,above] (origin) {\tikz[scale = .5, every node/.style={transform shape}, remember picture]{
% Commit DAG
\onslide<1-2>{
\gitDAG[grow up=0.75, branch left=0.75]{
A -- B -- C
};
% Branch
\gitbranch
{master}
{left=of C}
{C}
% % HEAD reference
% \gitHEAD
% {left=of master}
% {master}
}
\onslide<3-5>{
\gitDAG[grow up=0.75, branch left=0.75]{
A -- B -- C -- D -- E
};
% Branch
\gitbranch
{master}
{left=of E}
{E}
% % HEAD reference
% \gitHEAD
% {left=of master}
% {master}
}
\onslide<6-8>{
\gitDAG[grow up=0.75, branch left=0.75]{
A -- B -- C -- D -- E -- F
};
% Branch
\gitbranch
{master}
{left=of F}
{F}
% % HEAD reference
% \gitHEAD
% {left=of master}
% {master}
}
\onslide<9-10>{
\gitDAG[grow up=0.75, branch left=0.75]{
A -- B -- C -- D -- E -- {
G,
F,
} -- H
};
% Branch
\gitbranch
{master}
{left=of H}
{H}
% % HEAD reference
% \gitHEAD
% {left=of master}
% {master}
}
% % Tag reference
% \gittag
% [v0p1]
% {v0.1}
% {left=of A}
% {A}
\node[DAGref,fill = white, below= of A] {\includegraphics[height=2cm]{img_git/Logo_GitLab.png}};
}
};
#+END_EXPORT
*** Actions :ignore:
#+BEGIN_EXPORT latex
\onslide<1-2>{
% Remote branch
\gitremotebranch
[origmaster]
{master}
{right=of C}
{C}
}
% Actions
% Push de Benoît
\draw<3>[->,-Latex] (historique de Benoit) to[out=90,in=0] node[midway,font=\scriptsize,above right]{\texttt{git push}} (origin);
\onslide<3-5>{
% Remote branch
\gitremotebranch
[origmaster]
{master}
{right=of E}
{E}
}
% Pull de Chloé
\draw<4>[->,-Latex] (origin) to[out=180,in=90] node[midway,font=\scriptsize,above left]{\texttt{git pull}} (historique de Chloe);
% Push de Chloé
\draw<6>[->,-Latex] (historique de Chloe) to[out=90,in=180] node[midway,font=\scriptsize,above left]{\texttt{git push}} (origin);
% Push raté de Benoît
\draw<7>[->,-Latex] (historique de Benoit) to[out=90,in=0] node[midway,font=\scriptsize,above right, strike out, draw=red, line width=2pt]{\texttt{git push}} (origin);
\onslide<6-8>{
% Remote branch
\gitremotebranch
[origmaster]
{master}
{right=of F}
{F}
}
% Pull de Benoît
\draw<8>[->,-Latex] (origin) to[out=0,in=90] node[midway,font=\scriptsize,above right]{\texttt{git pull}\quad \normalsize \fbox{Conflict?}} (historique de Benoit);
% Push de Benoît
\draw<9>[->,-Latex] (historique de Benoit) to[out=90,in=0] node[midway,font=\scriptsize,above right]{\texttt{git push}} (origin);
\onslide<9-10>{
% Remote branch
\gitremotebranch
[origmaster]
{master}
{right=of H}
{H}
}
% Pull de Chloé
\draw<10>[->,-Latex] (origin) to[out=180,in=90]
node[midway,font=\scriptsize,above left]{\texttt{git pull}}
(historique de Chloe);
#+END_EXPORT
*** Footer :ignore:
#+BEGIN_EXPORT latex
\end{tikzpicture}}
#+END_EXPORT
** À retenir
- Collaborer = gérer un historique distribué\bigskip
- Le serveur ne sert à rien: Alice et Bob pourraient échanger
directement leurs historiques \bigskip
# Git est complètemnet décentralisé, chacun a une copie complète de
# tout l'historique du projet (et pas juste de la dernière
# version...).
- Chacun a tout l'historique $\leadsto$ très résilient
** Org-mode: how to modify an Item :noexport:
https://emacs.stackexchange.com/questions/35976/how-to-change-the-appearance-of-list-bullets-in-latex-beamer-exports/35985#35985
- [@123] will set the counter of enumerations (or "ordered lists") to 123.
- [$Rightarrow$] :: bla will generate a "description".
Both do not really yield the flexibility that I was hoping for in my question, but it seems that this is as far as one can get.
EDIT:
I've stumbled over a not so obvious way to gain full flexiblity:
- @@latex:[$\Rightarrow$]@@ will be exported as \item[$\Rightarrow$]
Notice that @@beamer:[$\Rightarrow$]@@ does not effect this.
** La Démo :noexport:
#+begin_src shell :results output :exports both
cd /tmp/
git clone git@gitlab.inria.fr:learninglab/mooc-rr/mooc-rr-modele.git
cd mooc-rr-modele
sed -i 's/rebase = true/rebase = false/g' .git/config
git reset --hard f186adfdddfd0986ab3af38187b8e5f949f9bcf3
# git reset --hard 64844e0894095f7a8cd9609218bcad3d9b4b24ea
# 64844e0894095f7a8cd9609218bcad3d9b4b24ea
git checkout master
sed -i "s/= logmodel.predict/= logmodel.predict/" module2/exo5/exo5_python_fr.org
git commit -a -m "Carelessly adding space"
git pull
jed module2/exo5/exo5_python_fr.org
git status
git add module2/exo5/exo5_python_fr.org
git commit
#+end_src
** Le conflit
Au moment du pull, il se peut que le merge ne soit pas possible et
qu'un conflit apparaisse. Pas de panique!
# - Rien de grave, ne pas paniquer. Rien n'est perdu, tout est dans
# votre historique local!
#+BEGIN_CENTER
\bf Démonstration !\pause
#+END_CENTER
- Git travaille à la granularité du fichier et de la ligne
- @@latex:[$\Rightarrow$]@@ Modularisez autant que possible\pause
- Il y aura conflit dans un fichier si la même ligne a été modifiée
de chaque côté (même un espace)
- @@latex:[$\Rightarrow$]@@ Ne réindentez pas votre texte pour rien!
- @@latex:[$\Rightarrow$]@@ Faites des commits différents pour les
modifications de fonds, de forme (git *status*; git *diff*; git *add*)
- @@latex:[$\Rightarrow$]@@ Faites de *petits* commits *logiques* (+=git commit -a=+)\pause
- Les fichier binaires n'ont pas de lignes... le diff et la fusion sont souvent
impossibles
- @@latex:[$\Rightarrow$]@@ Préférer le format texte
** En conclusion, git:
#+BEGIN_EXPORT latex
\begin{overlayarea}{\linewidth}{0cm}\vspace{-.3cm}
\hfill\llap{%
\includegraphics[height=3.8cm]{img_git/git_tree.png}%
\hspace{-1cm}
}
\end{overlayarea}\vspace{-1\baselineskip}
#+END_EXPORT
#+LaTeX: \begin{minipage}[t]{.6\linewidth}
- Ça versionne ! (git *log* / *hist*)\medskip
- Ça facilite le travail collaboratif\newline (git *merge*) !\medskip
- Ça permet de stocker ses modifications localement\newline (git *commit*) !\medskip
#+LaTeX: \end{minipage}
- Ça permet de partager ses modifications quand on le souhaite (git *pull/push*) !\medskip\pause
Mais comment mettre ça en place ?
- Comment avoir un serveur de backup ?
- Comment gérer qui peut lire/écrire ?
** Crédits
- Un grand remerciement à Benoît Vinot qui m'a fourni deux
présentations en beamer + tikz déjà très proches de ce que je
souhaitais présenter.
- Merci à Vincent Danjean pour avoir repéré les nombreuses petites
incohérences qui trainaient dans les noms de branches.
* L'écosystème Git
** \large Les plates-formes de développement collaboratif \small (1/2)
#+LaTeX: \begin{overlayarea}{\linewidth}{8cm}
- GitHub, GitLab, et les autres! ::  
- Hébergement gratuit de projets publics
- Interfaces web (navigation, preview, édition en ligne)
- Gestion des permissions (lecture/écriture, public/privé) et des utilisateurs\medskip\pause
- Un réseau social des développeurs ::  
- Statistiques, émulation, gestion de communauté
- /Issues/, correction de bugs, revue de code\pause
- Le /fork/ et la /pull request/\medskip
#+BEGIN_EXPORT latex
\begin{overlayarea}{\linewidth}{0cm}\vspace{-1.6cm}
\hfill\llap{%
\includegraphics<3>[height=3.6cm]{img_git/github_pull_request_1.pdf}%
\includegraphics<4>[height=3.6cm]{img_git/github_pull_request_2.pdf}%
\includegraphics<5>[height=3.6cm]{img_git/github_pull_request_3.pdf}%
\hspace{-1cm}
}
\end{overlayarea}\vspace{-1\baselineskip}\pause\pause\pause
#+END_EXPORT
- Des tas de fonctionnalités incroyables ::  \hfill[\to MOOC RR avancé]
- Intégration continue
- Déversement vers des archives (Zenodo, SWH)
#+LaTeX: \end{overlayarea}
** \large Les plates-formes de développement collaboratif \small (2/2)
#+LaTeX: \begin{overlayarea}{\linewidth}{8cm}
- GitHub, GitLab, et les autres! ::  
- Hébergement _*gratuit*_ de projets publics ?!? \pause
- Github :: Leaders du marché mais logiciel propriétaire
- Projets privés:
# #+LaTeX: \hfill\llap{\includegraphics[height=.5cm]{img_git/Logo_GitHub.pdf}\includegraphics[height=.9cm]{img_git/Octocat.jpg}\hspace{-1cm}}
- gratuit pour étudiants/académiques
- payant pour les autres
#+BEGIN_EXPORT latex
\begin{overlayarea}{\linewidth}{0cm}
\vspace{-2.3cm}\hfill\llap{\includegraphics<2-3>[height=1.8cm]{img_git/github_interactions.pdf}}
\end{overlayarea}\vspace{-1\baselineskip}\pause
#+END_EXPORT
- GitLab :: Logiciel libre, plusieurs instances
- Instance =gitlab.com= similaire à GitHub
- Compagnies, institutions: support avancé
#+BEGIN_EXPORT latex
\begin{overlayarea}{\linewidth}{0cm}
\vspace{-.7cm}\centerline{\includegraphics<3>[height=1.8cm]{img_git/gitlab_interactions.pdf}}
\end{overlayarea}\vspace{-1\baselineskip}\pause
#+END_EXPORT
- Lequel choisir ? :: (+ FramaGit, BitBucket, SourceForge, ...)
- Visibilité/pérénité
- Projets privés ou publiques
- Confidentialité des données
#+LaTeX: \end{overlayarea}
** Interfaces graphiques
- JupyterLab-git
- Rstudio
- Emacs Magit\bigskip
- GitHub Desktop
- GitKraken
- SmartGit
** Crédits
- A cropped and rotated version of an image of Linus Torvalds speaking at the LinuxCon Europe 2014 in Düsseldorf. CC BY-SA 4.0. https://fr.wikipedia.org/wiki/Linus_Torvalds#/media/Fichier:LinuxCon_Europe_Linus_Torvalds_03_(cropped).jpg
- Un grand remerciement à Benoît Vinot qui m'a fourni deux
présentations en beamer + tikz déjà très proches de ce que je
souhaitais présenter.
** Managing large files (dans le module de RR2) :noexport:
- Refer to zenodo of figshare from the beginning
- git annex and git lfs (deployed on github, bitbucket, and recent
versions of gitlab) \hfill[\to MOOC RR advanced]
- Push to Zenodo ?
* Export png :noexport:
#+begin_src shell :results output :exports both
for i in `seq 1 69`; do
pdftk diapos_git.pdf cat $i output diapos_git-$i.pdf
inkscape --without-gui diapos_git-$i.pdf -e diapos_git-$i.png -d 285.8
done
#+end_src
#+RESULTS:
#+begin_example
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-1.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-2.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-3.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-4.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-5.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-6.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-7.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-8.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-9.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-10.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-11.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-12.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-13.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-14.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-15.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-16.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-17.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-18.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-19.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-20.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-21.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-22.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-23.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-24.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-25.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-26.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-27.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-28.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-29.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-30.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-31.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-32.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-33.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-34.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-35.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-36.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-37.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-38.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-39.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-40.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-41.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-42.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-43.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-44.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-45.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-46.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-47.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-48.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-49.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-50.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-51.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-52.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-53.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-54.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-55.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-56.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-57.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-58.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-59.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-60.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-61.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-62.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-63.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-64.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-65.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-66.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-67.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-68.png
DPI: 285.8
Background RRGGBBAA: ffffff00
Area 0:0:483.78:362.835 exported to 1440 x 1080 pixels (285.8 dpi)
Bitmap saved as: diapos_git-69.png
#+end_example
#+begin_src shell :results output :exports both
pdftoppm diapos_git.pdf diapos_git -png -r 285.6
#+end_src
#+RESULTS:
* Tikz :noexport:
** From the doc :noexport:
#+BEGIN_EXPORT latex
\scalebox{.8}{\begin{tikzpicture}[nodes={text height=.7em, text depth=.2em,
draw=black!20, thick, fill=white, font=\footnotesize},
>=spaced stealth', rounded corners, semithick]
\graph[layered layout, level distance=1cm, sibling sep=.5em, sibling distance=1cm] {
"5th Edition" -> { "6th Edition", "PWB 1.0" };
"6th Edition" -> { "LSX" [>child anchor=45], "1 BSD", "Mini Unix", "Wollongong", "Interdata" };
"Interdata" -> { "Unix/TS 3.0", "PWB 2.0", "7th Edition" };
"7th Edition" -> { "8th Edition", "32V", "V7M", "Ultrix-11", "Xenix", "UniPlus+" };
"V7M" -> "Ultrix-11";
"8th Edition" -> "9th Edition";
"1 BSD" -> "2 BSD" -> "2.8 BSD" -> { "Ultrix-11", "2.9 BSD" };
"32V" -> "3 BSD" -> "4 BSD" -> "4.1 BSD" -> { "4.2 BSD", "2.8 BSD", "8th Edition" };
"4.2 BSD" -> { "4.3 BSD", "Ultrix-32" };
"PWB 1.0" -> { "PWB 1.2" -> "PWB 2.0", "USG 1.0" -> { "CB Unix 1", "USG 2.0" }};
"CB Unix 1" -> "CB Unix 2" -> "CB Unix 3" -> { "Unix/TS++", "PDP-11 Sys V" };
{ "USG 2.0" -> "USG 3.0", "PWB 2.0", "Unix/TS 1.0" } -> "Unix/TS 3.0";
{ "Unix/TS++", "CB Unix 3", "Unix/TS 3.0" } -> "TS 4.0" -> "System V.0" -> "System V.2" -> "System V.3";
};
\end{tikzpicture}}
#+END_EXPORT
** Historiques
#+BEGIN_EXPORT latex
\centering
\begin{tikzpicture}
% Commit DAG
\gitDAG[grow right sep = 2em]{
A -- B -- {
C,
D -- E,
}
};
% Tag reference
\gittag
[v0p1] % node name
{v0.1} % node text
{above=of A} % node placement
{A} % target
% Remote branch
\gitremotebranch
[origmaster] % node name
{origin/master} % node text
{above=of C} % node placement
{C} % target
% Branch
\gitbranch
{master} % node name and text
{above=of E} % node placement
{E} % target
% HEAD reference
\gitHEAD
{above=of master} % node placement
{master} % target
\end{tikzpicture}
\begin{tikzpicture}
\gitDAG[grow right sep = 2em]{
A -- B -- {
C -- D' -- E',
{[nodes=unreachable] D -- E },
}
};
% Tag reference
\gittag
[v0p1] % node name
{v0.1} % node text
{above=of A} % node placement
{A} % target
% Remote branch
\gitremotebranch
[origmaster] % node name
{origin/master} % node text
{above=of C} % node placement
{C} % target
% Branch
\gitbranch
{master} % node name and text
{above=of E'} % node placement
{E'} % target
% HEAD reference
\gitHEAD
{above=of master} % node placement
{master} % target
\end{tikzpicture}
#+END_EXPORT
** Historiques
#+BEGIN_EXPORT latex
\centering
\begin{tikzpicture}
% Commit DAG
\gitDAG[grow up sep = 2em, branch right = 4em]{
A -- B -- {
C
\onslide<2>{,D -- E}
}
};
% Tag reference
\gittag
[v0p1] % node name
{v0.1} % node text
{right=of A} % node placement
{A} % target
% Remote branch
\gitremotebranch
[origmaster] % node name
{origin/master} % node text
{left=of C} % node placement
{C} % target
% Branch
\onslide<2>{
\gitbranch
{master} % node name and text
{right=of E} % node placement
{E} % target
% HEAD reference
\gitHEAD
{right=of master} % node placement
{master} % target
}
\end{tikzpicture}
#+END_EXPORT
** Historiques
# http://www.texample.net/media/tikz/examples/TEX/beamer-arrows.tex
#+BEGIN_EXPORT latex
\centering
\begin{tikzpicture}
% Commit DAG
\gitDAG[grow up sep = 2em, branch right = 4em]{
"" -- A -- B -- C -- {[nodes=unreachable] D};
{[nodes=placeholder] "" -- NAA -- NBB -- NCC } --[draw opacity = 0,fill opacity = 0] E -- F;
C -- E;
};
% Tag reference
\end{tikzpicture}
#+END_EXPORT
* Emacs Setup :noexport:
This document has local variables in its postembule, which should
allow Org-mode (9) to work seamlessly without any setup. If you're
uncomfortable using such variables, you can safely ignore them at
startup. Exporting may require that you copy them in your .emacs.
# ###############################
# Local Variables:
# eval: (setq my-utils-file "ox-extra.el")
# eval: (load-file (expand-file-name my-utils-file (file-name-directory (buffer-file-name))))
# eval: (ox-extras-activate '(ignore-headlines))
# End:
%%
%% Copyright (C) 2014 by Julien Cretel <jubobs.tex at gmail.com>
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%%
%% http://www.latex-project.org/lppl.txt
%%
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
%% This work has the LPPL maintenance status `maintained'.
%%
%% The Current Maintainer of this work is Julien Cretel.
%%
%% This work currently consists of the file gitdags.sty.
%%
\NeedsTeXFormat{LaTeX2e}[2011/06/27]
\ProvidesClass{gitdags}
[2014/08/28 v0.1 A package for drawing educational Git history graphs]
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{tikz}}
\ProcessOptions\relax
\RequirePackage{xcolor-solarized}
\RequirePackage{tikz}
\usetikzlibrary{
arrows.meta,
graphs,
positioning,
shadows,
shapes,
}
% conflict color
\colorlet{conflictcolor}{red}
% custom shape, adapted from 102.5.3 in the TikZ 3.0 manual
\pgfdeclareshape{dogeared}{
\inheritsavedanchors[from=rectangle]
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\backgroundpath{%
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgf@xc=\pgf@xb \advance\pgf@xc by-5pt
\pgf@yc=\pgf@yb \advance\pgf@yc by-5pt
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
\pgfpathclose
\pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
\pgfpathclose
}
}
% To cancel a shadow (see http://tex.stackexchange.com/a/198298/21891)
\tikzset{reset preaction/.code={\def\tikz@preactions{}}}
% --- repository history graphs ---
% style definitions
\tikzset{
gitdags node/.style={
draw,
node distance = 1.4em,
drop shadow = {opacity=0.15},
font = \fontfamily{lmtt}\selectfont\small,
},
DAGref/.style={
gitdags node,
shape = rectangle,
minimum height = 1.4em,
draw = solarized-base01,
thick,
font = \fontfamily{lmtt}\selectfont\scriptsize,
},
DAGedge/.style={
semithick,
Latex-,
draw = gray,
},
DAGrefedge/.style={
DAGedge,
thick,
densely dotted,
},
DAGcommit/.style={
gitdags node,
shape = rounded rectangle,
rounded rectangle arc length = 90,
minimum height = 1.6em,
minimum width = 2em,
draw = solarized-base01,
fill = solarized-green!20,
very thick,
},
graphs/DAG/.style={
nodes = DAGcommit,
edges = DAGedge,
branch down = 3em,
grow left sep = 1.5em,
},
gitareas/.style={
gitdags node,
shape = rectangle,
rounded corners = .5em,
minimum width = 7em,
minimum height = 3em,
text opacity = 0.75,
semithick,
},
gitSA/.style={
gitareas,
anchor = north west,
xshift = 1em,
yshift = -1em,
draw = solarized-orange,
fill = solarized-orange!5,
text = solarized-orange,
},
gitWT/.style={
gitareas,
node distance = .6em,
draw = solarized-violet,
fill = solarized-violet!5,
text = solarized-violet,
},
resetarrows/.style={
-Stealth,
dashed,
thick,
draw = solarized-base02,
draw opacity = .75,
},
highlighted commit/.style={
DAGcommit,
reset preaction,
fill opacity = 0,
draw = solarized-base02,
},
problematic commits/.style={
reset preaction,
draw opacity = .25,
fill opacity = .25,
},
graphs/unreachable/.style={
problematic commits,
target edge style = problematic commits,
},
graphs/conflict/.style={
empty nodes,
problematic commits,
target edge style = problematic commits,
draw = conflictcolor,
fill = conflictcolor!25,
},
placeholder commits/.style={
reset preaction,
draw opacity = 0,
fill opacity = 0,
},
graphs/placeholder/.style={
placeholder commits,
target edge style = placeholder commits,
},
blob/.style={
shape = dogeared,
minimum width = 2em,
minimum height = 2.82em,
node distance = .75em,
line join = bevel,
draw = black,
fill = white,
align = left,
font = \ttfamily\tiny,
},
}
% directed acyclic graph
\newcommand\gitDAG[1][]{\graph[DAG,#1]}
% helper macro (let's check the name's availability)
\newcommand\nodename@gitdags{}
% local-branch reference
\newcommand\gitbranch[4][]{%
\renewcommand\nodename@gitdags{#1}%
\if\relax\detokenize{#1}\relax% check for empty optional argument
\renewcommand\nodename@gitdags{#2}%
\fi
\node[
DAGref,
fill = yellow!30,
] (\nodename@gitdags) [#3] {#2};
\draw[DAGrefedge] (#4) -- (\nodename@gitdags);
}
\newcommand\gitcontent[2]{%
\node[
DAGref,
fill = yellow!10,
] (toto) [#2] {#1};
\draw (toto);
}
% remote-branch reference
\newcommand\gitremotebranch[4][]{%
\renewcommand\nodename@gitdags{#1}%
\if\relax\detokenize{#1}\relax% check for empty optional argument
\renewcommand\nodename@gitdags{#2}%
\fi
\node[
DAGref,
fill = solarized-blue!20,
] (\nodename@gitdags) [#3] {#2};
\draw[DAGrefedge] (#4) -- (\nodename@gitdags);
}
% tag reference
\newcommand\gittag[4][]{%
\renewcommand\nodename@gitdags{#1}%
\if\relax\detokenize{#1}\relax% check for empty optional argument
\renewcommand\nodename@gitdags{#2}%
\fi
\node[
DAGref,
fill = solarized-magenta!20,
] (\nodename@gitdags) [#3] {#2};
\draw[DAGrefedge] (#4) -- (\nodename@gitdags);
}
% HEAD symbolic reference
\newcommand\gitHEAD[2]{%
\node[
DAGref,
fill = solarized-red!20,
node distance = 1em,
] (gitHEAD) [#1] {HEAD};
\draw[DAGrefedge] (#2) -- (gitHEAD);
}
% the following macro is useful for explaining how merge conflicts arise
\newcommand\gitblob[2][]
{\node[blob,#1] {#2};}
% to highlight a merge conflict arising in a given file
\newcommand\gitblobmc[1]{%
\node[
blob,
draw = conflictcolor,
text = conflictcolor,
font = \scriptsize,
#1] {???};
}
% staging area and worktree
\newcommand\SAandWT{%
\node[
gitSA,
] (stagingarea) at (current bounding box.south east) {staging area};
\node[
gitWT,
below=of stagingarea,
] (workingtree) {working tree};
}
% arrows pointing from a commit to the staging area or working tree
\newcommand\toSAorWT[2]{%
\node[highlighted commit] at (#1) {\phantom{#1}};
\draw[resetarrows] (#1.south) to[out=290, in=170]
([xshift=1em,yshift=-1em]#2.north west);
}
\newcommand\toSAfrom[1]{\toSAorWT{#1}{stagingarea}}
\newcommand\toWTfrom[1]{\toSAorWT{#1}{workingtree}}
\endinput
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -321,7 +321,7 @@ Une requête basée sur un simple mot renvoie souvent un très grand nombre de p
Il nous reste encore nous reste encore un détail technique à régler dans le cas de nos notes prises en format texte comme =Markdown=. En effet, nous ne souhaitons pas que nos étiquettes apparaissent dans les sorties =html=, =pdf= ou =docx= de nos notes. Un façon de procéder, pour les langages de balisage légers qui ne disposent pas d'étiquettes — par exemple, =Markdown= n'en dispose pas, alors que =org= en a — et de les inclure dans des commentaires. En =Markdown=, tout ce qui est encadré par =<!--= et =-->= est considéré comme un commentaire et ne figure pas dans les sorties =html= ou =pdf= des notes. Nous pouvons ainsi utiliser :
#+BEGIN_EXAMPLE
<!-- :code: -->
<!-- ;code; -->
#+END_EXAMPLE
à l'endroit de nos notes où nous souhaitons aller rapidement lorsque que nous cherchons une information relative à de la programmation (production de codes).
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2019-03-28 Thu 11:13 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>On the computation of pi</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="Konrad Hinsen" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #ccc;
box-shadow: 3px 3px 3px #eee;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: visible;
padding-top: 1.2em;
}
pre.src:before {
display: none;
position: absolute;
background-color: white;
top: -10px;
right: 10px;
padding: 3px;
border: 1px solid black;
}
pre.src:hover:before { display: inline;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { width: 90%; }
/*]]>*/-->
</style>
<link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
<link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
<script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
<script type="text/javascript">
/*
@licstart The following is the entire license notice for the
JavaScript code in this tag.
Copyright (C) 2012-2018 Free Software Foundation, Inc.
The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version. The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.
@licend The above is the entire license notice
for the JavaScript code in this tag.
*/
<!--/*--><![CDATA[/*><!--*/
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.cacheClassElem = elem.className;
elem.cacheClassTarget = target.className;
target.className = "code-highlighted";
elem.className = "code-highlighted";
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(elem.cacheClassElem)
elem.className = elem.cacheClassElem;
if(elem.cacheClassTarget)
target.className = elem.cacheClassTarget;
}
/*]]>*///-->
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
displayAlign: "center",
displayIndent: "0em",
"HTML-CSS": { scale: 100,
linebreaks: { automatic: "false" },
webFont: "TeX"
},
SVG: {scale: 100,
linebreaks: { automatic: "false" },
font: "TeX"},
NativeMML: {scale: 100},
TeX: { equationNumbers: {autoNumber: "AMS"},
MultLineWidth: "85%",
TagSide: "right",
TagIndent: ".8em"
}
});
</script>
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body>
<div id="content">
<h1 class="title">On the computation of pi</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org9717861">1. Asking the maths library</a></li>
<li><a href="#orgf7d8991">2. Buffon's needle</a></li>
<li><a href="#orgb7b38f0">3. Using a surface fraction argument</a></li>
</ul>
</div>
</div>
<div id="outline-container-org9717861" class="outline-2">
<h2 id="org9717861"><span class="section-number-2">1</span> Asking the maths library</h2>
<div class="outline-text-2" id="text-1">
<p>
My computer tells me that \(\pi\) is <i>approximatively</i>
</p>
<div class="org-src-container">
<pre class="src src-R">pi
</pre>
</div>
<pre class="example">
[1] 3.141593
</pre>
</div>
</div>
<div id="outline-container-orgf7d8991" class="outline-2">
<h2 id="orgf7d8991"><span class="section-number-2">2</span> Buffon's needle</h2>
<div class="outline-text-2" id="text-2">
<p>
Applying the method of <a href="https://en.wikipedia.org/wiki/Buffon%27s_needle_problem">Buffon's needle</a>, we get the <b>approximation</b>
</p>
<div class="org-src-container">
<pre class="src src-R">set.seed(42)
N = 100000
x = runif(N)
theta = pi/2*runif(N)
2/(mean(x+sin(theta)&gt;1))
</pre>
</div>
<pre class="example">
[1] 3.14327
</pre>
</div>
</div>
<div id="outline-container-orgb7b38f0" class="outline-2">
<h2 id="orgb7b38f0"><span class="section-number-2">3</span> Using a surface fraction argument</h2>
<div class="outline-text-2" id="text-3">
<p>
A method that is easier to understand and does not make use of the \(\sin\) function is based on the fact that if \(X\sim U(0,1)\) and \(Y\sim U(0,1)\), then \(P[X^2+Y^2\leq 1] = \pi/4\) (see <a href="https://en.wikipedia.org/wiki/Monte_Carlo_method">"Monte Carlo method" on Wikipedia</a>). The following code uses this approach:
</p>
<div class="org-src-container">
<pre class="src src-R">set.seed(42)
N = 1000
df = data.frame(X = runif(N), Y = runif(N))
df$Accept = (df$X**2 + df$Y**2 &lt;=1)
<span style="color: #BFEBBF;">library</span>(ggplot2)
ggplot(df, aes(x=X,y=Y,color=Accept)) + geom_point(alpha=.2) + coord_fixed() + theme_bw()
</pre>
</div>
<div class="figure">
<p><img src="figure_pi_mc1.png" alt="figure_pi_mc1.png" />
</p>
</div>
<p>
It is then straightforward to obtain a (not really good) approximation to \(\pi\) by counting how many times, on average, \(X^2 + Y^2\) is smaller than 1:
</p>
<div class="org-src-container">
<pre class="src src-R">4*mean(df$Accept)
</pre>
</div>
<pre class="example">
[1] 3.156
</pre>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Author: Konrad Hinsen</p>
<p class="date">Created: 2019-03-28 Thu 11:13</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
</html>
......@@ -3,11 +3,12 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
<head>
<!-- 2018-09-19 mer. 21:51 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Analyse du risque de défaillance des joints toriques de la navette Challenger</title>
<title>À propos du calcul de \(\pi\)</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="Konrad Hinsen, Arnaud Legrand, Christophe Pouzat" />
<meta name="author" content="Arnaud Legrand" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center;
......@@ -273,304 +274,107 @@ for the JavaScript code in this tag.
</head>
<body>
<div id="content">
<h1 class="title">Analyse du risque de défaillance des joints toriques de la navette Challenger</h1>
<p>
<b>Préambule :</b> Les explications données dans ce document sur le contexte
de l'étude sont largement reprises de l'excellent livre d'Edward
R. Tufte intitulé <i>Visual Explanations: Images and Quantities, Evidence
and Narrative</i>, publié en 1997 par <i>Graphics Press</i> et réédité en 2005,
ainsi que de l'article de Dalal et al. intitulé <i>Risk Analysis of the
Space Shuttle: Pre-Challenger Prediction of Failure</i> et publié en 1989
dans <i>Journal of the American Statistical Association</i>.
</p>
<div id="outline-container-orgc84b2f3" class="outline-2">
<h2 id="orgc84b2f3"><span class="section-number-2">1</span> Contexte</h2>
<div class="outline-text-2" id="text-1">
<p>
Dans cette étude, nous vous proposons de revenir sur <a href="https://fr.wikipedia.org/wiki/Accident_de_la_navette_spatiale_Challenger">l'accident de la
navette spatiale Challenger</a>. Le 28 Janvier 1986, 73 secondes après son
lancement, la navette Challenger se désintègre (voir Figure <a href="#org22bba0b">1</a>)
et entraîne avec elle, les sept astronautes à son bord. Cette
explosion est due à la défaillance des deux joints toriques
assurant l'étanchéité entre les parties hautes et basses des
propulseurs (voir Figure <a href="#orgc01ded2">2</a>). Ces joints ont perdu de leur
efficacité en raison du froid particulier qui régnait au moment du
lancement. En effet, la température ce matin là était juste en dessous
de 0°C alors que l'ensemble des vols précédents avaient été effectués
à une température d'au moins 7 à 10°C de plus.
</p>
<div id="org22bba0b" class="figure">
<p><img src="challenger5.jpg" alt="challenger5.jpg" />
</p>
<p><span class="figure-number">Figure&nbsp;1&nbsp;: </span>Photos de la catastrophe de Challenger.</p>
</div>
<div id="orgc01ded2" class="figure">
<p><img src="o-ring.png" alt="o-ring.png" />
</p>
<p><span class="figure-number">Figure&nbsp;2&nbsp;: </span>Schéma des propulseurs de la navette challenger. Les joints toriques (un joint principale et un joint secondaire) en caoutchouc de plus de 11 mètres de circonférence assurent l'étanchéité entre la partie haute et la partie basse du propulseur.</p>
</div>
<p>
Le plus étonnant est que la cause précise de cet accident avait été
débattue intensément plusieurs jours auparavant et était encore
discutée la veille même du décollage, pendant trois heures de
télé-conférence entre les ingénieurs de la Morton Thiokol
(constructeur des moteurs) et de la NASA. Si la cause immédiate de
l'accident (la défaillance des joints toriques) a rapidement été
identifiée, les raisons plus profondes qui ont conduit à ce désastre
servent régulièrement de cas d'étude, que ce soit dans des cours de
management (organisation du travail, décision technique malgré des
pressions politiques, problèmes de communication), de statistiques
(évaluation du risque, modélisation, visualisation de données), ou de
sociologie (symptôme d'un historique, de la bureaucratie et du
conformisme à des normes organisationnelles).
</p>
<p>
Dans l'étude que nous vous proposons, nous nous intéressons
principalement à l'aspect statistique mais ce n'est donc qu'une
facette (extrêmement limitée) du problème et nous vous invitons à lire
par vous même les documents donnés en référence dans le
préambule. L'étude qui suit reprend donc une partie des analyses
effectuées cette nuit là et dont l'objectif était d'évaluer
l'influence potentielle de la température et de la pression à laquelle
sont soumis les joints toriques sur leur probabilité de
dysfonctionnement. Pour cela, nous disposons des résultats des
expériences réalisées par les ingénieurs de la NASA durant les 6
années précédant le lancement de la navette Challenger.
</p>
<p>
Dans le répertoire <code>module2/exo5/</code> de votre espace <code>gitlab</code>, vous
trouverez les données d'origine ainsi qu'une analyse pour chacun des
différents parcours proposés. Cette analyse comporte quatre étapes :
</p>
<ol class="org-ol">
<li>Chargement des données</li>
<li>Inspection graphique des données</li>
<li>Estimation de l'influence de la température</li>
<li>Estimation de la probabilité de dysfonctionnement des joints
toriques</li>
</ol>
<p>
Les deux premières étapes ne supposent que des compétences de base en
R ou en Python. La troisième étape suppose une familiarité avec la
régression logistique (généralement abordée en L3 ou M1 de stats,
économétrie, bio-statistique&#x2026;) et la quatrième étape des bases de
probabilités (niveau lycée). Nous vous présentons donc dans la
prochaine section une introduction à la régression logistique qui ne
s'attarde pas sur les détails du calcul, mais juste sur le sens donné
aux résultats de cette régression.
</p>
<h1 class="title">À propos du calcul de \(\pi\)</h1>
<div id="table-of-contents">
<h2>Table des matières</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#orga63dd54">1. En demandant à la lib maths</a></li>
<li><a href="#org23d5348">2. En utilisant la méthode des aiguilles de Buffon</a></li>
<li><a href="#org0097db4">3. Avec un argument "fréquentiel" de surface</a></li>
</ul>
</div>
</div>
<div id="outline-container-org2b7fcc8" class="outline-2">
<h2 id="org2b7fcc8"><span class="section-number-2">2</span> Introduction à la régression logistique</h2>
<div class="outline-text-2" id="text-2">
<div id="outline-container-orga63dd54" class="outline-2">
<h2 id="orga63dd54"><span class="section-number-2">1</span> En demandant à la lib maths</h2>
<div class="outline-text-2" id="text-1">
<p>
Imaginons que l'on dispose des données suivantes qui indiquent pour
une cohorte d'individus s'ils ont déclaré une maladie particulière ou
pas. Je montre ici l'analyse avec R mais le code Python n'est pas forcément
très éloigné. Les données sont stockées dans une data frame dont voici
un bref résumé :
Mon ordinateur m'indique que \(\pi\) vaut <i>approximativement</i>
</p>
<div class="org-src-container">
<pre class="src src-R">summary(df)
str(df)
<pre class="src src-R">pi
</pre>
</div>
<pre class="example">
Age Malade
Min. :22.01 Min. :0.000
1st Qu.:35.85 1st Qu.:0.000
Median :50.37 Median :1.000
Mean :50.83 Mean :0.515
3rd Qu.:65.37 3rd Qu.:1.000
Max. :79.80 Max. :1.000
'data.frame': 400 obs. of 2 variables:
$ Age : num 75.1 76.4 38.6 70.2 59.2 ...
$ Malade: int 1 1 0 1 1 1 0 0 1 1 ...
</pre>
[1] 3.141593
<p>
Voici une représentation graphique des données qui permet de mieux
percevoir le lien qu'il peut y avoir entre l'âge et le fait de
contracter cette maladie ou pas :
</p>
<div class="org-src-container">
<pre class="src src-R">ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) + theme_bw()
</pre>
</div>
<div class="figure">
<p><object type="image/svg+xml" data="fig1.svg" class="org-svg">
Sorry, your browser does not support SVG.</object>
</p>
</div>
<div id="outline-container-org23d5348" class="outline-2">
<h2 id="org23d5348"><span class="section-number-2">2</span> En utilisant la méthode des aiguilles de Buffon</h2>
<div class="outline-text-2" id="text-2">
<p>
Il apparaît clairement sur ces données que plus l'on est âgé, plus la
probabilité de développer cette maladie est importante. Mais comment
estimer cette probabilité à partir uniquement de ces valeurs binaires
(malade/pas malade) ? Pour chaque tranche d'âge (par exemple de 5 ans),
on pourrait regarder la fréquence de la maladie (le code qui suit est
un peu compliqué car le calcul de l'intervalle de confiance pour ce
type de données nécessite un traitement particulier via la fonction
<code>binconf</code>).
Mais calculé avec la <b>méthode</b> des <a href="https://fr.wikipedia.org/wiki/Aiguille_de_Buffon">aiguilles de Buffon</a>, on obtiendrait
comme <b>approximation</b> :
</p>
<div class="org-src-container">
<pre class="src src-R">age_range=5
df_grouped = df <span class="org-ess-XopX">%&gt;%</span> mutate(Age=age_range*(floor(Age/age_range)+.5)) <span class="org-ess-XopX">%&gt;%</span>
group_by(Age) <span class="org-ess-XopX">%&gt;%</span> summarise(Malade=sum(Malade),N=n()) <span class="org-ess-XopX">%&gt;%</span>
rowwise() <span class="org-ess-XopX">%&gt;%</span>
do(data.frame(Age=.$Age, binconf(.$Malade, .$N, alpha=0.05))) <span class="org-ess-XopX">%&gt;%</span>
as.data.frame()
ggplot(df_grouped,aes(x=Age)) + geom_point(data=df,aes(y=Malade),alpha=.3,size=3) +
geom_errorbar(data=df_grouped,
aes(x=Age,ymin=Lower, ymax=Upper, y=PointEst), color=<span class="org-string">"darkred"</span>) +
geom_point(data=df_grouped, aes(x=Age, y=PointEst), size=3, shape=21, color=<span class="org-string">"darkred"</span>) +
theme_bw()
<pre class="src src-R">set.seed(42)
N = 100000
x = runif(N)
theta = pi/2*runif(N)
2/(mean(x+sin(theta)&gt;1))
</pre>
</div>
<pre class="example">
[1] 3.14327
<div class="figure">
<p><object type="image/svg+xml" data="fig1bis.svg" class="org-svg">
Sorry, your browser does not support SVG.</object>
</p>
</div>
<p>
L'inconvénient de cette approche est que ce calcul est effectué
indépendemment pour chaque tranches d'âges, que la tranche d'âge est
arbitraire, et qu'on n'a pas grande idée de la façon dont ça
évolue. Pour modéliser cette évolution de façon plus continue, on
pourrait tenter une régression linéaire (le modèle le plus simple
possible pour rendre compte de l'influence d'un paramètre) et ainsi
estimer l'effet de l'âge sur la probabilité d'être malade :
</p>
<div class="org-src-container">
<pre class="src src-R">ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
theme_bw() + geom_smooth(method=<span class="org-string">"lm"</span>)
</pre>
</div>
<div class="figure">
<p><object type="image/svg+xml" data="fig2.svg" class="org-svg">
Sorry, your browser does not support SVG.</object>
</p>
</div>
<div id="outline-container-org0097db4" class="outline-2">
<h2 id="org0097db4"><span class="section-number-2">3</span> Avec un argument "fréquentiel" de surface</h2>
<div class="outline-text-2" id="text-3">
<p>
La ligne bleue est la régression linéaire au sens des moindres carrés
et la zone grise est la zone de confiance à 95% de cette
estimation (avec les données dont on dispose et cette hypothèse de
linéarité, la ligne bleue est la plus probable et il y a 95% de chance
que la vraie ligne soit dans cette zone grise).
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\sim
U(0,1)\) et \(Y\sim U(0,1)\) alors \(P[X^2+Y^2\leq 1] = \pi/4\) (voir <a href="https://fr.wikipedia.org/wiki/M%C3%A9thode_de_Monte-Carlo#D%C3%A9termination_de_la_valeur_de_%CF%80">méthode de
Monte Carlo sur Wikipedia</a>). Le code suivant illustre ce fait :
</p>
<p>
Mais on voit clairement dans cette représentation graphique que cette
estimation n'a aucun sens. Une probabilité doit être comprise entre 0
et 1 et avec une régression linéaire on arrivera forcément pour des
valeurs un peu extrêmes (jeune ou âgé) à des prédictions aberrantes
(négative ou supérieures à 1). C'est tout simplement dû au fait qu'une
régression linéaire fait l'hypothèse que \(\textsf{Malade} =
\alpha.\textsf{Age} + \beta + \epsilon\), où \(\alpha\) et \(\beta\) sont des nombres réels et \(\epsilon\)
est un bruit (une variable aléatoire de moyenne nulle), et estime \(\alpha\)
et \(\beta\) à partir des données.
</p>
<p>
Cette technique n'a pas de sens pour estimer une probabilité et il
convient donc d'utiliser ce que l'on appelle une <a href="https://fr.wikipedia.org/wiki/R%C3%A9gression_logistique">régression
logistique</a> :
</p>
<div class="org-src-container">
<pre class="src src-R">ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
theme_bw() +
geom_smooth(method = <span class="org-string">"glm"</span>,
method.args = list(family = <span class="org-string">"binomial"</span>)) + xlim(20,80)
<pre class="src src-R">set.seed(42)
N = 1000
df = data.frame(X = runif(N), Y = runif(N))
df$Accept = (df$X**2 + df$Y**2 &lt;=1)
<span class="org-constant">library</span>(ggplot2)
ggplot(df, aes(x=X,y=Y,color=Accept)) + geom_point(alpha=.2) + coord_fixed() + theme_bw()
</pre>
</div>
<div class="figure">
<p><object type="image/svg+xml" data="fig3.svg" class="org-svg">
Sorry, your browser does not support SVG.</object>
<p><img src="figure_pi_mc1.png" alt="figure_pi_mc1.png" />
</p>
</div>
<p>
Ici, la bibliothèque <code>ggplot</code> fait tous les calculs de régression
logistique pour nous et nous montre uniquement le résultat "graphique"
mais dans l'analyse que nous vous proposerons pour Challenger, nous
réalisons la régression et la prédiction à la main (en <code>R</code> ou en <code>Python</code>
selon le parcours que vous choisirez) de façon à pouvoir effectuer si
besoin une inspection plus fine. Comme avant, la courbe bleue indique
l'estimation de la probabilité d'être malade en fonction de l'âge et
la zone grise nous donne des indications sur l'incertitude de cette
estimation, i.e., "sous ces hypothèses et étant donné le peu de
données qu'on a et leur variabilité, il y a 95% de chances pour que la
vraie courbe se trouve quelque part (n'importe où) dans la zone
grise".
</p>
<p>
Dans ce modèle, on suppose que \(P[\textsf{Malade}] = \pi(\textsf{Age})\) avec
\(\displaystyle\pi(x)=\frac{e^{\alpha.x + \beta}}{1+e^{\alpha.x + \beta}}\). Cette
formule (étrange au premier abord) a la bonne propriété de nous donner
systématiquement une valeur comprise entre 0 et 1 et de bien tendre
rapidement vers \(0\) quand l'âge tend vers \(-\infty\) et vers \(1\) quand l'âge
tend vers \(+\infty\) (mais ce n'est pas bien sûr pas la seule motivation).
</p>
<p>
En conclusion, lorsque l'on dispose de données évènementielles
(binaires) et que l'on souhaite estimer l'influence d'un paramètre sur
la probabilité d'occurrence de l'évènement (maladie, défaillance&#x2026;),
le modèle le plus naturel et le plus simple est celui de la
régression logistique. Notez, que même en se restreignant à une petite
partie des données (par exemple, uniquement les patients de moins de
50 ans), il est possible d'obtenir une estimation assez raisonnable,
même si, comme on pouvait s'y attendre, l'incertitude augmente
singulièrement.
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 :
</p>
<div class="org-src-container">
<pre class="src src-R">ggplot(df[df$Age&lt;50,],aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
theme_bw() +
geom_smooth(method = <span class="org-string">"glm"</span>,
method.args = list(family = <span class="org-string">"binomial"</span>),fullrange = <span class="org-type">TRUE</span>) + xlim(20,80)
<pre class="src src-R">4*mean(df$Accept)
</pre>
</div>
<pre class="example">
[1] 3.156
<div class="figure">
<p><object type="image/svg+xml" data="fig4.svg" class="org-svg">
Sorry, your browser does not support SVG.</object>
</p>
</div>
</pre>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="date">Date: Juin 2018</p>
<p class="author">Auteur: Konrad Hinsen, Arnaud Legrand, Christophe Pouzat</p>
<p class="author">Auteur: Arnaud Legrand</p>
<p class="date">Created: 2018-09-19 mer. 21:51</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
......
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2019-03-28 Thu 11:13 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>On the computation of pi</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="Konrad Hinsen" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #ccc;
box-shadow: 3px 3px 3px #eee;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: visible;
padding-top: 1.2em;
}
pre.src:before {
display: none;
position: absolute;
background-color: white;
top: -10px;
right: 10px;
padding: 3px;
border: 1px solid black;
}
pre.src:hover:before { display: inline;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { width: 90%; }
/*]]>*/-->
</style>
<link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
<link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
<script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
<script type="text/javascript">
/*
@licstart The following is the entire license notice for the
JavaScript code in this tag.
Copyright (C) 2012-2018 Free Software Foundation, Inc.
The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version. The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.
@licend The above is the entire license notice
for the JavaScript code in this tag.
*/
<!--/*--><![CDATA[/*><!--*/
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.cacheClassElem = elem.className;
elem.cacheClassTarget = target.className;
target.className = "code-highlighted";
elem.className = "code-highlighted";
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(elem.cacheClassElem)
elem.className = elem.cacheClassElem;
if(elem.cacheClassTarget)
target.className = elem.cacheClassTarget;
}
/*]]>*///-->
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
displayAlign: "center",
displayIndent: "0em",
"HTML-CSS": { scale: 100,
linebreaks: { automatic: "false" },
webFont: "TeX"
},
SVG: {scale: 100,
linebreaks: { automatic: "false" },
font: "TeX"},
NativeMML: {scale: 100},
TeX: { equationNumbers: {autoNumber: "AMS"},
MultLineWidth: "85%",
TagSide: "right",
TagIndent: ".8em"
}
});
</script>
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body>
<div id="content">
<h1 class="title">On the computation of pi</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org00d8e4a">1. Asking the math library</a></li>
<li><a href="#org7025e2c">2. * Buffon's needle</a></li>
<li><a href="#org7d2ca3d">3. Using a surface fraction argument</a></li>
</ul>
</div>
</div>
<div id="outline-container-org00d8e4a" class="outline-2">
<h2 id="org00d8e4a"><span class="section-number-2">1</span> Asking the math library</h2>
<div class="outline-text-2" id="text-1">
<p>
My computer tells me that \(\pi\) is <i>approximatively</i>
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #F0DFAF; font-weight: bold;">from</span> math <span style="color: #F0DFAF; font-weight: bold;">import</span> *
pi
</pre>
</div>
<pre class="example">
3.141592653589793
</pre>
</div>
</div>
<div id="outline-container-org7025e2c" class="outline-2">
<h2 id="org7025e2c"><span class="section-number-2">2</span> * Buffon's needle</h2>
<div class="outline-text-2" id="text-2">
<p>
Applying the method of <a href="https://en.wikipedia.org/wiki/Buffon%27s_needle_problem">Buffon's needle</a>, we get the <b>approximation</b>
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #F0DFAF; font-weight: bold;">import</span> numpy <span style="color: #F0DFAF; font-weight: bold;">as</span> np
np.random.seed(seed=42)
<span style="color: #DFAF8F;">N</span> = 10000
<span style="color: #DFAF8F;">x</span> = np.random.uniform(size=N, low=0, high=1)
<span style="color: #DFAF8F;">theta</span> = np.random.uniform(size=N, low=0, high=pi/2)
2/(<span style="color: #DCDCCC; font-weight: bold;">sum</span>((x+np.sin(theta))&gt;1)/N)
</pre>
</div>
<pre class="example">
3.12891113892
</pre>
</div>
</div>
<div id="outline-container-org7d2ca3d" class="outline-2">
<h2 id="org7d2ca3d"><span class="section-number-2">3</span> Using a surface fraction argument</h2>
<div class="outline-text-2" id="text-3">
<p>
A method that is easier to understand and does not make use of the \(\sin\) function is based on the fact that if \(X\sim U(0,1)\) and \(Y\sim U(0,1)\), then \(P[X^2+Y^2\leq 1] = \pi/4\) (see <a href="https://en.wikipedia.org/wiki/Monte_Carlo_method">"Monte Carlo method" on Wikipedia</a>). The following code uses this approach:
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #F0DFAF; font-weight: bold;">import</span> matplotlib.pyplot <span style="color: #F0DFAF; font-weight: bold;">as</span> plt
np.random.seed(seed=42)
<span style="color: #DFAF8F;">N</span> = 1000
<span style="color: #DFAF8F;">x</span> = np.random.uniform(size=N, low=0, high=1)
<span style="color: #DFAF8F;">y</span> = np.random.uniform(size=N, low=0, high=1)
<span style="color: #DFAF8F;">accept</span> = (x*x+y*y) &lt;= 1
<span style="color: #DFAF8F;">reject</span> = np.logical_not(accept)
<span style="color: #DFAF8F;">fig</span>, <span style="color: #DFAF8F;">ax</span> = plt.subplots(1)
ax.scatter(x[accept], y[accept], c=<span style="color: #CC9393;">'b'</span>, alpha=0.2, edgecolor=<span style="color: #BFEBBF;">None</span>)
ax.scatter(x[reject], y[reject], c=<span style="color: #CC9393;">'r'</span>, alpha=0.2, edgecolor=<span style="color: #BFEBBF;">None</span>)
ax.set_aspect(<span style="color: #CC9393;">'equal'</span>)
plt.savefig(matplot_lib_filename)
<span style="color: #F0DFAF; font-weight: bold;">print</span>(matplot_lib_filename)
</pre>
</div>
<div class="figure">
<p><img src="figure_pi_mc2.png" alt="figure_pi_mc2.png" />
</p>
</div>
<p>
It is then straightforward to obtain a (not really good) approximation to \(\pi\) by counting how many times, on average, \(X^2 + Y^2\) is smaller than 1:
</p>
<div class="org-src-container">
<pre class="src src-python">4*np.mean(accept)
</pre>
</div>
<pre class="example">
3.1120000000000001
</pre>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Author: Konrad Hinsen</p>
<p class="date">Created: 2019-03-28 Thu 11:13</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
</html>
......@@ -3,12 +3,12 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
<head>
<!-- 2018-09-05 mer. 07:41 -->
<!-- 2019-03-28 Thu 11:06 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Analyse des mots-clés de mon journal</title>
<title>À propos du calcul de \(\pi\)</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="Arnaud Legrand" />
<meta name="author" content="Konrad Hinsen" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center;
......@@ -161,6 +161,19 @@
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
......@@ -232,455 +245,142 @@ for the JavaScript code in this tag.
}
/*]]>*///-->
</script>
<script type="text/javascript">
function rpl(expr,a,b) {
var i=0
while (i!=-1) {
i=expr.indexOf(a,i);
if (i>=0) {
expr=expr.substring(0,i)+b+expr.substring(i+a.length);
i+=b.length;
}
}
return expr
}
function show_org_source(){
document.location.href = rpl(document.location.href,".php",".org");
}
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
displayAlign: "center",
displayIndent: "0em",
"HTML-CSS": { scale: 100,
linebreaks: { automatic: "false" },
webFont: "TeX"
},
SVG: {scale: 100,
linebreaks: { automatic: "false" },
font: "TeX"},
NativeMML: {scale: 100},
TeX: { equationNumbers: {autoNumber: "AMS"},
MultLineWidth: "85%",
TagSide: "right",
TagIndent: ".8em"
}
});
</script>
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body>
<div id="content">
<h1 class="title">Analyse des mots-clés de mon journal</h1>
<h1 class="title">À propos du calcul de \(\pi\)</h1>
<div id="table-of-contents">
<h2>Table des matières</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#orge93496f">1. Mise en forme des données</a></li>
<li><a href="#org91643e3">2. Statistiques de base</a></li>
<li><a href="#org1db0ff8">3. Représentations graphiques</a></li>
<li><a href="#org5d62750">1. En demandant à la lib maths</a></li>
<li><a href="#org48ad359">2. En utilisant la méthode des aiguilles de Buffon</a></li>
<li><a href="#orgd097712">3. Avec un argument "fréquentiel" de surface</a></li>
</ul>
</div>
</div>
<p>
J'ai la chance de ne pas avoir de comptes à rendre trop précis sur le
temps que je passe à faire telle ou telle chose. Ça tombe bien car je
n'aime pas vraiment suivre précisément et quotidiennement le temps que
je passe à faire telle ou telle chose. Par contre, comme vous avez pu
le voir dans une des vidéos de ce module, je note beaucoup
d'informations dans mon journal et j'étiquette (quand j'y pense) ces
informations. Je me suis dit qu'il pourrait être intéressant de voir
si l'évolution de l'utilisation de ces étiquettes révélait quelque
chose sur mes centres d'intérêts professionnels. Je ne compte pas en
déduire grand chose de significatif sur le plan statistique vu que je
sais que ma rigueur dans l'utilisation de ces étiquettes et leur
sémantique a évolué au fil des années mais bon, on va bien voir ce
qu'on y trouve.
</p>
<div id="outline-container-orge93496f" class="outline-2">
<h2 id="orge93496f"><span class="section-number-2">1</span> Mise en forme des données</h2>
<div id="outline-container-org5d62750" class="outline-2">
<h2 id="org5d62750"><span class="section-number-2">1</span> En demandant à la lib maths</h2>
<div class="outline-text-2" id="text-1">
<p>
Mon journal est stocké dans <code>/home/alegrand/org/journal.org</code>. Les
entrées de niveau 1 (une étoile) indiquent l'année, celles de niveau 2
(2 étoiles) le mois, celles de niveau 3 (3 étoiles) la date du jour et
enfin, celles de profondeur plus importantes ce sur quoi j'ai
travaillé ce jour là. Ce sont généralement celles-ci qui sont
étiquetées avec des mots-clés entre ":" à la fin de la ligne.
</p>
<p>
Je vais donc chercher à extraire les lignes comportant trois <code>*</code> en
début de ligne et celles commençant par une <code>*</code> et terminant par des
mots-clés (des <code>:</code> suivis éventuellement d'un espace). L'expression
régulière n'est pas forcément parfaite mais ça me donne une première
idée de ce que j'aurai besoin de faire en terme de remise en forme.
</p>
<div class="org-src-container">
<pre class="src src-shell">grep -e <span class="org-string">'^\*\*\* '</span> -e <span class="org-string">'^\*.*:.*: *$'</span> ~/org/journal.org | tail -n 20
</pre>
</div>
<pre class="example">
*** 2018-06-01 vendredi
**** CP Inria du 01/06/18 :POLARIS:INRIA:
*** 2018-06-04 lundi
*** 2018-06-07 jeudi
**** The Cognitive Packet Network - Reinforcement based Network Routing with Random Neural Networks (Erol Gelenbe) :Seminar:
*** 2018-06-08 vendredi
**** The credibility revolution in psychological science: the view from an editor's desk (Simine Vazire, UC DAVIS) :Seminar:
*** 2018-06-11 lundi
**** LIG leaders du 11 juin 2018 :POLARIS:LIG:
*** 2018-06-12 mardi
**** geom_ribbon with discrete x scale :R:
*** 2018-06-13 mercredi
*** 2018-06-14 jeudi
*** 2018-06-20 mercredi
*** 2018-06-21 jeudi
*** 2018-06-22 vendredi
**** Discussion Nicolas Benoit (TGCC, Bruyère) :SG:WP4:
*** 2018-06-25 lundi
*** 2018-06-26 mardi
**** Point budget/contrats POLARIS :POLARIS:INRIA:
</pre>
<p>
OK, je suis sur la bonne voie. Je vois qu'il y a pas mal d'entrées
sans annotation. Tant pis. Il y a aussi souvent plusieurs mots-clés
pour une même date et pour pouvoir bien rajouter la date du jour en
face de chaque mot-clé, je vais essayer un vrai langage plutôt que
d'essayer de faire ça à coup de commandes shell. Je suis de l'ancienne
génération donc j'ai plus l'habitude de Perl que de Python pour ce
genre de choses. Curieusement, ça s'écrit bien plus facilement (ça m'a
pris 5 minutes) que ça ne se relit&#x2026; &#9786;
Mon ordinateur m'indique que \(\pi\) vaut <i>approximativement</i>:
</p>
<div class="org-src-container">
<pre class="src src-perl">open INPUT, <span class="org-string">"/home/alegrand/org/journal.org"</span> or <span class="org-keyword">die</span> $<span class="org-variable-name">_</span>;
open OUTPUT, <span class="org-string">"&gt; ./org_keywords.csv"</span> or <span class="org-keyword">die</span>;
$<span class="org-variable-name">date</span>=<span class="org-string">""</span>;
print OUTPUT <span class="org-string">"Date,Keyword\n"</span>;
%<span class="org-underline"><span class="org-variable-name">skip</span></span> = <span class="org-type">my</span> %<span class="org-underline"><span class="org-variable-name">params</span></span> = map { $<span class="org-variable-name">_</span> =&gt; 1 } (<span class="org-string">""</span>, <span class="org-string">"ATTACH"</span>, <span class="org-string">"Alvin"</span>, <span class="org-string">"Fred"</span>, <span class="org-string">"Mt"</span>, <span class="org-string">"Henri"</span>, <span class="org-string">"HenriRaf"</span>);
<span class="org-keyword">while</span>(defined($<span class="org-variable-name">line</span>=&lt;<span class="org-constant">INPUT</span>&gt;)) {
chomp($<span class="org-variable-name">line</span>);
<span class="org-keyword">if</span>($<span class="org-variable-name">line</span> =~ <span class="org-string">'^\*\*\* (20[\d\-]*)'</span>) {
$<span class="org-variable-name">date</span>=$<span class="org-variable-name">1</span>;
}
<span class="org-keyword">if</span>($<span class="org-variable-name">line</span> =~ <span class="org-string">'^\*.*(:\w*:)\s*$'</span>) {
@<span class="org-underline"><span class="org-variable-name">kw</span></span>=split(<span class="org-string">/:/</span>,$<span class="org-variable-name">1</span>);
<span class="org-keyword">if</span>($<span class="org-variable-name">date</span> eq <span class="org-string">""</span>) { <span class="org-keyword">next</span>;}
<span class="org-keyword">foreach</span> $<span class="org-variable-name">k</span> (@<span class="org-underline"><span class="org-variable-name">kw</span></span>) {
<span class="org-keyword">if</span>(exists($<span class="org-variable-name">skip</span>{$<span class="org-variable-name">k</span>})) { <span class="org-keyword">next</span>;}
print OUTPUT <span class="org-string">"$date,$k\n"</span>;
}
}
}
</pre>
</div>
<p>
Vérifions à quoi ressemble le résultat :
</p>
<div class="org-src-container">
<pre class="src src-shell">head org_keywords.csv
<span class="org-builtin">echo</span> <span class="org-string">"..."</span>
tail org_keywords.csv
<pre class="src src-python"><span style="color: #F0DFAF; font-weight: bold;">from</span> math <span style="color: #F0DFAF; font-weight: bold;">import</span> *
pi
</pre>
</div>
<pre class="example">
Date,Keyword
2011-02-08,R
2011-02-08,Blog
2011-02-08,WP8
2011-02-08,WP8
2011-02-08,WP8
2011-02-17,WP0
2011-02-23,WP0
2011-04-05,Workload
2011-05-17,Workload
...
2018-05-17,POLARIS
2018-05-30,INRIA
2018-05-31,LIG
2018-06-01,INRIA
2018-06-07,Seminar
2018-06-08,Seminar
2018-06-11,LIG
2018-06-12,R
2018-06-22,WP4
2018-06-26,INRIA
3.141592653589793
</pre>
<p>
C'est parfait !
</p>
</div>
</div>
<div id="outline-container-org91643e3" class="outline-2">
<h2 id="org91643e3"><span class="section-number-2">2</span> Statistiques de base</h2>
<div id="outline-container-org48ad359" class="outline-2">
<h2 id="org48ad359"><span class="section-number-2">2</span> En utilisant la méthode des aiguilles de Buffon</h2>
<div class="outline-text-2" id="text-2">
<p>
Je suis bien plus à l'aise avec R qu'avec Python. J'utiliserai les
package du tidyverse dès que le besoin s'en fera sentir. Commençons
par lire ces données :
Mais calculé avec la <b>méthode</b> des <a href="https://fr.wikipedia.org/wiki/Aiguille_de_Buffon">aiguilles de Buffon</a>, on obtiendrait
comme <b>approximation</b> :
</p>
<div class="org-src-container">
<pre class="src src-R"><span class="org-constant">library</span>(lubridate) <span class="org-comment-delimiter"># </span><span class="org-comment">&#224; installer via install.package("tidyverse")</span>
<span class="org-constant">library</span>(dplyr)
df=read.csv(<span class="org-string">"./org_keywords.csv"</span>,header=T)
df$Year=year(date(df$Date))
</pre>
</div>
<pre class="example">
Attachement du package : ‘lubridate’
The following object is masked from ‘package:base’:
date
Attachement du package : ‘dplyr’
The following objects are masked from ‘package:lubridate’:
intersect, setdiff, union
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
</pre>
<p>
Alors, à quoi ressemblent ces données :
</p>
<div class="org-src-container">
<pre class="src src-R">str(df)
summary(df)
<pre class="src src-python"><span style="color: #F0DFAF; font-weight: bold;">import</span> numpy <span style="color: #F0DFAF; font-weight: bold;">as</span> np
np.random.seed(seed=42)
<span style="color: #DFAF8F;">N</span> = 10000
<span style="color: #DFAF8F;">x</span> = np.random.uniform(size=N, low=0, high=1)
<span style="color: #DFAF8F;">theta</span> = np.random.uniform(size=N, low=0, high=pi/2)
2/(<span style="color: #DCDCCC; font-weight: bold;">sum</span>((x+np.sin(theta))&gt;1)/N)
</pre>
</div>
<pre class="example">
'data.frame': 566 obs. of 3 variables:
$ Date : Factor w/ 420 levels "2011-02-08","2011-02-17",..: 1 1 1 1 1 2 3 4 5 6 ...
$ Keyword: Factor w/ 36 levels "Argonne","autotuning",..: 22 3 36 36 36 30 30 29 29 36 ...
$ Year : num 2011 2011 2011 2011 2011 ...
Date Keyword Year
2011-02-08: 5 WP4 : 77 Min. :2011
2016-01-06: 5 POLARIS : 56 1st Qu.:2013
2016-03-29: 5 R : 48 Median :2016
2017-12-11: 5 LIG : 40 Mean :2015
2017-12-12: 5 Teaching: 38 3rd Qu.:2017
2016-01-26: 4 WP7 : 36 Max. :2018
(Other) :537 (Other) :271
</pre>
<p>
Les types ont l'air corrects, 568 entrées, tout va bien.
</p>
<div class="org-src-container">
<pre class="src src-R">df <span class="org-ess-XopX">%&gt;%</span> group_by(Keyword, Year) <span class="org-ess-XopX">%&gt;%</span> summarize(Count=n()) <span class="org-ess-XopX">%&gt;%</span>
ungroup() <span class="org-ess-XopX">%&gt;%</span> arrange(Keyword,Year) <span class="org-constant">-&gt;</span> df_summarized
df_summarized
3.12891113892
</pre>
</div>
<pre class="example">
# A tibble: 120 x 3
Keyword Year Count
&lt;fct&gt; &lt;dbl&gt; &lt;int&gt;
1 Argonne 2012 4
2 Argonne 2013 6
3 Argonne 2014 4
4 Argonne 2015 1
5 autotuning 2012 2
6 autotuning 2014 1
7 autotuning 2016 4
8 Blog 2011 2
9 Blog 2012 6
10 Blog 2013 4
# ... with 110 more rows
</pre>
<p>
Commençons par compter combien d'annotations je fais par an.
</p>
<div class="org-src-container">
<pre class="src src-R">df_summarized_total_year = df_summarized <span class="org-ess-XopX">%&gt;%</span> group_by(Year) <span class="org-ess-XopX">%&gt;%</span> summarize(Cout=sum(Count))
df_summarized_total_year
</pre>
</div>
<pre class="example">
# A tibble: 8 x 2
Year Cout
&lt;dbl&gt; &lt;int&gt;
1 2011 24
2 2012 57
3 2013 68
4 2014 21
5 2015 80
6 2016 133
7 2017 135
8 2018 48
</pre>
<p>
Ah, visiblement, je m'améliore au fil du temps et en 2014, j'ai oublié
de le faire régulièrement.
</p>
<p>
L'annotation étant libre, certains mots-clés sont peut-être très peu
présents. Regardons ça.
</p>
<div class="org-src-container">
<pre class="src src-R">df_summarized <span class="org-ess-XopX">%&gt;%</span> group_by(Keyword) <span class="org-ess-XopX">%&gt;%</span> summarize(Count=sum(Count)) <span class="org-ess-XopX">%&gt;%</span> arrange(Count) <span class="org-ess-XopX">%&gt;%</span> as.data.frame()
</pre>
</div>
<pre class="example">
Keyword Count
1 Gradient 1
2 LaTeX 1
3 Orange 1
4 PF 1
5 twitter 2
6 WP1 2
7 WP6 2
8 Epistemology 3
9 BULL 4
10 Vulgarization 4
11 Workload 4
12 GameTheory 5
13 noexport 5
14 autotuning 7
15 Python 7
16 Stats 7
17 WP0 7
18 SG 8
19 git 9
20 HACSPECIS 10
21 Blog 12
22 BOINC 12
23 HOME 12
24 WP3 12
25 OrgMode 14
26 Argonne 15
27 Europe 18
28 Seminar 28
29 WP8 28
30 INRIA 30
31 WP7 36
32 Teaching 38
33 LIG 40
34 R 48
35 POLARIS 56
36 WP4 77
</pre>
<p>
OK, par la suite, je me restraindrai probablement à ceux qui
apparaissent au moins trois fois.
</p>
</div>
</div>
<div id="outline-container-org1db0ff8" class="outline-2">
<h2 id="org1db0ff8"><span class="section-number-2">3</span> Représentations graphiques</h2>
<div id="outline-container-orgd097712" class="outline-2">
<h2 id="orgd097712"><span class="section-number-2">3</span> Avec un argument "fréquentiel" de surface</h2>
<div class="outline-text-2" id="text-3">
<p>
Pour bien faire, il faudrait que je mette une sémantique et une
hiérarchie sur ces mots-clés mais je manque de temps là. Comme
j'enlève les mots-clés peu fréquents, je vais quand même aussi
rajouter le nombre total de mots-clés pour avoir une idée de ce que
j'ai perdu. Tentons une première représentation graphique :
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\sim
U(0,1)\) et \(Y\sim U(0,1)\) alors \(P[X^2+Y^2\leq 1] = \pi/4\) (voir <a href="https://fr.wikipedia.org/wiki/M%C3%A9thode_de_Monte-Carlo#D%C3%A9termination_de_la_valeur_de_%CF%80">méthode de
Monte Carlo sur Wikipedia</a>). Le code suivant illustre ce fait :
</p>
<div class="org-src-container">
<pre class="src src-R"><span class="org-constant">library</span>(ggplot2)
df_summarized <span class="org-ess-XopX">%&gt;%</span> filter(Count &gt; 3) <span class="org-ess-XopX">%&gt;%</span>
ggplot(aes(x=Year, y=Count)) +
geom_bar(aes(fill=Keyword),stat=<span class="org-string">"identity"</span>) +
geom_point(data=df_summarized <span class="org-ess-XopX">%&gt;%</span> group_by(Year) <span class="org-ess-XopX">%&gt;%</span> summarize(Count=sum(Count))) +
theme_bw()
</pre>
</div>
<pre class="src src-python"><span style="color: #F0DFAF; font-weight: bold;">import</span> matplotlib.pyplot <span style="color: #F0DFAF; font-weight: bold;">as</span> plt
np.random.seed(seed=42)
<span style="color: #DFAF8F;">N</span> = 1000
<span style="color: #DFAF8F;">x</span> = np.random.uniform(size=N, low=0, high=1)
<span style="color: #DFAF8F;">y</span> = np.random.uniform(size=N, low=0, high=1)
<div class="figure">
<p><img src="barchart1.png" alt="barchart1.png" />
</p>
</div>
<p>
Aouch. C'est illisible avec une telle palette de couleurs mais vu
qu'il y a beaucoup de valeurs différentes, difficile d'utiliser une
palette plus discriminante. Je vais quand même essayer rapidement
histoire de dire&#x2026; Pour ça, j'utiliserai une palette de couleur
("Set1") où les couleurs sont toutes bien différentes mais elle n'a
que 9 couleurs. Je vais donc commencer par sélectionner les 9
mots-clés les plus fréquents.
</p>
<span style="color: #DFAF8F;">accept</span> = (x*x+y*y) &lt;= 1
<span style="color: #DFAF8F;">reject</span> = np.logical_not(accept)
<div class="org-src-container">
<pre class="src src-R"><span class="org-constant">library</span>(ggplot2)
frequent_keywords = df_summarized <span class="org-ess-XopX">%&gt;%</span> group_by(Keyword) <span class="org-ess-XopX">%&gt;%</span>
summarize(Count=sum(Count)) <span class="org-ess-XopX">%&gt;%</span> arrange(Count) <span class="org-ess-XopX">%&gt;%</span>
as.data.frame() <span class="org-ess-XopX">%&gt;%</span> tail(n=9)
<span style="color: #DFAF8F;">fig</span>, <span style="color: #DFAF8F;">ax</span> = plt.subplots(1)
ax.scatter(x[accept], y[accept], c=<span style="color: #CC9393;">'b'</span>, alpha=0.2, edgecolor=<span style="color: #BFEBBF;">None</span>)
ax.scatter(x[reject], y[reject], c=<span style="color: #CC9393;">'r'</span>, alpha=0.2, edgecolor=<span style="color: #BFEBBF;">None</span>)
ax.set_aspect(<span style="color: #CC9393;">'equal'</span>)
df_summarized <span class="org-ess-XopX">%&gt;%</span> filter(Keyword <span class="org-ess-XopX">%in%</span> frequent_keywords$Keyword) <span class="org-ess-XopX">%&gt;%</span>
ggplot(aes(x=Year, y=Count)) +
geom_bar(aes(fill=Keyword),stat=<span class="org-string">"identity"</span>) +
geom_point(data=df_summarized <span class="org-ess-XopX">%&gt;%</span> group_by(Year) <span class="org-ess-XopX">%&gt;%</span> summarize(Count=sum(Count))) +
theme_bw() + scale_fill_brewer(palette=<span class="org-string">"Set1"</span>)
plt.savefig(matplot_lib_filename)
<span style="color: #F0DFAF; font-weight: bold;">print</span>(matplot_lib_filename)
</pre>
</div>
<div class="figure">
<p><img src="barchart2.png" alt="barchart2.png" />
<p><img src="figure_pi_mc2.png" alt="figure_pi_mc2.png" />
</p>
</div>
<p>
OK. Visiblement, la part liée à l'administration (<code>Inria</code>, <code>LIG</code>, <code>POLARIS</code>)
et à l'enseignement (<code>Teaching</code>) augmente. L'augmentation des parties
sur <code>R</code> est à mes yeux signe d'une amélioration de ma maîtrise de
l'outil. L'augmentation de la partie <code>Seminar</code> ne signifie pas grand
chose car ce n'est que récemment que j'ai commencé à étiqueter
systématiquement les notes que je prenais quand j'assiste à un
exposé. Les étiquettes sur <code>WP</code> ont trait à la terminologie d'un ancien
projet ANR que j'ai continué à utiliser (<code>WP4</code> = prédiction de
performance HPC, <code>WP7</code> = analyse et visualisation, <code>WP8</code> = plans
d'expérience et moteurs d'expérimentation&#x2026;). Le fait que <code>WP4</code>
diminue est plutôt le fait que les informations à ce sujet sont
maintenant plutôt les journaux de mes doctorants qui réalisent
vraiment les choses que je ne fais que superviser.
</p>
<p>
Bon, une analyse de ce genre ne serait pas digne de ce nom sans un
<i>wordcloud</i> (souvent illisible, mais tellement sexy! &#9786;). Pour ça, je
m'inspire librement de ce post :
<a href="http://onertipaday.blogspot.com/2011/07/word-cloud-in-r.html">http://onertipaday.blogspot.com/2011/07/word-cloud-in-r.html</a>
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 :
</p>
<div class="org-src-container">
<pre class="src src-R"><span class="org-constant">library</span>(wordcloud) <span class="org-comment-delimiter"># </span><span class="org-comment">&#224; installer via install.package("wordcloud")</span>
<span class="org-constant">library</span>(RColorBrewer)
pal2 <span class="org-constant">&lt;-</span> brewer.pal(8,<span class="org-string">"Dark2"</span>)
df_summarized <span class="org-ess-XopX">%&gt;%</span> group_by(Keyword) <span class="org-ess-XopX">%&gt;%</span> summarize(Count=sum(Count)) <span class="org-constant">-&gt;</span> df_summarized_keyword
wordcloud(df_summarized_keyword$Keyword, df_summarized_keyword$Count,
random.order=<span class="org-type">FALSE</span>, rot.per=.15, colors=pal2, vfont=c(<span class="org-string">"sans serif"</span>,<span class="org-string">"plain"</span>))
<pre class="src src-python">4*np.mean(accept)
</pre>
</div>
<div class="figure">
<p><img src="wordcloud.png" alt="wordcloud.png" />
</p>
</div>
<p>
Bon&#x2026; voilà, c'est "joli" mais sans grand intérêt, tout
particulièrement quand il y a si peu de mots différents.
</p>
<pre class="example">
3.1120000000000001
</pre>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Auteur: Arnaud Legrand</p>
<p class="date">Created: 2018-09-05 mer. 07:41</p>
<p class="author">Auteur: Konrad Hinsen</p>
<p class="date">Created: 2019-03-28 Thu 11:06</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
......
#+TITLE: Analyse des mots-clés de mon journal
#+TITLE: Analyzing my journal's keywords
#+LANGUAGE: fr
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
......@@ -10,33 +10,32 @@
#+PROPERTY: header-args :session :exports both :eval never-export
J'ai la chance de ne pas avoir de comptes à rendre trop précis sur le
temps que je passe à faire telle ou telle chose. Ça tombe bien car je
n'aime pas vraiment suivre précisément et quotidiennement le temps que
je passe à faire telle ou telle chose. Par contre, comme vous avez pu
le voir dans une des vidéos de ce module, je note beaucoup
d'informations dans mon journal et j'étiquette (quand j'y pense) ces
informations. Je me suis dit qu'il pourrait être intéressant de voir
si l'évolution de l'utilisation de ces étiquettes révélait quelque
chose sur mes centres d'intérêts professionnels. Je ne compte pas en
déduire grand chose de significatif sur le plan statistique vu que je
sais que ma rigueur dans l'utilisation de ces étiquettes et leur
sémantique a évolué au fil des années mais bon, on va bien voir ce
qu'on y trouve.
* Mise en forme des données
Mon journal est stocké dans ~/home/alegrand/org/journal.org~. Les
entrées de niveau 1 (une étoile) indiquent l'année, celles de niveau 2
(2 étoiles) le mois, celles de niveau 3 (3 étoiles) la date du jour et
enfin, celles de profondeur plus importantes ce sur quoi j'ai
travaillé ce jour là. Ce sont généralement celles-ci qui sont
étiquetées avec des mots-clés entre ":" à la fin de la ligne.
Je vais donc chercher à extraire les lignes comportant trois ~*~ en
début de ligne et celles commençant par une ~*~ et terminant par des
mots-clés (des ~:~ suivis éventuellement d'un espace). L'expression
régulière n'est pas forcément parfaite mais ça me donne une première
idée de ce que j'aurai besoin de faire en terme de remise en forme.
I'm a lucky person as I do not have to account too precisely for how
much time I spend working on such or such topic. This is good as I
really like my freedom and I feel I would not like having to monitor
my activity on a daily basis. However, as you may have noticed in the
videos of this module, I keep track of a large amount of information
in my journal and I tag them (most of the time). So I thought it might
be interesting to see whether these tags could reveal something about
the evolution of my professional interest. I have no intention to
deduce anything really significant from a statistical point of view,
in particular as I know my tagging rigor and the tag semantic has
evolved through time. So it will be purely exploratory..
* Data Processing and Curation
My journal is stored in ~/home/alegrand/org/journal.org~. Level 1
entries (1 star) indicate the year. Level 2 entries (2 stars) indicate
the month. Level 3 entries (3 stars) indicate the day and finally
entries with a depth larger than 3 are generally the important ones
and indicate on what I've been working on this particular day. These
are the entries that may be tagged. The tags appear in the end of
theses lines and are surrounded with =:=.
So let's try to extract the lines with exactly three ~*~ in the beginning
of the line (the date) and those that start with a ~*~ and end with tags
(between ~:~ and possibly followed by spaces). The corresponding regular
expression is not perfect but it is a first attempt and will give me
an idea of how much parsing and string processing I'll have to do.
#+begin_src shell :results output :exports both :eval never-export
grep -e '^\*\*\* ' -e '^\*.*:.*: *$' ~/org/journal.org | tail -n 20
......@@ -66,14 +65,13 @@ grep -e '^\*\*\* ' -e '^\*.*:.*: *$' ~/org/journal.org | tail -n 20
,**** Point budget/contrats POLARIS :POLARIS:INRIA:
#+end_example
OK, je suis sur la bonne voie. Je vois qu'il y a pas mal d'entrées
sans annotation. Tant pis. Il y a aussi souvent plusieurs mots-clés
pour une même date et pour pouvoir bien rajouter la date du jour en
face de chaque mot-clé, je vais essayer un vrai langage plutôt que
d'essayer de faire ça à coup de commandes shell. Je suis de l'ancienne
génération donc j'ai plus l'habitude de Perl que de Python pour ce
genre de choses. Curieusement, ça s'écrit bien plus facilement (ça m'a
pris 5 minutes) que ça ne se relit... \smiley
OK, that's not so bad. There are actually many entries that are not
tagged. Never mind! There are also often several tags for a same entry
and several entries for a same day. If I want to add the date in front
of each key word, I'd rather use a real language rather than trying to
do it only with shell commands. I'm old-school so I'm more used to
using Perl than using Python. Amusingly, it is way easier to write (it
took me about 5 minutes) than to read... \smiley
#+begin_src perl :results output :exports both :eval never-export
open INPUT, "/home/alegrand/org/journal.org" or die $_;
......@@ -100,7 +98,7 @@ while(defined($line=<INPUT>)) {
#+RESULTS:
Vérifions à quoi ressemble le résultat :
Let's check the result:
#+begin_src shell :results output :exports both
head org_keywords.csv
echo "..."
......@@ -132,12 +130,12 @@ Date,Keyword
2018-06-26,INRIA
#+end_example
C'est parfait !
Awesome! That's exactly what I wanted.
* Statistiques de base
Je suis bien plus à l'aise avec R qu'avec Python. J'utiliserai les
package du tidyverse dès que le besoin s'en fera sentir. Commençons
par lire ces données :
* Basic Statistics
Again, I'm much more comfortable using R than using Python. I'll try
not to reinvent the wheel and I'll use the tidyverse packages as soon
as they appear useful. Let's start by reading data::
#+begin_src R :results output :session *R* :exports both
library(lubridate) # à installer via install.package("tidyverse")
library(dplyr)
......@@ -169,7 +167,7 @@ The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
#+end_example
Alors, à quoi ressemblent ces données :
What does it look like ?
#+begin_src R :results output :session *R* :exports both
str(df)
summary(df)
......@@ -191,7 +189,7 @@ summary(df)
(Other) :537 (Other) :271
#+end_example
Les types ont l'air corrects, 568 entrées, tout va bien.
Types appear to be correct. 568 entries. Nothing strange, let's keep going.
#+begin_src R :results output :session *R* :exports both
df %>% group_by(Keyword, Year) %>% summarize(Count=n()) %>%
ungroup() %>% arrange(Keyword,Year) -> df_summarized
......@@ -216,7 +214,7 @@ df_summarized
# ... with 110 more rows
#+end_example
Commençons par compter combien d'annotations je fais par an.
Let's start by counting how many annotations I do per year:
#+begin_src R :results output :session *R* :exports both
df_summarized_total_year = df_summarized %>% group_by(Year) %>% summarize(Cout=sum(Count))
df_summarized_total_year
......@@ -237,11 +235,10 @@ df_summarized_total_year
8 2018 48
#+end_example
Ah, visiblement, je m'améliore au fil du temps et en 2014, j'ai oublié
de le faire régulièrement.
Good. It looks like I'm improving over time. 2014 was a bad year and I
apparently forgot to review and tag on a regular basis.
L'annotation étant libre, certains mots-clés sont peut-être très peu
présents. Regardons ça.
Tags are free so maybe some tags are scarcely used. Let's have a look.
#+begin_src R :results output :session *R* :exports both
df_summarized %>% group_by(Keyword) %>% summarize(Count=sum(Count)) %>% arrange(Count) %>% as.data.frame()
#+end_src
......@@ -287,15 +284,14 @@ df_summarized %>% group_by(Keyword) %>% summarize(Count=sum(Count)) %>% arrange
36 WP4 77
#+end_example
OK, par la suite, je me restraindrai probablement à ceux qui
apparaissent au moins trois fois.
OK, in the following, I'll restrict to the tags that appear at least
three times.
* Représentations graphiques
Pour bien faire, il faudrait que je mette une sémantique et une
hiérarchie sur ces mots-clés mais je manque de temps là. Comme
j'enlève les mots-clés peu fréquents, je vais quand même aussi
rajouter le nombre total de mots-clés pour avoir une idée de ce que
j'ai perdu. Tentons une première représentation graphique :
* Nice Looking Graphics
Ideally, I would define a semantic and a hierarchy for my tags but I'm
running out of time. Since I've decided to remove rare tags, I'll also
count the total number of tags to get an idea of how much information
I've lost. Let's try a first representation:
#+begin_src R :results output graphics :file barchart1.png :exports both :width 600 :height 400 :session *R*
library(ggplot2)
df_summarized %>% filter(Count > 3) %>%
......@@ -308,13 +304,11 @@ df_summarized %>% filter(Count > 3) %>%
#+RESULTS:
[[file:barchart1.png]]
Aouch. C'est illisible avec une telle palette de couleurs mais vu
qu'il y a beaucoup de valeurs différentes, difficile d'utiliser une
palette plus discriminante. Je vais quand même essayer rapidement
histoire de dire... Pour ça, j'utiliserai une palette de couleur
("Set1") où les couleurs sont toutes bien différentes mais elle n'a
que 9 couleurs. Je vais donc commencer par sélectionner les 9
mots-clés les plus fréquents.
Aouch! This is very hard to read, in particular because of the many
different colors and the continuous palette that prevents to
distinguish between tags. Let's try an other palette ("Set1") where
colors are very different. Unfortunately there are only 9 colors in
this palette so I'll first have to select the 9 more frequent tags.
#+begin_src R :results output graphics :file barchart2.png :exports both :width 600 :height 400 :session *R*
library(ggplot2)
......@@ -332,23 +326,22 @@ df_summarized %>% filter(Keyword %in% frequent_keywords$Keyword) %>%
#+RESULTS:
[[file:barchart2.png]]
OK. Visiblement, la part liée à l'administration (~Inria~, ~LIG~, ~POLARIS~)
et à l'enseignement (~Teaching~) augmente. L'augmentation des parties
sur ~R~ est à mes yeux signe d'une amélioration de ma maîtrise de
l'outil. L'augmentation de la partie ~Seminar~ ne signifie pas grand
chose car ce n'est que récemment que j'ai commencé à étiqueter
systématiquement les notes que je prenais quand j'assiste à un
exposé. Les étiquettes sur ~WP~ ont trait à la terminologie d'un ancien
projet ANR que j'ai continué à utiliser (~WP4~ = prédiction de
performance HPC, ~WP7~ = analyse et visualisation, ~WP8~ = plans
d'expérience et moteurs d'expérimentation...). Le fait que ~WP4~
diminue est plutôt le fait que les informations à ce sujet sont
maintenant plutôt les journaux de mes doctorants qui réalisent
vraiment les choses que je ne fais que superviser.
Bon, une analyse de ce genre ne serait pas digne de ce nom sans un
/wordcloud/ (souvent illisible, mais tellement sexy! \smiley). Pour ça, je
m'inspire librement de ce post :
OK. That's much better. It appears like the administration part
(~Inria~, ~LIG~, ~POLARIS~) and the teaching part (~Teaching~) increases. The
increasing usage of the ~R~ tag is probably reflecting my improvement in
using this tool. The evolution of the ~Seminar~ tag is meaningless as I
only recently started to systematically tag my seminar notes. The ~WP~
tags are related to a former ANR project but I've kept using the same
annotation style (~WP4~ = performance evaluation of HPC systems, ~WP7~ =
data analysis and visualization, ~WP8~ = design of
experiments/experiment engines/reproducible research...).
~WP4~ is decreasing but it is because most of the work on this topic is
now in my students' labbbooks since they are doing all the real work
which I'm mostly supervising.
Well, such kind of exploratory analysis would not be complete without
a /wordcloud/ (most of the time completely unreadable but also so hype!
\smiley). To this end, I followed the ideas presented in this blog post:
http://onertipaday.blogspot.com/2011/07/word-cloud-in-r.html
#+begin_src R :results output graphics :file wordcloud.png :exports both :width 600 :height 400 :session *R*
......@@ -363,5 +356,5 @@ wordcloud(df_summarized_keyword$Keyword, df_summarized_keyword$Count,
#+RESULTS:
[[file:wordcloud.png]]
Bon... voilà, c'est "joli" mais sans grand intérêt, tout
particulièrement quand il y a si peu de mots différents.
Voilà! It is "nice" but rather useless, especially with so few words
and such a poor semantic.
#+TITLE: Analyse des mots-clés de mon journal
#+LANGUAGE: fr
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
#+HTML_HEAD: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
#+HTML_HEAD: <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
#+PROPERTY: header-args :session :exports both :eval never-export
J'ai la chance de ne pas avoir de comptes à rendre trop précis sur le
temps que je passe à faire telle ou telle chose. Ça tombe bien car je
n'aime pas vraiment suivre précisément et quotidiennement le temps que
je passe à faire telle ou telle chose. Par contre, comme vous avez pu
le voir dans une des vidéos de ce module, je note beaucoup
d'informations dans mon journal et j'étiquette (quand j'y pense) ces
informations. Je me suis dit qu'il pourrait être intéressant de voir
si l'évolution de l'utilisation de ces étiquettes révélait quelque
chose sur mes centres d'intérêts professionnels. Je ne compte pas en
déduire grand chose de significatif sur le plan statistique vu que je
sais que ma rigueur dans l'utilisation de ces étiquettes et leur
sémantique a évolué au fil des années mais bon, on va bien voir ce
qu'on y trouve.
* Mise en forme des données
Mon journal est stocké dans ~/home/alegrand/org/journal.org~. Les
entrées de niveau 1 (une étoile) indiquent l'année, celles de niveau 2
(2 étoiles) le mois, celles de niveau 3 (3 étoiles) la date du jour et
enfin, celles de profondeur plus importantes ce sur quoi j'ai
travaillé ce jour là. Ce sont généralement celles-ci qui sont
étiquetées avec des mots-clés entre ":" à la fin de la ligne.
Je vais donc chercher à extraire les lignes comportant trois ~*~ en
début de ligne et celles commençant par une ~*~ et terminant par des
mots-clés (des ~:~ suivis éventuellement d'un espace). L'expression
régulière n'est pas forcément parfaite mais ça me donne une première
idée de ce que j'aurai besoin de faire en terme de remise en forme.
#+begin_src shell :results output :exports both :eval never-export
grep -e '^\*\*\* ' -e '^\*.*:.*: *$' ~/org/journal.org | tail -n 20
#+end_src
#+RESULTS:
#+begin_example
,*** 2018-06-01 vendredi
,**** CP Inria du 01/06/18 :POLARIS:INRIA:
,*** 2018-06-04 lundi
,*** 2018-06-07 jeudi
,**** The Cognitive Packet Network - Reinforcement based Network Routing with Random Neural Networks (Erol Gelenbe) :Seminar:
,*** 2018-06-08 vendredi
,**** The credibility revolution in psychological science: the view from an editor's desk (Simine Vazire, UC DAVIS) :Seminar:
,*** 2018-06-11 lundi
,**** LIG leaders du 11 juin 2018 :POLARIS:LIG:
,*** 2018-06-12 mardi
,**** geom_ribbon with discrete x scale :R:
,*** 2018-06-13 mercredi
,*** 2018-06-14 jeudi
,*** 2018-06-20 mercredi
,*** 2018-06-21 jeudi
,*** 2018-06-22 vendredi
,**** Discussion Nicolas Benoit (TGCC, Bruyère) :SG:WP4:
,*** 2018-06-25 lundi
,*** 2018-06-26 mardi
,**** Point budget/contrats POLARIS :POLARIS:INRIA:
#+end_example
OK, je suis sur la bonne voie. Je vois qu'il y a pas mal d'entrées
sans annotation. Tant pis. Il y a aussi souvent plusieurs mots-clés
pour une même date et pour pouvoir bien rajouter la date du jour en
face de chaque mot-clé, je vais essayer un vrai langage plutôt que
d'essayer de faire ça à coup de commandes shell. Je suis de l'ancienne
génération donc j'ai plus l'habitude de Perl que de Python pour ce
genre de choses. Curieusement, ça s'écrit bien plus facilement (ça m'a
pris 5 minutes) que ça ne se relit... \smiley
#+begin_src perl :results output :exports both :eval never-export
open INPUT, "/home/alegrand/org/journal.org" or die $_;
open OUTPUT, "> ./org_keywords.csv" or die;
$date="";
print OUTPUT "Date,Keyword\n";
%skip = my %params = map { $_ => 1 } ("", "ATTACH", "Alvin", "Fred", "Mt", "Henri", "HenriRaf");
while(defined($line=<INPUT>)) {
chomp($line);
if($line =~ '^\*\*\* (20[\d\-]*)') {
$date=$1;
}
if($line =~ '^\*.*(:\w*:)\s*$') {
@kw=split(/:/,$1);
if($date eq "") { next;}
foreach $k (@kw) {
if(exists($skip{$k})) { next;}
print OUTPUT "$date,$k\n";
}
}
}
#+end_src
#+RESULTS:
Vérifions à quoi ressemble le résultat :
#+begin_src shell :results output :exports both
head org_keywords.csv
echo "..."
tail org_keywords.csv
#+end_src
#+RESULTS:
#+begin_example
Date,Keyword
2011-02-08,R
2011-02-08,Blog
2011-02-08,WP8
2011-02-08,WP8
2011-02-08,WP8
2011-02-17,WP0
2011-02-23,WP0
2011-04-05,Workload
2011-05-17,Workload
...
2018-05-17,POLARIS
2018-05-30,INRIA
2018-05-31,LIG
2018-06-01,INRIA
2018-06-07,Seminar
2018-06-08,Seminar
2018-06-11,LIG
2018-06-12,R
2018-06-22,WP4
2018-06-26,INRIA
#+end_example
C'est parfait !
* Statistiques de base
Je suis bien plus à l'aise avec R qu'avec Python. J'utiliserai les
package du tidyverse dès que le besoin s'en fera sentir. Commençons
par lire ces données :
#+begin_src R :results output :session *R* :exports both
library(lubridate) # à installer via install.package("tidyverse")
library(dplyr)
df=read.csv("./org_keywords.csv",header=T)
df$Year=year(date(df$Date))
#+end_src
#+RESULTS:
#+begin_example
Attachement du package : ‘lubridate’
The following object is masked from ‘package:base’:
date
Attachement du package : ‘dplyr’
The following objects are masked from ‘package:lubridate’:
intersect, setdiff, union
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
#+end_example
Alors, à quoi ressemblent ces données :
#+begin_src R :results output :session *R* :exports both
str(df)
summary(df)
#+end_src
#+RESULTS:
#+begin_example
'data.frame': 566 obs. of 3 variables:
$ Date : Factor w/ 420 levels "2011-02-08","2011-02-17",..: 1 1 1 1 1 2 3 4 5 6 ...
$ Keyword: Factor w/ 36 levels "Argonne","autotuning",..: 22 3 36 36 36 30 30 29 29 36 ...
$ Year : num 2011 2011 2011 2011 2011 ...
Date Keyword Year
2011-02-08: 5 WP4 : 77 Min. :2011
2016-01-06: 5 POLARIS : 56 1st Qu.:2013
2016-03-29: 5 R : 48 Median :2016
2017-12-11: 5 LIG : 40 Mean :2015
2017-12-12: 5 Teaching: 38 3rd Qu.:2017
2016-01-26: 4 WP7 : 36 Max. :2018
(Other) :537 (Other) :271
#+end_example
Les types ont l'air corrects, 568 entrées, tout va bien.
#+begin_src R :results output :session *R* :exports both
df %>% group_by(Keyword, Year) %>% summarize(Count=n()) %>%
ungroup() %>% arrange(Keyword,Year) -> df_summarized
df_summarized
#+end_src
#+RESULTS:
#+begin_example
# A tibble: 120 x 3
Keyword Year Count
<fct> <dbl> <int>
1 Argonne 2012 4
2 Argonne 2013 6
3 Argonne 2014 4
4 Argonne 2015 1
5 autotuning 2012 2
6 autotuning 2014 1
7 autotuning 2016 4
8 Blog 2011 2
9 Blog 2012 6
10 Blog 2013 4
# ... with 110 more rows
#+end_example
Commençons par compter combien d'annotations je fais par an.
#+begin_src R :results output :session *R* :exports both
df_summarized_total_year = df_summarized %>% group_by(Year) %>% summarize(Cout=sum(Count))
df_summarized_total_year
#+end_src
#+RESULTS:
#+begin_example
# A tibble: 8 x 2
Year Cout
<dbl> <int>
1 2011 24
2 2012 57
3 2013 68
4 2014 21
5 2015 80
6 2016 133
7 2017 135
8 2018 48
#+end_example
Ah, visiblement, je m'améliore au fil du temps et en 2014, j'ai oublié
de le faire régulièrement.
L'annotation étant libre, certains mots-clés sont peut-être très peu
présents. Regardons ça.
#+begin_src R :results output :session *R* :exports both
df_summarized %>% group_by(Keyword) %>% summarize(Count=sum(Count)) %>% arrange(Count) %>% as.data.frame()
#+end_src
#+RESULTS:
#+begin_example
Keyword Count
1 Gradient 1
2 LaTeX 1
3 Orange 1
4 PF 1
5 twitter 2
6 WP1 2
7 WP6 2
8 Epistemology 3
9 BULL 4
10 Vulgarization 4
11 Workload 4
12 GameTheory 5
13 noexport 5
14 autotuning 7
15 Python 7
16 Stats 7
17 WP0 7
18 SG 8
19 git 9
20 HACSPECIS 10
21 Blog 12
22 BOINC 12
23 HOME 12
24 WP3 12
25 OrgMode 14
26 Argonne 15
27 Europe 18
28 Seminar 28
29 WP8 28
30 INRIA 30
31 WP7 36
32 Teaching 38
33 LIG 40
34 R 48
35 POLARIS 56
36 WP4 77
#+end_example
OK, par la suite, je me restraindrai probablement à ceux qui
apparaissent au moins trois fois.
* Représentations graphiques
Pour bien faire, il faudrait que je mette une sémantique et une
hiérarchie sur ces mots-clés mais je manque de temps là. Comme
j'enlève les mots-clés peu fréquents, je vais quand même aussi
rajouter le nombre total de mots-clés pour avoir une idée de ce que
j'ai perdu. Tentons une première représentation graphique :
#+begin_src R :results output graphics :file barchart1.png :exports both :width 600 :height 400 :session *R*
library(ggplot2)
df_summarized %>% filter(Count > 3) %>%
ggplot(aes(x=Year, y=Count)) +
geom_bar(aes(fill=Keyword),stat="identity") +
geom_point(data=df_summarized %>% group_by(Year) %>% summarize(Count=sum(Count))) +
theme_bw()
#+end_src
#+RESULTS:
[[file:barchart1.png]]
Aouch. C'est illisible avec une telle palette de couleurs mais vu
qu'il y a beaucoup de valeurs différentes, difficile d'utiliser une
palette plus discriminante. Je vais quand même essayer rapidement
histoire de dire... Pour ça, j'utiliserai une palette de couleur
("Set1") où les couleurs sont toutes bien différentes mais elle n'a
que 9 couleurs. Je vais donc commencer par sélectionner les 9
mots-clés les plus fréquents.
#+begin_src R :results output graphics :file barchart2.png :exports both :width 600 :height 400 :session *R*
library(ggplot2)
frequent_keywords = df_summarized %>% group_by(Keyword) %>%
summarize(Count=sum(Count)) %>% arrange(Count) %>%
as.data.frame() %>% tail(n=9)
df_summarized %>% filter(Keyword %in% frequent_keywords$Keyword) %>%
ggplot(aes(x=Year, y=Count)) +
geom_bar(aes(fill=Keyword),stat="identity") +
geom_point(data=df_summarized %>% group_by(Year) %>% summarize(Count=sum(Count))) +
theme_bw() + scale_fill_brewer(palette="Set1")
#+end_src
#+RESULTS:
[[file:barchart2.png]]
OK. Visiblement, la part liée à l'administration (~Inria~, ~LIG~, ~POLARIS~)
et à l'enseignement (~Teaching~) augmente. L'augmentation des parties
sur ~R~ est à mes yeux signe d'une amélioration de ma maîtrise de
l'outil. L'augmentation de la partie ~Seminar~ ne signifie pas grand
chose car ce n'est que récemment que j'ai commencé à étiqueter
systématiquement les notes que je prenais quand j'assiste à un
exposé. Les étiquettes sur ~WP~ ont trait à la terminologie d'un ancien
projet ANR que j'ai continué à utiliser (~WP4~ = prédiction de
performance HPC, ~WP7~ = analyse et visualisation, ~WP8~ = plans
d'expérience et moteurs d'expérimentation...). Le fait que ~WP4~
diminue est plutôt le fait que les informations à ce sujet sont
maintenant plutôt les journaux de mes doctorants qui réalisent
vraiment les choses que je ne fais que superviser.
Bon, une analyse de ce genre ne serait pas digne de ce nom sans un
/wordcloud/ (souvent illisible, mais tellement tape à l'œil! \smiley). Pour
ça, je m'inspire librement de ce post :
http://onertipaday.blogspot.com/2011/07/word-cloud-in-r.html
#+begin_src R :results output graphics :file wordcloud.png :exports both :width 600 :height 400 :session *R*
library(wordcloud) # à installer via install.package("wordcloud")
library(RColorBrewer)
pal2 <- brewer.pal(8,"Dark2")
df_summarized %>% group_by(Keyword) %>% summarize(Count=sum(Count)) -> df_summarized_keyword
wordcloud(df_summarized_keyword$Keyword, df_summarized_keyword$Count,
random.order=FALSE, rot.per=.15, colors=pal2, vfont=c("sans serif","plain"))
#+end_src
#+RESULTS:
[[file:wordcloud.png]]
Bon... voilà, c'est "joli" mais sans grand intérêt, tout
particulièrement quand il y a si peu de mots différents.
#+TITLE: Analysis of the risk of failure of the O-rings of the space shuttle Challenger
#+AUTHOR: Konrad Hinsen, Arnaud Legrand, Christophe Pouzat
#+DATE: Juin 2018
#+LANGUAGE: en
#+OPTIONS: H:3 creator:nil timestamp:nil skip:nil toc:nil num:t ^:nil ~:~
# #+OPTIONS: author:nil title:nil date:nil
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
#+HTML_HEAD: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
#+HTML_HEAD: <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
#+LATEX_HEADER: \usepackage[utf8]{inputenc}
#+LATEX_HEADER: \usepackage[T1]{fontenc}
#+LATEX_HEADER: \usepackage{textcomp}
#+LATEX_HEADER: \usepackage[a4paper,margin=.8in]{geometry}
#+LATEX_HEADER: \usepackage[usenames,dvipsnames,svgnames,table]{xcolor}
#+LATEX_HEADER: \usepackage{palatino}
#+LATEX_HEADER: \usepackage{svg}
#+LATEX_HEADER: \let\epsilon=\varepsilon
*Foreword:* The explanations given in this document about the context
of the study have been taken from the excellent book /Visual
Explanations: Images and Quantities, Evidence and Narrative/ by Edward
R. Tufte, published in 1997 by /Graphics Press/ and re-edited in 2005,
and from the article /Risk Analysis of the Space Shuttle:
Pre-Challenger Prediction of Failure/ by Dalal et al., published in
1989 in the /Journal of the American Statistical Association/.
* Context
In this study, we propose a re-examination of the [[https://en.wikipedia.org/wiki/Space_Shuttle_Challenger_disaster][space shuttle
Challenger disaster]]. On January 28th, 1986, the space shuttle
Challenged exploded 73 seconds after launch (see Figure [[fig:photo]]),
causing the death of the seven astronauts on board. The explosion was
caused by the failure of the two O-ring seals between the upper and
lower parts of the boosters (see Figure [[fig:oring]]). The seals had
lost their efficiency because of the exceptionally cold weather at the
time of launch. The temperature on that morning was just below 0°C,
whereas the preceding flights hat been launched at temperatures at
least 7 to 10°C higher.
#+NAME: fig:photo
#+ATTR_LATEX: :width 10cm
#+CAPTION: Photographs of the Challenger catastrophe.
file:challenger5.jpg
#+NAME: fig:oring
#+ATTR_LATEX: :width 10cm
#+CAPTION: Diagram of the boosters of space shuttle Challenger. The rubber O-ring seals (a principal and a secondary one) of more than 11 meter circumference prevent leaks between the upper and lower parts.
file:o-ring.png
# From
# https://i0.wp.com/www.kylehailey.com/wp-content/uploads/2014/01/Screen-Shot-2013-12-30-at-12.05.04-PM-1024x679.png?zoom=2&resize=594%2C393
What is most astonishing is that the precise cause of the accident had
been intensely debated several days before and was still under
discussion the day before the launch, during a three-hour
teleconference involving engineers from Morton Thiokol (the supplier
of the engines) and from NASA. Whereas the immediate cause of the
accident, the failure of the O-ring, was quickly identified, the
underlying causes of the disaster have regularly served as a case
study, be it in management training (work organisation, decision
taking in spite of political pressure, communication problems),
statistics (risk evaluation, modelisation, data visualization), or
sociology (history, bureaucracy, conforming to organisational norms).
In the study that we propose, we are mainly concerned with the
statistical aspect, which however is only one piece of the puzzle. We
invite you to read the documents cited in the foreword for more
information. The following study takes up a part of the analyses that
were done that night with the goal of evaluating the potential impact
of temperature and air pressure on the probability of O-ring
malfunction. The starting point is experimental results obtained by
NASA engineers over the six years preceding the Challenger launch.
In the directory ~module2/exo5/~ of your GitLab workspace, you will
find the original data as well as an analysis for each of the paths we
offer. This analysis consists of four steps:
1. Loading the data
2. Visual inspection
3. Estimation of the influence of temperature
4. Estimation of the probability of O-ring malfunction
The first two steps require only a basic knowledge of R or Python. The
third step assumes some familiarity with logistic regression, and the
fourth a basic knowledge of probability. In the next section, we give
an introduction to logistic regression that skips the details of the
computations and focuses instead on the interpretation of the results.
* Introduction to logistic regression
Suppose we have the following dataset that indicates for a group of
people of varying age if they suffer from a specific illness or not. I
will present the analysis in R but Python code would look quite
similar. The data are stored in a data frame that is summarized as:
#+begin_src R :results output :session *R* :exports none
library(Hmisc) # to compute a confidence interval on binomial data
library(ggplot2)
library(dplyr)
set.seed(42)
proba = function(age) {
val=(age-50)/4
return(exp(val)/(1+exp(val)))
}
df = data.frame(Age = runif(400,min=22,max=80))
df$Ill = sapply(df$Age, function(x) rbinom(n=1,size=1,prob=proba(x)))
#+end_src
#+RESULTS:
#+begin_src R :results output :session *R* :exports both
summary(df)
str(df)
#+end_src
#+RESULTS:
#+begin_example
Age Ill
Min. :22.01 Min. :0.000
1st Qu.:35.85 1st Qu.:0.000
Median :50.37 Median :1.000
Mean :50.83 Mean :0.515
3rd Qu.:65.37 3rd Qu.:1.000
Max. :79.80 Max. :1.000
'data.frame': 400 obs. of 2 variables:
$ Age: num 75.1 76.4 38.6 70.2 59.2 ...
$ Ill: int 1 1 0 1 1 1 0 0 1 1 ...
#+end_example
Here is a plot that provides a better indication of the link that
could exist between age and illness:
#+begin_src R :results output graphics :file fig1.svg :exports both :width 4 :height 3 :session *R*
ggplot(df,aes(x=Age,y=Ill)) + geom_point(alpha=.3,size=3) + theme_bw()
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig1.svg]]
Clearly the probability of suffering from this illness increases with
age. But how can we estimate this probability based only on this
binary data ill/not ill? For each age slice (of, for example, 5
years), we could look at the frequency of the illness. The following
code is a bit complicated because the computation of the confidence
interval for this kind of data requires a particular treatment using
the function =binconf=.
#+begin_src R :results output graphics :file fig1bis.svg :exports both :width 4 :height 3 :session *R*
age_range=5
df_grouped = df %>% mutate(Age=age_range*(floor(Age/age_range)+.5)) %>%
group_by(Age) %>% summarise(Ill=sum(Ill),N=n()) %>%
rowwise() %>%
do(data.frame(Age=.$Age, binconf(.$Ill, .$N, alpha=0.05))) %>%
as.data.frame()
ggplot(df_grouped,aes(x=Age)) + geom_point(data=df,aes(y=Ill),alpha=.3,size=3) +
geom_errorbar(data=df_grouped,
aes(x=Age,ymin=Lower, ymax=Upper, y=PointEst), color="darkred") +
geom_point(data=df_grouped, aes(x=Age, y=PointEst), size=3, shape=21, color="darkred") +
theme_bw()
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig1bis.svg]]
A disadvantage of this method is that the computation is done
independently for each age slice, which moreover has been chosen
arbitrarily. For describing the evolution in a more continuous
fashion, we could apply a linear regression (which is the simplest
model for taking into account the influence of a parameter) and thus estimate the impact of age on the probability of illness:
#+begin_src R :results output graphics :file fig2.svg :exports both :width 4 :height 3 :session *R*
ggplot(df,aes(x=Age,y=Ill)) + geom_point(alpha=.3,size=3) +
theme_bw() + geom_smooth(method="lm")
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig2.svg]]
The blue line is the linear regression in the sense of least squares,
and the grey zone is the 95% confidence interval of this
estimation. In other words, given the dataset and the hypothesis of
linearity, the blue line is the most probable one and there is a 95%
chance that the true line is in the grey zone.
It is, however, clear from the plot that this estimation is
meaningless. A probability must lie between 0 and 1, whereas a linear
regression will inevitably lead to impossible values (negative or
greater than 1) for somewhat extreme age values (young or old). The
reason is simply that a linear regression implies the hypothesis
$\textsf{Ill} = \alpha.\textsf{Age} + \beta + \epsilon$, where
$\alpha$ and $\beta$ are real numbers and $\epsilon$ is a noise (a
random variable of mean zero), with $\alpha$ and $\beta$ estimated
from the data. This doesn't make sense for estimating a probability,
and therefore [[https://en.wikipedia.org/wiki/Logistic_regression][logistic regression]] is a better choice:
#+begin_src R :results output graphics :file fig3.svg :exports both :width 4 :height 3 :session *R*
ggplot(df,aes(x=Age,y=Ill)) + geom_point(alpha=.3,size=3) +
theme_bw() +
geom_smooth(method = "glm",
method.args = list(family = "binomial")) + xlim(20,80)
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig3.svg]]
Here the =ggplot= library does all the computations for us and only
shows the result graphically, but in the Challenger risk analysis we
perform the regression and prediction "by hand" in =R= or =Python=
(depending on the path you have chosen), so that we can inspect the
results in more detail. Like before, the blue line indicates the
estimation of the probability of being ill as a function of age, and
the grey zone informs us about the uncertainty of this estimate, i.e.
given the hypotheses and the dataset, there is a 95% chance for the
true curve to lie somewhere in the grey zone.
In this model, the assumption is $P[\textsf{Ill}] = \pi(\textsf{Age})$
with $\displaystyle\pi(x)=\frac{e^{\alpha.x + \beta}}{1+e^{\alpha.x +
\beta}}$. This at first look strange formulae has the nice property of
always yielding a value between zero and one, and to approach 0 and 1
rapidly as the age tends to $-\infty$ or $+\infty$, but this is not
the only motivation for this choice.
In summary, when we have event-like data (binary) and we wish to
estimate the influence of a parameter on the probability of the event
occurring (illness, failure, ...), the most natural and simple model
is logistic regression. Note that even if we restrain ourselves to a
small part of the data, e.g., only patients less than 50 years old, it
is possible to get a reasonable estimate, even though, as is to be
expected, the uncertainty grows rapidly.
#+begin_src R :results output graphics :file fig4.svg :exports both :width 4 :height 3 :session *R*
ggplot(df[df$Age<50,],aes(x=Age,y=Ill)) + geom_point(alpha=.3,size=3) +
theme_bw() +
geom_smooth(method = "glm",
method.args = list(family = "binomial"),fullrange = TRUE) + xlim(20,80)
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig4.svg]]
* Emacs Setup :noexport:
This document has local variables in its postembule, which should
allow Org-mode (9) to work seamlessly without any setup. If you're
uncomfortable using such variables, you can safely ignore them at
startup. Exporting may require that you copy them in your .emacs.
# Local Variables:
# eval: (add-to-list 'org-latex-packages-alist '("" "minted"))
# eval: (setq org-latex-listings 'minted)
# eval: (setq org-latex-minted-options '(("style" "Tango") ("bgcolor" "Moccasin") ("frame" "lines") ("linenos" "true") ("fontsize" "\\small")))
# eval: (setq org-latex-pdf-process '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
# End:
#+TITLE: Analyse du risque de défaillance des joints toriques de la navette Challenger
#+TITLE: Analysis of the risk of failure of the O-rings of the space shuttle Challenger
#+AUTHOR: Konrad Hinsen, Arnaud Legrand, Christophe Pouzat
#+DATE: Juin 2018
#+LANGUAGE: fr
#+LANGUAGE: en
#+OPTIONS: H:3 creator:nil timestamp:nil skip:nil toc:nil num:t ^:nil ~:~
# #+OPTIONS: author:nil title:nil date:nil
......@@ -17,106 +17,89 @@
#+LATEX_HEADER: \usepackage[T1]{fontenc}
#+LATEX_HEADER: \usepackage{textcomp}
#+LATEX_HEADER: \usepackage[a4paper,margin=.8in]{geometry}
#+LATEX_HEADER: \usepackage[french]{babel}
#+LATEX_HEADER: \usepackage[usenames,dvipsnames,svgnames,table]{xcolor}
#+LATEX_HEADER: \usepackage{palatino}
#+LATEX_HEADER: \usepackage{svg}
#+LATEX_HEADER: \let\epsilon=\varepsilon
*Préambule :* Les explications données dans ce document sur le contexte
de l'étude sont largement reprises de l'excellent livre d'Edward
R. Tufte intitulé /Visual Explanations: Images and Quantities, Evidence
and Narrative/, publié en 1997 par /Graphics Press/ et réédité en 2005,
ainsi que de l'article de Dalal et al. intitulé /Risk Analysis of the
Space Shuttle: Pre-Challenger Prediction of Failure/ et publié en 1989
dans /Journal of the American Statistical Association/.
* Contexte
Dans cette étude, nous vous proposons de revenir sur [[https://fr.wikipedia.org/wiki/Accident_de_la_navette_spatiale_Challenger][l'accident de la
navette spatiale Challenger]]. Le 28 Janvier 1986, 73 secondes après son
lancement, la navette Challenger se désintègre (voir Figure [[fig:photo]])
et entraîne avec elle, les sept astronautes à son bord. Cette
explosion est due à la défaillance des deux joints toriques
assurant l'étanchéité entre les parties hautes et basses des
propulseurs (voir Figure [[fig:oring]]). Ces joints ont perdu de leur
efficacité en raison du froid particulier qui régnait au moment du
lancement. En effet, la température ce matin là était juste en dessous
de 0°C alors que l'ensemble des vols précédents avaient été effectués
à une température d'au moins 7 à 10°C de plus.
*Foreword:* The explanations given in this document about the context
of the study have been taken from the excellent book /Visual
Explanations: Images and Quantities, Evidence and Narrative/ by Edward
R. Tufte, published in 1997 by /Graphics Press/ and re-edited in 2005,
and from the article /Risk Analysis of the Space Shuttle:
Pre-Challenger Prediction of Failure/ by Dalal et al., published in
1989 in the /Journal of the American Statistical Association/.
* Context
In this study, we propose a re-examination of the [[https://en.wikipedia.org/wiki/Space_Shuttle_Challenger_disaster][space shuttle
Challenger disaster]]. On January 28th, 1986, the space shuttle
Challenged exploded 73 seconds after launch (see Figure [[fig:photo]]),
causing the death of the seven astronauts on board. The explosion was
caused by the failure of the two O-ring seals between the upper and
lower parts of the boosters (see Figure [[fig:oring]]). The seals had
lost their efficiency because of the exceptionally cold weather at the
time of launch. The temperature on that morning was just below 0°C,
whereas the preceding flights hat been launched at temperatures at
least 7 to 10°C higher.
#+NAME: fig:photo
#+ATTR_LATEX: :width 10cm
#+CAPTION: Photos de la catastrophe de Challenger.
#+CAPTION: Photographs of the Challenger catastrophe.
file:challenger5.jpg
# #+NAME: fig:photo
# #+ATTR_LATEX: :width 6cm
# #+CAPTION: Photo montage de la catastrophe de Challenger. De gauche à droite, de haut en bas : traînée de fumée après la désintégration de la navette spatiale américaine Challenger 73 secondes après son lancement ; débris d'un propulseur d'appoint à poudre ; joints toriques brûlés, les fautifs de l'accident ; décollage final de Challenger ; cérémonie funéraire tenue par le président Ronald Reagan en hommage aux astronautes ; explosion en vol de Challenger
# file:Challenger_Photo_Montage.jpg
# # From https://upload.wikimedia.org/wikipedia/commons/a/a8/Challenger_Photo_Montage.jpg
#+NAME: fig:oring
#+ATTR_LATEX: :width 10cm
#+CAPTION: Schéma des propulseurs de la navette challenger. Les joints toriques (un joint principale et un joint secondaire) en caoutchouc de plus de 11 mètres de circonférence assurent l'étanchéité entre la partie haute et la partie basse du propulseur.
#+CAPTION: Diagram of the boosters of space shuttle Challenger. The rubber O-ring seals (a principal and a secondary one) of more than 11 meter circumference prevent leaks between the upper and lower parts.
file:o-ring.png
# From https://upload.wikimedia.org/wikipedia/commons/a/a8/Challenger_Photo_Montage.jpg
# From
# https://i0.wp.com/www.kylehailey.com/wp-content/uploads/2014/01/Screen-Shot-2013-12-30-at-12.05.04-PM-1024x679.png?zoom=2&resize=594%2C393
Le plus étonnant est que la cause précise de cet accident avait été
débattue intensément plusieurs jours auparavant et était encore
discutée la veille même du décollage, pendant trois heures de
télé-conférence entre les ingénieurs de la Morton Thiokol
(constructeur des moteurs) et de la NASA. Si la cause immédiate de
l'accident (la défaillance des joints toriques) a rapidement été
identifiée, les raisons plus profondes qui ont conduit à ce désastre
servent régulièrement de cas d'étude, que ce soit dans des cours de
management (organisation du travail, décision technique malgré des
pressions politiques, problèmes de communication), de statistiques
(évaluation du risque, modélisation, visualisation de données), ou de
sociologie (symptôme d'un historique, de la bureaucratie et du
conformisme à des normes organisationnelles).
Dans l'étude que nous vous proposons, nous nous intéressons
principalement à l'aspect statistique mais ce n'est donc qu'une
facette (extrêmement limitée) du problème et nous vous invitons à lire
par vous même les documents donnés en référence dans le
préambule. L'étude qui suit reprend donc une partie des analyses
effectuées cette nuit là et dont l'objectif était d'évaluer
l'influence potentielle de la température et de la pression à laquelle
sont soumis les joints toriques sur leur probabilité de
dysfonctionnement. Pour cela, nous disposons des résultats des
expériences réalisées par les ingénieurs de la NASA durant les 6
années précédant le lancement de la navette Challenger.
Dans le répertoire ~module2/exo5/~ de votre espace =gitlab=, vous
trouverez les données d'origine ainsi qu'une analyse pour chacun des
différents parcours proposés. Cette analyse comporte quatre étapes :
1. Chargement des données
2. Inspection graphique des données
3. Estimation de l'influence de la température
4. Estimation de la probabilité de dysfonctionnement des joints
toriques
Les deux premières étapes ne supposent que des compétences de base en
R ou en Python. La troisième étape suppose une familiarité avec la
régression logistique (généralement abordée en L3 ou M1 de stats,
économétrie, bio-statistique...) et la quatrième étape des bases de
probabilités (niveau lycée). Nous vous présentons donc dans la
prochaine section une introduction à la régression logistique qui ne
s'attarde pas sur les détails du calcul, mais juste sur le sens donné
aux résultats de cette régression.
* Introduction à la régression logistique
Imaginons que l'on dispose des données suivantes qui indiquent pour
une cohorte d'individus s'ils ont déclaré une maladie particulière ou
pas. Je montre ici l'analyse avec R mais le code Python n'est pas forcément
très éloigné. Les données sont stockées dans une data frame dont voici
un bref résumé :
What is most astonishing is that the precise cause of the accident had
been intensely debated several days before and was still under
discussion the day before the launch, during a three-hour
teleconference involving engineers from Morton Thiokol (the supplier
of the engines) and from NASA. Whereas the immediate cause of the
accident, the failure of the O-ring, was quickly identified, the
underlying causes of the disaster have regularly served as a case
study, be it in management training (work organisation, decision
taking in spite of political pressure, communication problems),
statistics (risk evaluation, modelisation, data visualization), or
sociology (history, bureaucracy, conforming to organisational norms).
In the study that we propose, we are mainly concerned with the
statistical aspect, which however is only one piece of the puzzle. We
invite you to read the documents cited in the foreword for more
information. The following study takes up a part of the analyses that
were done that night with the goal of evaluating the potential impact
of temperature and air pressure on the probability of O-ring
malfunction. The starting point is experimental results obtained by
NASA engineers over the six years preceding the Challenger launch.
In the directory ~module2/exo5/~ of your GitLab workspace, you will
find the original data as well as an analysis for each of the paths we
offer. This analysis consists of four steps:
1. Loading the data
2. Visual inspection
3. Estimation of the influence of temperature
4. Estimation of the probability of O-ring malfunction
The first two steps require only a basic knowledge of R or Python. The
third step assumes some familiarity with logistic regression, and the
fourth a basic knowledge of probability. In the next section, we give
an introduction to logistic regression that skips the details of the
computations and focuses instead on the interpretation of the results.
* Introduction to logistic regression
Suppose we have the following dataset that indicates for a group of
people of varying age if they suffer from a specific illness or not. I
will present the analysis in R but Python code would look quite
similar. The data are stored in a data frame that is summarized as:
#+begin_src R :results output :session *R* :exports none
library(Hmisc) # pour calculer un intervalle de confiance sur des données binomiales
library(Hmisc) # to compute a confidence interval on binomial data
library(ggplot2)
library(dplyr)
set.seed(42)
......@@ -125,36 +108,10 @@ proba = function(age) {
return(exp(val)/(1+exp(val)))
}
df = data.frame(Age = runif(400,min=22,max=80))
df$Malade = sapply(df$Age, function(x) rbinom(n=1,size=1,prob=proba(x)))
df$Ill = sapply(df$Age, function(x) rbinom(n=1,size=1,prob=proba(x)))
#+end_src
#+RESULTS:
#+begin_example
Le chargement a nécessité le package : lattice
Le chargement a nécessité le package : survival
Le chargement a nécessité le package : Formula
Le chargement a nécessité le package : ggplot2
Attachement du package : ‘Hmisc’
The following objects are masked from ‘package:base’:
format.pval, units
Attachement du package : ‘dplyr’
The following objects are masked from ‘package:Hmisc’:
src, summarize
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
#+end_example
#+begin_src R :results output :session *R* :exports both
summary(df)
......@@ -163,7 +120,7 @@ str(df)
#+RESULTS:
#+begin_example
Age Malade
Age Ill
Min. :22.01 Min. :0.000
1st Qu.:35.85 1st Qu.:0.000
Median :50.37 Median :1.000
......@@ -171,39 +128,38 @@ str(df)
3rd Qu.:65.37 3rd Qu.:1.000
Max. :79.80 Max. :1.000
'data.frame': 400 obs. of 2 variables:
$ Age : num 75.1 76.4 38.6 70.2 59.2 ...
$ Malade: int 1 1 0 1 1 1 0 0 1 1 ...
$ Age: num 75.1 76.4 38.6 70.2 59.2 ...
$ Ill: int 1 1 0 1 1 1 0 0 1 1 ...
#+end_example
Voici une représentation graphique des données qui permet de mieux
percevoir le lien qu'il peut y avoir entre l'âge et le fait de
contracter cette maladie ou pas :
Here is a plot that provides a better indication of the link that
could exist between age and illness:
#+begin_src R :results output graphics :file fig1.svg :exports both :width 4 :height 3 :session *R*
ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) + theme_bw()
ggplot(df,aes(x=Age,y=Ill)) + geom_point(alpha=.3,size=3) + theme_bw()
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig1.svg]]
Il apparaît clairement sur ces données que plus l'on est âgé, plus la
probabilité de développer cette maladie est importante. Mais comment
estimer cette probabilité à partir uniquement de ces valeurs binaires
(malade/pas malade) ? Pour chaque tranche d'âge (par exemple de 5 ans),
on pourrait regarder la fréquence de la maladie (le code qui suit est
un peu compliqué car le calcul de l'intervalle de confiance pour ce
type de données nécessite un traitement particulier via la fonction
=binconf=).
Clearly the probability of suffering from this illness increases with
age. But how can we estimate this probability based only on this
binary data ill/not ill? For each age slice (of, for example, 5
years), we could look at the frequency of the illness. The following
code is a bit complicated because the computation of the confidence
interval for this kind of data requires a particular treatment using
the function =binconf=.
#+begin_src R :results output graphics :file fig1bis.svg :exports both :width 4 :height 3 :session *R*
age_range=5
df_grouped = df %>% mutate(Age=age_range*(floor(Age/age_range)+.5)) %>%
group_by(Age) %>% summarise(Malade=sum(Malade),N=n()) %>%
group_by(Age) %>% summarise(Ill=sum(Ill),N=n()) %>%
rowwise() %>%
do(data.frame(Age=.$Age, binconf(.$Malade, .$N, alpha=0.05))) %>%
do(data.frame(Age=.$Age, binconf(.$Ill, .$N, alpha=0.05))) %>%
as.data.frame()
ggplot(df_grouped,aes(x=Age)) + geom_point(data=df,aes(y=Malade),alpha=.3,size=3) +
ggplot(df_grouped,aes(x=Age)) + geom_point(data=df,aes(y=Ill),alpha=.3,size=3) +
geom_errorbar(data=df_grouped,
aes(x=Age,ymin=Lower, ymax=Upper, y=PointEst), color="darkred") +
geom_point(data=df_grouped, aes(x=Age, y=PointEst), size=3, shape=21, color="darkred") +
......@@ -214,15 +170,14 @@ ggplot(df_grouped,aes(x=Age)) + geom_point(data=df,aes(y=Malade),alpha=.3,size=3
#+RESULTS:
[[file:fig1bis.svg]]
L'inconvénient de cette approche est que ce calcul est effectué
indépendemment pour chaque tranches d'âges, que la tranche d'âge est
arbitraire, et qu'on n'a pas grande idée de la façon dont ça
évolue. Pour modéliser cette évolution de façon plus continue, on
pourrait tenter une régression linéaire (le modèle le plus simple
possible pour rendre compte de l'influence d'un paramètre) et ainsi
estimer l'effet de l'âge sur la probabilité d'être malade :
A disadvantage of this method is that the computation is done
independently for each age slice, which moreover has been chosen
arbitrarily. For describing the evolution in a more continuous
fashion, we could apply a linear regression (which is the simplest
model for taking into account the influence of a parameter) and thus estimate the impact of age on the probability of illness:
#+begin_src R :results output graphics :file fig2.svg :exports both :width 4 :height 3 :session *R*
ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
ggplot(df,aes(x=Age,y=Ill)) + geom_point(alpha=.3,size=3) +
theme_bw() + geom_smooth(method="lm")
#+end_src
......@@ -230,27 +185,25 @@ ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
#+RESULTS:
[[file:fig2.svg]]
La ligne bleue est la régression linéaire au sens des moindres carrés
et la zone grise est la zone de confiance à 95% de cette
estimation (avec les données dont on dispose et cette hypothèse de
linéarité, la ligne bleue est la plus probable et il y a 95% de chance
que la vraie ligne soit dans cette zone grise).
Mais on voit clairement dans cette représentation graphique que cette
estimation n'a aucun sens. Une probabilité doit être comprise entre 0
et 1 et avec une régression linéaire on arrivera forcément pour des
valeurs un peu extrêmes (jeune ou âgé) à des prédictions aberrantes
(négative ou supérieures à 1). C'est tout simplement dû au fait qu'une
régression linéaire fait l'hypothèse que $\textsf{Malade} =
\alpha.\textsf{Age} + \beta + \epsilon$, où $\alpha$ et $\beta$ sont des nombres réels et $\epsilon$
est un bruit (une variable aléatoire de moyenne nulle), et estime $\alpha$
et $\beta$ à partir des données.
Cette technique n'a pas de sens pour estimer une probabilité et il
convient donc d'utiliser ce que l'on appelle une [[https://fr.wikipedia.org/wiki/R%C3%A9gression_logistique][régression
logistique]] :
The blue line is the linear regression in the sense of least squares,
and the grey zone is the 95% confidence interval of this
estimation. In other words, given the dataset and the hypothesis of
linearity, the blue line is the most probable one and there is a 95%
chance that the true line is in the grey zone.
It is, however, clear from the plot that this estimation is
meaningless. A probability must lie between 0 and 1, whereas a linear
regression will inevitably lead to impossible values (negative or
greater than 1) for somewhat extreme age values (young or old). The
reason is simply that a linear regression implies the hypothesis
$\textsf{Ill} = \alpha.\textsf{Age} + \beta + \epsilon$, where
$\alpha$ and $\beta$ are real numbers and $\epsilon$ is a noise (a
random variable of mean zero), with $\alpha$ and $\beta$ estimated
from the data. This doesn't make sense for estimating a probability,
and therefore [[https://en.wikipedia.org/wiki/Logistic_regression][logistic regression]] is a better choice:
#+begin_src R :results output graphics :file fig3.svg :exports both :width 4 :height 3 :session *R*
ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
ggplot(df,aes(x=Age,y=Ill)) + geom_point(alpha=.3,size=3) +
theme_bw() +
geom_smooth(method = "glm",
method.args = list(family = "binomial")) + xlim(20,80)
......@@ -260,38 +213,33 @@ ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
#+RESULTS:
[[file:fig3.svg]]
Ici, la bibliothèque =ggplot= fait tous les calculs de régression
logistique pour nous et nous montre uniquement le résultat "graphique"
mais dans l'analyse que nous vous proposerons pour Challenger, nous
réalisons la régression et la prédiction à la main (en =R= ou en =Python=
selon le parcours que vous choisirez) de façon à pouvoir effectuer si
besoin une inspection plus fine. Comme avant, la courbe bleue indique
l'estimation de la probabilité d'être malade en fonction de l'âge et
la zone grise nous donne des indications sur l'incertitude de cette
estimation, i.e., "sous ces hypothèses et étant donné le peu de
données qu'on a et leur variabilité, il y a 95% de chances pour que la
vraie courbe se trouve quelque part (n'importe où) dans la zone
grise".
Dans ce modèle, on suppose que $P[\textsf{Malade}] = \pi(\textsf{Age})$ avec
$\displaystyle\pi(x)=\frac{e^{\alpha.x + \beta}}{1+e^{\alpha.x + \beta}}$. Cette
formule (étrange au premier abord) a la bonne propriété de nous donner
systématiquement une valeur comprise entre 0 et 1 et de bien tendre
rapidement vers $0$ quand l'âge tend vers $-\infty$ et vers $1$ quand l'âge
tend vers $+\infty$ (mais ce n'est pas bien sûr pas la seule motivation).
En conclusion, lorsque l'on dispose de données évènementielles
(binaires) et que l'on souhaite estimer l'influence d'un paramètre sur
la probabilité d'occurrence de l'évènement (maladie, défaillance...),
le modèle le plus naturel et le plus simple est celui de la
régression logistique. Notez, que même en se restreignant à une petite
partie des données (par exemple, uniquement les patients de moins de
50 ans), il est possible d'obtenir une estimation assez raisonnable,
même si, comme on pouvait s'y attendre, l'incertitude augmente
singulièrement.
Here the =ggplot= library does all the computations for us and only
shows the result graphically, but in the Challenger risk analysis we
perform the regression and prediction "by hand" in =R= or =Python=
(depending on the path you have chosen), so that we can inspect the
results in more detail. Like before, the blue line indicates the
estimation of the probability of being ill as a function of age, and
the grey zone informs us about the uncertainty of this estimate, i.e.
given the hypotheses and the dataset, there is a 95% chance for the
true curve to lie somewhere in the grey zone.
In this model, the assumption is $P[\textsf{Ill}] = \pi(\textsf{Age})$
with $\displaystyle\pi(x)=\frac{e^{\alpha.x + \beta}}{1+e^{\alpha.x +
\beta}}$. This at first look strange formulae has the nice property of
always yielding a value between zero and one, and to approach 0 and 1
rapidly as the age tends to $-\infty$ or $+\infty$, but this is not
the only motivation for this choice.
In summary, when we have event-like data (binary) and we wish to
estimate the influence of a parameter on the probability of the event
occurring (illness, failure, ...), the most natural and simple model
is logistic regression. Note that even if we restrain ourselves to a
small part of the data, e.g., only patients less than 50 years old, it
is possible to get a reasonable estimate, even though, as is to be
expected, the uncertainty grows rapidly.
#+begin_src R :results output graphics :file fig4.svg :exports both :width 4 :height 3 :session *R*
ggplot(df[df$Age<50,],aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
ggplot(df[df$Age<50,],aes(x=Age,y=Ill)) + geom_point(alpha=.3,size=3) +
theme_bw() +
geom_smooth(method = "glm",
method.args = list(family = "binomial"),fullrange = TRUE) + xlim(20,80)
......
#+TITLE: Analyse du risque de défaillance des joints toriques de la navette Challenger
#+AUTHOR: Konrad Hinsen, Arnaud Legrand, Christophe Pouzat
#+DATE: Juin 2018
#+LANGUAGE: fr
#+OPTIONS: H:3 creator:nil timestamp:nil skip:nil toc:nil num:t ^:nil ~:~
# #+OPTIONS: author:nil title:nil date:nil
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
#+HTML_HEAD: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
#+HTML_HEAD: <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
#+LATEX_HEADER: \usepackage[utf8]{inputenc}
#+LATEX_HEADER: \usepackage[T1]{fontenc}
#+LATEX_HEADER: \usepackage{textcomp}
#+LATEX_HEADER: \usepackage[a4paper,margin=.8in]{geometry}
#+LATEX_HEADER: \usepackage[french]{babel}
#+LATEX_HEADER: \usepackage[usenames,dvipsnames,svgnames,table]{xcolor}
#+LATEX_HEADER: \usepackage{palatino}
#+LATEX_HEADER: \usepackage{svg}
#+LATEX_HEADER: \let\epsilon=\varepsilon
*Préambule :* Les explications données dans ce document sur le contexte
de l'étude sont largement reprises de l'excellent livre d'Edward
R. Tufte intitulé /Visual Explanations: Images and Quantities, Evidence
and Narrative/, publié en 1997 par /Graphics Press/ et réédité en 2005,
ainsi que de l'article de Dalal et al. intitulé /Risk Analysis of the
Space Shuttle: Pre-Challenger Prediction of Failure/ et publié en 1989
dans /Journal of the American Statistical Association/.
* Contexte
Dans cette étude, nous vous proposons de revenir sur [[https://fr.wikipedia.org/wiki/Accident_de_la_navette_spatiale_Challenger][l'accident de la
navette spatiale Challenger]]. Le 28 Janvier 1986, 73 secondes après son
lancement, la navette Challenger se désintègre (voir Figure [[fig:photo]])
et entraîne avec elle, les sept astronautes à son bord. Cette
explosion est due à la défaillance des deux joints toriques
assurant l'étanchéité entre les parties hautes et basses des
propulseurs (voir Figure [[fig:oring]]). Ces joints ont perdu de leur
efficacité en raison du froid particulier qui régnait au moment du
lancement. En effet, la température ce matin là était juste en dessous
de 0°C alors que l'ensemble des vols précédents avaient été effectués
à une température d'au moins 7 à 10°C de plus.
#+NAME: fig:photo
#+ATTR_LATEX: :width 10cm
#+CAPTION: Photos de la catastrophe de Challenger.
file:challenger5.jpg
# #+NAME: fig:photo
# #+ATTR_LATEX: :width 6cm
# #+CAPTION: Photo montage de la catastrophe de Challenger. De gauche à droite, de haut en bas : traînée de fumée après la désintégration de la navette spatiale américaine Challenger 73 secondes après son lancement ; débris d'un propulseur d'appoint à poudre ; joints toriques brûlés, les fautifs de l'accident ; décollage final de Challenger ; cérémonie funéraire tenue par le président Ronald Reagan en hommage aux astronautes ; explosion en vol de Challenger
# file:Challenger_Photo_Montage.jpg
# # From https://upload.wikimedia.org/wikipedia/commons/a/a8/Challenger_Photo_Montage.jpg
#+NAME: fig:oring
#+ATTR_LATEX: :width 10cm
#+CAPTION: Schéma des propulseurs de la navette challenger. Les joints toriques (un joint principale et un joint secondaire) en caoutchouc de plus de 11 mètres de circonférence assurent l'étanchéité entre la partie haute et la partie basse du propulseur.
file:o-ring.png
# From https://upload.wikimedia.org/wikipedia/commons/a/a8/Challenger_Photo_Montage.jpg
# https://i0.wp.com/www.kylehailey.com/wp-content/uploads/2014/01/Screen-Shot-2013-12-30-at-12.05.04-PM-1024x679.png?zoom=2&resize=594%2C393
Le plus étonnant est que la cause précise de cet accident avait été
débattue intensément plusieurs jours auparavant et était encore
discutée la veille même du décollage, pendant trois heures de
télé-conférence entre les ingénieurs de la Morton Thiokol
(constructeur des moteurs) et de la NASA. Si la cause immédiate de
l'accident (la défaillance des joints toriques) a rapidement été
identifiée, les raisons plus profondes qui ont conduit à ce désastre
servent régulièrement de cas d'étude, que ce soit dans des cours de
management (organisation du travail, décision technique malgré des
pressions politiques, problèmes de communication), de statistiques
(évaluation du risque, modélisation, visualisation de données), ou de
sociologie (symptôme d'un historique, de la bureaucratie et du
conformisme à des normes organisationnelles).
Dans l'étude que nous vous proposons, nous nous intéressons
principalement à l'aspect statistique mais ce n'est donc qu'une
facette (extrêmement limitée) du problème et nous vous invitons à lire
par vous même les documents donnés en référence dans le
préambule. L'étude qui suit reprend donc une partie des analyses
effectuées cette nuit là et dont l'objectif était d'évaluer
l'influence potentielle de la température et de la pression à laquelle
sont soumis les joints toriques sur leur probabilité de
dysfonctionnement. Pour cela, nous disposons des résultats des
expériences réalisées par les ingénieurs de la NASA durant les 6
années précédant le lancement de la navette Challenger.
Dans le répertoire ~module2/exo5/~ de votre espace =gitlab=, vous
trouverez les données d'origine ainsi qu'une analyse pour chacun des
différents parcours proposés. Cette analyse comporte quatre étapes :
1. Chargement des données
2. Inspection graphique des données
3. Estimation de l'influence de la température
4. Estimation de la probabilité de dysfonctionnement des joints
toriques
Les deux premières étapes ne supposent que des compétences de base en
R ou en Python. La troisième étape suppose une familiarité avec la
régression logistique (généralement abordée en L3 ou M1 de stats,
économétrie, bio-statistique...) et la quatrième étape des bases de
probabilités (niveau lycée). Nous vous présentons donc dans la
prochaine section une introduction à la régression logistique qui ne
s'attarde pas sur les détails du calcul, mais juste sur le sens donné
aux résultats de cette régression.
* Introduction à la régression logistique
Imaginons que l'on dispose des données suivantes qui indiquent pour
une cohorte d'individus s'ils ont déclaré une maladie particulière ou
pas. Je montre ici l'analyse avec R mais le code Python n'est pas forcément
très éloigné. Les données sont stockées dans une data frame dont voici
un bref résumé :
#+begin_src R :results output :session *R* :exports none
library(Hmisc) # pour calculer un intervalle de confiance sur des données binomiales
library(ggplot2)
library(dplyr)
set.seed(42)
proba = function(age) {
val=(age-50)/4
return(exp(val)/(1+exp(val)))
}
df = data.frame(Age = runif(400,min=22,max=80))
df$Malade = sapply(df$Age, function(x) rbinom(n=1,size=1,prob=proba(x)))
#+end_src
#+RESULTS:
#+begin_example
Le chargement a nécessité le package : lattice
Le chargement a nécessité le package : survival
Le chargement a nécessité le package : Formula
Le chargement a nécessité le package : ggplot2
Attachement du package : ‘Hmisc’
The following objects are masked from ‘package:base’:
format.pval, units
Attachement du package : ‘dplyr’
The following objects are masked from ‘package:Hmisc’:
src, summarize
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
#+end_example
#+begin_src R :results output :session *R* :exports both
summary(df)
str(df)
#+end_src
#+RESULTS:
#+begin_example
Age Malade
Min. :22.01 Min. :0.000
1st Qu.:35.85 1st Qu.:0.000
Median :50.37 Median :1.000
Mean :50.83 Mean :0.515
3rd Qu.:65.37 3rd Qu.:1.000
Max. :79.80 Max. :1.000
'data.frame': 400 obs. of 2 variables:
$ Age : num 75.1 76.4 38.6 70.2 59.2 ...
$ Malade: int 1 1 0 1 1 1 0 0 1 1 ...
#+end_example
Voici une représentation graphique des données qui permet de mieux
percevoir le lien qu'il peut y avoir entre l'âge et le fait de
contracter cette maladie ou pas :
#+begin_src R :results output graphics :file fig1.svg :exports both :width 4 :height 3 :session *R*
ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) + theme_bw()
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig1.svg]]
Il apparaît clairement sur ces données que plus l'on est âgé, plus la
probabilité de développer cette maladie est importante. Mais comment
estimer cette probabilité à partir uniquement de ces valeurs binaires
(malade/pas malade) ? Pour chaque tranche d'âge (par exemple de 5 ans),
on pourrait regarder la fréquence de la maladie (le code qui suit est
un peu compliqué car le calcul de l'intervalle de confiance pour ce
type de données nécessite un traitement particulier via la fonction
=binconf=).
#+begin_src R :results output graphics :file fig1bis.svg :exports both :width 4 :height 3 :session *R*
age_range=5
df_grouped = df %>% mutate(Age=age_range*(floor(Age/age_range)+.5)) %>%
group_by(Age) %>% summarise(Malade=sum(Malade),N=n()) %>%
rowwise() %>%
do(data.frame(Age=.$Age, binconf(.$Malade, .$N, alpha=0.05))) %>%
as.data.frame()
ggplot(df_grouped,aes(x=Age)) + geom_point(data=df,aes(y=Malade),alpha=.3,size=3) +
geom_errorbar(data=df_grouped,
aes(x=Age,ymin=Lower, ymax=Upper, y=PointEst), color="darkred") +
geom_point(data=df_grouped, aes(x=Age, y=PointEst), size=3, shape=21, color="darkred") +
theme_bw()
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig1bis.svg]]
L'inconvénient de cette approche est que ce calcul est effectué
indépendemment pour chaque tranches d'âges, que la tranche d'âge est
arbitraire, et qu'on n'a pas grande idée de la façon dont ça
évolue. Pour modéliser cette évolution de façon plus continue, on
pourrait tenter une régression linéaire (le modèle le plus simple
possible pour rendre compte de l'influence d'un paramètre) et ainsi
estimer l'effet de l'âge sur la probabilité d'être malade :
#+begin_src R :results output graphics :file fig2.svg :exports both :width 4 :height 3 :session *R*
ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
theme_bw() + geom_smooth(method="lm")
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig2.svg]]
La ligne bleue est la régression linéaire au sens des moindres carrés
et la zone grise est la zone de confiance à 95% de cette
estimation (avec les données dont on dispose et cette hypothèse de
linéarité, la ligne bleue est la plus probable et il y a 95% de chance
que la vraie ligne soit dans cette zone grise).
Mais on voit clairement dans cette représentation graphique que cette
estimation n'a aucun sens. Une probabilité doit être comprise entre 0
et 1 et avec une régression linéaire on arrivera forcément pour des
valeurs un peu extrêmes (jeune ou âgé) à des prédictions aberrantes
(négative ou supérieures à 1). C'est tout simplement dû au fait qu'une
régression linéaire fait l'hypothèse que $\textsf{Malade} =
\alpha.\textsf{Age} + \beta + \epsilon$, où $\alpha$ et $\beta$ sont des nombres réels et $\epsilon$
est un bruit (une variable aléatoire de moyenne nulle), et estime $\alpha$
et $\beta$ à partir des données.
Cette technique n'a pas de sens pour estimer une probabilité et il
convient donc d'utiliser ce que l'on appelle une [[https://fr.wikipedia.org/wiki/R%C3%A9gression_logistique][régression
logistique]] :
#+begin_src R :results output graphics :file fig3.svg :exports both :width 4 :height 3 :session *R*
ggplot(df,aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
theme_bw() +
geom_smooth(method = "glm",
method.args = list(family = "binomial")) + xlim(20,80)
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig3.svg]]
Ici, la bibliothèque =ggplot= fait tous les calculs de régression
logistique pour nous et nous montre uniquement le résultat "graphique"
mais dans l'analyse que nous vous proposerons pour Challenger, nous
réalisons la régression et la prédiction à la main (en =R= ou en =Python=
selon le parcours que vous choisirez) de façon à pouvoir effectuer si
besoin une inspection plus fine. Comme avant, la courbe bleue indique
l'estimation de la probabilité d'être malade en fonction de l'âge et
la zone grise nous donne des indications sur l'incertitude de cette
estimation, i.e., "sous ces hypothèses et étant donné le peu de
données qu'on a et leur variabilité, il y a 95% de chances pour que la
vraie courbe se trouve quelque part (n'importe où) dans la zone
grise".
Dans ce modèle, on suppose que $P[\textsf{Malade}] = \pi(\textsf{Age})$ avec
$\displaystyle\pi(x)=\frac{e^{\alpha.x + \beta}}{1+e^{\alpha.x + \beta}}$. Cette
formule (étrange au premier abord) a la bonne propriété de nous donner
systématiquement une valeur comprise entre 0 et 1 et de bien tendre
rapidement vers $0$ quand l'âge tend vers $-\infty$ et vers $1$ quand l'âge
tend vers $+\infty$ (mais ce n'est pas bien sûr pas la seule motivation).
En conclusion, lorsque l'on dispose de données évènementielles
(binaires) et que l'on souhaite estimer l'influence d'un paramètre sur
la probabilité d'occurrence de l'évènement (maladie, défaillance...),
le modèle le plus naturel et le plus simple est celui de la
régression logistique. Notez, que même en se restreignant à une petite
partie des données (par exemple, uniquement les patients de moins de
50 ans), il est possible d'obtenir une estimation assez raisonnable,
même si, comme on pouvait s'y attendre, l'incertitude augmente
singulièrement.
#+begin_src R :results output graphics :file fig4.svg :exports both :width 4 :height 3 :session *R*
ggplot(df[df$Age<50,],aes(x=Age,y=Malade)) + geom_point(alpha=.3,size=3) +
theme_bw() +
geom_smooth(method = "glm",
method.args = list(family = "binomial"),fullrange = TRUE) + xlim(20,80)
#+end_src
#+ATTR_LATEX: :width 8cm
#+RESULTS:
[[file:fig4.svg]]
* Emacs Setup :noexport:
This document has local variables in its postembule, which should
allow Org-mode (9) to work seamlessly without any setup. If you're
uncomfortable using such variables, you can safely ignore them at
startup. Exporting may require that you copy them in your .emacs.
# Local Variables:
# eval: (add-to-list 'org-latex-packages-alist '("" "minted"))
# eval: (setq org-latex-listings 'minted)
# eval: (setq org-latex-minted-options '(("style" "Tango") ("bgcolor" "Moccasin") ("frame" "lines") ("linenos" "true") ("fontsize" "\\small")))
# eval: (setq org-latex-pdf-process '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
# End:
#+TITLE: Analysis of the risk of failure of the O-rings on the Challenger shuttle
#+TITLE: Analyse du risque de défaillance des joints toriques de la navette Challenger
#+AUTHOR: Arnaud Legrand
#+LANGUAGE: fr
......@@ -14,26 +14,29 @@
# #+PROPERTY: header-args :session :exports both
On January 27, 1986, the day before the takeoff of the shuttle /Challenger/, had
a three-hour teleconference was held between
Morton Thiokol (the manufacturer of one of the engines) and NASA. The
discussion focused on the consequences of the
temperature at take-off of 31°F (just below
0°C) for the success of the flight and in particular on the performance of the
O-rings used in the engines. Indeed, no test
had been performed at this temperature.
The following study takes up some of the analyses carried out that
night with the objective of assessing the potential influence of
the temperature and pressure to which the O-rings are subjected
on their probability of malfunction. Our starting point is
the results of the experiments carried out by NASA engineers
during the six years preceding the launch of the shuttle
Le 27 Janvier 1986, veille du décollage de la navette /Challenger/, eu
lieu une télé-conférence de trois heures entre les ingénieurs de la
Morton Thiokol (constructeur d'un des moteurs) et de la NASA. La
discussion portait principalement sur les conséquences de la
température prévue au moment du décollage de 31°F (juste en dessous de
0°C) sur le succès du vol et en particulier sur la performance des
joints toriques utilisés dans les moteurs. En effet, aucun test
n'avait été effectué à cette température.
L'étude qui suit reprend donc une partie des analyses effectuées cette
nuit là et dont l'objectif était d'évaluer l'influence potentielle de
la température et de la pression à laquelle sont soumis les joints
toriques sur leur probabilité de dysfonctionnement. Pour cela, nous
disposons des résultats des expériences réalisées par les ingénieurs
de la NASA durant les 6 années précédant le lancement de la navette
Challenger.
* Loading the data
We start by loading this data:
#+begin_src python :results value :session *python* :exports both
* Première analyse
** Chargement des données
Nous commençons donc par charger ces données:
#+begin_src python :results value :session first :exports both
import numpy as np
import pandas as pd
data = pd.read_csv("shuttle.csv")
......@@ -60,7 +63,7 @@ data
14 4/12/85 6 67 200 0
15 4/29/85 6 75 200 0
16 6/17/85 6 70 200 0
17 7/2903/85 6 81 200 0
17 7/29/85 6 81 200 0
18 8/27/85 6 76 200 0
19 10/03/85 6 79 200 0
20 10/30/85 6 75 200 2
......@@ -68,17 +71,18 @@ data
22 1/12/86 6 58 200 1
#+end_example
The data set shows us the date of each test, the number of O-rings
(there are 6 on the main launcher), the
temperature (in Fahrenheit) and pressure (in psi), and finally the
number of identified malfunctions.
Le jeu de données nous indique la date de l'essai, le nombre de joints
toriques mesurés (il y en a 6 sur le lançeur principal), la
température (en Fahrenheit) et la pression (en psi), et enfin le
nombre de dysfonctionnements relevés.
* Graphical inspection
Flights without incidents do not provide any information
on the influence of temperature or pressure on malfunction.
We thus focus on the experiments in which at least one O-ring was defective.
** Inspection graphique des données
Les vols où aucun incident n'est relevé n'apportant aucune information
sur l'influence de la température ou de la pression sur les
dysfonctionnements, nous nous concentrons sur les expériences où au
moins un joint a été défectueux.
#+begin_src python :results value :session *python* :exports both
#+begin_src python :results value :session first :exports both
data = data[data.Malfunction>0]
data
#+end_src
......@@ -93,12 +97,12 @@ data
: 20 10/30/85 6 75 200 2
: 22 1/12/86 6 58 200 1
We have a high temperature variability but
the pressure is almost always 200, which should
simplify the analysis.
Très bien, nous avons une variabilité de température importante mais
la pression est quasiment toujours égale à 200, ce qui devrait
simplifier l'analyse.
How does the frequency of failure vary with temperature?
#+begin_src python :results output file :var matplot_lib_filename="freq_temp_python.png" :exports both :session *python*
Comment la fréquence d'échecs varie-t-elle avec la température ?
#+begin_src python :results output file :var matplot_lib_filename="freq_temp_python.png" :exports both :session first
import matplotlib.pyplot as plt
plt.clf()
......@@ -113,20 +117,21 @@ print(matplot_lib_filename)
#+RESULTS:
[[file:freq_temp_python.png]]
At first glance, the dependence does not look very important, but let's try to
estimate the impact of temperature $t$ on the probability of O-ring malfunction.
À première vue, ce n'est pas flagrant mais bon, essayons quand même
d'estimer l'impact de la température $t$ sur la probabilité de
dysfonctionnements d'un joint.
* Estimation of the temperature influence
** Estimation de l'influence de la température
Suppose that each of the six O-rings is damaged with the same
probability and independently of the others and that this probability
depends only on the temperature. If $p(t)$ is this probability, the
number $D$ of malfunctioning O-rings during a flight at
temperature $t$ follows a binomial law with parameters $n=6$ and
$p=p(t)$. To link $p(t)$ to $t$, we will therefore perform a
logistic regression.
Supposons que chacun des 6 joints toriques est endommagé avec la même
probabilité et indépendamment des autres et que cette probabilité ne
dépend que de la température. Si on note $p(t)$ cette probabilité, le
nombre de joints $D$ dysfonctionnant lorsque l'on effectue le vol à
température $t$ suit une loi binomiale de paramètre $n=6$ et
$p=p(t)$. Pour relier $p(t)$ à $t$, on va donc effectuer une
régression logistique.
#+begin_src python :results value :session *python* :exports both
#+begin_src python :results value :session first :exports both
import statsmodels.api as sm
data["Success"]=data.Count-data.Malfunction
......@@ -159,21 +164,21 @@ Temperature 0.0014 0.122 0.012 0.991 -0.238 0.240
===============================================================================
#+end_example
The most likely estimator of the temperature parameter is 0.0014
and the standard error of this estimator is 0.122, in other words we
cannot distinguish any particular impact and we must take our
estimates with caution.
L'estimateur le plus probable du paramètre de température est 0.0014
et l'erreur standard de cet estimateur est de 0.122, autrement dit on
ne peut pas distinguer d'impact particulier et il faut prendre nos
estimations avec des pincettes.
* Estimation of the probability of O-ring malfunction
The expected temperature on the take-off day is 31°F. Let's try to
estimate the probability of O-ring malfunction at
this temperature from the model we just built:
** Estimation de la probabilité de dysfonctionnant des joints toriques
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 first
import matplotlib.pyplot as plt
data_pred = pd.DataFrame({'Temperature': np.linspace(start=30, stop=90, num=121), 'Intercept': 1})
data_pred['Frequency'] = logmodel.predict(data_pred)
data_pred['Frequency'] = logmodel.predict(data_pred[['Intercept','Temperature']])
data_pred.plot(x="Temperature",y="Frequency",kind="line",ylim=[0,1])
plt.scatter(x=data["Temperature"],y=data["Frequency"])
plt.grid(True)
......@@ -185,12 +190,14 @@ print(matplot_lib_filename)
#+RESULTS:
[[file:proba_estimate_python.png]]
As expected from the initial data, the
temperature has no significant impact on the probability of failure of the
O-rings. It will be about 0.2, as in the tests
where we had a failure of at least one joint. Let's get back to the initial dataset to estimate the probability of failure:
Comme on pouvait s'attendre au vu des données initiales, la
température n'a pas d'impact notable sur la probabilité d'échec des
joints toriques. Elle sera d'environ 0.2, comme dans les essais
précédents où nous il y a eu défaillance d'au moins un joint. Revenons
à l'ensemble des données initiales pour estimer la probabilité de
défaillance d'un joint:
#+begin_src python :results output :session *python* :exports both
#+begin_src python :results output :session first :exports both
data = pd.read_csv("shuttle.csv")
print(np.sum(data.Malfunction)/np.sum(data.Count))
#+end_src
......@@ -198,20 +205,236 @@ print(np.sum(data.Malfunction)/np.sum(data.Count))
#+RESULTS:
: 0.06521739130434782
This probability is thus about $p=0.065$. Knowing that there is
a primary and a secondary O-ring on each of the three parts of the
launcher, the probability of failure of both joints of a launcher
is $p^2 \approx 0.00425$. The probability of failure of any one of the
launchers is $1-(1-p^2)^3 \approximately 1.2%$. That would really be
bad luck.... Everything is under control, so the takeoff can happen
tomorrow as planned.
But the next day, the Challenger shuttle exploded and took away
with her the seven crew members. The public was shocked and in
the subsequent investigation, the reliability of the
O-rings was questioned. Beyond the internal communication problems
of NASA, which have a lot to do with this fiasco, the previous analysis
includes (at least) a small problem.... Can you find it?
You are free to modify this analysis and to look at this dataset
from all angles in order to to explain what's wrong.
Cette probabilité est donc d'environ $p=0.065$, sachant qu'il existe
un joint primaire un joint secondaire sur chacune des trois parties du
lançeur, la probabilité de défaillance des deux joints d'un lançeur
est de $p^2 \approx 0.00425$. La probabilité de défaillance d'un des
lançeur est donc de $1-(1-p^2)^3 \approx 1.2%$. Ça serait vraiment
pas de chance... Tout est sous contrôle, le décollage peut donc avoir
lieu demain comme prévu.
Seulement, le lendemain, la navette Challenger explosera et emportera
avec elle ses sept membres d'équipages. L'opinion publique est
fortement touchée et lors de l'enquête qui suivra, la fiabilité des
joints toriques sera directement mise en cause. Au delà des problèmes
de communication interne à la NASA qui sont pour beaucoup dans ce
fiasco, l'analyse précédente comporte (au moins) un petit
problème... Saurez-vous le trouver ? Vous êtes libre de modifier cette
analyse et de regarder ce jeu de données sous tous les angles afin
d'expliquer ce qui ne va pas.
* Nouvelle analyse
Nous commençons donc par charger ces données:
#+begin_src python :results value :session second :exports both
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
data = pd.read_csv("shuttle.csv")
data
#+end_src
#+RESULTS:
#+begin_example
Date Count Temperature Pressure Malfunction
0 4/12/81 6 66 50 0
1 11/12/81 6 70 50 1
2 3/22/82 6 69 50 0
3 11/11/82 6 68 50 0
4 4/04/83 6 67 50 0
5 6/18/82 6 72 50 0
6 8/30/83 6 73 100 0
7 11/28/83 6 70 100 0
8 2/03/84 6 57 200 1
9 4/06/84 6 63 200 1
10 8/30/84 6 70 200 1
11 10/05/84 6 78 200 0
12 11/08/84 6 67 200 0
13 1/24/85 6 53 200 2
14 4/12/85 6 67 200 0
15 4/29/85 6 75 200 0
16 6/17/85 6 70 200 0
17 7/29/85 6 81 200 0
18 8/27/85 6 76 200 0
19 10/03/85 6 79 200 0
20 10/30/85 6 75 200 2
21 11/26/85 6 76 200 0
22 1/12/86 6 58 200 1
#+end_example
Tracons, pour ces 3 jeux de données, le nombre de Malfunction en fonction de la température sur le même graphique, une couleur par pression. On le nomme "P_temp_python.png".
#+begin_src python :results output file :var matplot_lib_filename="P_temp_python.png" :exports both :session second
dataP50 = data[data.Pressure==50]
dataP100 = data[data.Pressure==100]
dataP200 = data[data.Pressure==200]
plt.clf()
dataP50.plot(x="Temperature",y="Malfunction",kind="scatter",ylim=[-1,6],color='blue')
dataP100.plot(x="Temperature",y="Malfunction",kind="scatter",ylim=[-1,6],color='red',ax=plt.gca())
dataP200.plot(x="Temperature",y="Malfunction",kind="scatter",ylim=[-1,6],color='green',ax=plt.gca())
plt.grid(True)
plt.savefig(matplot_lib_filename)
print(matplot_lib_filename)
#+end_src
#+RESULTS:
[[file:P_temp_python.png]]
** Regression logistique
Nous allons maintenant effectuer 4 régressions logistiques
*** Régression logistique sur les données P50
#+begin_src python :results value :session second :exports both
# Filtrer les données et créer une copie
dataP50 = data[data.Pressure == 50].copy()
# Calcul des colonnes nécessaires
dataP50["Success"] = dataP50["Count"] - dataP50["Malfunction"]
dataP50["Intercept"] = 1
# Création du modèle avec une instance de sm.families.links.Logit()
logmodelP50 = sm.GLM(
dataP50['Malfunction'],
dataP50[['Intercept', 'Temperature']],
family=sm.families.Binomial(link=sm.families.links.Logit())
).fit()
# Résumé du modèle
logmodelP50.summary()
# Générer des données pour la prédiction (de 25 à 90)
data_pred50 = pd.DataFrame({
'Temperature': np.linspace(25, 90, 100),
'Intercept': 1
})
# Ajouter les prédictions au DataFrame
data_pred50['Malfunction_Prob'] = logmodelP50.predict(data_pred50[['Intercept', 'Temperature']])
# Tracer les points observés
plt.figure() # Nouvelle figure
plt.scatter(dataP50['Temperature'], dataP50['Malfunction'], color='blue', label='Observations')
# Tracer la courbe de régression logistique
plt.plot(data_pred50['Temperature'], data_pred50['Malfunction_Prob'], color='red', label='Régression logistique')
# Ajouter des labels et une légende
plt.xlabel('Température')
plt.ylabel('Probabilité de dysfonctionnement')
plt.title('Régression logistique sur les données P50')
plt.legend()
plt.grid(True)
# Créer une image regression_logistique_P50.png
plt.savefig("regression_logistique_P50.png")
print("regression_logistique_P50.png")
#+end_src
#+RESULTS:
[[file:regression_logistique_P50.png]]
*** Régression logistique sur les données P200
#+begin_src python :results value :session second :exports both
#+begin_src python :results value :session second :exports both
# Filtrer les données et créer une copie
dataP200 = data[data.Pressure == 200].copy()
# Calcul des colonnes nécessaires
dataP200["Success"] = dataP200["Count"] - dataP200["Malfunction"]
dataP200["Intercept"] = 1
dataP200["Proportion"] = dataP200["Malfunction"] / dataP200["Count"]
# Création du modèle avec une instance de sm.families.links.Logit()
logmodelP200 = sm.GLM(
dataP200['Proportion'],
dataP200[['Intercept', 'Temperature']],
family=sm.families.Binomial(link=sm.families.links.Logit())
).fit()
# Résumé du modèle
logmodelP200.summary()
# Générer des données pour la prédiction (de 25 à 90)
data_pred200 = pd.DataFrame({
'Temperature': np.linspace(25, 90, 100),
'Intercept': 1
})
data_pred200['Proportion_Pred'] = logmodelP200.predict(data_pred200[['Intercept', 'Temperature']])
# Tracer les points observés
plt.figure() # Nouvelle figure
plt.scatter(dataP200['Temperature'], dataP200['Proportion'], color='blue', label='Observations')
# Tracer la courbe de régression logistique
plt.plot(data_pred200['Temperature'], data_pred200['Proportion_Pred'], color='red', label='Régression logistique')
# Ajouter des labels et une légende
plt.xlabel('Température')
plt.ylabel('Proportion de dysfonctionnements')
plt.title('Régression logistique sur les données P200')
plt.legend()
plt.grid(True)
# Créer une image regression_logistique_P200.png
plt.savefig("regression_logistique_P200.png")
print("regression_logistique_P200.png")
#+end_src
*** Régression logistique sur toutes données
#+begin_src python :results value :session second :exports both
# Filtrer les données et créer une copie
dataAll = data.copy()
# Calcul des colonnes nécessaires
dataAll["Success"] = dataAll["Count"] - dataAll["Malfunction"]
dataAll["Intercept"] = 1
# Création du modèle avec une instance de sm.families.links.Logit()
logmodelAll = sm.GLM(
dataAll['Malfunction'],
dataAll[['Intercept', 'Temperature']],
family=sm.families.Binomial(link=sm.families.links.Logit())
).fit()
# Résumé du modèle
logmodelAll.summary()
# Générer des données pour la prédiction (de 25 à 90)
data_predAll = pd.DataFrame({
'Temperature': np.linspace(25, 90, 100),
'Intercept': 1
})
# Ajouter les prédictions au DataFrame
data_predAll['Malfunction_Prob'] = logmodelAll.predict(data_predAll[['Intercept', 'Temperature']])
# Tracer les points observés
plt.figure() # Nouvelle figure
plt.scatter(dataAll['Temperature'], dataAll['Malfunction'], color='blue', label='Observations')
# Tracer la courbe de régression logistique
plt.plot(data_predAll['Temperature'], data_predAll['Malfunction_Prob'], color='red', label='Régression logistique')
# Ajouter des labels et une légende
plt.xlabel('Température')
plt.ylabel('Probabilité de dysfonctionnement')
plt.title('Régression logistique sur toutes les données')
# Ajouter une légende
plt.legend()
# Créer une image regression_logistique_All.png
plt.savefig("regression_logistique_All.png")
print("regression_logistique_All.png")
#+end_src
#+RESULTS:
[[file:regression_logistique_All.png]]
all: gitlab.html emacs_orgmode.html jupyter.html rstudio.html maintaining_a_journal.html
ressources-md: emacs_orgmode.md emacs_orgmode_fr.md jupyter.md jupyter_fr.md maintaining_a_journal.md maintaining_a_journal_fr.md gitlab.md gitlab_fr.md rstudio.md rstudio_fr.md orgmode_examples/README.md orgmode_examples/README_fr.md
NLINES=10000000
include ../../Makefile.ressources
%.html: %.org
emacs -batch $^ --funcall org-html-export-to-html
sed -i -e 's/<pre /<pre style="padding-left: 30px; background-color: #f6f8fa;" /g' \
-e 's/<li>/<li style="margin-bottom:0;">/g' \
-e 's/<ul>/<ul style="margin:0 0;">/g' $@
mv $@ $@.bak
html_png_inliner.pl < $@.bak | grep -A $(NLINES) -e '<body>' | grep -B $(NLINES) -e '<div id="postamble" class="status">' | grep -v -e '<body>' -e '<div id="postamble" class="status">' > $@
rm $@.bak
clean:
rm -f *~
# -*- mode: org -*-
#+TITLE: Perform a Merge/Request in Gitlab to update your mooc-rr repository
#+AUTHOR: Laurence Farhi
#+DATE: April, 2019
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
This document explains how to retrieve from your GitLab repository the resource changes required for the exercise5 of Module 2.
To do this, we ask you to validate a Merge request with all the modifications made by Konrad, following the procedure below.
Go to your Gitlab workspace, from the page [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5571950188c946e790f06d4bc90fb5f6]["Your Gitlab space"]]
Follow the instructions below.
[[file:MergeRequest_images/MergeRequest1.png]]
You can see that there is a request for Merge pending.
[[file:MergeRequest_images/MergeRequest2.png]]
Select the Merge request.
[[file:MergeRequest_images/MergeRequest3.png]]
If you have meanwhile modified one of the files, Gitlab will warn you that there is a conflict (grey button with "!'') and will propose you to do the merge manually. Let you be guided...
If you go to mooc-rr/module2/exo5, you should see that 4 files have been modified.
[[file:MergeRequest_images/MergeRequest4.png]]
Then, if you follow the Jupyter path, you must also apply the changes in your Jupyter space.
To do this, go to your Jupyter space, from [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5310b948b605466d95b47e0676cf1069]["exercice 5 of Module 2"]]
(bouton "Read the analysis").
Make a "Git pull" to update your Jupiter space.
[[file:MergeRequest_images/MergeRequest5.png]]
When you read the notebook again (reload it), you should see the following change:
[[file:MergeRequest_images/MergeRequest6.png]]
# -*- mode: org -*-
#+TITLE: Faire un Merge/Request dans Gitlab pour mettre à jour son espace de travail mooc-rr
#+AUTHOR: Laurence Farhi
#+DATE: April, 2019
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
Ce document vous explique comment récupérer dans votre entrepôt GitLab les modifications des ressources nécessaires pour l'exercice5 du module 2.
Pour cela, nous vous demandons de valider une demande de "Merge request" avec toutes les modifications effectuées par Konrad, en suivant la procédure ci-dessous.
Rendez-vous sur votre espace Gitlab, depuis la page [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5571950188c946e790f06d4bc90fb5f6]["Votre espace Gitlab"]]
Suivez les indications ci dessous.
[[file:MergeRequest_images/MergeRequest1.png]]
Vous voyez qu'il y a une demande de Merge en attente.
[[file:MergeRequest_images/MergeRequest2.png]]
Sélectionnez la demande de Merge.
[[file:MergeRequest_images/MergeRequest3.png]]
Si vous aviez entretemps modifié un des fichiers, Gitlab vous avertira qu’il y a un conflit (bouton gris avec ‘!’) et vous proposera de faire le merge manuellement. Laissez-vous guider …
Si vous allez sur mooc-rr/module2/exo5, vous devez voir que 4 fichiers ont été modifiés.
[[file:MergeRequest_images/MergeRequest4.png]]
Ensuite, si vous suivez le parcours Jupyter, il faut aussi répercuter les modifications dans votre espace Jupyter.
Pour cela, rendez-vous sur votre espace Jupyter, depuis [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5310b948b605466d95b47e0676cf1069]["l'exercice 5 du Module 2"]]
(bouton "Lire l'analyse").
Faites un "Git pull" pour mettre à jour votre espace Jupiter.
[[file:MergeRequest_images/MergeRequest5.png]]
Quand vous lisez à nouveau le notebook (quittez la page et rechargez), vous devez voir la modification suivante :
[[file:MergeRequest_images/MergeRequest6.png]]
# -*- coding: utf-8 -*-
# -*- mode: org -*-
#+TITLE: Galerie de Notebooks
#+AUTHOR: Laurence Farhi
#+STARTUP: overview indent inlineimages logdrawer
#+LANGUAGE: fr
Voici un document qui recense quelques documents computationnels
"remarquables" dans toutes les disciplines et tous les domaines.
* Table of Contents :TOC:
- [[#notebooks-jupyter][Notebooks Jupyter]]
- [[#notebooks-rstudio][Notebooks RStudio]]
- [[#notebooks-org-mode][Notebooks Org-mode]]
* Notebooks Jupyter
- [[https://github.com/norvig/pytudes/blob/master/ipynb/Economics.ipynb][Simulation d'un marché économique]], Peter Norvig (github @norvig)
- [[https://github.com/mikhailklassen/Mining-the-Social-Web-3rd-Edition][Un complément exécutable (Python/Jupyter) pour le livre "Mining the Social Web", (O'Reilly, 2019)]], Mikhail Klassen (github @mikhailklassen)
- [[http://darribas.org/gds19][Des supports de cours ("Geographic Data Science") avec des notebooks
Jupyter]], (voir sous "labs"), Dr. Dani Arribas-Bel, Automne 2019 à
l'Université de Liverpool.
- [[https://github.com/lesteve/euroscipy-2019-scikit-learn-tutorial/tree/master/notebooks][EuroSciPy 2019 - scikit-learn tutorial]], Olivier Grisel (github
@ogrisel)
- [[https://github.com/jupyter/jupyter/wiki/A-gallery-of-interesting-Jupyter-Notebooks][A gallery of interesting Jupyter Notebooks]] :
un entrepôt github qui regroupe de nombreux notebooks Jupyter tous domaines
* Notebooks RStudio
- [[http://rpubs.com/alegrand/46031][Images Panini]], Arnaud Legrand
- [[http://rpubs.com/alegrand/224732][Les yeux bleus]], Arnaud Legrand
- [[https://gitlab.com/c_pouzat/etudes-de-cas-m1/blob/master/TriDesPA][Enregistrements extracellulaires et le tri des potentiel d'action :
supports de cours et les codes associés]] ([[https://gitlab.com/c_pouzat/etudes-de-cas-m1/blob/master/TriDesPA/Pouzat_TriDesPA_20190128.pdf][Pdf]]), Christophe Pouzat (github @c_pouzat)
- [[https://gitlab.com/c_pouzat/etudes-de-cas-m1/blob/master/FluoCalcium][Mesures de concentrations calciques au moyen de sondes
fluorescentes : supports de cours et les codes associés]] ([[https://gitlab.com/c_pouzat/etudes-de-cas-m1/blob/master/FluoCalcium/Pouzat_FluoCalcium_20180309.pdf][Pdf]]), Christophe
Pouzat (gitlab @c_pouzat)
- [[https://github.com/christophe-pouzat/YRLS2017][YRLS2017: R for statistics and reproducible research in the life
sciences]] ([[http://htmlpreview.github.io/?https://github.com/christophe-pouzat/YRLS2017/blob/master/Pouzat_YRLS_RR_20170516.html][Html]]), Christophe Pouzat (github @christophe-pouzat)
* Notebooks Org-mode
- [[https://gitlab.com/c_pouzat/etudes-de-cas-m1/blob/master/TriDesPA/Pouzat_TriDesPA_20190128.org][Enregistrements extracellulaires et le tri des potentiel d'action :
supports de cours et les codes associés]] ([[https://gitlab.com/c_pouzat/etudes-de-cas-m1/blob/master/TriDesPA/Pouzat_TriDesPA_20190128.pdf][Pdf]]), Christophe Pouzat (github @c_pouzat)
- [[https://gitlab.com/c_pouzat/etudes-de-cas-m1/blob/master/FluoCalcium/Pouzat_FluoCalcium_20180309.org][Mesures de concentrations calciques au moyen de sondes
fluorescentes : supports de cours et les codes associés]] ([[https://gitlab.com/c_pouzat/etudes-de-cas-m1/blob/master/FluoCalcium/Pouzat_FluoCalcium_20180309.pdf][Pdf]]), Christophe
Pouzat (gitlab @c_pouzat)
- [[https://github.com/jkitchin/dft-book][Un livre de chimie théorique écrit en Org-Mode]] ([[https://github.com/jkitchin/dft-book/raw/master/dft.pdf][Pdf version of the book]]), John Kitchin (github @jkitchin).
- [[https://plmlab.math.cnrs.fr/xtof/interacting_neurons_with_stp/blob/master/interacting_neurons_with_stp.org][A system of interacting neurons with short term plasticity]], (org
avec du C, gnuplot, shell) ([[https://plmlab.math.cnrs.fr/xtof/interacting_neurons_with_stp/blob/master/interacting_neurons_with_stp.Pdf][Pdf]]), Christophe Pouzat
- [[https://hal.archives-ouvertes.fr/hal-01224765][Supplementary Material for: Homogeneity and identity tests for unidimensional Poisson processes with an application to neurophysiological peri-stimulus time histograms--R version]], (org
avec R), ([[https://hal.archives-ouvertes.fr/hal-01224765/document][Pdf]]), Christophe Pouzat
- [[https://hal.archives-ouvertes.fr/hal-01224764][Supplementary Material for: Homogeneity and identity tests for unidimensional Poisson processes with an application to neurophysiological peri-stimulus time histograms--Python version]],
(org avec Python, mais les mêmes calculs que le précédent),([[https://hal.archives-ouvertes.fr/hal-01224764/document][Pdf]]), Christophe Pouzat
- [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/tree/master/module2/ressources/sequence6_examples][Les documents montrés en exemple dans les vidéos du MOOC]]
# -*- mode: org -*-
#+TITLE: First steps with Emacs/org-mode
#+DATE: March 2019
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
This document assumes you have installed emacs as explained [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/954f94ce4f9a4d858d47b41793cc96c8][here]]. All
the screenshots in this demo are done under the Windows operating
system but similar results should be obtained on any OS.
* First steps with Emacs as a computationnal environment
** A first org-mode document
- Launch emacs
#+BEGIN_CENTER
[[file:emacs_orgmode_images/emacs.png]]
#+END_CENTER
- Create a new file using the "white sheet of paper" left icon, right
below the =File= menu. Name it =foo.org= in which ever directory you
want.
** Running dos/shell commands
- You now have a blank org-mode file.
- Type =<b= and press the =tab= key to expend it as the beginning of a
shell block. You can then type whichever command you want (e.g., =dir=
under windows or =ls= under linux or Mac). By typing =C-c C-c= (this
means typing twice =Ctrl= =c=), your shell command should be executed
and the output should but put right below.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/shell.png]]
#+END_CENTER
- Whenever you feel emacs has entered a weird state and you want to
exit from this mode, press =C-g= (again, this reads as =Ctrl= =g=) several
times.
** Running R code
- Similarly to the abovementionned =<b= shortcut, the shortcut =<r= + =tab=
will allow you to create a block for running R commands (e.g.,
=summary(cars)=). Likewise, the code will be executed by typing =C-c
C-c= (typing twice =Ctrl= =c=)
#+BEGIN_CENTER
[[file:emacs_orgmode_images/commandeR1.png]]
#+END_CENTER
At this point, Emacs will prompt you to ask where R should be
launched. Simply keep the current directory by hitting the =Return=
key. Again, the output is captured and inserted right below.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/commandeR2.png]]
#+END_CENTER
- The =<R= + =tab= shortcut will allow you to run R commands that generate
graphics. The =(org-babel-temp-file \"figure\" \".png\")= generates a
temporary file name. It will thus be erased when closing emacs. If
you want the image to be persistant, indicate a real file name instead.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/graphiqueR.png]]
#+END_CENTER
If you do not like this behavior, you can edit the =init.el= file and
replace =(org-babel-temp-file \"figure\" \".png\")= by
=\"D:/temp/figure.png\"= or whichever location/name you prefer (both
for =<R= and =<PP=).
** Running Python code
- You may want to read the [[https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-python.html][Python Source Code Blocks in Org Mode]]
webpage for more examples
- The =<p= + =tab= will insert a Python block in a /non-session/ mode. This
means that a new Python shell will be started for this block and
that variables will not be shared between blocks. Again, the code
is executed with the =C-c C-c= shortcut.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/commande_python.png]]
#+END_CENTER
#+BEGIN_CENTER
[[file:emacs_orgmode_images/python1.png]]
#+END_CENTER
# Note that if python was not correctly installed, you may end up with
# a message like this:
# #+BEGIN_CENTER
# [[file:emacs_orgmode_images/python3.png]]
# #+END_CENTER
# Then try to follow the steps in the installation section.
- The =<P= + =tab= will insert a Python block in /session/ mode. This
allows to keep variables alive from a block to an other. Internally,
emacs will have a buffer with a Python session running. Again, the
code is executed with the =C-c C-c= shortcut.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/python2.png]]
#+END_CENTER
- The =<PP= + =tab= will insert a Python block in /session/ mode and ready
to generate graphics.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/python4.png]]
#+END_CENTER
If this fails, try to update the Python =numpy= library, for exemple
like this in a dos/shell command:
#+begin_src shell :results output :exports both
python -m pip install -U numpy
#+end_src
* Taking notes with Emacs Org-Mode
** What does it look like.
- Open the =journal.org= file you have placed in the =~/org/=
directory. You will find a few first "old" entries with the most
useful emacs shortcuts, including the ones that have been presented
above.
** Taking notes
- The =C-c c= (=Ctrl c= then =c=) will open a menu asking you whether you
want to take notes in your todo list or in your journal.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/ctrl_c_c.png]]
#+END_CENTER
- Hit =j= to take notes in your journal.
Emacs then opens =journal.org= to create an entry with the right date
and presents you with a mini buffer in which you can start taking
notes.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/org_mode.png]]
#+END_CENTER
When you are done, simply hit =C-c C-c= to save your modifications
and close the mini-buffer.
** Fast editing of an org document
- It is common when taking notes in a brainstorming session to have to
clean and reorganize them. The =Alt= + =\leftarrow= or =Alt= +
=\rightarrow= will allow you to shift items to the left or to the
right. Likewise, entries can be moved up or down.
- Org-mode shortcuts are actually much more intuitive than prehistoric
emacs shortcuts. You'll quickly get use to it. Again, have a look to
the first entry of the =journal.org= file we gave you and which
contains many useful tips.
- Do not forget to save your files before closing emacs!
# -*- mode: org -*-
#+TITLE: Premiers pas avec Emacs/org-mode
#+DATE: March 2019
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
Ce document présuppose que vous avez déjà installé Emacs et suivi les
instructions données [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/954f94ce4f9a4d858d47b41793cc96c8][ici]].
Toutes les captures d'écran utilisées dans ce document ont été faites sous
Windows mais vous devriez obtenir le même genre de choses avec n'importe quel
système d'exploitation.
* Premiers pas avec Emacs pour éditer des documents computationnels
** Un premier document org-mode
- Lancez Emacs
#+BEGIN_CENTER
[[file:emacs_orgmode_images/emacs.png]]
#+END_CENTER
- Créez un nouveau fichier à l'aide de la petite icône en forme de
"feuille de papier" en haut à gauche, juste en dessous du menu =File=.
Placez le dans le répertoire de votre choix et nommez le =toto.org=.
** Exécuter des commandes dos/shell
- Vous disposez maintenant d'un document org-mode vide
- Tapez =<b= et appuyez sur =tab= pour obtenir un bloc de code shell. Vous
pouvez alors écrire la commande shell de votre choix (par exemple
=dir= sous Windows ou =ls= sous Linux et Mac). Maintenant, faites =C-c C-c=
(cette notation signifie appuyer deux fois de suite rapidement
sur les touches =Ctrl= et =c=). Votre commande shell devrait avoir été
exécutée et la sortie devrait avoir été mise juste en dessous.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/shell.png]]
#+END_CENTER
- Si jamais vous avez l'impression qu'Emacs est entré dans un mode un
peu étrange suite à un raccourci clavier malencontreux, faites
plusieurs fois de suite =C-g= (à nouveau, cela signifie appuyer
sur les touches =Ctrl= et =g=).
** Exécuter du code R
- De la même façon que le raccourci =<b= que nous venons de présenter
permet d'insérer des blocs de commandes shell, le raccourci =<r= + =tab=
vous permettra d'insérer des blocs de commandes R (par exemple
=summary(cars)=). Toujours pareil, le code est exécuté à l'aide de la
séquence de touches =C-c C-c= (appuyer deux fois de suite sur les
touches =Ctrl= et =c=).
#+BEGIN_CENTER
[[file:emacs_orgmode_images/commandeR1.png]]
#+END_CENTER
Normalement, Emacs vous demandera alors où il doit lancer
R. Conservez alors la proposition d'utiliser le répertoire courant
en appuyant sur la touche =Entrée=. À nouveau, la sortie devrait être
capturée et insérée juste en dessous.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/commandeR2.png]]
#+END_CENTER
- Le raccourci clavier =<R= + =tab= vous permettra d'insérer des blocs de
code R adaptés au cas où vos commandes R génèrent des images. Le
=(org-babel-temp-file \"figure\" \".png\")= génère un nom de fichier
temporaire à chaque exécution. Ce fichier sera donc effacé lorsque
vous fermerez Emacs. Si vous souhaitez que vos images soient
conservées d'une fois sur l'autre, indiquez un vrai nom de fichier à
la place.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/graphiqueR.png]]
#+END_CENTER
Si ce comportement de noms de fichiers temporaires ne vous convient
pas, il vous suffit d'éditer votre fichier de configuration =init.el=
et de remplacer les occurrences (pour =<R= et =<PP=) de
=(org-babel-temp-file \"figure\" \".png\")= par =\"D:/temp/figure.png\"=
ou tout autre endroit/nom de fichier que vous préféreriez.
** Exécuter du code Python
- Vous trouverez quelques exemples sur la page [[https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-python.html][Python Source Code Blocks
in Org Mode]].
- Le raccourci =<p= + =tab= permet d'insérer un bloc de code Python en
mode /non-session/. Cela signifie qu'un nouvel interpréteur Python est
lancé pour chaque bloc et que les variables ne seront pas partagées
entre les blocs. Comme d'habitude, le code sera exécuté à l'aide de la
séquence de touches =C-c C-c=.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/commande_python.png]]
#+END_CENTER
#+BEGIN_CENTER
[[file:emacs_orgmode_images/python1.png]]
#+END_CENTER
# Note that if Python was not correctly installed, you may end up with
# a message like this:
# #+BEGIN_CENTER
# [[file:emacs_orgmode_images/python3.png]]
# #+END_CENTER
# Then try to follow the steps in the installation section.
- Le raccourci =<P= + =tab= permet d'insérer un bloc de code Python, mais
cette fois-ci en mode /session/. Cela permet de conserver les
variables et leurs valeurs d'un bloc à l'autre. En interne et en
arrière-plan, Emacs aura un buffer avec une session Python en cours
d'exécution. Comme d'habitude, le code sera exécuté à
l'aide de la séquence de touches =C-c C-c=.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/python2.png]]
#+END_CENTER
- Enfin, le raccourci =<PP= + =tab= vous permettra d'insérer un bloc
Python en mode /session/ spécialement adapté à la production de graphiques
#+BEGIN_CENTER
[[file:emacs_orgmode_images/python4.png]]
#+END_CENTER
Si vous rencontrez un problème, essayez de mettre à jour la
bibliothèque Python =numpy=, par exemple à l'aide de =pip= dans une
commande dos/shell :
#+begin_src shell :results output :exports both
python -m pip install -U numpy
#+end_src
* Prendre des notes avec Emacs Org-Mode
** Le journal
- Ouvrez le fichier =journal.org= que vous devriez avoir placé dans le
répertoire =~/org/=. Vous y trouverez au tout début quelques
"vieilles" entrées avec les raccourcis clavier Emacs les plus
utiles, dont ceux que nous venons de vous présenter ci-dessus.
** Prendre des notes
- Le raccourci =C-c c= (attention, pas =C-c C-c=, mais =C-c= puis =c=)
ouvrira un menu vous demandant si vous souhaitez prendre des notes
dans votre todo list ou dans votre journal.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/ctrl_c_c.png]]
#+END_CENTER
- Appuyez sur =j= pour prendre des notes dans votre journal. Emacs va
alors ouvrir votre fichier =journal.org= pour y créer, à la toute fin,
une entrée avec la date du jour et va vous présenter un mini buffer
dans lequel vous allez pouvoir prendre vos notes.
#+BEGIN_CENTER
[[file:emacs_orgmode_images/org_mode.png]]
#+END_CENTER
Lorsque vous avez fini, faites simplement =C-c C-c= pour sauvegarder
vos modifications et fermer le mini-buffer.
** Édition d'un document org
- Il est courant lorsque l'on prend des notes dans une session de
brainstorming de devoir les nettoyer et les réorganiser. Les raccourcis
=Alt= + =\leftarrow= et =Alt= + =\rightarrow= vous permettront de
décaler les entrées vers la gauche ou vers la droite. Pareil pour
vers le haut ou vers le bas...
- Les raccourcis Org-mode sont en fait bien plus intuitifs que les
raccourcis (pré-)historiques d'Emacs. Vous devriez vite vous y faire.
Encore une fois, regardez bien la première entrée de votre
=journal.org=. Nous y avons mis les raccourcis et les ruses les plus
essentiel(le)s.
- N'oubliez pas de sauvegarder vos fichiers avant de fermer Emacs.
Amusez-vous bien !
<div id="content">
<h1 class="title">Emacs/org-mode</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org945f839">Installing emacs, org-mode, ess, and auctex.</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#orge325516">Linux (Debian, Ubuntu)</a></li>
<li style="margin-bottom:0;"><a href="#org95706b9">macOS</a></li>
<li style="margin-bottom:0;"><a href="#orgb87390f">Windows</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org69f7d5a">Directory naming conventions</a></li>
<li style="margin-bottom:0;"><a href="#orgfe267c7">Making R and Python available to the console</a></li>
<li style="margin-bottom:0;"><a href="#orgc458b5a">Installing and configuring Matplotlib (graphic python library)</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#org47ff448">All platforms: pretty code in HTML export</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#org98a8b7e">A simple "<i>reproducible research</i>" emacs configuration</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#orgd0815e9">Step 0: Backup and download our configuration</a></li>
<li style="margin-bottom:0;"><a href="#org9008837">Step 1: Prepare your journal</a></li>
<li style="margin-bottom:0;"><a href="#orgd3b10f7">Step 2: Set up Emacs configuration</a></li>
<li style="margin-bottom:0;"><a href="#org73ef313">Step 3: Adapt the configuration to your specific needs if required</a></li>
<li style="margin-bottom:0;"><a href="#orgc85363f">Step 4: Check whether the installation is working or not</a></li>
<li style="margin-bottom:0;"><a href="#orgadd0750">Step 5: Open and play with your journal:</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#org7b9442b">A stub of a replicable article</a></li>
<li style="margin-bottom:0;"><a href="#orgdde4be6">Emacs tips and tricks</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org152ca8a">Cheat-sheets</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org8a94d36">Emacs</a></li>
<li style="margin-bottom:0;"><a href="#org1765514">Org-mode</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#org4cc7124">Video tutorials</a></li>
<li style="margin-bottom:0;"><a href="#orgd5c8443">Additional useful emacs packages</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#orgb58b5a8">Company-mode</a></li>
<li style="margin-bottom:0;"><a href="#orgc20d2e9">Magit</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#org9260c82">Other resources</a></li>
</ul>
</li>
</ul>
</div>
</div>
<p>
<b>Disclaimer:</b> The two sections <span class="underline">A simple "<i>reproducible research</i>" emacs
configuration</span> and <span class="underline">A stub of replicable article</span> explain how to set up
emacs/org-mode for this MOOC. These are very important sections in the
context of this MOOC. <b>These sections are illustrated in two
out of the <a href="https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4">three video tutorials of this sequence</a>, and</b> <b>which you
really should follow carefully</b>. <b>Otherwise, you may have trouble doing
the exercises later on</b>. Likewise, I strongly encourage you to watch
the <a href="https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4">"emacs and git" video tutorial available at the same place</a>.
</p>
<p>
The next section provides information on how to install emacs.
</p>
<div id="outline-container-org945f839" class="outline-2">
<h2 id="org945f839">Installing emacs, org-mode, ess, and auctex.</h2>
<div class="outline-text-2" id="text-org945f839">
</div>
<div id="outline-container-orge325516" class="outline-3">
<h3 id="orge325516">Linux (Debian, Ubuntu)</h3>
<div class="outline-text-3" id="text-orge325516">
<p>
We provide here only instructions for Debian-based distributions. Feel
free to contribute to this document to provide up-to-date information
for other distributions (e.g.n redhat, fedora).
</p>
<p>
Today, the stable versions of the most common distributions provide
recent enough versions of emacs and org-mode:
</p>
<ul class="org-ul">
<li style="margin-bottom:0;">Debian (stretch) ships with <a href="https://packages.debian.org/stretch/emacs25">emacs 25.1</a> and <a href="https://packages.debian.org/stretch/org-mode">org-mode 9.0.3</a></li>
<li style="margin-bottom:0;">Ubuntu (bionic 18.04) ships with <a href="https://packages.ubuntu.com/bionic/emacs25">emacs 25.2</a> and <a href="https://packages.ubuntu.com/bionic/org-mode">org-mode 9.1.6</a></li>
<li style="margin-bottom:0;">Ubuntu (artful 17.04) ships with <a href="https://packages.ubuntu.com/artful/emacs25">emacs 25.2</a> and <a href="https://packages.ubuntu.com/artful/org-mode">org-mode 9.0.9</a></li>
</ul>
<p>
If your distribution is older than this, well, it may be a good time
for upgrading&#x2026;
</p>
<p>
Simply run (as root):
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-sh">apt-get update ; apt-get install emacs25 org-mode ess r-base auctex
</pre>
</div>
<p>
Then make sure you have a sufficiently recent version of emacs.
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-sh">emacs --version 2&gt;&amp;1 | head -n 1
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
GNU Emacs 25.2.2
</pre>
<p>
Likewise, you'll want to check you have a recent version of org-mode:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-sh">emacs -batch --funcall <span style="font-style: italic;">"org-version"</span> 2&gt;&amp;1 | grep version
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
Org mode version 9.1.11 (9.1.11-dist @ /usr/share/emacs/25.2/site-lisp/elpa/org-9.1.11/)
</pre>
<p>
The version numbers you get will depend on the distribution you are
running. <span class="underline">You really want to make sure you do not rely on org-mode 8</span>,
which is now deprecated.
</p>
</div>
</div>
<div id="outline-container-org95706b9" class="outline-3">
<h3 id="org95706b9">macOS</h3>
<div class="outline-text-3" id="text-org95706b9">
<p>
<b>Note:</b> macOS comes with a prehistoric command-line-only version of Emacs located at <code>/usr/bin/emacs</code>. It's best to forget about it.
</p>
<ul class="org-ul">
<li style="margin-bottom:0;"><p>
<b>Option 1</b>: Install the <code>.dmg</code> file from <a href="http://vgoulet.act.ulaval.ca/">Vincent Goulet</a>:
<a href="https://vigou3.gitlab.io/emacs-modified-macos/">https://vigou3.gitlab.io/emacs-modified-macos/</a>. It ships with recent
versions:
</p>
<ul class="org-ul">
<li style="margin-bottom:0;">Emacs 26.1</li>
<li style="margin-bottom:0;">Org-mode 9.1.13</li>
<li style="margin-bottom:0;">ESS 17.11</li>
</ul>
<p>
If you install this version of Emacs, or in fact any other version of
Emacs distributed as a clickable application in a <code>.dmg</code> file,
you must type the full path to the executable if you want to run
Emacs from a terminal. For example, if your clickable application
is at <code>/Applications/Emacs.app</code>, then the executable is at
<code>/Applications/Emacs.app/Contents/MacOS/Emacs</code>
</p></li>
<li style="margin-bottom:0;"><p>
<b>Option 2</b>: If you use <a href="https://docs.brew.sh/">Homebrew</a>, do the following:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-sh">brew update
brew install emacs --with-cocoa
brew linkapps emacs
brew install wget
brew tap dunn/emacs
brew install auctex
brew tap brewsci/science
brew install ess
</pre>
</div>
<p>
This provides an <code>emacs</code> command for use from the command line, plus a clickable application at <code>Cellar/emacs/26.1_1/Emacs.app</code> inside your Homebrew directory. If
you installed Homebrew at the default location <code>/usr/local</code>, then this is <code>/usr/local/Cellar/emacs/26.1_1/Emacs.app</code>.
If you installed Homebrew on an account with administrator privileges, you can add
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-sh">brew linkapps emacs
</pre>
</div>
<p>
in order to make Emacs accessible directly from <code>/Applications</code>.
</p></li>
</ul>
</div>
</div>
<div id="outline-container-orgb87390f" class="outline-3">
<h3 id="orgb87390f">Windows</h3>
<div class="outline-text-3" id="text-orgb87390f">
<p>
Install the <code>.exe</code> file from <a href="http://vgoulet.act.ulaval.ca/">Vincent Goulet</a>:
<a href="https://vigou3.gitlab.io/emacs-modified-windows/">https://vigou3.gitlab.io/emacs-modified-windows/</a>. It ships with recent
versions:
</p>
<ul class="org-ul">
<li style="margin-bottom:0;">Emacs 26.1</li>
<li style="margin-bottom:0;">Org-mode 9.1.13</li>
<li style="margin-bottom:0;">ESS 17.11</li>
</ul>
</div>
<div id="outline-container-org69f7d5a" class="outline-4">
<h4 id="org69f7d5a">Directory naming conventions</h4>
<div class="outline-text-4" id="text-org69f7d5a">
<p>
In the following instructions, we refer to your home
directory through the (UNIX) <code>~/</code> notation. On Windows, your home
directory should be something like <code>C:\Users\yourname</code>. Therefore,
whenever we mention the <code>~/org/</code> (resp. the <code>~/.emacs.d/</code>) directory this
means we are referring to <code>C:\Users\yourname\org</code> (resp.
<code>C:\Users\yourname\.emacs.d\</code>).
</p>
</div>
</div>
<div id="outline-container-orgfe267c7" class="outline-4">
<h4 id="orgfe267c7">Making R and Python available to the console</h4>
<div class="outline-text-4" id="text-orgfe267c7">
<p>
When running a command, Windows will look for the command in the
directories indicated in the <code>PATH</code> environment variable. If none of
these directories contains the command, Windows will stop and indicate
the command does not exist. To make sure R (which may be in
something like <code>C:/Program Files/R/R-3.5.1/bin/x64/</code>) and Python (which may be in something like <code>C:/Program Files/Python/Python37/</code>) can
easily be run from Emacs, you should thus configure the <code>PATH</code> variable
accordingly.
</p>
<p>
This requires to go through the "Environment Variable" editor as
explained <a href="http://sametmax.com/ajouter-un-chemin-a-la-variable-denvironnement-path-sous-windows/">here</a>.
</p>
</div>
</div>
<div id="outline-container-orgc458b5a" class="outline-4">
<h4 id="orgc458b5a">Installing and configuring Matplotlib (graphic python library)</h4>
<div class="outline-text-4" id="text-orgc458b5a">
<p>
Open an DOS console and type the following command:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">python -m pip install -U matplotlib
</pre>
</div>
<div class="figure">
<p><img src="data:image/png;base64,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" alt="install_matplotlib.png" /></p>
</div>
<p>
Then you will want to deactivate interactive plots in matplotlib. To
this end, you first need to know where the matplotlib configuration is
located. Open a python console the type the following code:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-python"><span style="font-weight: bold;">import</span> matplotlib
matplotlib.matplotlib_fname()
</pre>
</div>
<div class="figure">
<p><img src="data:image/png;base64,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" alt="matplotlib.png" /></p>
</div>
<p>
Open the <code>matplotlibrc</code> file and add a <code>#</code> at the beginning of the line
starting with <code>backend</code>, which amounts to use the default <code>Agg</code> value.
</p>
</div>
</div>
</div>
<div id="outline-container-org47ff448" class="outline-3">
<h3 id="org47ff448">All platforms: pretty code in HTML export</h3>
<div class="outline-text-3" id="text-org47ff448">
<p>
To have code pretty printing when exporting to HTML, you should
install the <code>htmlize</code> package, which is done by opening emacs and
typing the following command:
</p>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
M-x package-install RET htmlize RET # where M-x means pressing the "Esc" key then the "x" key
</pre>
</div>
</div>
</div>
<div id="outline-container-org98a8b7e" class="outline-2">
<h2 id="org98a8b7e">A simple "<i>reproducible research</i>" emacs configuration</h2>
<div class="outline-text-2" id="text-org98a8b7e">
<p>
This section is illustrated in a <a href="https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4">video tutorial</a> (<i>"Mise en place
Emacs/Orgmode"</i> in French). Watching it before following the
instructions given in this section may help.
</p>
<p>
Emacs comes with very basic default configuration and it appears like
everyone has its own taste. You will for example find <a href="https://www.emacswiki.org/emacs/StarterKits">here</a> several
default Emacs configurations that reflect the preferences of their
creators. Likewise the configuration of Org-Mode is incredibly
flexible (see for example <a href="https://orgmode.org/worg/org-configs/index.html">the org-mode website</a> for more
references). In the context of this MOOC, we propose you a relatively
minimalist one that is rather "<i>reproducible research</i>" oriented by
adding a few org-mode specific configurations.
</p>
</div>
<div id="outline-container-orgd0815e9" class="outline-3">
<h3 id="orgd0815e9">Step 0: Backup and download our configuration</h3>
<div class="outline-text-3" id="text-orgd0815e9">
<p>
The procedure we propose will wipe your already existing custom Emacs
configuration if you have one. <b>You should thus beforehand make a
backup</b> of <code>~/.emacs</code> and of <code>~/.emacs.d/init.el</code> (if these files exist).
</p>
<p>
Then download <a href="https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/raw/master/module2/ressources/rr_org_archive.tgz">this archive</a> and uncompress it. It contains the
following files and we will refer to them in the following:
</p>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
rr_org/init.el
rr_org/journal.org
</pre>
<p>
Alternatively, <a href="rr_org/">the files you are looking for are available here</a>.
</p>
</div>
</div>
<div id="outline-container-org9008837" class="outline-3">
<h3 id="org9008837">Step 1: Prepare your journal</h3>
<div class="outline-text-3" id="text-org9008837">
<p>
Create an <code>org/</code> directory in the top of your home:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-sh">mkdir -p ~/org/
</pre>
</div>
<p>
Then copy <code>rr_org/journal.org</code> file in your <code>~/org/</code> directory. This
file will be your laboratory notebook and all the notes you will
capture with <code>C-c c</code> will go automatically go in this file. The first
entry of this notebook is populated with <a href="https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org">many Emacs shortcuts</a> that you
should give a try.
</p>
</div>
</div>
<div id="outline-container-orgd3b10f7" class="outline-3">
<h3 id="orgd3b10f7">Step 2: Set up Emacs configuration</h3>
<div class="outline-text-3" id="text-orgd3b10f7">
<p>
Copy <code>rr_org/init.el</code> in your <code>~/.emacs.d/</code> directory.
</p>
<p>
Alternatively, if you do not want to mess with your already existing
emacs configuration, you may launch emacs with this specific
configuration with the following command: <code>emacs -q -l rr_org/init.el</code>.
</p>
</div>
</div>
<div id="outline-container-org73ef313" class="outline-3">
<h3 id="org73ef313">Step 3: Adapt the configuration to your specific needs if required</h3>
<div class="outline-text-3" id="text-org73ef313">
<p>
There are two situations in which it might be necessary to modify
<code>init.el</code>:
</p>
<ol class="org-ol">
<li style="margin-bottom:0;">Your network environment forces you to use a proxy for access
to Web sites (HTTP(S) protocol).</li>
<li style="margin-bottom:0;"><p>
You have multiple installations of Python or R on your computer,
or they are in unusual places and not fully configured.
If you can run
</p>
<ul class="org-ul">
<li style="margin-bottom:0;">"python3" and "R" under Linux and macOS</li>
<li style="margin-bottom:0;">"Python" and "R" under Windows</li>
</ul>
<p>
in a terminal without getting an error message, then you should
not have to do anything.
</p></li>
</ol>
<p>
If you do have to modify <code>init.el</code>, check the comments at the
beginning of the file for instructions.
</p>
</div>
</div>
<div id="outline-container-orgc85363f" class="outline-3">
<h3 id="orgc85363f">Step 4: Check whether the installation is working or not</h3>
<div class="outline-text-3" id="text-orgc85363f">
<p>
Open a new instance of Emacs and open a <code>foo.org</code> file. Copy the
following lines in this file:
</p>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
#+begin_src shell :session foo :results output :exports both
ls -la # or dir under windows
#+end_src
</pre>
<p>
Put your cursor inside this code block and execute it with the
following command: <code>C-c C-c</code> (If you are not familiar with Emacs
commands, this one means '<code>Ctrl + C</code>' twice)
</p>
<p>
A <code>#+RESULTS:</code> block with the result of the command should appear if it
worked.
</p>
<p>
In the video, we already have demonstrated the main features and
shortcuts of emacs/org-mode that will help you maintain a document and
benefit from literate programming. The list of features and shortcuts
is demonstrated in the <a href="https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org">first entry of your labbook</a>.
</p>
</div>
</div>
<div id="outline-container-orgadd0750" class="outline-3">
<h3 id="orgadd0750">Step 5: Open and play with your journal:</h3>
<div class="outline-text-3" id="text-orgadd0750">
<p>
In step 1, you were told to create an journal in
<code>~org/journal.org</code>. First you probably want to make sure this file is
stored in a version control system like git. We leave it up to you
to set this up but if you have any trouble, feel free to ask on the
FUN forums.
</p>
</div>
</div>
</div>
<div id="outline-container-org7b9442b" class="outline-2">
<h2 id="org7b9442b">A stub of a replicable article</h2>
<div class="outline-text-2" id="text-org7b9442b">
<p>
This section is illustrated in a <a href="https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4">video tutorial</a> (<i>"Écrire un article
réplicable avec Emacs/Orgmode"</i> in French). Watching it before
following the instructions given in this section may help.
</p>
<p>
Remember, you need a working LaTeX and R environment. If you can't
open a terminal and run the commands <code>R</code>, <code>pdflatex</code>, and <code>python</code>, you will not be
able to generate this document. When being compiled, the article downloads the
corresponding LaTeX packages so you also need to have a working <code>wget</code>
command (alternatively, it uses <code>curl</code>). Once downloaded, you may still read the
source (<a href="https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.org">article.org</a>) and understand how it works though.
</p>
<p>
Download the following <a href="https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/raw/master/module2/ressources/replicable_article.tgz">archive</a>, uncompress it and simply <code>make</code> to generate the
article. You should then be able to open the <a href="https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.pdf">resulting article</a>. This
is summarized in the following command:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-sh">wget --no-check-certificate -O replicable_article.tgz https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/raw/master/module2/ressources/replicable_article.tgz
tar zxf replicable_article.tgz; <span style="font-weight: bold;">cd</span> replicable_article; make ; evince article.pdf
</pre>
</div>
<p>
<b>Possible issues</b>:
</p>
<ul class="org-ul">
<li style="margin-bottom:0;"><p>
If the <code>make</code> command fails (especially on Mac), it may be because
Emacs or something else is not correctly installed. In that case,
open the article directly with the following command:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-sh">emacs -q --eval <span style="font-style: italic;">"(setq enable-local-eval t)"</span> --eval <span style="font-style: italic;">"(setq enable-local-variables t)"</span> article.org
</pre>
</div>
<p>
and export it to pdf with the following shortcut: <code>C-c C-e l o</code>
</p></li>
<li style="margin-bottom:0;">If it still doesn't work and emacs complains about not finding ESS,
it may be because you installed ESS in your home instead of
system-wide. In that case, try to remove the <code>-q</code> in the previous
command line to load your personal emacs configuration.</li>
</ul>
<p>
Finally, when you'll be tired of always re-executing all the source
code when exporting, just look for the following line in <a href="https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.org">article.org</a>:
</p>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
# #+PROPERTY: header-args :eval never-export
</pre>
<p>
If you remove the <code></code> in the beginning of the line, it will not be a
comment anymore and will indicate org-mode to stop evaluating every
chunk of code when exporting.
</p>
</div>
</div>
<div id="outline-container-orgdde4be6" class="outline-2">
<h2 id="orgdde4be6">Emacs tips and tricks</h2>
<div class="outline-text-2" id="text-orgdde4be6">
</div>
<div id="outline-container-org152ca8a" class="outline-3">
<h3 id="org152ca8a">Cheat-sheets</h3>
<div class="outline-text-3" id="text-org152ca8a">
<p>
Learning Emacs and Org-Mode can be difficult as there is an inordinate
amount of shortcuts. Many people have thus come up with
cheat-sheats. Here is a selection in case it helps:
</p>
</div>
<div id="outline-container-org8a94d36" class="outline-4">
<h4 id="org8a94d36">Emacs</h4>
<div class="outline-text-4" id="text-org8a94d36">
<ul class="org-ul">
<li style="margin-bottom:0;"><a href="https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org">Common and step-by-step Emacs shortcuts for our <i>reproducible research</i> configuration</a></li>
<li style="margin-bottom:0;"><a href="https://www.gnu.org/software/emacs/refcards/pdf/refcard.pdf">The official GNU emacs refcard</a></li>
<li style="margin-bottom:0;">Two graphical cheat-sheats by Sacha Chua on <a href="http://sachachua.com/blog/wp-content/uploads/2013/05/How-to-Learn-Emacs-v2-Large.png">how to learn Emacs</a> and on
<a href="http://sachachua.com/blog/wp-content/uploads/2013/08/20130830-Emacs-Newbie-How-to-Learn-Emacs-Keyboard-Shortcuts.png">how to learn Emacs shortcuts</a>.</li>
</ul>
</div>
</div>
<div id="outline-container-org1765514" class="outline-4">
<h4 id="org1765514">Org-mode</h4>
<div class="outline-text-4" id="text-org1765514">
<ul class="org-ul">
<li style="margin-bottom:0;"><a href="https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org">Common and step-by-step org-mode shortcuts for our <i>reproducible research</i> configuration</a></li>
<li style="margin-bottom:0;"><a href="https://orgmode.org/worg/orgcard.html">The official org-mode refcard</a></li>
<li style="margin-bottom:0;"><a href="https://orgmode.org/worg/dev/org-syntax.html">The official description of the org-mode syntax</a> and a <a href="https://gist.github.com/hoeltgman/3825415">relatively concise description of the org-mode syntax</a>.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org4cc7124" class="outline-3">
<h3 id="org4cc7124">Video tutorials</h3>
<div class="outline-text-3" id="text-org4cc7124">
<p>
For those of you who prefer video explanations, here is a <a href="https://www.youtube.com/playlist?list=PL9KxKa8NpFxIcNQa9js7dQQIHc81b0-Xg">Youtube
channel with many step by step emacs tutorials</a>.
</p>
</div>
</div>
<div id="outline-container-orgd5c8443" class="outline-3">
<h3 id="orgd5c8443">Additional useful emacs packages</h3>
<div class="outline-text-3" id="text-orgd5c8443">
</div>
<div id="outline-container-orgb58b5a8" class="outline-4">
<h4 id="orgb58b5a8">Company-mode</h4>
<div class="outline-text-4" id="text-orgb58b5a8">
<p>
<a href="http://company-mode.github.io/">Company-mode</a> is a text completion framework for Emacs. It allows to
have smart completion in emacs for the most common languages. If you
feel this is needed, you should follow the instructions from the
official Web page: <a href="http://company-mode.github.io/">http://company-mode.github.io/</a>
</p>
</div>
</div>
<div id="outline-container-orgc20d2e9" class="outline-4">
<h4 id="orgc20d2e9">Magit</h4>
<div class="outline-text-4" id="text-orgc20d2e9">
<p>
<a href="https://magit.vc/">Magit</a> is an Emacs interface for Git. Its usage is briefly illustrated
in the context of this MOOC in a <a href="https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4">video tutorial</a> (<i>"Utilisation
Emacs/git"</i> in French).
</p>
<p>
It is very powerful and we use it on a daily basis but you should
definitely understand what git does behind the scenes beforehand. If
you feel this would be useful for you, you should follow <a href="https://magit.vc/screenshots/">this visual
walk-through</a> or <a href="https://www.emacswiki.org/emacs/Magit">this really short "crash course"</a>. If you installed the
previous "<i>reproducible research</i>" emacs configuration, you can easily
invoke magit by using <code>C-x g</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-org9260c82" class="outline-3">
<h3 id="org9260c82">Other resources</h3>
<div class="outline-text-3" id="text-org9260c82">
<ul class="org-ul">
<li style="margin-bottom:0;"><a href="https://orgmode.org/orgguide.pdf">The compact Org-mode Guide</a></li>
<li style="margin-bottom:0;"><a href="https://github.com/dfeich/org-babel-examples">Many examples illustrating the use of different languages in org-mode</a></li>
</ul>
</div>
</div>
</div>
</div>
**Disclaimer:** The two sections *A simple "reproducible research" emacs
configuration* and *A stub of replicable article* explain how to set up
emacs/org-mode for this MOOC. These are very important sections in the
context of this MOOC. **These sections are illustrated in two out of the
[three video tutorials of this
sequence](https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4),
and** **which you really should follow carefully**. **Otherwise, you may
have trouble doing the exercises later on**. Likewise, I strongly
encourage you to watch the ["emacs and git" video tutorial available at
the same
place](https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4).
The next section provides information on how to install emacs.
Table of Contents
=================
- [Installing emacs, org-mode, ess, and
auctex.](#installing-emacs-org-mode-ess-and-auctex)
- [Linux (Debian, Ubuntu)](#linux-debian-ubuntu)
- [macOS](#macos)
- [Windows](#windows)
- [All platforms: pretty code in HTML
export](#all-platforms-pretty-code-in-html-export)
- [A simple "*reproducible research*" emacs configuration
](#a-simple-reproducible-research-emacs-configuration-)
- [Step 0: Backup and download our
configuration](#step-0-backup-and-download-our-configuration)
- [Step 1: Prepare your journal](#step-1-prepare-your-journal)
- [Step 2: Set up Emacs
configuration](#step-2-set-up-emacs-configuration)
- [Step 3: Adapt the configuration to your specific needs if
required](#step-3-adapt-the-configuration-to-your-specific-needs-if-required)
- [Step 4: Check whether the installation is working or
not](#step-4-check-whether-the-installation-is-working-or-not)
- [Step 5: Open and play with your
journal:](#step-5-open-and-play-with-your-journal)
- [A stub of a replicable article](#a-stub-of-a-replicable-article)
- [Emacs tips and tricks](#emacs-tips-and-tricks)
- [Cheat-sheets](#cheat-sheets)
- [Video tutorials](#video-tutorials)
- [Additional useful emacs
packages](#additional-useful-emacs-packages)
- [Other resources](#other-resources)
Installing emacs, org-mode, ess, and auctex.
============================================
Linux (Debian, Ubuntu)
----------------------
We provide here only instructions for Debian-based distributions. Feel
free to contribute to this document to provide up-to-date information
for other distributions (e.g.n redhat, fedora).
Today, the stable versions of the most common distributions provide
recent enough versions of emacs and org-mode:
- Debian (stretch) ships with [emacs
25.1](https://packages.debian.org/stretch/emacs25) and [org-mode
9.0.3](https://packages.debian.org/stretch/org-mode)
- Ubuntu (bionic 18.04) ships with [emacs
25.2](https://packages.ubuntu.com/bionic/emacs25) and [org-mode
9.1.6](https://packages.ubuntu.com/bionic/org-mode)
- Ubuntu (artful 17.04) ships with [emacs
25.2](https://packages.ubuntu.com/artful/emacs25) and [org-mode
9.0.9](https://packages.ubuntu.com/artful/org-mode)
If your distribution is older than this, well, it may be a good time for
upgrading...
Simply run (as root):
``` {.bash .rundoc-block rundoc-language="sh" rundoc-results="output" rundoc-exports="both"}
apt-get update ; apt-get install emacs25 org-mode ess r-base auctex
```
Then make sure you have a sufficiently recent version of emacs.
``` {.bash .rundoc-block rundoc-language="sh" rundoc-results="output" rundoc-exports="both"}
emacs --version 2>&1 | head -n 1
```
``` {.example}
GNU Emacs 25.2.2
```
Likewise, you'll want to check you have a recent version of org-mode:
``` {.bash .rundoc-block rundoc-language="sh" rundoc-results="output" rundoc-exports="both"}
emacs -batch --funcall "org-version" 2>&1 | grep version
```
``` {.example}
Org mode version 9.1.11 (9.1.11-dist @ /usr/share/emacs/25.2/site-lisp/elpa/org-9.1.11/)
```
The version numbers you get will depend on the distribution you are
running. **You really want to make sure you do not rely on org-mode 8**,
which is now deprecated.
macOS
-----
**Note:** macOS comes with a prehistoric command-line-only version of
Emacs located at `/usr/bin/emacs`. It's best to forget about it.
- **Option 1**: Install the `.dmg` file from [Vincent
Goulet](http://vgoulet.act.ulaval.ca/):
[<https://vigou3.gitlab.io/emacs-modified-macos/>](https://vigou3.gitlab.io/emacs-modified-macos/).
It ships with recent versions:
- Emacs 26.1
- Org-mode 9.1.13
- ESS 17.11
If you install this version of Emacs, or in fact any other version
of Emacs distributed as a clickable application in a `.dmg` file,
you must type the full path to the executable if you want to run
Emacs from a terminal. For example, if your clickable application is
at `/Applications/Emacs.app`, then the executable is at
`/Applications/Emacs.app/Contents/MacOS/Emacs`
- **Option 2**: If you use [Homebrew](https://docs.brew.sh/), do the
following:
``` {.bash .rundoc-block rundoc-language="sh" rundoc-results="output" rundoc-exports="both"}
brew update
brew install emacs --with-cocoa
brew linkapps emacs
brew install wget
brew tap dunn/emacs
brew install auctex
brew tap brewsci/science
brew install ess
```
This provides an `emacs` command for use from the command line, plus
a clickable application at `Cellar/emacs/26.1_1/Emacs.app` inside
your Homebrew directory. If you installed Homebrew at the default
location `/usr/local`, then this is
`/usr/local/Cellar/emacs/26.1_1/Emacs.app`. If you installed
Homebrew on an account with administrator privileges, you can add
``` {.bash .rundoc-block rundoc-language="sh" rundoc-results="output" rundoc-exports="both"}
brew linkapps emacs
```
in order to make Emacs accessible directly from `/Applications`.
Windows
-------
Install the `.exe` file from [Vincent
Goulet](http://vgoulet.act.ulaval.ca/):
[<https://vigou3.gitlab.io/emacs-modified-windows/>](https://vigou3.gitlab.io/emacs-modified-windows/).
It ships with recent versions:
- Emacs 26.1
- Org-mode 9.1.13
- ESS 17.11
### Directory naming conventions
In the following instructions, we refer to your home directory through
the (UNIX) `~/` notation. On Windows, your home directory should be
something like `C:\Users\yourname`. Therefore, whenever we mention the
`~/org/` (resp. the `~/.emacs.d/`) directory this means we are referring
to `C:\Users\yourname\org` (resp. `C:\Users\yourname\.emacs.d\`).
### Making R and Python available to the console
When running a command, Windows will look for the command in the
directories indicated in the `PATH` environment variable. If none of
these directories contains the command, Windows will stop and indicate
the command does not exist. To make sure R (which may be in something
like `C:/Program Files/R/R-3.5.1/bin/x64/`) and Python (which may be in
something like `C:/Program Files/Python/Python37/`) can easily be run
from Emacs, you should thus configure the `PATH` variable accordingly.
This requires to go through the "Environment Variable" editor as
explained
[here](http://sametmax.com/ajouter-un-chemin-a-la-variable-denvironnement-path-sous-windows/).
### Installing and configuring Matplotlib (graphic python library)
Open an DOS console and type the following command:
``` {.shell .rundoc-block rundoc-language="shell" rundoc-results="output" rundoc-exports="both"}
python -m pip install -U matplotlib
```
![](emacs_orgmode_images/install_matplotlib.png)
Then you will want to deactivate interactive plots in matplotlib. To
this end, you first need to know where the matplotlib configuration is
located. Open a python console the type the following code:
``` {.python .rundoc-block rundoc-language="python" rundoc-results="output" rundoc-exports="both"}
import matplotlib
matplotlib.matplotlib_fname()
```
![](emacs_orgmode_images/matplotlib.png)
Open the `matplotlibrc` file and modify the line starting with `backend`
to make it `backend : Agg`.
All platforms: pretty code in HTML export
-----------------------------------------
To have code pretty printing when exporting to HTML, you should install
the `htmlize` package, which is done by opening emacs and typing the
following command:
``` {.example}
M-x package-install RET htmlize RET # where M-x means pressing the "Esc" key then the "x" key
```
A simple "*reproducible research*" emacs configuration
======================================================
This section is illustrated in a [video
tutorial](https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4)
(/"Mise en place Emacs/Orgmode"/ in French). Watching it before
following the instructions given in this section may help.
Emacs comes with very basic default configuration and it appears like
everyone has its own taste. You will for example find
[here](https://www.emacswiki.org/emacs/StarterKits) several default
Emacs configurations that reflect the preferences of their creators.
Likewise the configuration of Org-Mode is incredibly flexible (see for
example [the org-mode
website](https://orgmode.org/worg/org-configs/index.html) for more
references). In the context of this MOOC, we propose you a relatively
minimalist one that is rather "*reproducible research*" oriented by
adding a few org-mode specific configurations.
Step 0: Backup and download our configuration
---------------------------------------------
The procedure we propose will wipe your already existing custom Emacs
configuration if you have one. **You should thus beforehand make a
backup** of `~/.emacs` and of `~/.emacs.d/init.el` (if these files
exist).
Then download [this
archive](https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/raw/master/module2/ressources/rr_org_archive.tgz)
and uncompress it. It contains the following files and we will refer to
them in the following:
``` {.example}
rr_org/init.el
rr_org/journal.org
```
Alternatively, [the files you are looking for are available
here](rr_org/).
Step 1: Prepare your journal
----------------------------
Create an `org/` directory in the top of your home:
``` {.bash .rundoc-block rundoc-language="sh" rundoc-results="output" rundoc-exports="both"}
mkdir -p ~/org/
```
Then copy `rr_org/journal.org` file in your `~/org/` directory. This
file will be your laboratory notebook and all the notes you will capture
with `C-c c` will go automatically go in this file. The first entry of
this notebook is populated with [many Emacs
shortcuts](https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org)
that you should give a try.
Step 2: Set up Emacs configuration
----------------------------------
Copy `rr_org/init.el` in your `~/.emacs.d/` directory.
Alternatively, if you do not want to mess with your already existing
emacs configuration, you may launch emacs with this specific
configuration with the following command: `emacs -q -l rr_org/init.el`.
Step 3: Adapt the configuration to your specific needs if required
------------------------------------------------------------------
There are two situations in which it might be necessary to modify
`init.el`:
1. Your network environment forces you to use a proxy for access to Web
sites (HTTP(S) protocol).
2. You have multiple installations of Python or R on your computer, or
they are in unusual places and not fully configured. If you can run
- "python3" and "R" under Linux and macOS
- "Python" and "R" under Windows
in a terminal without getting an error message, then you should not
have to do anything.
If you do have to modify `init.el`, check the comments at the beginning
of the file for instructions.
Step 4: Check whether the installation is working or not
--------------------------------------------------------
Open a new instance of Emacs and open a `foo.org` file. Copy the
following lines in this file:
``` {.example}
#+begin_src shell :session foo :results output :exports both
ls -la # or dir under windows
#+end_src
```
Put your cursor inside this code block and execute it with the following
command: `C-c C-c` (If you are not familiar with Emacs commands, this
one means '`Ctrl + C`' twice)
A `#+RESULTS:` block with the result of the command should appear if it
worked.
In the video, we already have demonstrated the main features and
shortcuts of emacs/org-mode that will help you maintain a document and
benefit from literate programming. The list of features and shortcuts is
demonstrated in the [first entry of your
labbook](https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org).
Step 5: Open and play with your journal:
----------------------------------------
In step 1, you were told to create an journal in `~org/journal.org`.
First you probably want to make sure this file is stored in a version
control system like git. We leave it up to you to set this up but if you
have any trouble, feel free to ask on the FUN forums.
A stub of a replicable article
==============================
This section is illustrated in a [video
tutorial](https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4)
(/"Écrire un article réplicable avec Emacs/Orgmode"/ in French).
Watching it before following the instructions given in this section may
help.
Remember, you need a working LaTeX and R environment. If you can't open
a terminal and run the commands `R`, `pdflatex`, and `python`, you will
not be able to generate this document. When being compiled, the article
downloads the corresponding LaTeX packages so you also need to have a
working `wget` command (alternatively, it uses `curl`). Once downloaded,
you may still read the source
([article.org](https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.org))
and understand how it works though.
Download the following
[archive](https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/raw/master/module2/ressources/replicable_article.tgz),
uncompress it and simply `make` to generate the article. You should then
be able to open the [resulting
article](https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.pdf).
This is summarized in the following command:
``` {.bash .rundoc-block rundoc-language="sh" rundoc-results="output" rundoc-exports="both"}
wget --no-check-certificate -O replicable_article.tgz https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/raw/master/module2/ressources/replicable_article.tgz
tar zxf replicable_article.tgz; cd replicable_article; make ; evince article.pdf
```
**Possible issues**:
- If the `make` command fails (especially on Mac), it may be because
Emacs or something else is not correctly installed. In that case,
open the article directly with the following command:
``` {.bash .rundoc-block rundoc-language="sh" rundoc-results="output" rundoc-exports="both"}
emacs -q --eval "(setq enable-local-eval t)" --eval "(setq enable-local-variables t)" article.org
```
and export it to pdf with the following shortcut: `C-c C-e l o`
- If it still doesn't work and emacs complains about not finding ESS,
it may be because you installed ESS in your home instead of
system-wide. In that case, try to remove the `-q` in the previous
command line to load your personal emacs configuration.
Finally, when you'll be tired of always re-executing all the source code
when exporting, just look for the following line in
[article.org](https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.org):
``` {.example}
# #+PROPERTY: header-args :eval never-export
```
If you remove the `` in the beginning of the line, it will not be a
comment anymore and will indicate org-mode to stop evaluating every
chunk of code when exporting.
Emacs tips and tricks
=====================
Cheat-sheets
------------
Learning Emacs and Org-Mode can be difficult as there is an inordinate
amount of shortcuts. Many people have thus come up with cheat-sheats.
Here is a selection in case it helps:
### Emacs
- [Common and step-by-step Emacs shortcuts for our *reproducible
research*
configuration](https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org)
- [The official GNU emacs
refcard](https://www.gnu.org/software/emacs/refcards/pdf/refcard.pdf)
- Two graphical cheat-sheats by Sacha Chua on
![](http://sachachua.com/blog/wp-content/uploads/2013/05/How-to-Learn-Emacs-v2-Large.png)
and on
![](http://sachachua.com/blog/wp-content/uploads/2013/08/20130830-Emacs-Newbie-How-to-Learn-Emacs-Keyboard-Shortcuts.png).
### Org-mode
- [Common and step-by-step org-mode shortcuts for our *reproducible
research*
configuration](https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org)
- [The official org-mode
refcard](https://orgmode.org/worg/orgcard.html)
- [The official description of the org-mode
syntax](https://orgmode.org/worg/dev/org-syntax.html) and a
[relatively concise description of the org-mode
syntax](https://gist.github.com/hoeltgman/3825415).
Video tutorials
---------------
For those of you who prefer video explanations, here is a [Youtube
channel with many step by step emacs
tutorials](https://www.youtube.com/playlist?list=PL9KxKa8NpFxIcNQa9js7dQQIHc81b0-Xg).
Additional useful emacs packages
--------------------------------
### Company-mode
[Company-mode](http://company-mode.github.io/) is a text completion
framework for Emacs. It allows to have smart completion in emacs for the
most common languages. If you feel this is needed, you should follow the
instructions from the official Web page:
[<http://company-mode.github.io/>](http://company-mode.github.io/)
### Magit
[Magit](https://magit.vc/) is an Emacs interface for Git. Its usage is
briefly illustrated in the context of this MOOC in a [video
tutorial](https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4)
("*Utilisation Emacs/git*" in French).
It is very powerful and we use it on a daily basis but you should
definitely understand what git does behind the scenes beforehand. If you
feel this would be useful for you, you should follow [this visual
walk-through](https://magit.vc/screenshots/) or [this really short
"crash course"](https://www.emacswiki.org/emacs/Magit). If you installed
the previous "*reproducible research*" emacs configuration, you can
easily invoke magit by using `C-x g`.
Other resources
---------------
- [The compact Org-mode Guide](https://orgmode.org/orgguide.pdf)
- [Many examples illustrating the use of different languages in
org-mode](https://github.com/dfeich/org-babel-examples)
# -*- mode: org -*-
#+TITLE: Emacs/org-mode
#+AUTHOR: Arnaud Legrand
#+DATE: June, 2018
#+TITLE: Emacs/Org-mode : trucs et astuces, Intallation et configuration
#+DATE: March 2019
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
This document provides information on how to install emacs.
*Disclaimer:* The two sections /A simple "reproducible research" emacs configuration/
and /A stub of replicable article/ explain how to set up
emacs/org-mode for this MOOC. These are very important sections in the
context of this MOOC. *These sections are illustrated in two
out of the [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4][three video tutorials of this sequence]], and* *which you
out of the [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4][three video tutorials of this page]], and* *which you
really should follow carefully*. *Otherwise, you may have trouble doing
the exercises later on*. Likewise, I strongly encourage you to watch
the [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4]["emacs and git" video tutorial available at the same place]].
The next section provides information on how to install emacs.
the [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4]["Use Emacs/git" video tutorial available at the same page]].
* Table of Contents :TOC:
- [[#installing-emacs-org-mode-ess-and-auctex][Installing emacs, org-mode, ess, and auctex.]]
- [[#linux-debian-ubuntu][Linux (Debian, Ubuntu)]]
- [[#macos][macOS]]
- [[#windows][Windows]]
- [[#all-platforms-pretty-code-in-html-export][All platforms: pretty code in HTML export]]
- [[#a-simple-reproducible-research-emacs-configuration-][A simple "/reproducible research/" emacs configuration ]]
- [[#step-0-backup-and-download-our-configuration][Step 0: Backup and download our configuration]]
- [[#step-1-prepare-your-journal][Step 1: Prepare your journal]]
- [[#step-2-set-up-emacs-configuration][Step 2: Set up Emacs configuration]]
- [[#step-3-adapt-the-configuration-to-your-specific-needs-if-required][Step 3: Adapt the configuration to your specific needs if required]]
- [[#step-4-check-whether-the-installation-is-working-or-not][Step 4: Check whether the installation is working or not]]
- [[#step-5-open-and-play-with-your-journal][Step 5: Open and play with your journal:]]
- [[#a-stub-of-a-replicable-article][A stub of a replicable article]]
- [[#emacs-tips-and-tricks][Emacs tips and tricks]]
- [[#cheat-sheets][Cheat-sheets]]
- [[#video-tutorials][Video tutorials]]
- [[#additional-useful-emacs-packages][Additional useful emacs packages]]
- [[#other-resources][Other resources]]
* Installing emacs, org-mode, ess, and auctex.
- [[#installing-emacs][Installing Emacs]]
- [[#linux-debian-ubuntu][Linux (Debian, Ubuntu)]]
- [[#macos][macOS]]
- [[#windows][Windows]]
- [[#python-r-and-latex][Python, R, and LaTeX]]
- [[#a-simple-reproducible-research-emacs-configuration][A simple "reproducible research" emacs configuration]]
- [[#step-0-backup-and-remove-your-previous-configuration][Step 0: Backup and remove your previous configuration]]
- [[#step-1-download-our-configuration][Step 1: Download our configuration]]
- [[#step-2-prepare-your-journal][Step 2: Prepare your journal]]
- [[#step-3-put-the-emacs-configuration-file-in-the-right-place][Step 3: Put the Emacs configuration file in the right place]]
- [[#step-4-adapt-the-configuration-to-your-specific-needs-if-required][Step 4: Adapt the configuration to your specific needs if required]]
- [[#step-5-check-whether-the-installation-is-working-or-not][Step 5: Check whether the installation is working or not]]
- [[#step-6-open-and-play-with-your-journal][Step 6: Open and play with your journal:]]
- [[#a-stub-of-a-replicable-article][A stub of a replicable article]]
- [[#emacs-tips-and-tricks][Emacs tips and tricks]]
- [[#cheat-sheets][Cheat-sheets]]
- [[#video-tutorials][Video tutorials]]
- [[#additional-useful-emacs-packages][Additional useful emacs packages]]
- [[#other-resources][Other resources]]
* Installing Emacs
In the following we describe for each platform the installation method that we consider most convenient. There are other options that may be preferable in particular situations, so you may want to look at the [[https://www.gnu.org/software/emacs/download.html][Emacs Web site]] for details, but we strongly suggest you first try the method we recommend.
At the end of the installation procedure, you should have one of
1. Emacs 26 (the latest version)
2. Emacs 25 plus Org-Mode 9
Emacs 25 comes with Org-Mode 8, which is not compatible with our examples. So if you use Emacs 25, you must separately install Org-Mode 9. Emacs 26 already includes Org-Mode 9.
Our MOOC also requires a few extra Emacs packages: [[https://ess.r-project.org/][ESS]] (for working with the R language) and [[https://www.gnu.org/software/auctex/][AUCTeX]] (for editing LaTeX). They will be installed automatically the first time you start Emacs if you use the configuration described under [[#a-simple-reproducible-research-emacs-configuration][A simple "reproducible research" emacs configuration]].
** Linux (Debian, Ubuntu)
We provide here only instructions for Debian-based distributions. Feel
free to contribute to this document to provide up-to-date information
for other distributions (e.g.n redhat, fedora).
for other distributions (e.g. redhat, fedora).
Today, the stable versions of the most common distributions provide
recent enough versions of emacs and org-mode:
These are the versions of Emacs that various distributions provide:
- Debian (stretch) ships with [[https://packages.debian.org/stretch/emacs25][emacs 25.1]] and [[https://packages.debian.org/stretch/org-mode][org-mode 9.0.3]]
- Ubuntu (bionic 18.04) ships with [[https://packages.ubuntu.com/bionic/emacs25][emacs 25.2]] and [[https://packages.ubuntu.com/bionic/org-mode][org-mode 9.1.6]]
- Ubuntu (artful 17.04) ships with [[https://packages.ubuntu.com/artful/emacs25][emacs 25.2]] and [[https://packages.ubuntu.com/artful/org-mode][org-mode 9.0.9]]
......@@ -53,10 +63,10 @@ for upgrading...
Simply run (as root):
#+begin_src sh :results output :exports both
apt-get update ; apt-get install emacs25 org-mode ess r-base auctex
apt-get update ; apt-get install emacs25 org-mode
#+end_src
Then make sure you have a sufficiently recent version of emacs.
Then verify that you have a sufficiently recent version of Emacs.
#+begin_src sh :results output :exports both
emacs --version 2>&1 | head -n 1
#+end_src
......@@ -64,7 +74,7 @@ emacs --version 2>&1 | head -n 1
#+RESULTS:
: GNU Emacs 25.2.2
Likewise, you'll want to check you have a recent version of org-mode:
Likewise, you'll want to check you have a recent version of Org-Mode:
#+begin_src sh :results output :exports both
emacs -batch --funcall "org-version" 2>&1 | grep version
#+end_src
......@@ -74,57 +84,37 @@ emacs -batch --funcall "org-version" 2>&1 | grep version
The version numbers you get will depend on the distribution you are
running. _You really want to make sure you do not rely on org-mode 8_,
which is now deprecated.
which is now deprecated.
** macOS
*Note:* macOS comes with a prehistoric command-line-only version of Emacs located at =/usr/bin/emacs=. It's best to forget about it.
- *Option 1*: Install the =.dmg= file from [[http://vgoulet.act.ulaval.ca/][Vincent Goulet]]:
[[https://vigou3.gitlab.io/emacs-modified-macos/][https://vigou3.gitlab.io/emacs-modified-macos/]]. It ships with recent
versions:
- Emacs 26.1
- Org-mode 9.1.13
- ESS 17.11
If you install this version of Emacs, or in fact any other version of
Emacs distributed as a clickable application in a =.dmg= file,
you must type the full path to the executable if you want to run
Emacs from a terminal. For example, if your clickable application
is at =/Applications/Emacs.app=, then the executable is at
=/Applications/Emacs.app/Contents/MacOS/Emacs=
- *Option 2*: If you use [[https://docs.brew.sh/][Homebrew]], do the following:
#+begin_src sh :results output :exports both
brew update
brew install emacs --with-cocoa
brew linkapps emacs
brew install wget
brew tap dunn/emacs
brew install auctex
brew tap brewsci/science
brew install ess
#+end_src
This provides an =emacs= command for use from the command line, plus a clickable application at =Cellar/emacs/26.1_1/Emacs.app= inside your Homebrew directory. If
you installed Homebrew at the default location =/usr/local=, then this is =/usr/local/Cellar/emacs/26.1_1/Emacs.app=.
If you installed Homebrew on an account with administrator privileges, you can add
#+begin_src sh :results output :exports both
brew linkapps emacs
#+end_src
in order to make Emacs accessible directly from =/Applications=.
The Web site https://emacsformacosx.com/ proposes precompiled Emacs versions for macOS. Download the latest version (the one that figures prominently on the page) and install it like you would install any other macOS application, by copying =Emacs.app= from the downloaded disk image to a convenient location on your computer.
If you like working in a terminal (the =Terminal.app= from macOS, or an enhanced one such as [[https://iterm2.com/][iTerm2]]), the standard macOS way of opening a file in Emacs is =open -a Emacs.app /path/to/my/file.txt=. This will launch Emacs, unless it is already running, and then ask Emacs to open the file. Note that this is different from the Unix/Linux way of running Emacs, which is what you see in the videos. Under Linux, you type =emacs /path/to/my/file.txt= in the terminal, which always starts a fresh copy of Emacs.
*** Advanced topics - not required for following the MOOC
For advanced uses of Emacs, such as calling Emacs from a Makefile to automate document processing, you have to adopt the Unix way also under macOS, because this is the only way to provide parameters other than filenames. However, you have to enter the full path to the executable. Assuming that you have copied =Emacs.app= to =/path/to/emacs=, this is =/path/to/emacs/Emacs.app/Contents/MacOS/Emacs=. If you just type =emacs=, you will use the prehistoric command-line-only version at =/usr/bin/emacs= provided by Apple. You can of course make the Emacs executable more easily accessible using a shell alias, or by putting =/path/to/emacs/Emacs.app/Contents/MacOS/= on your =$PATH= in your =~/.bashrc= ou =~/.bash_profile=. See the [[https://www.gnu.org/software/bash/manual/bashref.html][bash manual]] for details and explanation.
Be aware that running Emacs the Unix way implies some subtle differences compared to running Emacs the macOS way. In particular, Emacs will inherit the shell's environment variables when run the Unix way, but the user session's environment variables when run the macOS way.
** Windows
Install the =.exe= file from [[http://vgoulet.act.ulaval.ca/][Vincent Goulet]]:
[[https://vigou3.gitlab.io/emacs-modified-windows/][https://vigou3.gitlab.io/emacs-modified-windows/]]. It ships with recent
versions:
- Emacs 26.1
- Org-mode 9.1.13
- ESS 17.11
Download the precompiled Emacs 26, which is available [[https://ftp.gnu.org/gnu/emacs/windows/emacs-26/emacs-26.1-i686.zip][for 32 bit architectures]] or [[https://ftp.gnu.org/gnu/emacs/windows/emacs-26/emacs-26.1-x86_64.zip][for 64 bit architectures]]. The choice depends on your machine; if you don't know which is best, try the 64-bit version and if it cannot be started, switch to 32-bit. Unzip the zip file preserving the directory structure. If this approach does not work, follow the instructions from the [[https://www.gnu.org/software/emacs/download.html#windows][official emacs website]]. If this still fails, do not hesitate to ask questions on the forum.
Finally run =bin\runemacs.exe=. Alternatively, create a desktop shortcut to =bin\runemacs.exe=, and start Emacs by double-clicking on that shortcut's icon. See [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Windows-Startup.html][here]] for an explanation of this and other methods for launching Emacs under Windows. You should be able to obtain a window that looks like this:
#+BEGIN_CENTER
[[file:emacs_orgmode_images/emacs.png]]
[[file:emacs_orgmode_images/scratch.png]]
#+END_CENTER
*** Directory naming conventions
In the following instructions, we refer to your home
directory through the (UNIX) =~/= notation. On Windows, your home
directory should be something like =C:\Users\yourname=. Therefore,
whenever we mention the =~/org/= (resp. the =~/.emacs.d/=) directory this
means we are referring to =C:\Users\yourname\org= (resp.
=C:\Users\yourname\.emacs.d\=).
=C:\Users\yourname\.emacs.d\=). Note that the =C:\Users\yourname\.emacs.d\= directory should be automatically created when running emacs for the first time. This is where the emacs configuration will go.
*** Managing archives
Later in this document, you will be asked to download small archives containing files ([[file:rr_org_archive.tgz][rr_org_archive.tgz]] and [[file:replicable_article.tgz][replicable_article.tgz]]). To uncompress these archives on your computer, you may want to use the =7z= program. In this case, you may have to uncompress each file twice... The first time, =archive.tgz= will be uncompressed in =archive.tar= and the second time =archive.tar= will create a =archive/= directory comprising all the files of the original archive.
*** Making R and Python available to the console
When running a command, Windows will look for the command in the
directories indicated in the =PATH= environment variable. If none of
......@@ -155,41 +145,61 @@ matplotlib.matplotlib_fname()
Open the =matplotlibrc= file and modify the line starting with =backend=
to make it =backend : Agg=.
** All platforms: pretty code in HTML export
To have code pretty printing when exporting to HTML, you should
install the =htmlize= package, which is done by opening emacs and
typing the following command:
#+BEGIN_EXAMPLE
M-x package-install RET htmlize RET # where M-x means pressing the "Esc" key then the "x" key
#+END_EXAMPLE
* Python, R, and LaTeX
Computational documents contain code, which in the case of our MOOC use the languages Python and R. So you must install Python and R in addition to Emacs, unless of course they are already installed on your computer. Since Python and R are also used in the other paths of our MOOC, we explain their installation in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/19c2b1de7766484bae73f3ab133463c6][separate resource]].
* A simple "/reproducible research/" emacs configuration
This section is illustrated in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4][video tutorial]] (/"Mise en place
That same resource also explains how to install LaTeX, which you must have if you want to produce PDF versions of org-mode documents. For example, if you want to work with the replicable article stub (shown in [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4#tuto3][the video "Write a replicable article with Emacs/Org-mode"]]), you must install LaTeX. However, it is a rather big piece of software (several GB), so you may prefer to skip its installation. It is not required to follow the MOOC.
* A simple "reproducible research" emacs configuration
This section is illustrated in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4][video tutorial]] (/"Mise en place
Emacs/Orgmode"/ in French). Watching it before following the
instructions given in this section may help.
Emacs comes with very basic default configuration and it appears like
everyone has its own taste. You will for example find [[https://www.emacswiki.org/emacs/StarterKits][here]] several
default Emacs configurations that reflect the preferences of their
creators. Likewise the configuration of Org-Mode is incredibly
flexible (see for example [[https://orgmode.org/worg/org-configs/index.html][the org-mode website]] for more
references). In the context of this MOOC, we propose you a relatively
minimalist one that is rather "/reproducible research/" oriented by
adding a few org-mode specific configurations.
** Step 0: Backup and download our configuration
The procedure we propose will wipe your already existing custom Emacs
configuration if you have one. *You should thus beforehand make a
backup* of =~/.emacs= and of =~/.emacs.d/init.el= (if these files exist).
Emacs comes with a very basic default configuration, so almost
everyone wants to personalize it. Given the flexibility of Emacs, a
configuration can become quite complex and in fact include what would
otherwise be considered complete software packages (see for example
these Emacs Starter Kits [[https://kieranhealy.org/resources/emacs-starter-kit/][here]] or [[https://www.emacswiki.org/emacs/StarterKits][here]]). In the context of
this MOOC, we propose a relatively minimalist configuration oriented
towards "/reproducible research/" with Org-Mode. If you are new to
Emacs, we strongly recommended that you use it with as little
modification as possible, by following the instructions in this
section. If you are a more experienced Emacs user, you can go through
the instructions and adopt the pieces that you consider useful for
you.
It is unfortunately rather probable that some of you will run into
unforeseen problems with this configuration. If that is your case, ask
a question on the forum. We will do our best to help you.
** Step 0: Backup and remove your previous configuration
If you have used Emacs before, you may already have a personal
configuration. And even if not, you may have Emacs configuration files
without being aware of them, since some software packages create or
modify Emacs configuration files. In order to avoid trouble, remove
prior configurations, after making a backup elsewhere.
The files that you should backup and then remove (if they exist) are:
1. =~/.emacs=
2. =~/.emacs.el=
3. =~/.emacs.elc=
There is also a directory that you should backup and then remove (if
it exists), with everything it might contain:
4. =~/.emacs.d=
In the above filenames, =~/= stands for your home directory. Windows
users should replace it by =C:\Users\MyName=, replacing MyName by
their user name.
** Step 1: Download our configuration
#+begin_src shell :results output :exports none
export FILE_LIST="rr_org/init.el rr_org/journal.org"
export FILE_LIST="rr_org/init.el rr_org/journal.org rr_org/init.org"
tar zcf rr_org_archive.tgz $FILE_LIST
#+end_src
#+RESULTS:
Then download [[https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/raw/master/module2/ressources/rr_org_archive.tgz][this archive]] and uncompress it. It contains the
Download [[file:rr_org_archive.tgz][this archive]] and uncompress it. It contains the
following files and we will refer to them in the following:
#+begin_src shell :results output :exports results
......@@ -199,49 +209,80 @@ tar tzf rr_org_archive.tgz
#+RESULTS:
: rr_org/init.el
: rr_org/journal.org
Alternatively, [[file:rr_org/][the files you are looking for are available here]].
** Step 1: Prepare your journal
: rr_org/init.org
Alternatively, [[file:rr_org/][the files you are looking for are available here]]. As
you may notice, the configuration (=init.el= in emacs lisp) is hard to
follow, which is why we manage it through an =init.org= file, which is
really nice for readability. This is a trick you may want to adopt
too (i.e., modify the =init.org= and regenerate the =init.el= by simply
/tangling/ the file --with =M-x org-babel-tangle=, see instructions in the
beginning of =init.org=).
If you use Windows, and if you use a desktop shortcut to start Emacs,
you must include the path to the file =init.el= in the command for the
shortcut. For example, if you installed Emacs as
=C:\Users\MyName\emacs=, your desktop shortcut should execute the
command =C:\Users\MyName\emacs\bin\runemacs.exe -l .emacs.d/init.el=.
** Step 2: Prepare your journal
Create an =org/= directory in the top of your home:
#+begin_src sh :results output :exports both
mkdir -p ~/org/
mkdir -p ~/org/
# on Windows, use the file explorer to create the directory C:\Users\MyName\org
#+end_src
Then copy =rr_org/journal.org= file in your =~/org/= directory. This
file will be your laboratory notebook and all the notes you will
capture with =C-c c= will go automatically go in this file. The first
entry of this notebook is populated with [[https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][many Emacs shortcuts]] that you
entry of this notebook is populated with [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][many Emacs shortcuts]] that you
should give a try.
** Step 2: Set up Emacs configuration
Copy =rr_org/init.el= in your =~/.emacs.d/= directory.
Alternatively, if you do not want to mess with your already existing
emacs configuration, you may launch emacs with this specific
configuration with the following command: =emacs -q -l rr_org/init.el=.
** Step 3: Adapt the configuration to your specific needs if required
** Step 3: Put the Emacs configuration file in the right place
Create the directory =~/.emacs.d/= and copy =rr_org/init.el= into it.
** Step 4: Adapt the configuration to your specific needs if required
There are two situations in which it might be necessary to modify
=init.el=:
1. Your network environment forces you to use a proxy for access
to Web sites (HTTP(S) protocol).
2. You have multiple installations of Python or R on your computer,
or they are in unusual places and not fully configured.
If you can run
- "python3" and "R" under Linux and macOS
- "Python" and "R" under Windows
in a terminal without getting an error message, then you should
not have to do anything.
or they are in unusual places and not fully configured. *Note that this will be
the case if you followed our recommendation to use the Anaconda distribution.*
For diagnosing your installation, do the following:
1. Open a new terminal, and try to run the following commands:
- =python3= and =R= under Linux and macOS
- =Python= and =R= under Windows
If you get no error message, all is gine. You should
not have to do anything to access Python and R from Emacs.
2. If you got an error message, you will have to track down where exactly
you installed Python and/or R. What you have to insert into =init.el= is the
complete path to each executable. For example, if you have installed Anaconda
under =/opt=, and if you have installed Python and/or R in Anaconda's default
environment, then the paths are =/opt/anaconda3/bin/python3= and
=/opt/anaconda3/bin/R=. If they are installed in an environment called
=mooc_rr=, the paths are =/opt/anaconda3/envs/mooc_rr/bin/python3= and
=/opt/anaconda3/envs/mooc_rr/bin/R=.
If you do have to modify =init.el=, check the comments at the
beginning of the file for instructions.
** Step 4: Check whether the installation is working or not
Open a new instance of Emacs and open a =foo.org= file. Copy the
following lines in this file:
** Step 5: Check whether the installation is working or not
Quit Emacs if it is running, and start it again. This first start will
take a bit of time because Emacs will download a few add-on
packages. For that reason, please make sure that you have a working
internet connection for this step. Note also that the download can
fail for other reasons, such as the package servers being overloaded.
Such situations do not last very long, so we recommend that you just
quit Emacs (=C-x C-c=, meaning =Ctrl + x= followed by =Ctrl + c=) and
restart it. At worst, repeat this until you get no more errors on
startup.
Next, create a file =foo.org=. Copy the following lines into this file:
: #+begin_src shell :session foo :results output :exports both
: ls -la # or dir under windows
: #+end_src
Put your cursor inside this code block and execute it with the
following command: =C-c C-c= (If you are not familiar with Emacs
commands, this one means '=Ctrl + C=' twice)
commands, this one means '=Ctrl + c=' twice)
A =#+RESULTS:= block with the result of the command should appear if it
worked.
......@@ -249,60 +290,38 @@ worked.
In the video, we already have demonstrated the main features and
shortcuts of emacs/org-mode that will help you maintain a document and
benefit from literate programming. The list of features and shortcuts
is demonstrated in the [[https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][first entry of your labbook]].
** Step 5: Open and play with your journal:
In step 1, you were told to create an journal in
=~org/journal.org=. First you probably want to make sure this file is
is demonstrated in the [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][first entry of your labbook]].
** Step 6: Open and play with your journal:
In step 2, you were told to create a journal in
=~org/journal.org=. You probably want to make sure this file is
stored in a version control system like git. We leave it up to you
to set this up but if you have any trouble, feel free to ask on the
FUN forums.
MOOC forum.
* A stub of a replicable article
This section is illustrated in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4][video tutorial]] (/"Écrire un article
réplicable avec Emacs/Orgmode"/ in French). Watching it before
This section is illustrated in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4#tuto3][video tutorial]] (/"Write a replicable article with Emacs/Org-mode"/). Watching it before
following the instructions given in this section may help.
Remember, you need a working LaTeX and R environment. If you can't
open a terminal and run the commands =R=, =pdflatex=, and =python=, you will not be
able to generate this document. When being compiled, the article downloads the
corresponding LaTeX packages so you also need to have a working =wget=
command (alternatively, it uses =curl=). Once downloaded, you may still read the
source ([[https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.org][article.org]]) and understand how it works though.
To work with this article stub, you need working installations of LaTeX, R, and Python. If you can't open a terminal and run the commands =R=, =pdflatex=, and =python3=, you will not be able to generate this document. When being compiled, the article downloads the corresponding LaTeX packages, so you must have a working network connection.
Note for macOS users: Since the article is compiled using =make=, you need to put the Emacs executable on your shell's search path, as explained above under [[*Advanced topics - not required for following the MOOC][advanced topics]].
#+begin_src shell :results output :exports none
make -C replicable_article/ all ../replicable_article.tgz
export FILE_LIST="replicable_article/Makefile replicable_article/article.org replicable_article/biblio.bib replicable_article/article.pdf"
make -C replicable_article/ article.pdf
tar zcf replicable_article.tgz $FILE_LIST
#+end_src
#+RESULTS:
Download the following [[https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/raw/master/module2/ressources/replicable_article.tgz][archive]], uncompress it and simply =make= to generate the
article. You should then be able to open the [[https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.pdf][resulting article]]. This
is summarized in the following command:
#+begin_src sh :results output :exports both
wget --no-check-certificate -O replicable_article.tgz https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/raw/master/module2/ressources/replicable_article.tgz
tar zxf replicable_article.tgz; cd replicable_article; make ; evince article.pdf
#+end_src
Download the following [[file:replicable_article.tgz][archive]] and uncompress it. The archive contains the compiled article, so you can start by looking at it.
*Possible issues*:
- If the =make= command fails (especially on Mac), it may be because
Emacs or something else is not correctly installed. In that case,
open the article directly with the following command:
#+begin_src sh :results output :exports both
emacs -q --eval "(setq enable-local-eval t)" --eval "(setq enable-local-variables t)" article.org
#+end_src
and export it to pdf with the following shortcut: =C-c C-e l o=
- If it still doesn't work and emacs complains about not finding ESS,
it may be because you installed ESS in your home instead of
system-wide. In that case, try to remove the =-q= in the previous
command line to load your personal emacs configuration.
Finally, when you'll be tired of always re-executing all the source
code when exporting, just look for the following line in [[https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.org][article.org]]:
To rebuild the article, delete =article.pdf=, or rename it to something else. Otherwise the rebuild procedure will simply tell you that the article is already up to date. Then type =make= to build everything from scratch. Open the freshly built =article.pdf= to see if it looks OK.
If you get tired of always re-executing all the source code when exporting, look for the following line in [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.org][article.org]]:
#+BEGIN_EXAMPLE
# #+PROPERTY: header-args :eval never-export
#+END_EXAMPLE
If you remove the =# = in the beginning of the line, it will not be a
comment anymore and will indicate org-mode to stop evaluating every
chunk of code when exporting.
If you remove the =# = in the beginning of the line, it will not be a comment anymore and will indicate org-mode to stop evaluating every chunk of code when exporting.
* Emacs tips and tricks
** Cheat-sheets
......@@ -310,17 +329,21 @@ Learning Emacs and Org-Mode can be difficult as there is an inordinate
amount of shortcuts. Many people have thus come up with
cheat-sheats. Here is a selection in case it helps:
*** Emacs
- [[https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][Common and step-by-step Emacs shortcuts for our /reproducible research/ configuration]]
- [[https://www.gnu.org/software/emacs/refcards/pdf/refcard.pdf][The official GNU emacs refcard]]
- [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][Common and step-by-step Emacs shortcuts for our /reproducible research/ configuration]]
- [[https://www.gnu.org/software/emacs/refcards/pdf/refcard.pdf][The official GNU emacs refcard]]
# French version: https://www.gnu.org/software/emacs/refcards/pdf/fr-refcard.pdf
- Two graphical cheat-sheats by Sacha Chua on [[http://sachachua.com/blog/wp-content/uploads/2013/05/How-to-Learn-Emacs-v2-Large.png][how to learn Emacs]] and on
[[http://sachachua.com/blog/wp-content/uploads/2013/08/20130830-Emacs-Newbie-How-to-Learn-Emacs-Keyboard-Shortcuts.png][how to learn Emacs shortcuts]].
*** Org-mode
- [[https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][Common and step-by-step org-mode shortcuts for our /reproducible research/ configuration]]
- [[https://orgmode.org/worg/orgcard.html][The official org-mode refcard]]
- [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][Common and step-by-step org-mode shortcuts for our /reproducible research/ configuration]]
- [[https://orgmode.org/worg/orgcard.html][The official org-mode refcard]] ([[https://www.gnu.org/software/emacs/refcards/pdf/orgcard.pdf][in pdf]]).
- [[https://orgmode.org/worg/dev/org-syntax.html][The official description of the org-mode syntax]] and a [[https://gist.github.com/hoeltgman/3825415][relatively concise description of the org-mode syntax]].
** Video tutorials
For those of you who prefer video explanations, here is a [[https://www.youtube.com/playlist?list=PL9KxKa8NpFxIcNQa9js7dQQIHc81b0-Xg][Youtube
channel with many step by step emacs tutorials]].
For general information about a number of packages you could also
check the [[https://cestlaz.github.io/stories/emacs/][Using Emacs]], series of blogposts / videos.
** Additional useful emacs packages
*** Company-mode
[[http://company-mode.github.io/][Company-mode]] is a text completion framework for Emacs. It allows to
......@@ -329,15 +352,44 @@ feel this is needed, you should follow the instructions from the
official Web page: [[http://company-mode.github.io/][http://company-mode.github.io/]]
*** Magit
[[https://magit.vc/][Magit]] is an Emacs interface for Git. Its usage is briefly illustrated
in the context of this MOOC in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4][video tutorial]]
in the context of this MOOC in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4][video tutorial]]
("/Utilisation Emacs/git/" in French).
It is very powerful and we use it on a daily basis but you should
definitely understand what git does behind the scenes beforehand. If
you feel this would be useful for you, you should follow [[https://magit.vc/screenshots/][this visual
walk-through]] or [[https://www.emacswiki.org/emacs/Magit][this really short "crash course"]]. If you installed the
previous "/reproducible research/" emacs configuration, you can easily
invoke magit by using ~C-x g~.
walk-through]] or [[https://www.emacswiki.org/emacs/Magit][this really short "crash course"]].
If you installed the previous "/reproducible research/" emacs
configuration, you can easily invoke magit by using ~C-x g~. Magit will
then prompt you for the path of your local clone of the git repository
(the path to mooc-rr in the context of this MOOC).
[[file:emacs_orgmode_images/git1.png]]
If you do not rely on our "/reproducible research/" emacs configuration,
you should have a look at [[https://magit.vc/manual/magit/Installing-from-an-Elpa-Archive.html][how to install magit from an ELPA archive]].
The following method has been tested with Windows and worked like a charm:
- Add the following piece of text in your =.emacs.d/init.el= file:
#+begin_src emacs-lisp
(require 'package)
(add-to-list 'package-archives
'("melpa" . "http://melpa.org/packages/") t)
#+end_src
- Launch Emacs and run the following commands:
#+BEGIN_EXAMPLE
M-x package-refresh-contents RET
M-x package-install RET magit RET
#+END_EXAMPLE
NB: =M-= corresponds to the =<Alt>= key and =RET= corresponds to the
=<Return>= key.
** Other resources
- [[https://orgmode.org/orgguide.pdf][The compact Org-mode Guide]]
- [[https://github.com/dfeich/org-babel-examples][Many examples illustrating the use of different languages in org-mode]]
- The compact Org-mode Guide ([[https://orgmode.org/orgguide.pdf][pdf file]])
- A huge resource of emacs/org-mode magic is Bernt Hansen's «[[http://doc.norang.ca/org-mode.html][Organize
your life in plain text]]», whose source is obviously itself an
[[http://doc.norang.ca/org-mode.org][org-mode document]].
- [[https://github.com/dfeich/org-babel-examples][Many examples illustrating the use of different languages in
org-mode]]
# -*- mode: org -*-
#+TITLE: Emacs/org-mode
#+DATE: March 2019
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
Ce document explique comment installer Emacs et Org-mode sur votre
machine et recense un certain nombre d'autres références utiles sur
cet environnement.
*Attention:* Les sections [[#une-configuration-emacs-adaptée-à-la-recherche-reproductible][Une configuration Emacs adaptée à la
"recherche reproductible"]] et [[#un-mod%C3%A8le-darticle-r%C3%A9plicable][Un modèle d'article réplicable]]
expliquent comment configurer Emacs/Org-Mode pour ce MOOC. Ce sont donc
des sections très *importantes* qui sont *illustrées dans [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4][deux des trois
tutoriels vidéo de cette page]]*. *Nous vous encourageons vivement à
suivre attentivement ces sections* *et ces vidéos avant de vous lancer
dans les exercices*. De même, nous vous encourageons vivement à
regarder la vidéo [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4]["utilisation Emacs/git" disponible sur la même page]].
* Table des matières :TOC:
- [[#installation-demacs][Installation d'Emacs]]
- [[#linux-debian-ubuntu][Linux (Debian, Ubuntu)]]
- [[#macos][macOS]]
- [[#windows][Windows]]
- [[#python-r-et-latex][Python, R et LaTeX]]
- [[#une-configuration-emacs-adaptée-à-la-recherche-reproductible][Une configuration Emacs adaptée à la "recherche reproductible"]]
- [[#etape-0--sauvegarder-et-supprimer-votre-configuration-précédente][Etape 0 : Sauvegarder et supprimer votre configuration précédente]]
- [[#etape-1--télécharger-notre-configuration][Etape 1 : Télécharger notre configuration]]
- [[#étape-2--préparez-votre-journal][Étape 2 : Préparez votre journal]]
- [[#étape-3--placez-le-fichier-de-configuration-emacs-au-bon-endroit][Étape 3 : Placez le fichier de configuration Emacs au bon endroit]]
- [[#étape-4--adapter-la-configuration-à-vos-besoins-spécifiques-si-nécessaire][Étape 4 : Adapter la configuration à vos besoins spécifiques si nécessaire]]
- [[#etape-5--vérifier-si-linstallation-fonctionne-ou-non][Etape 5 : Vérifier si l'installation fonctionne ou non]]
- [[#étape-6--ouvrez-et-commencez-à-utiliser-votre-journal][Étape 6 : Ouvrez et commencez à utiliser votre journal]]
- [[#un-modèle-darticle-réplicable][Un modèle d'article réplicable]]
- [[#emacs-trucs-et-astuces][Emacs trucs et astuces]]
- [[#pense-bêtes][Pense-bêtes]]
- [[#tutoriels-vidéo][Tutoriels vidéo]]
- [[#paquets-emacs-utiles-supplémentaires][Paquets emacs utiles supplémentaires]]
- [[#autres-ressources][Autres ressources]]
* Installation d'Emacs
Dans cette section, nous décrivons pour chaque système d'exploitation la procédure d'installation qui nous a semblé la plus simple. Il y a d'autres options qui peuvent être plus adaptées à votre situation particulière donc n'hésitez pas à jeter un œil au [[https://www.gnu.org/software/emacs/download.html][site web officiel d'Emacs]] pour plus de détails. Mais nous vous recommandons néanmoins de d'abord essayer les méthodes décrites ci-dessous.
À la fin de cette installation, vous devriez avoir sur votre machine une des deux configurations suivantes:
1. Emacs 26 (la dernière version)
2. Emacs 25 plus Org-Mode 9
Emacs 25 vient avec Org-Mode 8 par défaut, qui est très ancien et n'est plus compatible avec les exemples que nous vous fournissons. Donc si vous utilisez Emacs 25, il vous faudra impérativement installer Org-Mode 9 séparément. Emacs 26 vient avec Org-Mode 9 donc pas de problème de ce coté là.
Les exemples que nous montrons dans notre MOOC nécessitent également quelques paquet Emacs supplémentaires: [[https://ess.r-project.org/][ESS]] (qui signifie /Emacs Speaks Statistics/ et qui permet d'utiliser le langage R) et [[https://www.gnu.org/software/auctex/][AUCTeX]] (pour éditer facilement des documents LaTeX). Si vous utilisez la configuration que nous décrivons dans la section [[#une-configuration-emacs-adaptée-à-la-recherche-reproductible][Une configuration Emacs adaptée à la "recherche reproductible"]], ces paquets seront installés automatiquement la première fois que vous lancerez Emacs.
** Linux (Debian, Ubuntu)
Vous ne trouverez dans cette section que les instructions pour les
distributions de type Debian (Ubuntu par exemple). N'hésitez pas à
contribuer à ce document pour partager des informations à jour pour
d'autres distributions (redhat, fedora, ...).
Voici les versions d'Emacs fournies par différentes distributions:
- Debian (stretch) fourni [[https://packages.debian.org/stretch/emacs25][emacs 25.1]] et [[https://packages.debian.org/stretch/org-mode][org-mode 9.0.3]]
- Ubuntu (bionic 18.04) fourni [[https://packages.ubuntu.com/bionic/emacs25][emacs 25.2]] et [[https://packages.ubuntu.com/bionic/org-mode][org-mode 9.1.6]]
- Ubuntu (artful 17.04) fourni [[https://packages.ubuntu.com/artful/emacs25][emacs 25.2]] et [[https://packages.ubuntu.com/artful/org-mode][org-mode 9.0.9]]
Si votre distribution est plus ancienne que celles-ci, et bien... c'est peut-être le bon moment pour faire une mise à jour.
En tant que root, tapez les commandes suivantes:
#+begin_src sh :results output :exports both
apt-get update ; apt-get install emacs25 org-mode
#+end_src
Puis vérifiez que vous avez bien une version d'Emacs suffisamment récente
#+begin_src sh :results output :exports both
emacs --version 2>&1 | head -n 1
#+end_src
#+RESULTS:
: GNU Emacs 25.2.2
De même, vérifiez que vous avez bien une version récente d'Org-Mode:
#+begin_src sh :results output :exports both
emacs -batch --funcall "org-version" 2>&1 | grep version
#+end_src
#+RESULTS:
: Org mode version 9.1.11 (9.1.11-dist @ /usr/share/emacs/25.2/site-lisp/elpa/org-9.1.11/)
Ces numéros de version dépendront de votre distribution mais
_assurez vous bien que vous n'utilisez pas Org-mode 8_ qui est désormais
complètement obsolète.
** macOS
*Note:* macOS est installé par défaut avec une version préhistorique d'emacs, qui ne fonctionne qu'en ligne de commande, qui est située dans =/usr/bin/emacs= et dont il est très difficile de se débarrasser. Il ne faut pas espérer en tirer quoi que ce soit.
Le site Web https://emacsformacosx.com/ propose des versions pré-compilées d'Emacs pour macOS. Téléchargez la dernière version (celle dont le numéro apparaît en gros sur la page d'accueil) et installez le de la même façon que n'importe quelle autre application macOS, en copiant =Emacs.app= de la zone de téléchargement vers le répertoire de votre choix sur votre ordinateur.
Si vous aimez travailler avec un terminal (le =Terminal.app= de macOS ou bien une version plus évoluée comme [[https://iterm2.com/][iTerm2]]), la façon standard sous macOS d'ouvrir emacs dans un terminal consiste à taper la commande =open -a Emacs.app /path/to/my/file.txt=. Cela lancera Emacs, à moins qu'il ne soit déjà ouvert, et demandera à Emacs d'ouvrir le fichier =file.txt=. Avec cette approche, il n'y a qu'une seule instance d'Emacs en cours d'exécution. C'est donc légèrement différent de la méthode Unix/Linux qui est illustrée dans les vidéos et où on tape =emacs /path/to/my/file.txt= dans le terminal, ce qui conduit à l'ouverture d'un nouvel emacs à chaque fois.
*** Sujets avancés - non requis pour suivre le MOOC
Pour les utilisations avancées d'Emacs, comme appeler Emacs à partir d'un Makefile pour automatiser le traitement de documents, il vous faudra adopter l'approche Unix également sous macOS car c'est le seul moyen de fournir des paramètres autres que des noms de fichiers. Il vous faudra alors également spécifier le chemin complet de l'exécutable. En effet, si vous tapez simplement =emacs=, vous utiliserez la version préhistorique en ligne de commande uniquement de =/usr/bin/emacs= fournie par Apple. En supposant que vous avez copié =Emacs.app= vers =/path/to/emacs=, l'exécutable =Emacs= sera situé dans =/path/to/emacs/Emacs.app/Contents/MacOS/Emacs=. Vous pouvez bien sûr rendre l'exécutable Emacs plus facilement accessible en utilisant un =alias= shell, ou en mettant =/path/to/emacs/Emacs.app/Contents/MacOS/= dans votre =$PATH=, par exemple en écrivant =export PATH=/path/to/emacs/Emacs.app/Contents/MacOS/:$PATH= dans votre =~/.bashrc= ou =~/.bash_profile=. Voir le [[https://www.gnu.org/software/bash/manual/bashref.html][bash manual]] pour plus de détails et explications.
Notez bien que l'exécution d'Emacs à la mode Unix implique quelques différences subtiles par rapport à l'exécution d'Emacs à la mode MacOS. En particulier, Emacs héritera des variables d'environnement du shell lorsqu'il est lancé à la mode Unix, alors qu'il héritera des variables d'environnement de la session utilisateur lorsqu'il est lancé à la mode MacOS.
** Windows
Téléchargez la version précompilée d'Emacs 26, disponible [[https://ftp.gnu.org/gnu/emacs/windows/emacs-26/emacs-26.1-i686.zip][pour les architectures 32 bits]] ou [[https://ftp.gnu.org/gnu/emacs/windows/emacs-26/emacs-26.1-x86_64.zip][pour les architectures 64 bits]]. Le choix dépend de votre machine. Si vous ne savez pas laquelle est la meilleure, essayez la version 64 bits et si elle ne peut pas être démarrée, passez à 32 bits. Décompressez le fichier zip en préservant la structure du répertoire. Si cette approche ne fonctionne pas, suivez les instructions du [[https://www.gnu.org/software/emacs/download.html#windows][site officiel d'Emacs]]. Si cela échoue toujours, n'hésitez pas à poser des questions sur le forum.
Enfin, exécutez =bin\runemacs.exe=. Sinon, créez un raccourci sur le bureau vers =bin\runemacs.exe=, et lancez Emacs en double-cliquant sur l'icône du raccourci. Voir [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Windows-Startup.html][ici]] pour une explication de cette méthode et d'autres méthodes pour lancer Emacs sous Windows. Vous devriez pouvoir obtenir une fenêtre qui ressemble à celle-ci :
#+BEGIN_CENTER
[[file:emacs_orgmode_images/emacs.png]]
[[file:emacs_orgmode_images/scratch.png]]
#+END_CENTER
*** Conventions de nommage des répertoires
Dans les instructions suivantes, nous faisons référence à votre répertoire personnel via la notation (UNIX) =~/=. Sous Windows, ce répertoire
devrait être quelque chose du genre =C:\Users\yourname=. Par conséquent,
chaque fois que nous mentionnons le répertoire =~/org/= (respectivement =~/.emacs.d/=)
cela signifie que nous faisons référence à =C:\Users\yourname\org= (respectivement
=C:\Utilisateurs\votre nom\.emacs.d\=). Notez que le répertoire =C:\Users\yourname\.emacs.d\= devrait être automatiquement créé lors de la première exécution d'emacs. C'est là que la configuration d'emacs ira.
*** Gestion des archives
Plus loin dans ce document, il vous sera demandé de télécharger de petites archives contenant des fichiers ([[file:rr_org_archive.tgz][rr_org_archive.tgz]] et [[file:réplicable_article.tgz][réplicable_article.tgz]]). Pour décompresser ces archives sur votre ordinateur, vous pouvez utiliser le programme =7z=. Dans ce cas, vous devrez probablement décompresser chaque fichier deux fois.... La première fois, =archive.tgz= sera décompressé dans =archive.tar= et la deuxième fois =archive.tar= créera un répertoire =archive/= comprenant tous les fichiers de l'archive originale.
*** Rendre R et Python disponible dans une console
Lors de l'exécution d'une commande, Windows recherchera l'exécutable dans les répertoires indiqués dans la variable d'environnement =PATH=. Si aucun de
ces répertoires ne contient la commande, Windows s'arrêtera et indiquera que
la commande n'existe pas. Pour s'assurer que R (qui peut être dans
quelque chose comme =C:/Program Files/R/R-3.5.1/bin/x64/=) et Python (qui peut être dans quelque chose comme =C:/Program Files/Python/Python/Python37/=) puissent
s'exécuter facilement à partir d'Emacs, vous devrez donc configurer la variable =PATH= en conséquence.
Cela nécessite de passer par l'éditeur de variables d'environnement comme
expliqué [[http://sametmax.com/ajouter-un-chemin-a-la-variable-denvironnement-path-sous-windows/][ici]].
*** Installation et configuration de Matplotlib (bibliothèque graphique python)
Ouvrez une console DOS et tapez la commande suivante :
#+begin_src shell :results output :exports both
python -m pip install -U matplotlib
#+end_src
[[file:emacs_orgmode_images/install_matplotlib.png]]
Ensuite, il vous faudra désactiver les tracés interactifs dans matplotlib (pour que l'image apparaisse dans votre emacs et pas dans une fenêtre à côté). Pour cela, il vous faut d'abord déterminer où se trouve la configuration matplotlib. Ouvrez une console python et tapez le code suivant :
#+begin_src python :results output :exports both
import matplotlib
matplotlib.matplotlib_fname()
#+end_src
[[file:emacs_orgmode_images/matplotlib.png]]
Ouvrez le fichier =matplotlibrc=, localisez la ligne commençant par =backend= et transformez là en =backend : Agg=.
* Python, R et LaTeX
Les documents computationnels contiennent du code, et en particulier dans le cas de notre MOOC du code utilisant les langages Python et R. Vous devrez donc installer Python et R en plus d'Emacs, sauf s'ils sont déjà installés sur votre ordinateur. Puisque Python et R sont aussi utilisés dans les autres parcours de notre MOOC, nous expliquons leur installation dans une [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/19c2b1de7766484bae73f3ab133463c6][ressource séparée]].
Cette même ressource explique également comment installer LaTeX, dont vous devrez disposer si vous voulez produire des versions PDF de documents org-mode. Par exemple, si vous voulez travailler avec modèle d'article réplicable (montré dans [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4#tuto3][la vidéo "écrire un article réplicable avec Emacs/Org-mode"]]), il vous faudra installer LaTeX. Cependant, comme il s'agit d'un logiciel assez volumineux (plusieurs Go), vous pouvez préférer ne pas l'installer. Ce n'est pas indispensable.
* Une configuration Emacs adaptée à la "recherche reproductible"
Cette section est illustrée dans une [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4][vidéo de démonstration]] (/Mise en place en place Emacs/Orgmode/). Nous vous suggérons de la regarder avant de suivre les instructions données dans cette section.
Emacs s'installe avec une configuration par défaut très basique que
chacun va donc vouloir personnaliser. Compte tenu de la flexibilité
d'Emacs, sa configuration peut vite devenir assez complexe et pourrait
même faire l'objet d'un paquet à part entière (voir par exemple les
différents Emacs Starter Kits [[https://kieranhealy.org/resources/emacs-starter-kit/][ici]] ou [[https://www.emacswiki.org/emacs/StarterKits][ici]]). Dans le contexte de ce
MOOC, nous vous proposons une configuration relativement minimaliste
orientée "/recherche reproductible/" avec Org-Mode. Si vous êtes peu
familier d'Emacs, nous vous recommandons fortement de l'utiliser et de la modifier le moins possible. Il vous suffira de suivre
les instructions données dans cette section. Si vous êtes un
utilisateur Emacs plus expérimenté, vous pouvez vous contenter de
regarder nos instructions et de ne récupérer que les parties qui vous
sembleront utiles.
Il est malheureusement assez probable que certains d'entre vous
rencontreront des problèmes que nous n'avons pas anticipés. Si c'est
votre cas, posez la question sur le forum. Nous ferons de notre mieux
pour vous aider.
** Etape 0 : Sauvegarder et supprimer votre configuration précédente
Si vous avez déjà utilisé Emacs auparavant, il se peut que vous ayez
déjà un fichier de configuration personnel. Et même si ce n'est pas
le cas, il se peut que vous en ayez un sans même le savoir puisque
certains paquets peuvent créer ou modifier les fichiers de
configuration d'Emacs. Afin d'éviter tout problème, nous vous
recommandons donc d'enlever ces anciennes configurations.
Les fichiers que vous devez sauvegarder puis supprimer (s'ils existent) sont :
1. =~/.emacs=
2. =~/.emacs.el=
3. =~/.emacs.elc=
Il y a aussi un répertoire que vous devez sauvegarder puis supprimer (s'il existe), avec tout ce qu'il peut contenir :
4. =~/.emacs.d=
Dans les noms de fichiers ci-dessus, =~/= représente votre répertoire
personnel. Sous Windows, les utilisateurs doivent le remplacer par
=C:\Users\MonNom=, remplaçant MonNom par leur nom d'utilisateur.
** Etape 1 : Télécharger notre configuration
#+begin_src shell :results output :exports none
export FILE_LIST="rr_org/init.el rr_org/journal.org rr_org/init.org"
tar zcf rr_org_archive.tgz $FILE_LIST
#+end_src
Télécharger [[file:rr_org_archive.tgz][cette archive]] et décompressez la. Elle contient les fichiers
suivants et nous y ferons référence par la suite :
#+begin_src shell :results output :exports results
tar tzf rr_org_org_archive.tgz
#+end_src
#+RESULTS:
: rr_org/init.el
: rr_org/journal.org
: rr_org/init.org
Si vous avez des problèmes avec cette archive, [[file:rr_org/][les fichiers dont vous
aurez besoin sont également disponibles ici]]. Vous allez vite réaliser
que la configuration (=init.el= en emacs lisp) est assez difficile à
suivre. C'est pourquoi nous le gérons via un fichier =init.org=, qui
bien plus lisible. C'est une astuce que vous voudrez peut-être aussi
adopter (pour cela, modifiez le =init.org= et régénérez le =init.el= en
/tanglant/ le fichier avec =M-x org-babel-tangle= comme expliqué dans les
instructions au début de =init.org=).
Si vous utilisez Windows, et si vous utilisez un raccourci du bureau pour démarrer Emacs,
il vous faudra inclure le chemin d'accès au fichier =init.el= dans la commande pour le fichier
raccourci. Par exemple, si vous avez installé Emacs en tant que
=C:\Users\MonNom\emacs=, votre raccourci de bureau devrait exécuter la commande
commande =C:\Users\MonNom\emacs\bin\runemacs.exe -l .emacs.d/init.el=.
** Étape 2 : Préparez votre journal
Créez un répertoire =org/= à la racine de votre répertoire personnel:
#+begin_src shell :results output :exports both
mkdir -p ~/org/g/
# sous Windows, utilisez l'explorateur de fichiers pour créer le répertoire C:\Users\MonNom\org
#+end_src
Copiez ensuite le fichier =rr_org/journal.org= dans votre répertoire
=~/org/=. Ce sera votre cahier de laboratoire et toutes les notes que
vous prendrez dans ce dossier avec =C-c c= iront automatiquement dans ce
fichier. La première entrée de ce carnet est remplie de [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][nombreux de
raccourcis claviers Emacs]] que nous vous encourageons à essayer.
** Étape 3 : Placez le fichier de configuration Emacs au bon endroit
Créez le répertoire =~/.emacs.d/= et copiez =rr_org/init.el= dedans.
** Étape 4 : Adapter la configuration à vos besoins spécifiques si nécessaire
Il y a deux situations dans lesquelles il peut être nécessaire de modifier
=init.el= :
1. Votre environnement réseau vous oblige à utiliser un proxy accéder à internet (protocole HTTP(S)).
2. Vous avez plusieurs installations de Python ou R sur votre ordinateur, ou bien elles se trouvent dans des endroits inhabituels ou ne sont pas entièrement configurées. *Ceci est notamment le cas si vous avez utilisé Anaconda pour installer Python et/ou R, comme nous le recommandons.*
Voici comment évaluer votre installation :
1. Ouvrez un nouveau terminal, et essayez d'exécuter les commandes suivantes:
- =python3= et =R= sous Linux et macOS
- =Python= et =R= sous Windows
Si vous n'obtenez pas de message d'erreur, tout va bien et vous ne devriez pas avoir à faire quoi que ce soit pour accéder à Python et R sous Emacs.
2. Si vous avez eu un message d'erreur, il va falloir trouver où vous avez installé Python et/où R. Notez le chemin complet à chaque exécutable - c'est ce qu'il faut insérer dans votre =init.el=. Par exemple, si vous avez installé Anaconda sous =/opt=, et si par la suite vous avez mis Python et R dans l'environnment par défaut, vos exécutables sont à =/opt/anaconda3/bin/python3= et =/opt/anaconda3/bin/R=. S'ils sont dans un environnment qui s'appelle =mooc_rr=, les chemins sont =/opt/anaconda3/envs/mooc_rr/bin/python3= et =/opt/anaconda3/envs/mooc_rr/bin/R=.
Si vous devez modifier =init.el=, regardez bien les commentaires dans le fichier =init.org= pour comprendre comment ça marche.
** Etape 5 : Vérifier si l'installation fonctionne ou non
Quittez Emacs s'il est en cours d'exécution, et redémarrez-le. Ce premier lancement devrait
prendre un peu de temps parce qu'Emacs va télécharger quelques paquets supplémentaires. Il vous faudra donc vous assurer que votre ordinateur a une connexion internet pour cette étape. Notez également que le téléchargement peut
échouer pour diverses raisons (surcharge des serveurs de paquets, connexion trop lente, ...).
Ces situations durent rarement bien longtemps. C'est pourquoi si cela arrive, nous vous recommandons de vous contenter de
quittez Emacs (=C-x C-c=, c'est-à-dire =Ctrl + x= suivi de =Ctrl + c=) et
redémarrez-le. Au pire, répétez cette opération jusqu'à ce que vous n'obteniez plus d'erreur au
démarrage.
Ensuite, créez un fichier =foo.org=. Copiez les lignes suivantes dans ce fichier :
: #+begin_src shell :session foo :results output :exports both
: ls -la # ou dir sous Windows
: #+end_src
Placez votre curseur à l'intérieur de ce bloc de code et exécutez-le
avec le raccourci clavier suivante : =C-c C-c= (cela signifie faire
=Ctrl + c= deux fois de suite rapidement).
Un bloc =#+RESULTS:= avec le résultat de la commande devrait alors apparaître.
Dans la vidéo, nous avons déjà fait une petite démonstration des
principales fonctionnalités d'emacs/org-mode qui vous aideront à tenir
à jour un journal et à faire de la programmation lettrée. Une liste des
principales fonctionnalités et des raccourcis est donnée dans le [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][première
entrée de votre labbook]]. N'hésitez pas à également suivre [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/b031e4067cf8410c86adbeba2f30c92f][cette ressource]] pour découvrir ces raccourcis.
** Étape 6 : Ouvrez et commencez à utiliser votre journal
À l'étape 2, nous vous avons demandé de créer un journal dans le
fichier =~org/journal.org=. C'est dans ce fichier que les notes prises
avec le raccourci =C-c c= (=Ctrl + c= puis =c=) atterrissent. Nous vous
conseillons fortement de vous assurer que ce fichier est stocké dans
un système de contrôle de version comme git. Nous vous laissons la
responsabilité de mettre tout ceci en place mais si vous avez des
problèmes, n'hésitez pas à poser des questions sur le forum du MOOC.
* Un modèle d'article réplicable
Cette section est illustrée dans une [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4#tuto3][vidéo]] (/"Écrire un article
réplicable avec Emacs/Orgmode"/). Nous vous suggérons de la regarder avant de suivre les instructions données dans cette section.
Pour travailler avec ce modèle d'article, vous aurez besoin d'installations fonctionnelles de LaTeX, R, et Python. Si vous ne pouvez pas ouvrir un terminal et exécuter les commandes =R=, =pdflatex=, et =python3=, vous ne pourrez pas générer ce document.
Lors de la compilation, l'article télécharge les paquets LaTeX correspondants. Vous devrez donc également disposer d'une connexion réseau fonctionnelle.
Note pour les utilisateurs de macOS : Puisque l'article est compilé à l'aide de =make=, il vous faudra mettre l'exécutable Emacs dans le chemin de recherche de votre shell (voir [[#rendre-r-et-python-disponible-dans-une-console][la section dédiée à ce sujet]]).
#+begin_src shell :results output :exports none
export FILE_LIST="replicable_article/Makefile replicable_article/article.org replicable_article/biblio.bib replicable_article/article.pdf"
make -C replicable_article/ article.pdf
tar zcf replicable_article.tgz $FILE_LIST
#+end_src
#+RESULTS:
Téléchargez l'[[file:replicable_article.tgz][archive]] suivante et décompressez-la. L'archive contient l'article compilé, vous pouvez donc commencer par le consulter.
Pour reconstruire l'article, supprimez =article.pdf=, ou renommez-le en autre chose. Sinon, la procédure de reconstruction vous indiquera simplement que l'article est déjà à jour. Tapez ensuite =make= pour tout construire à partir de zéro. Ouvrez l'article fraîchement construit =article.pdf= pour voir s'il a l'air correct.
Si vous en avez assez de toujours réexécuter tout le code source lors de l'exportation, recherchez la ligne suivante dans [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/replicable_article/article.org][article.org]] :
#+BEGIN_EXAMPLE
# #+PROPERTY: header-args :eval never-export
#+END_EXAMPLE
Si vous supprimez le =#= au début de la ligne qui indique un commentaire, org-mode arrêtera d'évaluer chaque morceau de code à chaque exportation.
* Emacs trucs et astuces
** Pense-bêtes
L'apprentissage d'Emacs et d'Org-Mode peut être difficile car il y a quantité de raccourcis clavier assez inhumaine.
On trouve donc de nombreux pense-bêtes dont voici une sélection à toute fin utile :
*** Emacs
- [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][Notre liste des raccourcis Emacs les plus utiles dans le contexte de notre configuration emacs /recherche reproductible/.]]
- [[https://www.gnu.org/software/emacs/refcards/pdf/fr-refcard.pdf][Le pense-bête officiel de GNU emacs]]
- Deux superbes pense-bêtes par Sacha Chua sur [[http://sachachua.com/blog/wp-content/uploads/2013/05/How-to-Learn-Emacs-v2-Large.png][comment apprendre Emacs]]
et sur [[http://sachachua.com/blog/wp-content/uploads/2013/08/20130830-Emacs-Newbie-How-to-Learn-Emacs-Keyboard-Shortcuts.png][comment apprendre les raccourcis d'Emacs]].
*** Org-mode
- [[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/rr_org/journal.org][Notre liste des raccourcis Emacs les plus utiles dans le contexte de notre configuration emacs /recherche reproductible/.]]
- [[https://orgmode.org/worg/orgcard.html][Le pense-bête officiel d'org-mode]] ([[https://www.gnu.org/software/emacs/refcards/pdf/orgcard.pdf][en pdf]]).
- [[https://orgmode.org/worg/dev/org-syntax.html][La description officielle de la syntaxe org-mode]] et une [[https://gist.github.com/hoeltgman/3825415][description relativement concise]].
** Tutoriels vidéo
Pour ceux d'entre vous qui préfèrent des explications vidéo, voici une
[[https://www.youtube.com/playlist?list=PL9KxKa8NpFxIcNQa9js7dQIHc81b0-Xg][chaîne Youtube avec de nombreux tutoriels emacs]].
Pour des informations générales sur un certain nombre de paquets, vous pouvez également
vouloir jeter un œil au blog [[https://cestlaz.github.io/stories/emacs/][Using Emacs]].
** Paquets emacs utiles supplémentaires
*** Company-mode
[[http://company-mode.github.io/][Company-mode]] est un paquet permettant d'améliorer les capacités de complétion de texte pour Emacs.
Il offre des capacités de complétion intelligente (et pas uniquement syntaxique) pour la plupart des langages. Si ce type de fonctionnalité vous parait utile, nous vous encourageons à suivre les instructions d'installation du site web officiel:
page Web officielle : [[http://company-mode.github.io/][http://company-mode.github.io/]].
*** Magit
[[https://magit.vc/][Magit]] est une interface Emacs pour Git. Son utilisation est brièvement
illustrée dans le contexte de ce MOOC dans un [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/9cfc7500f0ef46d288d2317ec7b037b4][tutoriel vidéo]].
("/Utilisation Emacs/git/").
C'est un outil vraiment très puissant et nous l'utilisons quotidiennement mais il est nécessaire de
vraiment comprendre ce que fait git dans les coulisses. Si
vous pensez que cela vous serait utile, vous devriez suivre [[https://magit.vc/screenshots/][ce petit tour du propriétaire]] ou bien [[https://www.emacswiki.org/emacs/Magit][cette brève introduction]].
Si vous avez installé notre configuration "/recherche reproductible/",
vous pouvez facilement invoquer magit en utilisant ~C-x g~. Si vous n'êtes pas déjà dans un répertoire sous contrôle de version avec git, Magit vous demandera le chemin de votre copie local du dépôt git
(le chemin vers mooc-rr dans le contexte de ce MOOC).
[[file:emacs_orgmode_images/git1.png]]
Si vous n'utilisez pas notre configuration, vous devriez jeter un coup d'œil à [[https://magit.vc/manual/magit/Installing-from-an-Elpa-Archive.html][comment installer magit à partir d'une archive ELPA]].
La méthode suivante a été testée avec Windows et a fonctionné sans encombre :
- Ajoutez le texte suivant dans votre fichier =.emacs.d/init.el= :
#+begin_src emacs-lisp
(require 'package)
(add-to-list 'package-archives
'("melpa" . "http://melpa.org/packages/") t)
#+end_src
- Lancez Emacs et exécutez les commandes suivantes :
#+BEGIN_EXAMPLE
M-x package-refresh-contents RET
M-x package-install RET magit RET
#+END_EXAMPLE
NB : =M-= (Meta) correspond à la touche =<Alt>= et =RET= correspond à la touche
=<Entrée>=.
** Autres ressources
- The compact Org-mode Guide ([[https://orgmode.org/orgguide.pdf][lien vers le pdf]])
- Une source inépuisable de magie emacs/org-mode: le site web de Bernt Hansen "[[http://doc.norang.ca/org-mode.html][Organisez votre vie en texte brute]]", dont les sources sont évidemment eux-mêmes un [[http://doc.norang.ca/org-mode.org][document org-mode]].
- [[https://github.com/dfeich/org-babel-examples][De nombreux exemples illustrant l'utilisation de différents langages]].
This source diff could not be displayed because it is too large. You can view the blob instead.
# -*- mode: org -*-
#+TITLE: Git and GitLab
#+AUTHOR: Arnaud Legrand
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
......@@ -24,10 +23,21 @@ GitLab.
This document describes the software you need to have installed on
your machine and how to handle authentication. The "Configuring Git"
section is illustrated in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/7508aece244548349424dfd61ee3ba85][video tutorial]] (in French).
section is illustrated in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][video tutorial]] (in French).
Please read all these instructions carefully, in particular the one on
"Configuring your password on GitLab".
* Table of Contents :TOC:
- [[#installing-git][Installing Git]]
- [[#linux-debian-ubuntu][Linux (Debian, Ubuntu)]]
- [[#mac-osx-and-windows][Mac OSX and Windows]]
- [[#configuring-git][Configuring Git]]
- [[#telling-git-who-you-are-name-and-email][Telling Git who you are: Name and Email]]
- [[#dealing-with-proxies][Dealing with proxies]]
- [[#getting-your-default-password-on-gitlab-and-possibly-changing-it][Getting your default password on GitLab (and possibly changing it)]]
- [[#remembering-your-password-locally][Remembering your password locally]]
- [[#optional-authenticating-through-ssh][Optional: authenticating through SSH]]
- [[#using-git-through-the-command-line-to-synchronize-your-local-files-with-gitlab][Using Git through the command line to synchronize your local files with Gitlab]]
* Installing Git
** Linux (Debian, Ubuntu)
......@@ -57,7 +67,11 @@ apt-get update ; apt-get install git
git config --global user.email "email@example.com"
#+end_src
#+RESULTS:
These two steps are really important to commit. If you forget to do
so, you will get the following message:
#+BEGIN_CENTER
[[file:gitlab_images/commit3.png]]
#+END_CENTER
3. Confirm that you have set the Git username correctly:
#+begin_src shell :results output :exports both
......@@ -81,6 +95,12 @@ git config --global http.proxy http://proxyUsername:proxyPassword@proxy.server.c
The =proxyPassword= will be stored in plain text (unencrypted) in your ~.gitconfig~ file,
which you may not want. In that case, remove it from the URL and you
will be prompted for it every time it is needed.
To stop using a proxy, simply use the following command:
#+begin_src shell :results output :exports both
git config --global --unset http.proxy
#+end_src
** Getting your default password on GitLab (and possibly changing it)
*Warning (Jupyter users) :* changing your default Gitlab password will
prevent you from committing in Jupyter. You will have to do the extra
......@@ -88,7 +108,7 @@ step of changing your =~/.git-credentials= in the Jupyter environment
(possibly several times).
1. Get your default password using the [[https://app-learninglab.inria.fr/jupyterhub/services/password][Gitlab credentials retrieval
tool]] as described on the [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/7508aece244548349424dfd61ee3ba85][corresponding resource]].
tool]] as described on the [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][corresponding resource]].
#+BEGIN_CENTER
[[file:gitlab_images/password_retrieval.png]]
#+END_CENTER
......@@ -106,7 +126,7 @@ step of changing your =~/.git-credentials= in the Jupyter environment
#+BEGIN_CENTER
[[file:gitlab_images/erreur405.png]]
#+END_CENTER
2. Access [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/xblock/block-v1:inria+41016+session01bis+type@lti+block@05a0ce425f1741e5bee5049040f70529/handler/preview_handler][GitLab]].
2. Access [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/5571950188c946e790f06d4bc90fb5f6][GitLab]] from the FUN plateform (click on "Accédez à Gitlab / Access to Gitlab" Button).
/Note: Again, you have to access Gitlab from the FUN platform
otherwise you may get a 405 error/ /when trying to direcly open
......@@ -150,6 +170,25 @@ git config credential.helper store
Your password will be then stored in a =.git-credentials= file in plain
text. On a perfectly secured machine, it may be fine... or not... ;)
Use it at your own risk.
To delete all the passwords that may have been stored, simply use the
following command:
#+begin_src shell :results output :exports both
git config --system --unset credential.helper
#+end_src
Finally, those of you using Windows may get the following error
message:
#+BEGIN_EXAMPLE
git: 'credential-cache' is not a git command. See 'get --help'.
#+END_EXAMPLE
This issue is mentioned on [[https://stackoverflow.com/questions/11693074/git-credential-cache-is-not-a-git-command][stackoverflow]]. In such case, try the
following command:
#+begin_src shell :results output :exports both
git config --global --unset credential.helper
#+end_src
If the problem persists, do not hesitate to describe your problem on
the MOOC forum to get some help.
** Optional: authenticating through SSH
There are two ways of authenticating and synchronizing your local
repository with GitLab: through HTTPS or through SSH. The first one is
......
# -*- mode: org -*-
#+TITLE: Git et GitLab
#+AUTHOR: Arnaud Legrand
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
......@@ -24,12 +23,24 @@ synchroniser votre copie locale avec celle de GitLab. Vous devrez
Ce document décrit le logiciel que vous devez installer sur votre
ordinateur et comment gérer l'authentification. La section
"Configuration de Git" est illustrée dans un [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/7508aece244548349424dfd61ee3ba85][tutoriel vidéo]] (en
"Configuration de Git" est illustrée dans un [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][tutoriel vidéo]] (en
français).
Veuillez lire attentivement toutes ces instructions, en particulier
celle sur la "Configuration de votre mot de passe sur GitLab".
* Table des matières :TOC:
- [[#installer-git][Installer Git]]
- [[#linux-debian-ubuntu][Linux (Debian, Ubuntu)]]
- [[#mac-osx-et-windows][Mac OSX et Windows]]
- [[#configurer-git][Configurer Git]]
- [[#dire-à-git-qui-vous-êtes-nom-et-email][Dire à Git qui vous êtes : nom et email]]
- [[#gérer-les-proxy][Gérer les proxy]]
- [[#récupérer-votre-mot-de-passe-par-défaut-sur-gitlab-et-le-changer-éventuellement][Récupérer votre mot de passe par défaut sur GitLab (et le changer éventuellement)]]
- [[#enregistrer-votre-mot-de-passe-localement][Enregistrer votre mot de passe localement]]
- [[#optionnel-authentification-par-ssh][Optionnel : authentification par SSH]]
- [[#utiliser-git-par-lignes-de-commandes-pour-synchroniser-vos-fichiers-locaux-avec-gitlab][Utiliser Git par lignes de commandes pour synchroniser vos fichiers locaux avec Gitlab]]
* Installer Git
** Linux (Debian, Ubuntu)
Nous ne fournissons ici que des instructions pour les distributions
......@@ -59,7 +70,12 @@ apt-get update ; apt-get install git
git config --global user.email "email@example.com"
#+end_src
#+RESULTS:
Ces deux paramètres sont obligatoire pour pouvoir commiter sinon
vous obtiendrez le message suivant:
#+BEGIN_CENTER
[[file:gitlab_images/commit3.png]]
#+END_CENTER
3. Confirmer que vous avez correctement défini le nom d'utilisateur et
l'email Git :
......@@ -86,6 +102,13 @@ Le =proxyPassword= sera stocké en texte brut (non crypté) dans votre
fichier ~.gitconfig~, ce que vous ne souhaitez peut-être pas. Dans ce
cas, supprimez-le de l'URL et vous serez invité à le saisir chaque fois
que vous en aurez besoin.
Pour effacer l'utilisation de ce proxy, il vous suffit d'utiliser cette
commande :
#+begin_src shell :results output :exports both
git config --global --unset http.proxy
#+end_src
** Récupérer votre mot de passe par défaut sur GitLab (et le changer éventuellement)
*Avertissement (utilisateurs Jupyter) :* changer votre mot de passe
Gitlab par défaut vous empêchera de commiter les notebooks Jupyter que
......@@ -94,7 +117,7 @@ supplémentaire de modification de votre =~/.git-credentials= dans
l’environnement Jupyter (éventuellement plusieurs fois).
1. Récupérer votre mot de passe par défaut en utilisant l'outil [[https://app-learninglab.inria.fr/jupyterhub/services/password][Gitlab
credentials retrieval]] comme décrit dans la [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/7508aece244548349424dfd61ee3ba85][ressource correspondante]].
credentials retrieval]] comme décrit dans la [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][ressource correspondante]].
#+BEGIN_CENTER
[[file:gitlab_images/password_retrieval.png]]
#+END_CENTER
......@@ -116,7 +139,7 @@ l’environnement Jupyter (éventuellement plusieurs fois).
#+BEGIN_CENTER
[[file:gitlab_images/erreur405.png]]
#+END_CENTER
2. Accéder à [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/xblock/block-v1:inria+41016+session01bis+type@lti+block@05a0ce425f1741e5bee5049040f70529/handler/preview_handler][GitLab]].
2. Accéder à [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session02/xblock/block-v1:inria+41016+session02+type@lti+block@05a0ce425f1741e5bee5049040f70529/handler/preview_handler][GitLab]].
/Note : Vous devez à nouveau accéder à Gitlab à partir de la plate-forme/
/FUN, sinon vous risquez d'obtenir une erreur 405 en essayant
......@@ -130,9 +153,9 @@ l’environnement Jupyter (éventuellement plusieurs fois).
#+BEGIN_CENTER
[[file:gitlab_images/signin.png]]
#+END_CENTER
4. Si vous souhaitez modifier votre mot de passe, accédez à =Account >
Settings > Password= et définissez votre mot de passe à l'aide du mot
de passe par défaut que vous venez de récupérer. Encore une fois, si
4. Si vous souhaitez modifier votre mot de passe, accédez à
=Account > Settings > Password= et définissez votre mot de passe à l'aide
du mot de passe par défaut que vous venez de récupérer. Encore une fois, si
vous utilisez les notebooks Jupyter que nous avons déployés pour le
MOOC, n’oubliez pas que changer votre mot de passe Gitlab par défaut
vous empêchera de les commiter. Vous devrez effectuer l’étape
......@@ -168,6 +191,25 @@ Votre mot de passe sera alors stocké dans un fichier =.git-credentials=
en texte brut (non-crypté). Sur une machine parfaitement sécurisée,
cela peut être très bien... ou pas... ;) Utilisez cette possibilité à
vos risques et périls.
Si vous souhaitez effacer les mots de passe enregistrés, il vous
suffit d'utiliser cette commande :
#+begin_src shell :results output :exports both
git config --system --unset credential.helper
#+end_src
Enfin, il peut arriver que vous ayez le message d'erreur suivant sous
Windows :
#+BEGIN_EXAMPLE
git: 'credential-cache' is not a git command. See 'get --help'.
#+END_EXAMPLE
Ce problème est évoqué sur [[https://stackoverflow.com/questions/11693074/git-credential-cache-is-not-a-git-command][stackoverflow]]. Dans ce cas, tentez la
commande suivante :
#+begin_src shell :results output :exports both
git config --global --unset credential.helper
#+end_src
Si ça ne marche toujours pas, n'hésitez pas à décrire votre problème
sur le forum du MOOC.
** Optionnel : authentification par SSH
Il existe deux manières d'authentifier et de synchroniser votre
dépôt local avec GitLab : via HTTPS ou via SSH. Le premier est ce
......@@ -208,14 +250,14 @@ Cette section décrit un moyen générique (par lignes de commandes) de
synchroniser vos fichiers locaux avec Gitlab. Vous n'en aurez pas
besoin si vous suivez le parcours Jupyter. Si vous suivez le parcours
RStudio, toutes ces opérations peuvent être effectuées via RStudio et
vous voudrez peut-être lire [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/1a4f58a1efed437c93a9f5c5f15df428][les instructions correspondantes]]. Si vous
vous voudrez peut-être lire [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/1a4f58a1efed437c93a9f5c5f15df428][les instructions correspondantes]]. Si vous
suivez le chemin Org-Mode, toutes ces opérations peuvent être
effectuées via Magit et vous voudrez peut-être lire
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/508299f7373449a3939faa5b11462bc4][les instructions correspondantes]].
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/508299f7373449a3939faa5b11462bc4][les instructions correspondantes]].
Voici d'autres moyens d'apprendre Git par lignes de commandes :
- Le [[http://swcarpentry.github.io/git-novice/][Software Carpentry git tutorial]]
- Le [[http://swcarpentry.github.io/git-novice/][Software Carpentry Git tutorial]]
- Le livre Pro Git (gratuit) en [[https://git-scm.com/book/en/v2][englais]] ou en [[https://git-scm.com/book/fr/v2][français]]. Les deux
premiers chapitres suffisent pour bien commencer.
- Le site [[https://learngitbranching.js.org/][Apprenez Git Branching]] permet d'apprendre Git
......@@ -296,7 +338,7 @@ Maintenant, commençons !
sauf si vous avez suivi les instructions de la partie /Enregistrer
votre mot de passe localement/.
NB : vous ne serez pas autorisé à propager vos modifications dans
N.B. : vous ne serez pas autorisé à propager vos modifications dans
GitLab si d'autres modifications ont été propagées entre temps (par
exemple par quelqu'un d'autre).
......
<div id="content">
<h1 class="title">Jupyter</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#orgd37ebcc">1. Jupyter tips and tricks</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#orge426487">Creating or importing a notebook</a></li>
<li style="margin-bottom:0;"><a href="#org6607533">Running R and Python in the same notebook</a></li>
<li style="margin-bottom:0;"><a href="#orgd909163">Other languages</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#org9176019">2. Installing and configuring Jupyter on your computer</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org51b3378">2.1 Installing Jupyter</a></li>
<li style="margin-bottom:0;"><a href="#orgc0d2a71">2.2 Making sure Jupyter allows you to use R</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org608c96e">• Installing IRKernel (R package)</a></li>
<li style="margin-bottom:0;"><a href="#org076acd5">• Installing rpy2 (Python package)</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#org524a8ac">2.3 Additional tips</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org814c076">• Exporting a notebook</a></li>
<li style="margin-bottom:0;"><a href="#orga5ae744">• Improving notebook readability</a></li>
<li style="margin-bottom:0;"><a href="#orgab0846a">• Interacting with GitLab and GitHub</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-orgd37ebcc" class="outline-2">
<h2 id="orgd37ebcc">1. Jupyter tips and tricks</h2>
<div class="outline-text-2" id="text-orgd37ebcc">
<p>
The following <a href="https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/">webpage</a> lists several Jupyter tricks (in particular, it
illustrates many <code>IPython magic</code> commands) that should improve your
efficiency (note that this blog post is about two years old so some of
the tricks may have been integrated in the default behavior of Jupyter
now).
</p>
</div>
<div id="outline-container-orge426487" class="outline-3">
<h3 id="orge426487">Creating or importing a notebook</h3>
<div class="outline-text-3" id="text-orge426487">
<p>
Using the Jupyter environment we deployed for this MOOC will allow to
easily access any file from your default GitLab project. There are
situations however where you may want to play with other notebooks.
</p>
<dl class="org-dl">
<dt>Adding a brand new notebook in a given directory</dt><dd>Simply follow
the following steps:
<ol class="org-ol">
<li style="margin-bottom:0;">From the menu: <code>File -&gt; Open</code>. You're now in the Jupyter file manager.</li>
<li style="margin-bottom:0;">Navigate to the directory where you want your notebook to be created.</li>
<li style="margin-bottom:0;">Then from the top right button: <code>New -&gt; Notebook: Python 3</code>.</li>
<li style="margin-bottom:0;"><p>
Give your notebook a name from the menu: <code>File -&gt; Rename</code>.
</p>
<p>
N.B.: If you create a file by doing <code>File -&gt; New Notebook -&gt;
Python 3</code>, the new notebook will be created in the current
directory. Moving it afterward is possible but a bit cumbersome
(you'll have to go through the Jupyter file manager by following
the menu <code>File -&gt; Open</code>, then select it, <code>Shut</code> it <code>down</code>, and <code>Move</code>
and/or <code>Rename</code>).
</p></li>
</ol></dd>
<dt>Importing an already existing notebook</dt><dd>If your notebook is
already in your GitLab project, then simply synchronize by using
the <code>Git pull</code> button and use the <code>File -&gt; Open</code> menu. Otherwise,
imagine, you want to import the <a href="https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/src/Python3/challenger.ipynb">following notebook</a> from someone
else's repository to re-execute it.
<ol class="org-ol">
<li style="margin-bottom:0;">Download the file on your computer. E.g., for this <a href="https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/src/Python3/challenger.ipynb">GitLab hosted
notebook</a>, click on <code>Open raw</code> (a small <code>&lt;/&gt;</code> within a document icon)
and save (<code>Ctrl-S</code> on most browsers) the content (a long Json text
file).</li>
<li style="margin-bottom:0;">Open the Jupyter file manager from the menu <code>File -&gt; Open</code> and
navigate to the directory where you want to upload your notebook.</li>
<li style="margin-bottom:0;">Then from the top right button, <code>Upload</code> the previously downloaded
notebook and confirm the upload.</li>
<li style="margin-bottom:0;">Open the freshly uploaded notebook through the Jupyter file
manager.</li>
</ol></dd>
</dl>
</div>
</div>
<div id="outline-container-org6607533" class="outline-3">
<h3 id="org6607533">Running R and Python in the same notebook</h3>
<div class="outline-text-3" id="text-org6607533">
<p>
<code>rpy2</code> package allows to use both languages in the same notebook by:
</p>
<ol class="org-ol">
<li style="margin-bottom:0;"><p>
Loading <code>rpy2</code>:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-python">%load_ext rpy2.ipython
</pre>
</div></li>
<li style="margin-bottom:0;"><p>
Using the <code>%R</code> Ipython magic:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-python">%%R
summary(cars)
</pre>
</div>
<p>
Python objects can then even be passed to R as follows (assuming <code>df</code>
is a pandas dataframe):
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-python">%%R -i df
plot(df)
</pre>
</div></li>
</ol>
<p>
Note that this <code>%%R</code> notation indicates that R should be used for the whole cell but
an other possibility is to use <code>%R</code> to have a single line of R within a
python cell.
</p>
</div>
</div>
<div id="outline-container-orgd909163" class="outline-3">
<h3 id="orgd909163">Other languages</h3>
<div class="outline-text-3" id="text-orgd909163">
<p>
Jupyter is not limited to Pytyhon and R. Many other languages are available:
<a href="https://github.com/jupyter/jupyter/wiki/Jupyter-kernels">https://github.com/jupyter/jupyter/wiki/Jupyter-kernels</a>, including
non-free languages like SAS, Mathematica, Matlab&#x2026; Note that the maturity of these kernels differs widely.
</p>
<p>
None of these other languages have been deployed in the context of our
MOOC but you may want to read the next sections to learn how
to set up your own Jupyter on your computer and benefit from these extensions.
</p>
<p>
Since the question was asked several times, if you really need to stay
with SAS, you should know that SAS can be used within Jupyter using
either the <a href="https://sassoftware.github.io/sas_kernel/">Python SASKernel</a> or the <a href="https://sassoftware.github.io/saspy/">Python SASPy</a> package (step by step
explanations about this are given <a href="https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md">here</a>).
</p>
<p>
Since proprietary software such as SAS cannot easily be inspected, we discourage its use as it hinders reproducibility by
essence. But perfection does not exist anyway and using Jupyter
literate programming approach allied with systematic control version
and environment control will certainly help anyway.
</p>
</div>
</div>
</div>
<div id="outline-container-org9176019" class="outline-2">
<h2 id="org9176019">2. Installing and configuring Jupyter on your computer</h2>
<div class="outline-text-2" id="text-org9176019">
<p>
In this section, we explain how to set up a Jupyter environment on
your own computer similar to the one deployed for this MOOC.
</p>
<p>
Note that Jupyter notebooks are only a small part of the picture and
that Jupyter is now part of a bigger project: <a href="https://blog.jupyter.org/jupyterlab-is-ready-for-users-5a6f039b8906">JupyterLab</a>, which allows
you to mix various components (including notebooks) in your
browser. In the context of this MOOC, our time frame was too short to
benefit from JupyterLab which was still under active development. You may, however, prefer JupyterLab when doing an installation on your own computer.
</p>
</div>
<div id="outline-container-org51b3378" class="outline-3">
<h3 id="org51b3378">2.1 Installing Jupyter</h3>
<div class="outline-text-3" id="text-org51b3378">
<p>
Follow these instructions if you wish to have a Jupyter environment on
your own computer similar to the one we set up for this MOOC.
</p>
<p>
First, download and install the <a href="https://conda.io/miniconda.html">latest version of Miniconda</a>. We use
Miniconda version <code>4.5.4</code> and Python version <code>3.6</code> on our server.
</p>
<p>
Miniconda is a light version of Anaconda, which includes Python, the Jupyter Notebook, and other commonly used packages for scientific computing and data science.
</p>
<p>
Then download the <a href="https://gist.github.com/brospars/4671d9013f0d99e1c961482dab533c57">mooc<sub>rr</sub> environment file</a> and create the environment using conda:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">conda env create -f environment.yml
<span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">Windows activate the environment</span>
activate mooc_rr
<span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">Linux and MacOS activate the environment</span>
<span style="font-weight: bold;">source</span> activate mooc_rr
<span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">Linux, MacOS and Windows: launch the notebook</span>
jupyter notebook
</pre>
</div>
</div>
</div>
<div id="outline-container-orgc0d2a71" class="outline-3">
<h3 id="orgc0d2a71">2.2 Making sure Jupyter allows you to use R</h3>
<div class="outline-text-3" id="text-orgc0d2a71">
<p>
The environment described in the last section should include R, but if
you proceeded otherwise and only have Python available in Jupyter, you
may want to read the following section.
</p>
</div>
<div id="outline-container-org608c96e" class="outline-4">
<h4 id="org608c96e">• Installing <a href="https://github.com/IRkernel/IRkernel">IRKernel</a> (R package)</h4>
<div class="outline-text-4" id="text-org608c96e">
<p>
Do the following in R console:
</p>
<p>
Install the <code>devtools</code> package:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-R">install.packages(<span style="font-style: italic;">'devtools'</span>,dep=<span style="font-weight: bold; text-decoration: underline;">TRUE</span>)
</pre>
</div>
<p>
Define a proxy if needed:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-R"><span style="font-weight: bold; text-decoration: underline;">library</span>(httr)
set_config(use_proxy(url=<span style="font-style: italic;">"proxy"</span>, port=80, username=<span style="font-style: italic;">"username"</span>, password=<span style="font-style: italic;">"password"</span>))
</pre>
</div>
<p>
Install the <code>IRkernel</code> package:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-R">devtools::install_github(<span style="font-style: italic;">'IRkernel/IRkernel'</span>)
IRkernel::installspec() <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">to register the kernel in the current R installation</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org076acd5" class="outline-4">
<h4 id="org076acd5">• Installing rpy2 (Python package)</h4>
<div class="outline-text-4" id="text-org076acd5">
<p>
On Linux, the rpy2 package is available in standard distributions
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">sudo apt-get install python3-rpy2 python3-tzlocal
</pre>
</div>
<p>
An alternative (not really recommended if the first one is available)
consists in going through the python package manager with
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-python">pip3 install rpy2
</pre>
</div>
<p>
<b>Windows</b>
</p>
<p>
Download the <code>rpy2</code> <a href="https://www.lfd.uci.edu/~gohlke/pythonlibs/#rpy2">binary file</a> by choosing the right operating system.
</p>
<p>
Open a DOS console and type the following command:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">python -m pip install rpy2&#8209;2.9.4&#8209;cp37&#8209;cp37m&#8209;win_amd64.whl <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">adapt filename</span>
</pre>
</div>
<p>
Install also <code>tzlocal</code>:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">python -m pip install tzlocal
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org524a8ac" class="outline-3">
<h3 id="org524a8ac">2.3 Additional tips</h3>
<div class="outline-text-3" id="text-org524a8ac">
</div>
<div id="outline-container-org814c076" class="outline-4">
<h4 id="org814c076">• Exporting a notebook</h4>
<div class="outline-text-4" id="text-org814c076">
<p>
Here is what we had to install on a recent Debian computer to make sure
the notebook export via LaTeX works:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">sudo apt-get install texlive-xetex wkhtmltopdf
</pre>
</div>
<p>
Obviously, you can convert to html or pdf using the using the <code>File &gt; Download as &gt; HTML</code> (or <code>PDF</code>) menu option. This can also be done from
the command line with the following command:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-sh">ipython3 nbconvert --to pdf Untitled.ipynb
</pre>
</div>
<p>
If you want to use a specific style, then the <code>nbconvert</code> exporter
should be customized. This is discussed and demoed <a href="http://markus-beuckelmann.de/blog/customizing-nbconvert-pdf.html">here</a>. We encourage
you to simply read the <a href="https://nbconvert.readthedocs.io/en/latest/">doc of nbconvert</a>.
</p>
<p>
Instead of going directly through LaTeX and playing too much with the
<code>nbconvert</code> exporter, an other option consists in exporting to Markdown
and playing with <a href="https://pandoc.org/">pandoc</a>. Both approaches work, it's rather a matter of
taste.
</p>
<p>
<b>Windows</b>
</p>
<p>
Download and install MiKTeX from the <a href="https://miktex.org/download">MiKTeX webpage</a> by choosing the
right operating system. You will be prompted to install some specific
packages when exporting to pdf.
</p>
</div>
</div>
<div id="outline-container-orga5ae744" class="outline-4">
<h4 id="orga5ae744">• Improving notebook readability</h4>
<div class="outline-text-4" id="text-orga5ae744">
<p>
Here are a few extensions that can ease your life:
</p>
<ul class="org-ul">
<li style="margin-bottom:0;"><p>
<a href="https://stackoverflow.com/questions/33159518/collapse-cell-in-jupyter-notebook">Code folding</a> to improve readability when browsing the notebook.
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">pip3 install jupyter_contrib_nbextensions
<span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">jupyter contrib nbextension install --user # not done yet</span>
</pre>
</div></li>
<li style="margin-bottom:0;"><p>
<a href="https://github.com/kirbs-/hide_code">Hiding code</a> to improve readability when exporting.
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-sh">sudo pip3 install hide_code
sudo jupyter-nbextension install --py hide_code
jupyter-nbextension enable --py hide_code
jupyter-serverextension enable --py hide_code
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-orgab0846a" class="outline-4">
<h4 id="orgab0846a">• Interacting with GitLab and GitHub</h4>
<div class="outline-text-4" id="text-orgab0846a">
<p>
To ease your experience, we added pull/push buttons that allow
you to commit and sync with GitLab. This development was specific to
the MOOC but inspired from a previous <a href="https://github.com/Lab41/sunny-side-up">proof of concept</a>. We have
recently discovered that someone else developed about at the same time
a <a href="https://github.com/sat28/githubcommit">rather generic version of this Jupyter plugin</a>. Otherwise, remember
that it is very easy to insert a shell cell in Jupyter in which you
can easily issue git commands. This is how we work most of the time.
</p>
<p>
This being said, you may have noticed that Jupyter keeps a perfect
track of the sequence in which cells have been run by updating the
"output index". This is a very good property from the reproducibility
point of view but depending on your usage, you may find it a bit
painful when committing. Some people have thus developed <a href="https://gist.github.com/pbugnion/ea2797393033b54674af">specific git
hooks</a> to ignore these numbers when committing Jupyter notebooks. There
is a long an interesting discussion about various options on
<a href="https://stackoverflow.com/questions/18734739/using-ipython-notebooks-under-version-control">StackOverflow</a>.
</p>
<p>
For those who use <a href="https://blog.jupyter.org/jupyterlab-is-ready-for-users-5a6f039b8906">JupyterLab</a> rather than the plain Jupyter, a specific <a href="https://github.com/jupyterlab/jupyterlab-git">JupyterLab git plugin</a> has been developed to offer a nice version control experience.
</p>
</div>
</div>
</div>
</div>
</div>
# -*- mode: org -*-
#+TITLE: Jupyter
#+TITLE: Jupyter : tips and tricks, installing and configuring
#+AUTHOR: Arnaud Legrand, Benoit Rospars, Konrad Hinsen
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* 1. Jupyter tips and tricks
Once you will have followed all these installation instructions, you
will be able to run jupyter notebooks by simply typing in a shell/DOS
command:
#+begin_src shell :results output :exports both
jupyter notebook
#+end_src
* Table of Contents :TOC:
- [[#jupyter-tips-and-tricks][Jupyter tips and tricks]]
- [[#creating-or-importing-a-notebook][Creating or importing a notebook]]
- [[#running-r-and-python-in-the-same-notebook][Running R and Python in the same notebook]]
- [[#other-languages][Other languages]]
- [[#installing-and-configuring-jupyter-on-your-computer][Installing and configuring Jupyter on your computer]]
- [[#installing-jupyter-and-python-r-][Installing Jupyter (and Python, R, ...)]]
- [[#making-sure-jupyter-allows-you-to-use-r][Making sure Jupyter allows you to use R]]
- [[#latex-for-pdf-export][LaTeX for PDF export]]
- [[#additional-tips][Additional tips]]
- [[#interacting-with-gitlab-and-git][Interacting with GitLab and Git]]
* Jupyter tips and tricks
The following [[https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/][webpage]] lists several Jupyter tricks (in particular, it
illustrates many =IPython magic= commands) that should improve your
efficiency (note that this blog post is about two years old so some of
......@@ -32,11 +51,11 @@ situations however where you may want to play with other notebooks.
- Importing an already existing notebook :: If your notebook is
already in your GitLab project, then simply synchronize by using
the =Git pull= button and use the =File -> Open= menu. Otherwise,
imagine, you want to import the [[https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/src/Python3/challenger.ipynb][following notebook]] from someone
imagine, you want to import the [[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/blob/master/src/Python3/challenger.ipynb][following notebook]] from someone
else's repository to re-execute it.
1. Download the file on your computer. E.g., for this [[https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/src/Python3/challenger.ipynb][GitLab hosted
1. Download the file on your computer. E.g., for this [[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/blob/master/src/Python3/challenger.ipynb][GitLab hosted
notebook]], click on =Open raw= (a small =</>= within a document icon)
and save (=Ctrl-S= on most browsers) the content (a long Json text
and save (=Ctrl-S= on most browsers) the content (a long JSON text
file).
2. Open the Jupyter file manager from the menu =File -> Open= and
navigate to the directory where you want to upload your notebook.
......@@ -44,8 +63,16 @@ situations however where you may want to play with other notebooks.
notebook and confirm the upload.
4. Open the freshly uploaded notebook through the Jupyter file
manager.
You will find [[file:../../documents/notebooks/][here]] a list of jupyter notebooks that illustrate how
different languages (python, R, SAS) can be used in Jupyter.
** Running R and Python in the same notebook
=rpy2= package allows to use both languages in the same notebook by:
It used to be impossible with earlier versions of Jupyter but it is
now very easy thanks to the the =rpy2= package (see the details of the
installation procedurer in the corresponding section below) that
allows you to use both languages in the same notebook. Simply open a
new python notebook and follow these instructions:
1. Loading =rpy2=:
#+begin_src python :results output :exports both
%load_ext rpy2.ipython
......@@ -64,8 +91,11 @@ situations however where you may want to play with other notebooks.
Note that this =%%R= notation indicates that R should be used for the whole cell but
an other possibility is to use =%R= to have a single line of R within a
python cell.
[[file:../../documents/notebooks/notebook_Jupyter_Python_R.ipynb][Here]] is an notebook example using both R et Python
** Other languages
Jupyter is not limited to Pytyhon and R. Many other languages are available:
Jupyter is not limited to Python and R. Many other languages are available:
[[https://github.com/jupyter/jupyter/wiki/Jupyter-kernels][https://github.com/jupyter/jupyter/wiki/Jupyter-kernels]], including
non-free languages like SAS, Mathematica, Matlab... Note that the maturity of these kernels differs widely.
......@@ -73,17 +103,65 @@ None of these other languages have been deployed in the context of our
MOOC but you may want to read the next sections to learn how
to set up your own Jupyter on your computer and benefit from these extensions.
Since the question was asked several times, if you really need to stay
with SAS, you should know that SAS can be used within Jupyter using
either the [[https://sassoftware.github.io/sas_kernel/][Python SASKernel]] or the [[https://sassoftware.github.io/saspy/][Python SASPy]] package (step by step
explanations about this are given [[https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md][here]]).
*** SAS
SAS is a proprietary statistical software which is very commonly used
in health research. Since the question was asked several times, if you
really need to stay with SAS, you should know that SAS can be used
within Jupyter using either the [[https://sassoftware.github.io/sas_kernel/][Python SASKernel]] (similar to the
=IRKernel=) or the [[https://sassoftware.github.io/saspy/][Python SASPy]] package (similar to the =rpy2= package).
Since proprietary software such as SAS cannot easily be inspected, we
discourage its use as it hinders reproducibility by essence. But
perfection does not exist anyway and using Jupyter literate
programming approach allied with systematic control version and
environment control will certainly help anyway.
*[[https://sassoftware.github.io/saspy/][SASPy]]*
- Install =saspy= with the =pip= command. E.g.,
#+begin_src shell :results output :exports both
python -m pip install saspy
#+end_src
- On Windows, you will have to modify the file =C:\Program
Files\Python\Python37\Lib\site-packages\saspy\sascfg_sav.py= and to
adapt it to your own system. In both following screenshots, the left
window corresponds to the initial file and the right window
corresponds to the modified one:
#+BEGIN_CENTER
[[file:jupyter_images/sascfg1.png]]
#+END_CENTER
#+BEGIN_CENTER
[[file:jupyter_images/sascfg2.png]]
#+END_CENTER
- Here is a [[file:../../documents/notebooks/notebook_Jupyter_Python_SAS.ipynb][example of Python/SAS notebook]].
- NB : Some people from the first edition of the MOOC reported us that
the pdf export did not not seem to work for SAS notebooks. However,
they could obtain pdf files through pandoc. E.g., export in HTML (or
markdown) in jupyter and then run:
#+begin_src shell :results output :exports both
pandoc --variable=geometry:a4paper --variable=geometry:margin=1in notebook_sas.html -o notebook_sas.pdf
#+end_src
- Useful link: https://sassoftware.github.io/saspy/
Since proprietary software such as SAS cannot easily be inspected, we discourage its use as it hinders reproducibility by
essence. But perfection does not exist anyway and using Jupyter
literate programming approach allied with systematic control version
and environment control will certainly help anyway.
*[[https://sassoftware.github.io/sas_kernel/install.html][SASKernel]]*
* 2. Installing and configuring Jupyter on your computer
- The =sas_kernel= is based on the =saspy= so first instll =saspy= by
following the previous instructions.
- Install the =sas_kernel= package through =pip=. E.g.,
#+begin_src shell :results output :exports both
python -m pip install sas_kernel
#+end_src
- You will then be able to create SAS notebooks
#+BEGIN_CENTER
[[file:jupyter_images/new_notebook.png]]
#+END_CENTER
#+BEGIN_CENTER
[[file:jupyter_images/notebook_SAS.png]]
#+END_CENTER
Please note the top right SAS icon.
- Here is a [[file:../../documents/notebooks/notebook_Jupyter_SAS.ipynb][example of SAS notebook]].
- Useful link: https://sassoftware.github.io/sas_kernel/install.html
* Installing and configuring Jupyter on your computer
In this section, we explain how to set up a Jupyter environment on
your own computer similar to the one deployed for this MOOC.
......@@ -93,7 +171,7 @@ you to mix various components (including notebooks) in your
browser. In the context of this MOOC, our time frame was too short to
benefit from JupyterLab which was still under active development. You may, however, prefer JupyterLab when doing an installation on your own computer.
** 2.1 Installing Jupyter
** Installing Jupyter (and Python, R, ...)
Follow these instructions if you wish to have a Jupyter environment on
your own computer similar to the one we set up for this MOOC.
......@@ -115,35 +193,66 @@ source activate mooc_rr
# Linux, MacOS and Windows: launch the notebook
jupyter notebook
#+end_src
** 2.2 Making sure Jupyter allows you to use R
** Making sure Jupyter allows you to use R
The environment described in the last section should include R, but if
you proceeded otherwise and only have Python available in Jupyter, you
may want to read the following section.
*** • Installing [[https://github.com/IRkernel/IRkernel][IRKernel]] (R package)
Do the following in R console:
IRKernel will allow you to manage notebooks using natively R rather
than python. We assume in this section that you already have a working
installation of R
Install the =devtools= package:
*Windows*
On Windows, you are unlikely to have the tools allowing you to compile
and install the latest version of IRKernel and you should rather
install the binary version. In an R console (or in Rstudio), type the
following commands:
#+begin_src R :results output :session *R* :exports both
install.packages('devtools',dep=TRUE)
install.packages('IRkernel',dep=TRUE)
IRkernel::installspec() # to register the kernel in the current R installation
#+end_src
Define a proxy if needed:
Right below, you will find a few explanations on how to use an R
notebook.
#+begin_src R :results output :session *R* :exports both
library(httr)
set_config(use_proxy(url="proxy", port=80, username="username", password="password"))
#+end_src
*Linux or Mac*
Install the =IRkernel= package:
To install the latest version of IRkernel, open an R console or
Rstudio.
- Install the =devtools= package:
#+begin_src R :results output :session *R* :exports both
install.packages('devtools',dep=TRUE)
#+end_src
- Define a proxy if needed (this is important if you are working in a
company which limits the access to the Internet):
#+begin_src R :results output :session *R* :exports both
library(httr)
set_config(use_proxy(url="proxy", port=80, username="username", password="password"))
#+end_src
#+begin_src R :results output :session *R* :exports both
devtools::install_github('IRkernel/IRkernel')
IRkernel::installspec() # to register the kernel in the current R installation
#+end_src
- Install the =IRkernel= package:
#+begin_src R :results output :session *R* :exports both
devtools::install_github('IRkernel/IRkernel')
IRkernel::installspec() # to register the kernel in the current R installation
#+end_src
You will then be able to create native R notebooks:
[[file:jupyter_images/new_notebook.png]]
[[file:jupyter_images/notebook_R.png]]
Note the R icon in the top right
corner. [[file:../..//documents/notebooks/notebook_Jupyter_R.ipynb][Here
is an example of R notebook]].
*** • Installing rpy2 (Python package)
On Linux, the rpy2 package is available in standard distributions
The =rpy2= package allows python to seamlessly call R and therefore to
have both languages in the same notebook.
*Linux or Mac*
On Linux, the rpy2 package is available in standard distributions. For
example on debian or ubuntu:
#+begin_src shell :results output :exports both
sudo apt-get install python3-rpy2 python3-tzlocal
#+end_src
......@@ -157,7 +266,7 @@ pip3 install rpy2
Download the =rpy2= [[https://www.lfd.uci.edu/~gohlke/pythonlibs/#rpy2][binary file]] by choosing the right operating system.
Open a DOS console and type the following command:
Open a DOS console, move to the /download/ directory and type the following command:
#+begin_src shell :results output :exports both
python -m pip install rpy2‑2.9.4‑cp37‑cp37m‑win_amd64.whl # adapt filename
#+end_src
......@@ -166,7 +275,17 @@ Install also =tzlocal=:
#+begin_src shell :results output :exports both
python -m pip install tzlocal
#+end_src
** 2.3 Additional tips
If you ever run into troubles, you may want to have a look on
[[https://stackoverflow.com/questions/14882477/rpy2-install-on-windows-7][StackOverflow]] (NB : when we tried it, there has been no need to define
the =R_HOME= and =R_USER= environnement variables).
You should be able to run Jupyter and to create a python notebook that runs
R commands by following the instructions given in the beginning of
this document (look for =rpy2=).
** LaTeX for PDF export
For exporting your notebooks as PDF files, you must also install LaTeX on your system. We describe this process in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/19c2b1de7766484bae73f3ab133463c6][separate resource]].
** Additional tips
*** • Exporting a notebook
Here is what we had to install on a recent Debian computer to make sure
the notebook export via LaTeX works:
......@@ -211,14 +330,32 @@ Here are a few extensions that can ease your life:
jupyter-serverextension enable --py hide_code
#+end_src
*** • Interacting with GitLab and GitHub
Then in jupyter, choose =Hide_code= in the menu
#+BEGIN_CENTER
[[file:jupyter_images/menu_hide_code.png]]
#+END_CENTER
You should then obtain this:
#+BEGIN_CENTER
[[file:jupyter_images/hide_code.png]]
#+END_CENTER
You should then use the icons to export rather than going through
the menu:
#+BEGIN_CENTER
[[file:jupyter_images/export_hide_code.png]]
#+END_CENTER
NB: In the first edition of the MOOC some people had issues making
it work under Windows.
** • Interacting with GitLab and git
To ease your experience, we added pull/push buttons that allow
you to commit and sync with GitLab. This development was specific to
the MOOC but inspired from a previous [[https://github.com/Lab41/sunny-side-up][proof of concept]]. We have
recently discovered that someone else developed about at the same time
a [[https://github.com/sat28/githubcommit][rather generic version of this Jupyter plugin]]. Otherwise, remember
that it is very easy to insert a shell cell in Jupyter in which you
can easily issue git commands. This is how we work most of the time.
can easily issue git commands. This is how we work most of the time. If you choose this solution, you will have to configure Git on your
computer. To do this, you can follow the video
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][Configure git for Gitlab]] and read the document
[[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/gitlab.org][Git and GitLab]].
This being said, you may have noticed that Jupyter keeps a perfect
track of the sequence in which cells have been run by updating the
......
# -*- mode: org -*-
#+TITLE: Jupyter : Trucs et astuces, installation et configuration
#+AUTHOR: Arnaud Legrand, Benoit Rospars, Konrad Hinsen
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
Quand vous aurez suivi les instructions suivantes, vous
pourrez ouvrir des notebooks jupyter en tapant une commande shell/DOS
command:
#+begin_src shell :results output :exports both
jupyter notebook
#+end_src
* Table des matières :TOC:
- [[#jupyter-trucs-et-astuces][Jupyter : Trucs et astuces]]
- [[#création-ou-import-dun-notebook][Création ou import d'un notebook]]
- [[#exécuter-du-code-r-et-du-code-python-dans-le-même-notebook][Exécuter du code R et du code Python dans le même notebook]]
- [[#autres-langages-que-python-et-r][Autres langages que Python et R]]
- [[#installation-et-configuration-de-jupyter-sur-votre-ordinateur][Installation et configuration de Jupyter sur votre ordinateur]]
- [[#installation-de-jupyter-et-de-python-r-][Installation de Jupyter (et de Python, R...)]]
- [[#sassurer-que-jupyter-vous-permet-dutiliser-r][S'assurer que Jupyter vous permet d'utiliser R]]
- [[#latex-pour-la-génération-de-pdf][LaTeX pour la génération de PDF]]
- [[#conseils-additionnels][Conseils additionnels]]
- [[#interaction-avec-gitlab-et-git][Interaction avec GitLab et git]]
* Jupyter : Trucs et astuces
Cette [[https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/][page web]] (en anglais) recense un certain nombre d'astuces
relatives à l'utilisation de Jupyter (et en particulier des
illustrations des nombreuses commandes magiques =IPython magic=) et
susceptibles d'améliorer votre efficacité (notez bien que ce billet a
plus de deux ans que Jupyter évoluant très rapidement, certaines de
ces astuces ou de ces modules complémentaires font maintenant partie
du comportement par défaut des versions les plus récentes de Jupyter).
** Création ou import d'un notebook
L'environnement Jupyter que nous avons déployé dans le cadre de ce
MOOC vous permettra d'accéder très simplement à tout fichier (et en
particulier les notebooks des différents exercices que nous avons
créés pour vous) de votre projet gitlab par défaut. Il y a néanmoins
des situations où vous pouvez vouloir utiliser d'autres notebooks que
ceux du MOOC.
- Créer un notebook tout neuf dans un répertoire donné ::
1. À partir du menu : =File -> Open=. Ceci vous permet d'accéder au
gestionnaire de fichiers de Jupyter.
2. Naviguez jusque dans le répertoire dans lequel vous souhaitez
créer votre notebook.
3. Utilisez le bouton en haut à droite : =New -> Notebook: Python 3=.
4. Donnez un nom à votre notebook à partir du menu : =File -> Rename=.
N.B. : Si vous créez un notebook à partir du menu ~File -> New Notebook -> Python 3~,
il sera créé dans le répertoire courant. Le
déplacer après coup est un peu pénible. Il vous faudra aller dans
le gestionnaire de fichiers de Jupyter (menu =File -> Open=),
sélectionner le notebook, l'arrêter (=Shutdown=), puis le déplacer
(=Move=) et/ou le renommer (=Rename=).
- Importer un notebook déjà existant :: Si le notebook qui vous
intéresse est déjà dans votre projet GitLab, il vous suffit de
synchroniser la copie de votre Jupyter à l'aide du bouton =Git pull=
et d'utiliser le menu =File -> Open=. Dans le cas contraire,
par exemple si souhaitez importer cet
[[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/blob/master/src/Python3/challenger.ipynb][autre notebook]]
rédigé par quelqu'un d'autre, procédez de la façon suivante :
1. Téléchargez le fichier sur votre répertoire. Pour ce [[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/blob/master/src/Python3/challenger.ipynb][Notebook
hébergé sur un gitLab]], cliquez sur =Open raw= (l'icone avec
un petit =</>= ) et sauvegardez (=Ctrl-S= sur la plupart des
navigateurs) son contenu (un long fichier texte au format JSON).
2. Ouvrez le gestionnaire de fichiers de Jupyter via le menu =File -> Open=
et naviguez jusqu'au répertoire où vous souhaitez déposer votre notebook.
3. Utilisez le bouton en haut à droite =Upload= pour transférer le
document de votre ordinateur vers le serveur Jupyter et confirmez
l'upload.
4. Vous pouvez maintenant ouvrir le notebook fraîchement récupéré
à l'aide du navigateur de fichiers de Jupyter et réexécuter le
code correspondant.
** Exécuter du code R et du code Python dans le même notebook
C'était impossible avec les premières versions de Jupyter mais c'est
désormais très facile grâce à la bibliothèque Python =rpy2= (les détails
d'installation sont donnés plus bas dans ce document). Il vous
faut tout d'abord ouvrir un notebook Python.
1. Chargez la bibliothèque =rpy2=. Le =%load_ext= est une commande magique
Jupyter qui charge cette bibliothèque et vous donne accès à de
nouvelles commandes magiques.
#+begin_src python :results output :exports both
%load_ext rpy2.ipython
#+end_src
2. Utilisez la (nouvellement activée) commande magique =%R= :
#+begin_src python :results output :exports both
%%R
summary(cars)
#+end_src
Les objets Python peuvent même être passé à R de la façon suivante
(ici, on suppose que =df= est une dataframe pandas) :
#+begin_src python :results output :exports both
%%R -i df
plot(df)
#+end_src
Cette notation =%%R= indique à Python et à Jupyter et que le langage R
doit être utilisé pour évaluer l'ensemble de la cellule. En interne,
Python (=rpy2=) maintient une session R, lui passe le code de la cellule
et récupère le résultat. Jupyter fait alors le nécessaire pour
l'afficher correctement. Il est également possible d'utiliser =%R= pour
avoir une seule ligne de R au sein d'une cellule Python.
Un exemple de notebook utilisant R et Python est proposé [[file:../../documents/notebooks/notebook_Jupyter_Python_R.ipynb][ici]].
** Autres langages que Python et R
Jupyter tire son nom des langages Julia, Python, et R. Il ne se limite
donc pas aux langages Python et R. De nombreux autres langages de
programmation sont disponibles :
[[https://github.com/jupyter/jupyter/wiki/Jupyter-kernels][https://github.com/jupyter/jupyter/wiki/Jupyter-kernels]], et en
particulier des langages non libres comme SAS, Mathematica,
Matlab... Notez que la maturité de ces noyaux est très variable.
Nous n'avons déployé aucun de ces autres langages dans le cadre du
MOOC mais nous vous invitons à lire les sections suivantes pour
apprendre à déployer votre propre instance de Jupyter et activer
certaines de ses extensions.
Vous trouverez [[file:../../documents/notebooks/][ici]] une liste de notebooks Jupyter illustrant comment
différents langages (Python, R, SAS) peuvent être utilisés dans Jupyter.
*** SAS
SAS est un logiciel de statistiques propriétaires qui est très
couramment utilisé dans le domaine de la santé. Puisque la question
est posée de façon récurrente, si vous avez besoin d'utiliser le
langage SAS plutôt que le langage R, il y a deux façons d'utiliser SAS
avec Jupyter : soit avec le noyau [[https://sassoftware.github.io/sas_kernel/][Python SASKernel]] (l'équivalent du
=IRKernel=), soit avec la bibliothèque [[https://sassoftware.github.io/saspy/][Python SASPy]] (l'équivalent de
=rpy2=).
Malgré la qualité et la stabilité de ce langage, SAS n'en reste pas
moins un langage propriétaire, ce qui rend l'inspection de ses
procédures très difficile et limite la réutilisation des procédures
produites par d'autres chercheurs. Nous le déconseillons donc dans un
objectif de recherche reproductible mais il faut aussi savoir ne pas
être dogmatique. La perfection n'existe pas ;) et, même en utilisant
SAS, l'utilisation de la programmation lettrée de Jupyter et d'un
contrôle de version (avec GitLab) et d'environnement (avec Docker par
exemple) se révélera très certainement précieux.
*[[https://sassoftware.github.io/saspy/][SASPy]]*
- Installer =saspy= via =pip=, par exemple comme ceci :
#+begin_src shell :results output :exports both
python -m pip install saspy
#+end_src
- Sous Windows, il vous faudra probablement modifier le fichier
=C:\Program Files\Python\Python37\Lib\site-packages\saspy\sascfg_sav.py=
et l'adapter à votre propre système. Dans les deux captures d'écran
suivantes, la fenêtre de gauche correspond à la version originale du
fichier et celle de droite à la version modifiée :
#+BEGIN_CENTER
[[file:jupyter_images/sascfg1.png]]
#+END_CENTER
#+BEGIN_CENTER
[[file:jupyter_images/sascfg2.png]]
#+END_CENTER
- Voici un [[file:../../documents/notebooks/notebook_Jupyter_Python_SAS.ipynb][exemple de notebook Python/SAS]].
- N.B. : Lors de la première édition du MOOC, certains participants nous
on rapporté avoir rencontré des difficultés pour exporter leurs
notebooks SAS au format PDF. Ils sont néanmoins parvenus à leur fin
en passant par pandoc. Par exemple, exportez en HTML (ou en
markdown) dans jupyter puis exécutez la commande suivante :
#+begin_src shell :results output :exports both
pandoc --variable=geometry:a4paper --variable=geometry:margin=1in notebook_sas.html -o notebook_sas.pdf
#+end_src
- Une référence, plus complète, et bien utile en cas de difficultés :
[[https://sassoftware.github.io/saspy/]]
*[[https://sassoftware.github.io/sas_kernel/install.html][SASKernel]]*
- Le =sas_kernel= utilise =saspy= donc la première chose à faire est
d'installer =saspy= en suivant les instructions précédentes.
- Installez =sas_kernel= à l'aide de =pip=, par exemple comme ceci :
#+begin_src shell :results output :exports both
python -m pip install sas_kernel
#+end_src
- Yous pourrez alors créer des notebooks utilisant SAS nativement :
#+BEGIN_CENTER
[[file:jupyter_images/new_notebook.png]]
#+END_CENTER
#+BEGIN_CENTER
[[file:jupyter_images/notebook_SAS.png]]
#+END_CENTER
Vous pouvez remarquer la petite icône SAS en haut à droite.
- À toute fin utile, voici un [[file:../../documents/notebooks/notebook_Jupyter_SAS.ipynb][exemple de notebooks SAS]].
- Une référence, plus complète, et bien utile en cas de difficultés :
[[https://sassoftware.github.io/sas_kernel/install.htmlxo]].
* Installation et configuration de Jupyter sur votre ordinateur
Dans cette section, nous expliquons comment installer, sur votre
ordinateur, un environnement Jupyter similaire à celui que nous avons
déployé pour ce MOOC.
Notez que les notebooks Jupyter ne constituent qu'une petite partie de
l'écosystème et que Jupyter fait maintenant partie d'un projet plus
large, [[https://blog.jupyter.org/jupyterlab-is-ready-for-users-5a6f039b8906][JupyterLab]],
qui permet d'assembler différents composants (dont
les notebooks) dans votre navigateur. Dans le cadre de ce MOOC, nous
avons manqué de temps pour bénéficier de tout JupyterLab qui était
toujours en développement actif. À l'heure actuelle, vous pouvez
cependant avoir intérêt à installer tout JupyterLab sur votre ordinateur.
** Installation de Jupyter (et de Python, R...)
Ces instructions permettent d'obtenir sur votre ordinateur un
environnement Jupyter similaire à celui que nous avons déployé dans le
cadre du MOOC.
Téléchargez et installez la [[https://conda.io/miniconda.html][dernière version de Miniconda]]. Sur notre
serveur, nous utilisons la version =4.5.4= de Miniconda et la version
=3.6= de Python.
Miniconda est une version légère d'Anaconda, une suite logicielle
incluant Python, Jupyter, R ainsi que les bibliothèques les plus
couramment utilisées en calcul scientifique et en science des données.
Téléchargez ensuite le [[https://gist.github.com/brospars/4671d9013f0d99e1c961482dab533c57][fichier d'environnement =mooc_rr= ]] et déployez
votre environnement à l'aide de Conda :
#+begin_src shell :results output :exports both
conda env create -f environment.yml
# Windows activate the environment
activate mooc_rr
# Linux and MacOS activate the environment
source activate mooc_rr
# Linux, MacOS and Windows: launch the notebook
jupyter notebook
#+end_src
** S'assurer que Jupyter vous permet d'utiliser R
Si vous avez installé l'environnement de la façon décrite dans la
section précédente, vous devriez déjà avoir R à votre disposition et
vous n'avez donc rien à faire. Mais si vous avez procédé différemment
et n'avez que Python et Jupyter à votre disposition, il vous faudra
certainement suivre les étapes suivantes :
*** • Installation de [[https://github.com/IRkernel/IRkernel][IRKernel]] (R package)
IRKernel vous permettra de faire des notebooks utilisant le langage R
plutôt que le langage Python. Nous supposons ici que R est déjà
installé et fonctionnel sur votre ordinateur.
*Windows*
Pour windows, il ne sera probablement pas possible de compiler la
toute dernière version et il faudra installer la version binaire de la
façon suivante. Dans une console R ou bien dans Rstudio :
#+begin_src R :results output :session *R* :exports both
install.packages('IRkernel',dep=TRUE)
IRkernel::installspec() # to register the kernel in the current R installation
#+end_src
Voir ce qui suit pour un exemple d'utilisation de notebook R.
*Linux ou Mac*
Pour installer la toute dernière version d'IRkernel, dans une console
R ou bien dans Rstudio :
- Installer la bibliothèque =devtools= :
#+begin_src R :results output :session *R* :exports both
install.packages('devtools',dep=TRUE)
#+end_src
- Définissez un proxy si nécessaire (c'est important si votre
ordinateur est connecté à une entreprise qui limite l'accès à
Internet) :
#+begin_src R :results output :session *R* :exports both
library(httr)
set_config(use_proxy(url="proxy", port=80, username="username", password="password"))
#+end_src
- Installez la bibliothèque =IRkernel= :
#+begin_src R :results output :session *R* :exports both
devtools::install_github('IRkernel/IRkernel')
IRkernel::installspec() # to register the kernel in the current R installation
#+end_src
Vous pourrez alors créer des notebooks utilisant directement R :
[[file:jupyter_images/new_notebook.png]]
[[file:jupyter_images/notebook_R.png]]
On remarque l'icône du logiciel R en haut à droite. Vous trouverez ici
[[file:../../documents/notebooks/notebook_Jupyter_R.ipynb][un exemple de notebook R]].
*** • Installation de rpy2 (Python package)
La bibliothèque =rpy2= permet à Python d'appeler R et donc de mélanger
les deux langages dans le même notebook.
*Linux ou Mac*
Cette bibliothèque est en général disponible sur les distributions
récentes. Par exemple sous Debian ou Ubuntu :
#+begin_src shell :results output :exports both
sudo apt-get install python3-rpy2 python3-tzlocal
#+end_src
Si vous ne disposez pas d'une distribution Linux récente, il est
possible (mais non recommandé) d'utiliser le gestionnaire de paquets
de Python :
#+begin_src python :results output :exports both
pip3 install rpy2
#+end_src
*Windows*
Téléchargez le [[https://www.lfd.uci.edu/~gohlke/pythonlibs/#rpy2][fichier binaire]] =rpy2= en choisissant le bon système
d'exploitation.
Ouvrez une console DOS, placez vous dans le dossier de téléchargement,
et exécutez la commande suivante :
#+begin_src shell :results output :exports both
python -m pip install rpy2‑2.9.4‑cp37‑cp37m‑win_amd64.whl # adaptez le nom de fichier
#+end_src
Installez également =tzlocal= :
#+begin_src shell :results output :exports both
python -m pip install tzlocal
#+end_src
En cas de difficulté, vous pouvez vouloir vous référer à
[[https://stackoverflow.com/questions/14882477/rpy2-install-on-windows-7][StackOverflow]] (N.B. : quand nous avons essayé, nous n'avons pas eu
besoin de définir les variables d'environnement =R_HOME= et =R_USER=).
Vous pouvez alors lancer Jupyter et créer un notebook Python utilisant
R en suivant les instructions données au début de ce document
(cherchez =rpy2=).
** LaTeX pour la génération de PDF
Si vous voulez convertir vos notebooks en PDF, vous devez aussi installer LaTeX sur votre ordinateur. Nous expliquons cette procédure dans une [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/19c2b1de7766484bae73f3ab133463c6][ressource spécifique]].
** Conseils additionnels
*** • Exporter un notebook
Jupyter évolue rapidement et ces informations peuvent vite devenir
obsolètes mais voici ce qu'il peut être utile d'installer sur une
Debian récente pour que l'export des notebooks via LaTeX soit
fonctionnel :
#+begin_src shell :results output :exports both
sudo apt-get install texlive-xetex wkhtmltopdf
#+end_src
L'export vers HTML ou PDF peut se faire dans Jupyter via le menu
=File > Download as > HTML= (ou =PDF=). Il peut également être fait en ligne de
commande de la façon suivante :
#+begin_src sh :results output :exports both
ipython3 nbconvert --to pdf Untitled.ipynb
#+end_src
Pour utiliser un style spécifique, il suffit de personnaliser
l'exporter =nbconvert=. Cette personnalisation est présentée [[http://markus-beuckelmann.de/blog/customizing-nbconvert-pdf.html][ici]] mais
nous vous encourageons à simplement lire la [[https://nbconvert.readthedocs.io/en/latest/][documentation de
nbconvert]].
Plutôt que de trop bidouiller =nbconvert=, il est aussi possible
d'exporter en Markdown et d'utiliser [[https://pandoc.org/][pandoc]] qui est très flexible. Les
deux approches sont possibles, c'est une question de goût.
*Windows*
Nous vous conseillons de télécharger et d'installer la distribution
MiKTeX à partir du [[https://miktex.org/download][site web de MiKTeX]] en choisissant le bon système
d'exploitation. Lors de votre premier export vers pdf, il vous sera
certainement demandé d'installer des packages LaTeX spécifiques.
*** • Améliorer la lisibilité d'un notebook
Lorsque les notebooks s'allongent, ils deviennent vite difficiles à
lire. Voici quelques extensions qui peuvent vous faciliter un peu la
vie :
- Il est possible [[https://stackoverflow.com/questions/33159518/collapse-cell-in-jupyter-notebook][plier/déplier votre code]] :
#+begin_src shell :results output :exports both
pip3 install jupyter_contrib_nbextensions
# jupyter contrib nbextension install --user # not done yet
#+end_src
- Il est aussi possible de [[https://github.com/kirbs-/hide_code][contrôler la visibilité des cellules]], ce
qui peut être très utile si on exporte le notebook :
#+begin_src sh :results output :exports both
sudo pip3 install hide_code
sudo jupyter-nbextension install --py hide_code
jupyter-nbextension enable --py hide_code
jupyter-serverextension enable --py hide_code
#+end_src
Vous pourrez alors choisir =Hide_code= dans le menu de Jupyter :
#+BEGIN_CENTER
[[file:jupyter_images/menu_hide_code.png]]
#+END_CENTER
Cela devrait vous permettre d'obtenir ce genre de panneau de
configuration pour chaque cellule :
#+BEGIN_CENTER
[[file:jupyter_images/hide_code.png]]
#+END_CENTER
Il vous faudra utiliser les icônes pour faire l'export en pdf ou en
html plutôt que de passer par le menu.
#+BEGIN_CENTER
[[file:jupyter_images/export_hide_code.png]]
#+END_CENTER
N.B. : Dans la première édition de ce MOOC, certains participants nous
ont rapporté avoir eu des difficultés à faire fonctionner cette
extension sous Windows.
** • Interaction avec GitLab et git
Pour rendre vous simplifier la vie, nous avons rajouté des boutons
=pull/push= dans Jupyter qui vous permettent de synchroniser vos
modifications avec GitLab. Ce développement spécifique pour ce MOOC
s'est inspiré d'une [[https://github.com/Lab41/sunny-side-up][preuve de concept]] précédente mais est vraiment /ad
hoc/. Indépendemment et à peu près au même moment, une autre personne a
développé un [[https://github.com/sat28/githubcommit][Plugin Jupyter assez générique permettant de se
synchroniser avec Gitlab ou Github]]. Si cette fonctionnalité vous
intéresse, c'est donc une piste intéressante à explorer. Sinon,
souvenez-vous qu'il est très simple d'insérer une cellule shell dans
Jupyter et vous pouvez facilement y insérer des commandes
Git. C'est la façon dont nous travaillons en pratique la majorité du
temps. Si vous optez pour cette solution, il vous faudra configurer Git sur votre
ordinateur. Pour ce faire, vous pouvez suivre la vidéo
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][configurer Git pour Gitlab]] et le document
[[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/gitlab_fr.org][Git et Gitlab]] correspondant.
Ceci étant dit, vous avez certainement remarqué que Jupyter conserve
une trace parfaite de l'ordre dans lequel les cellules ont été
exécutées en incrémentant leur "indice". C'est une très bonne
propriété d'un point de vue reproductibilité mais il se peut, selon
votre usage, que cela s'avère peu pratique du point de vue du suivi de
version. Certaines personnes ont donc développé des
[[https://gist.github.com/pbugnion/ea2797393033b54674af][git hooks spécifiques]]
permettant d'ignorer ces numéros lorsque l'on commite des
notebooks Jupyter. Il y eu une longue discussion à ce sujet sur
[[https://stackoverflow.com/questions/18734739/using-ipython-notebooks-under-version-control][StackOverflow]]
qui détaille différentes options.
Enfin, pour ceux qui utilisent [[https://blog.jupyter.org/jupyterlab-is-ready-for-users-5a6f039b8906][JupyterLab]] plutôt que le Jupyter de
base, un [[https://github.com/jupyterlab/jupyterlab-git][plugin Git pour JupyterLab]] a été développé et offre des
fonctionnalités de suivi de version dignes d'un IDE classique.
<div id="content">
<h1 class="title">Maintaining a journal</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#orgc95598e">Some examples of LabBooks provided for inspiration</a></li>
<li style="margin-bottom:0;"><a href="#org51674f0">How to report efficiently (by Martin Quinson)</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org976cc9a">Reporting</a></li>
<li style="margin-bottom:0;"><a href="#org5ff6009">Reporting Logistics</a></li>
<li style="margin-bottom:0;"><a href="#org50f88a2">Reporting Document Organization</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-orgc95598e" class="outline-2">
<h2 id="orgc95598e">Some examples of LabBooks provided for inspiration</h2>
<div class="outline-text-2" id="text-orgc95598e">
<p>
Since a few years, we systematically require any or our students to
have a laboratory notebook in org-mode. Most of the time, they start
in private repositories but often end up being fully opened. Here are
a few ones:
</p>
<ul class="org-ul">
<li style="margin-bottom:0;">Luka Stanisic (a former PhD student advised by Arnaud Legrand) starting
using this methodology during his Msc and developed further
throughout his PhD. Part of his <a href="http://mescal.imag.fr/membres/luka.stanisic/thesis/thesis.pdf">PhD thesis</a> was actually about
designing a methodology for reproducible experiments in large scale
distributed systems. You may want to have a look at <a href="http://starpu-simgrid.gforge.inria.fr/">his postdoc
LabBook</a> and to the <a href="https://framagit.org/lvgx/pfe/blob/master/doc/labbook.org">report of Léo Villeveygoux</a> whom he advised.</li>
<li style="margin-bottom:0;">Tom Cornebize is currently a PhD student advised by Arnaud Legrand
and during his MSc, he also heavily <a href="https://github.com/Ezibenroc/simulating_mpi_applications_at_scale">loged his activity on Github</a>.</li>
<li style="margin-bottom:0;"><a href="https://github.com/schnorr">Lucas Schnorr</a>'s students usually also maintain their journal in a
very nice way: <a href="https://github.com/taisbellini/aiyra/blob/master/LabBook.org">Tais Bellini's BSc.</a>, <a href="https://github.com/mittmann/hpc/blob/master/LabBook.org">Arthur Krause's LabBook</a>, <a href="http://www.inf.ufrgs.br/~llnesi/memory_report/MemoryReport.html">Luca
Nesi's LabBook</a>.</li>
<li style="margin-bottom:0;"><a href="https://people.irisa.fr/Martin.Quinson/Research/Students/Methodo/">Martin Quinson</a>'s students also follow such conventions:
<ul class="org-ul">
<li style="margin-bottom:0;">Ezequiel Torti Lopez, M2R 2014. <a href="https://github.com/mquinson/simgrid-simpar/blob/master/report.org">Report</a>, with both the data
provenance and the data analysis included in the appendix.</li>
<li style="margin-bottom:0;">Betsegaw Lemma, M2R 2017. <a href="https://github.com/betsegawlemma/internship/blob/master/intern_report.org">LabBook</a></li>
<li style="margin-bottom:0;">Gabriel Corona, engineer on SimGrid, 2015-2016. <a href="https://github.com/randomstuff/simgrid-journal/blob/master/journal.org">Journal</a>, <a href="http://www.gabriel.urdhr.fr/tags/simgrid/">Blog (findings)</a>.</li>
<li style="margin-bottom:0;">Matthieu Nicolas, engineer on PLM, 2014-2016, <a href="https://github.com/MatthieuNICOLAS/PLM-reporting/blob/master/activity-report.org">Journal</a>.</li>
</ul></li>
</ul>
<p>
Org-mode is obviously not the only option and many of our students use
am mixture of org-mode, rstudio and jupyter depending on what is more
convenient.
</p>
</div>
</div>
<div id="outline-container-org51674f0" class="outline-2">
<h2 id="org51674f0">How to report efficiently (by Martin Quinson)</h2>
<div class="outline-text-2" id="text-org51674f0">
<p>
My friend Martin has gathered <a href="https://people.irisa.fr/Martin.Quinson/Research/Students/Methodo/">an excellent compendium of information
and references on his webpage to explain his students what he expects
from them</a>. <b>I'll therefore simply paraphrase him here</b> with the most
important aspects related to reporting but feel free to read <a href="https://people.irisa.fr/Martin.Quinson/Research/Students/Methodo/">the
original version</a>:
</p>
</div>
<div id="outline-container-org976cc9a" class="outline-3">
<h3 id="org976cc9a">Reporting</h3>
<div class="outline-text-3" id="text-org976cc9a">
<p>
I ask you to write a little reporting regularly. Depending on the
situation, it may be every day, every week or every month. In any
case, your reporting is very important for the following reasons:
</p>
<ul class="org-ul">
<li style="margin-bottom:0;">It forces you to think about what you are doing, which may help you
to unblock your problem by your own. Writing down the problems in a
clear way is often sufficient to see the solution appearing.</li>
<li style="margin-bottom:0;">It helps me following your progress even between the meetings. I
cannot unblock you if I don't detect that you are on a wrong lead or
otherwise blocked.</li>
<li style="margin-bottom:0;">It keeps a track of the steps in your work. That's good for the day
where you want to write your final report (even if a final report
should never be presented in the chronological order). That's good
for the next after you who will be supposed to continue you effort,
or to build upon it.</li>
<li style="margin-bottom:0;">That person may be yourself (if you go for a PhD program), another
intern, myself or even someone else on the Internet: that's what we
call Open Science, an effort where everyone can build upon the
scientific work of everyone.</li>
</ul>
<p>
I want you to write your reporting in an org file (yep, you don't have
a choice here). [..]
</p>
</div>
</div>
<div id="outline-container-org5ff6009" class="outline-3">
<h3 id="org5ff6009">Reporting Logistics</h3>
<div class="outline-text-3" id="text-org5ff6009">
<p>
Once you're setup with all software installed and somehow configured,
you need to create a reporting file in a place where I can see it and
where it won't get lost if your disk crashes or something. Open a
dedicated git repository (on github, gitorious, gitlab, &#x2026;) for
that. After your internship, your report should be archived directly
in the source tree of the software that you are working on, if
any. But having your reporting located in the source tree may
complicate things during your work.
</p>
<p>
Yes, it means that your file will be public at some point, but that's
why we call it "Open Science", after all. Also, you should write it in
English if possible. The part of your reporting that is called
"Journal" (see below) may be written in French if you are more
efficient this way but the rest must be in English. Don't make your
tone too formal because the file is public. Make it efficient. Nobody
will ever blame you for the work you did during an internship a long
time ago. If you really want, we can even make this file
anonymous. Just speak to me.
</p>
<p>
You want to write your reporting before leaving work. Weekly reporting
should be written on Friday, one or two hours before leaving. That's
the best solution to have a nice week end without thinking about work,
and still lose no information that you would need on Monday morning.
</p>
</div>
</div>
<div id="outline-container-org50f88a2" class="outline-3">
<h3 id="org50f88a2">Reporting Document Organization</h3>
<div class="outline-text-3" id="text-org50f88a2">
<p>
Your reporting document should have four main parts:
</p>
<dl class="org-dl">
<dt>Findings</dt><dd>This section summarizes the general information that you
gathered during your work. It is empty at the beginning
of your internship, and gets fleshed with the important
things that you find on your way. That's where
bibliographical information go, for example. But that's
definitely not where TODO notes go (see below).</dd>
<dt>Development</dt><dd>This section presents the technical sides of your
work. Don't write anything in there yet. Put it all
in the Journal part for now.</dd>
<dt>Journal</dt><dd>Describe the day-to-day work done for each period (day,
week or month) of your internship. That's the most
important part of your reporting, and we come back to it
below.</dd>
<dt>Conclusion</dt><dd><p>
That's what you write in the next week of your
internship. You can see it as a letter to the next
guy, explaining the current state of your work, a few
words about its technical organization, and what
should be done next on that topic. Keep this part
highly technical, the overall organization of your
internship will be seen in your final report.
</p>
<p>
The Journal part is the only part that you may write
in French on need. You want to add one subsection per
period to your journal. Don't make it too long, or you
would waste time writing long texts that very few will
ever read. Don't make it too short or it will be
impossible to understand it on Monday morning (or
three months after). Finding the good balance is
sometimes difficult, but I will provide feedback on
your first entries, so don't worry.
</p></dd>
</dl>
<p>
Each of section describing a period should contain three subsubsections:
</p>
<dl class="org-dl">
<dt>Things done</dt><dd>a few words about what you've done. Something like 2
or 4 items with a few words describing what you've
done. You can omit the title of that section and put
the items directly in the upper section (see the
example below).</dd>
<dt>Blocking points and questions</dt><dd>try to explain clearly the things
that block you or slow you down. If you found the solution
already, then it should be part of the previous subsection (but
you should say a few words nevertheless). Also ask every question
that you may have for me in that section. If the question are
personal (e.g., about the logistics of your internship such as
salary or so), please prefer emails that are not publicly
visible. If this section is empty for a given period, skip it
all together (no empty subsubsections).</dd>
<dt>Planned work</dt><dd>A few items about what you plan to work on during
the next period.</dd>
</dl>
<p>
A template of reporting file is given at the end of this section. This
is just a strong advice: If you really feel better with another file
organization, then give it a try for one period, and ask for my
feedback. I can adapt, and I do not pretend that my advice is the
definitive answer. It's just the result of my experience so far.
</p>
<p>
Notice how TODO items are written: they are given as items in the
Planned work sections of the journal. As explained in the
<a href="http://orgmode.org/manual/Checkboxes.html">documentation</a>, you simply have to write "[ ]" in front of items that
you plan to do in the future.
</p>
<p>
You should add a <code>[1/]</code> on the "Planned work" line, so that emacs keeps
track of what is done and what is still to do. Once they are done, you
type C-c C-C on their lines to change the blank box [ ] into a checked
box [X]. Also, the <code>[1/]</code> will be changed to denote the amount of work
that is still to be done.
</p>
<p>
At any point, you can see all ongoing TODO items with the following
keystrokes: "C-c / t". More information on TODOs in orgmode's
<a href="http://orgmode.org/manual/TODO-basics.html">documentation</a>. The important thing here is that most TODO items must
only be written in the <i>Journal</i> part (so that we know when they
occurred).
</p>
<p>
<b>Do not edit past entries of your journal</b>, unless you have very good
reasons. If you must, make sure that you don't lose information about
the path that you took (remember the Open Science thingy). You should
always <b>add</b> information to past entries, such as:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">- *edit* This hypothesis does not hold; see the entry of [the day where you found it] for more information.
</pre>
</div>
<p>
The only exception are TODO entries, that should clearly be rewritten
to DONE entries. If you need to adapt your TODO entry (because the
initial goal was poorly stated or otherwise), change the initial entry
from TODO to CANCELED (or check the box after stating in a subitem
that it was not done but canceled, and why), and create a new TODO
entry in the current period section.
</p>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
* Introduction
This file contains the reporting for my beloved internship done on
this topic on that year. For now, just add the official title of
your internship (check the convention signed between your
university and my lab). After a few weeks, once you really
understand your internship, you should write a few paragraphs about
the context, problem and motivation of your work, with some
possible use cases. But don't do that right now.
* Bibliography
* Journal
** Week 2 feb
- read the doc about writing my reporting
*** Questions
- do I really have to use emacs?
*** Work Planed [1/2]
- [X] install emacs and setup orgmode
- [ ] read the provided articles
** Week 9 feb
- Installed emacs
(omit the Questions section if no question)
*** Work Planed
- do some useful work
</pre>
</div>
</div>
</div>
</div>
# -*- mode: org -*-
#+TITLE: Maintaining a journal
#+AUTHOR: Arnaud Legrand
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Table of Contents :TOC:
- [[#some-examples-of-labbooks-provided-for-inspiration][Some examples of LabBooks provided for inspiration]]
- [[#how-to-report-efficiently-by-martin-quinson][How to report efficiently (by Martin Quinson)]]
- [[#reporting][Reporting]]
- [[#reporting-logistics][Reporting Logistics]]
- [[#reporting-document-organization][Reporting Document Organization]]
* Some examples of LabBooks provided for inspiration
Since a few years, we systematically require any or our students to
have a laboratory notebook in org-mode. Most of the time, they start
......@@ -35,9 +41,7 @@ am mixture of org-mode, rstudio and jupyter depending on what is more
convenient.
* How to report efficiently (by Martin Quinson)
My friend Martin has gathered [[https://people.irisa.fr/Martin.Quinson/Research/Students/Methodo/][an excellent compendium of information
and references on his webpage to explain his students what he expects
from them]]. *I'll therefore simply paraphrase him here* with the most
My friend Martin has gathered [[https://people.irisa.fr/Martin.Quinson/Research/Students/Methodo/][an excellent compendium of information and references on his webpage to explain his students what he expects from them]]. *I'll therefore simply paraphrase him here* with the most
important aspects related to reporting but feel free to read [[https://people.irisa.fr/Martin.Quinson/Research/Students/Methodo/][the
original version]]:
** Reporting
......@@ -112,15 +116,13 @@ Your reporting document should have four main parts:
highly technical, the overall organization of your
internship will be seen in your final report.
The Journal part is the only part that you may write
in French on need. You want to add one subsection per
period to your journal. Don't make it too long, or you
would waste time writing long texts that very few will
ever read. Don't make it too short or it will be
impossible to understand it on Monday morning (or
three months after). Finding the good balance is
sometimes difficult, but I will provide feedback on
your first entries, so don't worry.
The Journal part is the only part that you may write in French on
need. You want to add one subsection per period to your journal. Don't
make it too long, or you would waste time writing long texts that very
few will ever read. Don't make it too short or it will be impossible
to understand it on Monday morning (or three months after). Finding
the good balance is sometimes difficult, but I will provide feedback
on your first entries, so don't worry.
Each of section describing a period should contain three subsubsections:
- Things done :: a few words about what you've done. Something like 2
......
# -*- mode: org -*-
#+TITLE: Tenir un journal à jour
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Table des matières :TOC:
- [[#quelques-exemples-de-cahiers-de-notes-ou-de-laboratoires-pouvant-servir-de-source-dinspiration][Quelques exemples de cahiers de notes ou de laboratoires pouvant servir de source d'inspiration]]
- [[#rendre-compte-de-son-activité-efficacement][Rendre compte de son activité efficacement]]
- [[#le-reporting][Le Reporting]]
- [[#logistique][Logistique]]
- [[#organisation-dun-compte-rendu-dactivité][Organisation d'un compte rendu d'activité]]
* Quelques exemples de cahiers de notes ou de laboratoires pouvant servir de source d'inspiration
Depuis plusieurs années, nous demandons systématiquement à tout
étudiant travaillant avec nous tenir à jour un cahier de laboratoire,
généralement en org-mode. La plupart du temps, ces documents
commencent à être rédigés dans des dépôts privés mais assez souvent
ils finissent par être complètement ouverts et mis à disposition du
plus grand nombre. En voici quelques-uns :
- Luka Stanisic (un ancien doctorant d'Arnaud Legrand) a commencé à
utiliser cette méthodologie pendant son stage de M2 et a continué à
l'améliorer pendant son doctorat. Une partie de sa [[http://mescal.imag.fr/membres/luka.stanisic/thesis/thesis.pdf][thèse]] a en fait
porté sur la conception d'une méthodologie adaptée à la traçabilité
et à la reproductibilité des expériences sur les plates-formes de
calcul à hautes performances. Vous pourriez donc vouloir jeter un
oeil au [[http://starpu-simgrid.gforge.inria.fr/][cahier de laboratoire tenu pendant son postdoc]] ainsi qu'au
[[https://framagit.org/lvgx/pfe/blob/master/doc/labbook.org][rapport de Léo Villeveygoux]] qu'il a encadré pendant cette même
période.
- Tom Cornebize est actuellement en thèse sous la supervision d'Arnaud
Legrand et comme les autres, pendant son stage de master, il a
également intensément [[https://github.com/Ezibenroc/simulating_mpi_applications_at_scale][pris des notes sur son activité quotidienne et
les a mises à disposition sur Github]].
- Les étudiants de [[https://github.com/schnorr][Lucas Schnorr]] sont aussi généralement bien formés à
cet exercice de prise de note dans un journal : [[https://github.com/taisbellini/aiyra/blob/master/LabBook.org][Tais Bellini's BSc.]],
[[https://github.com/mittmann/hpc/blob/master/LabBook.org][Arthur Krause's LabBook]], [[http://www.inf.ufrgs.br/~llnesi/memory_report/MemoryReport.html][Luca Nesi's LabBook]].
- Ceux qui travaillent sous la supervision de [[https://people.irisa.fr/Martin.Quinson/Research/Students/Methodo/][Martin Quinson]] suivent
des conventions similaires :
- Ezequiel Torti Lopez, pendant son M2 en 2014, a produit un [[https://github.com/mquinson/simgrid-simpar/blob/master/report.org][rapport]]
où les données, leur provenance et leur analyse étaient fournies
dans l'annexe.
- Betsegaw Lemma, M2R 2017, [[https://github.com/betsegawlemma/internship/blob/master/intern_report.org][LabBook]].
- Gabriel Corona (ingénieur de recherche sur le projet SimGrid,
2015-2016) maintient également un [[https://github.com/randomstuff/simgrid-journal/blob/master/journal.org][journal]] et un [[http://www.gabriel.urdhr.fr/tags/simgrid/][blog (findings)]].
- Matthieu Nicolas (ingénieur sur PLM, 2014-2016): [[https://github.com/MatthieuNICOLAS/PLM-reporting/blob/master/activity-report.org][Journal]].
Org-mode n'est évidemment pas la seule option et il est courant que
nos étudiants et collègues utilisent un mélange d'Org-mode, Rstudio et
de Jupyter selon ce qui est le plus adapté à leurs besoins du moment.
* Rendre compte de son activité efficacement
Mon ami Martin a réalisé
[[https://people.irisa.fr/Martin.Quinson/Research/Students/Methodo/][une excellente collection d'informations et de références sur sa page web pour expliquer à ses étudiants ce qu'il attend d'eux]].
*Je vais donc tout simplement le paraphraser dans cette
section* en rappelant les éléments qui me semblent essentiels (mais je
vous invite à lire [[https://people.irisa.fr/Martin.Quinson/Research/Students/Methodo/][l'original]]).
** Le Reporting
Je vous demande de rendre compte de votre activité par écrit,
régulièrement. Selon la situation, cela peut être chaque jour, chaque
semaine ou chaque mois, mais dans tous les cas, votre compte rendu est
essentiel pour les raisons suivantes :
- Ça vous force à réfléchir à ce que vous êtes en train de faire, à
prendre du recul, ce qui peut vous permettre de résoudre vos
problèmes par vous-même. Énoncer clairement votre problème permet
souvent de faire apparaître des solutions.
- Ça m'aide à suivre votre progression et à réfléchir à votre
problème, même entre deux réunions. Je ne pourrai pas vous aider si
je ne sais pas que vous êtes partis dans une mauvaise direction ou
même que vous êtes bloqués avec tel ou tel point technique.
- Ça vous permet de garder une trace de votre travail. C'est très
précieux le jour où vous aurez à écrire votre rapport final (même si
un rapport n'est jamais présenté dans un ordre chronologique).
- C'est aussi précieux pour celui qui viendra après vous et souhaitera
repartir de vos travaux, les poursuivre ou les améliorer. Cette
personne peut d'ailleurs être vous-même dans quelques mois (si vous
vous engagez dans une thèse), un autre stagiaire, moi-même ou même
un inconnu à l'autre bout du monde et qui a trouvé vos travaux via
Internet : c'est ce qu'on appelle la science ouverte, un effort
collectif ou chacun peut efficacement s'appuyer sur le travail
scientifique de toute autre personne.
Je veux que vous écriviez votre compte rendu d'activité dans un
fichier org-mode (et oui, vous n'avez pas le choix !). [...]
** Logistique
Une fois que vous aurez mis en place et plus ou moins configuré tous
les logiciels dont vous aurez besoin, il vous faudra créer un fichier
dans un endroit auquel je puisse accéder et qui ne sera pas perdu si
jamais votre disque dur est endommagé, que vous vous faites voler
votre ordinateur, ou autre. Pour cela, commencez par créer un dépôt
git (sur GitHub, Gitorious, ou GitLab...). À la fin de votre stage,
votre rapport devra être archivé directement dans l'arborescence du
logiciel auquel vous avez contribué. Travailler directement dans cette
arborescence pendant votre stage peut cependant être un peu compliqué.
Mais, oui, cela veut dire que votre journal sera publique à un moment
ou à un autre (après tout, c'est pour ça qu'on parle de science
ouverte). Vous avez donc intérêt à écrire votre rapport en anglais si
c'est possible. La partie compte-rendu d'activité (votre "journal")
peut être écrite en français si vous êtes plus efficace ainsi mais le
reste doit être rédigé en anglais. Pas la peine de prendre un ton trop
formel sous prétexte que le document a vocation à être publique.
Soyez efficace. Personne ne vous tiendra rigueur de ce que vous avez
pu écrire à l'occasion de votre stage il y a de nombreuses années. Si
vous insistez, il est possible d'anonymiser ou de pseudonymiser ce
document, venez m'en parler.
Enfin, il est important d'écrire votre compte rendu avant de quitter
votre bureau, tant que les choses sont fraîches dans votre esprit. En
plus, cela vous libérera de la charge mentale induite par ce travail
de mémorisation. Si vous décidez de faire un reporting hebdomadaire,
faites le le vendredi, une ou deux heures avant de partir. C'est la
meilleure façon de passer un bon week-end sans avoir à penser à votre
travail et de ne perdre aucune information dont vous pourriez avoir
besoin le lundi matin. Même principe si vous faites un reporting
quotidien.
** Organisation d'un compte rendu d'activité
Selon moi, une bonne pratique consiste à structurer votre compte rendu
d'activité de la façon suivante :
- Résultats :: Cette section résume les informations que vous avez
obtenues à l'occasion de votre recherche. Elle est
généralement vide au début de votre stage et prendra du
volume au fur et à mesure que vous trouverez des
choses. C'est aussi souvent ici qu'atterrissent les
références bibliographiques par exemple mais ce n'est
clairement pas l'endroit où vous stockez votre liste
des choses à faire (TODO).
- Développement :: Cette section présente les aspects techniques de
votre travail. N'écrivez rien ici pour
l'instant. Mettez tout ce que vous collectez dans
la partie Journal.
- Journal :: C'est ici que vous décrivez votre travail au jour le
jour, de façon chronologique (jour, semaine, mois...).
C'est la partie la plus importante de votre
reporting et nous y reviendrons un peu plus bas.
- Conclusion :: C'est la section que vous écrivez la dernière semaine
(ou celle d'après) de votre stage. Vous pouvez la voir
comme une lettre à la prochaine personne expliquant
l'état actuel de votre travail, avec quelques
informations sur son organisation technique et ce qui,
selon vous, sont les prochaines choses à faire et
pourquoi. Cette partie peut-être hautement technique,
les tenants et les aboutissants plus globaux de votre
stage étant des considérations qui apparaîtront plutôt
dans votre rapport final de stage.
La partie Journal est la seule que vous avez le droit d'écrire en
français si vous êtes plus à l'aise ainsi. Pas la peine de vous
"répandre", vous perdriez votre temps à écrire un long texte que très
peu de personnes seraient susceptibles de lire. Ne la bâclez pour autant
car si elle est trop courte elle sera incompréhensible la semaine
d'après (ou trois mois plus tard). Trouver le bon équilibre n'est pas
toujours simple mais je vous ferai un retour sur vos premières entrées
donc ne vous inquiétez pas.
Une bonne habitude consiste à ce que chacune des sections
décrivant une période de travail soit structurée de la façon suivante :
- Travail effectué :: quelques mots sur ce que vous avez fait et son
contexte. Cela peut prendre la forme d'une petite liste de 2 à 4
entrées sur ce que vous avez fait et pourquoi vous l'avez fait.
- Ponts bloquants et questions :: essayez d'expliquer clairement les
points de blocage que vous rencontrez ou bien les points qui vous
gênent et vous ralentissent. Si vous avez finalement déjà trouvé
la réponse à ces problèmes, indiquez le dans la sous-section
précédente. C'est aussi ici que vous écrirez toute question que
vous aimeriez me poser. Si ce sont des interrogations
personnelles (par exemple sur la logistique de votre stage, le
logement, votre salaire), utilisez plutôt le mail qui restera
privé entre nous (souvenez-vous que ce journal a vocation à
devenir un document publique). Si cette section est vide pour une
période donnée, sautez la tout simplement (ne gardez pas de
sous-sections vides).
- Travaux prévus :: Une petite liste détaillant les points auxquels
vous comptez vous attaquer dans la période à venir.
Vous trouverez à la fin un modèle de compte rendu d'activité. Un
conseil : si vraiment vous vous sentez mieux avec une autre
structuration de document, essayez pour une période donnée et on fera
le point. Je sais m'adapter et je ne prétends pas avoir la science
infuse ni que mes conseils soient la solution ultime et
universelle. C'est juste le résultat de mon expérience jusqu'ici.
Remarquez comment les entrées commençant par le mot-clé TODO
apparaissent. On le retrouvera typiquement dans les sections "Travaux
prévus" du journal. Comme expliqué dans la [[http://orgmode.org/manual/Checkboxes.html][documentation d'org-mode]],
vous pouvez aussi tout simplement écrire =[ ]= au début de chaque
élément d'une liste de choses que vous avez l'intention de faire.
Dans ce cas, en rajoutant un [1/] à la fin de la sous-sous-section
"Travaux prévus", Emacs tiendra à jour le compte des choses faites et
qui restent à faire. Une fois que ce qui est décrit dans l'un des
éléments d'une liste est faite, il vous suffit de faire =C-c C-C= sur
cette entrée pour transformer le =[ ]= en une version cochée =[X]=. Le
[1/] sera alors mis à jour pour refléter la quantité de travail
restant. Lorsque tout aura été effectué, le mot-clé TODO passera à
DONE, ce qui procure un incroyable sentiment de satisfaction. :)
À tout moment, vous pouvez avoir accès à l'ensemble des choses à faire
(TODO) à l'aide du raccourci clavier suivant : =C-c / t=. Vous trouverez
plus d'informations sur les TODOs dans la [[http://orgmode.org/manual/TODO-basics.html][documentation d'orgmode]]. Le
point important à retenir ici est que la plupart des TODO doivent
apparaître dans la partie journal (afin de savoir quand ils se sont
posés).
*N'éditez jamais les entrées de votre journal a posteriori*, sauf si
vous avez vraiment une très bonne raison. Si cela devait arriver,
assurez vous que vous ne perdez pas d'informations sur ce que vous
avez fait et les choix que vous avez effectués (souvenez vous, science
ouverte, tout ça tout ça). Il faut toujours *ajouter* des nouvelles
informations aux anciennes, par exemple comme ceci :
#+begin_src shell :results output :exports both
- *edit* This hypothesis does not hold; see the entry of [the day where you found it] for more information.
#+end_src
La seule exception à cette édition des entrées passées, ce sont les
entrées de type TODO, qui sont dynamiques et ont vocation à être
transformées en entrées de type DONE. Si vous réalisez qu'il est utile
d'adapter une entrée TODO (parce que l'objectif initial a été mal
formulé, est inadapté, que sais je ?), faites passer l'entrée d'origine
de TODO à CANCELED (et/ou cochez le =[ ]= en indiquant dans une
sous-entrée que cette tâche n'a pas été faite mais annulée et
pourquoi) et créez une nouvelle entrée TODO dans la section du jour.
#+BEGIN_EXAMPLE
* Introduction
This file contains the reporting for my beloved internship done on
this topic on that year. For now, just add the official title of
your internship (check the convention signed between your
university and my lab). After a few weeks, once you really
understand your internship, you should write a few paragraphs about
the context, problem and motivation of your work, with some
possible use cases. But don't do that right now.
* Bibliography
* Journal
** Week 2 feb
- read the doc about writing my reporting
*** Questions
- do I really have to use emacs?
*** Work Planed [1/2]
- [X] install emacs and setup orgmode
- [ ] read the provided articles
** Week 9 feb
- Installed emacs
(omit the Questions section if no question)
*** Work Planed
- do some useful work
#+END_EXAMPLE
# This file may be used to create an environment using:
# $ conda create --name <env> --file <this file>
# platform: osx-64
@EXPLICIT
https://repo.anaconda.com/pkgs/r/osx-64/_r-mutex-1.0.0-anacondar_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/bzip2-1.0.6-h1de35cc_5.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ca-certificates-2019.1.23-0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/compiler-rt-4.0.1-hcfea43d_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/fribidi-1.0.5-h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/gsl-2.4-h1de35cc_4.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/jpeg-9c-h1de35cc_1001.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libcxxabi-4.0.1-hcfea43d_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libgfortran-3.0.1-h93005f0_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libiconv-1.15-hdd342a3_7.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libsodium-1.0.16-h3efe00b_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/llvm-openmp-4.0.1-hcfea43d_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/make-4.2.1-h3efe00b_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pandoc-2.2.3.2-0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pixman-0.38.0-h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pthread-stubs-0.3-hdd91f34_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-kbproto-1.0.7-h1de35cc_1002.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-libice-1.0.9-h01d97ff_1004.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.9-h1de35cc_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-libxdmcp-1.1.3-h01d97ff_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-renderproto-0.11.1-h1de35cc_1002.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-xextproto-7.3.0-h1de35cc_1002.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-xproto-7.0.31-h1de35cc_1007.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/xz-5.2.4-h1de35cc_4.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/yaml-0.1.7-hc338f04_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/zlib-1.2.11-h1de35cc_3.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/gfortran_osx-64-4.8.5-h22b1bf0_8.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libcxx-4.0.1-hcfea43d_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libgcc-4.8.5-hdbeacc1_10.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libopenblas-0.3.3-hdc02c5d_3.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libpng-1.6.37-ha441bb4_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.13-h1de35cc_1002.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/openblas-0.3.6-hd44dcd8_3.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/openssl-1.0.2r-h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/tk-8.6.8-ha441bb4_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-libsm-1.2.3-h01d97ff_1000.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/zstd-1.3.7-h5bba6e5_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/bwidget-1.9.11-1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/cctools-895-1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/freetype-2.9.1-hb4e5f40_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/gmp-6.1.2-hb37e062_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/graphite2-1.3.13-h2098e52_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/hdf5-1.10.2-hfa1e0ec_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/icu-58.2-h4b95b61_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libblas-3.8.0-10_openblas.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libffi-3.2.1-h475c297_4.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libprotobuf-3.7.1-hd9629dc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libssh2-1.8.0-h322a93b_4.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libtiff-4.0.10-hcb84e12_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/llvm-lto-tapi-4.0.1-1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ncurses-6.1-h0a44026_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pcre-8.43-h0a44026_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/tktable-2.10-h1de35cc_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-libx11-1.6.7-h1de35cc_1000.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/zeromq-4.2.5-h0a44026_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/gettext-0.19.8.1-h15daf44_3.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ld64-274.2-1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.8.0-10_openblas.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libcurl-7.61.1-hf30b1f0_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libedit-3.1.20181209-hb402a30_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.8.0-10_openblas.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libxml2-2.9.9-hab757c2_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/mpfr-4.0.1-h3018a27_3.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/readline-7.0-hc1231fa_4.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-libxext-1.3.4-h01d97ff_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xorg-libxrender-0.9.10-h01d97ff_1002.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/curl-7.61.1-ha441bb4_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/fontconfig-2.13.0-h5d5b041_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/glib-2.56.2-hd9629dc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/krb5-1.16.1-h24a3359_6.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/liblapacke-3.8.0-10_openblas.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/llvm-4.0.1-1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/mpc-1.1.0-h6ef4df4_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/sqlite-3.23.1-hf1716c9_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/blas-2.10-openblas.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/cairo-1.14.12-hc4e6be7_4.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/clang-4.0.1-1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/python-3.6.5-hc167b69_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/appnope-0.1.0-py36hf537a9a_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/attrs-19.1.0-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/backcall-0.1.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/backports-1.0-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/backports_abc-0.5-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/beautifulsoup4-4.6.3-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/certifi-2019.3.9-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/clang_osx-64-4.0.1-h1ce6c1d_16.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/clangxx-4.0.1-1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/cloudpickle-0.5.6-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/dask-core-1.2.2-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/decorator-4.4.0-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/defusedxml-0.6.0-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/dill-0.2.9-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/entrypoints-0.3-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/fastcache-1.1.0-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/free/osx-64/funcsigs-1.0.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/gmpy2-2.0.8-py36h6ef4df4_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/harfbuzz-1.8.8-hb8d4a28_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ipython_genutils-0.2.0-py36h241746c_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/kiwisolver-1.1.0-py36h0a44026_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/llvmlite-0.23.2-py36hc454e04_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/markupsafe-1.1.1-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/mistune-0.8.4-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/mpmath-1.1.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/numpy-base-1.16.3-py36ha711998_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/olefile-0.46-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pandocfilters-1.4.2-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/parso-0.4.0-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pickleshare-0.7.5-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/prometheus_client-0.6.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ptyprocess-0.6.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/pyparsing-2.4.0-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/pytz-2019.1-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pyyaml-5.1-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pyzmq-17.1.2-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/free/osx-64/scandir-1.5-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/send2trash-1.5.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/simplegeneric-0.8.1-py36_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/six-1.12.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/sqlalchemy-1.2.18-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/testpath-0.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/toolz-0.9.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/tornado-6.0.2-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/wcwidth-0.1.7-py36h8c6ec74_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/webencodings-0.5.1-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/xlrd-1.2.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/backports.shutil_get_terminal_size-1.0.0-py36_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/clangxx_osx-64-4.0.1-h22b1bf0_16.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/configparser-3.7.4-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/cycler-0.10.0-py36hfc81398_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/cytoolz-0.9.0.1-py36h1de35cc_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jedi-0.13.3-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/numpy-1.16.3-py36h926163e_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/packaging-19.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pango-1.42.4-h060686c_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pathlib2-2.3.3-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pexpect-4.7.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pillow-6.0.0-py36hb68e598_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/protobuf-3.7.1-py36h0a44026_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pyrsistent-0.14.11-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/python-dateutil-2.8.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/setuptools-41.0.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/singledispatch-3.4.0.3-py36hf20db9d_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/sympy-1.1.1-py36h7f3cf04_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/terminado-0.8.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/traitlets-4.3.2-py36h65bd3ce_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/bleach-3.1.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/cython-0.28.5-py36h0a44026_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/h5py-2.7.1-py36ha8ecd60_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/imageio-2.5.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jinja2-2.10.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jsonschema-3.0.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jupyter_core-4.4.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/matplotlib-2.2.3-py36h54f8f79_0.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/networkx-2.3-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/numba-0.38.1-py36h6440ff4_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/numexpr-2.6.9-py36hafae301_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pandas-0.22.0-py36h0a44026_0.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/pygments-2.4.0-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pywavelets-1.0.3-py36h1d22016_1.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-base-3.5.1-h539fb6c_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/scipy-1.1.0-py36h1a1e112_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/wheel-0.33.4-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/bokeh-0.12.16-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jupyter_client-5.2.4-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/nbformat-4.4.0-py36h827af21_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/patsy-0.5.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pip-19.1.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/prompt_toolkit-2.0.9-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-abind-1.4_5-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-assertthat-0.2.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-backports-1.1.2-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-base64enc-0.1_3-r351h6402f54_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-bh-1.66.0_1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-bindr-0.1.1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-bit-1.1_14-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-bitops-1.0_6-r351h6402f54_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-cardata-3.0_1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-codetools-0.2_15-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-colorspace-1.3_2-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-crayon-1.3.4-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-curl-3.2-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-data.table-1.11.4-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-dbi-1.0.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-deoptimr-1.0_8-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-dichromat-2.0_0-r351hf348343_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-digest-0.6.15-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-fansi-0.2.3-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-foreign-0.8_71-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-fracdiff-1.4_2-r351h6402f54_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-git2r-0.23.0-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-glue-1.3.0-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-gower-0.1.2-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-gtable-0.2.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-highr-0.7-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-iterators-1.0.10-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-jsonlite-1.5-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-kernlab-0.9_26-r351h46e27c5_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-kernsmooth-2.23_15-r351h0b560c1_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-labeling-0.3-r351hf348343_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-lattice-0.20_35-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-lazyeval-0.2.1-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-magrittr-1.5-r351hf348343_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-mass-7.3_50-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-mime-0.5-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-mnormt-1.5_5-r351h0b560c1_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-nloptr-1.0.4-r351h32998d9_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-nnet-7.3_12-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-numderiv-2016.8_1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-openssl-1.0.2-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-pbdzmq-0.3_3-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-pkgconfig-2.0.1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-plogr-0.2.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-pls-2.6_0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-quadprog-1.5_5-r351h0b560c1_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-r6-2.2.2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-randomforest-4.6_14-r351h0b560c1_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rappdirs-0.3.1-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rcolorbrewer-1.1_2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rcpp-0.12.18-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rematch-1.0.1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rlang-0.2.1-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rpart-4.1_13-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rstudioapi-0.7-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-sfsmisc-1.1_2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-sourcetools-0.1.7-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-sparsem-1.77-r351h0b560c1_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-squarem-2017.10_1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-stringi-1.2.4-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-timedate-3043.102-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-utf8-1.1.4-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-uuid-0.1_2-r351h6402f54_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-viridislite-0.3.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-whisker-0.3_2-r351hf348343_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-withr-2.1.2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-xtable-1.8_2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-yaml-2.2.0-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-zip-1.0.0-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/scikit-image-0.14.2-py36h0a44026_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/scikit-learn-0.19.2-py36hebd9d1a_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ipython-7.5.0-py36h39e3cac_0.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/nbconvert-5.5.0-py_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-bindrcpp-0.2.2-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-bit64-0.9_7-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-class-7.3_14-r351h6402f54_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-cli-1.0.0-r351h6115d3f_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-config-0.3-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-foreach-1.4.4-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-hexbin-1.27.2-r351h0b560c1_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-hms-0.4.2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-htmltools-0.3.6-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-httr-1.3.1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-later-0.7.3-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-magic-1.5_8-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-markdown-0.8-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-matrix-1.2_14-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-memoise-1.1.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-minqa-1.2.4-r351h4496799_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-modelmetrics-1.1.0-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-munsell-0.5.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-nlme-3.1_137-r351h0b560c1_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-openxlsx-4.1.0-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-plyr-1.8.4-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-prettyunits-1.0.2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rcpparmadillo-0.8.600.0.0-r351h649bfe0_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rcpproll-0.3.0-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rcurl-1.95_4.11-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-robustbase-0.93_2-r351h0b560c1_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rprojroot-1.3_2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-sp-1.3_1-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-stringr-1.3.1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-xml2-1.2.0-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-zoo-1.8_3-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/statsmodels-0.9.0-py36h1d22016_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ipykernel-5.1.0-py36h39e3cac_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-blob-1.1.1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-cvst-0.2_2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-devtools-1.13.6-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-evaluate-0.11-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-geometry-0.3_6-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-lmtest-0.9_36-r351h0b560c1_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-lubridate-1.7.4-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-maptools-0.9_3-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-matrixmodels-0.4_1-r351hf348343_4.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-mgcv-1.8_24-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-pillar-1.3.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-promises-1.0.1-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-psych-1.8.4-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rcppeigen-0.3.3.4.0-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-repr-0.15.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-reshape2-1.4.3-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-scales-0.5.0-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-selectr-0.4_1-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-survival-2.42_6-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-xts-0.11_0-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/seaborn-0.8.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/notebook-5.7.8-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-ddalpha-1.3.4-r351h4496799_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-drr-0.0.3-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-httpuv-1.4.5-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-irdisplay-0.5.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-knitr-1.20-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-lava-1.6.2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-lme4-1.1_17-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-quantreg-5.36-r351h0b560c1_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rsqlite-2.1.1-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rvest-0.3.2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-tibble-1.4.2-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-ttr-0.23_3-r351h0b560c1_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-cellranger-1.1.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-dimred-0.1.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-forcats-0.3.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-ggplot2-3.0.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-irkernel-0.8.12-r351_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-pbkrtest-0.4_7-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-prodlim-2018.04.18-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-purrr-0.2.5-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-quantmod-0.4_13-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-readr-1.1.1-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/widgetsnbextension-3.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ipywidgets-7.2.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-haven-1.1.2-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-ipred-0.9_6-r351h6402f54_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-readxl-1.1.0-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-tidyselect-0.2.4-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-tseries-0.10_45-r351h0b560c1_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-dplyr-0.7.6-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-rio-0.5.10-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-car-3.0_0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-dbplyr-1.2.2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-tidyr-0.8.1-r351h32998d9_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-broom-0.5.0-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/rpy2-2.9.4-py36r351h1d22016_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-modelr-0.1.2-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-recipes-0.1.3-r351hf348343_0.tar.bz2
https://repo.anaconda.com/pkgs/r/osx-64/r-caret-6.0_80-r351h6402f54_0.tar.bz2
# -*- mode: org -*-
#+TITLE: Python, R, and LaTeX
#+DATE: March 2019
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
Computational documents contain code, which in the case of our MOOC use the languages Python and R. If you follow the RStudio or Emacs/Orgmode paths, or if you want to install Jupyter on your own computer, you must install Python and R.
LaTeX is a document typesetting language that is widely used to write scientific articles. We do not use LaTeX directly in this MOOC, but it is used both by Jupyter and Emacs/Orgmode to produce PDF output. LaTeX is a rather big piece of software (a complete installation takes one to five GB), so you may prefer not to install it. That will not prevent you from following the MOOC, you just lose the ability to produce PDF versions of your computational documents.
* Version requirements
For Python, the examples in the MOOC require version 3.6 or later. The current version is 3.7.3. Python 3.6 was released more than two years ago, but older versions are still very common. For example, the current stable release of Debian Linux (Debian 9, named "stretch"), proposes Python 3.5. Make sure you have Python 3.6 or later, if necessary by installing it in addition to an older version you might already have. Note that multiple Python versions co-exist very well on a single computer, but you must be careful to always run the right one.
For R, we have used version 3.4, but somewhat older versions are probably fine as well.
LaTeX evolves much more slowly, so even a installation that is a few years old should be fine.
* Installation
There are many ways to install Python, R, and LaTeX. Worse, there are good reasons for there being many ways, because there is no single best one for everybody. The following guidelines should help you pick a good one for you.
1. Use a package manager you already have.
*Linux users* should start by checking the packages provided by their Linux distribution. It almost certainly contains Python, R, and LaTeX. Unless you use a very conservative distribution (such as [[https://www.centos.org/][CentOS]]), you can expect to find sufficiently recent versions of R and LaTeX, but for Python, make sure you get 3.6 or later.
The exact names of the packages you need to install unfortunately vary among distributions, but they should be similar to =python3=, =r-base=, and =texlive=.
*macOS* users who already use one of the package managers for macOS, i.e. one of [[https://brew.sh/][Homebrew]], [[https://www.macports.org/][MacPorts]], or [[http://www.finkproject.org/][fink]], should also look for Python and R in their distributions. However, it's probably not worth installing any of these package managers just for Python, R, or LaTeX.
2. Anaconda (this is [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/8dcce91be83c4ece834abfa98b8bbfb1][the method we recommand]] if you want to install the exact same version as the one we deployed on our servers for this MOOC)
Users of *Windows*, as well as *Linux* and *macOS* users who don't find sufficiently recent versions in their package manager's distributions, should consider the [[https://www.anaconda.com/distribution/][Anaconda distribution]] that contains both Python and R plus a huge collection of add-on packages for both languages. Anaconda is particularly recommended for those who plan to use Python more regularly, as it is the most convenient approach to managing Python environments. It is also [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/8dcce91be83c4ece834abfa98b8bbfb1][the method we recommend for a local installation of Jupyter]].
3. Follow the instructions proposed by each language's developers
Finally, you can install [[https://www.python.org/][Python]] and [[https://www.r-project.org/][R]] following the installation procedures proposed by their development teams. Compared to the approaches described above, the main inconvenience is the absence of simple strategies for updating and for installing add-on packages. But if you install Python and/or R just for the MOOC, this is not much of an issue.
LaTeX is a bit different because it is already an add-on package to another piece of software called TeX, and then requires additional add-ons to be of practical use. You should therefore use one of [[https://tug.org/texlive/][TeX Live]] or [[https://miktex.org/][MiKTeX]], the two major TeX distributions that come with their own package managers, and follow the installation instructions they provide. [[https://www.tug.org/mactex/][MacTeX]] for macOS is TeX Live plus a few macOS-specific add-ons. The differences between MiKTeX and TeX Live are not very important, so if you don't know which one to pick, toss a coin!
# -*- mode: org -*-
#+TITLE: Python, R et LaTeX
#+DATE: March 2019
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
Les documents computationnels contiennent du code, et en particulier dans le
cadre de notre MOOC du code Python et R. Si vous suivez le parcours RStudio ou
le parcours Emacs/Orgmode, ou encore si vous souhaiter installer Jupyter sur
votre propre ordinateur, il vous faudra donc installer Python et R.
LaTeX est un système de composition de documents qui est couramment utilisé
pour mettre en page des articles scientifiques. Dans ce MOOC, nous n'utilisons
pas directement LaTeX mais il est utilisé par Jupyter, RStudio et Emacs/Orgmode
pour produire des documents au format PDF. LaTeX est un relativement gros
logiciel (une installation complète prend 1 à 5 Go) donc vous pouvez ne pas
souhaiter l'installer. Cela ne vous empêchera pas de suivre le MOOC. Vous ne
pourrez juste pas produire de versions PDF de vos documents computationnels.
* Versions recommandées
En ce qui concerne Python, les exemples du MOOC nécessitent a minima la version
3.6 de Python. La version actuelle est la 3.7.3. Python 3.6 a été publiée
il y a plus de deux ans mais il est encore très courant de trouver des versions
plus anciennes. Par exemple, la version stable actuelle de Debian (Debian 9, "stretch")
propose Python 3.5. Assurez-vous que vous avez Python 3.6 ou une version plus
récente en l'installant si besoin en plus de la version de Python que vous
auriez déjà. En effet, il est parfaitement possible d'avoir plusieurs versions
de Python sur la même machine. Il vous faudra juste bien faire attention à
toujours utiliser la bonne.
En ce qui concerne R, nous avons utilisé la version 3.4 mais des versions un
peu plus anciennes devraient parfaitement faire l'affaire.
Enfin, LaTeX est assez stable et donc une installation datant de quelques années
ne devrait poser aucun problème.
* Installation
Il y a hélas plusieurs façons d'installer Python, R et LaTeX. Et le pire, c'est
qu'il y a même de très bonnes raisons pour cette disparité : pour chacune de ces
méthodes il existe des situations où elle ne convient pas... Les conseils suivant
devraient vous permettre de décider la méthode la plus adaptée à votre propre situation.
1. Utilisez le gestionnaires de paquets/logiciels de votre système d'exploitation.
Les utilisateurs de *Linux* ont intérêt à commencer par vérifier quels sont
les paquets fournis par leur distribution Linux. Elle propose certainement
des versions de Python, R et LaTeX. À moins que vous n'utilisiez une version
extrêmement conservative (par exemple [[https://www.centos.org/][CentOS]]),
vous devriez y trouver des versions suffisamment récentes de R et de LaTeX.
En revanche pour Python, assurez vous que vous avez une version supérieure à 3.6.
Le nom exact des paquets à installer varie hélas d'une distribution
à l'autre mais ils devraient ressembler à quelque chose comme
=python3=, =r-base= et =texlive=.
Les utilisateurs de *macOS* qui utilisent déjà un des gestionnaire de paquets
de macOS (c'est-à-dire [[https://brew.sh/][Homebrew]],
[[https://www.macports.org/][MacPorts]], ou [[http://www.finkproject.org/][fink]])
devraient également y chercher Python et R. Cependant, cela ne vaut
probablement pas le coup d'installer un de ces gestionnaires de paquets,
juste pour avoir accès à Python, R, et LaTeX.
2. Anaconda (c'est
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/8dcce91be83c4ece834abfa98b8bbfb1][la méthode que nous recommendons]]
si vous souhaitez installer exactement la même version que celle que nous
avons déployée sur nos serveurs pour ce MOOC)
Nous conseillons aux utilisateurs de *Windows*, ainsi qu'à ceux de *Linux* et
de *macOS* qui n'auraient pas trouvé de versions suffisamment récentes dans
le gestionnaire de paquets de leur distribution, d'envisager la
[[https://www.anaconda.com/distribution/][distribution Anaconda]] qui contient
Python, R et une importante collection de paquets pour ces deux langages.
Anaconda est particulièrement adapté à ceux qui ont l'intention d'utiliser
Python régulièrement puisque c'est actuellement la méthode la plus pratique
pour gérer des environnements Python. C'est également
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/8dcce91be83c4ece834abfa98b8bbfb1][la méthode que nous recommendons pour installer Jupyter]].
3. Suivre les instructions proposées par les développeurs de chaque langage.
Il est tout à fait possible d'installer [[https://www.python.org/][Python]]
and [[https://www.r-project.org/][R]] en suivant les procédures d'installation
proposées par leurs équipes de développement respectives. En comparaison aux
approches que nous venons de décrire, l'inconvénient principal de cette approche
est l'absence de stratégie simple permettant de faire des mises à jour ou
d'installer des paquets supplémentaires. Mais si vous prévoyez d'installer
Python et R juste pour le MOOC, ça devrait être sans importance.
LaTeX est un peu différent car c'est déjà une extension à un autre logiciel
appelé TeX et qu'il a besoin de nombreux paquets supplémentaires pour être
d'une quelconque utilité. Nous vous conseillons d'utiliser l'une des deux
principales distributions LaTeX, [[https://tug.org/texlive/][TeX Live]] ou
[[https://miktex.org/][MiKTeX]], qui viennent avec leur propre gestionnaire
de paquets. Vous n'aurez alors qu'à suivre les instructions d'installations
fournies. [[https://www.tug.org/mactex/][MacTeX]] (pour macOS) est une
distribution TeX Live avec quelques extensions spécifiques pour macOS en
plus. La différence entre MiKTeX et TeX Live n'a pas grande importance donc
si vous hésitez, tirez ça à pile ou face!
......@@ -4,7 +4,7 @@ ARCHIVE_FILES=article.org biblio.bib Makefile
all: article.pdf
%.tex: %.org
emacs -q -batch --eval "(setq enable-local-eval t)" --eval "(setq enable-local-variables t)" $^ --funcall org-latex-export-to-latex
emacs -batch --eval="(package-initialize)" --eval="(setq enable-local-eval t)" --eval="(setq enable-local-variables t)" $^ --funcall=org-latex-export-to-latex
%.pdf: %.tex
pdflatex $^
......@@ -13,13 +13,13 @@ all: article.pdf
pdflatex $^
%.html: %.org
emacs -q -batch --eval "(setq enable-local-eval t)" --eval "(setq enable-local-variables t)" $^ --funcall org-html-export-to-html
emacs -batch --eval="(package-initialize)" --eval="(setq enable-local-eval t)" --eval="(setq enable-local-variables t)" $^ --funcall=org-html-export-to-html
../$(ARCHIVE).tgz: $(ARCHIVE_FILES)
tar --xform "s|^|$(ARCHIVE)/|" -zcf $@ $^
clean:
rm -f article.aux article.bbl article.blg article.log article.out *~
rm -f article.aux article.bbl article.blg article.log article.toc article.out *~
distclean: clean
rm -f article.html article.tex article.pdf figure.pdf data.csv measurements.txt IEEEtran.bst IEEEtran.cls \#article.org\#
Size: 100
Sequential quicksort took: 0.000010 sec.
Parallel quicksort took: 0.004024 sec.
Built-in quicksort took: 0.000013 sec.
Size: 100
Sequential quicksort took: 0.000010 sec.
Parallel quicksort took: 0.004448 sec.
Built-in quicksort took: 0.000014 sec.
Size: 100
Sequential quicksort took: 0.000009 sec.
Parallel quicksort took: 0.003384 sec.
Built-in quicksort took: 0.000013 sec.
Size: 100
Sequential quicksort took: 0.000010 sec.
Parallel quicksort took: 0.003738 sec.
Built-in quicksort took: 0.000012 sec.
Size: 100
Sequential quicksort took: 0.000010 sec.
Parallel quicksort took: 0.003133 sec.
Built-in quicksort took: 0.000011 sec.
Size: 1000
Sequential quicksort took: 0.000128 sec.
Parallel quicksort took: 0.020407 sec.
Built-in quicksort took: 0.000209 sec.
Size: 1000
Sequential quicksort took: 0.000126 sec.
Parallel quicksort took: 0.022003 sec.
Built-in quicksort took: 0.000201 sec.
Size: 1000
Sequential quicksort took: 0.000128 sec.
Parallel quicksort took: 0.016149 sec.
Built-in quicksort took: 0.000210 sec.
Size: 1000
Sequential quicksort took: 0.000128 sec.
Parallel quicksort took: 0.014594 sec.
Built-in quicksort took: 0.000209 sec.
Size: 1000
Sequential quicksort took: 0.000129 sec.
Parallel quicksort took: 0.014905 sec.
Built-in quicksort took: 0.000210 sec.
Size: 10000
Sequential quicksort took: 0.001774 sec.
Parallel quicksort took: 0.018943 sec.
Built-in quicksort took: 0.001720 sec.
Size: 10000
Sequential quicksort took: 0.001698 sec.
Parallel quicksort took: 0.016226 sec.
Built-in quicksort took: 0.001733 sec.
Size: 10000
Sequential quicksort took: 0.001652 sec.
Parallel quicksort took: 0.017348 sec.
Built-in quicksort took: 0.001702 sec.
Size: 10000
Sequential quicksort took: 0.001680 sec.
Parallel quicksort took: 0.017302 sec.
Built-in quicksort took: 0.001726 sec.
Size: 10000
Sequential quicksort took: 0.001675 sec.
Parallel quicksort took: 0.017386 sec.
Built-in quicksort took: 0.001716 sec.
Size: 100000
Sequential quicksort took: 0.020040 sec.
Parallel quicksort took: 0.050548 sec.
Built-in quicksort took: 0.020300 sec.
Size: 100000
Sequential quicksort took: 0.020004 sec.
Parallel quicksort took: 0.043119 sec.
Built-in quicksort took: 0.020504 sec.
Size: 100000
Sequential quicksort took: 0.019763 sec.
Parallel quicksort took: 0.050735 sec.
Built-in quicksort took: 0.020439 sec.
Size: 100000
Sequential quicksort took: 0.019913 sec.
Parallel quicksort took: 0.049806 sec.
Built-in quicksort took: 0.020541 sec.
Size: 100000
Sequential quicksort took: 0.019726 sec.
Parallel quicksort took: 0.044636 sec.
Built-in quicksort took: 0.020252 sec.
Size: 1000000
Sequential quicksort took: 0.230648 sec.
Parallel quicksort took: 0.162221 sec.
Built-in quicksort took: 0.242869 sec.
Size: 1000000
Sequential quicksort took: 0.235778 sec.
Parallel quicksort took: 0.162137 sec.
Built-in quicksort took: 0.241607 sec.
Size: 1000000
Sequential quicksort took: 0.238383 sec.
Parallel quicksort took: 0.163279 sec.
Built-in quicksort took: 0.242786 sec.
Size: 1000000
Sequential quicksort took: 0.232921 sec.
Parallel quicksort took: 0.170237 sec.
Built-in quicksort took: 0.241583 sec.
Size: 1000000
Sequential quicksort took: 0.230096 sec.
Parallel quicksort took: 0.153896 sec.
Built-in quicksort took: 0.242492 sec.
......@@ -51,8 +51,32 @@
;; " -Dhttp.proxyPort=" proxy-port)))
(package-initialize)
(add-to-list 'package-archives
'("gnu" . "https://elpa.gnu.org/packages/"))
(add-to-list 'package-archives
'("melpa-stable" . "http://stable.melpa.org/packages/"))
(add-to-list 'package-archives
'("melpa" . "http://melpa.org/packages/"))
(setq package-archive-priorities '(("gnu" . 100)
("melpa-stable" . 10)))
(require 'cl)
(let* ((required-packages
'(ess
auctex
htmlize
exec-path-from-shell))
(missing-packages (remove-if #'package-installed-p required-packages)))
(when missing-packages
(message "Missing packages: %s" missing-packages)
(package-refresh-contents)
(dolist (pkg missing-packages)
(package-install pkg)
(message "Package %s has been installed" pkg))))
(unless (memq system-type '(windows-nt ms-dos))
(exec-path-from-shell-initialize)
(exec-path-from-shell-copy-env "PYTHONPATH"))
(require 'org)
......@@ -212,49 +236,64 @@ Entered on %U
))
(setq org-src-preserve-indentation t)
(add-to-list 'org-structure-template-alist
'("s" "#+begin_src ?\n\n#+end_src" "<src lang=\"?\">\n\n</src>"))
(setq rrmooc/new-org-templates (version<= "9.2" (org-version)))
(when rrmooc/new-org-templates
(require 'org-tempo))
(require 'subr-x)
(defun rrmooc/add-org-template (old-style-template)
(add-to-list 'org-structure-template-alist
(if rrmooc/new-org-templates
(cons
(first old-style-template)
(string-trim-right (substring (second old-style-template) 8 -9)))
old-style-template)))
(unless rrmooc/new-org-templates
;; this template is predefined in the new templating system
(rrmooc/add-org-template
'("s" "#+begin_src ?\n\n#+end_src" "<src lang=\"?\">\n\n</src>")))
(add-to-list 'org-structure-template-alist
'("m" "#+begin_src emacs-lisp :tangle init.el\n\n#+end_src" "<src lang=\"emacs-lisp\">\n\n</src>"))
(rrmooc/add-org-template
'("m" "#+begin_src emacs-lisp\n\n#+end_src" "<src lang=\"emacs-lisp\">\n\n</src>"))
(add-to-list 'org-structure-template-alist
'("r" "#+begin_src R :results output :session *R* :exports both\n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(rrmooc/add-org-template
'("r" "#+begin_src R :results output :session *R* :exports both\n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(add-to-list 'org-structure-template-alist
'("R" "#+begin_src R :results output graphics :file (org-babel-temp-file \"figure\" \".png\") :exports both :width 600 :height 400 :session *R* \n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(rrmooc/add-org-template
'("R" "#+begin_src R :results output graphics :file (org-babel-temp-file \"figure\" \".png\") :exports both :width 600 :height 400 :session *R* \n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(add-to-list 'org-structure-template-alist
'("RR" "#+begin_src R :results output graphics :file (org-babel-temp-file (concat (file-name-directory (or load-file-name buffer-file-name)) \"figure-\") \".png\") :exports both :width 600 :height 400 :session *R* \n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(rrmooc/add-org-template
'("RR" "#+begin_src R :results output graphics :file (org-babel-temp-file (concat (file-name-directory (or load-file-name buffer-file-name)) \"figure-\") \".png\") :exports both :width 600 :height 400 :session *R* \n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(add-to-list 'org-structure-template-alist
'("p" "#+begin_src python :results output :exports both\n\n#+end_src" "<src lang=\"python\">\n\n</src>"))
(rrmooc/add-org-template
'("p" "#+begin_src python :results output :exports both\n\n#+end_src" "<src lang=\"python\">\n\n</src>"))
(add-to-list 'org-structure-template-alist
'("P" "#+begin_src python :results output :session :exports both\n\n#+end_src" "<src lang=\"python\">\n\n</src>"))
(rrmooc/add-org-template
'("P" "#+begin_src python :results output :session :exports both\n\n#+end_src" "<src lang=\"python\">\n\n</src>"))
(add-to-list 'org-structure-template-alist
'("PP" "#+begin_src python :results file :session :var matplot_lib_filename=(org-babel-temp-file \"figure\" \".png\") :exports both\nimport matplotlib.pyplot as plt\n\nimport numpy\nx=numpy.linspace(-15,15)\nplt.figure(figsize=(10,5))\nplt.plot(x,numpy.cos(x)/x)\nplt.tight_layout()\n\nplt.savefig(matplot_lib_filename)\nmatplot_lib_filename\n#+end_src" "<src lang=\"python\">\n\n</src>"))
(rrmooc/add-org-template
'("PP" "#+begin_src python :results file :session :var matplot_lib_filename=(org-babel-temp-file \"figure\" \".png\") :exports both\nimport matplotlib.pyplot as plt\n\nimport numpy\nx=numpy.linspace(-15,15)\nplt.figure(figsize=(10,5))\nplt.plot(x,numpy.cos(x)/x)\nplt.tight_layout()\n\nplt.savefig(matplot_lib_filename)\nmatplot_lib_filename\n#+end_src" "<src lang=\"python\">\n\n</src>"))
(if (memq system-type '(windows-nt ms-dos))
;; Non-session shell execution does not seem to work under Windows, so we use
;; a named session just like for B.
(add-to-list 'org-structure-template-alist
'("b" "#+begin_src shell :session session :results output :exports both\n\n#+end_src" "<src lang=\"sh\">\n\n</src>"))
(add-to-list 'org-structure-template-alist
'("b" "#+begin_src shell :results output :exports both\n\n#+end_src" "<src lang=\"sh\">\n\n</src>")))
(add-to-list 'org-structure-template-alist
'("B" "#+begin_src shell :session *shell* :results output :exports both \n\n#+end_src" "<src lang=\"sh\">\n\n</src>"))
(add-to-list 'org-structure-template-alist
'("g" "#+begin_src dot :results output graphics :file \"/tmp/graph.pdf\" :exports both
digraph G {
node [color=black,fillcolor=white,shape=rectangle,style=filled,fontname=\"Helvetica\"];
A[label=\"A\"]
B[label=\"B\"]
A->B
}\n#+end_src" "<src lang=\"dot\">\n\n</src>"))
(rrmooc/add-org-template
'("b" "#+begin_src shell :session session :results output :exports both\n\n#+end_src" "<src lang=\"sh\">\n\n</src>"))
(rrmooc/add-org-template
'("b" "#+begin_src shell :results output :exports both\n\n#+end_src" "<src lang=\"sh\">\n\n</src>")))
(rrmooc/add-org-template
'("B" "#+begin_src shell :session *shell* :results output :exports both \n\n#+end_src" "<src lang=\"sh\">\n\n</src>"))
(rrmooc/add-org-template
'("g" "#+begin_src dot :results output graphics :file \"/tmp/graph.pdf\" :exports both
digraph G {
node [color=black,fillcolor=white,shape=rectangle,style=filled,fontname=\"Helvetica\"];
A[label=\"A\"]
B[label=\"B\"]
A->B
}\n#+end_src" "<src lang=\"dot\">\n\n</src>"))
(global-set-key (kbd "C-c S-t") 'org-babel-execute-subtree)
......
......@@ -6,13 +6,9 @@
#+LANGUAGE: en
This is a "minimal" =.emacs= configuration file. For this configuration
to work, you'll need:
- emacs25 (>25.2) (this way installing through elpa will save you some
time) and emacs-goodies (e.g., for color themes)
- org-mode > 9.0 (there has been several major compatibility breakage
so need to stay away from old versions)
- ess and R
- texlive and auctex
to work, you'll need one of:
- Emacs 26 (preferred)
- Emacs 25 plus Org-Mode 9
* Installation Instructions
Backup you own =.emacs= if you have one and replace it with [[file:init.el][the content
......@@ -75,12 +71,40 @@ document, simply =M-x org-babel-tangle=.
#+end_src
* Package sources
** Use melpa-stable
** Use melpa-stable (preferred) and melpa in addition to the default GNU archive
#+BEGIN_SRC emacs-lisp :tangle init.el
(package-initialize)
(add-to-list 'package-archives
'("gnu" . "https://elpa.gnu.org/packages/"))
(add-to-list 'package-archives
'("melpa-stable" . "http://stable.melpa.org/packages/"))
(add-to-list 'package-archives
'("melpa" . "http://melpa.org/packages/"))
(setq package-archive-priorities '(("gnu" . 100)
("melpa-stable" . 10)))
#+END_SRC
* Install packages
#+begin_src emacs-lisp :tangle init.el
(require 'cl)
(let* ((required-packages
'(ess
auctex
htmlize
exec-path-from-shell))
(missing-packages (remove-if #'package-installed-p required-packages)))
(when missing-packages
(message "Missing packages: %s" missing-packages)
(package-refresh-contents)
(dolist (pkg missing-packages)
(package-install pkg)
(message "Package %s has been installed" pkg))))
#+end_src
* Import environment variables
#+begin_src emacs-lisp :tangle init.el
(unless (memq system-type '(windows-nt ms-dos))
(exec-path-from-shell-initialize)
(exec-path-from-shell-copy-env "PYTHONPATH"))
#+end_src
* Loading files:
** Loading babel: :ARNAUD:
#+begin_src emacs-lisp :tangle init.el
......@@ -349,55 +373,74 @@ Additional shortcuts for navigating through org-mode documents:
#+end_src
** Adding source code blocks: :LUKA:
*** Enable the old template system with Orgmode 9.2 and later
#+begin_src emacs-lisp :tangle init.el
(setq rrmooc/new-org-templates (version<= "9.2" (org-version)))
(when rrmooc/new-org-templates
(require 'org-tempo))
#+end_src
*** Template definitions that work with the old and new templating systems
#+begin_src emacs-lisp :tangle init.el
(require 'subr-x)
(defun rrmooc/add-org-template (old-style-template)
(add-to-list 'org-structure-template-alist
(if rrmooc/new-org-templates
(cons
(first old-style-template)
(string-trim-right (substring (second old-style-template) 8 -9)))
old-style-template)))
#+end_src
*** With capital letters:
To use this type <s and then TAB
#+begin_src emacs-lisp :tangle init.el
(add-to-list 'org-structure-template-alist
'("s" "#+begin_src ?\n\n#+end_src" "<src lang=\"?\">\n\n</src>"))
(unless rrmooc/new-org-templates
;; this template is predefined in the new templating system
(rrmooc/add-org-template
'("s" "#+begin_src ?\n\n#+end_src" "<src lang=\"?\">\n\n</src>")))
#+end_src
*** Emacs-elisp code:
To use this type <m and then TAB
#+begin_src emacs-lisp :tangle init.el
(add-to-list 'org-structure-template-alist
'("m" "#+begin_src emacs-lisp :tangle init.el\n\n#+end_src" "<src lang=\"emacs-lisp\">\n\n</src>"))
(rrmooc/add-org-template
'("m" "#+begin_src emacs-lisp\n\n#+end_src" "<src lang=\"emacs-lisp\">\n\n</src>"))
#+end_src
*** R code:
To use this type <r and then TAB. This creates an R block for textual output.
#+begin_src emacs-lisp :tangle init.el
(add-to-list 'org-structure-template-alist
'("r" "#+begin_src R :results output :session *R* :exports both\n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(rrmooc/add-org-template
'("r" "#+begin_src R :results output :session *R* :exports both\n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
#+end_src
To use this type <R and then TAB. This creates an R block for graphics
that are stored in the =/tmp/=.
#+begin_src emacs-lisp :tangle init.el
(add-to-list 'org-structure-template-alist
'("R" "#+begin_src R :results output graphics :file (org-babel-temp-file \"figure\" \".png\") :exports both :width 600 :height 400 :session *R* \n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(rrmooc/add-org-template
'("R" "#+begin_src R :results output graphics :file (org-babel-temp-file \"figure\" \".png\") :exports both :width 600 :height 400 :session *R* \n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
#+end_src
To use this type <RR and then TAB. This creates an R block for
graphics that are stored in the directory of the current file.
#+begin_src emacs-lisp :tangle init.el
(add-to-list 'org-structure-template-alist
'("RR" "#+begin_src R :results output graphics :file (org-babel-temp-file (concat (file-name-directory (or load-file-name buffer-file-name)) \"figure-\") \".png\") :exports both :width 600 :height 400 :session *R* \n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
(rrmooc/add-org-template
'("RR" "#+begin_src R :results output graphics :file (org-babel-temp-file (concat (file-name-directory (or load-file-name buffer-file-name)) \"figure-\") \".png\") :exports both :width 600 :height 400 :session *R* \n\n#+end_src" "<src lang=\"R\">\n\n</src>"))
#+end_src
*** Python code
To use this type <p and then TAB
#+begin_src emacs-lisp :tangle init.el
(add-to-list 'org-structure-template-alist
'("p" "#+begin_src python :results output :exports both\n\n#+end_src" "<src lang=\"python\">\n\n</src>"))
(rrmooc/add-org-template
'("p" "#+begin_src python :results output :exports both\n\n#+end_src" "<src lang=\"python\">\n\n</src>"))
#+end_src
#+begin_src emacs-lisp :tangle init.el
(add-to-list 'org-structure-template-alist
'("P" "#+begin_src python :results output :session :exports both\n\n#+end_src" "<src lang=\"python\">\n\n</src>"))
(rrmooc/add-org-template
'("P" "#+begin_src python :results output :session :exports both\n\n#+end_src" "<src lang=\"python\">\n\n</src>"))
#+end_src
#+begin_src emacs-lisp :tangle init.el
(add-to-list 'org-structure-template-alist
'("PP" "#+begin_src python :results file :session :var matplot_lib_filename=(org-babel-temp-file \"figure\" \".png\") :exports both\nimport matplotlib.pyplot as plt\n\nimport numpy\nx=numpy.linspace(-15,15)\nplt.figure(figsize=(10,5))\nplt.plot(x,numpy.cos(x)/x)\nplt.tight_layout()\n\nplt.savefig(matplot_lib_filename)\nmatplot_lib_filename\n#+end_src" "<src lang=\"python\">\n\n</src>"))
(rrmooc/add-org-template
'("PP" "#+begin_src python :results file :session :var matplot_lib_filename=(org-babel-temp-file \"figure\" \".png\") :exports both\nimport matplotlib.pyplot as plt\n\nimport numpy\nx=numpy.linspace(-15,15)\nplt.figure(figsize=(10,5))\nplt.plot(x,numpy.cos(x)/x)\nplt.tight_layout()\n\nplt.savefig(matplot_lib_filename)\nmatplot_lib_filename\n#+end_src" "<src lang=\"python\">\n\n</src>"))
#+end_src
*** Bash "sh" code:
To use this type <b and then TAB
......@@ -405,28 +448,28 @@ To use this type <b and then TAB
(if (memq system-type '(windows-nt ms-dos))
;; Non-session shell execution does not seem to work under Windows, so we use
;; a named session just like for B.
(add-to-list 'org-structure-template-alist
'("b" "#+begin_src shell :session session :results output :exports both\n\n#+end_src" "<src lang=\"sh\">\n\n</src>"))
(add-to-list 'org-structure-template-alist
'("b" "#+begin_src shell :results output :exports both\n\n#+end_src" "<src lang=\"sh\">\n\n</src>")))
(rrmooc/add-org-template
'("b" "#+begin_src shell :session session :results output :exports both\n\n#+end_src" "<src lang=\"sh\">\n\n</src>"))
(rrmooc/add-org-template
'("b" "#+begin_src shell :results output :exports both\n\n#+end_src" "<src lang=\"sh\">\n\n</src>")))
#+end_src
To use this type <B and then TAB. This comes with a session argument
(e.g., in case you want to keep ssh connexions open).
#+begin_src emacs-lisp :tangle init.el
(add-to-list 'org-structure-template-alist
'("B" "#+begin_src shell :session *shell* :results output :exports both \n\n#+end_src" "<src lang=\"sh\">\n\n</src>"))
(rrmooc/add-org-template
'("B" "#+begin_src shell :session *shell* :results output :exports both \n\n#+end_src" "<src lang=\"sh\">\n\n</src>"))
#+end_src
*** Graphviz
#+begin_src emacs-lisp :tangle init.el
(add-to-list 'org-structure-template-alist
'("g" "#+begin_src dot :results output graphics :file \"/tmp/graph.pdf\" :exports both
digraph G {
node [color=black,fillcolor=white,shape=rectangle,style=filled,fontname=\"Helvetica\"];
A[label=\"A\"]
B[label=\"B\"]
A->B
}\n#+end_src" "<src lang=\"dot\">\n\n</src>"))
(rrmooc/add-org-template
'("g" "#+begin_src dot :results output graphics :file \"/tmp/graph.pdf\" :exports both
digraph G {
node [color=black,fillcolor=white,shape=rectangle,style=filled,fontname=\"Helvetica\"];
A[label=\"A\"]
B[label=\"B\"]
A->B
}\n#+end_src" "<src lang=\"dot\">\n\n</src>"))
#+end_src
** Evaluating whole subtree: :LUKA:
#+begin_src emacs-lisp :tangle init.el
......
......@@ -22,7 +22,7 @@ These informations were gathered and first demonstrated in my [[https://github.c
webinar on reproducible research: litterate programming]].
***** Emacs shortcuts
Here are a few convenient emacs shortcuts for those that have never
used emacs. In all of the emacs shortcuts, =C=Ctrl=, =M=Alt/Esc= and
used emacs. In all of the emacs shortcuts, =C=Ctrl=, =M=Alt/Esc or Cmd with MacOs= and
=S=Shift=. Note that you may want to use two hours to follow the emacs
tutorial (=C-h t=). In the configuration file CUA keys have been
activated and allow you to use classical copy/paste (=C-c/C-v=)
......
# -*- mode: org -*-
#+TITLE: Using Git from RStudio
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
* Table of Contents :TOC:
- [[#to-begin][To begin]]
- [[#cloning-a-repository][Cloning a repository]]
- [[#modifying-a-file][Modifying a file]]
* To begin
If you have never used git with RStudio, *we strongly advise that you
follow [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/d132a854b0464ad29085cedaded23136][our tutorial on using git from RStudio]]* (/"RStudio et Gitlab"/
). Before proceeding, make sure you also have followed the
*[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85]["git/GitLab configuration" tutorial]]*.
Alternatively, you may want to watch [[https://www.youtube.com/embed/uHYcDQDbMY8][this video]] (in English). If you
do not like videos, you should have a look at the [[https://swcarpentry.github.io/git-novice/14-supplemental-rstudio/index.html][step-by-step
explanations from Software Carpentry]]. It comes with many screenshots
and is quite progressive.
* Cloning a repository
Open RStudio and do the following steps:
- Create a new version controled project: =File / New Project / Version Control=
#+BEGIN_CENTER
[[file:rstudio_images/new_project.png]]
[[file:rstudio_images/git.png]]
#+END_CENTER
- Get the URL from your GitLab repository:
#+BEGIN_CENTER
[[file:rstudio_images/adresse_depot.png]]
#+END_CENTER
- Indicate this URL in the "Repository URL" field (/you may want to
prefix this URL with =xxx@= where =xxx= is/ /your Gitlab id to avoid
repeatedly giving it later on/).
#+BEGIN_CENTER
[[file:rstudio_images/clone.png]]
#+END_CENTER
- If you're behind a proxy, git should be configured
accordingly. Check the [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85]["Dealing with proxies" section]].
- Git will then connect to Gitlab and fetch a whole copy of the
repository.
- RStudio should restart in a mode related to Git:
#+BEGIN_CENTER
[[file:rstudio_images/rstudio.png]]
#+END_CENTER
- The file manager on the right, allows you to browse the version
controled repository.
* Modifying a file
- Open =Module2/exo1/toy_document.Rmd= and perform a simple
modification.
- Save
- Go to the Git menu to commit
#+BEGIN_CENTER
[[file:rstudio_images/commit.png]]
[[file:rstudio_images/commit2.png]]
#+END_CENTER
- Select the lines to commit and then click on =commit=
#+BEGIN_CENTER
[[file:rstudio_images/commit5.png]]
#+END_CENTER
Your modifications have now been commited on your local
machine. They haven't been propagated to GitLab yet.
- Click on =push= to propagate them on GitLab
#+BEGIN_CENTER
[[file:rstudio_images/push.png]]
[[file:rstudio_images/push2.png]]
[[file:rstudio_images/push3.png]]
#+END_CENTER
*NB*: You won't be able to propagate your modifications on GitLab if
some modifications have been done on GitLab in the meantime.
[[file:rstudio_images/push4.png]]
- You should first merge these remote modifications locally. Click on
=pull= to get these modifications on your machine.
# -*- mode: org -*-
#+TITLE: Utiliser Git avec RStudio
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
* Table des matières :TOC:
- [[#pour-commencer][Pour commencer]]
- [[#Cloner-un-dépôt][Cloner un dépôt]]
- [[#modifier-un-fichier][Modifier un fichier]]
* Avant de commencer
La première chose à faire est de configurer Git sur votre
ordinateur. Pour ce faire, vous pouvez suivre la vidéo
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][configurer Git pour Gitlab]] et le document
[[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/gitlab_fr.org][Git et Gitlab]] correspondant.
Vous pourrez alors utiliser Git avec RStudio. Pour ce faire, vous
pouvez suivre la vidéo [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/d132a854b0464ad29085cedaded23136][RStudio - Gitlab]] dont les étapes
sont reprises ci-dessous.
/(Nous vous signalons aussi cette/ [[https://www.youtube.com/embed/uHYcDQDbMY8][vidéo]] /(en anglais) ainsi que le/ [[https://swcarpentry.github.io/git-novice/14-supplemental-rstudio/index.html][tuto
pas à pas]] /(en anglais) de Software Carpentry.)/
* Cloner un dépôt
Ouvrir RStudio et procéder comme suit :
- Créer un nouveau projet sous contrôle de version : =File / New Project / Version Control=
#+BEGIN_CENTER
[[file:rstudio_images/new_project.png]]
[[file:rstudio_images/git.png]]
#+END_CENTER
- Récupérer l'URL du dépôt Gitlab
#+BEGIN_CENTER
[[file:rstudio_images/adresse_depot.png]]
#+END_CENTER
- Indiquez cette URL dans le champ "Repository URL" /(vous voudrez/
/peut-être préfixer cette URL avec =xxx@= où =xxx= est votre identifiant/
/Gitlab pour éviter d'avoir à le ressaisir ultérieurement)/.
#+BEGIN_CENTER
[[file:rstudio_images/clone.png]]
#+END_CENTER
- Si vous êtes derrière un proxy, il faut le définir dans Git (voir le
paragraphe "Gérer les proxy" de la page sur [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][Git et Gitlab]]).
- Git se connecte à Gitlab et récupère une copie complète du dépôt.
- RStudio redémarre dans un mode lié à Git :
#+BEGIN_CENTER
[[file:rstudio_images/rstudio.png]]
#+END_CENTER
- Le gestionnaire de fichiers à droite vous permet de parcourir le
dépôt sous contrôle de version.
* Modifier un fichier
- Ouvrir le fichier =Module2/exo1/toy_document.Rmd= et le modifier.
- Enregistrer.
- Aller dans le menu Git pour effectuer le commit.
#+BEGIN_CENTER
[[file:rstudio_images/commit.png]]
[[file:rstudio_images/commit2.png]]
#+END_CENTER
- Sélectionner les lignes à commiter puis cliquer sur =commit=.
#+BEGIN_CENTER
[[file:rstudio_images/commit5.png]]
#+END_CENTER
Les modifications ont été commitées uniquement sur la machine. Elles
n'ont pas été propagées sur Gitlab.
- Cliquer sur =push= pour les propager sur Gitlab.
#+BEGIN_CENTER
[[file:rstudio_images/push.png]]
[[file:rstudio_images/push2.png]]
[[file:rstudio_images/push3.png]]
#+END_CENTER
N.B. : Vous ne pouvez pas propager vos modifications sur GitLab si
des modifications ont été faites sur GitLab entre-temps.
#+BEGIN_CENTER
[[file:rstudio_images/push4.png]]
#+END_CENTER
- Il faut d’abord récupérer ces modifications distantes sur votre
machine locale. Pour ce faire cliquer sur =pull=.
# -*- mode: org -*-
#+TITLE: Rstudio: installation and documentation
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
* Table of Contents :TOC:
- [[#installing-rstudio][Installing RStudio]]
- [[#linux-debian-ubuntu][Linux (debian, ubuntu)]]
- [[#mac-osx-and-windows][Mac OSX and Windows]]
- [[#rstudio-documentation][RStudio documentation]]
* Installing RStudio
** Linux (debian, ubuntu)
We provide here only instructions for Debian-based distributions. Feel
free to contribute to this document to provide up-to-date information
for other distributions (e.g., RedHat, Fedora).
Today, the stable versions of the most common distributions provide
recent enough versions of R:
- Debian (stretch) ships with [[https://packages.debian.org/stretch/r-base][R 3.3.3-1]], [[https://packages.debian.org/stretch/r-cran-knitr][knitr 1.15.1]], and [[https://packages.debian.org/stretch/r-cran-ggplot2][ggplot 2.2.1]]
- Ubuntu (bionic 18.04) ships with [[https://packages.ubuntu.com/bionic/r-base][R 3.4.4]], and [[https://packages.ubuntu.com/bionic/r-cran-knitr][knitr 1.17]], and [[https://packages.ubuntu.com/bionic/r-cran-ggplot2][ggplot 2.2.1]]
- Ubuntu (artful 17.04) ships with [[https://packages.ubuntu.com/artful/r-base][R 3.4.2]], and [[https://packages.ubuntu.com/artful/r-cran-knitr][knitr 1.15]], and [[https://packages.ubuntu.com/artful/r-cran-ggplot2][ggplot 2.2.1]]
If your distribution is older than this, well, it may be a good time
for upgrading...
*** Installing R
First, you need to install the R language and convenient packages
by running (as root):
#+BEGIN_SRC shell
apt-get update ; sudo apt-get install r-base r-cran-knitr r-cran-ggplot2
#+END_SRC
Alternatively, if the installation of =r-cran-gplot2= or =r-cran-knitr=
fails, you may want to install them locally (through the R packaging
system) and manually by running the following commands in R (or
RStudio):
#+BEGIN_SRC R
install.packages("knitr")
install.packages("ggplot2")
#+END_SRC
If you plan to export pdf documents with LaTeX, you probably also want
to run (as root):
#+begin_src sh :results output :exports both
apt-get update ; apt-get install texlive-base
#+end_src
*** Installing RStudio
RStudio is unfortunately not packaged within Debian so the easiest is
to download the corresponding Debian package on the [[https://www.rstudio.com/products/rstudio/download/#download][RStudio webpage]]
and then to install it manually (you may have to adjust the version number in the following example). Here is how to install it:
#+BEGIN_SRC shell
cd /tmp/
wget https://download1.rstudio.org/rstudio-xenial-1.1.453-amd64.deb
sudo dpkg -i rstudio-xenial-1.1.453-amd64.deb
sudo apt-get update ; sudo apt-get -f install # to fix possibly missing dependencies
#+END_SRC
** Mac OSX and Windows
- Install R and Python following the instructions given in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/19c2b1de7766484bae73f3ab133463c6][separate resource]].
- Download and install RStudio from the [[https://www.rstudio.com/products/rstudio/download/#download][RStudio webpage]] by choosing the right operating system.
- Download and install MiKTeX from the [[https://miktex.org/download][MiKTeX webpage]] by choosing the right operating system. You will be prompted to install some specific packages when exporting to pdf.
- Open RStudio and type the following commands in the console to install =knitr= and =ggplot2=:
#+BEGIN_SRC R
install.packages("knitr", dep=TRUE)
install.packages("ggplot2", dep=TRUE)
#+END_SRC
* RStudio documentation
The RStudio team has created a lot of very good material and
tutorials. You should definitively look at the [[https://www.rstudio.com/resources/cheatsheets/][Cheat sheets
webpage]]. In particular you may want to have look at the following
ones:
- [[https://github.com/rstudio/cheatsheets/raw/master/rstudio-ide.pdf][The RStudio IDE]],
- [[https://github.com/rstudio/cheatsheets/raw/master/rmarkdown-2.0.pdf][R Markdown]] (here is also a [[https://rmarkdown.rstudio.com/][nice step-by-step presentation of Rmarkdown]]),
- The [[https://www.rstudio.com/wp-content/uploads/2015/03/rmarkdown-reference.pdf][R Markdown Reference guide]],
- [[https://github.com/rstudio/cheatsheets/raw/master/data-visualization-2.1.pdf][Data visualization with ggplot2]],
- [[https://github.com/rstudio/cheatsheets/raw/master/data-transformation.pdf][Data transformation with dplyr]]
In case it helps, here are some (sometimes outdated) French versions
of these documents:
- [[https://github.com/rstudio/cheatsheets/raw/master/translations/french/rstudio-IDE-cheatsheet.pdf][L'IDE RStudio]]
- [[https://github.com/rstudio/cheatsheets/raw/master/translations/french/ggplot2-french-cheatsheet.pdf][Visualisation de données avec ggplot2]]
- [[https://github.com/rstudio/cheatsheets/raw/master/translations/french/data-wrangling-french.pdf][Transformation de données avec dplyr]]
- [[https://www.fun-mooc.fr/c4x/UPSUD/42001S02/asset/RMarkdown.pdf][Un court document sur R Markdown]]
# -*- mode: org -*-
#+TITLE: Rstudio : installation et documentation
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
* Table des matières :TOC:
- [[#installer-rstudio][Installer RStudio]]
- [[#linux-debian-ubuntu][Linux (debian, ubuntu)]]
- [[#mac-osx-and-windows][Mac OSX and Windows]]
- [[#documentation-rstudio][Documentation RStudio]]
* Installer RStudio
** Linux (debian, ubuntu)
Nous ne fournissons ici que des instructions pour les distributions
basées sur Debian. N’hésitez pas à contribuer à ce document en
fournissant des informations à jour sur les autres distributions
(RedHat, Fedora, par exemple).
Aujourd'hui, les versions stables des distributions les plus courantes
fournissent des versions assez récentes de R :
- Debian (stretch) est livré avec [[https://packages.debian.org/stretch/r-base][R 3.3.3-1]], [[https://packages.debian.org/stretch/r-cran-knitr][knitr 1.15.1]], et [[https://packages.debian.org/stretch/r-cran-ggplot2][ggplot 2.2.1]]
- Ubuntu (bionic 18.04) est livré avec [[https://packages.ubuntu.com/bionic/r-base][R 3.4.4]], [[https://packages.ubuntu.com/bionic/r-cran-knitr][knitr 1.17]], et [[https://packages.ubuntu.com/bionic/r-cran-ggplot2][ggplot 2.2.1]]
- Ubuntu (artful 17.04) est livré avec [[https://packages.ubuntu.com/artful/r-base][R 3.4.2]], [[https://packages.ubuntu.com/artful/r-cran-knitr][knitr 1.15]], et [[https://packages.ubuntu.com/artful/r-cran-ggplot2][ggplot 2.2.1]]
Si votre distribution est plus ancienne, c'est peut-être l'occasion de
la mettre à jour...
*** Installer R
Pour commencer, vous devez installer le langage R et quelques packages
en exécutant (à la racine) :
#+BEGIN_SRC shell
apt-get update ; sudo apt-get install r-base r-cran-knitr r-cran-ggplot2
#+END_SRC
Si l'installation de =r-cran-knitr= ou =r-cran-gplot2= échoue, vous pouvez
également installer ces packages manuellement en exécutant les
commandes suivantes sous R (ou RStudio) :
#+BEGIN_SRC R
install.packages("knitr")
install.packages("ggplot2")
#+END_SRC
Si vous envisagez d'exporter des documents pdf avec LaTeX, il faudra
probablement aussi exécuter (à la racine) :
#+begin_src shell :results output :exports both
apt-get update ; apt-get install texlive-base
#+end_src
*** Installer RStudio
RStudio n’est malheureusement pas intégré à Debian. Le plus simple est
de télécharger le paquet Debian correspondant sur le [[https://www.rstudio.com/products/rstudio/download/#download][site RStudio]],
puis de l’installer manuellement (vous devrez peut-être adapter le
numéro de version) :
#+BEGIN_SRC shell
cd /tmp/
wget https://download1.rstudio.org/rstudio-xenial-1.1.453-amd64.deb
sudo dpkg -i rstudio-xenial-1.1.453-amd64.deb
sudo apt-get update ; sudo apt-get -f install # to fix possibly missing dependencies
#+END_SRC
** Mac OSX and Windows
- Installer R et Python en suivant les instruction dans une [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/19c2b1de7766484bae73f3ab133463c6][ressource spécifique]].
- Télécharger et installer RStudio depuis le [[https://www.rstudio.com/products/rstudio/download/#download][site RStudio]] en
choisissant le bon système d'exploitation.
- Télécharger et installer MiKTeX depuis le [[https://miktex.org/download][site MiKTeX]] en choisissant le bon
système d'exploitation. Vous serez amené à installer différents
packages lors du premier export pdf.
- Ouvrir RStudio et exécuter les commandes suivantes dans la console pour
installer =knitr= et =ggplot2=
#+BEGIN_SRC R
install.packages("knitr", dep=TRUE)
install.packages("ggplot2", dep=TRUE)
#+END_SRC
* Documentation RStudio
L’équipe de RStudio a créé différents matériels et tutoriels très bien
faits. Nous vous recommandons de consulter les [[https://www.rstudio.com/resources/cheatsheets/][fiches mémo]]. En
particulier, vous pourriez être intéressés par celles-ci :
- [[https://github.com/rstudio/cheatsheets/raw/master/rstudio-ide.pdf][RStudio IDE]],
- [[https://github.com/rstudio/cheatsheets/raw/master/rmarkdown-2.0.pdf][R Markdown]] (here is also a [[https://rmarkdown.rstudio.com/][nice step-by-step presentation of Rmarkdown]]),
- The [[https://www.rstudio.com/wp-content/uploads/2015/03/rmarkdown-reference.pdf][R Markdown Reference guide]],
- [[https://github.com/rstudio/cheatsheets/raw/master/data-visualization-2.1.pdf][Data visualization with ggplot2]],
- [[https://github.com/rstudio/cheatsheets/raw/master/data-transformation.pdf][Data transformation with dplyr]]
Voici aussi les versions françaises de certains documents mais elles
ne sont pas toujours à jour :
- [[https://github.com/rstudio/cheatsheets/raw/master/translations/french/rstudio-IDE-cheatsheet.pdf][IDE RStudio]]
- [[https://github.com/rstudio/cheatsheets/raw/master/translations/french/ggplot2-french-cheatsheet.pdf][Visualisation de données avec ggplot2]]
- [[https://github.com/rstudio/cheatsheets/raw/master/translations/french/data-wrangling-french.pdf][Transformation de données avec dplyr]]
- [[https://www.fun-mooc.fr/c4x/UPSUD/42001S02/asset/RMarkdown.pdf][Un court document sur R Markdown]]
This source diff could not be displayed because it is too large. You can view the blob instead.
# -*- mode: org -*-
#+TITLE: Rstudio
#+AUTHOR: Arnaud Legrand
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
* Table of Contents :TOC:
- [[#installing-rstudio][Installing RStudio]]
- [[#linux-debian-ubuntu][Linux (debian, ubuntu)]]
- [[#mac-osx-and-windows][Mac OSX and Windows]]
- [[#rstudio-documentation][RStudio documentation]]
- [[#using-git-from-rstudio][Using Git from RStudio]]
- [[#cloning-a-repository][Cloning a repository]]
- [[#modifying-a-file][Modifying a file]]
* Installing RStudio
** Linux (debian, ubuntu)
We provide here only instructions for Debian-based distributions. Feel
......@@ -53,11 +61,7 @@ sudo dpkg -i rstudio-xenial-1.1.453-amd64.deb
sudo apt-get update ; sudo apt-get -f install # to fix possibly missing dependencies
#+END_SRC
** Mac OSX and Windows
#+BEGIN_QUOTE
Some instructions on installing R and knitr must be missing. This
should be tested and improved.
#+END_QUOTE
- Download and install R from the [[https://cran.r-project.org/][CRAN webpage]] by choosing the right operating system.
- Install R and Python following the instructions given in a [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/19c2b1de7766484bae73f3ab133463c6][separate resource]].
- Download and install RStudio from the [[https://www.rstudio.com/products/rstudio/download/#download][RStudio webpage]] by choosing the right operating system.
- Download and install MiKTeX from the [[https://miktex.org/download][MiKTeX webpage]] by choosing the right operating system. You will be prompted to install some specific packages when exporting to pdf.
- Open RStudio and type the following commands in the console to install =knitr= and =ggplot2=:
......@@ -84,9 +88,9 @@ of these documents:
* Using Git from RStudio
If you have never used git with RStudio, *we strongly advise that you
follow [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/d132a854b0464ad29085cedaded23136][our tutorial on using git from RStudio]]* (/"RStudio et Gitlab"/
in French). Before proceeding, make sure you also have followed the
*[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/7508aece244548349424dfd61ee3ba85]["git/GitLab configuration" tutorial]]* (in French).
follow [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/d132a854b0464ad29085cedaded23136][our tutorial on using git from RStudio]]* (/"RStudio et Gitlab"/
). Before proceeding, make sure you also have followed the
*[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85]["git/GitLab configuration" tutorial]]*.
Alternatively, you may want to watch [[https://www.youtube.com/embed/uHYcDQDbMY8][this video]] (in English). If you
do not like videos, you should have a look at the [[https://swcarpentry.github.io/git-novice/14-supplemental-rstudio/index.html][step-by-step
......@@ -112,7 +116,7 @@ Open RStudio and do the following steps:
[[file:rstudio_images/clone.png]]
#+END_CENTER
- If you're behind a proxy, git should be configured
accordingly. Check the [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/7508aece244548349424dfd61ee3ba85]["Dealing with proxies" section]].
accordingly. Check the [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85]["Dealing with proxies" section]].
- Git will then connect to Gitlab and fetch a whole copy of the
repository.
- RStudio should restart in a mode related to Git:
......
# -*- mode: org -*-
#+TITLE: Rstudio
#+AUTHOR: Arnaud Legrand
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
* Table des matières :TOC:
- [[#installer-rstudio][Installer RStudio]]
- [[#linux-debian-ubuntu][Linux (debian, ubuntu)]]
- [[#mac-osx-and-windows][Mac OSX and Windows]]
- [[#documentation-rstudio][Documentation RStudio]]
- [[#utiliser-git-avec-rstudio][Utiliser Git avec RStudio]]
- [[#cloner-un-dépôt][Cloner un dépôt]]
- [[#modifier-un-fichier][Modifier un fichier]]
* Installer RStudio
** Linux (debian, ubuntu)
Nous ne fournissons ici que des instructions pour les distributions
......@@ -54,8 +62,7 @@ sudo dpkg -i rstudio-xenial-1.1.453-amd64.deb
sudo apt-get update ; sudo apt-get -f install # to fix possibly missing dependencies
#+END_SRC
** Mac OSX and Windows
- Télécharger et installer R depuis le [[https://cran.r-project.org/][site CRAN]] en choisissant le bon
système d'exploitation.
- Installer R et Python en suivant les instruction dans une [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/19c2b1de7766484bae73f3ab133463c6][ressource spécifique]].
- Télécharger et installer RStudio depuis le [[https://www.rstudio.com/products/rstudio/download/#download][site RStudio]] en
choisissant le bon système d'exploitation.
- Télécharger et installer MiKTeX depuis le [[https://miktex.org/download][site MiKTeX]] en choisissant le bon
......@@ -86,11 +93,11 @@ ne sont pas toujours à jour :
* Utiliser Git avec RStudio
La première chose à faire est de configurer Git sur votre
ordinateur. Pour ce faire, vous pouvez suivre la vidéo
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/courseware/66bc811404b8481da5f794de54681c5e/2419fd0fb6a0484988ca9d65497dcaaf/1?activate_block_id=block-v1%3Ainria%2B41016%2Bsession01bis%2Btype%40vertical%2Bblock%407508aece244548349424dfd61ee3ba85][configurer Git pour Gitlab]] (en français) et le document
[[https://app-learninglab.inria.fr/gitlab/learning-lab/mooc-rr-ressources/blob/master/module2/ressources/gitlab_fr.org][Git et Gitlab]] correspondant (en français).
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][configurer Git pour Gitlab]] et le document
[[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/module2/ressources/gitlab_fr.org][Git et Gitlab]] correspondant.
Vous pourrez alors utiliser Git avec RStudio. Pour ce faire, vous
pouvez suivre la vidéo [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/d132a854b0464ad29085cedaded23136][RStudio - Gitlab]] (en français) dont les étapes
pouvez suivre la vidéo [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/d132a854b0464ad29085cedaded23136][RStudio - Gitlab]] dont les étapes
sont reprises ci-dessous.
/(Nous vous signalons aussi cette/ [[https://www.youtube.com/embed/uHYcDQDbMY8][vidéo]] /(en anglais) ainsi que le/ [[https://swcarpentry.github.io/git-novice/14-supplemental-rstudio/index.html][tuto
......@@ -98,8 +105,7 @@ pas à pas]] /(en anglais) de Software Carpentry.)/
** Cloner un dépôt
Ouvrir RStudio et procéder comme suit :
- Créer un nouveau projet sous contrôle de version : =File / New
Project / Version Control=
- Créer un nouveau projet sous contrôle de version : =File / New Project / Version Control=
#+BEGIN_CENTER
[[file:rstudio_images/new_project.png]]
......@@ -117,7 +123,7 @@ Ouvrir RStudio et procéder comme suit :
[[file:rstudio_images/clone.png]]
#+END_CENTER
- Si vous êtes derrière un proxy, il faut le définir dans Git (voir le
paragraphe "Gérer les proxy" de la page sur [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/7508aece244548349424dfd61ee3ba85][Git et Gitlab]]).
paragraphe "Gérer les proxy" de la page sur [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/7508aece244548349424dfd61ee3ba85][Git et Gitlab]]).
- Git se connecte à Gitlab et récupère une copie complète du dépôt.
- RStudio redémarre dans un mode lié à Git :
#+BEGIN_CENTER
......@@ -148,7 +154,7 @@ Ouvrir RStudio et procéder comme suit :
[[file:rstudio_images/push3.png]]
#+END_CENTER
*NB :* Vous ne pouvez pas propager vos modifications sur GitLab si
N.B. : Vous ne pouvez pas propager vos modifications sur GitLab si
des modifications ont été faites sur GitLab entre-temps.
#+BEGIN_CENTER
[[file:rstudio_images/push4.png]]
......
---
title: "Mon premier document"
author: "Arnaud Legrand"
date: "10 octobre 2017"
output: word_document
---
## R Markdown
This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.
When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
```{r cars}
summary(cars)
```
## Including Plots
You can also embed plots, for example:
```{r pressure, echo=FALSE}
plot(pressure)
```
Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.
## Ma propre section
```{r}
x=1
x
```
```{r}
x = x + 10
x
```
```{r}
hist(rnorm(1000))
```
```{r}
hist(rnorm(100,mean = 2, sd = .2))
```
## Un petit exemple avec d'autres langages
```{python}
from math import *
x = 3.14
print(sin(x))
```
```{python}
print(sin(x))
```
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Titre du document"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2+2"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"10\n"
]
}
],
"source": [
"x=10\n",
"print(x)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"20\n"
]
}
],
"source": [
"x = x + 10\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Petit exemple de completion"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"mu, sigma = 100, 15"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"x = np.random.normal(loc=mu, scale=sigma, size=10000)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYMAAAD8CAYAAACVZ8iyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4xLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvAOZPmwAAEGRJREFUeJzt3X+s3XV9x/Hna1TY/LFQ1gvDtu5WU7eBUSQdspEtKBMKGIvJTEqMNI6kZoFNF/ejaDKchgQ3lY2EsVTpKJuDMcXRSCd2nZnxD34UhoVaGXfQwaUdrUPRjQQF3/vjfBoP7bm395x7e889+HwkJ+d83+fzPd/PJ5/b+7rfH+fbVBWSpJ9sPzXsDkiShs8wkCQZBpIkw0CShGEgScIwkCRhGEiSMAwkSRgGkiRg0bA7MJ0lS5bU+Pj4sLshSSPlvvvu+3ZVjfWzzoIOg/HxcXbs2DHsbkjSSEnyX/2u42EiSZJhIEkyDCRJGAaSJAwDSRKGgSQJw0CShGEgScIwkCSxwL+BLC1k4xvuGMp291x94VC2q5c29wwkSYaBJMkwkCRhGEiSMAwkSRgGkiS8tFQjbliXd0ovNe4ZSJIMA0mSYSBJwjCQJGEYSJIwDCRJGAaSJAwDSRKGgSSJGYRBkuVJvppkd5JdST7Q6h9N8mSSB9rjgq51rkgykeThJOd11Ve32kSSDUdnSJKkfs3kdhTPAx+qqvuTvAq4L8m29t41VfXJ7sZJTgHWAqcCrwb+Jcnr29vXAW8HJoF7k2ypqm/OxUAkSYM7YhhU1T5gX3v9/SS7gaXTrLIGuKWqngMeSzIBnNHem6iqRwGS3NLaGgaSNGR9nTNIMg68Gbi7lS5PsjPJpiSLW20p8ETXapOtNlVdkjRkMw6DJK8EvgB8sKq+B1wPvA44jc6ew6cONu2xek1TP3Q765PsSLLjwIEDM+2eJGkWZhQGSV5GJwg+V1W3AVTVU1X1QlX9CPgMPz4UNAks71p9GbB3mvqLVNXGqlpVVavGxsb6HY8kaQAzuZoowA3A7qr6dFf95K5m7wIeaq+3AGuTHJdkBbASuAe4F1iZZEWSY+mcZN4yN8OQJM3GTK4mOgt4L/Bgkgda7cPAxUlOo3OoZw/wfoCq2pXkVjonhp8HLquqFwCSXA7cCRwDbKqqXXM4FknSgGZyNdHX6X28f+s061wFXNWjvnW69SRJw+E3kCVJhoEkyTCQJGEYSJIwDCRJGAaSJAwDSRKGgSQJw0CShGEgScIwkCRhGEiSMAwkSRgGkiQMA0kShoEkCcNAkoRhIEnCMJAkYRhIkjAMJEkYBpIkDANJEoaBJAnDQJKEYSBJwjCQJGEYSJKYQRgkWZ7kq0l2J9mV5AOtfkKSbUkeac+LWz1Jrk0ykWRnktO7Pmtda/9IknVHb1iSpH7MZM/geeBDVfXLwJnAZUlOATYA26tqJbC9LQOcD6xsj/XA9dAJD+BK4C3AGcCVBwNEkjRcRwyDqtpXVfe3198HdgNLgTXA5tZsM3BRe70GuKk67gKOT3IycB6wraqerqrvANuA1XM6GknSQPo6Z5BkHHgzcDdwUlXtg05gACe2ZkuBJ7pWm2y1qeqSpCGbcRgkeSXwBeCDVfW96Zr2qNU09UO3sz7JjiQ7Dhw4MNPuSZJmYUZhkORldILgc1V1Wys/1Q7/0J73t/oksLxr9WXA3mnqL1JVG6tqVVWtGhsb62cskqQBzeRqogA3ALur6tNdb20BDl4RtA64vat+Sbuq6EzgmXYY6U7g3CSL24njc1tNkjRki2bQ5izgvcCDSR5otQ8DVwO3JrkUeBx4d3tvK3ABMAE8C7wPoKqeTvJx4N7W7mNV9fScjEKSNCtHDIOq+jq9j/cDnNOjfQGXTfFZm4BN/XRQknT0+Q1kSZJhIEkyDCRJGAaSJAwDSRKGgSQJw0CShGEgScIwkCRhGEiSMAwkSRgGkiQMA0kShoEkCcNAkoRhIEliZv/TmaQFZHzDHUPb9p6rLxzatnV0uWcgSTIMJEmGgSQJw0CShGEgScIwkCRhGEiSMAwkSRgGkiQMA0kShoEkiRmEQZJNSfYneair9tEkTyZ5oD0u6HrviiQTSR5Ocl5XfXWrTSTZMPdDkSQNaiZ7BjcCq3vUr6mq09pjK0CSU4C1wKltnb9KckySY4DrgPOBU4CLW1tJ0gJwxLuWVtXXkozP8PPWALdU1XPAY0kmgDPaexNV9ShAklta22/23WMtSMO8k6ak2ZvNOYPLk+xsh5EWt9pS4ImuNpOtNlVdkrQADBoG1wOvA04D9gGfavX0aFvT1A+TZH2SHUl2HDhwYMDuSZL6MVAYVNVTVfVCVf0I+Aw/PhQ0CSzvaroM2DtNvddnb6yqVVW1amxsbJDuSZL6NFAYJDm5a/FdwMErjbYAa5Mcl2QFsBK4B7gXWJlkRZJj6Zxk3jJ4tyVJc+mIJ5CT3AycDSxJMglcCZyd5DQ6h3r2AO8HqKpdSW6lc2L4eeCyqnqhfc7lwJ3AMcCmqto156ORJA1kJlcTXdyjfMM07a8CrupR3wps7at3kqR54TeQJUmGgSTJMJAkYRhIkjAMJEkYBpIkDANJEoaBJAnDQJKEYSBJwjCQJGEYSJIwDCRJGAaSJAwDSRKGgSQJw0CShGEgScIwkCRhGEiSMAwkSRgGkiQMA0kShoEkCcNAkoRhIEnCMJAkYRhIkjAMJEnMIAySbEqyP8lDXbUTkmxL8kh7XtzqSXJtkokkO5Oc3rXOutb+kSTrjs5wJEmDmMmewY3A6kNqG4DtVbUS2N6WAc4HVrbHeuB66IQHcCXwFuAM4MqDASJJGr4jhkFVfQ14+pDyGmBze70ZuKirflN13AUcn+Rk4DxgW1U9XVXfAbZxeMBIkoZk0HMGJ1XVPoD2fGKrLwWe6Go32WpT1Q+TZH2SHUl2HDhwYMDuSZL6MdcnkNOjVtPUDy9WbayqVVW1amxsbE47J0nqbdAweKod/qE972/1SWB5V7tlwN5p6pKkBWDQMNgCHLwiaB1we1f9knZV0ZnAM+0w0p3AuUkWtxPH57aaJGkBWHSkBkluBs4GliSZpHNV0NXArUkuBR4H3t2abwUuACaAZ4H3AVTV00k+Dtzb2n2sqg49KS1JGpIjhkFVXTzFW+f0aFvAZVN8ziZgU1+9kyTNC7+BLEkyDCRJhoEkCcNAkoRhIEnCMJAkYRhIkjAMJEkYBpIkDANJEoaBJAnDQJKEYSBJwjCQJGEYSJIwDCRJGAaSJAwDSRKGgSQJw0CShGEgScIwkCRhGEiSMAwkSRgGkiQMA0kSsGjYHZA0OsY33DGU7e65+sKhbPcniXsGkqTZhUGSPUkeTPJAkh2tdkKSbUkeac+LWz1Jrk0ykWRnktPnYgCSpNmbiz2Dt1bVaVW1qi1vALZX1Upge1sGOB9Y2R7rgevnYNuSpDlwNA4TrQE2t9ebgYu66jdVx13A8UlOPgrblyT1abZhUMBXktyXZH2rnVRV+wDa84mtvhR4omvdyVaTJA3ZbK8mOquq9iY5EdiW5FvTtE2PWh3WqBMq6wFe85rXzLJ7P3mGdbWHpNE2qz2DqtrbnvcDXwTOAJ46ePinPe9vzSeB5V2rLwP29vjMjVW1qqpWjY2NzaZ7kqQZGjgMkrwiyasOvgbOBR4CtgDrWrN1wO3t9RbgknZV0ZnAMwcPJ0mShms2h4lOAr6Y5ODn/H1VfTnJvcCtSS4FHgfe3dpvBS4AJoBngffNYtuSpDk0cBhU1aPAm3rU/wc4p0e9gMsG3Z4k6ejxG8iSJMNAkmQYSJIwDCRJGAaSJAwDSRKGgSQJw0CShGEgScIwkCRhGEiSMAwkSRgGkiQMA0kShoEkCcNAkoRhIEnCMJAkYRhIkjAMJEkYBpIkDANJErBo2B2QpCMZ33DH0La95+oLh7bt+eSegSTJMJAkGQaSJDxncFQM8/imJA3CPQNJ0vyHQZLVSR5OMpFkw3xvX5J0uHkNgyTHANcB5wOnABcnOWU++yBJOtx87xmcAUxU1aNV9QPgFmDNPPdBknSI+T6BvBR4omt5EnjL0dqYJ3Ilzdawfo/M95fd5jsM0qNWL2qQrAfWt8X/TfLwNJ+3BPj2HPVtIXFco8VxjZaRGFc+0fcq3eP6hX5Xnu8wmASWdy0vA/Z2N6iqjcDGmXxYkh1VtWruurcwOK7R4rhGi+Pqbb7PGdwLrEyyIsmxwFpgyzz3QZJ0iHndM6iq55NcDtwJHANsqqpd89kHSdLh5v0byFW1Fdg6Rx83o8NJI8hxjRbHNVocVw+pqiO3kiS9pHk7CknSaIVBkmOS/HuSL7XlFUnuTvJIkn9oJ6VHTpLjk3w+ybeS7E7yq0lOSLKtjW1bksXD7me/kvx+kl1JHkpyc5KfHsU5S7Ipyf4kD3XVes5POq5tt1vZmeT04fV8elOM68/bz+HOJF9McnzXe1e0cT2c5Lzh9PrIeo2r670/SFJJlrTlkZ6vVv/dNie7kvxZV72v+RqpMAA+AOzuWv4EcE1VrQS+A1w6lF7N3l8CX66qXwLeRGeMG4DtbWzb2/LISLIU+D1gVVW9gc4FA2sZzTm7EVh9SG2q+TkfWNke64Hr56mPg7iRw8e1DXhDVb0R+A/gCoB225i1wKltnb9qt5dZiG7k8HGRZDnwduDxrvJIz1eSt9K5i8Mbq+pU4JOt3vd8jUwYJFkGXAh8ti0HeBvw+dZkM3DRcHo3uCQ/C/wGcANAVf2gqr5LZ4I3t2YjOTY6Fyj8TJJFwMuBfYzgnFXV14CnDylPNT9rgJuq4y7g+CQnz09P+9NrXFX1lap6vi3eRee7QNAZ1y1V9VxVPQZM0Lm9zIIzxXwBXAP8ES/+outIzxfwO8DVVfVca7O/1fuer5EJA+Av6Ezkj9ryzwHf7frBnaRzu4tR81rgAPA37RDYZ5O8AjipqvYBtOcTh9nJflXVk3T+SnmcTgg8A9zHS2POYOr56XXLlVEd428D/9xej/S4krwTeLKqvnHIWyM9LuD1wK+3Q6//luRXWr3vcY1EGCR5B7C/qu7rLvdoOoqXRi0CTgeur6o3A//HiB0S6qUdQ18DrABeDbyCzi75oUZxzqbzkvi5TPIR4HngcwdLPZqNxLiSvBz4CPAnvd7uURuJcTWLgMXAmcAfAre2oyZ9j2skwgA4C3hnkj107nT6Njp7Cse3QxDQ49YWI2ISmKyqu9vy5+mEw1MHd1fb8/4p1l+ofhN4rKoOVNUPgduAX+OlMWcw9fwc8ZYrC12SdcA7gPfUj689H+VxvY7OHyXfaL9DlgH3J/l5Rntc0On/be0w1z10jpwsYYBxjUQYVNUVVbWsqsbpnBT516p6D/BV4Ldas3XA7UPq4sCq6r+BJ5L8YiudA3yTzm061rXaKI7tceDMJC9vf6kcHNfIz1kz1fxsAS5pV6mcCTxz8HDSKEiyGvhj4J1V9WzXW1uAtUmOS7KCzgnXe4bRx35V1YNVdWJVjbffIZPA6e3f3kjPF/BPdP44JsnrgWPp3Kyu//mqqpF6AGcDX2qvX9sGOAH8I3DcsPs34JhOA3YAO9vkLqZzTmQ78Eh7PmHY/RxgXH8KfAt4CPhb4LhRnDPgZjrnPX5I5xfJpVPND53d8+uA/wQepHM11dDH0Me4Jugca36gPf66q/1H2rgeBs4fdv/7Gdch7+8BlrxE5utY4O/av7H7gbcNOl9+A1mSNBqHiSRJR5dhIEkyDCRJhoEkCcNAkoRhIEnCMJAkYRhIkoD/B8IGXPTxqh8eAAAAAElFTkSuQmCC\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f1a57acff98>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"plt.hist(x)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Utilisation d'autres langages"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"%load_ext rpy2.ipython"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n"
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%R\n",
"plot(cars)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
# -*- coding: utf-8 -*-
# -*- mode: org -*-
#+TITLE: Une petite démo d'Org-Mode
#+AUTHOR: Arnaud Legrand
#+STARTUP: overview indent inlineimages logdrawer
#+LANGUAGE: en
#+HTML_HEAD: <link rel="stylesheet" title="Standard" href="http://orgmode.org/worg/style/worg.css" type="text/css" />
#+PROPERTY: header-args :eval never-export
* Section 1
** Sous-section
* Section 2
** Foo
*** Hello
Avec du texte
- ici du *gras*
- et là, de /l'italique/
*** Salut
*** Etc
** Bar
** Baz
* Exécution de calculs :noexport:
#+begin_src R :results output :session *R* :exports both
cars
#+end_src
#+RESULTS:
#+begin_example
speed dist
1 4 2
2 4 10
3 7 4
4 7 22
5 8 16
6 9 10
7 10 18
8 10 26
9 10 34
10 11 17
11 11 28
12 12 14
13 12 20
14 12 24
15 12 28
16 13 26
17 13 34
18 13 34
19 13 46
20 14 26
21 14 36
22 14 60
23 14 80
24 15 20
25 15 26
26 15 54
27 16 32
28 16 40
29 17 32
30 17 40
31 17 50
32 18 42
33 18 56
34 18 76
35 18 84
36 19 36
37 19 46
38 19 68
39 20 32
40 20 48
41 20 52
42 20 56
43 20 64
44 22 66
45 23 54
46 24 70
47 24 92
48 24 93
49 24 120
50 25 85
#+end_example
#+begin_src R :results output graphics :file (org-babel-temp-file "figure" ".png") :exports results :width 600 :height 400 :session *R*
plot(cars)
#+end_src
#+RESULTS:
[[file:/tmp/babel-148945lI/figure14894n0r.png]]
#+begin_src R :results output :session *R* :exports both
(x=10)
#+end_src
#+RESULTS:
: [1] 10
#+begin_src R :results output :session *R* :exports both
(x = x+10)
#+end_src
#+RESULTS:
: [1] 20
* Autres langages
#+begin_src python :results output :exports both
print(2+2)
#+end_src
#+RESULTS:
: 4
#+begin_src shell :results output :exports both
ls /tmp
#+end_src
#+RESULTS:
#+begin_example
babel-148945lI
babel-1933r-E
babel-7506nSG
emacs1000
emacs14894axZ
firefox-esr_alegrand
mozilla_alegrand0
pulse-PKdhtXMmr18n
RtmpsK10QZ
RtmpvMPlZs
ScientificMethodologyProjectGithub.ipynb
ssh-KQXcWTA8Cx6u
systemd-private-0461cab7d3944a9e974b73d23efc09af-apache2.service-QPpUU4
systemd-private-0461cab7d3944a9e974b73d23efc09af-colord.service-wdsVAi
systemd-private-0461cab7d3944a9e974b73d23efc09af-iio-sensor-proxy.service-UYGEGU
systemd-private-0461cab7d3944a9e974b73d23efc09af-ModemManager.service-FKfsh9
systemd-private-0461cab7d3944a9e974b73d23efc09af-rtkit-daemon.service-43AVDL
systemd-private-0461cab7d3944a9e974b73d23efc09af-systemd-timesyncd.service-4pB1fo
thunderbird_alegrand
tracker-extract-files.1000
tutoriel.pdf
#+end_example
#+begin_src shell :session *shell* :results output :exports both
hostname
#+end_src
#+RESULTS:
:
: icarus
#+begin_src shell :session *shell* :results output :exports both
ssh nipmuk
#+end_src
#+RESULTS:
: The programs included with the Debian GNU/Linux system are free software;
: the exact distribution terms for each program are described in the
: individual files in /usr/share/doc/*/copyright.
:
: Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
: permitted by applicable law.
: Last login: Tue Apr 10 12:10:47 2018 from ligone.imag.fr
#+begin_src shell :session *shell* :results output :exports both
hostname
ls /tmp/
#+end_src
#+RESULTS:
: nipmuk
: ATN452-P5785-Linux-X64.bin tina_update vgauthsvclog.txt.0
: P57 tn_pipe vmware-root
: ssh-0xgYrn2tUz upgrade_linux.batch
# -*- coding: utf-8 -*-
# -*- mode: org -*-
#+TITLE: Org document examples
#+TITLE: Document Examples
#+AUTHOR: Arnaud Legrand
#+STARTUP: overview indent inlineimages logdrawer
#+LANGUAGE: en
* Table of Contents :TOC:
- [[#examples-from-the-video][Examples from the Video]]
- [[#other-examples][Other examples]]
* Examples from the Video
In the MOOC video, I quickly demo how org-mode can be used in various
contexts. Here are the (sometimes trimmed) corresponding
org-files. These documents depend on many other external data files
and are not meant to lead to reproducible documents but it will give
you an idea of how it can be organized:
1. [[file:journal.org][journal.org]]: an excerpt (I've only left a few code samples and links
1. [[file:td2_PS.ipynb][td2_PS.ipynb]]: this is a practical session (in French) on random
number generation for 1st year master students in computer
science. It uses the R language. In this teaching context, the main
advantage of using a jupyter notebook over other environments is
that students can use the University jupyterhub and thus do not
have to install anything on their laptop.
2. [[file:journal.org][journal.org]]: an excerpt (I've only left a few code samples and links
to some resources on R, Stats, ...) from my own journal. This is a
personal document where everything (meeting notes, hacking, random
thoughts, ...) goes by default. Entries are created with the =C-c c=
shortcut.
2. [[file:labbook_single.org][labbook_single.org]]: this is an excerpt from the laboratory notebook
3. [[file:labbook_single.org][labbook_single.org]]: this is an excerpt from the laboratory notebook
[[https://cornebize.net/][Tom Cornebize]] wrote during his Master thesis internship under my
supervision. This a personal labbook. I consider this notebook to be
excellent and was the ideal level of details for us to communicate
without any ambiguity and for him to move forward with confidence.
3. [[file:paper.org][paper.org]]: this is an ongoing paper based on the previous labbook of
4. [[file:paper.org][paper.org]]: this is an ongoing paper based on the previous labbook of
Tom Cornebize. As such it is not reproducible as there are hardcoded
paths and uncleaned dependencies but writing it from the labbook was
super easy as we just had to cut and paste the parts we
......@@ -32,7 +44,7 @@ you an idea of how it can be organized:
commands that are automatically executed when opening the file. It
is an effective way to depend less on the =.emacs/init.el= which is
generally customized by everyone.
4. [[file:labbook_several.org][labbook_several.org]]: this is a labbook for a specific project shared
5. [[file:labbook_several.org][labbook_several.org]]: this is a labbook for a specific project shared
by several persons. As a consequence it starts with information
about installation, common scripts, has section with notes about all
our meetings, a section with information about experiments and an
......@@ -41,7 +53,7 @@ you an idea of how it can be organized:
available in git so we did not bother. In such labbook, it is common
to find annotations indicating that such experiment was =:FLAWED:= as
it had some issues.
5. [[file:technical_report.org][technical_report.org]]: this is a short technical document I wrote
6. [[file:technical_report.org][technical_report.org]]: this is a short technical document I wrote
after a colleague sent me a PDF describing an experiment he was
conducting and asked me about how reproducible I felt it was. It
turned out I had to cut and paste the C code from the PDF, then
......@@ -50,7 +62,11 @@ you an idea of how it can be organized:
org-mode made it very easy to generate both HTML and PDF and to
explicitly explain how the measurements were done.
* Other examples
Here are a few links to other kind of examples:
- John Kitchin is an expert org-mode user and he maintains a very
interesting [[http://kitchingroup.cheme.cmu.edu/blog/][blog with many interesting tips]]. You may want to check
this [[https://www.youtube.com/watch?v=IsSMs-4GlT8&list=FLQp2VLAOlvq142YN3JO3y8w&app=desktop][seminar he gave at SciPy]].
- Slides: all my slides for a series of lectures is available here:
https://github.com/alegrand/SMPE. Here is a [[https://raw.githubusercontent.com/alegrand/SMPE/master/lectures/lecture_central_limit_theorem.org][typical source]] and the
[[https://raw.githubusercontent.com/alegrand/SMPE/master/lectures/lecture_central_limit_theorem.pdf][resulting PDF]]
......@@ -60,3 +76,4 @@ Here are a few links to other kind of examples:
- his lecture on programming languages for undergrads:
https://github.com/schnorr/mlp/tree/master/conteudo
# -*- coding: utf-8 -*-
# -*- mode: org -*-
#+TITLE: Quelques exemples de documents en Org-mode
#+AUTHOR: Arnaud Legrand
#+STARTUP: overview indent inlineimages logdrawer
#+LANGUAGE: en
* Table of Contents :TOC:
- [[#les-documents-montrés-en-exemple-dans-les-vidéos-du-mooc][Les documents montrés en exemple dans les vidéos du MOOC]]
- [[#autres-exemples][Autres exemples]]
* Les documents montrés en exemple dans les vidéos du MOOC
Dans les vidéos, je montre rapidement comment Org-mode peut être
utilisé dans différents contextes (feuille de TD, journal, cahier de
laboratoire, article). Voici les fichiers Org-mode (quelques fois un
peu épurés) correspondants. Ces documents dépendent souvent d'autres
fichiers externes et ne sont pas prévus pour permettre de produire
directement des documents reproductibles mais ils peuvent vous donner
une idée de la façon dont ils peuvent être organisés :
1. [[file:td2_PS.ipynb][td2_PS.ipynb]] : ceci est une feuille de TD (en français) sur la
génération de nombres aléatoires à destination d'étudiants de
première année de Master en informatique. Elle utilise le langage
R. Dans ce contexte d'enseignement, l'intérêt du notebook Jupyter
est que les étudiants peuvent utiliser le Jupyterhub de l'université et n'ont
donc rien à installer sur leur machine.
2. [[file:journal.org][journal.org]] : ceci est un extrait (je n'ai laissé que quelques
exemples de programmes et de liens vers des ressources sur R, les
statistiques, etc.) de mon propre journal. C'est un document
personnel dans lequel tout ce que je peux faire (notes prises
pendant une réunion, petit code vite fait, idées diverses et
variées, notes bibliographiques...) atterrit par défaut. Les
entrées avec la date sont créées automatiquement à l'aide du
raccourci =C-c c=.
3. [[file:labbook_single.org][labbook_single.org]] : ceci est un extrait du cahier de laboratoire
tenu par [[https://cornebize.net/][Tom Cornebize]] pendant son stage de Master sous ma
direction. C'est un cahier de laboratoire personnel que je
considère comme excellent car il a le niveau de détail idéal pour
nous permettre à la fois de communiquer sans aucune ambiguïté, pour
moi de bien suivre ses avancées, et pour lui d'avancer dans ses
travaux avec confiance.
4. [[file:paper.org][paper.org]] : ceci est un article en cours basé sur le cahier de
laboratoire précédent. En l'état, il n'est pas reproductible car il
y a plusieurs chemins absolus en dur et des dépendances logicielles
non explicitées mais sa rédaction à partir du cahier de laboratoire
a vraiment été très facile puisqu'il nous suffisait de
copier/coller et d'assembler toutes les parties dont nous avions
besoin de rendre compte. Ce qui peut être intéressant, c'est
l'organisation de ce document (avec des sections cachées qui
récupèrent les données, les traitent et génèrent les figures) ainsi
que la configuration Org-mode permettant d'exporter avec le bon
style LaTeX. Comme vous le remarquerez, il y a à la toute fin du
document une section avec des commandes Emacs Lisp commentées mais
qui sont exécutées par Emacs à l'ouverture du fichier. C'est une
façon simple mais efficace de dépendre le moins possible du
=.emacs/init.el= que chacun personnalise à sa convenance.
5. [[file:labbook_several.org][labbook_several.org]] : ceci est un petit exemple de cahier de
laboratoire partagé par plusieurs personnes. Il commence donc par
des informations sur les dépendances logicielles à installer, les
scripts les plus utiles. On y trouve ensuite une section avec des
notes sur nos réunions puis une section avec des informations sur
nos expériences et enfin une section sur les analyses de données.
Idéalement, chaque entrée devrait être étiquetée par le nom de
celui qui l'a écrite mais comme nous étions peu nombreux et que
cette information est de toutes façons disponible dans le Git, nous
ne nous sommes pas embêtés. C'est néanmoins une bonne habitude à
prendre car si quelqu'un reformate le document (par exemple en
ré-indentant et en changeant les espaces) il devient en général le
dernier "propriétaire" de l'ensemble des lignes dans Git. Dans ce
cahier de laboratoire, vous trouverez également des annotations
indiquant que telle ou telle expérience est =:FLAWED:=. Ces
annotations ont été réalisées a posteriori, lorsque l'on a réalisé
qu'il y avait eu un problème et une petite explication (avec une
nouvelle date) est en général alors ajoutée. L'annotation =:FLAWED:=
nous permet de conserver l'ensemble des expériences tout en sachant
d'un coup d'oeil lesquelles ne doivent pas être prises en compte.
6. [[file:technical_report.org][technical_report.org]] : ceci est un petit document technique que j'ai
écrit après qu'un collègue m'a envoyé un document PDF décrivant
une expérience qu'il avait réalisée alors qu'il souhaitait mon avis pour savoir si
c'était suffisant d'un point de vue reproductibilité. Il s'est
avéré que pour ré-exécuter le code présenté, j'ai pu copier-coller le
code C à partir du PDF mais qu'il a fallu que j'enlève tous les
numéros de lignes, que je corrige des problèmes de syntaxes
introduits par la colorisation syntaxique et le formatage PDF,
etc. Évidemment, les résultats de performance que j'ai obtenus
étaient assez différents mais en écrivant tout en Org-mode, j'ai
très facilement et très rapidement pu produire un document à la
fois en HTML et en PDF tout en explicitant très précisément comment
les mesures étaient effectuées.
* Autres exemples
Voici à toute fin utile quelques liens vers d'autres types d'exemples :
- John Kitchin est un expert org-modiste impliqué dans les questions
de recherche reproductible et qui tient à jour un [[http://kitchingroup.cheme.cmu.edu/blog/][blog avec une
foule d'astuces intéressantes]]. Vous trouverez ici un
[[https://www.youtube.com/watch?v=IsSMs-4GlT8&list=FLQp2VLAOlvq142YN3JO3y8w&app=desktop][séminaire qu'il a donné à SciPy]].
- Présentations : l'ensemble des slides que j'utilise pour une série de
cours ainsi que pour des présentations sur la recherche
reproductible sont disponibles ici :
[[https://github.com/alegrand/SMPE]]. Je n'ai pas fait d'effort
particulier pour m'assurer que ça compile sur toutes les machines de
la terre mais voici à quoi ressemblent typiquement les
[[https://raw.githubusercontent.com/alegrand/SMPE/master/lectures/lecture_central_limit_theorem.org][sources]] avec
le [[https://raw.githubusercontent.com/alegrand/SMPE/master/lectures/lecture_central_limit_theorem.pdf][PDF résultant]].
- Lucas Schnorr, un collègue et ami, maintient :
- un ensemble de modèles en Org-mode pour certaines conférences et
journaux en informatique: [[https://github.com/schnorr/ieeeorg][IEEE]], [[https://github.com/schnorr/wileyorg][Wiley]],
[[https://github.com/schnorr/acmorg][ACM]], [[https://github.com/schnorr/llncsorg][LNCS]]
- son cours de programmation (en portugais) pour les élèves de licence :
https://github.com/schnorr/mlp/tree/master/conteudo
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# TD2: Générateurs pseudo-aléatoires (RICM4, 2013)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"L'objectif de cette fiche est de présenter les méthodes principales de génération de nombres pseudo-aléatoires, de comprendre leurs limitations, d'apprendre à s'en méfier et de voir comment éventuellement les corriger...\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Générateurs à base de congruence"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"congruent_random <- function(n = 100, a=4, b=2, m=9, x1=1) {\n",
" res = c(x1)\n",
" for(i in 2:n) {\n",
" res[i] = (a * res[i-1] + b) %% m\n",
" }\n",
" res\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Regardons les premières valeurs"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<ol class=list-inline>\n",
"\t<li>1</li>\n",
"\t<li>6</li>\n",
"\t<li>8</li>\n",
"\t<li>7</li>\n",
"\t<li>3</li>\n",
"\t<li>5</li>\n",
"\t<li>4</li>\n",
"\t<li>0</li>\n",
"\t<li>2</li>\n",
"\t<li>1</li>\n",
"</ol>\n"
],
"text/latex": [
"\\begin{enumerate*}\n",
"\\item 1\n",
"\\item 6\n",
"\\item 8\n",
"\\item 7\n",
"\\item 3\n",
"\\item 5\n",
"\\item 4\n",
"\\item 0\n",
"\\item 2\n",
"\\item 1\n",
"\\end{enumerate*}\n"
],
"text/markdown": [
"1. 1\n",
"2. 6\n",
"3. 8\n",
"4. 7\n",
"5. 3\n",
"6. 5\n",
"7. 4\n",
"8. 0\n",
"9. 2\n",
"10. 1\n",
"\n",
"\n"
],
"text/plain": [
" [1] 1 6 8 7 3 5 4 0 2 1"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"congruent_random(10)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Regardons maintenant graphiquement ces valeurs"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAADAFBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGC\ngoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OU\nlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWm\npqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4\nuLi5ubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnK\nysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc\n3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u\n7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7////i\nsF19AAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dCZhU1Znw8be6oWkb2URAkEUb\ng4i4RBEbJMRPMSC474i7BjSjMS6JUaPRkM3RSUzGMc7EBYMzSdRkcEaNCigTcde4Mm4RDC5g\n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",
"text/plain": [
"Plot with title “Histogram of X”"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"graphical_check <- function(X) {\n",
" par(mfrow=c(1,2))\n",
" hist(X)\n",
" plot(X[1:length(X)-1],X[2:length(X)])\n",
"}\n",
"graphical_check(congruent_random(100))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Évidemment, l'espace d'état est trop petit. Essayons avec d'autres paramètres."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAADAFBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGC\ngoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OU\nlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWm\npqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4\nuLi5ubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnK\nysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc\n3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u\n7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7////i\nsF19AAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO2dCXwTRfvHnyS9aEspR4EWWk6x\nVECQqyCXgByVGwSRS174cygICt6+iOKBgjf64gGi4In6oq+AiAKKCqKCgqggAiKnIFAECpR2\n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\nAAAAAElFTkSuQmCC",
"text/plain": [
"Plot with title “Histogram of X”"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"graphical_check(congruent_random(n=100,a=11,b=1,m=71))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cela parait mieux mais en s'intéressant à la corrélation et à la covariance entre $X_n$ et $X_{n+1}$, le fait que nos nombres ne sont pas indépendants les uns des autres est plus évident."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"0.0457750907128348"
],
"text/latex": [
"0.0457750907128348"
],
"text/markdown": [
"0.0457750907128348"
],
"text/plain": [
"[1] 0.04577509"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"19.0913087436134"
],
"text/latex": [
"19.0913087436134"
],
"text/markdown": [
"19.0913087436134"
],
"text/plain": [
"[1] 19.09131"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"X <- congruent_random(n=1000,a=11,b=1,m=71)\n",
"cor(X[1:length(X)-1],X[2:length(X)])\n",
"cov(X[1:length(X)-1],X[2:length(X)])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il faut donc être suspicieux avec les générateurs de nombres alétaoires et leur faire subir plusieurs tests."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Générateurs à décalage de registres"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1] 4\n"
]
},
{
"data": {
"text/html": [
"<ol class=list-inline>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"</ol>\n"
],
"text/latex": [
"\\begin{enumerate*}\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\end{enumerate*}\n"
],
"text/markdown": [
"1. 1\n",
"2. 0\n",
"3. 1\n",
"4. 0\n",
"5. 0\n",
"6. 0\n",
"7. 1\n",
"8. 0\n",
"9. 1\n",
"10. 0\n",
"11. 0\n",
"12. 0\n",
"13. 1\n",
"14. 0\n",
"15. 1\n",
"16. 0\n",
"17. 0\n",
"18. 0\n",
"19. 1\n",
"20. 0\n",
"21. 1\n",
"22. 0\n",
"23. 0\n",
"24. 0\n",
"25. 1\n",
"26. 0\n",
"27. 1\n",
"28. 0\n",
"29. 0\n",
"30. 0\n",
"31. 1\n",
"32. 0\n",
"33. 1\n",
"34. 0\n",
"35. 0\n",
"36. 0\n",
"37. 1\n",
"38. 0\n",
"39. 1\n",
"40. 0\n",
"41. 0\n",
"42. 0\n",
"43. 1\n",
"44. 0\n",
"45. 1\n",
"46. 0\n",
"47. 0\n",
"48. 0\n",
"49. 1\n",
"50. 0\n",
"51. 1\n",
"52. 0\n",
"53. 0\n",
"54. 0\n",
"55. 1\n",
"56. 0\n",
"57. 1\n",
"58. 0\n",
"59. 0\n",
"60. 0\n",
"61. 1\n",
"62. 0\n",
"63. 1\n",
"64. 0\n",
"65. 0\n",
"66. 0\n",
"67. 1\n",
"68. 0\n",
"69. 1\n",
"70. 0\n",
"71. 0\n",
"72. 0\n",
"73. 1\n",
"74. 0\n",
"75. 1\n",
"76. 0\n",
"77. 0\n",
"78. 0\n",
"79. 1\n",
"80. 0\n",
"81. 1\n",
"82. 0\n",
"83. 0\n",
"84. 0\n",
"85. 1\n",
"86. 0\n",
"87. 1\n",
"88. 0\n",
"89. 0\n",
"90. 0\n",
"91. 1\n",
"92. 0\n",
"93. 1\n",
"94. 0\n",
"95. 0\n",
"96. 0\n",
"97. 1\n",
"98. 0\n",
"99. 1\n",
"100. 0\n",
"\n",
"\n"
],
"text/plain": [
" [1] 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1\n",
" [38] 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0\n",
" [75] 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1] 4\n"
]
},
{
"data": {
"text/html": [
"<ol class=list-inline>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"</ol>\n"
],
"text/latex": [
"\\begin{enumerate*}\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\end{enumerate*}\n"
],
"text/markdown": [
"1. 1\n",
"2. 0\n",
"3. 0\n",
"4. 1\n",
"5. 1\n",
"6. 1\n",
"7. 1\n",
"8. 0\n",
"9. 0\n",
"10. 1\n",
"11. 1\n",
"12. 1\n",
"13. 1\n",
"14. 0\n",
"15. 0\n",
"16. 1\n",
"17. 1\n",
"18. 1\n",
"19. 1\n",
"20. 0\n",
"21. 0\n",
"22. 1\n",
"23. 1\n",
"24. 1\n",
"25. 1\n",
"26. 0\n",
"27. 0\n",
"28. 1\n",
"29. 1\n",
"30. 1\n",
"31. 1\n",
"32. 0\n",
"33. 0\n",
"34. 1\n",
"35. 1\n",
"36. 1\n",
"37. 1\n",
"38. 0\n",
"39. 0\n",
"40. 1\n",
"41. 1\n",
"42. 1\n",
"43. 1\n",
"44. 0\n",
"45. 0\n",
"46. 1\n",
"47. 1\n",
"48. 1\n",
"49. 1\n",
"50. 0\n",
"51. 0\n",
"52. 1\n",
"53. 1\n",
"54. 1\n",
"55. 1\n",
"56. 0\n",
"57. 0\n",
"58. 1\n",
"59. 1\n",
"60. 1\n",
"61. 1\n",
"62. 0\n",
"63. 0\n",
"64. 1\n",
"65. 1\n",
"66. 1\n",
"67. 1\n",
"68. 0\n",
"69. 0\n",
"70. 1\n",
"71. 1\n",
"72. 1\n",
"73. 1\n",
"74. 0\n",
"75. 0\n",
"76. 1\n",
"77. 1\n",
"78. 1\n",
"79. 1\n",
"80. 0\n",
"81. 0\n",
"82. 1\n",
"83. 1\n",
"84. 1\n",
"85. 1\n",
"86. 0\n",
"87. 0\n",
"88. 1\n",
"89. 1\n",
"90. 1\n",
"91. 1\n",
"92. 0\n",
"93. 0\n",
"94. 1\n",
"95. 1\n",
"96. 1\n",
"97. 1\n",
"98. 0\n",
"99. 0\n",
"100. 1\n",
"\n",
"\n"
],
"text/plain": [
" [1] 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1\n",
" [38] 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0\n",
" [75] 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"X=xor_random <- function(n = 100, filter=c(1,0,1,0), seed=c(1,0,1,0)) {\n",
" res = seed\n",
" m = length(filter)\n",
" print(m)\n",
" for(i in (length(seed)):(n-1)) { # Yes, you need to put parenthesis around n-1 :(\n",
" res[i+1] = sum(filter*(res[(i-m+1):i]))%%2 # Yes, you need to put parenthesis around i-m+1 :(\n",
" }\n",
" res\n",
"}\n",
"xor_random()\n",
"xor_random(seed=c(1,0,0,1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ouh là, tout ceci n'a rien d'aléatoire. Il y a deux séquences entrelacées et la longueur du cycle est 8. Essayons avec d'autres paramètres."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1] 4\n"
]
},
{
"data": {
"text/html": [
"<ol class=list-inline>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>1</li>\n",
"\t<li>0</li>\n",
"</ol>\n"
],
"text/latex": [
"\\begin{enumerate*}\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 0\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 1\n",
"\\item 0\n",
"\\end{enumerate*}\n"
],
"text/markdown": [
"1. 1\n",
"2. 1\n",
"3. 0\n",
"4. 1\n",
"5. 0\n",
"6. 1\n",
"7. 1\n",
"8. 1\n",
"9. 1\n",
"10. 0\n",
"11. 0\n",
"12. 0\n",
"13. 1\n",
"14. 0\n",
"15. 0\n",
"16. 1\n",
"17. 1\n",
"18. 0\n",
"19. 1\n",
"20. 0\n",
"21. 1\n",
"22. 1\n",
"23. 1\n",
"24. 1\n",
"25. 0\n",
"26. 0\n",
"27. 0\n",
"28. 1\n",
"29. 0\n",
"30. 0\n",
"31. 1\n",
"32. 1\n",
"33. 0\n",
"34. 1\n",
"35. 0\n",
"36. 1\n",
"37. 1\n",
"38. 1\n",
"39. 1\n",
"40. 0\n",
"41. 0\n",
"42. 0\n",
"43. 1\n",
"44. 0\n",
"45. 0\n",
"46. 1\n",
"47. 1\n",
"48. 0\n",
"49. 1\n",
"50. 0\n",
"51. 1\n",
"52. 1\n",
"53. 1\n",
"54. 1\n",
"55. 0\n",
"56. 0\n",
"57. 0\n",
"58. 1\n",
"59. 0\n",
"60. 0\n",
"61. 1\n",
"62. 1\n",
"63. 0\n",
"64. 1\n",
"65. 0\n",
"66. 1\n",
"67. 1\n",
"68. 1\n",
"69. 1\n",
"70. 0\n",
"71. 0\n",
"72. 0\n",
"73. 1\n",
"74. 0\n",
"75. 0\n",
"76. 1\n",
"77. 1\n",
"78. 0\n",
"79. 1\n",
"80. 0\n",
"81. 1\n",
"82. 1\n",
"83. 1\n",
"84. 1\n",
"85. 0\n",
"86. 0\n",
"87. 0\n",
"88. 1\n",
"89. 0\n",
"90. 0\n",
"91. 1\n",
"92. 1\n",
"93. 0\n",
"94. 1\n",
"95. 0\n",
"96. 1\n",
"97. 1\n",
"98. 1\n",
"99. 1\n",
"100. 0\n",
"\n",
"\n"
],
"text/plain": [
" [1] 1 1 0 1 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 0 1 1\n",
" [38] 1 1 0 0 0 1 0 0 1 1 0 1 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 0 1 1 1 1 0 0 0 1 0\n",
" [75] 0 1 1 0 1 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 0 1 1 1 1 0"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"xor_random(filter=c(1,1,0,0),seed=c(1,1,0,1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cela semble mieux, la longueur du cycle est de 16. Est-ce satisfaisant pour autant ? À vous de voir... À vous de concevoir de nouveaux algorithmes de génération et d'imaginer des tests d'aléa.."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Well, maybe those numbers are just intrinsically better!](http://imgs.xkcd.com/comics/ayn_random.png)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "R",
"language": "R",
"name": "ir"
},
"language_info": {
"codemirror_mode": "r",
"file_extension": ".r",
"mimetype": "text/x-r-source",
"name": "R",
"pygments_lexer": "r",
"version": "3.4.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
ressources-md: ressources.md ressources_fr.md
include ../../Makefile.ressources
C028AL_slides_module2-en-gz.pdf: slides_module2.pdf
mv $< $@
......
# -*- mode: org -*-
#+TITLE: A few Recent Controversial Studies
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
** Economy: Austerity in Fiscal Policy
- [[https://en.wikipedia.org/wiki/Growth_in_a_Time_of_Debt][Reinhart et Rogoff]]: /Growth in a Time of Debt/
- Herndon, Ash et Pollin
- Wray: combining data across centuries, exchange rate regimes,
** Functional MRI
- 2010: [[https://www.researchgate.net/publication/255651552_Neural_correlates_of_interspecies_perspective_taking_in_the_post-mortem_Atlantic_Salmon_an_argument_for_multiple_comparisons_correction][Bennett et al. and the dead salmon]] \smiley
- 2016: [[http://www.pnas.org/content/113/28/7900.abstract][Eklund, Nichols, and Knutsson]]. [[http://www.sciencealert.com/a-bug-in-fmri-software-could-invalidate-decades-of-brain-research-scientists-discover][A bug in fmri software could
invalidate 15 years of brain research]] (/40 000 articles/)
- 2016: But it's [[https://www.cogneurosociety.org/debunking-the-myth-that-fmri-studies-are-invalid/][more subtle than it looks like]]. [[http://blogs.warwick.ac.uk/nichols/entry/bibliometrics_of_cluster/][Nichols]]. /\approx
3 600 impacted studies/
** Incorrect Protein Structures
[[https://people.ligo-wa.caltech.edu/~michael.landry/calibration/S5/getsignright.pdf][A "buggy software"]].
** Other domains
- [[http://www.nature.com/nrd/journal/v10/n9/full/nrd3439-c1.html?foxtrotcallback=true][Oncology]]: "/half of published studies, even in prestigious journals,
can't be reproduced in industrial labs/"
- [[http://theconversation.com/we-found-only-one-third-of-published-psychology-research-is-reliable-now-what-46596][Psychology]]: "/attempting to reproduce 100 previously published
findings/, /only one-third of published psychology research was found
to be reliable/"
# -*- mode: org -*-
#+TITLE: Exemples récents d'études assez discutées
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
** Économie: Politiques d'austérité
- [[https://en.wikipedia.org/wiki/Growth_in_a_Time_of_Debt][Reinhart et Rogoff]]: /Growth in a Time of Debt/
- Herndon, Ash et Pollin
- Wray: combining data across centuries, exchange rate regimes,
** Les IRM fonctionnelles
- 2010: [[https://www.researchgate.net/publication/255651552_Neural_correlates_of_interspecies_perspective_taking_in_the_post-mortem_Atlantic_Salmon_an_argument_for_multiple_comparisons_correction][Bennett et al.: le saumon mort]] \smiley
- 2016: [[http://www.pnas.org/content/113/28/7900.abstract][Eklund, Nichols, and Knutsson]]. [[http://www.sciencealert.com/a-bug-in-fmri-software-could-invalidate-decades-of-brain-research-scientists-discover][Un bug dans les logiciels d'IRM
pourrait invalider 15 années de recherche sur le cerveau]] (/40 000 articles/)
- 2016: C'est [[https://www.cogneurosociety.org/debunking-the-myth-that-fmri-studies-are-invalid/][plus subtil que ça]]. [[http://blogs.warwick.ac.uk/nichols/entry/bibliometrics_of_cluster/][D'après Nichols, un des auteurs de
l'article d'origine]], c'est plutôt de l'ordre de /3 600 études qui
seraient potentiellement impactées/.
** Les fausses structures de protéines
[[https://people.ligo-wa.caltech.edu/~michael.landry/calibration/S5/getsignright.pdf][A "buggy software"]].
** Autres domaines
- [[http://www.nature.com/nrd/journal/v10/n9/full/nrd3439-c1.html?foxtrotcallback=true][Oncologie]]: "/half of published studies, even in prestigious journals,
can't be reproduced in industrial labs/"
- [[http://theconversation.com/we-found-only-one-third-of-published-psychology-research-is-reliable-now-what-46596][Psychologie]]: "/attempting to reproduce 100 previously published
findings/, /only one-third of published psychology research was found
to be reliable/"
# -*- mode: org -*-
#+TITLE: Why is This so Difficult?
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Mistakes
- [[http://theconversation.com/how-computers-broke-science-and-what-we-can-do-to-fix-it-49938][Computers broke science]]
- [[https://qz.com/768334/years-of-genomics-research-is-riddled-with-errors-thanks-to-a-bunch-of-botched-excel-spreadsheets/][Programming and data manipulation mistakes in Genomics]]
* Going Public?
- Someone may [[http://www.nature.com/news/the-top-100-papers-1.16224][benefit from my hard work]]. The most cited papers are
those describing a new technique or some software that has allowed a
community of researchers to evolve and go farther.
# -*- mode: org -*-
#+TITLE: Pourquoi est-ce difficile?
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Les erreurs classiques
- [[http://theconversation.com/how-computers-broke-science-and-what-we-can-do-to-fix-it-49938][Enquoi les ordinateurs ont "cassé" la science]]
- [[https://qz.com/768334/years-of-genomics-research-is-riddled-with-errors-thanks-to-a-bunch-of-botched-excel-spreadsheets/][Erreurs de programmation et de manipulation de données en génomique]]
* Tout rendre publique ?
- Quelqu'un pourrait [[http://www.nature.com/news/the-top-100-papers-1.16224][tirer parti de mon dur labeur]]. Les papiers les
plus cités sont des papiers qui décrivent une nouvelle technique ou
un logiciel permettant à une communauté de recherche d'avancer.
# -*- mode: org -*-
#+TITLE: Collaborating
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Preparing a Document for a Journal or a Conference
Requirements for producing a *pdf*:
- Internally, /pandoc/, /knitr/ or /emacs/org-mode/
- /LaTeX/ should be installed
- http://blog.juliusschulz.de/blog/ultimate-ipython-notebook
- https://github.com/kirbs-/hide_code is a must-have
- http://svmiller.com/blog/2016/02/svm-r-markdown-manuscript/
- https://github.com/balouf/Kleinberg/blob/master/KleinbergsGridSimulator.ipynb
# -*- mode: org -*-
#+TITLE: Travailler avec les autres
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Préparation d'un document pour un journal ou pour une conférence
De quoi aurez-vous besoin pour produire un document *pdf*:
- En interne: /pandoc/, /knitr/ ou /emacs/org-mode/.
- /LaTeX/ devra aussi être installé
Voici quelques billets intéressants sur le sujet:
- http://blog.juliusschulz.de/blog/ultimate-ipython-notebook
- https://github.com/kirbs-/hide_code is a must-have
- http://svmiller.com/blog/2016/02/svm-r-markdown-manuscript/
- https://github.com/balouf/Kleinberg/blob/master/KleinbergsGridSimulator.ipynb
# -*- mode: org -*-
#+TITLE: External resources to discover git
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
For Git beginners, here are some links that will allow you to familiarize yourself with this very powerful tool:
- To learn how to use Git with command line, here is the [[http://swcarpentry.github.io/git-novice/][course offered by Software Carpentry]] (in the form of TP with very progressive explanations)
As part of this Mooc, we have deployed an instance of GitLab but there are many other similar platforms (gitlab.com, github.com, bitbucket.com, framagit.org...). The next two videos illustrate the creation of a project on one of these platforms.
# -*- mode: org -*-
#+TITLE: Ressources externes pour découvrir git
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
Pour les débutants Git, voici quelques liens qui vous permettront de vous familiariser avec cet outil très puissant :
- Pour apprendre à utiliser Git en ligne de commande , voici [[http://swcarpentry.github.io/git-novice/][le cours proposé par Software Carpentry]], sous forme de TP avec des explications très progressives (cours en anglais).
- Le livre [[https://git-scm.com/book/fr/v2][Pro Git]] est disponible, gratuitement, légalement. La lecture des deux premiers chapitres vous suffira pour démarrer (livre en français)
- [[https://learngitbranching.js.org/][Learn Git Branching]] vous permettra d'apprendre Git de façon interactive et de bien comprendre les notions de branches (cours en français)
# Sujet 1 : Concentration de CO2 dans l'atmosphère depuis 1958
__Prérequis__ : traitement de suites chronologiques
En 1958, Charles David Keeling a initié une mesure de la concentration de CO2 dans l'atmosphère à l'observatoire de Mauna Loa, Hawaii, États-Unis qui continue jusqu'à aujourd'hui. L'objectif initial était d'étudier la variation saisonnière, mais l'intérêt s'est déplacé plus tard vers l'étude de la tendance croissante dans le contexte du changement climatique. En honneur à Keeling, ce jeu de données est souvent appelé "Keeling Curve" (voir https://en.wikipedia.org/wiki/Keeling_Curve pour l'histoire et l'importance de ces données).
Les données sont disponibles sur [le site Web de l'institut Scripps](https://scrippsco2.ucsd.edu/data/atmospheric_co2/primary_mlo_co2_record.html). Utilisez le fichier avec les observations hebdomadaires. Attention, ce fichier est mis à jour régulièrement avec de nouvelles observations. Notez donc bien la date du téléchargement, et gardez une copie locale de la version précise que vous analysez. Faites aussi attention aux données manquantes.
__Votre mission si vous l'acceptez__ :
1. Réalisez un graphique qui vous montrera une oscillation périodique superposée à une évolution systématique plus lente.
2. Séparez ces deux phénomènes. Caractérisez l'oscillation périodique. Proposez un modèle simple de la contribution lente, estimez ses paramètres et tentez une extrapolation jusqu'à 2025 (dans le but de pouvoir valider le modèle par des observations futures).
3. Déposer dans FUN votre résultat
# Sujet 2 : le pouvoir d'achat des ouvriers anglais du XVIe au XIXe siècle
__Prérequis__ : techniques de présentation graphique
[William Playfair](https://fr.wikipedia.org/wiki/William_Playfair) était un des pionniers de la présentation graphique des données. Il est notamment considéré comme l'inventeur de l'histogramme. Un de ses graphes célèbres, tiré de son livre "[A Letter on Our Agricultural Distresses, Their Causes and Remedies](https://books.google.fr/books/about/A_Letter_on_Our_Agricultural_Distresses.html?id=aQZGAQAAMAAJ)", montre l'[évolution du prix du blé et du salaire moyen entre 1565 et 1821](https://fr.wikipedia.org/wiki/William_Playfair#/media/File:Chart_Showing_at_One_View_the_Price_of_the_Quarter_of_Wheat,_and_Wages_of_Labour_by_the_Week,_from_1565_to_1821.png). Playfair n'a pas publié les données numériques brutes qu'il a utilisées, car à son époque la réplicabilité n'était pas encore considérée comme essentielle. Des [valeurs obtenues par numérisation du graphe](https://vincentarelbundock.github.io/Rdatasets/doc/HistData/Wheat.html) sont aujourd'hui téléchargeables, [la version en format CSV](https://raw.githubusercontent.com/vincentarelbundock/Rdatasets/master/csv/HistData/Wheat.csv) étant la plus pratique.
Quelques remarques pour la compréhension des données :
- Jusqu'en 1971, la livre sterling était divisée en 20 shillings, et un shilling en 12 pences.
- Le prix du blé est donné en shillings pour un quart de boisseau de blé. Un quart de boisseau équivaut 15 livres britanniques ou 6,8 kg.
- Les salaires sont donnés en shillings par semaine.
__Votre mission si vous l'acceptez__ :
1. Votre première tâche est de reproduire le graphe de Playfair à partir des données numériques. Représentez, comme Playfair, le prix du blé par des barres et les salaires par une surface bleue délimitée par une courbe rouge. Superposez les deux de la même façon dans un seul graphique. Le style de votre graphique pourra rester différent par rapport à l'original, mais l'impression globale devrait être la même.
2. Par la suite, améliorez la présentation de ces données. Pour commencer, Playfair a combiné les deux quantités dans un même graphique en simplifiant les unités "shillings par quart de boisseau de blé" et "shillings par semaine" à un simple "shillings", ce qui aujourd'hui n'est plus admissible. Utilisez deux ordonnées différentes, une à gauche et une à droite, et indiquez les unités correctes. À cette occasion, n'hésitez pas à proposer d'autres représentations que des barres et des surface/courbes pour les deux jeux de données si ceci vous paraît judicieux.
3. L'objectif de Playfair était de montrer que le pouvoir d'achat des ouvriers avait augmenté au cours du temps. Essayez de mieux faire ressortir cette information. Pour cela, faites une représentation graphique du pouvoir d'achat au cours du temps, définie comme la quantité de blé qu'un ouvrier peut acheter avec son salaire hebdomadaire. Dans un autre graphique, montrez les deux quantités (prix du blé, salaire) sur deux axes différents, sans l'axe du temps. Trouvez une autre façon d'indiquer la progression du temps dans ce graphique. Quelle représentation des données vous paraît la plus claire ? N'hésitez pas à en proposer d'autres.
4. Déposer dans FUN votre résultat
# Sujet 3 : L'épidémie de choléra à Londres en 1854
__Prérequis__ : représentation de données géographiques
En 1854, le quartier de Soho à Londres a vécu [une des pires épidémies de choléra du Royaume-Uni](https://fr.wikipedia.org/wiki/%C3%89pid%C3%A9mie_de_chol%C3%A9ra_de_Broad_Street), avec 616 morts. Cette épidémie est devenue célèbre à cause de l'analyse détaillée de ses causes réalisée par le médecin [John Snow](http://www.johnsnowsociety.org/). Ce dernier a notamment montré que le choléra est transmis par l'eau plutôt que par l'air, ce qui était la théorie dominante de l'époque.
Un élément clé de cette analyse était une [carte](https://commons.wikimedia.org/wiki/File:Snow-cholera-map-1.jpg) sur laquelle John Snow avait marqué les lieux des décès et les endroits où se trouvaient les pompes à eau publiques. Ces données sont aujourd'hui [disponibles sous forme numérique](http://blog.rtwilson.com/john-snows-cholera-data-in-more-formats). Nous vous proposons de les utiliser pour recréer la carte de John Snow dans un document computationnel réplicable.
Votre mission si vous l'acceptez :
1. Londres a bien sûr évolué depuis 1854, mais une carte d'aujourd'hui est tout à fait utilisable comme support pour ces données historiques. À partir des données numériques, réalisez une carte dans l'esprit de celle de John Snow. Montrez les lieux de décès avec des symboles dont la taille indique le nombre de décès. Indiquez sur la même carte la localisation des pompes en utilisant une autre couleur et/ou un autre symbole.
2. Par la suite, essayez de trouver d'autres façons pour montrer que la pompe de Broad Street est au centre de l'épidémie. Vous pouvez par exemple calculer la densité des décès dans le quartier et l'afficher sur la carte, mais n'hésitez pas à expérimenter avec d'autres approches.
3. Déposer dans FUN votre résultat
**Conseils techniques pour l'affichage de cartes**
En R, nous vous suggérons l'utilisation de la bibliothèque [ggmap](https://journal.r-project.org/archive/2013-1/kahle-wickham.pdf). Evitez Google Maps comme source de cartes car ce service est devenu payant en 2018 (et même si vous restez dans le quota gratuit, vous devez déposer vos coordonnées bancaires pour vous inscrire). OpenStreetMaps est une bonne alternative que ggmap propose également (source="osm").
En Python dans l'environnement Jupyter, la bibliothèque [folium](https://python-visualization.github.io/folium/) produit des belles cartes qui en plus sont interactives. Le seul inconvénient est que les cartes stockées dans les notebooks ne sont pas affichées dans GitLab. Pour que vos évaluateurs puissent les voir plus facilement, pensez à exporter votre notebook au format HTML et déposer cette version aussi dans votre dépôt.
# Sujet 4 : Estimation de la latence et de la capacité d’une connexion à partir de mesures asymétriques
__Prérequis__ : régression linéaire
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.
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
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:
[1421761682.052172] 665 bytes from lig-publig.imag.fr (129.88.11.7): icmp_seq=1 ttl=60 time=22.5 ms
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
# Sujet 5 : Analyse des dialogues dans l'Avare de Molière
__Prérequis__ : analyse de texte, éventuellement techniques de présentation graphique
L’Observatoire de la vie littéraire ([OBVIL](http://obvil.sorbonne-universite.site/obvil/presentation)) promeut une approche de l'analyse des textes littéraires fondée sur le numérique.
Dans le cadre du [Projet Molière](http://obvil.sorbonne-universite.site/projets/projet-moliere), des pièces de cet auteur ont été numérisées et sont accessibles librement dans différents formats utilisables par un programme informatique.
Pour l'Avare de Molière, voici les formats disponibles : [TEI](http://dramacode.github.io/moliere/moliere_avare.xml), [epub](http://dramacode.github.io/epub/moliere_avare.epub), [kindle](kindle/moliere_avare.mobi), [markdown](http://dramacode.github.io/markdown/moliere_avare.txt), [Texte iramuteq](http://dramacode.github.io/iramuteq/moliere_avare.txt ), [Texte dit/Paroles](http://dramacode.github.io/naked/moliere_avare.txt), [TXM](http://dramacode.github.io/txm/moliere_avare.xml), [html complet avec table des matières](http://dramacode.github.io/html/moliere_avare.html), [fragment html](http://dramacode.github.io/article/moliere_avare.html).
Grâce à ces numérisations, il est possible d'écrire des programmes pour réaliser des analyses syntaxiques et sémantiques. Nous vous proposons dans ce sujet de reproduire une étude réalisée par l'OBVIL sur l'étude des dialogues de l'Avare de Molière.
Nous vous conseillons de réaliser cet exercice en Python plutôt que en R, surtout pour la partie qui traite le texte.
__Votre mission si vous l'acceptez__ :
1. Classez les personnages selon la quantité de parole grâce à une analyse syntaxique du texte (scènes / répliques / mots). En particulier, quel est celui qui parle le plus ? Quel est celui qui ne parle pas du tout ? Attention, les noms des personnages ne sont pas forcément homogènes (casse et accents par exemple).
2. Réalisez un graphique qui montrera le nombre de mots que chaque acteur prononce dans chaque scène. Pour cela, vous pouvez vous inspirer de l'[étude de l'Avare de Molière réalisée par l'OBVIL](https://obvil.sorbonne-universite.fr/corpus/moliere/moliere_avare) (graphe de gauche). Dans ce graphique, les lignes sont de longueurs égales et la hauteur représente le nombre de mots prononcés au total dans la scène. La largeur de chaque rectangle indique le pourcentage de la scène qu’un acteur occupe.
3. Facultatif : Construisez un graphe d’interlocution permettant de visualiser les échanges entre les personnages. Pour cela, vous pouvez vous inspirer de l'[étude de l'Avare de Molière réalisée par l'OBVIL](https://obvil.sorbonne-universite.fr/corpus/moliere/moliere_avare) (graphe de droite).
4. Déposer dans FUN votre résultat
resources-md: iso_date_format.md iso_date_format_fr.md
include ../../Makefile.ressources
......@@ -10,7 +10,7 @@
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
#+PROPERTY: header-args :session :exports both
#+PROPERTY: header-args :session
* Préface
......@@ -22,7 +22,7 @@ Une version plus ancienne d'Emacs devrait suffire, mais en ce cas il est prudent
Bibliothèque supplémentaire:
- [[https://github.com/magnars/dash.el][Dash]] 2.13.0
#+BEGIN_SRC emacs-lisp :results output
#+BEGIN_SRC emacs-lisp :results output :exports both
(require 'dash)
(unless (featurep 'dash)
(print "Veuillez installer Dash !"))
......@@ -33,13 +33,13 @@ Bibliothèque supplémentaire:
** Python 3.6
Nous utilisons le traitement de dates en format ISO 8601, qui a été implémenté en Python seulement avec la version 3.6.
#+BEGIN_SRC python :results output
#+BEGIN_SRC python :results output :exports both
import sys
if sys.version_info.major < 3 or sys.version_info.minor < 6:
print("Veuillez utiliser Python 3.6 (ou plus) !")
#+END_SRC
#+BEGIN_SRC emacs-lisp :results output
#+BEGIN_SRC emacs-lisp :results output :exports both
(unless (featurep 'ob-python)
(print "Veuillez activer python dans org-babel (org-babel-do-languages) !"))
#+END_SRC
......@@ -47,7 +47,7 @@ if sys.version_info.major < 3 or sys.version_info.minor < 6:
** R 3.4
Nous n'utilisons que des fonctionnalités de base du langage R, une version antérieure devrait suffire.
#+BEGIN_SRC emacs-lisp :results output
#+BEGIN_SRC emacs-lisp :results output :exports both
(unless (featurep 'ob-R)
(print "Veuillez activer R dans org-babel (org-babel-do-languages) !"))
#+END_SRC
......@@ -80,7 +80,7 @@ Pour éviter de télécharger les données plusieurs fois, nous les gardons dans
#+NAME: data-buffer-name
*données syndrome grippal*
#+BEGIN_SRC emacs-lisp :results silent :var url=data-url :var name=data-buffer-name
#+BEGIN_SRC emacs-lisp :results silent :var url=data-url :var name=data-buffer-name :exports both
(require 'url)
(with-current-buffer (get-buffer-create name)
(unless buffer-read-only
......@@ -90,7 +90,7 @@ Pour éviter de télécharger les données plusieurs fois, nous les gardons dans
#+END_SRC
La prochaine étape est l'extraction des données qui nous intéressent. D'abord nous découpons le contenu du fichier en lignes, dont nous jetons la première qui ne contient qu'un commentaire. Les autres lignes sont découpées en colonnes. Pour détecter les données manquantes, nous vérifions si une ligne contient au moins un champ vide. A la fin de ce bloc, deux variables contiennent les données manquantes et les donées valables.
#+BEGIN_SRC emacs-lisp :results silent :var name=data-buffer-name
#+BEGIN_SRC emacs-lisp :results silent :var name=data-buffer-name :exports both
(require 'cl)
(require 'dash)
(defun missing-data? (row)
......@@ -105,19 +105,19 @@ La prochaine étape est l'extraction des données qui nous intéressent. D'abord
#+END_SRC
Regardons les données manquantes...
#+BEGIN_SRC emacs-lisp
#+BEGIN_SRC emacs-lisp :exports both
missing-data-lines
#+END_SRC
Nous ne gardons que la première (~"week"~) et la troisième (~"inc"~) colonne des données valables. Nous insérons ~hline~ comme deuxième élément de notre tableau pour indiquer à org-mode la séparation entre l'en-tête (les noms des colonnes) et les données.
#+NAME: data
#+BEGIN_SRC emacs-lisp :results silent
#+BEGIN_SRC emacs-lisp :results silent :exports both
(-insert-at 1 'hline
(-select-columns '(0 2) valid-data-lines))
#+END_SRC
Regardons les premières et les dernières lignes:
#+BEGIN_SRC emacs-lisp :results value :var data=data :colnames yes
#+BEGIN_SRC emacs-lisp :results value :var data=data :colnames yes :exports both
(-concat (-take 5 data)
'(hline)
(-take-last 5 data))
......@@ -126,7 +126,7 @@ Regardons les premières et les dernières lignes:
** 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), dont les deux premiers sont ou "19" ou "20", et que les incidences sont des nombres entiers positifs.
#+BEGIN_SRC emacs-lisp :results output :var data=data :colnames yes
#+BEGIN_SRC emacs-lisp :results output :var data=data :colnames yes :exports both
(defun check-week (week)
(unless (string-match-p (rx (or "19" "20") (repeat 4 digit)) week)
(princ (format "Invalid week value: %s\n" week))))
......@@ -146,7 +146,7 @@ Rien à signaler !
** Conversions
Pour faciliter les traitements suivants, nous remplaçons les numéros de semaine ISO par les dates qui correspondent aux lundis. A cette occasion, nous trions aussi les données par la date, et nous transformons les incidences en nombres entiers. Nous utilisons le langage Python 3 parce qu'il est un des rares à proposer la conversion de semaines ISO en dates dans sa biblithèque standard.
#+BEGIN_SRC python :results silent :var input_data=data
#+BEGIN_SRC python :results silent :var input_data=data :exports both
import datetime
data = [(datetime.datetime.strptime(year_and_week + ":1" , '%G%V:%u').date(),
int(inc))
......@@ -155,14 +155,14 @@ data.sort(key = lambda record: record[0])
#+END_SRC
Regardons de nouveau les premières et les dernières lignes:
#+BEGIN_SRC python :results value
#+BEGIN_SRC python :results value :exports both
str_data = [(str(date), str(inc)) for date, inc in data]
[('date', 'inc'), None] + str_data[:5] + [None] + str_data[-5:]
#+END_SRC
** 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
#+BEGIN_SRC python :results output :exports both
dates = [date for date, _ in data]
for date1, date2 in zip(dates[:-1], dates[1:]):
if date2-date1 != datetime.timedelta(weeks=1):
......@@ -174,24 +174,24 @@ Nous passons au langage R pour inspecter nos données, parce que l'analyse et la
Nous utilisons le mécanisme d'échange de données proposé par org-mode, ce qui nécessite un peu de code Python pour transformer les données dans le bon format.
#+NAME: data-for-R
#+BEGIN_SRC python :results silent
#+BEGIN_SRC python :results silent :exports both
[('date', 'inc'), None] + [(str(date), inc) for date, inc in data]
#+END_SRC
En R, les données arrivent sous forme d'un data frame, mais il faut encore convertir les dates, qui arrivent comme chaînes de caractères.
#+BEGIN_SRC R :results output :var data=data-for-R
#+BEGIN_SRC R :results output :var data=data-for-R :exports both
data$date <- as.Date(data$date)
summary(data)
#+END_SRC
** Inspection
Regardons enfin à quoi ressemblent nos données !
#+BEGIN_SRC R :results output graphics :file inc-plot.png
#+BEGIN_SRC R :results output graphics :file inc-plot.png :exports both
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
#+BEGIN_SRC R :results output graphics :file inc-plot-zoom.png :exports both
plot(tail(data, 200), type="l", xlab="Date", ylab="Incidence hebdomadaire")
#+END_SRC
......@@ -201,7 +201,7 @@ plot(tail(data, 200), type="l", xlab="Date", ylab="Incidence hebdomadaire")
Étant donné que le pic de l'épidémie se situe en hiver, à cheval entre deux années civiles, nous définissons la période de référence entre deux minima de l'incidence, du 1er août de l'année /N/ au 1er août de l'année /N+1/. Nous mettons l'année /N+1/ comme étiquette sur cette année décalée, car le pic de l'épidémie est toujours au début de l'année /N+1/. Comme l'incidence du syndrome grippal est très faible en été, cette modification ne risque pas de fausser nos conclusions.
Voici une fonction qui calcule l'incidence annuelle en appliquant ces conventions.
#+BEGIN_SRC R :results silent
#+BEGIN_SRC R :results silent :exports both
pic_annuel = function(annee) {
debut = paste0(annee-1,"-08-01")
fin = paste0(annee,"-08-01")
......@@ -211,11 +211,11 @@ pic_annuel = function(annee) {
#+END_SRC
Nous devons aussi faire attention aux premières et dernières années de notre jeux de données. Les données commencent en octobre 1984, ce qui ne permet pas de quantifier complètement le pic attribué à l'année 1985. Nous le supprimons donc de notre analyse. Par contre, les données se terminent après le 1er août 2018 (pour une exécution après cette date bien sûr), ce qui nous permet d'inclure cette année dans l'analyse.
#+BEGIN_SRC R :results silent
#+BEGIN_SRC R :results silent :exports both
annees <- 1986:2018
#+END_SRC
#+BEGIN_SRC R :results value
#+BEGIN_SRC R :results value :exports both
inc_annuelle = data.frame(annee = annees,
incidence = sapply(annees, pic_annuel))
head(inc_annuelle)
......@@ -223,17 +223,17 @@ head(inc_annuelle)
** Inspection
Voici les incidences annuelles en graphique.
#+BEGIN_SRC R :results output graphics :file annual-inc-plot.png
#+BEGIN_SRC R :results output graphics :file annual-inc-plot.png :exports both
plot(inc_annuelle, type="p", xlab="Année", ylab="Incidence annuelle")
#+END_SRC
** Identification des épidémies les plus fortes
Une liste triée par ordre décroissant d'incidence annuelle permet de plus facilement repérer les valeurs les plus élevées:
#+BEGIN_SRC R :results output
#+BEGIN_SRC R :results output :exports both
head(inc_annuelle[order(-inc_annuelle$incidence),])
#+END_SRC
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
#+BEGIN_SRC R :results output graphics :file annual-inc-hist.png :exports both
hist(inc_annuelle$incidence, breaks=10, xlab="Incidence annuelle", ylab="Nb d'observations", main="")
#+END_SRC
......@@ -10,7 +10,7 @@
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
#+PROPERTY: header-args :session :exports both
#+PROPERTY: header-args :session
* Préface
......@@ -21,18 +21,18 @@ Une version plus ancienne d'Emacs devrait suffire, mais en ce cas il est prudent
** R 3.4
Nous n'utilisons que des fonctionnalités de base du langage R, une version antérieure devrait suffire.
#+BEGIN_SRC emacs-lisp :results output
#+BEGIN_SRC emacs-lisp :results output :exports both
(unless (featurep 'ob-R)
(print "Veuillez activer R dans org-babel (org-babel-do-languages) !"))
#+END_SRC
Pour la manipulation des dates au format ISO-8601, nous avons besoin du paquet ~parsedate~.
#+BEGIN_SRC R :results output
#+BEGIN_SRC R :results output :exports both
library(parsedate)
#+END_SRC
Enfin, nous allons demander à R d'écrire les nombres décimaux en français — c'est-à-dire avec une virgule entre parties entière et décimale — et d'utiliser un nombre de colonnes plus large que celui utilisé par défaut.
#+BEGIN_SRC R :results silent
#+BEGIN_SRC R :results silent :exports both
options(OutDec=",")
options(width=150)
#+END_SRC
......@@ -59,28 +59,27 @@ Voici l'explication des colonnes donnée sur [[https://ns.sentiweb.fr/incidence/
| ~geo_name~ | Libellé de la zone géographique (ce libellé peut être modifié sans préavis) |
** Téléchargement
La première ligne du fichier CSV est un commentaire, que nous ignorons en précisant `skip=1`.
La première ligne du fichier CSV est un commentaire, que nous ignorons en précisant ~skip=1~.
#+BEGIN_SRC R :session :results silent :var url=data-url
#+BEGIN_SRC R :session :results silent :var url=data-url :exports both
data = read.csv(trimws(url), skip=1)
#+END_SRC
Après avoir téléchargé les données, nous commençons par l'extraction des données qui nous intéressent. D'abord nous découpons le contenu du fichier en lignes, dont nous jetons la première qui ne contient qu'un commentaire. Les autres lignes sont découpées en colonnes.
#+BEGIN_SRC R :results output
Regardons ce que nous avons obtenu !
#+BEGIN_SRC R :results output :exports both
head(data)
tail(data)
#+END_SRC
** Vérification
Il est toujours prudent de vérifier si les données semblent crédibles. Commençons par regarder s'il y a des points manquants dans ce jeu de données:
#+BEGIN_SRC R :results value
#+BEGIN_SRC R :results value :exports both
na_records = apply(data, 1, function(x) any(is.na(x)))
data[na_records,]
#+END_SRC
Voyons aussi comment R a interpreté nos données:
#+BEGIN_SRC R :results output
#+BEGIN_SRC R :results output :exports both
class(data$week)
class(data$inc)
#+END_SRC
......@@ -89,7 +88,7 @@ Ce sont des entiers, tout va bien !
** Conversions
Pour faciliter les traitements suivants, nous remplaçons les numéros de semaine ISO par les dates qui correspondent aux lundis. D'abord, une petite fonction qui fait le travail:
#+BEGIN_SRC R :results silent
#+BEGIN_SRC R :results silent :exports both
convert_week = function(w) {
ws = paste(w)
iso = paste0(substring(ws,1,4), "-W", substring(ws,5,6))
......@@ -98,34 +97,34 @@ convert_week = function(w) {
#+END_SRC
Nous appliquons cette fonction à tous les points, créant une nouvelle colonne `date` dans notre jeu de données:
#+BEGIN_SRC R :results output
#+BEGIN_SRC R :results output :exports both
data$date = as.Date(convert_week(data$week))
#+END_SRC
Vérifions qu'elle est de classe `Date`:
#+BEGIN_SRC R :results output
#+BEGIN_SRC R :results output :exports both
class(data$date)
#+END_SRC
Les points sont dans l'ordre chronologique inverse, il est donc utile de les trier:
#+BEGIN_SRC R :results output
#+BEGIN_SRC R :results output :exports both
data = data[order(data$date),]
#+END_SRC
** Vérification des dates
Nous faisons encore une vérification: nos dates doivent être séparées d'exactement une semaine.
#+BEGIN_SRC R :results value
#+BEGIN_SRC R :results value :exports both
all(diff(data$date) == 7)
#+END_SRC
** Inspection
Regardons enfin à quoi ressemblent nos données !
#+BEGIN_SRC R :results output graphics :file inc-plot.png
#+BEGIN_SRC R :results output graphics :file inc-plot.png :exports both
plot(data$date, data$inc, 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
#+BEGIN_SRC R :results output graphics :file inc-plot-zoom.png :exports both
with(tail(data, 200), plot(date, inc, type="l", xlab="Date", ylab="Incidence hebdomadaire"))
#+END_SRC
......@@ -135,7 +134,7 @@ with(tail(data, 200), plot(date, inc, type="l", xlab="Date", ylab="Incidence heb
Étant donné que le pic de l'épidémie se situe en hiver, à cheval entre deux années civiles, nous définissons la période de référence entre deux minima de l'incidence, du 1er août de l'année /N/ au 1er août de l'année /N+1/. Nous mettons l'année /N+1/ comme étiquette sur cette année décalée, car le pic de l'épidémie est toujours au début de l'année /N+1/. Comme l'incidence du syndrome grippal est très faible en été, cette modification ne risque pas de fausser nos conclusions.
Voici une fonction qui calcule l'incidence annuelle en appliquant ces conventions.
#+BEGIN_SRC R :results silent
#+BEGIN_SRC R :results silent :exports both
pic_annuel = function(annee) {
debut = paste0(annee-1,"-08-01")
fin = paste0(annee,"-08-01")
......@@ -145,12 +144,12 @@ pic_annuel = function(annee) {
#+END_SRC
Nous devons aussi faire attention aux premières et dernières années de notre jeux de données. Les données commencent en octobre 1984, ce qui ne permet pas de quantifier complètement le pic attribué à l'année 1985. Nous le supprimons donc de notre analyse. Par contre, pour une exécution en octobre 2018, les données se terminent après le 1er août 2018, ce qui nous permet d'inclure cette année.
#+BEGIN_SRC R :results silent
#+BEGIN_SRC R :results silent :exports both
annees <- 1986:2018
#+END_SRC
Nous créons un nouveau jeu de données pour l'incidence annuelle, en applicant la fonction `pic_annuel` à chaque année:
#+BEGIN_SRC R :results value
#+BEGIN_SRC R :results value :exports both
inc_annuelle = data.frame(annee = annees,
incidence = sapply(annees, pic_annuel))
head(inc_annuelle)
......@@ -158,17 +157,17 @@ head(inc_annuelle)
** Inspection
Voici les incidences annuelles en graphique.
#+BEGIN_SRC R :results output graphics :file annual-inc-plot.png
#+BEGIN_SRC R :results output graphics :file annual-inc-plot.png :exports both
plot(inc_annuelle, type="p", xlab="Année", ylab="Incidence annuelle")
#+END_SRC
** Identification des épidémies les plus fortes
Une liste triée par ordre décroissant d'incidence annuelle permet de plus facilement repérer les valeurs les plus élevées:
#+BEGIN_SRC R :results output
#+BEGIN_SRC R :results output :exports both
head(inc_annuelle[order(-inc_annuelle$incidence),])
#+END_SRC
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
#+BEGIN_SRC R :results output graphics :file annual-inc-hist.png :exports both
hist(inc_annuelle$incidence, breaks=10, xlab="Incidence annuelle", ylab="Nb d'observations", main="")
#+END_SRC
......@@ -10,39 +10,45 @@
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
#+PROPERTY: header-args :session :exports both
#+PROPERTY: header-args :session
* Préface
Pour exécuter le code de cette analyse, il faut disposer des logiciels suivants:
** Emacs 25 ou 26
Une version plus ancienne d'Emacs devrait suffire, mais en ce cas il est prudent d'installer une version récente (9.x) d'org-mode.
** Python 3.6
** Emacs 25 ou plus
Une version plus ancienne d'Emacs devrait suffire. Pour une version antérieure à 26, il faut installer une version récente (9.x) d'org-mode.
** Python 3.6 ou plus
Nous utilisons le traitement de dates en format ISO 8601, qui a été implémenté en Python seulement avec la version 3.6.
#+BEGIN_SRC python :results output
#+BEGIN_SRC python :results output :exports both
import sys
if sys.version_info.major < 3 or sys.version_info.minor < 6:
print("Veuillez utiliser Python 3.6 (ou plus) !")
#+END_SRC
#+BEGIN_SRC emacs-lisp :results output
#+RESULTS:
#+BEGIN_SRC emacs-lisp :results output :exports both
(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.
#+BEGIN_SRC emacs-lisp :results output
#+BEGIN_SRC emacs-lisp :results output :exports both
(unless (featurep 'ob-R)
(print "Veuillez activer R dans org-babel (org-babel-do-languages) !"))
#+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 demandée. Nous téléchargeons toujours le jeu de données complet, qui commence en 1984 et se termine avec une semaine récente. L'URL est:
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:
#+NAME: data-url
http://www.sentiweb.fr/datasets/incidence-PAY-3.csv
......@@ -66,7 +72,7 @@ L'indication d'une semaine calendaire en format [[https://en.wikipedia.org/wiki/
** Téléchargement
Après avoir téléchargé les données, nous commençons par l'extraction des données qui nous intéressent. D'abord nous découpons le contenu du fichier en lignes, dont nous jetons la première qui ne contient qu'un commentaire. Les autres lignes sont découpées en colonnes.
#+BEGIN_SRC python :results silent :var data_url=data-url
#+BEGIN_SRC python :results silent :var data_url=data-url :exports both
from urllib.request import urlopen
data = urlopen(data_url).read()
......@@ -76,15 +82,22 @@ table = [line.split(',') for line in data_lines]
#+END_SRC
Regardons ce que nous avons obtenu:
#+BEGIN_SRC python :results value
#+BEGIN_SRC python :results value :exports both
table[:5]
#+END_SRC
#+RESULTS:
| week | indicator | inc | inc_low | inc_up | inc100 | inc100_low | inc100_up | geo_insee | geo_name |
| 201911 | 3 | 31787 | 26747 | 36827 | 48 | 40 | 56 | FR | France |
| 201910 | 3 | 49871 | 43378 | 56364 | 76 | 66 | 86 | FR | France |
| 201909 | 3 | 88354 | 79564 | 97144 | 134 | 121 | 147 | FR | France |
| 201908 | 3 | 172604 | 160024 | 185184 | 262 | 243 | 281 | 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.
Nous construisons un nouveau jeu de données sans les lignes qui contiennent des champs vides. Nous affichons ces lignes pour en garder une trace.
#+BEGIN_SRC python :results output
#+BEGIN_SRC python :results output :exports both
valid_table = []
for row in table:
missing = any([column == '' for column in row])
......@@ -94,26 +107,44 @@ 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
#+BEGIN_SRC python :results silent :exports both
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
Regardons les premières et les dernières lignes. Nous insérons ~None~ pour indiquer à org-mode la séparation entre les trois sections du tableau: en-tête, début des données, fin des données.
#+BEGIN_SRC python :results value
#+BEGIN_SRC python :results value :exports both
[('week', 'inc'), None] + data[:5] + [None] + data[-5:]
#+END_SRC
#+RESULTS:
| week | inc |
|--------+--------|
| 201911 | 31787 |
| 201910 | 49871 |
| 201909 | 88354 |
| 201908 | 172604 |
| 201907 | 307338 |
|--------+--------|
| 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
#+BEGIN_SRC python :results output :exports both
for week, inc in data:
if len(week) != 6 or not week.isdigit():
print("Valeur suspecte dans la colonne 'week': ", (week, inc))
......@@ -121,12 +152,14 @@ for week, inc in data:
print("Valeur suspecte dans la colonne 'inc': ", (week, inc))
#+END_SRC
#+RESULTS:
Pas de problème !
** Conversions
Pour faciliter les traitements suivants, nous remplaçons les numéros de semaine ISO par les dates qui correspondent aux lundis. A cette occasion, nous trions aussi les données par la date, et nous transformons les incidences en nombres entiers.
#+BEGIN_SRC python :results silent
#+BEGIN_SRC python :results silent :exports both
import datetime
converted_data = [(datetime.datetime.strptime(year_and_week + ":1" , '%G%V:%u').date(),
int(inc))
......@@ -135,53 +168,86 @@ converted_data.sort(key = lambda record: record[0])
#+END_SRC
Regardons de nouveau les premières et les dernières lignes:
#+BEGIN_SRC python :results value
#+BEGIN_SRC python :results value :exports both
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 |
|------------+--------|
| 2019-02-11 | 307338 |
| 2019-02-18 | 172604 |
| 2019-02-25 | 88354 |
| 2019-03-04 | 49871 |
| 2019-03-11 | 31787 |
** 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
#+BEGIN_SRC python :results output :exports both
dates = [date for date, _ in converted_data]
for date1, date2 in zip(dates[:-1], dates[1:]):
if date2-date1 != datetime.timedelta(weeks=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.
Nous utilisons le mécanisme d'échange de données proposé par org-mode, ce qui nécessite un peu de code Python pour transformer les données dans le bon format.
#+NAME: data-for-R
#+BEGIN_SRC python :results silent
#+BEGIN_SRC python :results silent :exports both
[('date', 'inc'), None] + [(str(date), inc) for date, inc in converted_data]
#+END_SRC
En R, les données arrivent sous forme d'un data frame, mais il faut encore convertir les dates, qui arrivent comme chaînes de caractères.
#+BEGIN_SRC R :results output :var data=data-for-R
#+BEGIN_SRC R :results output :var data=data-for-R :exports both
data$date <- as.Date(data$date)
summary(data)
#+END_SRC
#+RESULTS:
: date inc
: Min. :1984-10-29 Min. : 0
: 1st Qu.:1993-06-07 1st Qu.: 5137
: Median :2002-01-07 Median : 16182
: Mean :2002-01-06 Mean : 62939
: 3rd Qu.:2010-08-09 3rd Qu.: 51746
: Max. :2019-03-11 Max. :1001824
** Inspection
Regardons enfin à quoi ressemblent nos données !
#+BEGIN_SRC R :results output graphics :file inc-plot.png
#+BEGIN_SRC R :results output graphics :file inc-plot.png :exports both
plot(data, type="l", xlab="Date", ylab="Incidence hebdomadaire")
#+END_SRC
#+RESULTS:
[[file:inc-plot.png]]
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
#+BEGIN_SRC R :results output graphics :file inc-plot-zoom.png :exports both
plot(tail(data, 200), type="l", xlab="Date", ylab="Incidence hebdomadaire")
#+END_SRC
#+RESULTS:
[[file:inc-plot-zoom.png]]
* Étude de l'incidence annuelle
** Calcul de l'incidence annuelle
Étant donné que le pic de l'épidémie se situe en hiver, à cheval entre deux années civiles, nous définissons la période de référence entre deux minima de l'incidence, du 1er août de l'année /N/ au 1er août de l'année /N+1/. Nous mettons l'année /N+1/ comme étiquette sur cette année décalée, car le pic de l'épidémie est toujours au début de l'année /N+1/. Comme l'incidence du syndrome grippal est très faible en été, cette modification ne risque pas de fausser nos conclusions.
Voici une fonction qui calcule l'incidence annuelle en appliquant ces conventions.
#+BEGIN_SRC R :results silent
#+BEGIN_SRC R :results silent :exports both
pic_annuel = function(annee) {
debut = paste0(annee-1,"-08-01")
fin = paste0(annee,"-08-01")
......@@ -190,30 +256,53 @@ pic_annuel = function(annee) {
}
#+END_SRC
Nous devons aussi faire attention aux premières et dernières années de notre jeux de données. Les données commencent en octobre 1984, ce qui ne permet pas de quantifier complètement le pic attribué à l'année 1985. Nous le supprimons donc de notre analyse. Par contre, les données se terminent après le 1er août 2018 (pour une exécution après cette date bien sûr), ce qui nous permet d'inclure cette année dans l'analyse.
#+BEGIN_SRC R :results silent
Nous devons aussi faire attention aux premières et dernières années de notre jeux de données. Les données commencent en octobre 1984, ce qui ne permet pas de quantifier complètement le pic attribué à l'année 1985. Nous le supprimons donc de notre analyse. Pour la même raison, nous arrêtons en 2018. Nous devons attendre les données pour juillet 2019 avant d'augmenter la dernière année à 2019.
#+BEGIN_SRC R :results silent :exports both
annees <- 1986:2018
#+END_SRC
#+BEGIN_SRC R :results value
#+BEGIN_SRC R :results value :exports both
inc_annuelle = data.frame(annee = annees,
incidence = sapply(annees, pic_annuel))
head(inc_annuelle)
#+END_SRC
#+RESULTS:
| 1986 | 5100540 |
| 1987 | 2861556 |
| 1988 | 2766142 |
| 1989 | 5460155 |
| 1990 | 5233987 |
| 1991 | 1660832 |
** Inspection
Voici les incidences annuelles en graphique.
#+BEGIN_SRC R :results output graphics :file annual-inc-plot.png
#+BEGIN_SRC R :results output graphics :file annual-inc-plot.png :exports both
plot(inc_annuelle, type="p", xlab="Année", ylab="Incidence annuelle")
#+END_SRC
#+RESULTS:
[[file:annual-inc-plot.png]]
** Identification des épidémies les plus fortes
Une liste triée par ordre décroissant d'incidence annuelle permet de plus facilement repérer les valeurs les plus élevées:
#+BEGIN_SRC R :results output
#+BEGIN_SRC R :results output :exports both
head(inc_annuelle[order(-inc_annuelle$incidence),])
#+END_SRC
#+RESULTS:
: annee incidence
: 4 1989 5460155
: 5 1990 5233987
: 1 1986 5100540
: 28 2013 4182265
: 25 2010 4085126
: 14 1999 3897443
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
#+BEGIN_SRC R :results output graphics :file annual-inc-hist.png :exports both
hist(inc_annuelle$incidence, breaks=10, xlab="Incidence annuelle", ylab="Nb d'observations", main="")
#+END_SRC
#+RESULTS:
[[file:annual-inc-hist.png]]
This source diff could not be displayed because it is too large. You can view the blob instead.
#+TITLE: Incidence du syndrôme grippal
#+LANGUAGE: en
#+OPTIONS: *:nil num:1 toc:t
# #+HTML_HEAD: <link rel="stylesheet" title="Standard" href="http://orgmode.org/worg/style/worg.css" type="text/css" />
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
#+HTML_HEAD: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
#+HTML_HEAD: <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
#+PROPERTY: header-args :session
* Foreword
For running this analysis, you need the following software:
** Emacs 25 or higher
Older versions may suffice. For Emacs versions older than 26, org-mode must be updated to version 9.x.
** Python 3.6 or higher
We use the ISO 8601 date format, which has been added to Python's standard library with version 3.6.
#+BEGIN_SRC python :results output :exports both
import sys
if sys.version_info.major < 3 or sys.version_info.minor < 6:
print("Please use Python 3.6 (or higher)!")
#+END_SRC
#+BEGIN_SRC emacs-lisp :results output :exports both
(unless (featurep 'ob-python)
(print "Please activate python in org-babel (org-babel-do-languages)!"))
#+END_SRC
** R 3.4
We use only basic R functionality, so a earlier version might be OK, but we did not test this.
#+BEGIN_SRC emacs-lisp :results output :exports both
(unless (featurep 'ob-R)
(print "Please activate R in org-babel (org-babel-do-languages)!"))
#+END_SRC
* Data preprocessing
The data on the incidence of influenza-like illness are available from the Web site of the [[http://www.sentiweb.fr/][Réseau Sentinelles]]. We download them as a file in CSV format, in which each line corresponds to a week in the observation period. Only the complete dataset, starting in 1984 and ending with a recent week, is available for download. The URL is:
#+NAME: data-url
http://www.sentiweb.fr/datasets/incidence-PAY-3.csv
This is the documentation of the data from [[https://ns.sentiweb.fr/incidence/csv-schema-v1.json][the download site]]:
| Column name | Description |
|--------------+---------------------------------------------------------------------------------------------------------------------------|
| ~week~ | ISO8601 Yearweek number as numeric (year*100 + week nubmer) |
| ~indicator~ | Unique identifier of the indicator, see metadata document https://www.sentiweb.fr/meta.json |
| ~inc~ | Estimated incidence value for the time step, in the geographic level |
| ~inc_low~ | Lower bound of the estimated incidence 95% Confidence Interval |
| ~inc_up~ | Upper bound of the estimated incidence 95% Confidence Interval |
| ~inc100~ | Estimated rate incidence per 100,000 inhabitants |
| ~inc100_low~ | Lower bound of the estimated incidence 95% Confidence Interval |
| ~inc100_up~ | Upper bound of the estimated rate incidence 95% Confidence Interval |
| ~geo_insee~ | Identifier of the geographic area, from INSEE https://www.insee.fr |
| ~geo_name~ | Geographic label of the area, corresponding to INSEE code. This label is not an id and is only provided for human reading |
The [[https://en.wikipedia.org/wiki/ISO_8601][ISO-8601]] format is popular in Europe, but less so in North America. This may explain why few software packages handle this format.
** Download
To avoid downloading the data multiple times, we keep it in a buffer, which is a memory area in Emacs that contains text. The name of the buffer is
#+NAME: data-buffer-name
*influenza-like-illness data*
#+BEGIN_SRC emacs-lisp :results silent :var url=data-url :var name=data-buffer-name :exports both
(require 'url)
(with-current-buffer (get-buffer-create name)
(unless buffer-read-only
(url-handler-mode)
(insert-file-contents url)
(setq buffer-read-only t)))
#+END_SRC
The next step is the extraction of the data we need. We first split the file into lines, of which we discard the first one that contains a comment. We then split the remaining lines into columns. To identify missing data values, we check if a line contains at least one empty field. At the end of this code block two variables contain the missing data and the valid data, respectively.
#+BEGIN_SRC emacs-lisp :results silent :var name=data-buffer-name :exports both
(require 'cl)
(require 'dash)
(defun missing-data? (row)
(--any (string= it "") row))
(with-current-buffer name
(let* ((lines (split-string (buffer-string) "\n" t))
(table (rest lines))
(columns (--map (split-string it ",") table))
(missing/valid (-separate 'missing-data? columns)))
(setq missing-data-lines (first missing/valid))
(setq valid-data-lines (second missing/valid))))
#+END_SRC
Let's look at the missing data...
#+BEGIN_SRC emacs-lisp :exports both
missing-data-lines
#+END_SRC
There are only two columns that we will need for our analysis: the first (~"week"~) and the third (~"inc"~). We insert ~hline~ as the second element of the table to tell org-mode to separate the header from the data.
#+NAME: data
#+BEGIN_SRC emacs-lisp :results silent :exports both
(-insert-at 1 'hline
(-select-columns '(0 2) valid-data-lines))
#+END_SRC
Let's look at the first and last lines:
#+BEGIN_SRC emacs-lisp :results value :var data=data :colnames yes :exports both
(-concat (-take 5 data)
'(hline)
(-take-last 5 data))
#+END_SRC
** Verification
It is always prudent to verify if the data looks credible. A simple fact we can check for is that weeks are given as six-digit integers (four for the year, two for the week), that the first two are "19" or "20", and that the incidence values are positive integers.
#+BEGIN_SRC emacs-lisp :results output :var data=data :colnames yes :exports both
(defun check-week (week)
(unless (string-match-p (rx (or "19" "20") (repeat 4 digit)) week)
(princ (format "Invalid week value: %s\n" week))))
(defun check-inc (inc)
(unless (string-match-p "[0-9]+" inc)
(princ (format "Invalid incidence value: %s\n" inc) )))
(-map (lambda (week+inc)
(check-week (first week+inc))
(check-inc (second week+inc)))
data)
#+END_SRC
Everything seems to be OK !
** Conversions
In order to facilitate the subsequent treatment, we replace the ISO week numbers by the dates of each week's Monday. This is also a good occasion to sort the lines by increasing data, and to convert the incidences from strings to integers. We use the Python 3 language which is one of the few to have ISO week handling in its standard library.
#+BEGIN_SRC python :results silent :var input_data=data :exports both
import datetime
data = [(datetime.datetime.strptime(year_and_week + ":1" , '%G%V:%u').date(),
int(inc))
for year_and_week, inc in input_data]
data.sort(key = lambda record: record[0])
#+END_SRC
We'll look again at the first and last lines:
#+BEGIN_SRC python :results value :exports both
str_data = [(str(date), str(inc)) for date, inc in data]
[('date', 'inc'), None] + str_data[:5] + [None] + str_data[-5:]
#+END_SRC
** Date verification
We do one more verification: our dates must be separated by exactly one week, except around the missing data point.
#+BEGIN_SRC python :results output :exports both
dates = [date for date, _ in data]
for date1, date2 in zip(dates[:-1], dates[1:]):
if date2-date1 != datetime.timedelta(weeks=1):
print(f"The difference between {date1} and {date2} is {date2-date1}")
#+END_SRC
** Transfer Python -> R
We switch to R for data inspection and analysis, because the code is more concise in R and requires no additional libraries.
Org-mode's data exchange mechanism requires some Python code for transforming the data to the right format.
#+NAME: data-for-R
#+BEGIN_SRC python :results silent :exports both
[('date', 'inc'), None] + [(str(date), inc) for date, inc in converted_data]
#+END_SRC
In R, the dataset arrives as a data frame, which is fine. But the dates arrive as strings and must be converted.
#+BEGIN_SRC R :results output :var data=data-for-R :exports both
data$date <- as.Date(data$date)
summary(data)
#+END_SRC
** Inspection
Finally we can look at a plot of our data!
#+BEGIN_SRC R :results output graphics :file inc-plot.png :exports both
plot(data, type="l", xlab="Date", ylab="Weekly incidence")
#+END_SRC
A zoom on the last few years makes the peaks in winter stand out more clearly.
#+BEGIN_SRC R :results output graphics :file inc-plot-zoom.png :exports both
plot(tail(data, 200), type="l", xlab="Date", ylab="Weekly incidence")
#+END_SRC
* Study of the annual incidence
** Computation of the annual incidence
Since the peaks of the epidemic happen in winter, near the transition between calendar years, we define the reference period for the annual incidence from August 1st of year /N/ to August 1st of year /N+1/. We label this period as year /N+1/ because the peak is always located in year /N+1/. The very low incidence in summer ensures that the arbitrariness of the choice of reference period has no impact on our conclusions.
This R function computes the annual incidence as defined above:
#+BEGIN_SRC R :results silent :exports both
yearly_peak = function(year) {
debut = paste0(year-1,"-08-01")
fin = paste0(year,"-08-01")
semaines = data$date > debut & data$date <= fin
sum(data$inc[semaines], na.rm=TRUE)
}
#+END_SRC
We must also be careful with the first and last years of the dataset. The data start in October 1984, meaning that we don't have all the data for the peak attributed to the year 1985. We therefore exclude it from the analysis. For the same reason, we define 2018 as the final year. We can increase this value to 2019 only when all data up to July 2019 is available.
#+BEGIN_SRC R :results silent :exports both
years <- 1986:2018
#+END_SRC
We make a new data frame for the annual incidence, applying the function ~yearly_peak~ to each year:
#+BEGIN_SRC R :results value :exports both
annnual_inc = data.frame(year = years,
incidence = sapply(years, yearly_peak))
head(annnual_inc)
#+END_SRC
** Inspection
A plot of the annual incidence:
#+BEGIN_SRC R :results output graphics :file annual-inc-plot.png :exports both
plot(annnual_inc, type="p", xlab="Année", ylab="Annual incidence")
#+END_SRC
** Identification of the strongest epidemics
A list sorted by decreasing annual incidence makes it easy to find the most important ones:
#+BEGIN_SRC R :results output :exports both
head(annnual_inc[order(-annnual_inc$incidence),])
#+END_SRC
Finally, a histogram clearly shows the few very strong epidemics, which affect about 10% of the French population, but are rare: there were three of them in the course of 35 years. The typical epidemic affects only half as many people.
#+BEGIN_SRC R :results output graphics :file annual-inc-hist.png :exports both
hist(annnual_inc$incidence, breaks=10, xlab="Annual incidence", ylab="Number of observations", main="")
#+END_SRC
#+TITLE: Incidence du syndrôme grippal
#+LANGUAGE: en
#+OPTIONS: *:nil num:1 toc:t
# #+HTML_HEAD: <link rel="stylesheet" title="Standard" href="http://orgmode.org/worg/style/worg.css" type="text/css" />
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
#+HTML_HEAD: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
#+HTML_HEAD: <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
#+PROPERTY: header-args :session
* Foreword
For running this analysis, you need the following software:
** Emacs 25 or higher
Older versions may suffice. For Emacs versions older than 26, org-mode must be updated to version 9.x.
** R 3.4
We use only basic R functionality, so a earlier version might be OK, but we did not test this.
#+BEGIN_SRC emacs-lisp :results output :exports both
(unless (featurep 'ob-R)
(print "Please activate R in org-babel (org-babel-do-languages)!"))
#+END_SRC
For handling dates in ISO-8601 format, we need the library ~parsedate~.
#+BEGIN_SRC R :results output :exports both
library(parsedate)
#+END_SRC
* Data preprocessing
The data on the incidence of influenza-like illness are available from the Web site of the [[http://www.sentiweb.fr/][Réseau Sentinelles]]. We download them as a file in CSV format, in which each line corresponds to a week in the observation period. Only the complete dataset, starting in 1984 and ending with a recent week, is available for download. The URL is:
#+NAME: data-url
http://www.sentiweb.fr/datasets/incidence-PAY-3.csv
This is the documentation of the data from [[https://ns.sentiweb.fr/incidence/csv-schema-v1.json][the download site]]:
| Column name | Description |
|--------------+---------------------------------------------------------------------------------------------------------------------------|
| ~week~ | ISO8601 Yearweek number as numeric (year*100 + week nubmer) |
| ~indicator~ | Unique identifier of the indicator, see metadata document https://www.sentiweb.fr/meta.json |
| ~inc~ | Estimated incidence value for the time step, in the geographic level |
| ~inc_low~ | Lower bound of the estimated incidence 95% Confidence Interval |
| ~inc_up~ | Upper bound of the estimated incidence 95% Confidence Interval |
| ~inc100~ | Estimated rate incidence per 100,000 inhabitants |
| ~inc100_low~ | Lower bound of the estimated incidence 95% Confidence Interval |
| ~inc100_up~ | Upper bound of the estimated rate incidence 95% Confidence Interval |
| ~geo_insee~ | Identifier of the geographic area, from INSEE https://www.insee.fr |
| ~geo_name~ | Geographic label of the area, corresponding to INSEE code. This label is not an id and is only provided for human reading |
** Download
The first line of the CSV file is a comment, which we ignore with ~skip=1~.
#+BEGIN_SRC R :session :results silent :var url=data-url :exports both
data = read.csv(trimws(url), skip=1)
#+END_SRC
Let's see what we got!
#+BEGIN_SRC R :results output :exports both
head(data)
tail(data)
#+END_SRC
** Verification
Are there missing data points?
#+BEGIN_SRC R :results value :exports both
na_records = apply(data, 1, function(x) any(is.na(x)))
data[na_records,]
#+END_SRC
The two relevant columns for us are `week` and `inc`. Let's verify their classes:
#+BEGIN_SRC R :results output :exports both
class(data$week)
class(data$inc)
#+END_SRC
Integers, fine!
** Conversions
In order to facilitate the subsequent treatment, we replace the ISO week numbers by the dates of each week's Monday. This function does it for one value:
#+BEGIN_SRC R :results silent :exports both
convert_week = function(w) {
ws = paste(w)
iso = paste0(substring(ws,1,4), "-W", substring(ws,5,6))
as.Date(parse_iso_8601(iso))
}
#+END_SRC
We apply it to all points, creating a new column ~date~ in our data frame:
#+BEGIN_SRC R :results output :exports both
data$date = as.Date(convert_week(data$week))
#+END_SRC
Let's check that is has class ~Date~:
#+BEGIN_SRC R :results output :exports both
class(data$date)
#+END_SRC
The points are in inverse chronological order, so it's preferable to sort them:
#+BEGIN_SRC R :results output :exports both
data = data[order(data$date),]
#+END_SRC
** Verification of the dates
Another check: our dates should be separated by exactly seven days:
#+BEGIN_SRC R :results value :exports both
all(diff(data$date) == 7)
#+END_SRC
** Inspection
Finally we can look at a plot of our data!
#+BEGIN_SRC R :results output graphics :file inc-plot.png :exports both
plot(data$date, data$inc, type="l", xlab="Date", ylab="Incidence hebdomadaire")
#+END_SRC
A zoom on the last few years makes the peaks in winter stand out more clearly.
#+BEGIN_SRC R :results output graphics :file inc-plot-zoom.png :exports both
with(tail(data, 200), plot(date, inc, type="l", xlab="Date", ylab="Incidence hebdomadaire"))
#+END_SRC
* Study of the annual incidence
** Computation of the annual incidence
Since the peaks of the epidemic happen in winter, near the transition between calendar years, we define the reference period for the annual incidence from August 1st of year /N/ to August 1st of year /N+1/. We label this period as year /N+1/ because the peak is always located in year /N+1/. The very low incidence in summer ensures that the arbitrariness of the choice of reference period has no impact on our conclusions.
This R function computes the annual incidence as defined above:
#+BEGIN_SRC R :results silent :exports both
yearly_peak = function(year) {
debut = paste0(year-1,"-08-01")
fin = paste0(year,"-08-01")
semaines = data$date > debut & data$date <= fin
sum(data$inc[semaines], na.rm=TRUE)
}
#+END_SRC
We must also be careful with the first and last years of the dataset. The data start in October 1984, meaning that we don't have all the data for the peak attributed to the year 1985. We therefore exclude it from the analysis. For the same reason, we define 2018 as the final year. We can increase this value to 2019 only when all data up to July 2019 is available.
#+BEGIN_SRC R :results silent :exports both
years <- 1986:2018
#+END_SRC
We make a new data frame for the annual incidence, applying the function ~yearly_peak~ to each year:
#+BEGIN_SRC R :results value :exports both
annnual_inc = data.frame(year = years,
incidence = sapply(years, yearly_peak))
head(annnual_inc)
#+END_SRC
** Inspection
A plot of the annual incidence:
#+BEGIN_SRC R :results output graphics :file annual-inc-plot.png :exports both
plot(annnual_inc, type="p", xlab="Année", ylab="Annual incidence")
#+END_SRC
** Identification of the strongest epidemics
A list sorted by decreasing annual incidence makes it easy to find the most important ones:
#+BEGIN_SRC R :results output :exports both
head(annnual_inc[order(-annnual_inc$incidence),])
#+END_SRC
Finally, a histogram clearly shows the few very strong epidemics, which affect about 10% of the French population, but are rare: there were three of them in the course of 35 years. The typical epidemic affects only half as many people.
#+BEGIN_SRC R :results output graphics :file annual-inc-hist.png :exports both
hist(annnual_inc$incidence, breaks=10, xlab="Annual incidence", ylab="Number of observations", main="")
#+END_SRC
#+TITLE: Incidence of influenza-like illness in France
#+LANGUAGE: en
#+OPTIONS: *:nil num:1 toc:t
# #+HTML_HEAD: <link rel="stylesheet" title="Standard" href="http://orgmode.org/worg/style/worg.css" type="text/css" />
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
#+HTML_HEAD: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
#+HTML_HEAD: <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
#+PROPERTY: header-args :session
* Foreword
For running this analysis, you need the following software:
** Emacs 25 or higher
Older versions may suffice. For Emacs versions older than 26, org-mode must be updated to version 9.x.
** Python 3.6 or higher
We use the ISO 8601 date format, which has been added to Python's standard library with version 3.6.
#+BEGIN_SRC python :results output :exports both
import sys
if sys.version_info.major < 3 or sys.version_info.minor < 6:
print("Please use Python 3.6 (or higher)!")
#+END_SRC
#+RESULTS:
#+BEGIN_SRC emacs-lisp :results output :exports both
(unless (featurep 'ob-python)
(print "Please activate python in org-babel (org-babel-do-languages)!"))
#+END_SRC
#+RESULTS:
** R 3.4
We use only basic R functionality, so a earlier version might be OK, but we did not test this.
#+BEGIN_SRC emacs-lisp :results output :exports both
(unless (featurep 'ob-R)
(print "Please activate R in org-babel (org-babel-do-languages)!"))
#+END_SRC
#+RESULTS:
* Data preprocessing
The data on the incidence of influenza-like illness are available from the Web site of the [[http://www.sentiweb.fr/][Réseau Sentinelles]]. We download them as a file in CSV format, in which each line corresponds to a week in the observation period. Only the complete dataset, starting in 1984 and ending with a recent week, is available for download. The URL is:
#+NAME: data-url
http://www.sentiweb.fr/datasets/incidence-PAY-3.csv
This is the documentation of the data from [[https://ns.sentiweb.fr/incidence/csv-schema-v1.json][the download site]]:
| Column name | Description |
|--------------+---------------------------------------------------------------------------------------------------------------------------|
| ~week~ | ISO8601 Yearweek number as numeric (year*100 + week nubmer) |
| ~indicator~ | Unique identifier of the indicator, see metadata document https://www.sentiweb.fr/meta.json |
| ~inc~ | Estimated incidence value for the time step, in the geographic level |
| ~inc_low~ | Lower bound of the estimated incidence 95% Confidence Interval |
| ~inc_up~ | Upper bound of the estimated incidence 95% Confidence Interval |
| ~inc100~ | Estimated rate incidence per 100,000 inhabitants |
| ~inc100_low~ | Lower bound of the estimated incidence 95% Confidence Interval |
| ~inc100_up~ | Upper bound of the estimated rate incidence 95% Confidence Interval |
| ~geo_insee~ | Identifier of the geographic area, from INSEE https://www.insee.fr |
| ~geo_name~ | Geographic label of the area, corresponding to INSEE code. This label is not an id and is only provided for human reading |
The [[https://en.wikipedia.org/wiki/ISO_8601][ISO-8601]] format is popular in Europe, but less so in North America. This may explain why few software packages handle this format. The Python language does it since version 3.6. We therefore use Python for the pre-processing phase, which has the advantage of not requiring any additional library. (Note: we will explain in module 4 why it is desirable for reproducibility to use as few external libraries as possible.)
** Download
After downloading the raw data, we extract the part we are interested in. We first split the file into lines, of which we discard the first one that contains a comment. We then split the remaining lines into columns.
#+BEGIN_SRC python :results silent :var data_url=data-url :exports both
from urllib.request import urlopen
data = urlopen(data_url).read()
lines = data.decode('latin-1').strip().split('\n')
data_lines = lines[1:]
table = [line.split(',') for line in data_lines]
#+END_SRC
Let's have a look at what we have so far:
#+BEGIN_SRC python :results value :exports both
table[:5]
#+END_SRC
#+RESULTS:
| week | indicator | inc | inc_low | inc_up | inc100 | inc100_low | inc100_up | geo_insee | geo_name |
| 201911 | 3 | 31787 | 26747 | 36827 | 48 | 40 | 56 | FR | France |
| 201910 | 3 | 49871 | 43378 | 56364 | 76 | 66 | 86 | FR | France |
| 201909 | 3 | 88354 | 79564 | 97144 | 134 | 121 | 147 | FR | France |
| 201908 | 3 | 172604 | 160024 | 185184 | 262 | 243 | 281 | FR | France |
** Checking for missing data
Unfortunately there are many ways to indicate the absence of a data value in a dataset. Here we check for a common one: empty fields. For completeness, we should also look for non-numerical data in numerical columns. We don't do this here, but checks in later processing steps would catch such anomalies.
We make a new dataset without the lines that contain empty fields. We print those lines to preserve a trace of their contents.
#+BEGIN_SRC python :results output :exports both
valid_table = []
for row in table:
missing = any([column == '' for column in row])
if missing:
print(row)
else:
valid_table.append(row)
#+END_SRC
#+RESULTS:
: ['198919', '3', '0', '', '', '0', '', '', 'FR', 'France']
** Extraction of the required columns
There are only two columns that we will need for our analysis: the first (~"week"~) and the third (~"inc"~). We check the names in the header to be sure we pick the right data. We make a new table containing just the two columns required, without the header.
#+BEGIN_SRC python :results silent :exports both
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
del inc[0]
data = list(zip(week, inc))
#+END_SRC
Let's look at the first and last lines. We insert ~None~ to indicate to org-mode the separation between the three parts of the table: header, first lines, last lines.
#+BEGIN_SRC python :results value :exports both
[('week', 'inc'), None] + data[:5] + [None] + data[-5:]
#+END_SRC
#+RESULTS:
| week | inc |
|--------+--------|
| 201911 | 31787 |
| 201910 | 49871 |
| 201909 | 88354 |
| 201908 | 172604 |
| 201907 | 307338 |
|--------+--------|
| 198448 | 78620 |
| 198447 | 72029 |
| 198446 | 87330 |
| 198445 | 135223 |
| 198444 | 68422 |
** Verification
It is always prudent to verify if the data looks credible. A simple fact we can check for is that weeks are given as six-digit integers (four for the year, two for the week), and that the incidence values are positive integers.
#+BEGIN_SRC python :results output :exports both
for week, inc in data:
if len(week) != 6 or not week.isdigit():
print("Suspicious value in column 'week': ", (week, inc))
if not inc.isdigit():
print("Suspicious value in column 'inc': ", (week, inc))
#+END_SRC
#+RESULTS:
No problem - fine!
** Date conversion
In order to facilitate the subsequent treatment, we replace the ISO week numbers by the dates of each week's Monday. This is also a good occasion to sort the lines by increasing data, and to convert the incidences from strings to integers.
#+BEGIN_SRC python :results silent :exports both
import datetime
converted_data = [(datetime.datetime.strptime(year_and_week + ":1" , '%G%V:%u').date(),
int(inc))
for year_and_week, inc in data]
converted_data.sort(key = lambda record: record[0])
#+END_SRC
We'll look again at the first and last lines:
#+BEGIN_SRC python :results value :exports both
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 |
|------------+--------|
| 2019-02-11 | 307338 |
| 2019-02-18 | 172604 |
| 2019-02-25 | 88354 |
| 2019-03-04 | 49871 |
| 2019-03-11 | 31787 |
** Date verification
We do one more verification: our dates must be separated by exactly one week, except around the missing data point.
#+BEGIN_SRC python :results output :exports both
dates = [date for date, _ in converted_data]
for date1, date2 in zip(dates[:-1], dates[1:]):
if date2-date1 != datetime.timedelta(weeks=1):
print(f"The difference between {date1} and {date2} is {date2-date1}")
#+END_SRC
#+RESULTS:
: The difference between 1989-05-01 and 1989-05-15 is 14 days, 0:00:00
** Transfer Python -> R
We switch to R for data inspection and analysis, because the code is more concise in R and requires no additional libraries.
Org-mode's data exchange mechanism requires some Python code for transforming the data to the right format.
#+NAME: data-for-R
#+BEGIN_SRC python :results silent :exports both
[('date', 'inc'), None] + [(str(date), inc) for date, inc in converted_data]
#+END_SRC
In R, the dataset arrives as a data frame, which is fine. But the dates arrive as strings and must be converted.
#+BEGIN_SRC R :results output :var data=data-for-R :exports both
data$date <- as.Date(data$date)
summary(data)
#+END_SRC
#+RESULTS:
: date inc
: Min. :1984-10-29 Min. : 0
: 1st Qu.:1993-06-07 1st Qu.: 5137
: Median :2002-01-07 Median : 16182
: Mean :2002-01-06 Mean : 62939
: 3rd Qu.:2010-08-09 3rd Qu.: 51746
: Max. :2019-03-11 Max. :1001824
** Inspection
Finally we can look at a plot of our data!
#+BEGIN_SRC R :results output graphics :file inc-plot.png :exports both
plot(data, type="l", xlab="Date", ylab="Weekly incidence")
#+END_SRC
#+RESULTS:
[[file:inc-plot.png]]
A zoom on the last few years makes the peaks in winter stand out more clearly.
#+BEGIN_SRC R :results output graphics :file inc-plot-zoom.png :exports both
plot(tail(data, 200), type="l", xlab="Date", ylab="Weekly incidence")
#+END_SRC
#+RESULTS:
[[file:inc-plot-zoom.png]]
* Study of the annual incidence
** Computation of the annual incidence
Since the peaks of the epidemic happen in winter, near the transition between calendar years, we define the reference period for the annual incidence from August 1st of year /N/ to August 1st of year /N+1/. We label this period as year /N+1/ because the peak is always located in year /N+1/. The very low incidence in summer ensures that the arbitrariness of the choice of reference period has no impact on our conclusions.
This R function computes the annual incidence as defined above:
#+BEGIN_SRC R :results silent :exports both
yearly_peak = function(year) {
debut = paste0(year-1,"-08-01")
fin = paste0(year,"-08-01")
semaines = data$date > debut & data$date <= fin
sum(data$inc[semaines], na.rm=TRUE)
}
#+END_SRC
We must also be careful with the first and last years of the dataset. The data start in October 1984, meaning that we don't have all the data for the peak attributed to the year 1985. We therefore exclude it from the analysis. For the same reason, we define 2018 as the final year. We can increase this value to 2019 only when all data up to July 2019 is available.
#+BEGIN_SRC R :results silent :exports both
years <- 1986:2018
#+END_SRC
We make a new data frame for the annual incidence, applying the function ~yearly_peak~ to each year:
#+BEGIN_SRC R :results value :exports both
annnual_inc = data.frame(year = years,
incidence = sapply(years, yearly_peak))
head(annnual_inc)
#+END_SRC
#+RESULTS:
| 1986 | 5100540 |
| 1987 | 2861556 |
| 1988 | 2766142 |
| 1989 | 5460155 |
| 1990 | 5233987 |
| 1991 | 1660832 |
** Inspection
A plot of the annual incidence:
#+BEGIN_SRC R :results output graphics :file annual-inc-plot.png :exports both
plot(annnual_inc, type="p", xlab="Année", ylab="Annual incidence")
#+END_SRC
#+RESULTS:
[[file:annual-inc-plot.png]]
** Identification of the strongest epidemics
A list sorted by decreasing annual incidence makes it easy to find the most important ones:
#+BEGIN_SRC R :results output :exports both
head(annnual_inc[order(-annnual_inc$incidence),])
#+END_SRC
#+RESULTS:
: year incidence
: 4 1989 5460155
: 5 1990 5233987
: 1 1986 5100540
: 28 2013 4182265
: 25 2010 4085126
: 14 1999 3897443
Finally, a histogram clearly shows the few very strong epidemics, which affect about 10% of the French population, but are rare: there were three of them in the course of 35 years. The typical epidemic affects only half as many people.
#+BEGIN_SRC R :results output graphics :file annual-inc-hist.png :exports both
hist(annnual_inc$incidence, breaks=10, xlab="Annual incidence", ylab="Number of observations", main="")
#+END_SRC
#+RESULTS:
[[file:annual-inc-hist.png]]
---
title: "Incidence of influenza-like illness in France"
author: "Konrad Hinsen"
output:
pdf_document:
toc: true
html_document:
toc: true
theme: journal
documentclass: article
classoption: a4paper
header-includes:
- \usepackage[french]{babel}
- \usepackage[upright]{fourier}
- \hypersetup{colorlinks=true,pagebackref=true}
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## Data preprocessing
The data on the incidence of influenza-like illness are available from the Web site of the [Réseau Sentinelles](http://www.sentiweb.fr/). We download them as a file in CSV format, in which each line corresponds to a week in the observation period. Only the complete dataset, starting in 1984 and ending with a recent week, is available for download. The URL is:
```{r}
data_url = "http://www.sentiweb.fr/datasets/incidence-PAY-3.csv"
```
This is the documentation of the data from [the download site](https://ns.sentiweb.fr/incidence/csv-schema-v1.json):
| Column name | Description |
|--------------+---------------------------------------------------------------------------------------------------------------------------|
| `week` | ISO8601 Yearweek number as numeric (year*100 + week nubmer) |
| `indicator` | Unique identifier of the indicator, see metadata document https://www.sentiweb.fr/meta.json |
| `inc` | Estimated incidence value for the time step, in the geographic level |
| `inc_low` | Lower bound of the estimated incidence 95% Confidence Interval |
| `inc_up` | Upper bound of the estimated incidence 95% Confidence Interval |
| `inc100` | Estimated rate incidence per 100,000 inhabitants |
| `inc100_low` | Lower bound of the estimated incidence 95% Confidence Interval |
| `inc100_up` | Upper bound of the estimated rate incidence 95% Confidence Interval |
| `geo_insee` | Identifier of the geographic area, from INSEE https://www.insee.fr |
| `geo_name` | Geographic label of the area, corresponding to INSEE code. This label is not an id and is only provided for human reading |
### Download
The first line of the CSV file is a comment, which we ignore with `skip=1`.
```{r}
data = read.csv(data_url, skip=1)
```
Let's have a look at what we got:
```{r}
head(data)
tail(data)
```
Are there missing data points?
```{r}
na_records = apply(data, 1, function (x) any(is.na(x)))
data[na_records,]
```
The two relevant columns for us are `week` and `inc`. Let's verify their classes:
```{r}
class(data$week)
class(data$inc)
```
Integers, fine!
### Conversion of the week numbers
Date handling is always a delicate subject. There are many conventions that are easily confused. Our dataset uses the [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) week number format, which is popular in Europe but less so in North America. In `R`, it is handled by the library [parsedate](https://cran.r-project.org/package=parsedate):
```{r}
library(parsedate)
```
In order to facilitate the subsequent treatment, we replace the ISO week numbers by the dates of each week's Monday. This function does it for one value:
```{r}
convert_week = function(w) {
ws = paste(w)
iso = paste0(substring(ws, 1, 4), "-W", substring(ws, 5, 6))
as.character(parse_iso_8601(iso))
}
```
We apply it to all points, creating a new column `date` in our data frame:
```{r}
data$date = as.Date(convert_week(data$week))
```
Let's check that is has class `Date`:
```{r}
class(data$date)
```
The points are in inverse chronological order, so it's preferable to sort them:
```{r}
data = data[order(data$date),]
```
That's a good occasion for another check: our dates should be separated by exactly seven days:
```{r}
all(diff(data$date) == 7)
```
### Inspection
Finally we can look at a plot of our data!
```{r}
plot(data$date, data$inc, type="l", xlab="Date", ylab="Weekly incidence")
```
A zoom on the last few years makes the peaks in winter stand out more clearly.
```{r}
with(tail(data, 200), plot(date, inc, type="l", xlab="Date", ylab="Weekly incidence"))
```
## Annual incidence
### Computation
Since the peaks of the epidemic happen in winter, near the transition between calendar years, we define the reference period for the annual incidence from August 1st of year $N$ to August 1st of year $N+1$. We label this period as year $N+1$ because the peak is always located in year $N+1$. The very low incidence in summer ensures that the arbitrariness of the choice of reference period has no impact on our conclusions.
The argument `na.rm=True` in the sum indicates that missing data points are removed. This is a reasonable choice since there is only one missing point, whose impact cannot be very strong.
```{r}
yearly_peak = function(year) {
debut = paste0(year-1,"-08-01")
fin = paste0(year,"-08-01")
semaines = data$date > debut & data$date <= fin
sum(data$inc[semaines], na.rm=TRUE)
}
```
We must also be careful with the first and last years of the dataset. The data start in October 1984, meaning that we don't have all the data for the peak attributed to the year 1985. We therefore exclude it from the analysis. For the same reason, we define 2018 as the final year. We can increase this value to 2019 only when all data up to July 2019 is available.
```{r}
years = 1986:2018
```
We make a new data frame for the annual incidence, applying the function `yearly_peak` to each year:
```{r}
annnual_inc = data.frame(year = years,
incidence = sapply(years, yearly_peak))
head(annnual_inc)
```
### Inspection
A plot of the annual incidences:
```{r}
plot(annnual_inc, type="p", xlab="Année", ylab="Annual incidence")
```
### Identification of the strongest epidemics
A list sorted by decreasing annual incidence makes it easy to find the most important ones:
```{r}
head(annnual_inc[order(-annnual_inc$incidence),])
```
Finally, a histogram clearly shows the few very strong epidemics, which affect about 10% of the French population, but are rare: there were three of them in the course of 35 years. The typical epidemic affects only half as many people.
```{r}
hist(annnual_inc$incidence, breaks=10, xlab="Annual incidence", ylab="Number of observations", main="")
```
# -*- mode: org -*-
#+TITLE: The ISO date format
#+DATE: March 2019
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:nil
#+PROPERTY: header-args :eval never-export
[[https://en.wikipedia.org/wiki/ISO_8601][ISO 8601]] specifies the digital representation of date and time. For dates, which are of interest to us here, there are two different ways of proceeding: we can give the year, the month, and the day of the month, or we can give the year, the week, and the day of the week. August 8, 2018 can therefore be written =2018-08-08= or =2018-W32-3=, as it is the third day (Wednesday) of week 32 of 2018.
The definition of the week number requires some thought, as January 1st rarely falls on a Monday. What week is the first week of the year? The answer given by ISO 8601 is: the one that has more than half of its days in the new year, which is equivalent to the one that contains the first Thursday of the year. Consequently, it is quite possible, even frequent, that the first day of the first week of year /N/ is in year /N-1/. To designate a whole week, we simply do not provide the day.
The Sentinel Network uses this definition of the week number, but does not respect the precise representation provided by ISO 8601. Instead of writing the third week of 1995 as =1995-W03=, it uses =199503=.
# -*- mode: org -*-
#+TITLE: Le format ISO pour les dates
#+DATE: Mars 2019
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:nil
#+PROPERTY: header-args :eval never-export
La norme [[https://fr.wikipedia.org/wiki/ISO_8601][ISO 8601]] spécifie la représentation numérique de la date et de l'heure. Pour la date, qui nous intéresse ici, il y a deux façons différentes de procéder : on peut donner l'année, le mois, et le jour du mois, ou on peut donner l'année, la semaine, et le jour de la semaine. Le 8 août 2018 peut donc être écrit =2018-08-08= ou =2018-W32-3=, car il s'agit du troisième jour (mercredi) de la semaine 32 de l'année 2018.
La définition du numéro de la semaine nécessite un peu de réflexion, car le 1er janvier ne tombe que rarement sur un lundi. Quelle semaine est donc la première de l'année ? La réponse de la norme ISO 8601 est : celle qui a plus de la moitié de ses jours dans la nouvelle année, ce qui est équivalent à dire celle qui contient le premier jeudi de l'année. Par conséquent, il est tout à fait possible, même fréquent, que le 1er jour de la première semaine de l'année /N/ tombe dans l'année /N-1/. Pour désigner une semaine entière, on ne fournit simplement pas le jour.
Le Réseau Sentinelles reprend cette définition du numéro de semaine, mais ne respecte pas la représentation précise prévue par la norme ISO 8601. Au lieu d'écrire la troisième semaine de 1995 comme =1995-W03=, il écrit =199503=.
all: resources_refs.html resources_environment.html exo1.html exo2.html exo3.html
ressources-md: resources_refs.md resources_environment.md resources_refs_fr.md resources_environment_fr.md # exo1.html exo2.html exo3.html
NLINES=10000000
include ../../Makefile.ressources
%.html: %.org
emacs -batch $^ --funcall org-html-export-to-html
sed -i -e 's/<pre /<pre style="padding-left: 30px; background-color: #f6f8fa;" /g' \
-e 's/<li>/<li style="margin-bottom:0;">/g' \
-e 's/<ul>/<ul style="margin:0 0;">/g' $@
mv $@ $@.bak
html_png_inliner.pl < $@.bak | grep -A $(NLINES) -e '<body>' | grep -B $(NLINES) -e '<div id="postamble" class="status">' | grep -v -e '<body>' -e '<div id="postamble" class="status">' > $@
rm $@.bak
clean:
rm -f *~
<div id="outline-container-orgc50e61e" class="outline-2">
<h2 id="orgc50e61e">Exercice 1 : Ré-exécuter n'est pas répliquer&#x2026;</h2>
<div class="outline-text-2" id="text-orgc50e61e">
<p>
Même si la terminologie peut varier d'un auteur ou d'une communauté à
l'autre, il est important de comprendre que l'on peut distinguer
différents niveaux de "réplication" selon que l'on s'est contenté de
vérifier que l'on pouvait ré-exécuter le code et obtenir exactement les
mêmes résultats ou bien que l'on arrivait à reproduire des résultats
similaires en suivant une approche similaire (éventuellement avec un
autre langage, une autre méthode de calcul, etc.). À ce sujet, vous
pourrez vouloir par exemple lire <a href="https://arxiv.org/abs/1708.08205">https://arxiv.org/abs/1708.08205</a>.
</p>
<p>
Le diable se cache souvent dans des endroits auxquels on n'aurait jamais
pensé et nous sommes nous-mêmes allés de surprise en surprise en
préparant ce MOOC, notamment avec l'exercice du module 2 sur
Challenger. C'est pourquoi nous vous proposons dans cet exercice, de
refaire une partie de l'analyse des données de Challenger, comme l'ont
fait Siddhartha Dallal et ses co-auteurs il y a presque 30 ans dans
leur article <i>Risk Analysis of the Space Shuttle: Pre-Challenger
Prediction of Failure</i> et publié dans le <i>Journal of the American
Statistical Association</i> (Vol. 84, No. 408, Déc., 1989) mais dans un autre langage de votre choix (Python, R, Julia, SAS&#x2026;).
</p>
<p>
Nous savons d'expérience que si les estimations de pente et
d'intercept sont généralement les mêmes, on peut avoir des différences
lorsque l'on regarde les estimateurs de variance et le R<sup>2</sup> un peu plus
dans les détails. Il peut également y avoir des surprises dans le
graphique final selon les versions de bibliothèques utilisées.
</p>
<p>
L'ensemble des calculs à effectuer est décrit ici avec les
indications sur comment contribuer :
<a href="https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/">https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/</a>
</p>
<p>
Vous y trouverez notre réplication des calculs de Dallal <i>et al.</i> (en
R), une mise en œuvre en Python et une en R (très similaires à ce que
vous avez pu utiliser dans le module 2). Cet exercice peut donc se
faire à deux niveaux :
</p>
<ol class="org-ol">
<li>un niveau facile pour ceux qui repartiront du code dans le langage
qu'ils n'auront initialement pas utilisé et se contenteront de le
ré-exécuter. Pour cela, nul besoin de maîtriser la régression
logistique, il suffit de bien inspecter les sorties produites et de
vérifier qu'elles correspondent bien aux valeurs attendues. Pour
ceux qui ré-exécuteraient le notebook Python dans l'environnement
Jupyter du MOOC, n'hésitez pas à consulter <a href="https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405">les ressources de la
section 4A du module 2</a> qui expliquent comment y importer un
notebook.</li>
<li>un niveau plus difficile pour ceux qui souhaiteront le réécrire
complètement (éventuellement dans un autre langage que R ou Python,
l'expérience peut être d'autant plus intéressante que nous n'avons
pas testé ces variations). Là, si les fonctions de calcul d'une
régression logistique ne sont pas présentes, il y a par contre
intérêt à en savoir un minimum pour pouvoir les
implémenter. L'exercice en est d'autant plus instructif.</li>
</ol>
<p>
Vous pourrez alors discuter sur le forum des succès et des échecs que
vous aurez pu rencontrer. Pour cela :
</p>
<ul class="org-ul">
<li><b>Vous publierez auparavant dans votre dépôt les différents notebooks</b>
en prenant bien soin d'enrichir votre document des informations
(numéros de version, etc.) sur votre système et sur les
bibliothèques installées.</li>
<li>Vous indiquerez votre résultat (que ça soit un succès ou échec à
obtenir les mêmes résultats) en <b>remplissant ce <a href="https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md">tableau</a></b> (vous avez
les droits d'édition donc il vous suffit d'éditer les fichiers via
l'interface GitLab). Vous vérifierez les valeurs obtenues pour :
<ol class="org-ol">
<li>les coefficients de la pente et de l'intercept</li>
<li>les estimations d'erreur de ces coefficients</li>
<li>le goodness of fit</li>
<li>la figure</li>
<li>la zone de confiance</li>
</ol></li>
<li><p>
Pour chacun vous indiquerez si le résultat est :
</p>
<ul class="org-ul">
<li>identique</li>
<li>proche à moins de trois décimales</li>
<li>très différent</li>
<li>non fonctionnel (pas de résultat obtenu)</li>
</ul>
<p>
Vous indiquerez également dans ce tableau :
</p>
<ul class="org-ul">
<li>un lien vers votre espace gitlab contenant les différents notebooks</li>
<li>le nom du système d'exploitation utilisé</li>
<li>le langage utilisé et son numéro de version</li>
<li>les numéros des principales bibliothèques utilisées
<ul class="org-ul">
<li>Python : numpy, pandas, matplotlib, statsmodels&#x2026;</li>
<li>R : BLAS, ggplot, dplyr si chargées</li>
</ul></li>
</ul></li>
</ul>
<p>
Ne vous inquiétez pas si ces consignes vous semblent peu claires sur l'instant,
elles sont rappelées en haut du <a href="https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md">tableau</a> et vous vous rendrez vite
compte s'il vous manque quelque chose quand vous essaierez de remplir
ce tableau.
</p>
<p>
Nous effectuerons une synthèse illustrant les principales divergences
observées et nous vous l'enverrons à la fin du MOOC.
</p>
</div>
</div>
<div id="outline-container-org55f722b" class="outline-2">
<h2 id="org55f722b" style="color: #b62567;">Re-execution is not replication&#x2026;</h2>
<div class="outline-text-2" id="text-org55f722b">
<p style="color: #b62567;">
Unfortunately terminology varies a lot between authors and
communities, but it is important to understand the distinction between
different levels of "replication". You can be satisfied with
re-running the code and get exactly the same results, but you can also
try to obtain similar results using a similar approach, changing for
example the programming language, computational method, etc. An
article we recommend on this topic is
<a href="https://arxiv.org/abs/1708.08205">https://arxiv.org/abs/1708.08205</a>.
</p>
<p style="color: #b62567;">
Often the devil is in the details that one would have never thought
about, and we have had our share of surprises while preparing this
MOOC, in particular with the exercise on the Challenger catastrophe
from module 2. We therefore propose in this exercise that you re-do a
part of this analysis, following the example of Siddhartha Dallal and
co-authors almost 30 years ago in their article <i>Risk Analysis of the
Space Shuttle: Pre-Challenger Prediction of Failure</i>, published in the
<i>Journal of the American Statistical Association</i> (Vol. 84, No. 408,
Déc., 1989), but using a different language of your choosing (Python,
R, Julia, SAS&#x2026;).
</p>
<p style="color: #b62567;">
Our experience shows that the estimations of slope and intercept are
generally the same, but there can be differences when looking at
variance estimators and R<sup>2</sup> in more detail. Another source of
surprises is the final graphical presentation, depending on the
versions of the libraries that are used.
</p>
<p style="color: #b62567;">
The computations to be done are described at
<a href="https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/">https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/</a>
together with instructions for contributing.
</p>
<p style="color: #b62567;">
You will find there our replications of the computations by Dallal <i>et
al.</i> (in R), one in Python and one in R (very similar to what you have
used in module 2). This exercise can be done at two levels:
</p>
<ol class="org-ol">
<li style="color: #b62567;">an easy level at which you start from the code in the language that you did not use initially, and content yourself with re-executin it. This doesn't require mastering logistic regression, it is sufficien to inspect the outputs produced and check that they correspond to the expected values. For those who want to re-execute the Python notebook in our MOOC's Jupyter environment, check <a href="https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405">the resources for sequence 4A of module 2</a> that explain how to import a notebook.</li>
<li style="color: #b62567;">a more difficult level at which you rewrite the analysis completely, possibly in a different language than Python or R, which makes the exercise more interesting because we have not tested such variants. If logistic regression is not already implemented for your language, you will need a good understanding of it in order to write the code yourself, which of course makes the exercise even more instructive.</li>
</ol>
<p style="color: #b62567;">
You can discuss your successes or failures on the forum, after following these instructions:
</p>
<ul class="org-ul">
<li style="color: #b62567;"><b>First, publish your notebooks in your repository</b>, taking care to enrich your document with information about your system and your libraries (version numbers etc.).</li>
<li style="color: #b62567;">Indicate your result by adding to this <a href="https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md">table</a> (you have write permissions, so you can simply edit it via the GitLab interface). Check the values obtained for:
<ol class="org-ol">
<li style="color: #b62567;">the slope and intercept coefficients</li>
<li style="color: #b62567;">the error estimates for these coefficients</li>
<li style="color: #b62567;">the goodness of fit</li>
<li style="color: #b62567;">the plot</li>
<li style="color: #b62567;">the confidence region</li>
</ol></li>
<li><p style="color: #b62567;">
For each of these values, specify if your result is
</p>
<ul class="org-ul">
<li style="color: #b62567;">identical</li>
<li style="color: #b62567;">close, to three decimal places</li>
<li style="color: #b62567;">very different</li>
<li style="color: #b62567;">non functional (no result obtained)</li>
</ul>
<p style="color: #b62567;">
Also provide in this table:
</p>
<ul class="org-ul">
<li style="color: #b62567;">a link to your GitLab workspace with your notebook(s)</li>
<li style="color: #b62567;">your operating system</li>
<li style="color: #b62567;">the language you used, with the version number</li>
<li style="color: #b62567;">version numbers for the main libraries
<ul class="org-ul">
<li style="color: #b62567;">Python: numpy, pandas, matplotlib, statsmodels&#x2026;</li>
<li style="color: #b62567;">R: BLAS, ggplot, dplyr if used</li>
</ul></li>
</ul></li>
</ul>
<p style="color: #b62567;">
Don't worry if these instructions seem confusing, they are reproduced above the <a href="https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md">table</a> and you will quickly notice if something is missing when you try to add your data.
</p>
<p style="color: #b62567;">
We will compile a synthesis of the principal divergences observes and make it available at the end of the MOOC.
</p>
</div>
</div>
</div>
# -*- mode: org -*-
#+TITLE:
#+AUTHOR: Arnaud Legrand
#+TITLE: Module 4 / Exercice 1
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
......@@ -34,7 +33,7 @@ graphique final selon les versions de bibliothèques utilisées.
L'ensemble des calculs à effectuer est décrit ici avec les
indications sur comment contribuer :
[[https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/][https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/]]
[[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/][https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/]]
Vous y trouverez notre réplication des calculs de Dallal /et al./ (en
R), une mise en œuvre en Python et une en R (très similaires à ce que
......@@ -46,7 +45,7 @@ faire à deux niveaux :
logistique, il suffit de bien inspecter les sorties produites et de
vérifier qu'elles correspondent bien aux valeurs attendues. Pour
ceux qui ré-exécuteraient le notebook Python dans l'environnement
Jupyter du MOOC, n'hésitez pas à consulter [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405][les ressources de la
Jupyter du MOOC, n'hésitez pas à consulter [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405][les ressources de la
section 4A du module 2]] qui expliquent comment y importer un
notebook.
2. un niveau plus difficile pour ceux qui souhaiteront le réécrire
......@@ -64,7 +63,7 @@ vous aurez pu rencontrer. Pour cela :
(numéros de version, etc.) sur votre système et sur les
bibliothèques installées.
- Vous indiquerez votre résultat (que ça soit un succès ou échec à
obtenir les mêmes résultats) en *remplissant ce [[https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md][tableau]]* (vous avez
obtenir les mêmes résultats) en *remplissant ce [[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/blob/master/results.md][tableau]]* (vous avez
les droits d'édition donc il vous suffit d'éditer les fichiers via
l'interface GitLab). Vous vérifierez les valeurs obtenues pour :
1) les coefficients de la pente et de l'intercept
......@@ -86,7 +85,7 @@ vous aurez pu rencontrer. Pour cela :
- R : BLAS, ggplot, dplyr si chargées
Ne vous inquiétez pas si ces consignes vous semblent peu claires sur l'instant,
elles sont rappelées en haut du [[https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md][tableau]] et vous vous rendrez vite
elles sont rappelées en haut du [[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/blob/master/results.md][tableau]] et vous vous rendrez vite
compte s'il vous manque quelque chose quand vous essaierez de remplir
ce tableau.
......@@ -121,19 +120,19 @@ surprises is the final graphical presentation, depending on the
versions of the libraries that are used.
The computations to be done are described at
[[https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/][https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/]]
[[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/][https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/]]
together with instructions for contributing.
You will find there our replications of the computations by Dallal /et
al./ (in R), one in Python and one in R (very similar to what you have
used in module 2). This exercise can be done at two levels:
1. an easy level at which you start from the code in the language that you did not use initially, and content yourself with re-executin it. This doesn't require mastering logistic regression, it is sufficien to inspect the outputs produced and check that they correspond to the expected values. For those who want to re-execute the Python notebook in our MOOC's Jupyter environment, check [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405][the resources for sequence 4A of module 2]] that explain how to import a notebook.
1. an easy level at which you start from the code in the language that you did not use initially, and content yourself with re-executin it. This doesn't require mastering logistic regression, it is sufficien to inspect the outputs produced and check that they correspond to the expected values. For those who want to re-execute the Python notebook in our MOOC's Jupyter environment, check [[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405][the resources for sequence 4A of module 2]] that explain how to import a notebook.
2. a more difficult level at which you rewrite the analysis completely, possibly in a different language than Python or R, which makes the exercise more interesting because we have not tested such variants. If logistic regression is not already implemented for your language, you will need a good understanding of it in order to write the code yourself, which of course makes the exercise even more instructive.
You can discuss your successes or failures on the forum, after following these instructions:
- *First, publish your notebooks in your repository*, taking care to enrich your document with information about your system and your libraries (version numbers etc.).
- Indicate your result by adding to this [[https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md][table]] (you have write permissions, so you can simply edit it via the GitLab interface). Check the values obtained for:
- Indicate your result by adding to this [[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/blob/master/results.md][table]] (you have write permissions, so you can simply edit it via the GitLab interface). Check the values obtained for:
1) the slope and intercept coefficients
2) the error estimates for these coefficients
3) the goodness of fit
......@@ -152,6 +151,6 @@ You can discuss your successes or failures on the forum, after following these i
- Python: numpy, pandas, matplotlib, statsmodels...
- R: BLAS, ggplot, dplyr if used
Don't worry if these instructions seem confusing, they are reproduced above the [[https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md][table]] and you will quickly notice if something is missing when you try to add your data.
Don't worry if these instructions seem confusing, they are reproduced above the [[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/blob/master/results.md][table]] and you will quickly notice if something is missing when you try to add your data.
We will compile a synthesis of the principal divergences observes and make it available at the end of the MOOC.
<h2 id="org1f802ba">Exercice 2 : L'importance de l'environnement</h2>
<div class="outline-text-2" id="text-org1f802ba">
<p>
Dans cet exercice, nous vous proposons de reprendre l'exercice
précédent mais en mettant à jour l'environnement de calcul. En effet,
nous avons rencontré des surprises en préparant ce MOOC puisqu'il nous
est arrivé d'avoir des résultats différents entre nos machines et
l'environnement Jupyter que nous avions mis en place pour le MOOC. Ça
sera peut-être également votre cas !
</p>
<ol class="org-ol">
<li>Pour ceux qui ont suivi le parcours Jupyter, recréez
l'environnement du MOOC sur votre propre machine en suivant les
instructions données
<a href="https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405">dans les ressources de la section 4A du module 2</a>.</li>
<li>Vérifiez si vous obtenez bien les mêmes résultats que ceux
attendus.</li>
<li>Mettez à jour (vers le haut ou vers la bas) cet environnement et
vérifiez si vous obtenez les mêmes résultats.</li>
</ol>
<p>
Comme précédemment, vous mettrez à jour le <a href="https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md">tableau</a> et vous discuterez
sur le forum des succès et des échecs que vous aurez rencontrés.
</p>
</div>
</div>
<div id="outline-container-org1a24dbb" class="outline-2">
<h2 id="org1a24dbb"><span style="color: #b62567;">The importance of the environment</span></h2>
<div class="outline-text-2" id="text-org1a24dbb">
<p style="color: #b62567;">
In this exercise, we ask you to redo the preceding exercise after
updating the computational environment. When preparing this MOOC, we
had a few surprises due to different results on our own computers and
on the Jupyter environment that we had installed for the MOOC. Maybe
that will happen to you as well!
</p>
<ol class="org-ol">
<li style="color: #b62567;">For those you followed the Jupyter path, re-create the MOOC's Jupyter environment on your own computer by following the instructions given
<a href="https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405">in the resource section of sequence 4A of module 2</a>.</li>
<li style="color: #b62567;">Check if you get the same results as in the MOOC environment.</li>
<li style="color: #b62567;">Update this environment, increasing or decreasing some package's version numbers, and check if the results are still the same.</li>
</ol>
<p style="color: #b62567;">
As before, you can add your observations to the <a href="https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md">table</a> and discuss your successes and failures on the forum.
</p>
</div>
# -*- mode: org -*-
#+TITLE:
#+AUTHOR: Arnaud Legrand
#+TITLE: Module 4 / Exercice 2
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
......@@ -17,13 +16,13 @@ sera peut-être également votre cas !
1. Pour ceux qui ont suivi le parcours Jupyter, recréez
l'environnement du MOOC sur votre propre machine en suivant les
instructions données
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405][dans les ressources de la section 4A du module 2]].
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405][dans les ressources de la section 4A du module 2]].
2. Vérifiez si vous obtenez bien les mêmes résultats que ceux
attendus.
3. Mettez à jour (vers le haut ou vers la bas) cet environnement et
vérifiez si vous obtenez les mêmes résultats.
Comme précédemment, vous mettrez à jour le [[https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md][tableau]] et vous discuterez
Comme précédemment, vous mettrez à jour le [[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/blob/master/results.md][tableau]] et vous discuterez
sur le forum des succès et des échecs que vous aurez rencontrés.
* Exercice 2: The importance of the environment
......@@ -34,8 +33,8 @@ on the Jupyter environment that we had installed for the MOOC. Maybe
that will happen to you as well!
1. For those you followed the Jupyter path, re-create the MOOC's Jupyter environment on your own computer by following the instructions given
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+session01bis/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405][in the resource section of sequence 4A of module 2]].
[[https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/jump_to_id/4ab5bb42ca1e45c8b0f349751b96d405][in the resource section of sequence 4A of module 2]].
2. Check if you get the same results as in the MOOC environment.
3. Update this environment, increasing or decreasing some package's version numbers, and check if the results are still the same.
As before, you can add your observations to the [[https://app-learninglab.inria.fr/gitlab/moocrr-session1/moocrr-reproducibility-study/blob/master/results.md][table]] and discuss your successes and failures on the forum.
As before, you can add your observations to the [[https://app-learninglab.inria.fr/gitlab/moocrr-session2/moocrr-reproducibility-study/blob/master/results.md][table]] and discuss your successes and failures on the forum.
<div id="outline-container-org5b10dc4" class="outline-2">
<h2 id="org5b10dc4">Exercice 3 : Répliquer un papier de ReScience</h2>
<div class="outline-text-2" id="text-org5b10dc4">
<p>
ReScience (<a href="http://rescience.github.io/">http://rescience.github.io/</a>) est un journal de sciences
computationnelles entièrement ouvert dont l'objectif est d'encourager
la réplication de travaux déjà publiés en s'assurant que l'ensemble du
code et des données soit disponible. Pour chacun des articles publiés
dans ReScience, nous avons la garantie qu'au moins two chercheurs
indépendants ont réussi à suivre les indications, à ré-exécuter le
code et à ré-obtenir les mêmes résultats que ceux décrits par les
auteurs. Cela ne veut pas dire que cela soit parfaitement automatique
pour autant et il peut être intéressant de voir comment ils ont
procédé.
</p>
<p>
Nous vous proposons donc de choisir l'un de ces articles (celui avec
lequel vous avez le plus d'affinité) et d'essayer de réexécuter les
codes et les calculs décrits dans l'article. N'hésitez pas à indiquer
vos difficultés éventuelles sur le forum où nous répondrons à vos questions.
</p>
</div>
</div>
<div id="outline-container-org60c7839" class="outline-2">
<h2 id="org60c7839" style="color: #b62567;">Replicate a paper from ReScience</h2>
<div class="outline-text-2" id="text-org60c7839">
<p style="color: #b62567;">
ReScience (<a href="http://rescience.github.io/">http://rescience.github.io/</a>) is a scientific journal for
computational science that is completely open and has the goal of
encouraging the replication of already published work while providing
a complete set of code and data. For each article published in
ReScience, we know that at least two independent researchers (the
reviewers) have been able to follow the instructions, re-execute the
code, and obtain the same results as those described by the
authors. This doesn't mean that the process is fully automatic, and
therefore it is of interest to see how they have proceeded.
</p>
<p style="color: #b62567;">
We ask you to choose one of the articles (the one that you like most)
and to try to re-execute the code as described in the article. Don't
hesitate to indicate any difficulties you might encounter in the
forum, where we will reply to your questions&#x2026;
</p>
</div>
# -*- mode: org -*-
#+TITLE:
#+AUTHOR: Arnaud Legrand
#+TITLE: Module 4 / Exercice 3
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
......
#!/usr/bin/perl -w
use strict;
my($line);
while(defined($line=<STDIN>)) {
if($line =~ /^(.*)<img *src="([^"]*)"(.*)$/g) {
my($pre,$image,$post) = ($1,$2,$3);
$image =~ s|file://||;
# print "$image\n";
my $base64=`base64 -w 0 $image`;
my $format=$image;
$format =~ s/.*\.//g;
print $pre."<img src=\"data:image/$format;base64,".$base64.'"'.$post;
} else {
print $line;
}
}
<div id="content">
<h1 class="title">Tracking environment information</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org54d219c">Getting information about your Git repository</a></li>
<li style="margin-bottom:0;"><a href="#orgd1774c3">Getting information about Python(3) libraries</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org7283a87">Getting information about your system</a></li>
<li style="margin-bottom:0;"><a href="#orgfa4dc3a">Getting the list of installed packages and their version</a></li>
<li style="margin-bottom:0;"><a href="#org31cde5f">How to list imported modules?</a></li>
<li style="margin-bottom:0;"><a href="#orgcea179c">Saving and restoring an environment with pip</a></li>
<li style="margin-bottom:0;"><a href="#org849fdbb">Installing a new package or a specific version</a></li>
</ul>
</li>
<li style="margin-bottom:0;"><a href="#org4f45b1e">Getting information about R libraries</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#orgc583ee9">Getting the list imported modules and their version</a></li>
<li style="margin-bottom:0;"><a href="#orgdffc6a5">Getting the list of installed packages and their version</a></li>
<li style="margin-bottom:0;"><a href="#orgb52d0ce">Installing a new package or a specific version</a>
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#orgaf558a0">Installing a pre-compiled version</a></li>
<li style="margin-bottom:0;"><a href="#org7d8a9f0">Using devtools</a></li>
<li style="margin-bottom:0;"><a href="#org4509fba">Installing from source code</a></li>
<li style="margin-bottom:0;"><a href="#org9d64d25">Potential issues</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-org54d219c" class="outline-2">
<h2 id="org54d219c">Getting information about your Git repository</h2>
<div class="outline-text-2" id="text-org54d219c">
<p>
When taking notes, it may be difficult to remember which version of
the code or of a file was used. This is what version control is useful
for. Here are a few useful commands that we typically insert at the
top of our notebooks in shell cells
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">git log -1
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
commit 741b0088af5b40588493c23c46d6bab5d0adeb33
Author: Arnaud Legrand &lt;arnaud.legrand@imag.fr&gt;
Date: Tue Sep 4 12:45:43 2018 +0200
Fix a few typos and provide information on jupyter-git plugins.
</pre>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">git status -u
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add &lt;file&gt;..." to update what will be committed)
(use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
modified: resources.org
Untracked files:
(use "git add &lt;file&gt;..." to include in what will be committed)
../../module2/ressources/replicable_article/IEEEtran.bst
../../module2/ressources/replicable_article/IEEEtran.cls
../../module2/ressources/replicable_article/article.bbl
../../module2/ressources/replicable_article/article.tex
../../module2/ressources/replicable_article/data.csv
../../module2/ressources/replicable_article/figure.pdf
../../module2/ressources/replicable_article/logo.png
.#resources.org
no changes added to commit (use "git add" and/or "git commit -a")
</pre>
<p>
<i>Note: the -u indicates that git should also display the contents of
new directories it did not previously know about.</i>
</p>
<p>
Then, we often include commands at the end of our notebook indicating
how to commit the results (adding the new files, committing with a
clear message and pushing). E.g.,
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">git add resources.org;
git commit -m <span style="font-style: italic;">"Completing the section on getting Git information"</span>
git push
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
[master 514fe2c1 ] Completing the section on getting Git information
1 file changed, 61 insertions(+)
Counting objects: 25, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (20/20), done.
Writing objects: 100% (25/25), 7.31 KiB | 499.00 KiB/s, done.
Total 25 (delta 11), reused 0 (delta 0)
To ssh://app-learninglab.inria.fr:9418/learning-lab/mooc-rr-ressources.git
6359f8c..1f8a567 master -&gt; master
</pre>
<p>
Obviously, in this case you need to save the notebook before running
this cell, hence the output of this final command (with the new git
hash) will not be stored in the cell. This is not really a problem and
is the price to pay for running git from within the notebook itself.
</p>
</div>
</div>
<div id="outline-container-orgd1774c3" class="outline-2">
<h2 id="orgd1774c3">Getting information about Python(3) libraries</h2>
<div class="outline-text-2" id="text-orgd1774c3">
</div>
<div id="outline-container-org7283a87" class="outline-3">
<h3 id="org7283a87">Getting information about your system</h3>
<div class="outline-text-3" id="text-org7283a87">
<p>
This topic is discussed on <a href="https://stackoverflow.com/questions/3103178/how-to-get-the-system-info-with-python">StackOverflow</a>.
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-python"><span style="font-weight: bold;">import</span> platform
<span style="font-weight: bold;">print</span>(platform.uname())
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
uname_result(system='Linux', node='icarus', release='4.15.0-2-amd64', version='#1 SMP Debian 4.15.11-1 (2018-03-20)', machine='x86_64', processor='')
</pre>
</div>
</div>
<div id="outline-container-orgfa4dc3a" class="outline-3">
<h3 id="orgfa4dc3a">Getting the list of installed packages and their version</h3>
<div class="outline-text-3" id="text-orgfa4dc3a">
<p>
This topic is discussed on <a href="https://stackoverflow.com/questions/20180543/how-to-check-version-of-python-modules">StackOverflow</a>. When using <code>pip</code> (the Python
package installer) within a shell command, it is easy to query the
version of all installed packages (note that on your system, you may
have to use either <code>pip</code> or <code>pip3</code> depending on how it is named and which
versions of Python are available on your machine
</p>
<p>
Here is for example how I get this information on my machine:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">pip3 freeze
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
asn1crypto==0.24.0
attrs==17.4.0
bcrypt==3.1.4
beautifulsoup4==4.6.0
bleach==2.1.3
...
pandas==0.22.0
pandocfilters==1.4.2
paramiko==2.4.0
patsy==0.5.0
pexpect==4.2.1
...
traitlets==4.3.2
tzlocal==1.5.1
urllib3==1.22
wcwidth==0.1.7
webencodings==0.5
</pre>
<p>
In a Jupyter notebook, this can easily be done by using the <code>%%sh</code>
magic. Here is for example what you could do and get on the Jupyter
notebooks we deployed for the MOOC (note that here, you should simply
use the <code>pip</code> command):
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-python">%%sh
pip freeze
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
alembic==0.9.9
asn1crypto==0.24.0
attrs==18.1.0
Automat==0.0.0
...
numpy==1.13.3
olefile==0.45.1
packaging==17.1
pamela==0.3.0
pandas==0.22.0
...
webencodings==0.5
widgetsnbextension==3.2.1
xlrd==1.1.0
zope.interface==4.5.0
</pre>
<p>
In the rest of this document, I will assume the correct command is <code>pip</code>
and I will not systematically insert the <code>%%sh</code> magic.
</p>
<p>
Once you know which packages are installed, you can easily get
additional information about a given package and in particular check
whether it was installed "locally" through pip or whether it is
installed system-wide. Again, in a shell command:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">pip show pandas
<span style="font-weight: bold;">echo</span> <span style="font-style: italic;">" "</span>
pip show statsmodels
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
Name: pandas
Version: 0.22.0
Summary: Powerful data structures for data analysis, time series,and statistics
Home-page: http://pandas.pydata.org
Author: None
Author-email: None
License: BSD
Location: /usr/lib/python3/dist-packages
Requires:
Name: statsmodels
Version: 0.9.0
Summary: Statistical computations and models for Python
Home-page: http://www.statsmodels.org/
Author: None
Author-email: None
License: BSD License
Location: /home/alegrand/.local/lib/python3.6/site-packages
Requires: patsy, pandas
</pre>
</div>
</div>
<div id="outline-container-org31cde5f" class="outline-3">
<h3 id="org31cde5f">How to list imported modules?</h3>
<div class="outline-text-3" id="text-org31cde5f">
<p>
Without resorting to pip (that will list all available packages), you
may want to know which modules are loaded in a Python session as well
as their version. Inspired by <a href="https://stackoverflow.com/questions/4858100/how-to-list-imported-modules">StackOverflow</a>, here is a simple
function that lists loaded package (that have a <code>__version__</code> attribute,
which is unfortunately not completely standard).
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-python"><span style="font-weight: bold;">def</span> <span style="font-weight: bold;">print_imported_modules</span>():
<span style="font-weight: bold;">import</span> sys
<span style="font-weight: bold;">for</span> name, val <span style="font-weight: bold;">in</span> <span style="font-weight: bold;">sorted</span>(sys.modules.items()):
<span style="font-weight: bold;">if</span>(<span style="font-weight: bold;">hasattr</span>(val, <span style="font-style: italic;">'__version__'</span>)):
<span style="font-weight: bold;">print</span>(val.<span style="font-weight: bold;">__name__</span>, val.__version__)
<span style="font-weight: bold;">else</span>:
<span style="font-weight: bold;">print</span>(val.<span style="font-weight: bold;">__name__</span>, <span style="font-style: italic;">"(unknown version)"</span>)
<span style="font-weight: bold;">print</span>(<span style="font-style: italic;">"**** Package list in the beginning ****"</span>);
print_imported_modules()
<span style="font-weight: bold;">print</span>(<span style="font-style: italic;">"**** Package list after loading pandas ****"</span>);
<span style="font-weight: bold;">import</span> pandas
print_imported_modules()
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
**** Package list in the beginning ****
**** Package list after loading pandas ****
_csv 1.0
_ctypes 1.1.0
decimal 1.70
argparse 1.1
csv 1.0
ctypes 1.1.0
cycler 0.10.0
dateutil 2.7.3
decimal 1.70
distutils 3.6.5rc1
ipaddress 1.0
json 2.0.9
logging 0.5.1.2
matplotlib 2.1.1
numpy 1.14.5
numpy.core 1.14.5
numpy.core.multiarray 3.1
numpy.core.umath b'0.4.0'
numpy.lib 1.14.5
numpy.linalg._umath_linalg b'0.1.5'
pandas 0.22.0
_libjson 1.33
platform 1.0.8
pyparsing 2.2.0
pytz 2018.5
re 2.2.1
six 1.11.0
urllib.request 3.6
zlib 1.0
</pre>
</div>
</div>
<div id="outline-container-orgcea179c" class="outline-3">
<h3 id="orgcea179c">Saving and restoring an environment with pip</h3>
<div class="outline-text-3" id="text-orgcea179c">
<p>
The easiest way to go is as follows:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">pip3 freeze &gt; requirements.txt <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">to obtain the list of packages with their version</span>
pip3 install -r requirements.txt <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">to install the previous list of packages, possibly on an other machine</span>
</pre>
</div>
<p>
If you want to have several installed Python environments, you may
want to use <a href="https://docs.pipenv.org/">Pipenv</a>. I doubt it allows to track correctly FORTRAN or C
dynamic libraries that are wrapped by Python though.
</p>
</div>
</div>
<div id="outline-container-org849fdbb" class="outline-3">
<h3 id="org849fdbb">Installing a new package or a specific version</h3>
<div class="outline-text-3" id="text-org849fdbb">
<p>
The Jupyter environment we deployed on our servers for the MOOC is
based on the version 4.5.4 of Miniconda and Python 3.6. In this
environment you should simply use the <code>pip</code> command (remember on your
machine, you may have to use <code>pip3</code>).
</p>
<p>
If I query the current version of <code>statsmodels</code> in a shell command,
here is what I will get.
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">pip show statsmodels
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
Name: statsmodels
Version: 0.8.0
Summary: Statistical computations and models for Python
Home-page: http://www.statsmodels.org/
Author: Skipper Seabold, Josef Perktold
Author-email: pystatsmodels@googlegroups.com
License: BSD License
Location: /opt/conda/lib/python3.6/site-packages
Requires: scipy, patsy, pandas
</pre>
<p>
I can then easily upgrade <code>statsmodels</code>:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">pip install --upgrade statsmodels
</pre>
</div>
<p>
Then the new version should then be:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">pip show statsmodels
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
Name: statsmodels
Version: 0.9.0
Summary: Statistical computations and models for Python
Home-page: http://www.statsmodels.org/
Author: Skipper Seabold, Josef Perktold
Author-email: pystatsmodels@googlegroups.com
License: BSD License
Location: /opt/conda/lib/python3.6/site-packages
Requires: scipy, patsy, pandas
</pre>
<p>
It is even possible to install a specific (possibly much older) version, e.g.,:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">pip install <span style="font-weight: bold; font-style: italic;">statsmodels</span>==0.6.1
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org4f45b1e" class="outline-2">
<h2 id="org4f45b1e">Getting information about R libraries</h2>
<div class="outline-text-2" id="text-org4f45b1e">
</div>
<div id="outline-container-orgc583ee9" class="outline-3">
<h3 id="orgc583ee9">Getting the list imported modules and their version</h3>
<div class="outline-text-3" id="text-orgc583ee9">
<p>
The best way seems to be to rely on the <code>devtools</code> package (if this
package is not installed, you should install it first by running in <code>R</code>
the command <code>install.packages("devtools")</code>).
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-R">sessionInfo()
devtools::session_info()
</pre>
</div>
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="example">
R version 3.5.1 (2018-07-02)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Debian GNU/Linux buster/sid
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.8.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.8.0
locale:
[1] LC_CTYPE=fr_FR.UTF-8 LC_NUMERIC=C
[3] LC_TIME=fr_FR.UTF-8 LC_COLLATE=fr_FR.UTF-8
[5] LC_MONETARY=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8
[7] LC_PAPER=fr_FR.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.5.1
Session info ------------------------------------------------------------------
setting value
version R version 3.5.1 (2018-07-02)
system x86_64, linux-gnu
ui X11
language (EN)
collate fr_FR.UTF-8
tz Europe/Paris
date 2018-08-01
Packages ----------------------------------------------------------------------
package * version date source
base * 3.5.1 2018-07-02 local
compiler 3.5.1 2018-07-02 local
datasets * 3.5.1 2018-07-02 local
devtools 1.13.6 2018-06-27 CRAN (R 3.5.1)
digest 0.6.15 2018-01-28 CRAN (R 3.5.0)
graphics * 3.5.1 2018-07-02 local
grDevices * 3.5.1 2018-07-02 local
memoise 1.1.0 2017-04-21 CRAN (R 3.5.1)
methods * 3.5.1 2018-07-02 local
stats * 3.5.1 2018-07-02 local
utils * 3.5.1 2018-07-02 local
withr 2.1.2 2018-03-15 CRAN (R 3.5.0)
</pre>
<p>
Some actually advocate that <a href="https://github.com/ropensci/rrrpkg">writing a reproducible research compendium
is best done by writing an R package</a>. Those of you willing to have a
clean R dependency management should thus have a look at <a href="https://rstudio.github.io/packrat/">Packrat</a>.
</p>
</div>
</div>
<div id="outline-container-orgdffc6a5" class="outline-3">
<h3 id="orgdffc6a5">Getting the list of installed packages and their version</h3>
<div class="outline-text-3" id="text-orgdffc6a5">
<p>
Finally, it is good to know that there is a built-in R command
(<code>installed.packages</code>) allowing to retrieve and list the details of all
packages installed.
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-R">head(installed.packages())
</pre>
</div>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-left" />
<col class="org-right" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-right" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Package</th>
<th scope="col" class="org-left">LibPath</th>
<th scope="col" class="org-right">Version</th>
<th scope="col" class="org-left">Priority</th>
<th scope="col" class="org-left">Depends</th>
<th scope="col" class="org-left">Imports</th>
<th scope="col" class="org-left">LinkingTo</th>
<th scope="col" class="org-left">Suggests</th>
<th scope="col" class="org-left">Enhances</th>
<th scope="col" class="org-left">License</th>
<th scope="col" class="org-left">License<sub>is</sub><sub>FOSS</sub></th>
<th scope="col" class="org-left">License<sub>restricts</sub><sub>use</sub></th>
<th scope="col" class="org-left">OS<sub>type</sub></th>
<th scope="col" class="org-left">MD5sum</th>
<th scope="col" class="org-left">NeedsCompilation</th>
<th scope="col" class="org-left">Built</th>
<th scope="col" class="org-right">&#xa0;</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">BH</td>
<td class="org-left">/home/alegrand/R/x86<sub>64</sub>-pc-linux-gnu-library/3.5</td>
<td class="org-right">1.66.0-1</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">BSL-1.0</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">no</td>
<td class="org-left">3.5.1</td>
<td class="org-right">&#xa0;</td>
</tr>
<tr>
<td class="org-left">Formula</td>
<td class="org-left">/home/alegrand/R/x86<sub>64</sub>-pc-linux-gnu-library/3.5</td>
<td class="org-right">1.2-3</td>
<td class="org-left">nil</td>
<td class="org-left">R (&gt;= 2.0.0), stats</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">GPL-2</td>
<td class="org-left">GPL-3</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">no</td>
<td class="org-right">3.5.1</td>
</tr>
<tr>
<td class="org-left">Hmisc</td>
<td class="org-left">/home/alegrand/R/x86<sub>64</sub>-pc-linux-gnu-library/3.5</td>
<td class="org-right">4.1-1</td>
<td class="org-left">nil</td>
<td class="org-left">lattice, survival (&gt;= 2.40-1), Formula, ggplot2 (&gt;= 2.2)</td>
<td class="org-left">methods, latticeExtra, cluster, rpart, nnet, acepack, foreign,</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-right">&#xa0;</td>
</tr>
<tr>
<td class="org-left">gtable, grid, gridExtra, data.table, htmlTable (&gt;= 1.11.0),</td>
<td class="org-left">&#xa0;</td>
<td class="org-right">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-right">&#xa0;</td>
</tr>
<tr>
<td class="org-left">viridis, htmltools, base64enc</td>
<td class="org-left">nil</td>
<td class="org-right">chron, rms, mice, tables, knitr, ff, ffbase, plotly (&gt;=</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-right">&#xa0;</td>
</tr>
<tr>
<td class="org-left">4.5.6)</td>
<td class="org-left">nil</td>
<td class="org-right">GPL (&gt;= 2)</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">yes</td>
<td class="org-left">3.5.1</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-right">&#xa0;</td>
</tr>
<tr>
<td class="org-left">Matrix</td>
<td class="org-left">/home/alegrand/R/x86<sub>64</sub>-pc-linux-gnu-library/3.5</td>
<td class="org-right">1.2-14</td>
<td class="org-left">recommended</td>
<td class="org-left">R (&gt;= 3.2.0)</td>
<td class="org-left">methods, graphics, grid, stats, utils, lattice</td>
<td class="org-left">nil</td>
<td class="org-left">expm, MASS</td>
<td class="org-left">MatrixModels, graph, SparseM, sfsmisc</td>
<td class="org-left">GPL (&gt;= 2)</td>
<td class="org-left">file LICENCE</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">yes</td>
<td class="org-right">3.5.1</td>
</tr>
<tr>
<td class="org-left">StanHeaders</td>
<td class="org-left">/home/alegrand/R/x86<sub>64</sub>-pc-linux-gnu-library/3.5</td>
<td class="org-right">2.17.2</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">RcppEigen, BH</td>
<td class="org-left">nil</td>
<td class="org-left">BSD<sub>3</sub><sub>clause</sub> + file LICENSE</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">yes</td>
<td class="org-left">3.5.1</td>
<td class="org-right">&#xa0;</td>
</tr>
<tr>
<td class="org-left">acepack</td>
<td class="org-left">/home/alegrand/R/x86<sub>64</sub>-pc-linux-gnu-library/3.5</td>
<td class="org-right">1.4.1</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">testthat</td>
<td class="org-left">nil</td>
<td class="org-left">MIT + file LICENSE</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">nil</td>
<td class="org-left">yes</td>
<td class="org-left">3.5.1</td>
<td class="org-right">&#xa0;</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-orgb52d0ce" class="outline-3">
<h3 id="orgb52d0ce">Installing a new package or a specific version</h3>
<div class="outline-text-3" id="text-orgb52d0ce">
<p>
This section is mostly a cut and paste from the <a href="https://support.rstudio.com/hc/en-us/articles/219949047-Installing-older-versions-of-packages">recent post by Ian
Pylvainen</a> on this topic. It comprises a very clear explanation of how
to proceed.
</p>
</div>
<div id="outline-container-orgaf558a0" class="outline-4">
<h4 id="orgaf558a0">Installing a pre-compiled version</h4>
<div class="outline-text-4" id="text-orgaf558a0">
<p>
If you're on a Debian or a Ubuntu system, it may be difficult to
access a specific version without breaking your system. So unless you
are moving to the latest version available in your Linux distribution,
<b>we strongly recommend you to build from source</b>. In this case, you'll
need to make sure you have the necessary toolchain to build packages
from source (e.g., gcc, FORTRAN, etc.). On Windows, this may require
you to install <a href="https://cran.r-project.org/bin/windows/Rtools/">Rtools</a>.
</p>
<p>
If you're on Windows or OS X and looking for a package for an <b>older
version of R</b> (R 2.1 or below), you can check the <a href="https://cran-archive.r-project.org/bin/">CRAN binary
archive</a>. Once you have the URL, you can install it using a command
similar to the example below:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-R">packageurl <span style="font-weight: bold; text-decoration: underline;">&lt;-</span> <span style="font-style: italic;">"https://cran-archive.r-project.org/bin/windows/contrib/2.13/BBmisc_1.0-58.zip"</span>
install.packages(packageurl, repos=<span style="font-weight: bold; text-decoration: underline;">NULL</span>, type=<span style="font-style: italic;">"binary"</span>)
</pre>
</div>
</div>
</div>
<div id="outline-container-org7d8a9f0" class="outline-4">
<h4 id="org7d8a9f0">Using devtools</h4>
<div class="outline-text-4" id="text-org7d8a9f0">
<p>
The simplest method to install the version you need is to use the
<code>install_version()</code> function of the <code>devtools</code> package (obviously, you
need to install <code>devtools</code> first, which can be done by running in <code>R</code> the
command <code>install.packages("devtools")</code>). For instance:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-R"><span style="font-weight: bold; text-decoration: underline;">require</span>(devtools)
install_version(<span style="font-style: italic;">"ggplot2"</span>, version = <span style="font-style: italic;">"0.9.1"</span>, repos = <span style="font-style: italic;">"http://cran.us.r-project.org"</span>)
</pre>
</div>
</div>
</div>
<div id="outline-container-org4509fba" class="outline-4">
<h4 id="org4509fba">Installing from source code</h4>
<div class="outline-text-4" id="text-org4509fba">
<p>
Alternatively, you may want to install an older package from source If
devtools fails or if you do not want to depend on it, you can install
it from source via <code>install.packages()</code> directed using the right
URL. This URL can be obtained by browsing the <a href="https://cran.r-project.org/src/contrib/Archive">CRAN Package Archive</a>.
</p>
<p>
Once you have the URL, you can install it using a command similar to
the example below:
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-R">packageurl <span style="font-weight: bold; text-decoration: underline;">&lt;-</span> <span style="font-style: italic;">"http://cran.r-project.org/src/contrib/Archive/ggplot2/ggplot2_0.9.1.tar.gz"</span>
install.packages(packageurl, repos=<span style="font-weight: bold; text-decoration: underline;">NULL</span>, type=<span style="font-style: italic;">"source"</span>)
</pre>
</div>
<p>
If you know the URL, you can also install from source via the command
line outside of R. For instance (in bash):
</p>
<div class="org-src-container">
<pre style="padding-left: 30px; background-color: #f6f8fa;" class="src src-shell">wget http://cran.r-project.org/src/contrib/Archive/ggplot2/ggplot2_0.9.1.tar.gz
R CMD INSTALL ggplot2_0.9.1.tar.gz
</pre>
</div>
</div>
</div>
<div id="outline-container-org9d64d25" class="outline-4">
<h4 id="org9d64d25">Potential issues</h4>
<div class="outline-text-4" id="text-org9d64d25">
<p>
There are a few potential issues that may arise with installing older
versions of packages:
</p>
<ul class="org-ul">
<li style="margin-bottom:0;">You may be losing functionality or bug fixes that are only present
in the newer versions of the packages.</li>
<li style="margin-bottom:0;">The older package version needed may not be compatible with the
version of R you have installed. In this case, you will either need
to downgrade R to a compatible version or update your R code to work
with a newer version of the package.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
# -*- mode: org -*-
#+TITLE: Tracking environment information
#+AUTHOR: Arnaud Legrand
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Table of Contents :TOC:
- [[#getting-information-about-your-git-repository][Getting information about your Git repository]]
- [[#getting-information-about-python3-libraries][Getting information about Python(3) libraries]]
- [[#getting-information-about-your-system][Getting information about your system]]
- [[#getting-the-list-of-installed-packages-and-their-version][Getting the list of installed packages and their version]]
- [[#how-to-list-imported-modules][How to list imported modules?]]
- [[#saving-and-restoring-an-environment-with-pip][Saving and restoring an environment with pip]]
- [[#installing-a-new-package-or-a-specific-version][Installing a new package or a specific version]]
- [[#getting-information-about-r-libraries][Getting information about R libraries]]
- [[#getting-the-list-imported-modules-and-their-version][Getting the list imported modules and their version]]
- [[#getting-the-list-of-installed-packages-and-their-version-1][Getting the list of installed packages and their version]]
- [[#installing-a-new-package-or-a-specific-version-1][Installing a new package or a specific version]]
* Getting information about your Git repository
When taking notes, it may be difficult to remember which version of
the code or of a file was used. This is what version control is useful
......@@ -76,7 +88,7 @@ Delta compression using up to 4 threads.
Compressing objects: 100% (20/20), done.
Writing objects: 100% (25/25), 7.31 KiB | 499.00 KiB/s, done.
Total 25 (delta 11), reused 0 (delta 0)
To ssh://app-learninglab.inria.fr:9418/learning-lab/mooc-rr-ressources.git
To gitlab.inria.fr:learninglab/mooc-rr/mooc-rr-ressources.git
6359f8c..1f8a567 master -> master
#+END_EXAMPLE
......
# -*- mode: org -*-
#+TITLE: Informations sur l'environnement
#+AUTHOR: Arnaud Legrand
#+TITLE: Bien contrôler son environnement logiciel
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Table des matières
- Obtenir des informations sur votre dépôt Git
- Obtenir des informations sur les librairies Python 3
- Obtenir des informations sur les packages R
* Table des matières :TOC:
- [[#obtenir-des-informations-sur-votre-dépôt-git][Obtenir des informations sur votre dépôt Git]]
- [[#obtenir-des-informations-sur-les-librairies-python-3][Obtenir des informations sur les librairies Python 3]]
- [[#obtenir-des-informations-sur-votre-système][Obtenir des informations sur votre système]]
- [[#lister-les-packages-installés-et-leur-version][Lister les packages installés et leur version]]
- [[#lister-les-packages-importés-chargés-dans-une-session-python-et-leur-version][Lister les packages importés (chargés dans une session Python) et leur version]]
- [[#sauvegarder-et-restaurer-un-environnement-avec-pip][Sauvegarder et restaurer un environnement avec pip]]
- [[#installer-un-nouveau-package-ou-une-version-spécifique][Installer un nouveau package ou une version spécifique]]
- [[#obtenir-des-informations-sur-les-packages-r][Obtenir des informations sur les packages R]]
- [[#lister-les-packages-installés-et-leur-version-1][Lister les packages installés et leur version]]
- [[#lister-les-packages-importés-chargés-dans-une-session-r-et-leur-version][Lister les packages importés (chargés dans une session R) et leur version]]
- [[#installer-un-nouveau-package-ou-une-version-spécifique-1][Installer un nouveau package ou une version spécifique]]
* Obtenir des informations sur votre dépôt Git
Lorsqu'on prend des notes, il peut être difficile de se rappeler
......@@ -82,7 +89,7 @@ Delta compression using up to 4 threads.
Compressing objects: 100% (20/20), done.
Writing objects: 100% (25/25), 7.31 KiB | 499.00 KiB/s, done.
Total 25 (delta 11), reused 0 (delta 0)
To ssh://app-learninglab.inria.fr:9418/learning-lab/mooc-rr-ressources.git
To gitlab.inria.fr:learninglab/mooc-rr/mooc-rr-ressources.git
6359f8c..1f8a567 master -> master
#+END_EXAMPLE
......@@ -473,4 +480,4 @@ d'anciennes versions de packages :
avec la version de R que vous avez installée. Dans ce cas, vous
devrez soit rétrograder R vers une version compatible, soit mettre à
jour votre code R pour qu'il fonctionne avec une version plus
récente du package.
\ No newline at end of file
récente du package.
<div id="content">
<h1 class="title">Additional references</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul style="margin:0 0;">
<li style="margin-bottom:0;"><a href="#org3b8ed57">"Thoughts" on language/software stability</a></li>
<li style="margin-bottom:0;"><a href="#org1d2d532">Controlling your software environment</a></li>
<li style="margin-bottom:0;"><a href="#org50da419">Preservation/Archiving</a></li>
<li style="margin-bottom:0;"><a href="#org5d2f9e5">Workflows</a></li>
<li style="margin-bottom:0;"><a href="#orgad41259">Numerical and statistical issues</a></li>
<li style="margin-bottom:0;"><a href="#org7321a51">Publication practices</a></li>
<li style="margin-bottom:0;"><a href="#orge4adad6">Experimentation</a></li>
</ul>
</div>
</div>
<div id="outline-container-org3b8ed57" class="outline-2">
<h2 id="org3b8ed57">"Thoughts" on language/software stability</h2>
<div class="outline-text-2" id="text-org3b8ed57">
<p>
As we explained, the programming language used in an analysis has a
clear influence on the reproducibility of your analysis. It is not a
characteristic of the language itself but rather a consequence of the
development philosophy of the underlying community. For example C is a
very stable language with a <a href="https://en.wikipedia.org/wiki/C_(programming_language)#ANSI_C_and_ISO_C">very clear specification designed by a
committee</a> (even though some compilers may not respect this norm).
</p>
<p>
On the other end of the spectrum, <a href="https://en.wikipedia.org/wiki/Python_(programming_language)">Python</a> had a much more organic
development based on a readability philosophy and valuing continuous
improvement over backwards-compatibility. Furthermore, Python is
commonly used as a wrapping language (e.g., to easily use C or FORTRAN
libraries) and has its own packaging system. All these design choices
tend to make reproducibility often a bit painful with Python, even
though the community is slowly taking this into account. The transition from Python 2 to the not fully backwards compatible Python 3 has been a particularly painful process, not least because the two languages are so similar that is it not always easy to figure out if a given script or module is written in Python 2 or Python 3. It isn't even rare to see Python scripts that work under both Python 2 and Python 3, but produce different results due to the change in the behavior of integer division.
</p>
<p>
<a href="https://en.wikipedia.org/wiki/R_(programming_language)">R</a>, in comparison is much closer (in terms of developer community) to
languages like <a href="https://en.wikipedia.org/wiki/SAS_(software)">SAS</a>, which is heavily used in the pharmaceutical
industry where statistical procedures need to be standardized and rock
solid/stable. R is obviously not immune to evolutions that break old
versions and hinder reproducibility/backward compatibility. Here is a
relatively recent <a href="http://members.cbio.mines-paristech.fr/~thocking/HOCKING-reproducible-research-with-R.html">true story about this</a> and some colleagues who worked
on the <a href="https://www.fun-mooc.fr/courses/UPSUD/42001S06/session06/about">statistics introductory course with R on FUN</a> reported us
several issues with a few functions (<code>plotmeans</code> from <code>gplots</code>,
<code>survfit</code> from <code>survival</code>, or <code>hclust</code>) whose default parameters had
changed over the years. It is thus probably good practice to give
explicit values for all parameters (which can be cumbersome) instead
of relying on default values, and to restrict your dependencies as much
as possible.
</p>
<p>
This being said, the R development community is generally quite
careful about stability. We (the authors of this MOOC) believe that open
source (which allows to inspect how computation is done and to
identify both mistakes and sources of non-reproducibility) is more
important than the rock solid stability of SAS, which is proprietary
software. Yet, if you really need to stay with SAS (similar solutions
probably exist for other languages as well), you should know that SAS
can be used within Jupyter using either the <a href="https://sassoftware.github.io/sas_kernel/">Python SASKernel</a> or the
<a href="https://sassoftware.github.io/saspy/">Python SASPy</a> package (step by step explanations about this are given
<a href="https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md">here</a>). Using such literate programming approach allied with systematic
version and environment control will always help.
</p>
</div>
</div>
<div id="outline-container-org1d2d532" class="outline-2">
<h2 id="org1d2d532">Controlling your software environment</h2>
<div class="outline-text-2" id="text-org1d2d532">
<p>
As we mentioned in the video sequences, there are several solutions to
control your environment:
</p>
<ul class="org-ul">
<li style="margin-bottom:0;">The easy (preserve the mess) ones: <a href="http://www.pgbovine.net/cde.html">CDE</a> or <a href="https://vida-nyu.github.io/reprozip/">ReproZip</a></li>
<li style="margin-bottom:0;">The more demanding (encourage cleanliness) where you start with a
clean environment and install only what's strictly necessary (and document it):
<ul class="org-ul">
<li style="margin-bottom:0;">The very well known <a href="https://www.docker.io/">Docker</a></li>
<li style="margin-bottom:0;"><a href="https://singularity.lbl.gov/">Singularity</a> or <a href="https://spack.io/">Spack</a>, which are more targeted toward the specific
needs of high performance computing users</li>
<li style="margin-bottom:0;"><a href="https://www.gnu.org/software/guix/">Guix</a>, <a href="https://nixos.org/">Nix</a> that are very clean (perfect?) solutions to this
dependency hell and which we recommend</li>
</ul></li>
</ul>
<p>
It may be hard to understand the difference between these different
approaches and decide which one is better in your context.
</p>
<p>
Here is a webinar where some of these tools are demoed in a
reproducible research context: <a href="https://github.com/alegrand/RR_webinars/blob/master/2_controling_your_environment/index.org">Controling your environment (by Michael
Mercier and Cristian Ruiz)</a>
</p>
<p>
You may also want to have a look at <a href="http://falsifiable.us/">the Popper conventions</a> (<a href="https://github.com/alegrand/RR_webinars/blob/master/11_popper/index.org">webinar by
Ivo Gimenez through google hangout</a>) or at the <a href="https://github.com/alegrand/RR_webinars/blob/master/7_publications/index.org">presentation of Konrad
Hinsen on Active Papers</a> (<a href="http://www.activepapers.org/">http://www.activepapers.org/</a>).
</p>
</div>
</div>
<div id="outline-container-org50da419" class="outline-2">
<h2 id="org50da419">Preservation/Archiving</h2>
<div class="outline-text-2" id="text-org50da419">
<p>
Ensuring software is properly archived, i.e, is safely stored so that
it can be accessed in a perennial way, can be quite tricky. If you
have never seen <a href="https://github.com/alegrand/RR_webinars/blob/master/5_archiving_software_and_data/index.org">Roberto Di Cosmo presenting the Software Heritage
project</a>, this is a must see. <a href="https://www.softwareheritage.org/">https://www.softwareheritage.org/</a>
</p>
<p>
For regular data, we highly recommend using <a href="https://www.zenodo.org/">https://www.zenodo.org/</a>
whenever the data is not sensitive.
</p>
</div>
</div>
<div id="outline-container-org5d2f9e5" class="outline-2">
<h2 id="org5d2f9e5">Workflows</h2>
<div class="outline-text-2" id="text-org5d2f9e5">
<p>
In the video sequences, we mentioned workflow managers (original application domain in parenthesis):
</p>
<ul class="org-ul">
<li style="margin-bottom:0;"><a href="https://galaxyproject.org/">Galaxy</a> (genomics), <a href="https://kepler-project.org/">Kepler</a> (ecology), <a href="https://taverna.apache.org/">Taverna</a> (bio-informatics), <a href="https://pegasus.isi.edu/">Pegasus</a>
(astronomy), <a href="http://cknowledge.org/">Collective Knowledge</a> (compiling optimization) ,
<a href="https://www.vistrails.org">VisTrails</a> (image processing)</li>
<li style="margin-bottom:0;">Light-weight: <a href="http://dask.pydata.org/">dask</a> (python), <a href="https://ropensci.github.io/drake/">drake</a> (R), <a href="http://swift-lang.org/">swift</a> (molecular biology),
<a href="https://snakemake.readthedocs.io/">snakemake</a> (like <code>make</code> but more expressive and in <code>python</code>) &#x2026;</li>
<li style="margin-bottom:0;">Hybrids: <a href="https://vatlab.github.io/sos-docs/">SOS-notebook</a>, &#x2026;</li>
</ul>
<p>
You may want to have a look at this webinar: <a href="https://github.com/alegrand/RR_webinars/blob/master/6_reproducibility_bioinformatics/index.org">Reproducible Science in
Bio-informatics: Current Status, Solutions and Research Opportunities
(by Sarah Cohen Boulakia, Yvan Le Bras and Jérôme Chopard).</a>
</p>
</div>
</div>
<div id="outline-container-orgad41259" class="outline-2">
<h2 id="orgad41259">Numerical and statistical issues</h2>
<div class="outline-text-2" id="text-orgad41259">
<p>
We have mentioned these topics in our MOOC but we could by no way
cover them properly. We only suggest here a few interesting talks
about this.
</p>
<ul class="org-ul">
<li style="margin-bottom:0;"><a href="https://github.com/alegrand/RR_webinars/blob/master/10_statistics_and_replication_in_HCI/index.org">In this talk, Pierre Dragicevic provides a nice illustration of the
consequences of statistical uncertainty and of how some concepts
(e.G. p-values) are commonly badly understood.</a></li>
<li style="margin-bottom:0;"><a href="https://github.com/alegrand/RR_webinars/blob/master/3_numerical_reproducibility/index.org">Nathalie Revol, Philippe Langlois and Stef Graillat present the main
challenges encountered when trying to achieve numerical
reproducibility and present recent research work on this topic.</a></li>
</ul>
</div>
</div>
<div id="outline-container-org7321a51" class="outline-2">
<h2 id="org7321a51">Publication practices</h2>
<div class="outline-text-2" id="text-org7321a51">
<p>
You may want to have a look at the following two webinars:
</p>
<ul class="org-ul">
<li style="margin-bottom:0;"><a href="https://github.com/alegrand/RR_webinars/blob/master/8_artifact_evaluation/index.org">Enabling open and reproducible research at computer systems’
conferences (by Grigori Fursin)</a>. In particular, this talk discusses
<i>artifact evaluation</i> that is becoming more and more popular.</li>
<li style="margin-bottom:0;"><a href="https://github.com/alegrand/RR_webinars/blob/master/7_publications/index.org">Publication Modes Favoring Reproducible Research (by Konrad Hinsen
and Nicolas Rougier)</a>. In this talk, the motivation for the <a href="http://rescience.github.io/">ReScience
journal</a> initiative are presented.</li>
<li style="margin-bottom:0;"><a href="https://www.youtube.com/watch?v=HuJ2G8rXHMs">Simine Vazire - When Should We be Skeptical of Scientific Claims?</a>,
which is discussing publication practices in social sciences and in
particular HARKing (Hypothesizing After the Results are Known),
p-hacking, etc.</li>
</ul>
</div>
</div>
<div id="outline-container-orge4adad6" class="outline-2">
<h2 id="orge4adad6">Experimentation</h2>
<div class="outline-text-2" id="text-orge4adad6">
<p>
Experimentation was not covered in this MOOC, although it is an
essential part of science. The main reason is that practices and
constraints can vary so wildly from one domain to another that it could
not be properly covered in a first edition. We would be happy to
gather references you consider as interesting in your domain so do not
hesitate to provide us with such references by using the forum and we
will update this page.
</p>
<ul class="org-ul">
<li style="margin-bottom:0;"><a href="https://github.com/alegrand/RR_webinars/blob/master/9_experimental_testbeds/index.org">A recent talk by Lucas Nussbaum on Experimental Testbeds in Computer
Science</a>.</li>
</ul>
</div>
</div>
</div>
# -*- mode: org -*-
#+TITLE: Additional references
#+AUTHOR: Arnaud Legrand
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Table of Contents :TOC:
- [[#thoughts-on-languagesoftware-stability]["Thoughts" on language/software stability]]
- [[#controlling-your-software-environment][Controlling your software environment]]
- [[#preservationarchiving][Preservation/Archiving]]
- [[#workflows][Workflows]]
- [[#numerical-and-statistical-issues][Numerical and statistical issues]]
- [[#publication-practices][Publication practices]]
- [[#experimentation][Experimentation]]
* "Thoughts" on language/software stability
As we explained, the programming language used in an analysis has a
clear influence on the reproducibility of your analysis. It is not a
......@@ -46,7 +54,7 @@ software.
Yet, if you really need to stay with SAS, you should know that SAS can be used
within Jupyter using the [[https://sassoftware.github.io/saspy/][Python SASPy]] and the
[[https://sassoftware.github.io/sas_kernel/][Python SASKernel]] packages (step by step explanations about this are given
[[https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#53-le-package-python-saspy-permet-dex%C3%A9cuter-du-code-sas-dans-un-notebook-python][here]]). Using such literate programming approach allied with systematic
[[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#53-le-package-python-saspy-permet-dex%C3%A9cuter-du-code-sas-dans-un-notebook-python][here]]). Using such literate programming approach allied with systematic
version and environment control will always help. Similar solutions exist for many languages ([[https://github.com/jupyter/jupyter/wiki/Jupyter-kernels][list of Jupyter kernels]]).
* Controlling your software environment
As we mentioned in the video sequences, there are several solutions to
......@@ -54,11 +62,11 @@ control your environment:
- The easy (preserve the mess) ones: [[http://www.pgbovine.net/cde.html][CDE]] or [[https://vida-nyu.github.io/reprozip/][ReproZip]]
- The more demanding (encourage cleanliness) where you start with a
clean environment and install only what's strictly necessary (and document it):
- The very well known [[https://www.docker.io/][Docker]]
- The very well known [[https://www.docker.io/][Docker]];
- [[https://singularity.lbl.gov/][Singularity]] or [[https://spack.io/][Spack]], which are more targeted toward the specific
needs of high performance computing users
needs of high performance computing users;
- [[https://www.gnu.org/software/guix/][Guix]], [[https://nixos.org/][Nix]] that are very clean (perfect?) solutions to this
dependency hell and which we recommend
dependency hell and which we recommend.
It may be hard to understand the difference between these different
approaches and decide which one is better in your context.
......@@ -95,12 +103,8 @@ Bio-informatics: Current Status, Solutions and Research Opportunities
We have mentioned these topics in our MOOC but we could by no way
cover them properly. We only suggest here a few interesting talks
about this.
- [[https://github.com/alegrand/RR_webinars/blob/master/10_statistics_and_replication_in_HCI/index.org][In this talk, Pierre Dragicevic provides a nice illustration of the
consequences of statistical uncertainty and of how some concepts
(e.G. p-values) are commonly badly understood.]]
- [[https://github.com/alegrand/RR_webinars/blob/master/3_numerical_reproducibility/index.org][Nathalie Revol, Philippe Langlois and Stef Graillat present the main
challenges encountered when trying to achieve numerical
reproducibility and present recent research work on this topic.]]
- [[https://github.com/alegrand/RR_webinars/blob/master/10_statistics_and_replication_in_HCI/index.org][In this talk, Pierre Dragicevic provides a nice illustration of the consequences of statistical uncertainty and of how some concepts (e.g., p-values) are commonly badly understood.]]
- [[https://github.com/alegrand/RR_webinars/blob/master/3_numerical_reproducibility/index.org][Nathalie Revol, Philippe Langlois and Stef Graillat present the main challenges encountered when trying to achieve numerical reproducibility and present recent research work on this topic.]]
* Publication practices
You may want to have a look at the following two webinars:
- [[https://github.com/alegrand/RR_webinars/blob/master/8_artifact_evaluation/index.org][Enabling open and reproducible research at computer systems’
......
# -*- mode: org -*-
#+TITLE: Références complémentaires
#+AUTHOR: Arnaud Legrand
#+DATE: June, 2018
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Table des matières :TOC:
- [[#réflexions-sur-la-stabilité-des-langages-de-programmation][Réflexions sur la stabilité des langages de programmation]]
- [[#contrôler-votre-environnement-logiciel][Contrôler votre environnement logiciel]]
- [[#préservationarchivage][Préservation/Archivage]]
- [[#workflows][Workflows]]
- [[#problèmes-numériques-et-statistiques][Problèmes numériques et statistiques]]
- [[#pratiques-de-publication][Pratiques de publication]]
- [[#expérimentation][Expérimentation]]
* Réflexions sur la stabilité des langages de programmation
Comme nous l'avons expliqué, le langage de programmation utilisé dans
une analyse a une influence évidente sur la reproductibilité de
......@@ -33,12 +41,12 @@ Python 3, mais produisent des résultats différents en raison du
changement de comportement de la division entière.
[[https://en.wikipedia.org/wiki/R_(programming_language)][R]], en comparaison, est beaucoup plus proche (en termes de communauté
de développeurs) de langages comme [[https://en.wikipedia.org/wiki/SAS_(logiciel)][SAS]], très utilisé dans l'industrie
de développeurs) de langages comme [[https://fr.wikipedia.org/wiki/SAS_(langage)][SAS]], très utilisé dans l'industrie
pharmaceutique où les procédures statistiques doivent être
standardisées et stables/solides. R n’est évidemment pas à l’abri des
évolutions qui cassent les anciennes versions et gênent la
reproductibilité/compatibilité avec les versions antérieures. Voici
une [[http://members.cbio.mines-paristech.fr//thocking/HOCKING-reproducible-research-with-R.html][véritable histoire relativement récente à ce sujet]] et des
une [[http://members.cbio.mines-paristech.fr/~thocking/HOCKING-reproducible-research-with-R.html][véritable histoire relativement récente à ce sujet]] et des
collègues qui ont travaillé sur le [[https://www.fun-mooc.fr/courses/course-v1:UPSUD+42001+session10/about][MOOC d'initiation à la statistique
avec R sur FUN]] nous ont signalé plusieurs problèmes concernant
quelques fonctions (=gplots::plotmeans=, =survival::survfit= ou =hclust=)
......@@ -58,7 +66,7 @@ propriétaire.
Cependant, si vous avez vraiment besoin de rester sous
SAS, sachez que SAS peut être utilisé dans Jupyter en utilisant
les packages Python [[https://sassoftware.github.io/saspy/][SASPy]] et [[https://sassoftware.github.io/sas_kernel/][SASKernel]] (tuto pas à pas
[[https://app-learninglab.inria.fr/gitlab/85bc36e0a8096c618fbd5993d1cca191/mooc-rr/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#53-le-package-python-saspy-permet-dex%C3%A9cuter-du-code-sas-dans-un-notebook-python][ici]]). L'utilisation d'une telle approche de programmation
[[https://gitlab.inria.fr/learninglab/mooc-rr/mooc-rr-ressources/blob/master/documents/tuto_jupyter_windows/tuto_jupyter_windows.md#53-le-package-python-saspy-permet-dex%C3%A9cuter-du-code-sas-dans-un-notebook-python][ici]]). L'utilisation d'une telle approche de programmation
alphabète alliée à un contrôle systématique de la version et de
l'environnement est un plus. Des solutions similaires existent pour de
nombreux langages ([[https://github.com/jupyter/jupyter/wiki/Jupyter-kernels][liste des kernels Jupyter]]).
......@@ -70,11 +78,11 @@ solutions permettent de contrôler votre environnement :
- Les plus exigeants (encourageant la propreté) où vous commencez avec un
environnement propre et n’installez que ce qui est strictement
nécessaire (et le documentez) :
- Le très connu [[https://www.docker.io/][Docker]]
- Le très connu [[https://www.docker.io/][Docker]];
- [[https://singularity.lbl.gov/][Singularity]] ou [[https://spack.io/][Spack]], qui sont plus ciblés sur les besoins
spécifiques des utilisateurs d'informatique de haute performance
spécifiques des utilisateurs d'informatique de haute performance;
- [[https://www.gnu.org/software/guix/][Guix]], [[https://nixos.org/][Nix]] qui sont des solutions très propres (parfaites ?) à cet
enfer de dépendance et que nous recommandons
enfer de dépendance et que nous recommandons.
Il peut être difficile de comprendre la différence entre ces
différentes approches et de décider laquelle est la meilleure dans
......@@ -117,13 +125,8 @@ Jérôme Chopard)]].
Nous avons mentionné ces sujets dans notre MOOC mais nous ne pourrions
en aucun cas les couvrir correctement. Nous ne suggérons ici que
quelques présentations intéressantes à ce sujet.
- [[https://github.com/alegrand/RR_webinars/blob/master/10_statistics_and_replication_in_HCI/index.org][Pierre Dragicevic donne une belle illustration des conséquences de
l’incertitude statistique et de la manière dont certains concepts
(par exemple les p-values) sont généralement mal compris]].
- [[https://github.com/alegrand/RR_webinars/blob/master/3_numerical_reproducibility/index.org][Nathalie Revol, Philippe Langlois et Stef Graillat présentent les
principaux problèmes rencontrés en essayant d'obtenir une
reproductibilité numérique et présentent les travaux de recherche
récents en la matière]].
- [[https://github.com/alegrand/RR_webinars/blob/master/10_statistics_and_replication_in_HCI/index.org][Pierre Dragicevic donne une belle illustration des conséquences de l'incertitude statistique et de la manière dont certains concepts par exemple les p-values) sont généralement mal compris]].
- [[https://github.com/alegrand/RR_webinars/blob/master/3_numerical_reproducibility/index.org][Nathalie Revol, Philippe Langlois et Stef Graillat présentent les principaux problèmes rencontrés en essayant d'obtenir une reproductibilité numérique et présentent les travaux de recherche récents en la matière]].
* Pratiques de publication
Vous souhaiterez peut-être consulter les webinaires suivants :
......@@ -149,4 +152,4 @@ références que vous jugez intéressantes dans votre domaine. N'hésitez
donc pas à nous les fournir à l'aide du forum. Nous les intégrerons
dans cette page.
- [[https://github.com/alegrand/RR_webinars/blob/master/9_experimental_testbeds/index.org][Une récente conférence de Lucas Nussbaum sur les bancs d’essais expérimentaux en informatique]].
- [[https://github.com/alegrand/RR_webinars/blob/master/9_experimental_testbeds/index.org][Une récente conférence de Lucas Nussbaum sur les plates-formes expérimentales en informatique]].
This source diff could not be displayed because it is too large. You can view the blob instead.
# -*- mode: org -*-
#+TITLE: Contrôler un environnement logiciel avec Guix
#+DATE: Février 2020
#+STARTUP: overview indent
#+OPTIONS: num:nil toc:t
#+PROPERTY: header-args :eval never-export
* Point de départ
Pour utiliser Guix, il faut évidemment l'installer. Il y a deux façons d'y arriver:
1. Installer [[https://guix.gnu.org/manual/en/html_node/System-Installation.html][Guix System]] sur votre ordinateur, à la place d'une distribution Linux plus traditionnelle comme Debian ou Ubuntu. Tout votre système est alors géré avec Guix, ce qui a des avantages (notamment la reproductibilité totale de votre configuration), mais aussi des inconvénients (il y a moins que logiciels disponibles pour Guix que pour une vieille distribution genre Debian). Vous pouvez bien sûr installer Guix dans une machine virtuelle.
2. Installer seulement [[https://guix.gnu.org/manual/en/html_node/Binary-Installation.html][le gestionnaire de paquets Guix]] sur un ordinateur qui tourne déjà sous Linux. Vous pouvez alors utiliser Guix en parallèle avec le gestionnaire de paquets de votre distribution, ce qui donne beaucoup de flexibilité, mais il faut bien sûr faire attention à quel paquet est installé comment, et éviter des doublons. Python est particulièrement problématique, parce que la coexistence de plusieurs installations de Python nécessite quelques précautions (qui n'ont rien à voir avec Guix d'ailleurs). Votre distribution Python a fort probablement déjà une installation Python, et ce tutoriel vous fera travailler avec un Python fourni par Guix, ce qui crée la possibilité d'un conflit. Si vous rencontrez des difficultés que vous ne pouvez pas résoudre (normalement le résultat d'une configuration personnalisée par $PATH et/ou $PYTHONPATH), perséverez : dès que vous arrivez au point ou je commence à utiliser "guix environment", ça devrait fonctionner quand-même (c'est fait pour!).
D'abord, quelques mots sur le fonctionnement de Guix pour les habitués de Linux - si vous ne comprenez pas ces explications, ce n'est pas grave pour la suite. La gestion traditionnelle des logiciels sous Linux est basé sur des conventions définissant l'emplacement des fichiers. Par exemple, les exécutables se trouve sous =/bin=, =/usr/bin=, et =/usr/local/bin=. Ce genre de convention est très contraignant parce qu'elle vous empêche d'installer facilement plusieurs versions d'un même logiciel.
Guix fonctionne autrement: il place tous les fichiers sous =/gnu/store=, ou chaque paquet à son sous-répertoire avec un nom très long et très bizarre comme par example =/gnu/store/kwf1gzgk7f0l1sz84d0frrfvlqysnbz7-jupyter-1.0.0=. Les 32 permiers caractères de ces noms de ces sous-répertoires sont en fait une somme de contrôle calculé sur le code source du logiciel et de toutes ses dépendances. Si vous installez Jupyter 1.0.0 avec une autre version de Python, cette somme de contrôle change, et elle change même si vous compilez Python avec une autre version de =gcc=. C'est comme ça que Guix permet la coëxistence de plusieurs versions.
Sur cette base, Guix introduit des /profils/, qui remplacent la collection conventionnelle des répertoires comme =/bin=, =/lib=, =/etc= etc. A l'intérieur d'un profil, vous retrouvez ces répertoires, mais leur contenu ne consiste que de liens symboliques vers les paquets sous =/gnu/store=. Chaque utilisateur a son profil personnel, sous =$HOME/.guix-profile=. C'est comme ça que chaque utilisateur peut gèrer sa propre collection de logiciels, sans dépendre d'un administrateur pour les installer ou mettre à jour. Et comme les profils sont légers, on peut en définir d'autres à volonté (mais je n'en parle pas dans ce tutoriel). On peut aussi travailler avec des profils ephémères qui s'appellent "environnements". C'est cette approche que j'ai choisi pour ce tutoriel.
* Séquence 2: Créer son propre environnement, automatiser sa construction et le partage
** 2.2 Installer tous les paquets dont on a besoin
Une installation Guix de base ne contient même pas python,
il va donc falloir l'installer ainsi que =jupyter= et différents paquets
comme =matplotlib=, =pandas=, =numpy=, =statsmodels=... L'installation
se fait à l'aide de la commande =guix install <nom_du_paquet>=. Comment
faire pour trouver le nom du paquet Guix qui contient ce qui vous intéresse ?
Avec la commande =guix search "<un truc lié au nom de ce que vous cherchez>"=.
D'abord, je cherche tout ce qui a trait à jupyter
#+begin_src shell :session *docker* :results output :exports both
guix search jupyter
#+end_src
#+RESULTS:
#+begin_example
name: jupyter
version: 1.0.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-ipykernel@5.1.3 python-ipywidgets@5.2.2
+ python-jupyter-console@6.0.0 python-nbconvert@5.0.0b1 python-notebook@5.7.4
+ python-qtconsole@4.4.3
location: gnu/packages/python-xyz.scm:8070:2
homepage: https://jupyter.org
license: Modified BSD
synopsis: Web application for interactive documents
description: The Jupyter Notebook is a web application that allows you
+ to create and share documents that contain live code, equations,
+ visualizations and explanatory text. Uses include: data cleaning and
+ transformation, numerical simulation, statistical modeling, machine
+ learning and much more.
relevance: 22
hint: Run `guix search ... | less' to view all the results.
#+end_example
C'est déjà prometteur, mais voyons comme proposé la totalité des résultats. Dans Emacs, nous remplaçons =less= par =cat=:
#+begin_src sh :results output :exports both
guix search jupyter | cat
#+end_src
#+RESULTS:
#+begin_example
name: jupyter
version: 1.0.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-ipykernel@5.1.3 python-ipywidgets@5.2.2
+ python-jupyter-console@6.0.0 python-nbconvert@5.0.0b1 python-notebook@5.7.4
+ python-qtconsole@4.4.3
location: gnu/packages/python-xyz.scm:8070:2
homepage: https://jupyter.org
license: Modified BSD
synopsis: Web application for interactive documents
description: The Jupyter Notebook is a web application that allows you
+ to create and share documents that contain live code, equations,
+ visualizations and explanatory text. Uses include: data cleaning and
+ transformation, numerical simulation, statistical modeling, machine
+ learning and much more.
relevance: 22
name: python-jupyter-kernel-test
version: 0.3
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-jsonschema@3.0.1 python-jupyter-kernel-mgmt@0.4.0
+ python-jupyter-protocol@0.1.1
location: gnu/packages/jupyter.scm:98:2
homepage: https://github.com/jupyter/jupyter_kernel_test
license: Modified BSD
synopsis: Test Jupyter kernels
description: `jupyter_kernel_test' is a tool for testing Jupyter
+ kernels. It tests kernels for successful code execution and conformance
+ with the Jupyter Messaging Protocol
+ (https://jupyter-client.readthedocs.io/en/latest/messaging.html).
relevance: 20
name: xeus
version: 0.23.2
outputs: out
systems: x86_64-linux i686-linux
dependencies: cppzmq@4.2.2-0.d9f0f01 googletest@1.10.0 json-modern-cxx@3.7.3
+ openssl@1.1.1c pkg-config@0.29.2 python-jupyter-client@5.2.4
+ python-jupyter-kernel-test@0.3 python-pytest@4.4.2 python@3.7.4
+ util-linux@2.34 xtl@0.6.8 zeromq@4.3.2
location: gnu/packages/jupyter.scm:142:2
homepage: https://quantstack.net/xeus
license: Modified BSD
synopsis: C++ implementation of the Jupyter Kernel protocol
description: `xeus' is a library meant to facilitate the implementation
+ of kernels for Jupyter. It takes the burden of implementing the Jupyter
+ Kernel protocol so developers can focus on implementing the interpreter
+ part of the kernel.
+
+ Several Jupyter kernels are built upon `xeus', such as `xeus-cling', a
+ kernel for the C++ programming language, and `xeus-python', an
+ alternative Python kernel for Jupyter.
relevance: 16
name: python-jupyter-protocol
version: 0.1.1
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-dateutil@2.8.0 python-ipykernel@5.1.3
+ python-ipython@7.9.0 python-jupyter-core@4.4.0 python-mock@2.0.0
+ python-pytest@4.4.2 python-pyzmq@17.1.2 python-traitlets@4.3.3
location: gnu/packages/jupyter.scm:37:2
homepage: https://jupyter.org
license: Modified BSD
synopsis: Jupyter protocol implementation
description: This Python library is an experimental implementation of
+ the Jupyter protocol
+ (https://jupyter-client.readthedocs.io/en/latest/messaging.html) to be
+ used by both clients and kernels.
relevance: 16
name: python2-jupyter-client
version: 5.2.4
outputs: out
systems: x86_64-linux i686-linux
dependencies: iproute2@5.5.0 python2-jupyter-core@4.4.0 python2-pyzmq@17.1.2
+ python2-traitlets@4.3.3
location: gnu/packages/python-xyz.scm:5302:2
homepage: http://jupyter.org/
license: Modified BSD
synopsis: Jupyter protocol implementation and client libraries
description: The `jupyter_client' package contains the reference
+ implementation of the Jupyter protocol. It also provides client and
+ kernel management APIs for working with kernels, and the `jupyter
+ kernelspec' entrypoint for installing `kernelspec's for use with Jupyter
+ frontends.
relevance: 15
name: python-jupyter-client
version: 5.2.4
outputs: out
systems: x86_64-linux i686-linux
dependencies: iproute2@5.5.0 python-jupyter-core@4.4.0 python-pyzmq@17.1.2
+ python-traitlets@4.3.3
location: gnu/packages/python-xyz.scm:5302:2
homepage: http://jupyter.org/
license: Modified BSD
synopsis: Jupyter protocol implementation and client libraries
description: The `jupyter_client' package contains the reference
+ implementation of the Jupyter protocol. It also provides client and
+ kernel management APIs for working with kernels, and the `jupyter
+ kernelspec' entrypoint for installing `kernelspec's for use with Jupyter
+ frontends.
relevance: 15
name: python-jupyter-kernel-mgmt
version: 0.4.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-dateutil@2.8.0 python-entrypoints@0.3
+ python-ipykernel@5.1.3 python-ipython@7.9.0 python-jupyter-core@4.4.0
+ python-jupyter-protocol@0.1.1 python-mock@2.0.0 python-pytest@4.4.2
+ python-pyzmq@17.1.2 python-traitlets@4.3.3
location: gnu/packages/jupyter.scm:67:2
homepage: https://jupyter.org
license: Modified BSD
synopsis: Discover, launch, and communicate with Jupyter kernels
description: This package is an experimental refactoring of the
+ machinery for launching and using Jupyter kernels.
relevance: 14
name: guix-jupyter
version: 0.1.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: autoconf@2.69 automake@1.16.1 guile-gcrypt@0.2.1
+ guile-json@3.2.0 guile-simple-zmq@0.0.0-3.68bedb6 guile@2.2.6
+ guix@1.0.1-13.50299ad jupyter@1.0.0 pkg-config@0.29.2 python-ipykernel@5.1.3
+ python-ipython@7.9.0
location: gnu/packages/package-management.scm:820:2
homepage: https://gitlab.inria.fr/guix-hpc/guix-kernel
license: GPL 3+
synopsis: Guix kernel for Jupyter
description: Guix-Jupyter is a Jupyter kernel. It allows you to
+ annotate notebooks with information about their software dependencies,
+ such that code is executed in the right software environment.
+ Guix-Jupyter spawns the actual kernels such as `python-ipykernel' on
+ behalf of the notebook user and runs them in an isolated environment, in
+ separate namespaces.
relevance: 13
name: python2-jupyter-core
version: 4.4.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: python2-traitlets@4.3.3
location: gnu/packages/python-xyz.scm:5277:2
homepage: http://jupyter.org/
license: Modified BSD
synopsis: Jupyter base package
description: Jupyter core is the base package on which Jupyter projects
+ rely.
relevance: 11
name: python2-jupyter-console
version: 5.2.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: python2-ipykernel@5.1.0 python2-jupyter-client@5.2.4
+ python2-nose@1.3.7 python2-prompt-toolkit@1.0.15 python2-pygments@2.5.2
location: gnu/packages/python-xyz.scm:7941:2
homepage: https://jupyter.org
license: Modified BSD
synopsis: Jupyter terminal console
description: This package provides a terminal-based console frontend for
+ Jupyter kernels. It also allows for console-based interaction with
+ non-Python Jupyter kernels such as IJulia and IRKernel.
relevance: 11
name: python-jupyter-core
version: 4.4.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-traitlets@4.3.3
location: gnu/packages/python-xyz.scm:5277:2
homepage: http://jupyter.org/
license: Modified BSD
synopsis: Jupyter base package
description: Jupyter core is the base package on which Jupyter projects
+ rely.
relevance: 11
name: python-jupyter-console
version: 6.0.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-ipykernel@5.1.3 python-jupyter-client@5.2.4
+ python-nose@1.3.7 python-prompt-toolkit@2.0.7 python-pygments@2.5.2
location: gnu/packages/python-xyz.scm:7915:2
homepage: https://jupyter.org
license: Modified BSD
synopsis: Jupyter terminal console
description: This package provides a terminal-based console frontend for
+ Jupyter kernels. It also allows for console-based interaction with
+ non-Python Jupyter kernels such as IJulia and IRKernel.
relevance: 11
name: jupyter-guile-kernel
version: 0.0.0-1.a7db924
outputs: out
systems: x86_64-linux i686-linux
dependencies: guile-json@1.2.0 guile-simple-zmq@0.0.0-3.68bedb6 guile@2.2.6
+ openssl@1.1.1c
location: gnu/packages/guile-xyz.scm:859:4
homepage: https://github.com/jerry40/guile-kernel
license: GPL 3+
synopsis: Guile kernel for the Jupyter Notebook
description: This package provides a Guile 2.x kernel for the Jupyter
+ Notebook. It allows users to interact with the Guile REPL through
+ Jupyter.
relevance: 11
name: python-pari-jupyter
version: 1.3.2
outputs: out
systems: x86_64-linux i686-linux
dependencies: pari-gp@2.11.2 python-ipykernel@5.1.3 readline@8.0
location: gnu/packages/python-xyz.scm:5423:2
homepage: https://github.com/jdemeyer/pari_jupyter
license: GPL 3+
synopsis: A Jupyter kernel for PARI/GP
description: The package provides a PARI/GP kernel for Jupyter.
relevance: 9
name: r-irkernel
version: 1.1
outputs: out
systems: x86_64-linux i686-linux
dependencies: jupyter@1.0.0 r-crayon@1.3.4 r-digest@0.6.23 r-evaluate@0.14
+ r-irdisplay@0.7.0 r-jsonlite@1.6 r-minimal@3.6.2 r-pbdzmq@0.3-3 r-repr@1.0.2
+ r-uuid@0.1-2
location: gnu/packages/cran.scm:12543:2
homepage: https://cran.r-project.org/web/packages/IRkernel/
license: Expat
synopsis: Native R kernel for Jupyter
description: The R kernel for the Jupyter environment executes R code
+ which the front-end (Jupyter Notebook or other front-ends) submits to
+ the kernel via the network.
relevance: 7
name: r-irdisplay
version: 0.7.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: r-repr@1.0.2
location: gnu/packages/cran.scm:12520:2
homepage: https://cran.r-project.org/web/packages/IRdisplay/
license: Expat
synopsis: Jupyter display machinery
description: This package provides an interface to the rich display
+ capabilities of Jupyter front-ends (e.g. Jupyter Notebook). It is
+ designed to be used from a running IRkernel session.
relevance: 7
name: ruby-iruby
version: 0.3
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-ipython@7.9.0 ruby-bond@0.5.1 ruby-cztop@0.12.2
+ ruby-data_uri@0.1.0 ruby-mimemagic@0.3.3 ruby-multi-json@1.13.1
+ ruby-pry@0.11.3
location: gnu/packages/ruby.scm:397:2
homepage: https://github.com/SciRuby/iruby
license: Expat
synopsis: Ruby kernel for Jupyter/IPython
description: This package provides a Ruby kernel for Jupyter/IPython
+ frontends (e.g. notebook).
relevance: 5
name: python2-widgetsnbextension
version: 3.4.2
outputs: out
systems: x86_64-linux i686-linux
dependencies: python2-certifi@2019.3.9 python2-ipykernel@5.1.3
+ python2-nose@1.3.7 python2-notebook@5.7.4
location: gnu/packages/python-xyz.scm:7858:2
homepage: https://ipython.org
license: Modified BSD
synopsis: IPython HTML widgets for Jupyter
description: This package provides interactive HTML widgets for Jupyter
+ notebooks.
relevance: 5
name: python2-nbformat
version: 4.4.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: python2-ipython-genutils@0.1.0 python2-jsonschema@3.0.1
+ python2-jupyter-core@4.4.0 python2-traitlets@4.3.3
location: gnu/packages/python-xyz.scm:7648:2
homepage: http://jupyter.org
license: Modified BSD
synopsis: Jupyter Notebook format
description: This package provides the reference implementation of the
+ Jupyter Notebook format and Python APIs for working with notebooks.
relevance: 5
name: python2-nbconvert
version: 5.0.0b1
outputs: out
systems: x86_64-linux i686-linux
dependencies: python2-bleach@3.1.0 python2-entrypoints@0.3
+ python2-jinja2@2.10.1 python2-jupyter-core@4.4.0 python2-mistune@0.8.4
+ python2-nbformat@4.4.0 python2-pygments@2.5.2 python2-pytest@4.4.2
+ python2-traitlets@4.3.3
location: gnu/packages/python-xyz.scm:7739:2
homepage: http://jupyter.org
license: Modified BSD
synopsis: Converting Jupyter Notebooks
description: The `nbconvert' tool, {jupyter nbconvert
relevance: 5
name: python2-ipywidgets
version: 5.2.2
outputs: out
systems: x86_64-linux i686-linux
dependencies: python2-ipython@7.9.0 python2-nose@1.3.7 python2-pytest@4.4.2
+ python2-traitlets@4.3.3 python2-widgetsnbextension@3.4.2
location: gnu/packages/python-xyz.scm:7885:2
homepage: https://ipython.org
license: Modified BSD
synopsis: IPython HTML widgets for Jupyter
description: Ipywidgets are interactive HTML widgets for Jupyter
+ notebooks and the IPython kernel. Notebooks come alive when interactive
+ widgets are used. Users gain control of their data and can visualize
+ changes in the data.
relevance: 5
name: python2-ipykernel
version: 5.1.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: python2-ipython@5.8.0 python2-jupyter-client@5.2.4
+ python2-nose@1.3.7 python2-pytest@4.4.2
location: gnu/packages/python-xyz.scm:5390:2
homepage: https://ipython.org
license: Modified BSD
synopsis: IPython Kernel for Jupyter
description: This package provides the IPython kernel for Jupyter.
relevance: 5
name: python-widgetsnbextension
version: 3.4.2
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-certifi@2019.3.9 python-ipykernel@5.1.3 python-nose@1.3.7
+ python-notebook@5.7.4
location: gnu/packages/python-xyz.scm:7858:2
homepage: https://ipython.org
license: Modified BSD
synopsis: IPython HTML widgets for Jupyter
description: This package provides interactive HTML widgets for Jupyter
+ notebooks.
relevance: 5
name: python-slurm-magic
version: 0.0-0.73dd1a2
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-ipython@7.9.0 python-pandas@0.25.2 slurm@19.05.3-2
location: gnu/packages/parallel.scm:222:4
homepage: https://github.com/NERSC/slurm-magic
license: Modified BSD
synopsis: Control the SLURM batch scheduler from Jupyter Notebook
description: This package implements Jupyter/IPython magic commands
+ (http://ipython.readthedocs.io/en/stable/interactive/magics.html) for
+ interacting with the SLURM workload manager. SLURM magic simply wraps
+ command-line executables and the commands themselves should look like
+ their command-line counterparts. Commands are spawned via `subprocess'
+ and output captured in the notebook. Whatever arguments are accepted by
+ a SLURM command line executable are also accepted by the corresponding
+ magic command---e.g., `%salloc', `%sbatch', etc.
relevance: 5
name: python-qtconsole
version: 4.4.3
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-ipykernel@5.1.3 python-ipython@7.9.0 python-pytest@4.4.2
location: gnu/packages/python-xyz.scm:7995:2
homepage: http://jupyter.org
license: Modified BSD
synopsis: Jupyter Qt console
description: This package provides a Qt-based console for Jupyter with
+ support for rich media output.
relevance: 5
name: python-nbformat
version: 4.4.0
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-ipython-genutils@0.1.0 python-jsonschema@3.0.1
+ python-jupyter-core@4.4.0 python-traitlets@4.3.3
location: gnu/packages/python-xyz.scm:7648:2
homepage: http://jupyter.org
license: Modified BSD
synopsis: Jupyter Notebook format
description: This package provides the reference implementation of the
+ Jupyter Notebook format and Python APIs for working with notebooks.
relevance: 5
name: python-nbconvert
version: 5.0.0b1
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-bleach@3.1.0 python-entrypoints@0.3 python-jinja2@2.10.1
+ python-jupyter-core@4.4.0 python-mistune@0.8.4 python-nbformat@4.4.0
+ python-pygments@2.5.2 python-pytest@4.4.2 python-traitlets@4.3.3
location: gnu/packages/python-xyz.scm:7739:2
homepage: http://jupyter.org
license: Modified BSD
synopsis: Converting Jupyter Notebooks
description: The `nbconvert' tool, {jupyter nbconvert
relevance: 5
name: python-ipywidgets
version: 5.2.2
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-ipython@7.9.0 python-nose@1.3.7 python-pytest@4.4.2
+ python-traitlets@4.3.3 python-widgetsnbextension@3.4.2
location: gnu/packages/python-xyz.scm:7885:2
homepage: https://ipython.org
license: Modified BSD
synopsis: IPython HTML widgets for Jupyter
description: Ipywidgets are interactive HTML widgets for Jupyter
+ notebooks and the IPython kernel. Notebooks come alive when interactive
+ widgets are used. Users gain control of their data and can visualize
+ changes in the data.
relevance: 5
name: python-ipykernel
version: 5.1.3
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-flaky@3.5.3 python-ipython@7.9.0
+ python-jupyter-client@5.2.4 python-nose@1.3.7 python-pytest@4.4.2
location: gnu/packages/python-xyz.scm:5346:2
homepage: https://ipython.org
license: Modified BSD
synopsis: IPython Kernel for Jupyter
description: This package provides the IPython kernel for Jupyter.
relevance: 5
name: ghc-ipynb
version: 0.1
outputs: out
systems: x86_64-linux i686-linux
dependencies: ghc-aeson-diff@1.1.0.7 ghc-aeson@1.4.5.0
+ ghc-base64-bytestring@1.0.0.2 ghc-microlens-aeson@2.3.0.4 ghc-microlens@0.4.10
+ ghc-semigroups@0.18.5 ghc-tasty-hunit@0.10.0.2 ghc-tasty@1.2.3
+ ghc-unordered-containers@0.2.10.0 ghc-vector@0.12.0.3
location: gnu/packages/haskell-xyz.scm:6170:2
homepage: https://hackage.haskell.org/package/ipynb
license: Modified BSD
synopsis: Data structure for working with Jupyter notebooks
description: This library defines a data structure for representing
+ Jupyter notebooks, along with `ToJSON' and `FromJSON' instances for
+ conversion to and from JSON .ipynb files.
relevance: 5
name: python2-ipython-genutils
version: 0.1.0
outputs: out
systems: x86_64-linux i686-linux
dependencies:
location: gnu/packages/python-xyz.scm:5209:2
homepage: https://ipython.org
license: Modified BSD
synopsis: Vestigial utilities from IPython
description: This package provides retired utilities from IPython. No
+ packages outside IPython/Jupyter should depend on it.
+
+ This package shouldn't exist. It contains some common utilities shared
+ by Jupyter and IPython projects during The Big Split. As soon as
+ possible, those packages will remove their dependency on this, and this
+ package will go away.
relevance: 4
name: python-ipython-genutils
version: 0.1.0
outputs: out
systems: x86_64-linux i686-linux
dependencies:
location: gnu/packages/python-xyz.scm:5209:2
homepage: https://ipython.org
license: Modified BSD
synopsis: Vestigial utilities from IPython
description: This package provides retired utilities from IPython. No
+ packages outside IPython/Jupyter should depend on it.
+
+ This package shouldn't exist. It contains some common utilities shared
+ by Jupyter and IPython projects during The Big Split. As soon as
+ possible, those packages will remove their dependency on this, and this
+ package will go away.
relevance: 4
name: python2-notebook
version: 5.7.4
outputs: out
systems: x86_64-linux i686-linux
dependencies: python2-jupyter-core@4.4.0 python2-mock@2.0.0
+ python2-nbconvert@5.0.0b1 python2-nbformat@4.4.0 python2-nose@1.3.7
+ python2-prometheus-client@0.5.0 python2-requests@2.22.0
+ python2-send2trash@1.5.0 python2-sphinx@1.7.7 python2-terminado@0.8.1
location: gnu/packages/python-xyz.scm:7840:4
homepage: http://jupyter.org/
license: Modified BSD
synopsis: Web-based notebook environment for interactive computing
description: The Jupyter HTML notebook is a web-based notebook
+ environment for interactive computing.
relevance: 2
name: python-notebook
version: 5.7.4
outputs: out
systems: x86_64-linux i686-linux
dependencies: python-jupyter-core@4.4.0 python-nbconvert@5.0.0b1
+ python-nbformat@4.4.0 python-nose@1.3.7 python-prometheus-client@0.5.0
+ python-requests@2.22.0 python-send2trash@1.5.0 python-sphinx@2.3.1
+ python-terminado@0.8.1
location: gnu/packages/python-xyz.scm:7793:2
homepage: http://jupyter.org/
license: Modified BSD
synopsis: Web-based notebook environment for interactive computing
description: The Jupyter HTML notebook is a web-based notebook
+ environment for interactive computing.
relevance: 2
#+end_example
Aouch! Ça fait beaucoup. Dans le tas, il y a un paquet qui s'appelle
=jupyter=. C'est un bon point de départ. Installons-le et voyons ce qu'on peut faire avec. Attention, ce qui se passe quand vous lancez la commande suivante peut être très variable. Dans le meilleur cas, Guix télécharge une version précompilée de Jupyter. Au pire, Guix compile Jupyter à partir de son code source. Et si vous n'avez vraiment pas de chance, Guix va d'abord compiler juste la bonne version des compilateurs qu'il faut pour compiler Jupyter. Dans ce cas, vous devez attendre longtemps - mais à la fin, vous aurez ce que vous avez demandé.
Alors... allons-y !
#+begin_src sh :results output :exports both
guix install jupyter
#+end_src
#+RESULTS:
: 84 packages in profile
Ceux qui ont l'habitude d'une distribution classique étaient peut-être tentés de rajouter =sudo= devant la commande, parce que l'installation d'un logiciel, ça relève des privilèges d'un administrateur. Ce n'est pas le cas avec Guix. Sous Guix, chaque utilisateur gère ses logiciels de façon autonome. Le =jupyter= que je viens d'installer n'est accessible que pour moi. En fait, l'annonce des "84 paquets dans mon profil" veut dire qu'il y a 84 paquets installés à mon nom, un "profil" étant une collection de paquets installés (et on peut même en avoir plusieurs, mais ça dépasse le cadre de ce tutoriel).
Pour tester, lançons =jupyter=:
#+begin_src sh :results none :exports code
jupyter notebook
#+end_src
Un essai rapide confirme que tout est là pour créer un notebook en langage Python 3, donc tout va bien.
Il reste à faire la même chose avec =matplotlib=, =pandas=, =numpy= et =statsmodels=. Je trouve les noms des paquets avec =guix search=, et puis j'installe tout avec une seule commande:
#+begin_src sh :results output :exports both
guix install python-matplotlib python-numpy python-pandas python-statsmodels
#+end_src
#+RESULTS:
: 88 packages in profile
Je rajoute le paquet =python-nbconvert= qui permet de
convertir les notebooks en ligne de commande sans passer par
l'interface graphique, ça peut toujours servir:
#+begin_src sh :results output :exports both
guix install python-nbconvert
#+end_src
#+RESULTS:
: 89 packages in profile
** 2.4 Automatiser la construction de son environnement
Vous remarquerez que dans tout ce qui a précédé, j'ai noté dans mon
journal de ce que j'ai effectué mais vous n'avez aucune garantie que
je n'ai rien oublié. De plus, si vous voulez refaire cet environnement
vous même, il vous faudra suivre ces instructions scrupuleusement en
espérant que rien n'aille de travers.
Je vais donc maintenant introduire alors la notion du =manifest= qui
va réaliser la préparation de l'environnement automatiquement à l'aide
de la commande =guix environment=. Un =manifest= est une spécification
complète d'un environnement de calcul. Voyons à quoi ça ressemble.
#+begin_src shell :results output :exports none
mkdir -p moocrr_guix_jupyter
#+end_src
#+RESULTS:
Je crée un fichier [[file:moocrr_guix_jupyter/manifest.scm][moocrr_guix_jupyter/manifest.scm]] dont voici
le contenu.
#+begin_src sh :results output :exports both
cat moocrr_guix_jupyter/manifest.scm
#+end_src
#+RESULTS:
: (specifications->manifest
: '("jupyter"
: "python-matplotlib"
: "python-numpy"
: "python-pandas"
: "python-statsmodels"
: "python-nbconvert"))
:
C'est essentiellement la liste des paquets que j'ai installé à la main auparavant, mais dans un format un peu particulier qu'il faut respecter scrupuleusement. En fait, ce format n'est rien d'autre que le langage de programmation [[https://fr.wikipedia.org/wiki/Scheme][Scheme]]. Guix est écrit en Scheme, et exprimer une liste de paquets en Scheme a le grand avantage qu'on peut utiliser des fonctionnalités avancées de Guix pour définir son environnement. Par exemple, je pourrais demander que tous mes paquets, en commençant par Python, soient compilés avec =gcc 7= plutôt qu'avec le compilateur par défaut de Guix, qui est actuellement =gcc 5=.
Je peux alors créer un environnement contenant ces paquets avec
#+begin_src sh :session *jupyter-env* :results output :exports both
guix environment --pure -m ./moocrr_guix_jupyter/manifest.scm
#+end_src
#+RESULTS:
Ceci me lance une shell (=bash=, plus précisement) de laquelle Jupyter est accessible et configuré avec tous les modules Python demandés:
#+begin_src sh :session *jupyter-env* :results output :exports both
jupyter notebook
#+end_src
#+RESULTS:
Mais il est encore plus pratique de lancer directement Jupyter plutôt de passer par une shell::
#+begin_src sh :results output :exports both
guix environment -m ./moocrr_guix_jupyter/manifest.scm -- jupyter notebook
#+end_src
Pour faire encore mieux, rajoutons l'option =–pure=:
#+begin_src sh :results output :exports both
guix environment –pure -m ./moocrr_guix_jupyter/manifest.scm -- jupyter notebook
#+end_src
Un environnement "pur" ne contient que les paquets définis dans le manifeste, pendant qu'un environnement "standard" contient aussi tout ce qu'on a disponible par défaut par la ligne de commande, donc des utilitaires comme =ls=, =cp=, etc. Avec un environnement pur, on est sûr de n'utiliser rien qui n'est pas listé dans le manifeste, même pas par erreur.
** 2.5 Mieux connaître son environnement
J'ai bien choisi les paquets qui seront dans mon environnement, mais je n'ai pas choisi les versions. Contrairement à des gestionnaires de paquet traditionnels, Guix peux gérer plusieurs versions d'un même paquet dans la distribution, et c'est à l'utilisateur de choisir laquelle installer. En pratique, Guix contient seulement la version la plus récente de chaque paquet, pour faciliter la maintenance. Une exception est faite pour quelques paquets particulièrement importants dont il y a des versions différentes qui restent d'actualité. L'exemple typique est =gcc=, la collection des compilateurs GNU. Dans mon environnement, il n'y a rien de cette catégorie. J'ai donc installé les seules versions définies dans l'état actuel de Guix.
Il est pourtant important de savoir quelles versions on utilise, et il est fortement conseillé d'inclure cette information dans toute publication scientifique. La commande pour accéder à ces informations est =guix package -I=. Pour l'exécuter correctement dans mon environnement, je rentre d'abord dans une shell comme montré ci-dessus:
#+begin_src sh :session *guix* :results output :exports both
guix environment -m ./moocrr_guix_jupyter/manifest.scm
#+end_src
#+RESULTS:
Puis je lance ma requête:
#+begin_src sh :session *guix* :results output :exports both
guix package -p $GUIX_ENVIRONMENT -I
#+end_src
#+RESULTS:
| python-nbconvert | 5.0.0b1 | out | /gnu/store/5m8mdhj6wpgsxll5c45bc7ha2sl8n1gf-python-nbconvert-5.0.0b1 |
| python-statsmodels | 0.9.0 | out | /gnu/store/zl3p1kzbg0fgdys4vk420g5q0vb4fa5q-python-statsmodels-0.9.0 |
| python-pandas | 0.25.2 | out | /gnu/store/wxq7g1mfn66xhf9iz8sgccnp4bb1bsi0-python-pandas-0.25.2 |
| python-numpy | 1.17.3 | out | /gnu/store/h7g276fj8n0ns1r2lz4rjzxbkp9wnrnr-python-numpy-1.17.3 |
| python-matplotlib | 3.1.2 | out | /gnu/store/n8x2rygfi70g594yc02r7ww6hxady5vb-python-matplotlib-3.1.2 |
| jupyter | 1.0.0 | out | /gnu/store/kwf1gzgk7f0l1sz84d0frrfvlqysnbz7-jupyter-1.0.0 |
La dernière colonne montre les répertoires où se trouvent les paquets. Ceci est utile par exemple pour regarder les modules Python qui en font partie.
Reste à comprendre à quoi sert l'argument =-p $GUIX_ENVIRONMENT=. Normalement, l'option =-p= sert à choisir un "profil", ce qui est un environnement permanent. Dans un environnement temporaire, c'est =$GUIX_ENVIRONMENT= qui pointe vers l'endroit approprié. Sans l'argument =-p $GUIX_ENVIRONMENT=, guix afficherait autant les paquets dans mon profil permanent (le profil par défaut de mon compte) en plus des paquets qui font partie de mon environnement temporaire.
Ma petite liste ci-dessus contient seulement les paquets que j'ai installés explicitement. Chaque paquet dans cette liste a des dépendances, que Guix a rajouté automatiquement. Leurs versions comptent tout autant, car elle peuvent influencer les résultats de mes calculs. Pour ne citer qu'un exemple, =python-statsmodels= dépend de =python-patsy=, qui fournit le cadre pour définir des modèles statistiques. Une erreur dans =python-patsy= peut donc fausser mes résultats. Il faudrait alors idéalement connaître les versions de toutes les dépendances, directes et indirectes.
A ma connaissance, Guix ne propose pas de commande pour récupérer cette liste. Je vais la récupérer par un petit script en langage Guile, le langage de Guix. Je vous le montre sans explication:
#+begin_src guile :exports both :tangle moocrr_guix_jupyter/installed-dependencies.scm
(use-modules (guix profiles)
(gnu packages)
(srfi srfi-1))
(define manifest
(specifications->manifest
'("jupyter"
"python-matplotlib"
"python-numpy"
"python-pandas"
"python-statsmodels"
"python-nbconvert")))
(define (manifest-entry-name-and-version entry)
(string-append (manifest-entry-name entry)
"@"
(manifest-entry-version entry)
"\n"))
(define transitive-entries
(manifest-transitive-entries manifest))
(define transitive-packages
(delete-duplicates
(stable-sort
(map manifest-entry-name-and-version transitive-entries)
string<)))
(format #t "~a packages:\n" (length transitive-packages))
(format #t "~a"
(apply string-append transitive-packages))
#+end_src
Et le résultat est...
#+begin_src sh :results output :exports both
guile -s moocrr_guix_jupyter/installed-dependencies.scm
#+end_src
#+RESULTS:
#+begin_example
119 packages:
cairo@1.16.0
expat@2.2.7
fontconfig@2.13.1
freetype@2.10.1
glib@2.60.6
gobject-introspection@1.60.2
jupyter@1.0.0
libffi@3.2.1
libpng@1.6.37
libpthread-stubs@0.4
libselinux@2.7
libsepol@2.7
libx11@1.6.8
libxau@1.0.9
libxcb@1.13
libxdmcp@1.1.3
libxext@1.3.4
libxrender@0.9.10
pcre@8.43
pixman@0.38.4
python-asn1crypto@0.24.0
python-attrs@19.1.0
python-automat@0.7.0
python-babel@2.7.0
python-backcall@0.1.0
python-bleach@3.1.0
python-cairocffi@0.9.0
python-certifi@2019.3.9
python-cffi@1.11.5
python-chardet@3.0.4
python-constantly@15.1.0
python-cryptography@2.7
python-cycler@0.10.0
python-dateutil@2.8.0
python-decorator@4.3.0
python-docutils@0.14
python-entrypoints@0.3
python-et-xmlfile@1.0.1
python-hyperlink@19.0.0
python-idna@2.8
python-imagesize@1.1.0
python-incremental@17.5.0
python-ipaddress@1.0.22
python-ipykernel@5.1.3
python-ipython-genutils@0.1.0
python-ipython@7.9.0
python-ipywidgets@5.2.2
python-iso8601@0.1.12
python-jdcal@1.4
python-jedi@0.15.1
python-jinja2@2.10.1
python-jsonschema@3.0.1
python-jupyter-client@5.2.4
python-jupyter-console@6.0.0
python-jupyter-core@4.4.0
python-kiwisolver@1.0.1
python-markupsafe@1.1.1
python-matplotlib@3.1.2
python-mistune@0.8.4
python-nbconvert@5.0.0b1
python-nbformat@4.4.0
python-notebook@5.7.4
python-numpy@1.17.3
python-numpydoc@0.8.0
python-olefile@0.46
python-openpyxl@2.6.2
python-packaging@20.0
python-pandas@0.25.2
python-parso@0.5.1
python-patsy@0.5.1
python-pexpect@4.6.0
python-pickleshare@0.7.5
python-pillow@6.2.1
python-prometheus-client@0.5.0
python-prompt-toolkit@2.0.7
python-ptyprocess@0.5.2
python-pycairo@1.17.1
python-pycparser@2.19
python-pygments@2.4.2
python-pygobject@3.28.3
python-pyhamcrest@1.9.0-0.25fdc5f
python-pyopenssl@19.0.0
python-pyparsing@2.3.1
python-pyrsistent@0.14.11
python-pysocks@1.7.0
python-pytz@2019.1
python-pyzmq@17.1.2
python-qtconsole@4.4.3
python-requests@2.22.0
python-scipy@1.3.2
python-send2trash@1.5.0
python-simplegeneric@0.8.1
python-six@1.12.0
python-snowballstemmer@1.2.1
python-sphinx-alabaster-theme@0.7.12
python-sphinx@2.3.1
python-sphinxcontrib-applehelp@1.0.1
python-sphinxcontrib-devhelp@1.0.1
python-sphinxcontrib-htmlhelp@1.0.2
python-sphinxcontrib-jsmath@1.0.1
python-sphinxcontrib-qthelp@1.0.2
python-sphinxcontrib-serializinghtml@1.1.3
python-statsmodels@0.9.0
python-terminado@0.8.1
python-tornado@5.1.1
python-traitlets@4.3.3
python-twisted@19.7.0
python-urllib3@1.25.3
python-wcwidth@0.1.8
python-webencodings@0.5.1
python-widgetsnbextension@3.4.2
python-xcffib@0.6.0
python-xlrd@1.2.0
python-zope-interface@4.6.0
python@3.7.4
util-linux@2.34
util-macros@1.19.2
xorgproto@2019.1
zlib@1.2.11
#+end_example
Il faut donc 119 paquets en total pour construire mon environnement! Et ce sont seulement les paquets qui doivent être en mémoire pour utiliser l'environnement. D'autres paquets ont été déployés pour construire ces 118 paquets. Par exemple, pour construire le paquet =python= il a fallu un compilateur C. Une erreur dans ce compilateur peut aussi fausser mes résultats, donc je devrais le rajouter à ma liste de paquets dont il faut noter les versions. Alors... encore un petit script pour faire la liste complète !
#+begin_src guile :exports both :tangle moocrr_guix_jupyter/all-dependencies.scm
(use-modules (guix profiles)
(guix packages)
(gnu packages)
(srfi srfi-1))
(define manifest
(specifications->manifest
'("jupyter"
"python-matplotlib"
"python-numpy"
"python-pandas"
"python-statsmodels"
"python-nbconvert")))
(define (manifest-entry->package entry)
(car
(find-packages-by-name
(manifest-entry-name entry)
(manifest-entry-version entry))))
(define (package->name-and-version entry)
(string-append (package-name entry)
"@"
(package-version entry)
"\n"))
(define packages-in-manifest
(map manifest-entry->package (manifest-entries manifest)))
(define closure-of-manifest
(package-closure packages-in-manifest))
(define package-names-in-closure
(stable-sort
(delete-duplicates (map package->name-and-version closure-of-manifest))
string<))
(format #t "~a packages:\n" (length package-names-in-closure))
(format #t "~a"
(apply string-append package-names-in-closure))
#+end_src
Et le résultat est...
#+begin_src sh :results output :exports both
guile -s moocrr_guix_jupyter/all-dependencies.scm
#+end_src
#+RESULTS:
#+begin_example
570 packages:
acl@2.2.53
aspell@0.60.6.1
at-spi2-atk@2.34.1
at-spi2-core@2.34.0
atk@2.34.1
atkmm@2.28.0
attr@2.4.48
autoconf-wrapper@2.69
autoconf@2.69
automake@1.16.1
avahi@0.7
bash-minimal@5.0.7
bash-static@5.0.7
bash@5.0.7
bc@1.07.1
bdb@5.3.28
bdb@6.2.32
binutils-cross-boot0@2.32
binutils-mesboot0@2.20.1a
binutils-mesboot@2.20.1a
binutils@2.32
bison@3.4.1
boost@1.70.0
bootstrap-binaries@0
bootstrap-mes@0
bootstrap-mescc-tools@0.5.2
bzip2@1.0.6
c-ares@1.15.0
cairo@1.16.0
cairomm@1.12.2
cmake-minimal@3.15.1
coreutils@8.31
cunit@2.1-3
cups-filters@1.25.13
cups-minimal@2.3.0
cups@2.3.0
curl@7.65.3
cyrus-sasl@2.1.27
dblatex@0.3.10
dbus@1.12.16
diffutils-boot0@3.7
diffutils-mesboot@2.7
diffutils@3.7
docbook-xml@4.2
docbook-xml@4.3
docbook-xml@4.4
docbook-xml@4.5
docbook-xsl@1.79.1
doxygen@1.8.15
ed@1.15
elfutils@0.176
eudev@3.2.9
expat@2.2.7
fftw@3.3.8
file-boot0@5.33
file@5.33
findutils-boot0@4.6.0
findutils@4.6.0
flex@2.6.4
font-dejavu@2.37
fontconfig@2.13.1
fontforge@20190801
freeglut@3.0.0
freetype@2.10.1
fribidi@1.0.5
gawk@5.0.1
gcc-core-mesboot@2.95.3
gcc-cross-boot0-wrapped@7.4.0
gcc-cross-boot0@7.4.0
gcc-mesboot-wrapper@4.9.4
gcc-mesboot0@2.95.3
gcc-mesboot1-wrapper@4.7.4
gcc-mesboot1@4.7.4
gcc-mesboot@4.9.4
gcc@7.4.0
gd@2.2.5
gdbm@1.18.1
gdk-pixbuf+svg@2.40.0
gdk-pixbuf@2.40.0
gettext-boot0@0.19.8.1
gettext-minimal@0.20.1
gfortran@7.4.0
ghostscript-with-cups@9.27
ghostscript@9.27
giflib@5.1.4
glib@2.60.6
glibc-headers-mesboot@2.16.0
glibc-intermediate@2.29
glibc-mesboot0@2.2.5
glibc-mesboot@2.16.0
glibc-utf8-locales@2.29
glibc@2.29
glibmm@2.60.0
glslang@7.11.3214
glu@9.0.1
gmp@6.1.2
gnutls@3.6.9
gobject-introspection@1.60.2
gperf@3.1
graphite2@1.3.13
graphviz@2.40.1
grep@3.3
groff-minimal@1.22.4
groff@1.22.4
gs-fonts@8.11
gsl@2.5
gtk+@2.24.32
gtk+@3.24.13
gtk-doc@1.28
gtkmm@2.24.5
gts@0.7.6
guile-bootstrap@2.0
guile@2.0.14
guile@2.2.6
gzip@1.10
harfbuzz@2.5.3
help2man@1.47.10
icu4c@64.2
ijs@9.27
imagemagick@6.9.10-78
inkscape@0.92.4
intltool@0.51.0
iproute2@5.3.0
iptables@1.8.4
isl@0.21
itstool@2.0.6
jansson@2.12
jbig2dec@0.16
jemalloc@5.2.0
json-glib@1.4.4
jupyter@1.0.0
kmod@26
lapack@3.9.0
lcms@2.9
ld-wrapper-boot0@0
ld-wrapper-boot3@0
ld-wrapper@0
less@551
libarchive@3.4.0
libatomic-ops@7.6.10
libbsd@0.9.1
libcap@2.27
libcroco@0.6.13
libdaemon@0.14
libdmx@1.1.4
libdrm@2.4.100
libelf@0.8.13
libepoxy@1.5.4
libev@4.25
libffi@3.2.1
libfontenc@1.1.4
libgc@7.6.12
libgcrypt@1.8.4
libgpg-error@1.36
libgsf@1.14.46
libice@1.0.10
libidn2@2.2.0
libidn@1.35
libjpeg-turbo@2.0.2
libjpeg@9c
libltdl@2.4.6
libmnl@1.0.4
libnftnl@1.1.5
libpaper@1.1.24
libpciaccess@0.16
libpipeline@1.5.1
libpng@1.6.37
libpthread-stubs@0.4
librsvg@2.40.20
libselinux@2.7
libsepol@2.7
libsigc++@2.10.2
libsigsegv@2.12
libsm@1.2.3
libspectre@0.2.8
libspiro@0.5.20150702
libstdc++-boot0@4.9.4
libstdc++@7.4.0
libtasn1@4.14
libtiff@4.0.10
libtool@2.4.6
libungif@4.1.4
libuninameslist@20190701
libunistring@0.9.10
libuv@1.30.1
libva-without-mesa@2.5.0
libvdpau@1.3
libwebp@1.0.3
libx11@1.6.8
libxau@1.0.9
libxaw@1.0.13
libxcb@1.13
libxcomposite@0.4.5
libxcursor@1.2.0
libxdamage@1.1.5
libxdmcp@1.1.3
libxext@1.3.4
libxfixes@5.0.3
libxfont@2.0.4
libxft@2.3.3
libxi@1.7.10
libxinerama@1.1.4
libxkbcommon@0.9.1
libxkbfile@1.1.0
libxml2@2.9.9
libxmu@1.1.3
libxpm@3.5.12
libxrandr@1.5.2
libxrender@0.9.10
libxres@1.2.0
libxshmfence@1.3
libxslt@1.1.33
libxt@1.2.0
libxtst@1.2.3
libxv@1.0.11
libxvmc@1.0.12
libxxf86vm@1.1.4
linux-libre-headers-bootstrap@0
linux-libre-headers@4.19.56
llvm@8.0.0
lzip@1.21
lzo@2.10
m4@1.4.18
make-boot0@4.2.1
make-mesboot0@3.80
make-mesboot@3.82
make@4.2.1
makedepend@1.0.6
man-db@2.9.0
mes-boot@0.19
mesa@19.2.7
mesboot-headers@0.19
meson-for-build@0.50.1
mit-krb5@1.17
mpc@1.1.0
mpfr@4.0.2
nasm@2.14.02
ncurses@6.1-20190609
net-base@5.3
net-tools@1.60-0.479bb4a
nettle@3.5.1
nghttp2@1.39.1
ninja@1.9.0
openblas@0.3.7
openjpeg@2.3.1
openldap@2.4.47
openssl@1.1.1c
pango@1.42.4
pangomm@2.42.0
patch@2.7.6
pciutils@3.6.2
pcre@8.43
perl-boot0@5.30.0
perl-xml-parser@2.44
perl@5.30.0
pixman@0.38.4
pkg-config@0.29.2
poppler@0.79.0
popt@1.16
potrace@1.15
psutils@17
python-asn1crypto@0.24.0
python-atomicwrites@1.3.0
python-attrs-bootstrap@19.1.0
python-attrs@19.1.0
python-automat@0.7.0
python-babel@2.7.0
python-backcall@0.1.0
python-beautifulsoup4@4.7.1
python-bleach@3.1.0
python-cairocffi@0.9.0
python-certifi@2019.3.9
python-cffi@1.11.5
python-chardet@3.0.4
python-constantly@15.1.0
python-coverage@4.5.3
python-cryptography-vectors@2.7
python-cryptography@2.7
python-cycler@0.10.0
python-cython@0.29.13
python-dateutil@2.8.0
python-decorator@4.3.0
python-docopt@0.6.2
python-docutils@0.14
python-entrypoints@0.3
python-et-xmlfile@1.0.1
python-flake8@3.7.7
python-flaky@3.5.3
python-fonttools@3.38.0
python-freezegun@0.3.12
python-graphviz@0.13.2
python-html5lib@1.0.1
python-hyperlink@19.0.0
python-hypothesis@4.18.3
python-idna@2.8
python-imagesize@1.1.0
python-incremental@17.5.0
python-ipaddress@1.0.22
python-ipykernel@5.1.3
python-ipython-genutils@0.1.0
python-ipython@7.9.0
python-ipywidgets@5.2.2
python-iso8601@0.1.12
python-jdcal@1.4
python-jedi@0.15.1
python-jinja2@2.10.1
python-jsonschema@3.0.1
python-jupyter-client@5.2.4
python-jupyter-console@6.0.0
python-jupyter-core@4.4.0
python-kiwisolver@1.0.1
python-libxml2@2.9.9
python-linecache2@1.0.0
python-lxml@4.4.2
python-m2r@0.2.1
python-mako@1.1.0
python-markupsafe@1.1.1
python-matplotlib@3.1.2
python-mccabe@0.6.1
python-minimal-wrapper@3.7.4
python-minimal@3.5.7
python-minimal@3.7.4
python-mistune@0.8.4
python-mock@2.0.0
python-more-itertools@7.1.0
python-nbconvert@5.0.0b1
python-nbformat@4.4.0
python-nose@1.3.7
python-notebook@5.7.4
python-numpy@1.17.3
python-numpydoc@0.8.0
python-olefile@0.46
python-openpyxl@2.6.2
python-packaging@20.0
python-pandas@0.25.2
python-parso@0.5.1
python-patsy@0.5.1
python-pbr-minimal@3.0.1
python-pexpect@4.6.0
python-pickleshare@0.7.5
python-pillow@6.2.1
python-pluggy@0.11.0
python-pretend@1.0.9
python-prometheus-client@0.5.0
python-prompt-toolkit@2.0.7
python-ptyprocess@0.5.2
python-py@1.8.0
python-pycairo@1.17.1
python-pycodestyle@2.5.0
python-pycparser@2.19
python-pyflakes@2.1.1
python-pygments@2.4.2
python-pygobject@3.28.3
python-pyhamcrest@1.9.0-0.25fdc5f
python-pympler@0.7
python-pyopenssl@19.0.0
python-pyparsing@2.3.1
python-pyrsistent@0.14.11
python-pysocks@1.7.0
python-pytest-bootstrap@4.4.2
python-pytest-cov@2.6.1
python-pytest-mock@1.10.1
python-pytest-runner@2.12.2
python-pytest-runner@4.4
python-pytest@4.4.2
python-pytz@2019.1
python-pyzmq@17.1.2
python-qtconsole@4.4.3
python-requests@2.22.0
python-scipy@1.3.2
python-send2trash@1.5.0
python-setuptools-scm@3.2.0
python-simplegeneric@0.8.1
python-six-bootstrap@1.12.0
python-six@1.12.0
python-snowballstemmer@1.2.1
python-soupsieve@1.9.5
python-sphinx-alabaster-theme@0.7.12
python-sphinx@2.3.1
python-sphinxcontrib-applehelp@1.0.1
python-sphinxcontrib-devhelp@1.0.1
python-sphinxcontrib-htmlhelp@1.0.2
python-sphinxcontrib-jsmath@1.0.1
python-sphinxcontrib-qthelp@1.0.2
python-sphinxcontrib-serializinghtml@1.1.3
python-statsmodels@0.9.0
python-terminado@0.8.1
python-testpath@0.2
python-tornado@5.1.1
python-traceback2@1.4.0
python-traitlets@4.3.3
python-twisted@19.7.0
python-unittest2@1.1.0
python-urllib3@1.25.3
python-wcwidth@0.1.8
python-webencodings@0.5.1
python-widgetsnbextension@3.4.2
python-wrapper@3.7.4
python-xcffib@0.6.0
python-xlrd@1.2.0
python-zope-event@4.4
python-zope-interface@4.6.0
python2@2.7.16
python@3.7.4
qpdf@9.1.0
readline@8.0
rhash@1.3.8
ruby@2.5.3
sed@4.7
shared-mime-info@1.10
source-highlight@3.1.8
sqlite@3.28.0
swig@3.0.12
tar@1.32
tcc-boot0@0.9.26-6.c004e9a
tcc-boot@0.9.27
tcl@8.6.9
tcsh@6.20.00
teckit@2.5.9
texinfo@6.6
texlive-amsfonts@49435
texlive-bin@20180414
texlive-cm@49435
texlive-dehyph-exptl@49435
texlive-docstrip@49435
texlive-dvips@49435
texlive-etex@49435
texlive-fontname@49435
texlive-fonts-ec@49435
texlive-fonts-knuth-lib@49435
texlive-fonts-latex@49435
texlive-fonts-rsfs@49435
texlive-fonts-stmaryrd@49435
texlive-generic-babel-english@49435
texlive-generic-ifxetex@49435
texlive-graphics-cfg@49435
texlive-graphics-def@49435
texlive-hyph-utf8@49435
texlive-hyphen-afrikaans@49435
texlive-hyphen-ancientgreek@49435
texlive-hyphen-armenian@49435
texlive-hyphen-base@49435
texlive-hyphen-basque@49435
texlive-hyphen-belarusian@49435
texlive-hyphen-bulgarian@49435
texlive-hyphen-catalan@49435
texlive-hyphen-chinese@49435
texlive-hyphen-churchslavonic@49435
texlive-hyphen-coptic@49435
texlive-hyphen-croatian@49435
texlive-hyphen-czech@49435
texlive-hyphen-danish@49435
texlive-hyphen-dutch@49435
texlive-hyphen-english@49435
texlive-hyphen-esperanto@49435
texlive-hyphen-estonian@49435
texlive-hyphen-ethiopic@49435
texlive-hyphen-finnish@49435
texlive-hyphen-french@49435
texlive-hyphen-friulan@49435
texlive-hyphen-galician@49435
texlive-hyphen-georgian@49435
texlive-hyphen-german@49435
texlive-hyphen-greek@49435
texlive-hyphen-hungarian@49435
texlive-hyphen-icelandic@49435
texlive-hyphen-indic@49435
texlive-hyphen-indonesian@49435
texlive-hyphen-interlingua@49435
texlive-hyphen-irish@49435
texlive-hyphen-italian@49435
texlive-hyphen-kurmanji@49435
texlive-hyphen-latin@49435
texlive-hyphen-latvian@49435
texlive-hyphen-lithuanian@49435
texlive-hyphen-mongolian@49435
texlive-hyphen-norwegian@49435
texlive-hyphen-occitan@49435
texlive-hyphen-piedmontese@49435
texlive-hyphen-polish@49435
texlive-hyphen-portuguese@49435
texlive-hyphen-romanian@49435
texlive-hyphen-romansh@49435
texlive-hyphen-russian@49435
texlive-hyphen-sanskrit@49435
texlive-hyphen-serbian@49435
texlive-hyphen-slovak@49435
texlive-hyphen-slovenian@49435
texlive-hyphen-spanish@49435
texlive-hyphen-swedish@49435
texlive-hyphen-thai@49435
texlive-hyphen-turkish@49435
texlive-hyphen-turkmen@49435
texlive-hyphen-ukrainian@49435
texlive-hyphen-uppersorbian@49435
texlive-hyphen-welsh@49435
texlive-kpathsea@49435
texlive-latex-amscls@49435
texlive-latex-amsmath@49435
texlive-latex-anysize@49435
texlive-latex-appendix@49435
texlive-latex-babel@49435
texlive-latex-base@49435
texlive-latex-changebar@49435
texlive-latex-colortbl@49435
texlive-latex-cyrillic@49435
texlive-latex-eepic@49435
texlive-latex-eso-pic@49435
texlive-latex-fancybox@49435
texlive-latex-fancyhdr@49435
texlive-latex-fancyvrb@49435
texlive-latex-filecontents@49435
texlive-latex-float@49435
texlive-latex-footmisc@49435
texlive-latex-graphics@49435
texlive-latex-hyperref@6.84a2
texlive-latex-jknapltx@49435
texlive-latex-listings@49435
texlive-latex-multirow@49435
texlive-latex-oberdiek@49435
texlive-latex-overpic@49435
texlive-latex-pdfpages@49435
texlive-latex-psnfss@49435
texlive-latex-subfigure@49435
texlive-latex-titlesec@49435
texlive-latex-tools@49435
texlive-latex-url@49435
texlive-latex-wasysym@49435
texlive-latexconfig@49435
texlive-metafont-base@49435
texlive-mkpattern@49435
texlive-ruhyphen@49435
texlive-tetex@49435
texlive-tex-fontinst-base@49435
texlive-tex-ini-files@49435
texlive-tex-plain@49435
texlive-ukrhyph@49435
texlive-unicode-data@49435
texlive-union@49435
tk@8.6.9.1
tzdata@2019b
unzip@6.0
util-linux@2.34
util-macros@1.19.2
vala@0.44.5
wayland-protocols@1.18
wayland@1.17.0
which@2.21
xcb-proto@1.13
xcb-util-image@0.4.0
xcb-util-keysyms@0.4.0
xcb-util-renderutil@0.3.9
xcb-util-wm@0.4.1
xcb-util@0.4.0
xinput@1.6.2
xkbcomp-intermediate@1.4.2
xkbcomp@1.4.2
xkeyboard-config@2.27
xmlto@0.0.28
xorg-server@1.20.5
xorgproto@2019.1
xtrans@1.4.0
xz@5.2.4
yelp-tools@3.28.0
yelp-xsl@3.32.1
zeromq@4.3.2
zip@3.0
zlib@1.2.11
zstd@1.4.2
zziplib@0.13.69
#+end_example
** 2.6 Mettre son environnement à disposition
L'environnement étant défini par le manifeste, il suffit de mettre ce petit fichier à disposition de ses collègues pour leur permettre de travailler dans un environnement identique. Sauf que... les versions qu'ils auront ne sont peut-être pas les mêmes ! Peu après la publication d'une nouvelle version de Jupyter, Guix adoptera cette nouvelle version, et l'environnement créé par mon manifest ne sera plus le même. Ceci est d'ailleurs voulu: souvent on veut tout juste avoir la dernière version de tout. Mais pour la reproductibilité, on veut tout à l'identique.
L'information qu'il faut rajouter, c'est la version de Guix à laquelle le manifeste fait référence. On l'obtient avec
#+begin_src sh :results output :exports both
guix describe
#+end_src
#+RESULTS:
: Generation 20 Feb 10 2020 10:21:15 (current)
: guix df931ac
: repository URL: https://git.savannah.gnu.org/git/guix.git
: branch: master
: commit: df931ac39c40ac8a702e37cb434d9a1016606ed7
Ceci me dit d'abord que je suis dans la génération 20 de Guix, ce qui veut dire que j'ai mis à jour Guix 19 fois depuis la première installation. Guix garde une trace de mes mise à jour et me permet de revenir en arrière si je le souhaite. Mais ce qui nous intéresse maintenant, c'est la suite. La version de Guix que j'utilise, c'est la =df931ac=. En tant qu'habitués de =git=, vous devinez peut-être ce que c'est, et vous avez raison: c'est bien un commit, et vous le voyez dans sa totalité dans la dernière ligne. Guix est développé sous git, et on peut donc identifier une version précise par son identifiant de commit. Les trois dernières lignes donnent un peu plus de précision, dont notamment l'URL où on peut récupérer le dépôt.
** 2.7 Reconstruire un environnement
Maintenant je me place du côté du consommateur. J'ai reçu un notebook Jupyter accompagné d'un fichier =manifest.scm= et d'un commit. Que faire?
La réponse est simple: je fais appel à la machine à voyager dans le temps. Pour lancer Jupyter dans une environnement "pur", la commande était bien:
#+begin_src sh :results output :exports both :eval no
guix environment --pure -m ./moocrr_guix_jupyter/manifest.scm -- jupyter notebook
#+end_src
Pour faire exactement la même chose plus tard, quand Guix aura avancé, je demande simplement à Guix de se placer sur le commit de sa version antérieure qui m'intéresse:
#+begin_src sh :session *time-machine* :results output :exports both
guix time-machine --commit=df931ac39c40ac8a702e37cb434d9a1016606ed7 -- environment --pure -m ./moocrr_guix_jupyter/manifest.scm -- jupyter notebook
#+end_src
:
Attention, la première fois que je lance =guix environment= après =guix pull=, il se peut que Guix se mette à compiler une bonne partie des 570 paques listés ci-dessus. Mieux vaut prévoir du temps!
Avec =guix time-machine=, tout ce qui se passe après le premier =--= est passé à la commande =guix= dans sa version définie par le commit indiqué. On travaille donc à 100% avec le guix historique.
** 2.8 Mettre son environnement à disposition sous forme d'une image Docker
Il reste un problème que vous pouvez rencontrer: vos collègues n'utilisent pas Guix, peut-être même pas Linux. Un manifeste et un commit ne vont pas leur être utiles. En attendant qu'ils se mettent à utiliser Guix, vous pouvez leur fournir votre environnement sous forme d'une image Docker probablement plus simple à utiliser:
#+begin_src sh :results output :exports both
guix pack -f docker -m ./moocrr_guix_jupyter/manifest.scm
#+end_src
#+RESULTS:
: /gnu/store/hgd89l0r46liqwlz4idhwaymsngrm255-docker-pack.tar.gz
La commande nous affiche le nom du fichier qui contient l'image Docker. Il peut paraître un peu bizarre, tout comme le répertoire =/gnu/store= dans lequel le fichier se trouve. Quand on comprend le fonctionnement de Guix un peu mieux, tout ça s'explique facilement mais pour ce tutoriel, je vais me contenter de le copier ailleurs avec un nom plus parlant:
#+begin_src sh :results output :exports both
cp /gnu/store/hgd89l0r46liqwlz4idhwaymsngrm255-docker-pack.tar.gz moocrr-jupyter-docker.tar.gz
#+end_src
#+RESULTS:
Sur une machine avec Docker installé, l'image est chargée avec
#+begin_src sh :results output :exports both
docker load -i moocrr-jupyter-docker.tar.gz
#+end_src
#+RESULTS:
#+begin_example
850f4083e529: Loading layer 1.64GB/1.64GB
Loaded image: jupyter-python-matplotlib-python-numpy:latest
#+end_example
puis Jupyter est exécuté avec
#+begin_src sh :results output :exports both
docker run -it -p 8888:8888 jupyter-python-matplotlib-python-numpy:latest jupyter notebook --ip=127.0.0.1 --allow-root
#+end_src
** 2.9 Modifier son environnement
Je vous ai montré comment vous pouvez installer des logiciels avec Guix avec toutes leurs dépendances, et comment archiver et reconstruire un tel environnement. Ceci couvre une grande partie des opérations nécessaires pour pratiquer la recherche reproductible. Mais comment faire si vous voulez (ou devez) modifier un environnement donné, que ce soit le vôtre ou un environnement récupéré sous forme d'un manifeste ?
Commençons avec la situation la plus simple: vous voulez mettre à jour tous les logiciels à la dernière version. Pour cela il suffit un simple
#+begin_src sh :results output :exports both :eval no
guix pull
#+end_src
et la prochaine fois que vous faites
#+begin_src sh :session *jupyter-env* :results output :exports both :eval no
guix environment -m ./moocrr_guix_jupyter/manifest.scm
#+end_src
vous utilisez les versions indiquées dans la toute dernière version de Guix. Mais que faire s'il vous faut une combinaison de versions qui ne se trouve nulle part dans l'historique de Guix? Par exemple, pour chercher la cause d'un bug introduit récemment par un changement dans votre environnement, vous voulez combiner la dernière version de =python-statsmodels= avec une version plus ancienne de =python-pandas=.
Avant de passer à l'acte, il faut bien comprendre que ce genre de modification est risqué. Rien ne promet que la combinaison de versions que vous envisagez est installable, et encore moins qu'elle fonctionne. Vous pouvez rencontrer un grand nombre de problèmes sur votre chemin, et c'est à vous de trouver une solution. Dans la vaste majorité des "petites" modifications, ou on remplace une version relativement stable d'un logiciel avec une version proche dans l'historique, la procédure que je vais montrer fonctionne sans difficulté, mais on n'est jamais à l'abri de mauvaises surprises!
Guix propose plusieurs façons d'introduire des modifications. Il n'est pas facile d'en choisir la meilleure sans avoir une certaine expérience de Guix. Je vous en montre une qui me paraît bien adaptée à la situation: définir un nouveau paquet, localement sur votre ordinateur, qui hérite la plupart des caractéristiques d'un paquet existant. Comme exemple, je vais remplacer la version 0.25.2 de Pandas par la version 0.25.1.
Je commence en regardant la définition du paquet =python-pandas= dans Guix:
#+begin_src sh :results none :exports code
guix edit python-pandas
#+end_src
Ceci ouvre le fichier =python-science.scm= dans un éditeur de texte avec le curseur sur la définition de =python-pandas=. Il y a deux champs que je vais devoir remplacer: le numéro de version, et la référence au code source. Tout le reste peut rester pareil - j'espère ! Voici le début de ma nouvelle définition:
#+begin_src guile :exports code :eval no
(package
(inherit python-pandas)
(version "0.25.1")
(source
(origin
(method url-fetch)
(uri (pypi-uri "pandas" version))
(sha256
(base32
"1xm9dmbngsq46vj836csnb5j0bs88b1d713b0b5vx1q6gdxijbnb")))))
#+end_src
Comme annoncé, j'ai modifié la version. Et dans le champ =source=, j'ai changé la somme de contrôle =sha256= qui doit correspondre au fichier téléchargé pour la version 0.25.1. Pour trouver la bonne somme de contrôle, guix m'ai aidé:
#+begin_src sh :results output :exports both
guix download https://files.pythonhosted.org/packages/source/p/pandas/pandas-0.25.1.tar.gz
#+end_src
mais vous êtes libre de faire appel à toute technique à laquelle vous faites confiance. Le but est d'être sûr que vous récupérez le code source d'un serveur fiable!
#+RESULTS:
: /gnu/store/52yc31ykwidx0fbmds7r0nz13rvkw2vf-pandas-0.25.1.tar.gz
: 1xm9dmbngsq46vj836csnb5j0bs88b1d713b0b5vx1q6gdxijbnb
Pour compléter la définition du paquet, qui est en fait du code en langage Guile (comme avant pour le manifeste), il faut importer quelques modules:
#+begin_src guile :exports both :tangle moocrr_guix_jupyter/pandas.scm
(use-modules (guix packages)
(guix download)
(guix build-system python)
(gnu packages python-science))
(package
(inherit python-pandas)
(version "0.25.1")
(source
(origin
(method url-fetch)
(uri (pypi-uri "pandas" version))
(sha256
(base32
"1xm9dmbngsq46vj836csnb5j0bs88b1d713b0b5vx1q6gdxijbnb")))))
#+end_src
Comment savoir quels modules importer? Le plus simple est =(gnu packages python-science)=, parce que c'est là qu'on a trouvé la définition de =python-pandas=. Sinon, il faut toujours =(guix packages)= et =(guix download)=. Pour finir, pour un paquet Python il faut toujours =(guix build-system python)=. Mais si vous oubliez un paquet, il y a une bonne chance que Guix vous indique le module manquant.
Pour compiler le paquet et exécuter sa batterie de tests, la commande est
#+begin_src sh :results none :exports code
guix build -f moocrr_guix_jupyter/pandas.scm
#+end_src
Attention, c'est long, et ça produit plus de 60000 lignes de texte diagnostic que je ne vais pas reproduire ici. Les deux dernières lignes sont
#+begin_example
successfully built /gnu/store/ab6i60xyinj47wqxd99sc0ih16d0a22p-python-pandas-0.25.1.drv
/gnu/store/9gswclr3gk7pdgxddznpw3lvgj8yywhl-python-pandas-0.25.1
#+end_example
et la toute dernière indique le repertoire où se trouve le nouveau paquet. Reste la question comment l'intégrer dans mon environnement. La réponse n'est pas difficile sur le principe ("il faut modifier le manifeste"), mais les détails techniques sont un peu laborieux - une lecture du manuel de Guix s'impose. Voici le manifeste final:
#+begin_src guile :exports both :tangle moocrr_guix_jupyter/manifest-with-pandas-0.25.1.scm
(use-modules (guix packages)
(guix download)
(guix build-system python)
(gnu packages python-science))
(define modified-python-pandas
(package
(inherit python-pandas)
(version "0.25.1")
(source
(origin
(method url-fetch)
(uri (pypi-uri "pandas" version))
(sha256
(base32
"1xm9dmbngsq46vj836csnb5j0bs88b1d713b0b5vx1q6gdxijbnb"))))))
(define standard-packages
(map (compose list specification->package+output)
'("jupyter"
"python"
"python-matplotlib"
"python-numpy"
"python-pandas"
"python-statsmodels"
"python-nbconvert")))
(packages->manifest
(cons modified-python-pandas
standard-packages))
#+end_src
Et voici la preuve que ça marche - on demande à Python d'imprimer le numéro de version de Pandas:
#+begin_src sh :results output :exports both
guix environment --pure -m ./moocrr_guix_jupyter/manifest-with-pandas-0.25.1.scm -- python3 -c 'import pandas; print(pandas.__version__)'
#+end_src
#+RESULTS:
: 0.25.1
En fait, si vous comparez bien mon nouveau manifeste avec celui d'origine, vous remarquez que j'ai rajouté =python= qui n'y était pas avant. C'est juste pour pouvoir apporter cette preuve de réussite de l'opération!
FROM alegrand/moocrr_debian_snapshot_slim:20171003T094008Z
LABEL maintainer="Arnaud Legrand <arnaud.legrand@imag.fr>"
RUN sed -i s/20171003T094008Z/20171209T114814Z/ /etc/apt/sources.list
RUN apt-get -o Acquire::Check-Valid-Until=false update \
&& apt-get install -y jupyter-notebook jupyter-nbconvert \
python3-matplotlib python3-pandas python3-numpy python3-statsmodels
CMD bash
debuerreotype-init rootfs testing 2017-10-03-T09:40:08Z
debuerreotype-minimizing-config rootfs # apply configuration tweaks to make the rootfs minimal and keep it minimal (especially targeted at Docker images, with comments explicitly describing Docker use cases)
debuerreotype-apt-get rootfs update -qq # let's update the package list
debuerreotype-apt-get rootfs dist-upgrade -yqq # let's upgrade any package that would need to be upgraded
debuerreotype-apt-get rootfs install -yqq --no-install-recommends inetutils-ping iproute2 # useful stuff
debuerreotype-slimify rootfs # remove files such as documentation to create an even smaller rootfs (used for creating slim variants of the Docker images, for example)
debuerreotype-tar rootfs - | sha256sum
debuerreotype-tar rootfs - | docker import - alegrand/moocrr_debian_snapshot_slim:20171003T094008Z
docker build -t alegrand/moocrr_debian_snapshot_jupyter:20171209T114814Z ./
FROM debian:stable
LABEL maintainer="Arnaud Legrand <arnaud.legrand@imag.fr>"
RUN apt-get update \
&& apt-get install -y jupyter-notebook jupyter-nbconvert \
python3-matplotlib python3-pandas python3-numpy python3-statsmodels
(use-modules (guix profiles)
(guix packages)
(gnu packages)
(srfi srfi-1))
(define manifest
(specifications->manifest
'("jupyter"
"python-matplotlib"
"python-numpy"
"python-pandas"
"python-statsmodels"
"python-nbconvert")))
(define (manifest-entry->package entry)
(car
(find-packages-by-name
(manifest-entry-name entry)
(manifest-entry-version entry))))
(define (package->name-and-version entry)
(string-append (package-name entry)
"@"
(package-version entry)
"\n"))
(define packages-in-manifest
(map manifest-entry->package (manifest-entries manifest)))
(define closure-of-manifest
(package-closure packages-in-manifest))
(define package-names-in-closure
(stable-sort
(delete-duplicates (map package->name-and-version closure-of-manifest))
string<))
(format #t "~a packages:\n" (length package-names-in-closure))
(format #t "~a"
(apply string-append package-names-in-closure))
(use-modules (guix profiles)
(gnu packages)
(srfi srfi-1))
(define manifest
(specifications->manifest
'("jupyter"
"python-matplotlib"
"python-numpy"
"python-pandas"
"python-statsmodels"
"python-nbconvert")))
(define (manifest-entry-name-and-version entry)
(string-append (manifest-entry-name entry)
"@"
(manifest-entry-version entry)
"\n"))
(define transitive-entries
(manifest-transitive-entries manifest))
(define transitive-packages
(delete-duplicates
(stable-sort
(map manifest-entry-name-and-version transitive-entries)
string<)))
(format #t "~a packages:\n" (length transitive-packages))
(format #t "~a"
(apply string-append transitive-packages))
(use-modules (guix packages)
(guix download)
(guix build-system python)
(gnu packages python-science))
(define modified-python-pandas
(package
(inherit python-pandas)
(version "0.25.1")
(source
(origin
(method url-fetch)
(uri (pypi-uri "pandas" version))
(sha256
(base32
"1xm9dmbngsq46vj836csnb5j0bs88b1d713b0b5vx1q6gdxijbnb"))))))
(define standard-packages
(map (compose list specification->package+output)
'("jupyter"
"python"
"python-matplotlib"
"python-numpy"
"python-pandas"
"python-statsmodels"
"python-nbconvert")))
(packages->manifest
(cons modified-python-pandas
standard-packages))
(specifications->manifest
'("jupyter"
"python-matplotlib"
"python-numpy"
"python-pandas"
"python-statsmodels"
"python-nbconvert"))
(use-modules (guix packages)
(guix download)
(guix build-system python)
(gnu packages python-science))
(package
(inherit python-pandas)
(version "0.25.1")
(source
(origin
(method url-fetch)
(uri (pypi-uri "pandas" version))
(sha256
(base32
"1xm9dmbngsq46vj836csnb5j0bs88b1d713b0b5vx1q6gdxijbnb")))))
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Analyse du risque de défaillance des joints toriques de la navette Challenger"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le 27 Janvier 1986, veille du décollage de la navette *Challenger*, eu\n",
"lieu une télé-conférence de trois heures entre les ingénieurs de la\n",
"Morton Thiokol (constructeur d'un des moteurs) et de la NASA. La\n",
"discussion portait principalement sur les conséquences de la\n",
"température prévue au moment du décollage de 31°F (juste en dessous de\n",
"0°C) sur le succès du vol et en particulier sur la performance des\n",
"joints toriques utilisés dans les moteurs. En effet, aucun test\n",
"n'avait été effectué à cette température.\n",
"\n",
"L'étude qui suit reprend donc une partie des analyses effectuées cette\n",
"nuit là et dont l'objectif était d'évaluer l'influence potentielle de\n",
"la température et de la pression à laquelle sont soumis les joints\n",
"toriques sur leur probabilité de dysfonctionnement. Pour cela, nous\n",
"disposons des résultats des expériences réalisées par les ingénieurs\n",
"de la NASA durant les 6 années précédant le lancement de la navette\n",
"Challenger.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Chargement des données\n",
"Nous commençons donc par charger ces données:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Count</th>\n",
" <th>Temperature</th>\n",
" <th>Pressure</th>\n",
" <th>Malfunction</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>4/12/81</td>\n",
" <td>6</td>\n",
" <td>66</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>11/12/81</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>50</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3/22/82</td>\n",
" <td>6</td>\n",
" <td>69</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>11/11/82</td>\n",
" <td>6</td>\n",
" <td>68</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>4/04/83</td>\n",
" <td>6</td>\n",
" <td>67</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>6/18/82</td>\n",
" <td>6</td>\n",
" <td>72</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>8/30/83</td>\n",
" <td>6</td>\n",
" <td>73</td>\n",
" <td>100</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>11/28/83</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>100</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>2/03/84</td>\n",
" <td>6</td>\n",
" <td>57</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>4/06/84</td>\n",
" <td>6</td>\n",
" <td>63</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>8/30/84</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>10/05/84</td>\n",
" <td>6</td>\n",
" <td>78</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>11/08/84</td>\n",
" <td>6</td>\n",
" <td>67</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>1/24/85</td>\n",
" <td>6</td>\n",
" <td>53</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>4/12/85</td>\n",
" <td>6</td>\n",
" <td>67</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>4/29/85</td>\n",
" <td>6</td>\n",
" <td>75</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>6/17/85</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>7/2903/85</td>\n",
" <td>6</td>\n",
" <td>81</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>8/27/85</td>\n",
" <td>6</td>\n",
" <td>76</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>10/03/85</td>\n",
" <td>6</td>\n",
" <td>79</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>20</th>\n",
" <td>10/30/85</td>\n",
" <td>6</td>\n",
" <td>75</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>21</th>\n",
" <td>11/26/85</td>\n",
" <td>6</td>\n",
" <td>76</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>1/12/86</td>\n",
" <td>6</td>\n",
" <td>58</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Count Temperature Pressure Malfunction\n",
"0 4/12/81 6 66 50 0\n",
"1 11/12/81 6 70 50 1\n",
"2 3/22/82 6 69 50 0\n",
"3 11/11/82 6 68 50 0\n",
"4 4/04/83 6 67 50 0\n",
"5 6/18/82 6 72 50 0\n",
"6 8/30/83 6 73 100 0\n",
"7 11/28/83 6 70 100 0\n",
"8 2/03/84 6 57 200 1\n",
"9 4/06/84 6 63 200 1\n",
"10 8/30/84 6 70 200 1\n",
"11 10/05/84 6 78 200 0\n",
"12 11/08/84 6 67 200 0\n",
"13 1/24/85 6 53 200 2\n",
"14 4/12/85 6 67 200 0\n",
"15 4/29/85 6 75 200 0\n",
"16 6/17/85 6 70 200 0\n",
"17 7/2903/85 6 81 200 0\n",
"18 8/27/85 6 76 200 0\n",
"19 10/03/85 6 79 200 0\n",
"20 10/30/85 6 75 200 2\n",
"21 11/26/85 6 76 200 0\n",
"22 1/12/86 6 58 200 1"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"data = pd.read_csv(\"shuttle.csv\")\n",
"data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le jeu de données nous indique la date de l'essai, le nombre de joints\n",
"toriques mesurés (il y en a 6 sur le lançeur principal), la\n",
"température (en Farenheit) et la pression (en psi), et enfin le\n",
"nombre de dysfonctionnements relevés. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Inspection graphique des données\n",
"Les vols où aucun incident n'est relevé n'apportant aucun information\n",
"sur l'influence de la température ou de la pression sur les\n",
"dysfonctionnements, nous nous concentrons sur les expériences où au\n",
"moins un joint a été défectueux.\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Count</th>\n",
" <th>Temperature</th>\n",
" <th>Pressure</th>\n",
" <th>Malfunction</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>11/12/81</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>50</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>2/03/84</td>\n",
" <td>6</td>\n",
" <td>57</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>4/06/84</td>\n",
" <td>6</td>\n",
" <td>63</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>8/30/84</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>1/24/85</td>\n",
" <td>6</td>\n",
" <td>53</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>20</th>\n",
" <td>10/30/85</td>\n",
" <td>6</td>\n",
" <td>75</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>1/12/86</td>\n",
" <td>6</td>\n",
" <td>58</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Count Temperature Pressure Malfunction\n",
"1 11/12/81 6 70 50 1\n",
"8 2/03/84 6 57 200 1\n",
"9 4/06/84 6 63 200 1\n",
"10 8/30/84 6 70 200 1\n",
"13 1/24/85 6 53 200 2\n",
"20 10/30/85 6 75 200 2\n",
"22 1/12/86 6 58 200 1"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = data[data.Malfunction>0]\n",
"data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Très bien, nous avons une variabilité de température importante mais\n",
"la pression est quasiment toujours égale à 200, ce qui devrait\n",
"simplifier l'analyse.\n",
"\n",
"Comment la fréquence d'échecs varie-t-elle avec la température ?\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"pd.set_option('mode.chained_assignment',None) # this removes a useless warning from pandas\n",
"import matplotlib.pyplot as plt\n",
"\n",
"data[\"Frequency\"]=data.Malfunction/data.Count\n",
"data.plot(x=\"Temperature\",y=\"Frequency\",kind=\"scatter\",ylim=[0,1])\n",
"plt.grid(True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"À première vue, ce n'est pas flagrant mais bon, essayons quand même\n",
"d'estimer l'impact de la température $t$ sur la probabilité de\n",
"dysfonctionnements d'un joint. \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Estimation de l'influence de la température\n",
"\n",
"Supposons que chacun des 6 joints toriques est endommagé avec la même\n",
"probabilité et indépendamment des autres et que cette probabilité ne\n",
"dépend que de la température. Si on note $p(t)$ cette probabilité, le\n",
"nombre de joints $D$ dysfonctionnant lorsque l'on effectue le vol à\n",
"température $t$ suit une loi binomiale de paramètre $n=6$ et\n",
"$p=p(t)$. Pour relier $p(t)$ à $t$, on va donc effectuer une\n",
"régression logistique."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/ipykernel_launcher.py:6: DeprecationWarning: Calling Family(..) with a link class as argument is deprecated.\n",
"Use an instance of a link class instead.\n",
" \n"
]
},
{
"data": {
"text/html": [
"<table class=\"simpletable\">\n",
"<caption>Generalized Linear Model Regression Results</caption>\n",
"<tr>\n",
" <th>Dep. Variable:</th> <td>Frequency</td> <th> No. Observations: </th> <td> 7</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Model:</th> <td>GLM</td> <th> Df Residuals: </th> <td> 5</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Model Family:</th> <td>Binomial</td> <th> Df Model: </th> <td> 1</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Link Function:</th> <td>logit</td> <th> Scale: </th> <td> 1.0000</td>\n",
"</tr>\n",
"<tr>\n",
" <th>Method:</th> <td>IRLS</td> <th> Log-Likelihood: </th> <td> -2.5250</td>\n",
"</tr>\n",
"<tr>\n",
" <th>Date:</th> <td>Tue, 20 Aug 2019</td> <th> Deviance: </th> <td> 0.22231</td>\n",
"</tr>\n",
"<tr>\n",
" <th>Time:</th> <td>09:05:05</td> <th> Pearson chi2: </th> <td> 0.236</td> \n",
"</tr>\n",
"<tr>\n",
" <th>No. Iterations:</th> <td>4</td> <th> </th> <td> </td> \n",
"</tr>\n",
"<tr>\n",
" <th>Covariance Type:</th> <td>nonrobust</td> <th> </th> <td> </td> \n",
"</tr>\n",
"</table>\n",
"<table class=\"simpletable\">\n",
"<tr>\n",
" <td></td> <th>coef</th> <th>std err</th> <th>z</th> <th>P>|z|</th> <th>[0.025</th> <th>0.975]</th> \n",
"</tr>\n",
"<tr>\n",
" <th>Intercept</th> <td> -1.3895</td> <td> 7.828</td> <td> -0.178</td> <td> 0.859</td> <td> -16.732</td> <td> 13.953</td>\n",
"</tr>\n",
"<tr>\n",
" <th>Temperature</th> <td> 0.0014</td> <td> 0.122</td> <td> 0.012</td> <td> 0.991</td> <td> -0.238</td> <td> 0.240</td>\n",
"</tr>\n",
"</table>"
],
"text/plain": [
"<class 'statsmodels.iolib.summary.Summary'>\n",
"\"\"\"\n",
" Generalized Linear Model Regression Results \n",
"==============================================================================\n",
"Dep. Variable: Frequency No. Observations: 7\n",
"Model: GLM Df Residuals: 5\n",
"Model Family: Binomial Df Model: 1\n",
"Link Function: logit Scale: 1.0000\n",
"Method: IRLS Log-Likelihood: -2.5250\n",
"Date: Tue, 20 Aug 2019 Deviance: 0.22231\n",
"Time: 09:05:05 Pearson chi2: 0.236\n",
"No. Iterations: 4 \n",
"Covariance Type: nonrobust \n",
"===============================================================================\n",
" coef std err z P>|z| [0.025 0.975]\n",
"-------------------------------------------------------------------------------\n",
"Intercept -1.3895 7.828 -0.178 0.859 -16.732 13.953\n",
"Temperature 0.0014 0.122 0.012 0.991 -0.238 0.240\n",
"===============================================================================\n",
"\"\"\""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import statsmodels.api as sm\n",
"\n",
"data[\"Success\"]=data.Count-data.Malfunction\n",
"data[\"Intercept\"]=1\n",
"\n",
"logmodel=sm.GLM(data['Frequency'], data[['Intercept','Temperature']], family=sm.families.Binomial(sm.families.links.logit)).fit()\n",
"\n",
"logmodel.summary()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"L'estimateur le plus probable du paramètre de température est 0.0014\n",
"et l'erreur standard de cet estimateur est de 0.122, autrement dit on\n",
"ne peut pas distinguer d'impact particulier et il faut prendre nos\n",
"estimations avec des pincettes.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Estimation de la probabilité de dysfonctionnant des joints toriques\n",
"La température prévue le jour du décollage est de 31°F. Essayons\n",
"d'estimer la probabilité de dysfonctionnement des joints toriques à\n",
"cette température à partir du modèle que nous venons de construire:\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEKCAYAAAAcgp5RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAay0lEQVR4nO3dfZRU9Z3n8fenGwgNIoxIMgoayBzSrhsVMYDK6PYYBc2JT7tRJM6YuMMSd2Iy2T1ho+dkVjPRc3YO7hwzGSOyhnGMGR/GVdQcJqBuOs64PqABQSQ8rCHSkAQxo9DaKN393T/u7aa6upuuLqof6ufndU6frnvrd299v1Vdn7p969YtRQRmZpaumqEuwMzMBpaD3swscQ56M7PEOejNzBLnoDczS5yD3swscX0GvaQVkvZIerWX6yXpbyRtl7RB0szKl2lmZuUqZYv+HuDCw1x/ETA9/1kM3HnkZZmZWaX0GfQR8Qzwu8MMuRS4NzLPAxMkHVepAs3M7MiMqMA6JgM7C6ab8nm/Lh4oaTHZVj+jR48+48QTT6zAzQ9P7e3t1NSk+xaI+6teKfcG6fe3devWvRExqT/LVCLo1cO8Hs+rEBHLgeUA9fX1sWXLlgrc/PDU2NhIQ0PDUJcxYNxf9Uq5N0i/P0m/6u8ylXjZawJOKJieAuyuwHrNzKwCKhH0jwPX5EffnAm8ExHddtuYmdnQ6HPXjaT7gQbgWElNwE3ASICIWAasAj4LbAfeA64dqGLNzKz/+gz6iFjYx/UBfKViFZlZVTh48CBNTU0cOHBgqEvpYvz48WzevHmoyzhio0ePZsqUKYwcOfKI11WJN2PN7EOoqamJcePGMXXqVKSejskYGvv372fcuHFDXcYRiQjeeustmpqamDZt2hGvL91jkMxsQB04cICJEycOq5BPhSQmTpxYsf+WHPRmVjaH/MCp5H3roDczS5z30ZtZ1aqtreWUU07pnF65ciUTJ04cwoqGJwe9mVWturo61q9f32Xe/v37Oy+3trYyYoRjzrtuzCwpP/rRj7jiiiu4+OKLmTdvHgBLly5l1qxZnHrqqdx0002dY2+99Vbq6+s5//zzWbhwIbfddhsADQ0NvPTSSwDs3buXqVOnAtDW1saSJUs613XXXXcBh0678PnPf56TTjqJq6++muzIc1i7di1nn302p512GrNnz2b//v2cc845XV6g5s6dy4YNGwbsPvFLnZkdsW8/sYnXdu+r6DpPPv5obrr43x52TEtLCzNmzABg2rRpPProowA899xzbNiwgWOOOYY1a9awbds2XnzxRSKCSy65hGeeeYaxY8fywAMPsG7dOlpbW5k5cyZnnHHGYW/vBz/4AePHj2ft2rW8//77zJ07t/PFZN26dWzatInjjz+euXPn8uyzzzJ79mwWLFjAgw8+yKxZs9i3bx91dXUsWrSIe+65h9tvv52tW7fy/vvvc+qpp1bgXuuZg97MqlZPu24ALrjgAo455hgA1qxZw5o1azj99NMBaG5uZtu2bezfv5/LL7+cMWPGAHDJJZf0eXtr1qxhw4YNPPzwwwC88847bNu2jVGjRjF79mymTJkCwIwZM9ixYwfjx4/nuOOOY9asWQAcffTRAFxxxRV85zvfYenSpaxYsYIvfelLR3ZH9MFBb2ZHrK8t78E2duzYzssRwY033siXv/zlLmNuv/32Xg9hHDFiBO3t7QBdjmWPCL73ve8xf/78LuMbGxv5yEc+0jldW1tLa2srEdHjbYwZM4YLLriAxx57jIceeqhzN9FA8T56M0va/PnzWbFiBc3NzQDs2rWLPXv2cO655/Loo4/S0tLC/v37eeKJJzqXmTp1Ki+//DJA59Z7x7ruvPNODh48CMDWrVt59913e73tk046id27d7N27Voge6O4tbUVgEWLFvG1r32NWbNmdf73MVC8RW9mSZs3bx6bN2/mrLPOAuCoo47ivvvuY+bMmSxYsIAZM2bw8Y9/nHPOOadzmW984xtceeWV/PCHP+S8887rnL9o0SJ27NjBzJkziQgmTZrEypUre73tUaNG8eCDD/LVr36VlpYW6urqeOqppzjqqKM444wzOProo7n22kE4D2REDMnPJz/5yUjZT3/606EuYUC5v+pVqd5ee+21iqyn0vbt21fWcjfddFMsXbq0wtX0bteuXTF9+vRoa2vrdUxP9zHwUvQzb73rxsxskN17773MmTOHW2+9dVC+9tC7bszMgJtvvnnQbuuaa67hmmuuGbTb8xa9mZUtosevh7YKqOR966A3s7KMHj2at956y2E/ACI/H/3o0aMrsj7vujGzskyZMoWmpibefPPNoS6liwMHDlQsIIdSxzdMVYKD3szKMnLkyIp8+1Gl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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"data_pred = pd.DataFrame({'Temperature': np.linspace(start=30, stop=90, num=121), 'Intercept': 1})\n",
"data_pred['Frequency'] = logmodel.predict(data_pred[['Intercept','Temperature']])\n",
"data_pred.plot(x=\"Temperature\",y=\"Frequency\",kind=\"line\",ylim=[0,1])\n",
"plt.scatter(x=data[\"Temperature\"],y=data[\"Frequency\"])\n",
"plt.grid(True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"hideCode": false,
"hidePrompt": false,
"scrolled": true
},
"source": [
"Comme on pouvait s'attendre au vu des données initiales, la\n",
"température n'a pas d'impact notable sur la probabilité d'échec des\n",
"joints toriques. Elle sera d'environ 0.2, comme dans les essais\n",
"précédents où nous il y a eu défaillance d'au moins un joint. Revenons\n",
"à l'ensemble des données initiales pour estimer la probabilité de\n",
"défaillance d'un joint:\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.06521739130434782\n"
]
}
],
"source": [
"data = pd.read_csv(\"shuttle.csv\")\n",
"print(np.sum(data.Malfunction)/np.sum(data.Count))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cette probabilité est donc d'environ $p=0.065$, sachant qu'il existe\n",
"un joint primaire un joint secondaire sur chacune des trois parties du\n",
"lançeur, la probabilité de défaillance des deux joints d'un lançeur\n",
"est de $p^2 \\approx 0.00425$. La probabilité de défaillance d'un des\n",
"lançeur est donc de $1-(1-p^2)^3 \\approx 1.2%$. Ça serait vraiment\n",
"pas de chance... Tout est sous contrôle, le décollage peut donc avoir\n",
"lieu demain comme prévu.\n",
"\n",
"Seulement, le lendemain, la navette Challenger explosera et emportera\n",
"avec elle ses sept membres d'équipages. L'opinion publique est\n",
"fortement touchée et lors de l'enquête qui suivra, la fiabilité des\n",
"joints toriques sera directement mise en cause. Au delà des problèmes\n",
"de communication interne à la NASA qui sont pour beaucoup dans ce\n",
"fiasco, l'analyse précédente comporte (au moins) un petit\n",
"problème... Saurez-vous le trouver ? Vous êtes libre de modifier cette\n",
"analyse et de regarder ce jeu de données sous tous les angles afin\n",
"d'expliquer ce qui ne va pas."
]
}
],
"metadata": {
"celltoolbar": "Hide code",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Analyse du risque de défaillance des joints toriques de la navette Challenger"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le 27 Janvier 1986, veille du décollage de la navette *Challenger*, eu\n",
"lieu une télé-conférence de trois heures entre les ingénieurs de la\n",
"Morton Thiokol (constructeur d'un des moteurs) et de la NASA. La\n",
"discussion portait principalement sur les conséquences de la\n",
"température prévue au moment du décollage de 31°F (juste en dessous de\n",
"0°C) sur le succès du vol et en particulier sur la performance des\n",
"joints toriques utilisés dans les moteurs. En effet, aucun test\n",
"n'avait été effectué à cette température.\n",
"\n",
"L'étude qui suit reprend donc une partie des analyses effectuées cette\n",
"nuit là et dont l'objectif était d'évaluer l'influence potentielle de\n",
"la température et de la pression à laquelle sont soumis les joints\n",
"toriques sur leur probabilité de dysfonctionnement. Pour cela, nous\n",
"disposons des résultats des expériences réalisées par les ingénieurs\n",
"de la NASA durant les 6 années précédant le lancement de la navette\n",
"Challenger.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Chargement des données\n",
"Nous commençons donc par charger ces données:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Count</th>\n",
" <th>Temperature</th>\n",
" <th>Pressure</th>\n",
" <th>Malfunction</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>4/12/81</td>\n",
" <td>6</td>\n",
" <td>66</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>11/12/81</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>50</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3/22/82</td>\n",
" <td>6</td>\n",
" <td>69</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>11/11/82</td>\n",
" <td>6</td>\n",
" <td>68</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>4/04/83</td>\n",
" <td>6</td>\n",
" <td>67</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>6/18/82</td>\n",
" <td>6</td>\n",
" <td>72</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>8/30/83</td>\n",
" <td>6</td>\n",
" <td>73</td>\n",
" <td>100</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>11/28/83</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>100</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>2/03/84</td>\n",
" <td>6</td>\n",
" <td>57</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>4/06/84</td>\n",
" <td>6</td>\n",
" <td>63</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>8/30/84</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>10/05/84</td>\n",
" <td>6</td>\n",
" <td>78</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>11/08/84</td>\n",
" <td>6</td>\n",
" <td>67</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>1/24/85</td>\n",
" <td>6</td>\n",
" <td>53</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>4/12/85</td>\n",
" <td>6</td>\n",
" <td>67</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>4/29/85</td>\n",
" <td>6</td>\n",
" <td>75</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>6/17/85</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>7/2903/85</td>\n",
" <td>6</td>\n",
" <td>81</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>8/27/85</td>\n",
" <td>6</td>\n",
" <td>76</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>10/03/85</td>\n",
" <td>6</td>\n",
" <td>79</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>20</th>\n",
" <td>10/30/85</td>\n",
" <td>6</td>\n",
" <td>75</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>21</th>\n",
" <td>11/26/85</td>\n",
" <td>6</td>\n",
" <td>76</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>1/12/86</td>\n",
" <td>6</td>\n",
" <td>58</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Count Temperature Pressure Malfunction\n",
"0 4/12/81 6 66 50 0\n",
"1 11/12/81 6 70 50 1\n",
"2 3/22/82 6 69 50 0\n",
"3 11/11/82 6 68 50 0\n",
"4 4/04/83 6 67 50 0\n",
"5 6/18/82 6 72 50 0\n",
"6 8/30/83 6 73 100 0\n",
"7 11/28/83 6 70 100 0\n",
"8 2/03/84 6 57 200 1\n",
"9 4/06/84 6 63 200 1\n",
"10 8/30/84 6 70 200 1\n",
"11 10/05/84 6 78 200 0\n",
"12 11/08/84 6 67 200 0\n",
"13 1/24/85 6 53 200 2\n",
"14 4/12/85 6 67 200 0\n",
"15 4/29/85 6 75 200 0\n",
"16 6/17/85 6 70 200 0\n",
"17 7/2903/85 6 81 200 0\n",
"18 8/27/85 6 76 200 0\n",
"19 10/03/85 6 79 200 0\n",
"20 10/30/85 6 75 200 2\n",
"21 11/26/85 6 76 200 0\n",
"22 1/12/86 6 58 200 1"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"data = pd.read_csv(\"shuttle.csv\")\n",
"data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le jeu de données nous indique la date de l'essai, le nombre de joints\n",
"toriques mesurés (il y en a 6 sur le lançeur principal), la\n",
"température (en Farenheit) et la pression (en psi), et enfin le\n",
"nombre de dysfonctionnements relevés. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Inspection graphique des données\n",
"Les vols où aucun incident n'est relevé n'apportant aucun information\n",
"sur l'influence de la température ou de la pression sur les\n",
"dysfonctionnements, nous nous concentrons sur les expériences où au\n",
"moins un joint a été défectueux.\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Count</th>\n",
" <th>Temperature</th>\n",
" <th>Pressure</th>\n",
" <th>Malfunction</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>11/12/81</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>50</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>2/03/84</td>\n",
" <td>6</td>\n",
" <td>57</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>4/06/84</td>\n",
" <td>6</td>\n",
" <td>63</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>8/30/84</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>1/24/85</td>\n",
" <td>6</td>\n",
" <td>53</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>20</th>\n",
" <td>10/30/85</td>\n",
" <td>6</td>\n",
" <td>75</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>1/12/86</td>\n",
" <td>6</td>\n",
" <td>58</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Count Temperature Pressure Malfunction\n",
"1 11/12/81 6 70 50 1\n",
"8 2/03/84 6 57 200 1\n",
"9 4/06/84 6 63 200 1\n",
"10 8/30/84 6 70 200 1\n",
"13 1/24/85 6 53 200 2\n",
"20 10/30/85 6 75 200 2\n",
"22 1/12/86 6 58 200 1"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = data[data.Malfunction>0]\n",
"data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Très bien, nous avons une variabilité de température importante mais\n",
"la pression est quasiment toujours égale à 200, ce qui devrait\n",
"simplifier l'analyse.\n",
"\n",
"Comment la fréquence d'échecs varie-t-elle avec la température ?\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"pd.set_option('mode.chained_assignment',None) # this removes a useless warning from pandas\n",
"import matplotlib.pyplot as plt\n",
"\n",
"data[\"Frequency\"]=data.Malfunction/data.Count\n",
"data.plot(x=\"Temperature\",y=\"Frequency\",kind=\"scatter\",ylim=[0,1])\n",
"plt.grid(True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"À première vue, ce n'est pas flagrant mais bon, essayons quand même\n",
"d'estimer l'impact de la température $t$ sur la probabilité de\n",
"dysfonctionnements d'un joint. \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Estimation de l'influence de la température\n",
"\n",
"Supposons que chacun des 6 joints toriques est endommagé avec la même\n",
"probabilité et indépendamment des autres et que cette probabilité ne\n",
"dépend que de la température. Si on note $p(t)$ cette probabilité, le\n",
"nombre de joints $D$ dysfonctionnant lorsque l'on effectue le vol à\n",
"température $t$ suit une loi binomiale de paramètre $n=6$ et\n",
"$p=p(t)$. Pour relier $p(t)$ à $t$, on va donc effectuer une\n",
"régression logistique."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<table class=\"simpletable\">\n",
"<caption>Generalized Linear Model Regression Results</caption>\n",
"<tr>\n",
" <th>Dep. Variable:</th> <td>Frequency</td> <th> No. Observations: </th> <td> 7</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Model:</th> <td>GLM</td> <th> Df Residuals: </th> <td> 5</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Model Family:</th> <td>Binomial</td> <th> Df Model: </th> <td> 1</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Link Function:</th> <td>logit</td> <th> Scale: </th> <td> 1.0000</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Method:</th> <td>IRLS</td> <th> Log-Likelihood: </th> <td> -2.5250</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Date:</th> <td>Sat, 13 Apr 2019</td> <th> Deviance: </th> <td> 0.22231</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Time:</th> <td>19:11:24</td> <th> Pearson chi2: </th> <td> 0.236</td> \n",
"</tr>\n",
"<tr>\n",
" <th>No. Iterations:</th> <td>4</td> <th> Covariance Type: </th> <td>nonrobust</td>\n",
"</tr>\n",
"</table>\n",
"<table class=\"simpletable\">\n",
"<tr>\n",
" <td></td> <th>coef</th> <th>std err</th> <th>z</th> <th>P>|z|</th> <th>[0.025</th> <th>0.975]</th> \n",
"</tr>\n",
"<tr>\n",
" <th>Intercept</th> <td> -1.3895</td> <td> 7.828</td> <td> -0.178</td> <td> 0.859</td> <td> -16.732</td> <td> 13.953</td>\n",
"</tr>\n",
"<tr>\n",
" <th>Temperature</th> <td> 0.0014</td> <td> 0.122</td> <td> 0.012</td> <td> 0.991</td> <td> -0.238</td> <td> 0.240</td>\n",
"</tr>\n",
"</table>"
],
"text/plain": [
"<class 'statsmodels.iolib.summary.Summary'>\n",
"\"\"\"\n",
" Generalized Linear Model Regression Results \n",
"==============================================================================\n",
"Dep. Variable: Frequency No. Observations: 7\n",
"Model: GLM Df Residuals: 5\n",
"Model Family: Binomial Df Model: 1\n",
"Link Function: logit Scale: 1.0000\n",
"Method: IRLS Log-Likelihood: -2.5250\n",
"Date: Sat, 13 Apr 2019 Deviance: 0.22231\n",
"Time: 19:11:24 Pearson chi2: 0.236\n",
"No. Iterations: 4 Covariance Type: nonrobust\n",
"===============================================================================\n",
" coef std err z P>|z| [0.025 0.975]\n",
"-------------------------------------------------------------------------------\n",
"Intercept -1.3895 7.828 -0.178 0.859 -16.732 13.953\n",
"Temperature 0.0014 0.122 0.012 0.991 -0.238 0.240\n",
"===============================================================================\n",
"\"\"\""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import statsmodels.api as sm\n",
"\n",
"data[\"Success\"]=data.Count-data.Malfunction\n",
"data[\"Intercept\"]=1\n",
"\n",
"logmodel=sm.GLM(data['Frequency'], data[['Intercept','Temperature']], family=sm.families.Binomial(sm.families.links.logit)).fit()\n",
"\n",
"logmodel.summary()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"L'estimateur le plus probable du paramètre de température est 0.0014\n",
"et l'erreur standard de cet estimateur est de 0.122, autrement dit on\n",
"ne peut pas distinguer d'impact particulier et il faut prendre nos\n",
"estimations avec des pincettes.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Estimation de la probabilité de dysfonctionnant des joints toriques\n",
"La température prévue le jour du décollage est de 31°F. Essayons\n",
"d'estimer la probabilité de dysfonctionnement des joints toriques à\n",
"cette température à partir du modèle que nous venons de construire:\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEKCAYAAAAcgp5RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAGyFJREFUeJzt3X2UVPWd5/H3pxuQBhEjkhkFDWSWtHF9ABRQWZ3WqGhORLPrE2vGMRNCdmeMk83Knng2E43Rc2YHd2I26zgy6jgxiUo8iiSHCahjT2Y8PoCCILAIY4g2JEGND7Q2Snd/9497u6kuqunqpvqhfnxe5/Tpurd+de/3V7fvp27fuvUrRQRmZpaumsEuwMzM+peD3swscQ56M7PEOejNzBLnoDczS5yD3swscT0GvaR7Je2U9HI390vS/5G0VdI6SdMrX6aZmfVVOUf09wEX7Of+C4Ep+c8C4M4DL8vMzCqlx6CPiF8Av9tPk4uBH0TmWeBwSUdVqkAzMzswwyqwjAnA6wXTTfm8Xxc3lLSA7KifkSNHnnLsscdWYPVDU3t7OzU16b4FknL/Uu4buH/V7pVXXnkzIsb35jGVCHqVmFdyXIWIWAwsBqivr4/NmzdXYPVDU2NjIw0NDYNdRr9JuX8p9w3cv2on6Ve9fUwlXvaagGMKpicCOyqwXDMzq4BKBP0y4Or86pvTgHcjYp/TNmZmNjh6PHUj6QGgAThSUhNwIzAcICL+FlgOfBbYCnwAfLG/ijUzs97rMegjYl4P9wfwZxWryMyqwp49e2hqamL37t2DXUoXY8eOZdOmTYNdxgEbOXIkEydOZPjw4Qe8rEq8GWtmB6GmpibGjBnDpEmTkEpdkzE4du3axZgxYwa7jAMSEbz11ls0NTUxefLkA15eutcgmVm/2r17N+PGjRtSIZ8KSYwbN65i/y056M2szxzy/aeSz62D3swscT5Hb2ZVq7a2lhNPPLFzeunSpYwbN24QKxqaHPRmVrXq6upYu3Ztl3m7du3qvN3a2sqwYY45n7oxs6T86Ec/4rLLLuOiiy7i/PPPB2DRokXMmDGDk046iRtvvLGz7a233kp9fT3nnnsu8+bN47bbbgOgoaGB1atXA/Dmm28yadIkANra2li4cGHnsu666y5g77ALl156KccddxxXXXUV2ZXnsGrVKs444wxOPvlkZs6cya5duzjzzDO7vEDNnj2bdevW9dtz4pc6Mztg3/7pBjbueK+iyzz+6MO48aJ/v982LS0tTJ06FYDJkyfz6KOPAvDMM8+wbt06jjjiCFauXMmWLVt4/vnniQjmzp3LL37xC0aPHs2DDz7ImjVraG1tZfr06Zxyyin7Xd8999zD2LFjWbVqFR9++CGzZ8/ufDFZs2YNGzZs4Oijj2b27Nk8/fTTzJw5kyuuuIKHHnqIGTNm8N5771FXV8f8+fO57777uP3223nllVf48MMPOemkkyrwrJXmoDezqlXq1A3AeeedxxFHHAHAypUrWblyJdOmTQOgubmZLVu2sGvXLj7/+c8zatQoAObOndvj+lauXMm6det4+OGHAXj33XfZsmULI0aMYObMmUycOBGAqVOnsm3bNsaOHctRRx3FjBkzADjssMMAuOyyy/jOd77DokWLuPfee7nmmmsO7InogYPezA5YT0feA2306NGdtyOCG264ga985Std2tx+++3dXsI4bNgw2tvbAbpcyx4RfP/732fOnDld2jc2NnLIIYd0TtfW1tLa2kpElFzHqFGjOO+883jsscdYsmRJ52mi/uJz9GaWtDlz5nDvvffS3NwMwPbt29m5cydnnXUWjz76KC0tLezatYuf/vSnnY+ZNGkSL7zwAkDn0XvHsu6880727NkDwCuvvML777/f7bqPO+44duzYwapVq4DsjeLW1lYA5s+fz3XXXceMGTM6//voLz6iN7OknX/++WzatInTTz8dgEMPPZQf/vCHTJ8+nSuuuIKpU6fyiU98gjPPPLPzMddffz2XX345999/P+ecc07n/Pnz57Nt2zamT59ORDB+/HiWLl3a7bpHjBjBQw89xFe/+lVaWlqoq6vjiSee4NBDD+WUU07hsMMO44tfHIBxICNiUH4+9alPRcqeeuqpwS6hX6Xcv5T7FlG5/m3cuLEiy6m09957r0+Pu/HGG2PRokUVrqZ727dvjylTpkRbW1u3bUo9x8Dq6GXe+tSNmdkA+8EPfsCsWbO49dZbB+RrD33qxswMuOmmmwZsXVdffTVXX331gK3PR/Rm1mcRJb8e2iqgks+tg97M+mTkyJG89dZbDvt+EPl49CNHjqzI8nzqxsz6ZOLEiTQ1NfHGG28Mdild7N69u2IBOZg6vmGqEhz0ZtYnw4cP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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"data_pred = pd.DataFrame({'Temperature': np.linspace(start=30, stop=90, num=121), 'Intercept': 1})\n",
"data_pred['Frequency'] = logmodel.predict(data_pred[['Intercept','Temperature']])\n",
"data_pred.plot(x=\"Temperature\",y=\"Frequency\",kind=\"line\",ylim=[0,1])\n",
"plt.scatter(x=data[\"Temperature\"],y=data[\"Frequency\"])\n",
"plt.grid(True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"hideCode": false,
"hidePrompt": false,
"scrolled": true
},
"source": [
"Comme on pouvait s'attendre au vu des données initiales, la\n",
"température n'a pas d'impact notable sur la probabilité d'échec des\n",
"joints toriques. Elle sera d'environ 0.2, comme dans les essais\n",
"précédents où nous il y a eu défaillance d'au moins un joint. Revenons\n",
"à l'ensemble des données initiales pour estimer la probabilité de\n",
"défaillance d'un joint:\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.06521739130434782\n"
]
}
],
"source": [
"data = pd.read_csv(\"shuttle.csv\")\n",
"print(np.sum(data.Malfunction)/np.sum(data.Count))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cette probabilité est donc d'environ $p=0.065$, sachant qu'il existe\n",
"un joint primaire un joint secondaire sur chacune des trois parties du\n",
"lançeur, la probabilité de défaillance des deux joints d'un lançeur\n",
"est de $p^2 \\approx 0.00425$. La probabilité de défaillance d'un des\n",
"lançeur est donc de $1-(1-p^2)^3 \\approx 1.2%$. Ça serait vraiment\n",
"pas de chance... Tout est sous contrôle, le décollage peut donc avoir\n",
"lieu demain comme prévu.\n",
"\n",
"Seulement, le lendemain, la navette Challenger explosera et emportera\n",
"avec elle ses sept membres d'équipages. L'opinion publique est\n",
"fortement touchée et lors de l'enquête qui suivra, la fiabilité des\n",
"joints toriques sera directement mise en cause. Au delà des problèmes\n",
"de communication interne à la NASA qui sont pour beaucoup dans ce\n",
"fiasco, l'analyse précédente comporte (au moins) un petit\n",
"problème... Saurez-vous le trouver ? Vous êtes libre de modifier cette\n",
"analyse et de regarder ce jeu de données sous tous les angles afin\n",
"d'expliquer ce qui ne va pas."
]
}
],
"metadata": {
"celltoolbar": "Hide code",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Analyse du risque de défaillance des joints toriques de la navette Challenger"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le 27 Janvier 1986, veille du décollage de la navette *Challenger*, eu\n",
"lieu une télé-conférence de trois heures entre les ingénieurs de la\n",
"Morton Thiokol (constructeur d'un des moteurs) et de la NASA. La\n",
"discussion portait principalement sur les conséquences de la\n",
"température prévue au moment du décollage de 31°F (juste en dessous de\n",
"0°C) sur le succès du vol et en particulier sur la performance des\n",
"joints toriques utilisés dans les moteurs. En effet, aucun test\n",
"n'avait été effectué à cette température.\n",
"\n",
"L'étude qui suit reprend donc une partie des analyses effectuées cette\n",
"nuit là et dont l'objectif était d'évaluer l'influence potentielle de\n",
"la température et de la pression à laquelle sont soumis les joints\n",
"toriques sur leur probabilité de dysfonctionnement. Pour cela, nous\n",
"disposons des résultats des expériences réalisées par les ingénieurs\n",
"de la NASA durant les 6 années précédant le lancement de la navette\n",
"Challenger.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Chargement des données\n",
"Nous commençons donc par charger ces données:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Count</th>\n",
" <th>Temperature</th>\n",
" <th>Pressure</th>\n",
" <th>Malfunction</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>4/12/81</td>\n",
" <td>6</td>\n",
" <td>66</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>11/12/81</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>50</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3/22/82</td>\n",
" <td>6</td>\n",
" <td>69</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>11/11/82</td>\n",
" <td>6</td>\n",
" <td>68</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>4/04/83</td>\n",
" <td>6</td>\n",
" <td>67</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>6/18/82</td>\n",
" <td>6</td>\n",
" <td>72</td>\n",
" <td>50</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>8/30/83</td>\n",
" <td>6</td>\n",
" <td>73</td>\n",
" <td>100</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>11/28/83</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>100</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>2/03/84</td>\n",
" <td>6</td>\n",
" <td>57</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>4/06/84</td>\n",
" <td>6</td>\n",
" <td>63</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>8/30/84</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>10/05/84</td>\n",
" <td>6</td>\n",
" <td>78</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>11/08/84</td>\n",
" <td>6</td>\n",
" <td>67</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>1/24/85</td>\n",
" <td>6</td>\n",
" <td>53</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>4/12/85</td>\n",
" <td>6</td>\n",
" <td>67</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>4/29/85</td>\n",
" <td>6</td>\n",
" <td>75</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>6/17/85</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>7/2903/85</td>\n",
" <td>6</td>\n",
" <td>81</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>8/27/85</td>\n",
" <td>6</td>\n",
" <td>76</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>10/03/85</td>\n",
" <td>6</td>\n",
" <td>79</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>20</th>\n",
" <td>10/30/85</td>\n",
" <td>6</td>\n",
" <td>75</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>21</th>\n",
" <td>11/26/85</td>\n",
" <td>6</td>\n",
" <td>76</td>\n",
" <td>200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>1/12/86</td>\n",
" <td>6</td>\n",
" <td>58</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Count Temperature Pressure Malfunction\n",
"0 4/12/81 6 66 50 0\n",
"1 11/12/81 6 70 50 1\n",
"2 3/22/82 6 69 50 0\n",
"3 11/11/82 6 68 50 0\n",
"4 4/04/83 6 67 50 0\n",
"5 6/18/82 6 72 50 0\n",
"6 8/30/83 6 73 100 0\n",
"7 11/28/83 6 70 100 0\n",
"8 2/03/84 6 57 200 1\n",
"9 4/06/84 6 63 200 1\n",
"10 8/30/84 6 70 200 1\n",
"11 10/05/84 6 78 200 0\n",
"12 11/08/84 6 67 200 0\n",
"13 1/24/85 6 53 200 2\n",
"14 4/12/85 6 67 200 0\n",
"15 4/29/85 6 75 200 0\n",
"16 6/17/85 6 70 200 0\n",
"17 7/2903/85 6 81 200 0\n",
"18 8/27/85 6 76 200 0\n",
"19 10/03/85 6 79 200 0\n",
"20 10/30/85 6 75 200 2\n",
"21 11/26/85 6 76 200 0\n",
"22 1/12/86 6 58 200 1"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"data = pd.read_csv(\"shuttle.csv\")\n",
"data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le jeu de données nous indique la date de l'essai, le nombre de joints\n",
"toriques mesurés (il y en a 6 sur le lançeur principal), la\n",
"température (en Farenheit) et la pression (en psi), et enfin le\n",
"nombre de dysfonctionnements relevés. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Inspection graphique des données\n",
"Les vols où aucun incident n'est relevé n'apportant aucun information\n",
"sur l'influence de la température ou de la pression sur les\n",
"dysfonctionnements, nous nous concentrons sur les expériences où au\n",
"moins un joint a été défectueux.\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Count</th>\n",
" <th>Temperature</th>\n",
" <th>Pressure</th>\n",
" <th>Malfunction</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>11/12/81</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>50</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>2/03/84</td>\n",
" <td>6</td>\n",
" <td>57</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>4/06/84</td>\n",
" <td>6</td>\n",
" <td>63</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>8/30/84</td>\n",
" <td>6</td>\n",
" <td>70</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>1/24/85</td>\n",
" <td>6</td>\n",
" <td>53</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>20</th>\n",
" <td>10/30/85</td>\n",
" <td>6</td>\n",
" <td>75</td>\n",
" <td>200</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>1/12/86</td>\n",
" <td>6</td>\n",
" <td>58</td>\n",
" <td>200</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Count Temperature Pressure Malfunction\n",
"1 11/12/81 6 70 50 1\n",
"8 2/03/84 6 57 200 1\n",
"9 4/06/84 6 63 200 1\n",
"10 8/30/84 6 70 200 1\n",
"13 1/24/85 6 53 200 2\n",
"20 10/30/85 6 75 200 2\n",
"22 1/12/86 6 58 200 1"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = data[data.Malfunction>0]\n",
"data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Très bien, nous avons une variabilité de température importante mais\n",
"la pression est quasiment toujours égale à 200, ce qui devrait\n",
"simplifier l'analyse.\n",
"\n",
"Comment la fréquence d'échecs varie-t-elle avec la température ?\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"pd.set_option('mode.chained_assignment',None) # this removes a useless warning from pandas\n",
"import matplotlib.pyplot as plt\n",
"\n",
"data[\"Frequency\"]=data.Malfunction/data.Count\n",
"data.plot(x=\"Temperature\",y=\"Frequency\",kind=\"scatter\",ylim=[0,1])\n",
"plt.grid(True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"À première vue, ce n'est pas flagrant mais bon, essayons quand même\n",
"d'estimer l'impact de la température $t$ sur la probabilité de\n",
"dysfonctionnements d'un joint. \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Estimation de l'influence de la température\n",
"\n",
"Supposons que chacun des 6 joints toriques est endommagé avec la même\n",
"probabilité et indépendamment des autres et que cette probabilité ne\n",
"dépend que de la température. Si on note $p(t)$ cette probabilité, le\n",
"nombre de joints $D$ dysfonctionnant lorsque l'on effectue le vol à\n",
"température $t$ suit une loi binomiale de paramètre $n=6$ et\n",
"$p=p(t)$. Pour relier $p(t)$ à $t$, on va donc effectuer une\n",
"régression logistique."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<table class=\"simpletable\">\n",
"<caption>Generalized Linear Model Regression Results</caption>\n",
"<tr>\n",
" <th>Dep. Variable:</th> <td>Frequency</td> <th> No. Observations: </th> <td> 7</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Model:</th> <td>GLM</td> <th> Df Residuals: </th> <td> 5</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Model Family:</th> <td>Binomial</td> <th> Df Model: </th> <td> 1</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Link Function:</th> <td>logit</td> <th> Scale: </th> <td> 1.0000</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Method:</th> <td>IRLS</td> <th> Log-Likelihood: </th> <td> -2.5250</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Date:</th> <td>Sat, 13 Apr 2019</td> <th> Deviance: </th> <td> 0.22231</td> \n",
"</tr>\n",
"<tr>\n",
" <th>Time:</th> <td>19:11:24</td> <th> Pearson chi2: </th> <td> 0.236</td> \n",
"</tr>\n",
"<tr>\n",
" <th>No. Iterations:</th> <td>4</td> <th> Covariance Type: </th> <td>nonrobust</td>\n",
"</tr>\n",
"</table>\n",
"<table class=\"simpletable\">\n",
"<tr>\n",
" <td></td> <th>coef</th> <th>std err</th> <th>z</th> <th>P>|z|</th> <th>[0.025</th> <th>0.975]</th> \n",
"</tr>\n",
"<tr>\n",
" <th>Intercept</th> <td> -1.3895</td> <td> 7.828</td> <td> -0.178</td> <td> 0.859</td> <td> -16.732</td> <td> 13.953</td>\n",
"</tr>\n",
"<tr>\n",
" <th>Temperature</th> <td> 0.0014</td> <td> 0.122</td> <td> 0.012</td> <td> 0.991</td> <td> -0.238</td> <td> 0.240</td>\n",
"</tr>\n",
"</table>"
],
"text/plain": [
"<class 'statsmodels.iolib.summary.Summary'>\n",
"\"\"\"\n",
" Generalized Linear Model Regression Results \n",
"==============================================================================\n",
"Dep. Variable: Frequency No. Observations: 7\n",
"Model: GLM Df Residuals: 5\n",
"Model Family: Binomial Df Model: 1\n",
"Link Function: logit Scale: 1.0000\n",
"Method: IRLS Log-Likelihood: -2.5250\n",
"Date: Sat, 13 Apr 2019 Deviance: 0.22231\n",
"Time: 19:11:24 Pearson chi2: 0.236\n",
"No. Iterations: 4 Covariance Type: nonrobust\n",
"===============================================================================\n",
" coef std err z P>|z| [0.025 0.975]\n",
"-------------------------------------------------------------------------------\n",
"Intercept -1.3895 7.828 -0.178 0.859 -16.732 13.953\n",
"Temperature 0.0014 0.122 0.012 0.991 -0.238 0.240\n",
"===============================================================================\n",
"\"\"\""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import statsmodels.api as sm\n",
"\n",
"data[\"Success\"]=data.Count-data.Malfunction\n",
"data[\"Intercept\"]=1\n",
"\n",
"logmodel=sm.GLM(data['Frequency'], data[['Intercept','Temperature']], family=sm.families.Binomial(sm.families.links.logit)).fit()\n",
"\n",
"logmodel.summary()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"L'estimateur le plus probable du paramètre de température est 0.0014\n",
"et l'erreur standard de cet estimateur est de 0.122, autrement dit on\n",
"ne peut pas distinguer d'impact particulier et il faut prendre nos\n",
"estimations avec des pincettes.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Estimation de la probabilité de dysfonctionnant des joints toriques\n",
"La température prévue le jour du décollage est de 31°F. Essayons\n",
"d'estimer la probabilité de dysfonctionnement des joints toriques à\n",
"cette température à partir du modèle que nous venons de construire:\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEKCAYAAAAcgp5RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAGyFJREFUeJzt3X2UVPWd5/H3pxuQBhEjkhkFDWSWtHF9ABRQWZ3WqGhORLPrE2vGMRNCdmeMk83Knng2E43Rc2YHd2I26zgy6jgxiUo8iiSHCahjT2Y8PoCCILAIY4g2JEGND7Q2Snd/9497u6kuqunqpvqhfnxe5/Tpurd+de/3V7fvp27fuvUrRQRmZpaumsEuwMzM+peD3swscQ56M7PEOejNzBLnoDczS5yD3swscT0GvaR7Je2U9HI390vS/5G0VdI6SdMrX6aZmfVVOUf09wEX7Of+C4Ep+c8C4M4DL8vMzCqlx6CPiF8Av9tPk4uBH0TmWeBwSUdVqkAzMzswwyqwjAnA6wXTTfm8Xxc3lLSA7KifkSNHnnLsscdWYPVDU3t7OzU16b4FknL/Uu4buH/V7pVXXnkzIsb35jGVCHqVmFdyXIWIWAwsBqivr4/NmzdXYPVDU2NjIw0NDYNdRr9JuX8p9w3cv2on6Ve9fUwlXvaagGMKpicCOyqwXDMzq4BKBP0y4Or86pvTgHcjYp/TNmZmNjh6PHUj6QGgAThSUhNwIzAcICL+FlgOfBbYCnwAfLG/ijUzs97rMegjYl4P9wfwZxWryMyqwp49e2hqamL37t2DXUoXY8eOZdOmTYNdxgEbOXIkEydOZPjw4Qe8rEq8GWtmB6GmpibGjBnDpEmTkEpdkzE4du3axZgxYwa7jAMSEbz11ls0NTUxefLkA15eutcgmVm/2r17N+PGjRtSIZ8KSYwbN65i/y056M2szxzy/aeSz62D3swscT5Hb2ZVq7a2lhNPPLFzeunSpYwbN24QKxqaHPRmVrXq6upYu3Ztl3m7du3qvN3a2sqwYY45n7oxs6T86Ec/4rLLLuOiiy7i/PPPB2DRokXMmDGDk046iRtvvLGz7a233kp9fT3nnnsu8+bN47bbbgOgoaGB1atXA/Dmm28yadIkANra2li4cGHnsu666y5g77ALl156KccddxxXXXUV2ZXnsGrVKs444wxOPvlkZs6cya5duzjzzDO7vEDNnj2bdevW9dtz4pc6Mztg3/7pBjbueK+iyzz+6MO48aJ/v982LS0tTJ06FYDJkyfz6KOPAvDMM8+wbt06jjjiCFauXMmWLVt4/vnniQjmzp3LL37xC0aPHs2DDz7ImjVraG1tZfr06Zxyyin7Xd8999zD2LFjWbVqFR9++CGzZ8/ufDFZs2YNGzZs4Oijj2b27Nk8/fTTzJw5kyuuuIKHHnqIGTNm8N5771FXV8f8+fO57777uP3223nllVf48MMPOemkkyrwrJXmoDezqlXq1A3AeeedxxFHHAHAypUrWblyJdOmTQOgubmZLVu2sGvXLj7/+c8zatQoAObOndvj+lauXMm6det4+OGHAXj33XfZsmULI0aMYObMmUycOBGAqVOnsm3bNsaOHctRRx3FjBkzADjssMMAuOyyy/jOd77DokWLuPfee7nmmmsO7InogYPezA5YT0feA2306NGdtyOCG264ga985Std2tx+++3dXsI4bNgw2tvbAbpcyx4RfP/732fOnDld2jc2NnLIIYd0TtfW1tLa2kpElFzHqFGjOO+883jsscdYsmRJ52mi/uJz9GaWtDlz5nDvvffS3NwMwPbt29m5cydnnXUWjz76KC0tLezatYuf/vSnnY+ZNGkSL7zwAkDn0XvHsu6880727NkDwCuvvML777/f7bqPO+44duzYwapVq4DsjeLW1lYA5s+fz3XXXceMGTM6//voLz6iN7OknX/++WzatInTTz8dgEMPPZQf/vCHTJ8+nSuuuIKpU6fyiU98gjPPPLPzMddffz2XX345999/P+ecc07n/Pnz57Nt2zamT59ORDB+/HiWLl3a7bpHjBjBQw89xFe/+lVaWlqoq6vjiSee4NBDD+WUU07hsMMO44tfHIBxICNiUH4+9alPRcqeeuqpwS6hX6Xcv5T7FlG5/m3cuLEiy6m09957r0+Pu/HGG2PRokUVrqZ727dvjylTpkRbW1u3bUo9x8Dq6GXe+tSNmdkA+8EPfsCsWbO49dZbB+RrD33qxswMuOmmmwZsXVdffTVXX331gK3PR/Rm1mcRJb8e2iqgks+tg97M+mTkyJG89dZbDvt+EPl49CNHjqzI8nzqxsz6ZOLEiTQ1NfHGG28Mdild7N69u2IBOZg6vmGqEhz0ZtYnw4cP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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"data_pred = pd.DataFrame({'Temperature': np.linspace(start=30, stop=90, num=121), 'Intercept': 1})\n",
"data_pred['Frequency'] = logmodel.predict(data_pred[['Intercept','Temperature']])\n",
"data_pred.plot(x=\"Temperature\",y=\"Frequency\",kind=\"line\",ylim=[0,1])\n",
"plt.scatter(x=data[\"Temperature\"],y=data[\"Frequency\"])\n",
"plt.grid(True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"hideCode": false,
"hidePrompt": false,
"scrolled": true
},
"source": [
"Comme on pouvait s'attendre au vu des données initiales, la\n",
"température n'a pas d'impact notable sur la probabilité d'échec des\n",
"joints toriques. Elle sera d'environ 0.2, comme dans les essais\n",
"précédents où nous il y a eu défaillance d'au moins un joint. Revenons\n",
"à l'ensemble des données initiales pour estimer la probabilité de\n",
"défaillance d'un joint:\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.06521739130434782\n"
]
}
],
"source": [
"data = pd.read_csv(\"shuttle.csv\")\n",
"print(np.sum(data.Malfunction)/np.sum(data.Count))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cette probabilité est donc d'environ $p=0.065$, sachant qu'il existe\n",
"un joint primaire un joint secondaire sur chacune des trois parties du\n",
"lançeur, la probabilité de défaillance des deux joints d'un lançeur\n",
"est de $p^2 \\approx 0.00425$. La probabilité de défaillance d'un des\n",
"lançeur est donc de $1-(1-p^2)^3 \\approx 1.2%$. Ça serait vraiment\n",
"pas de chance... Tout est sous contrôle, le décollage peut donc avoir\n",
"lieu demain comme prévu.\n",
"\n",
"Seulement, le lendemain, la navette Challenger explosera et emportera\n",
"avec elle ses sept membres d'équipages. L'opinion publique est\n",
"fortement touchée et lors de l'enquête qui suivra, la fiabilité des\n",
"joints toriques sera directement mise en cause. Au delà des problèmes\n",
"de communication interne à la NASA qui sont pour beaucoup dans ce\n",
"fiasco, l'analyse précédente comporte (au moins) un petit\n",
"problème... Saurez-vous le trouver ? Vous êtes libre de modifier cette\n",
"analyse et de regarder ce jeu de données sous tous les angles afin\n",
"d'expliquer ce qui ne va pas."
]
}
],
"metadata": {
"celltoolbar": "Hide code",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
jupyter-nbconvert --to notebook --execute notebook.ipynb --output notebook.nbconvert.ipynb
compare_notebooks() {
OLD=$1
NEW=$2
mkdir -p `dirname sed/$1`
mkdir -p `dirname sed/$2`
echo "======= Comparing to $OLD ======="
sed -e "s/Date:.*Deviance:/Deviance/" -e "s/Time:.*Pearson/Pearson/" $1 > sed/$1
sed -e "s/Date:.*Deviance:/Deviance/" -e "s/Time:.*Pearson/Pearson/" $2 > sed/$2
# Test #1 (--ignore-matching-lines="image/png" )
diff -w --ignore-matching-lines="nbformat_minor" \
--ignore-matching-lines="hidePrompt" \
--ignore-matching-lines="scrolled" \
--ignore-matching-lines="No. Iterations:" \
--ignore-matching-lines="Covariance Type:" \
sed/$1 sed/$2 # | sed 's/^/>/'
CMP_RES=$?
echo "======= End of Comparison ======="
rm sed/$1 sed/$2
return $CMP_RES
}
compare_notebooks correct_output/notebook_orig.ipynb notebook.nbconvert.ipynb
CMP1=$?
compare_notebooks correct_output/notebook_844815ed865e.ipynb notebook.nbconvert.ipynb
CMP2=$?
if [ $CMP1 -eq "0" -o $CMP2 -eq "0" ] ; then
echo "Test succeeded";
return 0;
else
echo "Test failed";
return 1;
fi
Date,Count,Temperature,Pressure,Malfunction
4/12/81,6,66,50,0
11/12/81,6,70,50,1
3/22/82,6,69,50,0
11/11/82,6,68,50,0
4/04/83,6,67,50,0
6/18/82,6,72,50,0
8/30/83,6,73,100,0
11/28/83,6,70,100,0
2/03/84,6,57,200,1
4/06/84,6,63,200,1
8/30/84,6,70,200,1
10/05/84,6,78,200,0
11/08/84,6,67,200,0
1/24/85,6,53,200,2
4/12/85,6,67,200,0
4/29/85,6,75,200,0
6/17/85,6,70,200,0
7/2903/85,6,81,200,0
8/27/85,6,76,200,0
10/03/85,6,79,200,0
10/30/85,6,75,200,2
11/26/85,6,76,200,0
1/12/86,6,58,200,1
image: "debian:stable"
before_script:
- perl -v
- which perl
perl_addition:
script:
- perl -e "print(3+2);"
perl_multiplication:
script:
- perl -e "print(3*2);"
jupyter_debian_frozen:
image: "alegrand38/moocrr_jupyter"
before_script:
- python3 --version
- jupyter-nbconvert --version
script:
- sh notebook_test.sh
jupyter_scipy_uptodate:
image: "jupyter/scipy-notebook"
before_script:
- python3 --version
- jupyter-nbconvert --version
script:
- sh notebook_test.sh
jupyter_debian_uptodate:
image: "debian:stable"
before_script:
- apt-get update && apt-get install -y python3 jupyter-nbconvert python3-ipykernel python3-matplotlib python3-pandas python3-numpy python3-statsmodels
- python3 --version
- jupyter-nbconvert --version
script:
- sh notebook_test.sh
image: "jupyter/scipy-notebook"
before_script:
- python3 --version
- jupyter-nbconvert --version
jupyter:
script:
- sh notebook_test.sh
This source diff could not be displayed because it is too large. You can view the blob instead.
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic|Roboto+Slab:400,700|Inconsolata:400,700);
@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css);
h1,h2,h3,h4,h5,h6,legend{
font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;
font-weight:700;
margin-top:0;
}
h1{
font-size:175%;
}
.subtitle{
font-size:95%; /* of h1 */
}
h2{
font-size:150%;
}
h3{
font-size:125%;
}
h4{
font-size:115%;
}
h5{
font-size:110%;
}
h6{
font-size:100%;
}
h4,h5,h6{
color:#2980B9;
font-weight:300;
}
html{
-ms-text-size-adjust:100%;
-webkit-text-size-adjust:100%;
font-size:100%;
height:100%;
overflow-x:hidden;
}
body{
background:#edf0f2;
color:#404040;
font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;
font-weight:normal;
margin:0;
min-height:100%;
overflow-x:hidden;
}
#content{
background:#fcfcfc;
height:100%;
margin-left:300px;
/* margin:auto; */
max-width:800px;
min-height:100%;
padding:1.618em 3.236em;
}
p{
font-size:16px;
line-height:24px;
margin:0px 0px 24px 0px;
}
b,strong{
font-weight:bold}
blockquote{
background-color: #F0F0F0;
border-left:5px solid #CCCCCC;
font-style:italic;
line-height:24px;
margin:0px 0px 24px 0px;
/* margin-left:24px; */
padding: 6px 20px;
}
ul,ol,dl{
line-height:24px;
list-style-image:none;
/* list-style:none; */
margin:0px 0px 24px 0px;
padding:0;
}
li{
margin-left: 24px;
}
dd{
margin:0;
}
#content .section ul,#content .toctree-wrapper ul,article ul{
list-style:disc;
line-height:24px;
margin-bottom:24px}
#content .section ul li,#content .toctree-wrapper ul li,article ul li{
list-style:disc;
margin-left:24px}
#content .section ul li p:last-child,#content .toctree-wrapper ul li p:last-child,article ul li p:last-child{
margin-bottom:0}
#content .section ul li ul,#content .toctree-wrapper ul li ul,article ul li ul{
margin-bottom:0}
#content .section ul li li,#content .toctree-wrapper ul li li,article ul li li{
list-style:circle}
#content .section ul li li li,#content .toctree-wrapper ul li li li,article ul li li li{
list-style:square}
#content .section ul li ol li,#content .toctree-wrapper ul li ol li,article ul li ol li{
list-style:decimal}
#content .section ol,#content ol,article ol{
list-style:decimal;
line-height:24px;
margin-bottom:24px}
#content .section ol li,#content ol li,article ol li{
list-style:decimal;
margin-left:24px}
#content .section ol li p:last-child,#content ol li p:last-child,article ol li p:last-child{
margin-bottom:0}
#content .section ol li ul,#content ol li ul,article ol li ul{
margin-bottom:0}
#content .section ol li ul li,#content ol li ul li,article ol li ul li{
list-style:disc}
dl dt{
font-weight:bold;
}
dl p,dl table,dl ul,dl ol{
margin-bottom:12px !important;
}
dl dd{
margin:0 0 12px 24px;
}
@media print{
.codeblock,pre.src{
white-space:pre.src-wrap}
}
@media print{
html,body,section{
background:none !important}
*{
box-shadow:none !important;
text-shadow:none !important;
filter:none !important;
-ms-filter:none !important}
a,a:visited{
text-decoration:underline}
pre.src,blockquote{
page-break-inside:avoid}
thead{
display:table-header-group}
tr,img{
page-break-inside:avoid}
img{
max-width:100% !important}
@page{
margin:0.5cm}
p,h2,h3{
orphans:3;
widows:3}
h2,h3{
page-break-after:avoid}
}
@media print{
#postamble{
display:none}
#content{
margin-left:0}
}
@media print{
#table-of-contents{
display:none}
@page{
size: auto;
margin: 25mm 25mm 25mm 25mm;}
body {
margin: 0px;}
}
@media screen and (max-width: 768px){
}
@media only screen and (max-width: 480px){
}
@media screen and (max-width: 768px){
.tablet-hide{
display:none}
}
@media screen and (max-width: 480px){
.mobile-hide{
display:none}
}
@media screen and (max-width: 480px){
}
@media screen and (max-width: 768px){
#content{
margin-left:0}
#content #content{
padding:1.618em}
#content.shift{
position:fixed;
min-width:100%;
left:85%;
top:0;
height:100%;
overflow:hidden}
}
@media screen and (min-width: 1400px){
#content{
background:rgba(0,0,0,0.05)}
#content{
background:#fcfcfc}
}
@media screen and (max-width: 768px){
#copyright{
width:85%;
display:none}
#copyright.shift{
display:block}
img{
width:100%;
height:auto}
}
@media screen and (max-width: 480px){
#content .sidebar{
width:100%}
}
code{
background:#fff;
border:solid 1px #e1e4e5;
/* color:#000; for clickable code */
font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;
font-size:75%;
max-width:100%;
overflow-x:auto;
padding:0 5px;
white-space:nowrap;
}
.codeblock-example{
border:1px solid #e1e4e5;
border-bottom:none;
padding:24px;
padding-top:48px;
font-weight:500;
background:#fff;
position:relative}
.codeblock-example:after{
content:"Example";
position:absolute;
top:0px;
left:0px;
background:#9B59B6;
color:#fff;
padding:6px 12px}
.codeblock-example.prettyprint-example-only{
border:1px solid #e1e4e5;
margin-bottom:24px}
.codeblock,pre.src,#content .literal-block{
border:1px solid #e1e4e5;
padding:12px;
overflow-x:auto;
background:#fff;
margin:1px 0 24px 0}
pre.src{
/* color:#404040; */
display:block;
font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;
font-size:12px;
line-height:1.5;
margin:1px 0px 24px 0px;
overflow:auto;
padding:12px;
white-space:pre;
}
.example{
background:#f3f6f6;
border:1px solid #e1e4e5;
color:#404040;
font-size: 12px;
line-height: 1.5;
margin-bottom:24px;
padding:12px;
}
table{
border-collapse:collapse;
border-spacing:0;
empty-cells:show;
margin-bottom:24px;
border-bottom:1px solid #e1e4e5;
}
td{
vertical-align:top}
table td,table th{
font-size:90%;
margin:0;
overflow:visible;
padding:8px 16px;
background-color:white;
border:1px solid #e1e4e5;
}
table thead th{
font-weight:bold;
border-top:3px solid #e1e4e5;
border-bottom:1px solid #e1e4e5;
}
table caption{
color:#000;
font:italic 85%/1 arial,sans-serif;
padding:1em 0;
}
table tr:nth-child(2n-1) td{
background-color:#f3f6f6;
}
table tr:nth-child(2n) td{
background-color:white;
}
.figure p{
color:#000;
font:italic 85%/1 arial,sans-serif;
padding:1em 0;
}
.rotate-90{
-webkit-transform:rotate(90deg);
-moz-transform:rotate(90deg);
-ms-transform:rotate(90deg);
-o-transform:rotate(90deg);
transform:rotate(90deg);
}
.rotate-270{
-webkit-transform:rotate(270deg);
-moz-transform:rotate(270deg);
-ms-transform:rotate(270deg);
-o-transform:rotate(270deg);
transform:rotate(270deg);
}
#toggle-sidebar,
#table-of-contents .close-sidebar {
display: none;
}
@media screen and (max-width: 768px) {
#table-of-contents {
display: none;
width: 60%;
}
#table-of-contents h2 a {
display: block;
}
#table-of-contents:target {
display: block;
}
#copyright, #postamble {
display: none;
}
#toggle-sidebar {
background-color: #2980B9;
display: block;
margin-bottom: 1.6em;
padding: 0.6em;
text-align: center;
}
#toggle-sidebar h2 {
color: white;
font-size: 100%;
line-height: 50px;
margin: 0;
padding: 0;
}
#table-of-contents .close-sidebar {
color: rgba(255, 255, 255, 0.3);
display: inline-block;
margin: 0px 10px 0px 45px;
padding: 10px;
}
}
*{
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
figcaption,figure,footer,header,hgroup,nav{
display:block}
ins{
background:#ff9;
color:#000;
text-decoration:none}
mark{
background:#ff0;
color:#000;
font-style:italic;
font-weight:bold}
small{
font-size:85%}
sub,sup{
font-size:75%;
line-height:0;
position:relative;
vertical-align:baseline}
sup{
top:-0.5em}
sub{
bottom:-0.25em}
img{
-ms-interpolation-mode:bicubic;
vertical-align:middle;
max-width:100%}
svg:not(:root){
overflow:hidden}
figure{
margin:0}
label{
cursor:pointer}
legend{
border:0;
margin-left:-7px;
padding:0;
white-space:normal}
.fa:before,#content .admonition-title:before,#content h1 .headerlink:before,#content h2 .headerlink:before,#content h3 .headerlink:before,#content h4 .headerlink:before,#content h5 .headerlink:before,#content h6 .headerlink:before,#content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,#content .note,#content .attention,#content .caution,#content .danger,#content .error,#content .hint,#content .important,#content .tip,#content .warning,#content .seealso,#content .admonitiontodo,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,#table-of-contents li.on a,#table-of-contents li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{
-webkit-font-smoothing:antialiased}
/*!
* Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/@font-face{
font-family:'FontAwesome';
src:url("../fonts/fontawesome-webfont.eot?v=4.1.0");
src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.1.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.1.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular") format("svg");
font-weight:normal;
font-style:normal}
.fa,#content .admonition-title,.icon{
display:inline-block;
font-family:FontAwesome;
font-style:normal;
font-weight:normal;
line-height:1;
-webkit-font-smoothing:antialiased;
-moz-osx-font-smoothing:grayscale}
.fa-ul{
padding-left:0;
margin-left:2.14286em;
list-style-type:none}
.fa-ul>li{
position:relative}
.fa-li{
position:absolute;
left:-2.14286em;
width:2.14286em;
top:0.14286em;
text-align:center}
.fa-li.fa-lg{
left:-1.85714em}
.fa-border{
padding:.2em .25em .15em;
border:solid 0.08em #eee;
border-radius:.1em}
.fa,#content .admonition-title{
font-family:inherit}
.fa:before,#content .admonition-title:before{
font-family:"FontAwesome";
display:inline-block;
font-style:normal;
font-weight:normal;
line-height:1;
text-decoration:inherit}
a .fa,a #content .admonition-title,#content a .admonition-title{
display:inline-block;
text-decoration:inherit}
.nav #content .admonition-title,#content .nav .admonition-title,.nav .icon{
display:inline}
.wy-alert,#content .note,#content .attention,#content .caution,#content .danger,#content .error,#content .hint,#content .important,#content .tip,#content .warning,#content .seealso,#content .admonitiontodo{
padding:12px;
line-height:24px;
margin-bottom:24px;
/* background:#e7f2fa; */
}
.wy-alert-title,#content .admonition-title{
color:#fff;
font-weight:bold;
display:block;
color:#fff;
/* background:#6ab0de; */
/* margin:-12px; */
padding:6px 12px;
margin-bottom:0px}
#content .danger,#content .error{
background:#fdf3f2}
.wy-alert.wy-alert-warning,#content .wy-alert-warning.note,#content .attention,#content .caution,#content .wy-alert-warning.danger,#content .wy-alert-warning.error,#content .wy-alert-warning.hint,#content .wy-alert-warning.important,#content .wy-alert-warning.tip,#content .warning,#content .wy-alert-warning.seealso,#content .admonitiontodo{
background:#ffedcc}
#content .admonition-title.note:before, #content .admonition-title.seealso:before,
#content .admonition-title.warning:before, #content .admonition-title.caution:before,
#content .admonition-title.attention:before,
#content .admonition-title.tip:before, #content .admonition-title.hint:before,
#content .admonition-title.important:before,
#content .admonition-title.error:before, #content .admonition-title.danger:before{
font-family:FontAwesome;
content: "";}
#content .note,#content .seealso{
background:#e7f2fa}
.wy-alert p:last-child,#content .note p:last-child,#content .attention p:last-child,#content .caution p:last-child,#content .danger p:last-child,#content .error p:last-child,#content .hint p:last-child,#content .important p:last-child,#content .tip p:last-child,#content .warning p:last-child,#content .seealso p:last-child,#content .admonitiontodo p:last-child{
margin-bottom:0}
#content .admonition-title.tip,#content .admonition-title.important,#content .admonition-title.hint{
line-height: 1;
background:#1abc9c}
#content .important,#content .tip,#content .hint{
background:#dbfaf4}
#content .admonition-title.note,#content .admonition-title.seealso{
line-height: 1;
background:#6ab0de}
#content .admonition-title.warning,#content .admonition-title.caution,#content .admonition-title.attention{
line-height: 1;
background:#F0B37E}
#content .admonition-title.error,#content .admonition-title.danger{
line-height: 1;
background:#f29f97}
legend{
display:block;
width:100%;
border:0;
padding:0;
white-space:normal;
margin-bottom:24px;
font-size:150%;
*margin-left:-7px}
label{
display:block;
margin:0 0 0.3125em 0;
color:#333;
font-size:90%}
a{
color:#2980B9;
text-decoration:none;
cursor:pointer}
a:hover,a:active{
outline:0;
}
a:hover{
color:#3091d1}
a:visited{
color:#9B59B6}
.left{
text-align:left}
.center{
text-align:center}
.right{
text-align:right}
hr{
display:block;
height:1px;
border:0;
border-top:1px solid #e1e4e5;
margin:24px 0;
padding:0}
#table-of-contents li{
list-style:none;
margin-left: 0px;
}
#table-of-contents header{
height:32px;
display:inline-block;
line-height:32px;
padding:0 1.618em;
display:block;
font-weight:bold;
text-transform:uppercase;
font-size:80%;
color:#2980B9;
white-space:nowrap}
#table-of-contents ul{
margin-bottom:0}
#table-of-contents li.divide-top{
border-top:solid 1px #404040}
#table-of-contents li.divide-bottom{
border-bottom:solid 1px #404040}
#table-of-contents li.current{
background:#e3e3e3}
#table-of-contents li.current a{
color:gray;
border-right:solid 1px #c9c9c9;
padding:0.4045em 2.427em}
#table-of-contents li.current a:hover{
background:#d6d6d6}
#table-of-contents li a{
/* color:#404040; */
padding:0.4045em 1.618em;
position:relative;
/* background:#fcfcfc; */
border:none;
/* border-bottom:solid 1px #c9c9c9; */
/* border-top:solid 1px #c9c9c9; */
padding-left:1.618em -4px}
#table-of-contents li.on a:hover,#table-of-contents li.current>a:hover{
background:#fcfcfc}
#table-of-contents li ul li a{
/* background:#c9c9c9; */
padding:0.4045em 2.427em}
#table-of-contents li ul li ul li a{
padding:0.4045em 3.236em}
#table-of-contents li.current ul{
display:block}
/* #table-of-contents li ul{ */
/* margin-bottom:0; */
/* display:none} */
#table-of-contents .local-toc li ul{
display:block}
#table-of-contents li ul li a{
margin-bottom:0;
color:#b3b3b3;
font-weight:normal}
#table-of-contents a{
display:inline-block;
line-height:18px;
padding:0.4045em 1.618em;
display:block;
position:relative;
font-size:90%;
color:#b3b3b3;
direction: ltr;
}
#table-of-contents a:hover{
background-color:#4e4a4a;
cursor:pointer}
/* #text-table-of-contents { */
/* overflow:scroll; */
/* } */
#table-of-contents{
position:fixed;
top:0;
left:0;
width:300px;
overflow-x:hidden;
overflow-y:scroll;
height:100%;
background:#343131;
z-index:200;
scrollbar-base-color: #1F1D1D;
scrollbar-arrow-color: #b3b3b3;
scrollbar-shadow-color: #1F1D1D;
scrollbar-track-color : #343131;
}
#table-of-contents h2{
z-index:200;
background-color:#2980B9;
text-align:center;
padding:0.809em;
display:block;
color:#fcfcfc;
font-size: 100%;
margin-bottom:0.809em}
ul.nav li ul li {
display: none;
}
ul.nav li ul li ul li {
display: none;
}
ul.nav li.active ul li {
display: inline;
}
ul.nav li.active ul li ul li {
display: inline;
}
ul.nav li.active ul li a {
background-color: #E3E3E3;
color: #8099B0;
border-right:solid 1px #c9c9c9 !important;
}
ul.nav li.active ul li.active a {
background-color: #C9C9C9;
color: black !important;
font-weight: bold !important;
}
ul.nav li.active ul li.active ul li.active a {
color: black !important;
font-weight: bold !important;
display: block !important;
}
ul.nav li.active ul li.active ul li a {
color: #808080 !important;
font-weight: normal !important;
display: block !important;
}
ul.nav li.active ul li ul li a {
display: none !important;
}
/* ul.nav li ul li ul li { */
/* display: none !important; /\* as long as nav is on multiple levels of ul *\/ */
/* /\* display: none; /\* as long as nav is on multiple levels of ul *\\/ *\/ */
/* } */
ul.nav li ul li ul li ul li {
display: none !important; /* as long as nav is on multiple levels of ul */
/* display: none; /* as long as nav is on multiple levels of ul *\/ */
}
ul.nav li.active > a {
border-bottom:solid 1px #c9c9c9 !important; /* XXX Restrict it to 2nd level */
border-right:solid 1px #c9c9c9 !important;
}
ul.nav li.active a {
color: gray !important;
font-weight:bold;
background-color: white;
border-right:solid 0px white !important;
}
ul.nav > li.active > a {
color: black !important;
}
footer{
color:#999}
footer p{
margin-bottom:12px}
#copyright, #postamble{
position:fixed;
bottom:0;
left:0;
width:300px;
color:#fcfcfc;
background:#1f1d1d;
border-top:solid 10px #343131;
font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;
font-size: 90%;
z-index:400;
padding:12px;
}
#postamble .author {
font-size: 100%;
margin-bottom: 0px;
}
#postamble .date {
font-size: 90%;
margin-bottom: 0px;
color: #27AE60;
}
#postamble .creator,#postamble .validation {
display:none;
}
#copyright a{
color:#2980B9;
text-decoration:none}
#copyright .rst-current-version{
padding:12px;
background-color:#272525;
display:block;
text-align:right;
font-size:90%;
cursor:pointer;
color:#27AE60;
*zoom:1}
#content img{
max-width:100%;
}
#content div.figure{
margin-bottom:24px}
#content div.figure.align-center{
text-align:center}
#content .section>img,#content .section>a>img{
margin-bottom:24px}
.verse{
border-left:5px solid #6AB0DE;
background-color: #E7F2FA;
padding: 6px 20px;
font-style:italic;
}
#content .note .last,#content .attention .last,#content .caution .last,#content .danger .last,#content .error .last,#content .hint .last,#content .important .last,#content .tip .last,#content .warning .last,#content .seealso .last,#content .admonitiontodo .last{
margin-bottom:0}
#content .admonition-title:before{
margin-right:4px}
#content .section ol p,#content .section ul p{
margin-bottom:12px}
#content h1 .headerlink,#content h2 .headerlink,#content h3 .headerlink,#content h4 .headerlink,#content h5 .headerlink,#content h6 .headerlink,#content dl dt .headerlink{
display:none;
visibility:hidden;
font-size:14px}
#content h1 .headerlink:after,#content h2 .headerlink:after,#content h3 .headerlink:after,#content h4 .headerlink:after,#content h5 .headerlink:after,#content h6 .headerlink:after,#content dl dt .headerlink:after{
visibility:visible;
content:"";
font-family:FontAwesome;
display:inline-block}
#content h1:hover .headerlink,#content h2:hover .headerlink,#content h3:hover .headerlink,#content h4:hover .headerlink,#content h5:hover .headerlink,#content h6:hover .headerlink,#content dl dt:hover .headerlink{
display:inline-block}
#content .sidebar{
float:right;
width:40%;
display:block;
margin:0 0 24px 24px;
padding:24px;
background:#f3f6f6;
border:solid 1px #e1e4e5}
#content .sidebar p,#content .sidebar ul,#content .sidebar dl{
font-size:90%}
#content .sidebar .last{
margin-bottom:0}
#content .sidebar .sidebar-title{
display:block;
font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;
font-weight:bold;
background:#e1e4e5;
padding:6px 12px;
margin:-24px;
margin-bottom:24px;
font-size:100%}
#content .highlighted{
background:#F1C40F;
display:inline-block;
font-weight:bold;
padding:0 6px}
#content .footnote-reference,#content .citation-reference{
vertical-align:super;
font-size:90%}
span[id*='MathJax-Span']{
color:#404040}
.math{
text-align:center}
#footnotes{
border-top:1px solid #e1e4e5;
padding-top: 36px;
}
h2.footnotes{
display:none;
}
.footnum, .footref{
color: #2980b9;
font-size: 170%;
font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;
}
.footnum:before, .footref:before{
content:"[";
}
.footnum:after, .footref:after{
content:"]";
}
.footpara {
color: #999;
font-size: 90%;
font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;
padding-bottom: 8px;
padding-left: 16px;
padding-right: 16px;
padding-top: 8px;
line-height: 1.25em;
/* display: inline; */
}
.todo{
background-color: #f29f97;
padding: 0px 4px;
color: #fff;
}
.WAIT, .nilWAIT{
background-color: #6AB097;
}
.done{
background-color: #6ab0de;
padding: 0px 4px;
color: #fff;
}
.tag span {
background-color: #EDEDED;
border: 1px solid #EDEDED;
color: #939393;
cursor: pointer;
display: block;
float: right;
font-size: 80%;
font-weight: normal;
margin: 0 3px;
padding: 1px 2px;
border-radius: 10px;
}
.tag .FLAGGED {
background-color: #DB2D27;
border: 1px solid #DB2D27;
color: white;
font-weight: bold;
}
.timestamp {
font-family: Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;
font-size: 90%;
color: navy;
}
.inlinetask {
background: #FFF9E3; /* url(dialog-todo.png) no-repeat 10px 8px; */
border: 3px solid #FFEB8E;
/* border-right-style: none; */
/* border-left-style: none; */
/* padding: 10px 20px 10px 60px; */
padding: 9px 12px;
margin-bottom: 24px;
font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}