Introduction au débogage
Nathalie Grafféo
19 mars 2018
Nathalie Grafféo Introduction au débogage 19 mars 2018 1 / 17
La première méthode pour corriger une erreur dans un programme consiste
à lire le message d’erreur renvoyé par R
Nathalie Grafféo Introduction au débogage 19 mars 2018 2 / 17
Lire le message d’erreur : exemple 1
f1 <- function(x){
return(x+y)
}
f2 <- function(y){
return(sqrt(y))
}
f3 <- function(x){
print(f1(f2(x)))
}
f3(9)
Error in print(f1(f2(x))): erreur d'évaluation de l'argument
'x' lors de la sélection d'une méthode
pour la fonction 'print' :
Error in f1(f2(x)) : object 'y' not found
Nathalie Grafféo Introduction au débogage 19 mars 2018 3 / 17
Lire le message d’erreur : exemple 1 corrigé
y <- 16
f1 <- function(x){
return(x+y)
}
f2 <- function(y){
return(sqrt(y))
}
f3 <- function(x){
print(f1(f2(x)))
}
f3(9)
## [1] 19
Nathalie Grafféo Introduction au débogage 19 mars 2018 4 / 17
Lire le message d’erreur : exemple 2
fonc1 <- function(x){
y <- sqrt(x-500)
if(y>10) print("c'est grand")
}
fonc1(499)
Error in if (y > 10) print("c'est grand") :
missing value where TRUE/FALSE needed
In addition: Warning message:
In sqrt(x - 500) : NaNs produced
Nathalie Grafféo Introduction au débogage 19 mars 2018 5 / 17
Lire le message d’erreur : exemple 2 (suite)
fonc1 <- function(x){
if(x >= 500){
y <- sqrt(x-500)
if(y>10) print("c'est grand")
}else{
print("Essayez avec un x > 500")
}
}
fonc1(499)
## [1] "Essayez avec un x > 500"
Nathalie Grafféo Introduction au débogage 19 mars 2018 6 / 17
A propos du warning
Contrairement à un erreur, un warning ne provoque pas l’arrêt d’un
programme.
Cependant, il ne faut jamais ignorer un warning
x <- seq(1,-5,by=-2)
if(x>0) y <- sqrt(x)
Nathalie Grafféo Introduction au débogage 19 mars 2018 7 / 17
A propos du warning
Contrairement à un erreur, un warning ne provoque pas l’arrêt d’un
programme.
Cependant, il ne faut jamais ignorer un warning
x <- seq(1,-5,by=-2)
if(x>0) y <- sqrt(x)
Warning messages:
1: In if (x > 0) y <- sqrt(x) :
the condition has length > 1 and only the first
element will be used
2: In sqrt(x) : NaNs produced
> y
[1] 1 NaN NaN NaN
Nathalie Grafféo Introduction au débogage 19 mars 2018 7 / 17
Avec un simple print (1/2)
Utile et rapide !
Exemple extrait de “R-inferno”1
# Tester l'égalité de 2 chiffres après une opération
myIdent <- function(x,y){
x == y/3
}
myIdent(0.1,0.3)
## [1] FALSE
1
Burns, P. (2011). The R inferno. Lulu. com.
Nathalie Grafféo Introduction au débogage 19 mars 2018 8 / 17
Avec un simple print (2/2)
myIdent <- function(x,y){
x == y/3
print(y/3, digits=16)
}
myIdent(0.1,0.3)
## [1] 0.09999999999999999
Solution :
Nathalie Grafféo Introduction au débogage 19 mars 2018 9 / 17
Avec un simple print (2/2)
myIdent <- function(x,y){
x == y/3
print(y/3, digits=16)
}
myIdent(0.1,0.3)
## [1] 0.09999999999999999
Solution :
[Link](0.1, 0.3/3)
## [1] TRUE
Nathalie Grafféo Introduction au débogage 19 mars 2018 9 / 17
browser() : introduction
A placer avant la ligne qui provoque l’erreur
La fonction s’exécute jusqu’au browser()
Environnement de la fonction : toutes les variables peuvent être
vérifiées
Commandes possibles :
Commande Son action
n avance jusqu’à la prochaine étape
c continue jusqu’à la fin du pgm
where où suis-je ?
Q sortie du browser()
Nathalie Grafféo Introduction au débogage 19 mars 2018 10 / 17
browser() : un exemple trivial pour s’entraîner (1/3)
trinom <- function(a,b,c){
d <- b^2 - 4*a*c
if(d>=0) res <- (b + c(-1,1)*sqrt(d))/(2*a)
res
}
trinom(1,1,1)
## Error in trinom(1, 1, 1): objet 'res' introuvable
Nathalie Grafféo Introduction au débogage 19 mars 2018 11 / 17
browser() : un exemple trivial pour s’entraîner (2/3)
trinom <- function(a,b,c){
d <- b^2 - 4*a*c
browser()
if(d>=0) res <- (b + c(-1,1)*sqrt(d))/(2*a)
res
}
trinom(1,1,1)
Called from: trinom(1, 1, 1)
Browse[1]> where
where 1: trinom(1, 1, 1)
Browse[1]> d>=0
[1] FALSE
Browse[1]> res
Error: object 'res' not found
Browse[1]> Q
Nathalie Grafféo Introduction au débogage 19 mars 2018 12 / 17
browser() : un exemple trivial pour s’entraîner (3/3)
trinom <- function(a,b,c){
d <- b^2 - 4*a*c
if(d>=0) res <- (b + c(-1,1)*sqrt(d))/(2*a)
else {
print("non programmée pour un discriminant négatif")
res <- NULL
}
res
}
trinom(1,1,1)
[1] "non programmée pour un discriminant négatif"
Nathalie Grafféo Introduction au débogage 19 mars 2018 13 / 17
Débogage avec RStudio (1/3)
Cliquer sur Debug → On Error → Break in Code
Cette option est très pratique en présence de fonctions imbriquées.
Exécutons l’exemple naif suivant :
g1 <- function(x){
return(x^2 + g2(x))
}
g2 <- function(x){
if(log(x)>2) res <- log(x) + g3(x)
else res <- 0
return(res)
}
g3 <- function(x){
return(log(x^2))
}
g1(-2)
Nathalie Grafféo Introduction au débogage 19 mars 2018 14 / 17
Débogage avec RStudio (2/3)
La console renvoie le message suivant :
> g1(-2)
Error in if (log(x) > 2) res <- log(x) + g3(x)
else res <- 0 :
missing value where TRUE/FALSE needed
In addition: Warning message:
In log(x) : NaNs produced
Called from: g2(x)
Browse[1]>
Une fenêtre de débogage s’ouvre en mode browser avec la fonction qui
génère l’erreur (ici g2).
Nathalie Grafféo Introduction au débogage 19 mars 2018 15 / 17
Débogage avec RStudio (3/3)
Ici, l’erreur est vite repérée :
Called from: g2(x)
Browse[1]> log(x)
[1] NaN
Browse[1]> x
[1] -2
La correction dépend ici de ce que l’on voulait faire avec cette fonction. Une
solution pourrait être de remplacer la condition par if(log(abs(x))>2).
Nathalie Grafféo Introduction au débogage 19 mars 2018 16 / 17
Conclusion
1 Il n’y a pas UNE méthode pour trouver une erreur dans un programme
2 Toujours commencer par la lecture attentive du message d’erreur, cela
est souvent suffisant
3 Les méthodes basiques (insérer des print) ou d’exécution de son
programme ligne à ligne (avec un browser()) sont efficaces car elles
permettent de comprendre ce que fait réellement R (ce qui peut être
très différent de ce que l’on attend)
4 Le débogage avec RStudio est à privilégier dans le cas de multiples
fonctions imbriquées
5 Pour aller plus loin, on pourra se référer, par exemple, à
Wickham, H. (2014). Advanced R. CRC Press
([Link]
Nathalie Grafféo Introduction au débogage 19 mars 2018 17 / 17