Du code beau, parce que nous le valons bien !

Maëlle Salmon

Bonjour !

  • Pourquoi écrire du code beau ?
  • Comment ? Trucs et astuces

🔗 https://jolicode.netlify.app/

Coffee

Picture by Leonardo Luz on Pexels.

Qui suis-je ?

  • rOpenSci (dev guide, newsletter, paquets pour documents multi-langues babeldown et babelquarto…)

  • cynkra (contribution à fledge, igraph)

  • glitter pour écrire des requêtes SPARQL, avec Lise Vaudor

  • saperlipopette pour s’entraîner à Git

Pourquoi écrire du code beau

Du code facile à lire, facile à suivre.

Votre code est exécuté par des machines mais lu par des humains pour le comprendre, le vérifier, l’améliorer.

Mascara

Picture by Shiny Diamond on Pexels.

Du code bien proportionné

  • Des espacements réguliers entre les éléments

  • Pas trop large

  • Pas trop long : paragraphes, fonctions existantes et faites maison

  • Pas trop taché : des commentaires mais juste ce qu’il faut

Espacements réguliers

😱

starwars%>%
  select(name,height, mass,homeworld) %>%
  mutate(
    mass= NULL,
    height =height *0.0328084 # convert to feet
  )

Espacements réguliers

😌

starwars %>%
  select(name, height, mass, homeworld) %>%
  mutate(
    mass = NULL,
    height = height * 0.0328084 # convert to feet
  )

Espacements réguliers

Suivre des règles, toujours les mêmes, les mêmes que les copain·ine·s. Comment faire?

  • On s’y habitue.

  • Le paquet {styler} vous refait ça automatiquement ! Démo.

  • Dans RStudio IDE, Ctrl+I pour l’indentation.

Pas trop large

Pas plus de 80 caractères par ligne, ou quelque chose de semblable.

lintr peut vous avertir ! Démo

Aussi un réglage de RStudio (Code > Display > Show Margin).

Du code pas trop long : paragraphes

Comme dans la prose, un paragraphe pour une idée.

head <- collect_metadata(website)
head_string <- stringify(head)

body <- create_content(website)
body_string <- stringify(body)

Du code pas trop long : fonctions faites maison

Garder un corps de fonction principale pas trop long en sous-traitant des choses à des fonctions bien nommées.

create_content <- function(website) {
  title <- create_title(website)
  page <- create_page(website)
  combine_elements(title = title, page = page)
}

Aparté : naviguer entre fonctions dans RStudio IDE

Démo !

  • Enter click

  • Barre de recherche

Du code pas trop long : ne pas réinventer la roue !

Exemple: modifyList()

default_values <- list(a = 1, b = 2)
options <- list(b = 56)
temporary_list <- default_values
temporary_list[names(options)] <- options
options <- temporary_list

options
$a
[1] 1

$b
[1] 56

Du code pas trop long : ne pas réinventer la roue !

Exemple: modifyList()

default_values <- list(a = 1, b = 2)
options <- list(b = 56)
options <- modifyList(default_values, options)
options
$a
[1] 1

$b
[1] 56

Comment étendre son vocabulaire de R ?

Aussi peu de commentaires que possible

Avant, je pensais…

# données starwars
starwars %>%
  # sélectionne name et mass
  select(name, mass) %>%
  mutate(
    # ajoute mass2 comme double de mass
    mass2 = mass * 2,
    # ajoute mass2_squareed comme mass2 au carré
    mass2_squared = mass2 * mass2
  )

Cela ne sert à rien et c’est ennuyeux à écrire et ça peut même être dangereux !

Aussi peu de commentaires que possible

Un commentaire = comme une alerte !

S’il y en a trop on ne les lit plus.

Envie de commenter ? Soignez !

  • Changer le nom d’une variable plutôt que commenter ce que c’est.

  • Changer la structure d’un code compliqué plutôt que de commenter ce qu’il fait.

Les variables ou fonctions explicatives

Bof :

# Utilise string si x est non manquant et non vide
if (!is.na(x) && nzchar(x)) {
  use_string(x)
}

Les variables ou fonctions explicatives

Youpi :

x_is_not_empty_string <- (!is.na(x) && nzchar(x))
if (x_is_not_empty_string) {
  use_string(x)
}

Pareil avec une fonction si le cas se répète.

Les commentaires qui sont bien

  • Documentation des fonctions avec roxygen2 ;

  • Les choses qu’on voudrait indiquer à un·e réviseur·se de code comme # This query can not be done via GraphQL, so have to use v3 REST API

  • Les commentaires qui donnent une table des matières. Démo.

Du code bien proportionné

  • Des espacements réguliers entre les éléments

  • Pas trop large

  • Pas trop long : paragraphes, fonctions existantes et faites maison

  • Pas trop taché : des commentaires mais juste ce qu’il faut

Du code clair

  • Des noms explicites.

  • Des astuces sur la logique: return() tôt, switch().

  • Du code en moins.

Des noms explicites

  • Suivre la mode.

  • Felienne Hermans conseille de choisir les concepts qui vont dans le nom, les mots pour le dire, les assembler.

  • Plus le nom est loin de son utilisation, plus il doit être long. (Andrew Gerrand)

  • C’est clair si la personne relisant votre code est d’accord. 😉

Renommer des fonctions

On peut même renommer des fonctions qui existent si ça clarifie.

# Dans utils.R
remove_extension <- function(path) {
  tools::file_path_sans_ext(path)
}

# Dans les autres scripts
remove_extension(path)

Simplifier la logique : return() tôt

Bof

do_thing <- function(x) {
  if (is.na(x)) {
    NA
  } else {
    x + 1
  }
}

Simplifier la logique : return() tôt

Mieux !

do_thing <- function(x) {
  if (is.na(x)) {
    return(NA)
  } 
  
  x + 1
}

Simplifier la logique : switch()

Bof !

if (type == "mean") {
  mean(x)
} else if (type == "median") {
  median(x)
} else if (type == "trimmed") {
  mean(x, trim = .1)
}

Simplifier la logique : switch()

Mieux !

switch(type,
       mean = mean(x),
       median = median(x),
       trimmed = mean(x, trim = .1))

On peut même préciser une valeur par défaut pour les autres valeurs du premier argument.

Moins de code, moins de problèmes !

  • Être strict sur ce qui est à faire ou pas.

  • Utiliser des dépendences externes auxquelles on fait confiance.

Du code clair

  • Des noms explicites.

  • Des astuces sur la logique: return() tôt, switch().

  • Du code en moins.

Comment améliorer son code ?

  • Nettoyage de printemps ;

  • lintr ;

  • Révision par des humains.

Nettoyage de printemps

lintr, un ami qui vous veut du bien

Allons jeter un oeil à la documentation !

https://lintr.r-lib.org/reference/index.html

Révision par des humains

Lisez le code de vos collègues et inversement ! https://code-review.tidyverse.org/

Revue de paquets par les pairs à rOpenSci https://ropensci.org/software-review/

En conclusion

La beauté et la clarté du code, aussi importantes que sa performance.

Code plus facile à vérifier et maintenir !

Un travail permanent.

Références / ressources supplémentaires

Merci !

À vous tou·te·s et à Marylène Henry !

https://jolicode.netlify.app/

Thank you

Picture by Ann H on Pexels.