Uma das grandes vantagens de se utilizar Jupyter Notebooks para nossos projetos de AI, Machine Learning e Dados, é que nós podemos com muita facilidade documentar o nosso projeto, de forma bonita e agradável, utilizando células de Markdown em conjunto com células de código.
Eu acredito que todos conheçam esta funcionalidade dos Jupyter Notebooks e saibam como inserir células de documentação Markdown, pois toda e qualquer introdução aos notebooks irá cobrir esta parte. Caso você não conheça os Jupyter Notebooks ou não saiba inserir células Markdown, uma busca rápida no Google deve ajudar com isso.
E se você está pensando “Caramba, mais um post sobre Markdown na internet…”, eu espero te animar dizendo que vamos um pouco além. Vamos falar sobre o uso de JavaScript e até mesmo de frameworks CSS nos Jupyter Notebooks. Este post pode (e deve) ser salvo para referências futuras e te ajudar na hora da formatação do seu notebook.
Nós vamos, porém, dar sim um passo atrás e vamos discutir brevemente sobre…
O que é Markdown?
Markdown é uma linguagem extremamente leve de marcação (markup language) usada para formatação de textos em editores simples. A linguagem foi criada em 2004 por John Gruber e Aaron Swartz e podemos encontrar a página oficial do projeto no site do John, Daring Fireball.
Esta linguagem de marcação é muito simples e intuitiva e nos permite escrever texto de maneira simples e fácil de ler – de uma forma que sabemos o resultado final mesmo lendo só o código fonte. Após interpretada, a sintaxe do Markdown é convertida em HTML válido que pode ser exibido em qualquer navegador web.
E por falar em sintaxe, Markdown faz uso apenas de alguns caracteres especiais que regem a formatação do texto. Por exemplo, podemos utilizar asteriscos para criar texto em negrito ou usar o sinal de sublinhado (underline) para criar texto em itálico. Além disso, o Markdown também permite que criemos títulos, listas, links, adicionemos imagens de maneira simples, e muito mais.
Uma das principais vantagens do Markdown é que ele permite que nos concentremos no nosso texto, em vez de nos preocuparmos tanto com a formatação, e sem a necessidade do uso do mouse (nós, programadores, adoramos isso, né?). Isso o torna uma opção popular para a criação de documentos, artigos, relatórios e até mesmo notas de aulas. Ele é também largamente utilizado em plataformas web, onde é possível escrever mensagens com formatação de forma segura sem precisar usar HTML.
Até mesmo o WhatsApp usa um “sabor” de Markdown, você sabia?
Markdown em Jupyter Notebooks
Existem diversos “sabores” de Markdown, cada um com suas particularidades. Jupyter Notebooks fazem uso de uma sintaxe muito similar à original, e a própria documentação oficial do Jupyter Notebook faz menção ao projeto original. De acordo com o site Jupyter Book, a sintaxe dos notebooks é uma extensão do “sabor” chamado CommonMark Markdown.
O importante é que a sintaxe básica vai ser a mesma que iremos encontrar em toda e qualquer documentação ou tutorial de Markdown disponível na internet. Vamos revisar aqui alguns das funcionalidades básicas do Markdown.
Para títulos usamos o caractere “hashtag” ( #
), onde podemos ter títulos de seis tamanhos e relevância diferentes. Uma sequência de três ou mais traços ( ---
) ou asteriscos ( ***
) sozinhos em uma linha de texto formam uma linha horizontal, muito útil para divisão de seções do texto
# Título 1
---
## Título 2
### Título 3
***
#### Título 4
##### Título 5
##### Título 6
Esta marcação vai ter como equivalente o seguinte código HTML.
<h1>Título 1</h1>
<hr>
<h2>Título 2</h2>
<h3>Título 3</h3>
<hr>
<h4>Título 4</h4>
<h5>Título 5</h5>
<h6>Título 6</h6>
E irá renderizar da seguinte forma.
Algumas das outras formatações padrão de Markdown são de negrito, itálico, riscado, citações, listas, hyperlinks e imagens. Vamos tentar cobrir esses pontos de forma bem sucinta, pois acredito que já tenham visto material o suficiente sobre isso na internet.
Dentro da sintaxe padrão do Markdown nós podemos ter
**texto em negrito** e também _texto em itálico_, e
podemos ter até ***texto em negrito E em itálico***.
Caso ~~tenha se arrependido de escrever algo~~ queira
riscar algum texto, é possível fazer também e deixá-lo
~~assim~~.
Podemos ter código `inline` no texto, como `model.fit()` .
- Podemos listar
- nossos itens
- (e texto)
- de forma não-ordenada.
1. Ou podemos listar
2. de forma ordenada.
Hyperlinks podem ser inseridos, como este para o site do
[BRAINS](https://brains.dev/). E podemos também inserir
uma imagem.
![Texto Alternativo para BRAINS](https://brains.dev/wp-content/uploads/2022/11/BRAINS_black-230-%C3%97-50-px.png)
O equivalente em HTML seria como o código abaixo.
Dentro da sintaxe padrão do Markdown nós podemos ter
<strong>texto em negrito</strong> e também
<em>texto em itálico</em>, e podemos ter até
<strong><em>texto em negrito E em itálico</strong></em>.
Caso <del>tenha se arrependido de escrever algo</del>
queira riscar algum texto, é possível fazer também e deixá-lo
<del>assim</del>.
Podemos ter código <code>inline</code> no texto, como
<code>model.fit()</code> .
<ul>
<li>Podemos listar</li>
<li>nossos itens
<ul>
<li>(e texto)</li>
</ul>
</li>
<li>de forma não-ordenada.</li>
</ul>
<ol>
<li>Ou podemos listar</li>
<li>de forma ordenada.</li>
</ol>
Hyperlinks podem ser inseridos, como este para o site do
<a href="https://brains.dev/">BRAINS</a>. E podemos também
inserir uma imagem.
<img src="https://brains.dev/wp-content/uploads/2022/11/BRAINS_black-230-%C3%97-50-px.png" alt="Texto Alternativo para BRAINS">
E o texto renderizará da seguinte forma.
Espero que essa revisão sucinta sobre Markdown não tenha ficado cansativa, eu sei que isso é “mais do mesmo” para muitos, mas não poderia deixar de cobrir esse básico para quem não conhece. Vale ressaltar que é possível combinar diferentes formatações, como títulos e itálico ou código inline, mas cobrir todas as combinações aqui seria exaustivo. Eu recomendo que treinem e testes todas as combinações que vierem à mente para pegarem prática com Markdown. E caso tenham alguma dúvida sobre a sintaxe de Markdown, irão facilmente encontrar a resposta na internet.
Mas agora vamos ao que interessa, vamos além nos Jupyter Notebooks.
Indo além nos Jupyter Notebooks
Foi importante fazer aquela chata comparação acima de Markdown e HTML para vermos que há algo acontecendo por trás, e que nossa IDE de Jupyter Notebook nada mais é do que uma interface web, uma página da internet, que é renderizada e exibida no seu navegador. E hoje, qualquer página web se resume a HTML, CSS e JavaScript. Dominar esses três vai fazer com que você domine a apresentação do seu notebook.
Para contextualizar, um Jupyter Notebook, como dito, é apenas uma página servida por um servidor de notebooks Jupyter, que é uma aplicação web que roda no backend e gerencia a execução dos notebooks. Um arquivo .ipynb
nada mais é que um grande arquivo JSON com metadados sobre as células que se renderiza em HTML, sendo estilizado por CSS e com suas funções gráficas sendo manuseadas via JavaScript.
Quando nós abrimos um notebook no navegador, o servidor Jupyter recebe o conteúdo das células, envia o código para um kernel, que por sua vez executa o código da linguagem de programação em questão e devolve para o servidor a saída do código, a ser exibida na nossa página web. No caso do Python, nós temos o kernel IPython fazendo esse trabalho para nós.
Se você tiver interesse em entender mais sobre como funcionam os Jupyter Notebooks e sobre a arquitetura do IPython, podemos escrever sobre isso no futuro (e se você domina o assunto, colabora com nossa comunidade e escreve sobre pra gente!).
Um ponto importante a ressaltar é que quando falamos de HMTL, CSS e JavaScript, estamos falando de estilizar a apresentação do notebook como um todo – no geral as células Markdown. É possível sim estilizar e formatar as saídas de código também, mas isso é assunto para um outro dia. Caso tenham interesse em saber mais sobre isso, o artigo Formatting code outputs (Inglês) do site Jupyter Book pode ser útil.
Mas vamos voltar a falar da formatação.
Formatando o código em Jupyter Notebooks
Eu acabei de falar que não vamos falar da formatação da saída de códigos e agora aparece esse título? Parece até sacanagem né. Mas a questão aqui é ligeiramente diferente, estamos falando de trechos de código dentro das células Markdown.
Vimos acima que é possível colocar trechos de código inline
, ou seja, dentro de uma linha de texto puro. Fazemos isso colocando o texto entre crases e ele vai aparecer como mostramos acima.
O que muita gente sabe, é que podemos também ter código multilinhas, fazendo uso de três crases para abrir o bloco de código e três crases para fechar o bloco de código. Vamos ver um exemplo.
# Formatação de código
Podemos ter código `inline` assim e código multilinhas,
como abaixo.
```
import numpy as np
for i in range(10):
print(f'Entrada número {i+1}')
```
Este trecho de código renderiza da seguinte forma.
O que talvez algumas pessoas não saibam, é que os Jupyter Notebooks fazem uso do “sabor” do GitHub de Markdown para formatação de trechos de código. Para isso, basta especificar a linguagem do bloco de código ao abri-lo. Vamos ver um exemplo.
# Formatação de código
Podemos ter o código multilinhas formatado.
```python
import numpy as np
for i in range(10):
print(f'Entrada número {i+1}')
```
Que irá renderizar assim.
Bem melhor, né? E o mais legal é que o próprio estilo do Markdown vai conseguir encontrar erros no nosso código e apontá-los para nós. Vamos ver um exemplo com um erro de indentação e um parêntesis a mais. Note que onde há os erros fica vermelho.
E o legal é que não é apenas Python, podemos usar estilos de formatação para diversas linguagens.
# Formatação de código
Formatando código JavaScript.
```javascript
for (var i = 1; i <= 10; i++) {
console.log("Entrada número" + i); // Mesma saída
}
```
Legal, né? Vamos ver agora como fazer algumas “gambiarras” com HTML e CSS para personalizar ainda mais a formatação.
HTML & CSS nos Jupyter Notebooks
HTML e CSS são a base da estilização de qualquer página web e são conteúdo para livros e cursos inteiros. Seria impossível mostrar aqui nem mesmo uma fração das possibilidades, mas o objetivo é mostrar o tipo de personalização que é possível e deixá-los curiosos para ir atrás de mais conteúdo. Para guias rápidos e práticos sobre HTML e CSS, recomendo muito a W3Schools.
Uma das opções do CSS que eu acho muito interessante é a opção de float
para imagens. No geral, as imagens dos notebooks são sempre centralizadas. Mas definindo a propriedade float
podemos jogar imagens para os cantos e termos texto ao lado. Vamos ver o código e como fica a saída.
<img src="https://brains.dev/wp-content/uploads/2022/12/Logo_big.png" width="115px" style="float: right;">
# <center>BRAINS - Brazilian AI Networks</center>
## <center>Dicas de formatação para Jupyter Notebooks<center>
---
Eu gosto muito de fazer algo similar quando vou construir um notebook que será apresentado, internamente ou para algum cliente. Gosto de colocar a logo do cliente no início do notebook. Isso dá um ar profissional e personalizado ao notebook. Notem que fiz uso da tag <img>
com o style
de float: right;
e também de tags <center>
para centralizar o texto.
Usar imagens com float à direita ou à esquerda e com texto acompanhando torna a sua apresentação muito mais bonita e didática. Veja por exemplo este notebook didático ensinando sobre Regressão Linear.
E já que estamos falando de didática, quando vamos nos referir a algum elemento de saída de um código, ou de uma imagem inserida via Markdown, podemos fazer uso da formatação para deixar o texto com referências mais fáceis de entender.
Vamos pegar o exemplo acima e editar o último parágrafo, fazendo uma tradução livre a alterando ligeiramente para fins de exemplificação. Vamos ver o código e saída renderizada.
Nós gostaríamos de treinar um modelo de Regressão Linear
(exibido acima como a **<font color="blue">reta azul</font>**)
que melhor explique o padrão existente entre os
**<font color="red">pontos vermelhos</font>**,
para que possamos prever os preços de outras casas (...) .
E se você gosta de compartilhar seus notebooks de estudos (assim como eu), uma outra ferramenta super útil para você é a tag HTML <details>
, que vai te permitir ocultar dicas e/ou respostas de desafios propostos – e exibir quando a pessoa quiser ver.
Vamos ver um exemplo em código e como ficaria a sua saída, animada.
## Exercício 1
Desenvolva um código em Python que exiba todos os números
pares entre 0 e 100.
<br>
<details>
<summary>
<font size='3', color='darkblue'>
<b>Dica ↓</b>
</font>
</summary>
- Para sabermos se um número é par ou não, podemos usar
o operador `%` .
</details>
<br>
<details>
<summary>
<font size='3', color='darkblue'>
<b>Solução ↓</b>
</font>
</summary>
```python
for i in range(101):
if i % 2 == 0:
print(i)
```
</details>
Nós vamos ter dois campos clicáveis, “Dica ↓” e “Solução ↓“, que irão ocultar e exibir o texto abaixo delas. Vamos ver como fica.
Esta interatividade e o uso de HTML e CSS vão tornar o seu notebook muito mais atrativo. Mas vamos ver agora aplicações de CSS um pouco mais avançadas.
Frameworks CSS em Jupyter Notebooks
Existem hoje diversos frameworks CSS que nos auxiliam a personalizar nossas páginas web de maneira muito mais rápida e eficiente, deixando-as belíssimas. E os Jupyter Notebooks, assim como praticamente todas as outras páginas da internet, tem a sua própria folha de estilos de CSS. O interessante é que os estilos aplicados sobre as nossas células são baseados em um dos frameworks CSS mais famosos do mundo, o Bootstrap.
Para ver todas as possibilidades que o framework oferece (são muitas), visite a documentação oficial no link acima. Vamos abordar aqui apenas alguns exemplos que eu acho bastante interessantes para os meus notebooks.
O primeiro é a <div>
de alertas. Com elas conseguimos colocar alertas de diversos tipos nas nossas células Markdown. Vamos ver um exemplo.
# Bootstrap
## Alertas
<div class="alert alert-info">
**Nota**
É possível inserir uma nota formatada usando o Bootstrap.
</div>
E temos também outras possibilidades, com outras cores, alterando apenas a classe da div. Usamos a classe alert-info
para o exemplo acima, mas podemos usar a classe alert-danger
para alertas vermelhos de perigo, a classe alert-success
para alertas verdes de sucesso e a classe alert-warning
para alertas de aviso, amarelos. Vamos ver os resultados.
Uma outra classe interessante do Bootstrap são as Badges (ou “medalhas”, em tradução livre), que servem para dar ênfase a algum título, por exemplo.
Vamos supor que você inseriu no notebook colaborativo uma nova função avançada para plotar gráficos e quer chamar a atenção do seu time para isso, podemos usar uma Badge.
# Badges
<h3>Função Avançada de Gráficos
<span class="badge bg-secondary">Novo</span>
</h3>
Podemos também gerar botões estilizados com Bootstrap e listas que vão muito além na formatação do que as listas padrão do Markdown. E – como sempre – podemos combinar classes e formatações. O segredo é sempre experimentar.
Vamos ver alguns exemplos abaixo.
# Botões
<button type="button" class="btn btn-primary btn-lg">
Botão Grande Principal
</button>
<button type="button" class="btn btn-secondary btn-lg">
Botão Grande Secundário
</button>
# Listas
<ul class="list-group">
<li class="list-group-item active" aria-current="true">
Um item ativo
</li>
<li class="list-group-item">
Um segundo item
</li>
<li class="list-group-item">
Um terceiro item
</li>
<li class="list-group-item">
Um quarto item
</li>
<li class="list-group-item">
E um quinto
</li>
</ul>
<ul class="list-group">
<li class="list-group-item list-group-item-success">
Um item de lista de sucesso
</li>
<li class="list-group-item list-group-item-danger">
Um item de lista de perigo
</li>
<li class="list-group-item list-group-item-warning">
Um item de lista de alerta
</li>
<li class="list-group-item list-group-item-info">
Um item de lista de notas ou informações
</li>
</ul>
O próximo passo agora é explorar a documentação do Bootstrap para ver quais classes funcionam na folha de estilos dos Jupyter Notebooks e ver quais combinações dão bons resultados. A nossa curiosidade é o limite aqui.
E para personalizações um pouco mais avançadas e específicas, podemos usar JavaScript.
JavaScript nos Jupyter Notebooks
Aplicações onde iremos manipular o JavaScript da página do notebook costumam ser um pouco mais específicas (e avançadas, talvez). Para isso vamos precisar bastante de criatividade e um pouquinho de conhecimento da linguagem de programação interpretada pelos navegadores.
Vou trazer para vocês um exemplo bem prático e pontual que precisei resolver e usei JavaScript dentro dos notebooks. A PO de um dos times mais importantes do nosso cliente queria encontrar uma forma de ocultar a entrada e saída de algumas células dos notebooks.
Ela exportava o arquivo .ipynb
para HTML e usava isso como relatório de apresentação para a sua Diretoria, que tinha um cunho mais técnico. Ela gostaria de ocultar determinadas células para deixar o relatório mais limpo e apresentável.
Como o ambiente de desenvolvimento do cliente era um servidor Jupyter Lab rodando na Cloud privada deles, ela não conseguiria instalar extensões para fazer isso, e precisava de uma solução mais personalizada. Foi quando ela entrou em contato comigo para ver se conseguiria ajudar.
Para fazer o que ela queria, desenvolvi um módulo que era carregado no notebook em questão e fazia uso de uma magic line para carregar a função de ocultar a célula. Esta função “injetava” JavaScript dentro do HTML da página de forma que permitisse que a pessoa ocultasse e exibisse a célula clicando em um botão.
Podemos ver acima uma demonstração com o resultado final.
Se tiverem outros casos de uso do JavaScript em notebooks que queiram compartilhar, deixem nos comentários ou escrevam sobre para compartilhar e colaborar com a nossa comunidade. Estou curioso para saber outras aplicações que vocês já tenham usado ou pensado sobre.
Caso tenham interesse, posso compartilhar em um outro post como desenvolvi esse módulo e como “injetei” o JavaScript dentro do notebook.
Conclusão
Mais uma vez esperamos ter aguçado a curiosidade de vocês para pesquisar e testar novas combinações de formatação usando Markdown, HTML, CSS e JavaScript. Além disso, é um ótimo motivo para nós, da área de Dados, estudarmos um pouco mais de desenvolvimento de aplicações web. Conhecimento, quanto mais, melhor!
Caso tenha ficado com dúvidas ou tenham outras ideias de formatação interessantes, compartilhem com a gente nos comentários. Ou escreva o seu próprio post (ou traduza um) e mande pra gente que iremos ficar muito felizes de compartilhar aqui na nossa comunidade.
Sei que há diversos pontos de formatação que não foram cobertos, mas ficaria extremamente cansativo cobrir todos. Um outro ponto interessante que não foi abordado foi o uso de LaTeX para formatação de fórmulas matemáticas. Talvez fale sobre isso, brevemente, no futuro.
Acredito que possa ser interessante guardar esse post nos favoritos para consultas futuras de como formatar determinada célula. Espero ter ajudado. 🙂
E se estiver gostando da nossa comunidade, conheça um pouco mais sobre nós e nossos objetivos de fortalecer a comunidade brasileira de dados no post BRAINS – Brazilian AI Networks.
1 comentário