quinta-feira, 22 de fevereiro de 2024 From rOpenSci (https://ropensci.org/pt/blog/2024/02/22/codigo-bonito/). Except where otherwise noted, content on this site is licensed under the CC-BY license.
O segundo grupo de campeões e campeãs da rOpenSci foi integrado! O treinamento começou com uma sessão sobre estilo de código, que resumiremos aqui neste post. Saber mais sobre a qualidade do código é relevante para todos os projetos da Champion, seja na criação de um novo pacote, no envio de um pacote para a revisão de software ou na revisão de um pacote. Essa sessão de treinamento consistiu em uma palestra e discussão, enquanto as próximas sessões de treinamento de desenvolvimento de pacotes serão mais práticas.
Embora o seu código seja executado por máquinas, ele será lido por humanos. Esses humanos, sejam eles você no futuro, colaboradores que você conhece ou colaboradores que você não conhece, precisarão entender o seu código para verificar se não há erros, corrigir possíveis bugs e desenvolvê-lo adicionando novos recursos. Portanto, é fundamental facilitar a compreensão do seu código.
Na primeira parte, compartilhamos dicas que tornaram o código mais “bem proporcionado”. Não se trata apenas de uma questão de estética. Um código bem proporcionado é mais fácil de ser analisado por humanos.
Compare
starwars%>%
select(name,height, mass,homeworld) %>%
mutate(
mass=NULL,
height =height *0.0328084 # convert to feet
)
com
starwars %>%
select(name, height, mass, homeworld) %>%
mutate(
mass = NULL,
height = height * 0.0328084 # convert to feet
)
No primeiro bloco, o espaçamento entre os elementos é irregular.
Por exemplo, não há espaço antes de height e não há espaço ao redor do sinal de igual que vem depois de mass.
Em vez disso, recomendamos que você siga as regras de espaçamento (e de quebra de linha!) de forma consistente. A menos que você tenha uma opinião muito diferente, a estratégia mais fácil é seguir o guia de estilo de seus colaboradores ou um guia de estilo popular, como o guia de estilo do tidyverse.
Então, como você implementa essas regras na prática?
Primeiro, você precisa estar acostumado a usar um estilo específico.
Ferramentas automáticas como o pacote styler ou seu IDE podem ajudar você.
Por exemplo, no IDE do RStudio, o atalho de teclado Ctrl+I corrige a indentação.
Uma regra tradicional é que você não deve ter mais de 80 caracteres por linha. O número exato não é importante, o importante é evitar muita rolagem horizontal!
Os pacote lintr pode avisar você sobre linhas muito largas, entre muitas outras coisas. Em comparação com o styler, o lintr não corrige as coisas sozinho.
Há também uma configuração no RStudio IDE para mostrar uma margem de 80 caracteres (Code > Display > Show Margin).
O espaço vertical é limitado no código, tanto pela tela quanto pelo que a pessoa leitora pode ver de relance (sem considerar os limites de quanto ela pode armazenar em sua cabeça).
Uma maneira de tornar o seu código mais curto, mas ainda assim fácil de analisar, é usar parágrafos de código. As quebras de linha não são gratuitas, pois ocupam espaço vertical. Use quebras de linha para separar blocos de código que fazem algo relacionado. Como na prosa, um parágrafo deve corresponder aproximadamente a uma ideia. Por exemplo, no código abaixo, o primeiro bloco faz algo relacionado ao cabeçalho de uma página do site, enquanto o segundo lida com o corpo da página do site.
head <- collect_metadata(website)
head_string <- stringify(head)
body <- create_content(website)
body_string <- stringify(body)
Uma segunda maneira de tornar o seu código menos extenso é dividi-lo em funções.
Em uma função principal, você pode terceirizar tarefas para outras funções.
Dessa forma, um(a) leitor(a) pode ver rapidamente o que a função principal faz e, em seguida, ir para as outras funções para ler mais detalhes, como no exemplo abaixo, em que create_content() chama outras funções para criar um título, uma página e, em seguida, criar uma saída que combina os dois.
create_content <- function(website) {
title <- create_title(website)
page <- create_page(website)
combine_elements(title = title, page = page)
}
Em seu livro Learn AI-Assisted Python Programming Leo Porter e Daniel Zingaro compartilham os atributos de boas funções como: tarefa clara a ser executada, comportamento claramente definido, número reduzido de linhas de código, entrada e saída claras, valor geral sobre uso específico.
Também é útil saber como navegar rapidamente entre as funções em seu IDE!
No IDE do RStudio, você pode usar Ctrl+click no nome da função ou digitar o seu nome na barra de pesquisa acessada com Ctrl+..
Uma terceira maneira de encurtar o seu código é usar funções existentes do R básico ou de pacotes complementares.
Por exemplo, para combinar uma lista de valores padrão com uma lista de valores personalizados, você pode usar a função modifyList().
Assim como nos idiomas humanos, aprendemos mais palavras em R com o tempo, lendo o código de outras pessoas e fazendo com leiam o nosso código.
Esta parte do treinamento foi uma versão mais curta da publicação no blog do R-hub Por que comentar seu código o mínimo (e o melhor) possível.
Os comentários de código não são uma narração do código, eles devem funcionar como alertas curtos. Quanto mais comentários você tiver, maior será a probabilidade da pessoa leitora ignorá-los.
Os comentários de código não devem ser um “band-aid” para nomes ruins ou código excessivamente complexo: em vez de adicionar um comentário, você pode renomear uma variável ou refatorar um trecho de código?
Uma ideia útil é usar funções ou variáveis autoexplicativas, onde um código como
if (!is.na(x) && nzchar(x)) {
use_string(x)
}
se torna
x_is_not_empty_string <- (!is.na(x) && nzchar(x))
if (x_is_not_empty_string) {
use_string(x)
}
É claro que os comentários de código continuam sendo importantes quando necessários! Exemplos de bons comentários incluem:
# This query can not be done via GraphQL, so have to use v3 REST API,Na segunda parte do treinamento, compartilhamos dicas que melhoram a clareza do código.
Dar nomes às coisas é notoriamente difícil. Nós compartilhamos essas ideias:
Siga a moda, ou seja, use as mesmas palavras que outras pessoas em sua área ou linguagem de programação.
Felienne Hermans, em seu livro The Programmer’s Brain aconselha que você escolha os conceitos que compõem o nome, as palavras para dizê-lo e, em seguida, junte-os. Essa abordagem em três etapas é uma boa maneira de você se livrar do problema.
Seguindo o conselho anterior, os nomes devem ser consistentes em toda a base de código, e os name molds são uma ferramenta muito boa para isso. Moldes de nomes são padrões nos quais os elementos de um nome são combinados; por exemplo, se você calcular o valor máximo do rendimento da colheita, precisará concordar se maximum será max ou maximum e se a palavra estiver no início ou no final do nome da variável: deve ser maxYield ou yieldMax? Ao normalizar a forma de nomear as coisas, nosso código será mais fácil de ler.
“Quanto maior a distância entre a declaração de um nome e seus usos, mais longo deve ser o nome” (Andrew Gerrand). Entretanto, não importa o quão perto da definição de uma variável você a use, não use uma abreviação inteligente e muito curta.
Há várias maneiras de escrever os nomes de variáveis. O estilo camelCase leva a uma maior precisão na leitura do código (Dave Binkley, 2009) e é melhor para a leitura do código com leitores de tela. Sabemos que é difícil alterar o estilo de um projeto existente, mas se você estiver em uma situação em que possa decidir do zero, considere usar Camel Case. Se você não tiver certeza sobre os nomes dos casos, consulte o artigo cartoon of cases de Allison Horst (role para baixo até “Cartoon representations of common cases in coding”).
Um nome é claro se a pessoa que estiver revisando o seu código concordar com ele.
Outra dica é que não há problema algum em criar funções que envolvam funções existentes apenas para mudar o nome delas. Essa estratégia é comum para alterar a ordem dos argumentos, mas também é adequada para a nomeação. Digamos que você prefira que os nomes das funções sejam ações (verbos) em vez de descrições passivas, você pode ter:
# In utils.R
remove_extension <- function(path) {
tools::file_path_sans_ext(path)
}
# In other scripts
remove_extension(path)
return(), switch()Em uma função,
do_thing <- function(x) {
if (is.na(x)) {
NA
} else {
x + 1
}
}
é equivalente a
do_thing <- function(x) {
if (is.na(x)) {
return(NA)
}
x + 1
}
mas o último, com o início return() tem menos aninhamento e enfatiza o “caminho feliz”.
A função switch() também pode ajudar você a remover estruturas if-else aninhadas.
Com ela,
if (type == "mean") {
mean(x)
} else if (type == "median") {
median(x)
} else if (type == "trimmed") {
mean(x, trim = .1)
}
torna-se
switch(type,
mean = mean(x),
median = median(x),
trimmed = mean(x, trim = .1)
)
O código que você não escreve não tem bug (pelo qual você é responsável) e não precisa ser lido. 🎉
Antes de tudo, seja rigoroso quanto ao escopo do que você está tentando realizar.
Em segundo lugar, use dependências confiáveis para terceirizar parte do trabalho. O capítulo “Dependencies: Mindset and Background “ do livro R packages, de Hadley Wickham e Jenny Bryan, é uma ótima leitura sobre o assunto.
Na prática, como você aplica o que aprendeu sobre estilo de código? E como você atualiza as suas bases de código legadas criadas antes de você conhecer alguns desses aspectos?
Talvez você possa trabalhar regularmente no estilo e na refatoração do código.
Uma vez por ano? Andy Teucher escreveu no blog uma postagem interessante sobre a limpeza de primavera do tidyverse Package spring cleaning.
Com mais frequência?
Uma boa estratégia também é trabalhar um pouco na refatoração sempre que você entrar em uma base de código para corrigir um bug ou adicionar um recurso. A refatoração não precisa ir para o mesmo commit/ramo, mantenha as suas alterações de código nucleares e fáceis de revisar.
O pacote lintr é um pacote fantástico. Seus linters, ou regras, o lembrarão ou ensinarão sobre elementos a serem corrigidos que você não conhecia ou não conseguia manter na cabeça. Você pode executá-lo de vez em quando ou fazer com que ele seja executado em integração contínua.
Mesmo uma simples leitura da referência pode mostrar funções ou padrões que você desconhecia. Uma verdadeira joia do ecossistema R!
Outros seres humanos terão uma boa perspectiva externa do seu código e, provavelmente, boas dicas para você!
Leia o código de colegas e vice-versa! A equipe do tidyverse tem um guia de revisão de código.
Na rOpenSci, executamos um sistema de revisão por pares de pacotes de software 😁
Estas são as referências para a maior parte do conteúdo do treinamento: :smile_cat:
Palestra de Jenny Bryan Code Smells and Feels
Livro The Art of Readable Code por Dustin Boswell e Trevor Foucher
Livro Tidy Design, de Hadley Wickham, em andamento, com boletim informativo associado