jueves, 22 de febrero de 2024 From rOpenSci (https://ropensci.org/es/blog/2024/02/22/beautiful-code/). Except where otherwise noted, content on this site is licensed under the CC-BY license.
rOpenSci inició el segundo grupo de campeones y campeonas ¡! Su formación comenzó con una sesión sobre el estilo del código, que resumiremos en este post. Saber más sobre la calidad del código es relevante para todos los proyectos del programa, ya sea crear un nuevo paquete, someter un paquete a revisión de software o revisar un paquete. Esta sesión de formación consistió en una charla y un debate, mientras que las próximas sesiones de formación sobre desarrollo de paquetes serán más prácticas.
Aunque tu código será ejecutado por máquinas, será leído por humanos. Esos humanos, ya seas tú en el futuro, colaboradores que conozcas o que no conozcas, necesitarán entender tu código para comprobar que no tiene errores, para corregir posibles fallos y para construir sobre él añadiendo nuevas funciones. Por lo tanto, facilitar la comprensión de tu código es crucial.
En la primera parte, compartimos consejos que hacen el código “más proporcionado”. No es sólo una cuestión de estética. El código bien proporcionado es más fácil de analizar por los humanos.
Compara
starwars%>%
select(name,height, mass,homeworld) %>%
mutate(
mass=NULL,
height =height *0.0328084 # convert to feet
)
con
starwars %>%
select(name, height, mass, homeworld) %>%
mutate(
mass = NULL,
height = height * 0.0328084 # convert to feet
)
En el primer trozo, el espaciado entre elementos es irregular.
Por ejemplo, no hay espacio antes de height
no hay espacio alrededor del signo igual que aparece después de mass
.
En cambio, te recomendamos que sigas ordenadamente las reglas de espaciado (¡y de salto de línea!). A menos que tengas una opinión muy diferente la estrategia más sencilla es seguir la guía de estilo de tus colaboradores, o una guía de estilo popular como la guía de estilo tidyverse.
¿Cómo se aplican estas normas en la práctica?
Primero tendrás que acostumbrarte a utilizar un estilo concreto.
Las herramientas automáticas como el paquete estilizador o tu IDE pueden ayudarte.
Por ejemplo, en el IDE de RStudio, el atajo de teclado Ctrl+I
corrige la sangría.
Una regla tradicional es no tener más de 80 caracteres por línea. El número exacto no es importante, ¡lo importante es evitar demasiado desplazamiento horizontal!
El paquete lintr puede advertirte sobre líneas demasiado anchas, entre otras muchas cosas. Comparado con styler, lintr no arregla las cosas por sí mismo.
También hay un ajuste en el IDE de RStudio para mostrar un margen a los 80 caracteres (Código > Mostrar > Mostrar margen).
El espacio vertical está limitado en el código tanto por la pantalla como por lo que el lector puede ver de un vistazo (sin tener en cuenta los límites de lo que puede retener en su cabeza).
Una forma de hacer que tu código sea más corto, pero fácil de analizar, es utilizar párrafos de código. Los saltos de línea no son gratuitos, ya que ocupan espacio vertical. Utiliza saltos de línea para separar bloques de código que hagan algo relacionado. Como en la prosa, un párrafo debe corresponder relativamente a una idea. Por ejemplo, en el siguiente código, el primer bloque hace algo relacionado con la cabecera de una página web, mientras que el segundo bloque se ocupa del cuerpo de la página web.
head <- collect_metadata(website)
head_string <- stringify(head)
body <- create_content(website)
body_string <- stringify(body)
Una segunda forma de hacer que tu código sea menos largo es dividirlo en funciones.
En una función principal, puedes delegar tareas a otras funciones.
De este modo, un lector puede ver de un vistazo lo que hace la función principal, y luego dirigirse a las otras funciones para leer más detalles, como en el ejemplo siguiente, donde create_content()
llama a otras funciones para crear un título, una página y, a continuación, crear su salida que combina ambas cosas.
create_content <- function(website) {
title <- create_title(website)
page <- create_page(website)
combine_elements(title = title, page = page)
}
En su libro Aprende programación Python asistida por IA Leo Porter y Daniel Zingaro comparten los atributos de las buenas funciones: Una tarea clara a realizar, comportamiento claramente definido, poca cantidad de líneas de código, entradas y salidas claras y valor general sobre uso específico.
¡También es útil saber cómo navegar rápidamente entre funciones en tu IDE!
En el IDE de RStudio, puedes utilizar Ctrl+click
sobre el nombre de la función, o escribir su nombre en la barra de búsqueda a la que se accede con Ctrl+.
.
Una tercera forma de acortar tu código es utilizar funciones existentes de R base o de paquetes complementarios.
Por ejemplo, para combinar una lista de valores por defecto con una lista de valores personalizados, puedes utilizar la función modifyList()
función.
Como ocurre con las lenguas humanas, aprendemos más palabras R con el tiempo leyendo el código de otras personas y haciendo que lean nuestro código.
Esta parte de la formación era una versión abreviada de la entrada del blog R-hub Por qué comentar tu código lo menos (y lo mejor) posible.
Los comentarios del código no son la voz en off de un narrador del código, deben ser pequeñas alertas. Cuantos más comentarios haya, más probable es que el lector se los salte.
Los comentarios de código no deben ser una curita para una mala clasificación o un código demasiado complejo: en lugar de añadir un comentario, renombra una variable o refactoriza un trozo de código
Una idea útil es usar funciones o variables autoexplicativas donde código como
if (!is.na(x) && nzchar(x)) {
use_string(x)
}
se convierte en
x_is_not_empty_string <- (!is.na(x) && nzchar(x))
if (x_is_not_empty_string) {
use_string(x)
}
Por supuesto, ¡los comentarios del código siguen siendo importantes cuando son necesarios! Algunos ejemplos de buenos comentarios son
# Esta consulta no se puede realizar a través de GraphQL, por lo que se debe utilizar la API REST v3
,En la segunda parte de la formación, compartimos consejos que mejoran la claridad del código.
Poner nombre a las cosas es notoriamente difícil. Compartimos estas ideas:
Sigue la moda, es decir, utiliza las mismas palabras que otros en tu campo o lenguaje de programación.
Felienne Hermans, en su libro El cerebro del programador aconseja elegir los conceptos que componen el nombre, las palabras para decirlo y luego juntarlos. Este enfoque en tres pasos es una buena forma de desatascarse.
Siguiendo el consejo anterior, los nombres deben ser coherentes en toda la base de código y moldes de nombres son una herramienta muy buena para ello. Los moldes de nombres son patrones en los que se combinan los elementos de un nombre; por ejemplo, si calculas el valor máximo del rendimiento de una cosecha, tienes que acordar si maximum
será max
o maximum
y si la palabra estará al principio o al final del nombre de la variable: debe ser maxYield
o yieldMax
? Al normalizar la forma de nombrar las cosas, nuestro código será más fácil de leer.
“Cuanto mayor sea la distancia entre la declaración de un nombre y sus usos, más largo deberá ser el nombre” (Andrew Gerrand). Sin embargo, por muy cerca que estés de definir una variable, no utilices una abreviatura inteligente muy corta.
Hay varias formas de escribir los nombres de las variables. El estilo camelCase permite una mayor precisión al leer el código (Dave Binkley, 2009) y es mejor para leer el código con lectores de pantalla. Sabemos que es difícil cambiar el estilo de un proyecto existente, pero si te encuentras en una situación en la que puedes decidir desde cero, entonces considera la posibilidad de utilizar Camel Case. Si no estás seguro de los nombres, de las mayúsculas y minúsculas, consulta el artículo de Allison Horst caricatura de casos (desplázate hacia abajo hasta “Representaciones en viñetas de casos comunes en codificación”).
Un nombre está claro si la persona que revisa tu código está de acuerdo.
Otro consejo es que no pasa absolutamente nada por crear funciones que envuelvan otras ya existentes sólo para cambiarles el nombre. Esta estrategia es habitual para cambiar el orden de los argumentos, pero también está bien para cambiar el nombre. Digamos que prefieres que los nombres de tus funciones sean acciones (verbos) en lugar de descripciones pasivas, puedes tener:
# In utils.R
remove_extension <- function(path) {
tools::file_path_sans_ext(path)
}
# In other scripts
remove_extension(path)
return()
, switch()
En una función,
do_thing <- function(x) {
if (is.na(x)) {
NA
} else {
x + 1
}
}
que equivale a
do_thing <- function(x) {
if (is.na(x)) {
return(NA)
}
x + 1
}
pero esta última, con el return()
tiene menos anidamiento y enfatiza el “camino feliz”.
En switch()
también puede ayudarte a eliminar los if-else anidados.
Con el,
if (type == "mean") {
mean(x)
} else if (type == "median") {
median(x)
} else if (type == "trimmed") {
mean(x, trim = .1)
}
se convierte en
switch(type,
mean = mean(x),
median = median(x),
trimmed = mean(x, trim = .1)
)
El código que no escribes no tiene ningún fallo (del que seas responsable) y no necesita ser leído 🎉
En primer lugar, sé estricto con el alcance de lo que intentas conseguir.
En segundo lugar, utiliza dependencias de confianza para externalizar parte del trabajo. En “Dependencias: Mentalidad y antecedentes “ del libro R packages de Hadley Wickham y Jenny Bryan se explaya mejor el tema.
En la práctica, ¿cómo aplicas lo que has aprendido sobre estilo de código? ¿Y cómo actualizas tus bases de código heredadas, creadas antes de que conocieras algunos de estos aspectos?
Tal vez puedas trabajar en el estilo y la refactorización del código con regularidad
¿Una vez al año? Andy Teucher escribió una interesante entrada en su blog sobre la limpieza de primavera tidyverse.
¿Más a menudo?
Una buena estrategia es también trabajar un poco en la refactorización cada vez que entres en una base de código para corregir un error o añadir una característica. No es necesario que la refactorización vaya en el mismo commit / rama, mantén tus cambios de código centrados y fáciles de revisar.
El paquete lintr es un paquete fantástico. Sus linters, o reglas, te recordarán o enseñarán elementos a corregir que no conocías o no podías retener en tu cabeza. Puedes ejecutarlo de vez en cuando o hacerlo funcionar en integración continua.
Incluso la simple lectura de sus referencias puede mostrarte funciones o modelos que desconocías. ¡Una verdadera joya del ecosistema R!
Otros seres humanos tendrán una buena perspectiva externa de tu código y, probablemente, ¡buenos consejos para ti!
¡Lee el código de tus colegas y viceversa! El equipo de tidyverse tiene una guía de revisión de código.
En rOpenSci, llevamos a cabo un sistema de revisión por pares de paquetes :sonrisa
Estas son las referencias de la mayor parte del contenido :smile_cat:
Charla de Jenny Bryan El código se huele y se siente
Reserva El arte del código legible de Dustin Boswell y Trevor Foucher
Libro Diseño ordenado de Hadley Wickham, en curso con boletín asociado
Libro Una Filosofía del Diseño de Software por John Ousterhout