Esta página contém os detalhes de um projeto de redação técnica aceito para a Google Season of Docs.
Resumo do projeto
- Organização de código aberto:
- Matplotlib
- Redator técnico:
- brunobeltran
- Nome do projeto:
- Como melhorar a detecção de recursos padronizando a documentação de tipos "implícitos"
- Duração do projeto:
- Longa duração (cinco meses)
Project description
Motivação
Historicamente, a API da matplotlib dependia muito de "tipos implícitos"
de string como enum. Além de imitar a API do matlab, essas strings de parâmetro permitem que o
usuário transmita valores ricos em semântica como argumentos para funções do Matplotlib
sem precisar importar explicitamente ou prefixar um valor de tipo enumerado
apenas para transmitir opções básicas de plotagem (ou seja, plt.plot(x, y, linestyle='solid')
é
mais fácil de digitar e menos redundante do que algo como plt.plot(x, y,
linestyle=mpl.LineStyle.solid)
).
Muitos desses tipos implícitos de string como tipo enumerado evoluíram para recursos
mais sofisticados. Por exemplo, um linestyle
agora pode ser uma string
ou um par ordenado de sequências, e um MarkerStyle agora pode ser uma string ou um
matplotlib.path.Path
. Embora isso seja verdade para muitos tipos implícitos, MarkerStyle
é o único (que eu saiba) que tem o status de ter sido atualizado para
uma classe Python adequada.
Como esses tipos implícitos não são classes, o Matplotlib
historicamente precisava criar suas próprias soluções para centralizar a documentação e
a validação desses tipos implícitos (por exemplo, o padrão de interpolação de docstring
docstring.interpd.update
e o padrão de validador cbook._check_in_list
,
respectivamente) em vez de usar as cadeias de ferramentas padrão fornecidas pelas classes
do Python (por exemplo, docstrings e o padrão de validação __init__
,
respectivamente).
Embora essas soluções tenham funcionado bem para nós, a falta de um local explícito
para documentar cada tipo implícito significa que a documentação geralmente é difícil
de encontrar, grandes tabelas de valores permitidos são repetidas em toda a
documentação e, muitas vezes, uma declaração explícita do escopo de um tipo
implícito está completamente ausente dos documentos. Confira os documentos plt.plot
, por
exemplo: em "Notes", uma descrição do método de estilo de string de formato semelhante a matlab
menciona as opções linestyle
, color
e markers
. Há
muitas outras maneiras de transmitir esses três valores do que se sugere, mas, para muitos
usuários, essa é a única fonte de entendimento sobre quais valores são possíveis
para essas opções até que eles encontrem um dos tutoriais relevantes. A
tabela de atributos Line2D
é incluída para mostrar ao leitor quais
opções ele tem para controlar o gráfico. No entanto, embora a entrada linestyle
seja boa para vincular a Line2D.set_linestyle
(dois cliques
necessários), onde as entradas possíveis são descritas, as entradas color
e markers
não são. color
simplesmente é vinculado a Line2D.set_color
, o que não oferece nenhuma intuição sobre quais tipos de entradas são permitidos.
Pode-se argumentar que isso é algo que pode ser corrigido simplesmente organizando as docstrings individuais que estão causando problemas, mas, infelizmente, o problema é muito mais sistêmico que isso. Sem um local centralizado para encontrar a documentação, isso simplesmente vai fazer com que tenhamos cada vez mais cópias de documentação mais detalhada repetida em todos os lugares em que cada um desses tipos implícitos é usado, dificultando ainda mais que usuários iniciantes simplesmente encontrem o parâmetro necessário. No entanto, o sistema atual, que força os usuários a juntar lentamente o modelo mental de cada tipo implícito por percurso no estilo de mergulho na Wiki em toda a nossa documentação ou em partes dos exemplos do StackOverflow, também não é sustentável.
Objetivo final
Idealmente, qualquer menção de um tipo implícito deve vincular a uma única página que descreva todos os valores possíveis que esse tipo pode ter, ordenados do mais simples e comum ao mais avançado ou esotérico. Em vez de usar um espaço visual valioso na documentação da API de nível superior para enumerar em partes todos os tipos de entrada possíveis para um parâmetro específico, podemos usar esse mesmo espaço para fornecer uma descrição simples da abstração de plotagem que o parâmetro pretende controlar.
Para usar o exemplo de linestyle
novamente, o que queremos nos
documentos LineCollection
é apenas:
- Um link para documentos completos sobre entradas permitidas (uma combinação das encontradas em
Line2D.set_linestyle
e no tutorial de linestyle). - Uma descrição simples do que o parâmetro deve alcançar. Para usuários avançados do matplotlib, isso é evidente pelo nome do parâmetro, mas para novos usuários, isso não precisa ser o caso.
A aparência disso nos documentos LineCollection
reais é apenas
python
""""""
linestyles: `LineStyle` or list thereof, default: :rc:`lines.linestyle` ('-')
A description of whether the stroke used to draw each line in the collection
is dashed, dotted or solid, or some combination thereof.
""""""
em que a referência do tipo LineStyle
seria resolvida pelo Sphinx para apontar
para um conjunto único, oficial e completo de documentação sobre como
o Matplotlib trata os estilos de linha.
Vantagens
Alguns recursos poderosos dessa abordagem incluem
- Deixar a extensão completa do que cada função é capaz de fazer óbvia em texto simples (sem necessidade de cliques).
- Tornar a opção padrão visível (sem cliques). A visualização da opção padrão muitas vezes é suficiente para refrescar a memória dos usuários que retornam.
- Faça uma descrição completa das opções "mais comuns" e "mais fáceis" para um parâmetro facilmente disponível durante a navegação (com um único clique).
- Facilite o processo de descoberta de recursos e métodos de entrada mais eficientes, como "rolar para baixo" e conferir opções mais avançadas, com apenas um clique.
- Ofereça uma estratégia centralizada para vincular documentos de "API" de nível superior aos "tutoriais" relevantes.
- Evite a explosão de documentos da API, em que a verificação de várias opções possíveis para cada parâmetro torna as strings de documentação individuais difíceis de usar.
Outros benefícios dessa abordagem em relação aos documentos atuais são:
- Os documentos têm menos probabilidade de ficar desatualizados devido à centralização.
- Canonização de muitos "padrões implícitos" da matplotlib (como o que é um ""limites"" em vez de ""extensões"") que atualmente precisam ser aprendidos com a leitura do código.
- O processo destacaria problemas com a consistência da API de uma maneira que pode ser rastreada com mais facilidade pelo rastreador de problemas do GitHub, ajudando no processo de melhoria da nossa API.
- Tempos de build de documentos mais rápidos devido a reduções significativas na quantidade de texto que precisa ser analisado.
Implementação
As melhorias descritas acima vão exigir dois esforços importantes para os quais um redator técnico dedicado será de grande valor. A primeira é criar uma página "tutorial" centralizada por tipo implícito. Isso vai exigir que você trabalhe com a equipe principal de desenvolvedores para identificar uma lista concreta de tipos implícitos cuja documentação seja valiosa para os usuários (normalmente, porque eles contêm recursos poderosos e ocultos da nossa biblioteca, cuja documentação é encontrada apenas em tutoriais difíceis de encontrar). Para cada tipo implícito, vou sintetizar os vários tutoriais relevantes, documentos da API e páginas de exemplo em uma única fonte de documentação oficial que pode ser vinculada a qualquer lugar em que esse tipo específico seja referenciado.
Depois que a documentação centralizada de um determinado tipo implícito é concluída, o
segundo esforço principal começa: substituir a documentação de API atual por links para
a nova documentação, com o objetivo de tornar a experiência de uso
dessa nova documentação o mais fácil possível, tanto para quem usa o utilitário help()
integrado do Python quanto para quem navega pela nossa documentação on-line.
Embora o formato exato da documentação proposta aqui esteja sujeito a mudanças
conforme o projeto evolui, trabalhei com a equipe principal do Matplotlib durante
as ""chamadas de desenvolvedor"" semanais para estabelecer um consenso de que a estratégia proposta
aqui é a abordagem mais conveniente, útil e tecnicamente tratável para começar
a documentar esses ""tipos implícitos"". As notas sobre essas
chamadas estão disponíveis no hackmd.
Vou usar a infraestrutura de "tutoriais" existente para os estágios iniciais da
criação da documentação centralizada para cada tipo implícito, permitindo que eu
referenciar essas páginas da seguinte forma, sem precisar criar novas classes
públicas (novamente, usando os documentos LineCollection
como exemplo):
""""""
linestyles: LineStyle or list thereof, default: :rc:`lines.linestyle` ('-')
A description of whether the stroke used to draw each line in the collection
is dashed, dotted or solid, or some combination thereof. For a full
description of possible LineStyle's, see :doc:`tutorials/types/linestyle`.
""""""
No futuro, poderemos mudar facilmente a grafia dessas referências quando a equipe principal de desenvolvedores concordar com a melhor estratégia de longo prazo para incorporar nossa nova documentação de ""tipos"" a classes Python genuínas, por exemplo, como proposto por mim na Proposta de Melhoria 30 do Matplotlib.
Por fim, a lista preliminar de tipos implícitos que proponho documentar durante esta temporada de documentos do Google é a seguinte:
capstyle
joinstyle
bounds
extents
linestyle
colors
/lists of colors
colornorm/colormap
tick formatters
Uma versão ativa deste documento pode ser encontrada no nosso Discurso.