Olá, meu nome é André Santana e sou o instrutor que vai acompanhar você neste curso.
Audiodescrição: André Santana se identifica como uma pessoa branca. Possui barba cheia e cabelos curtos, ambos castanho-claros. Veste uma camiseta clara. Ao fundo, a sala da Alura com uma parede lisa, iluminada em tons de roxo e azul, e uma estante direita, decorada com uma série de objetos da cultura geek.
Neste curso, aprenderemos a:
Este curso é para quem:
Para aproveitar bem este curso, é importante fazer os cursos anteriores desta formação.
Vamos trabalhar em um projeto que envolve a criação de cenários de teste, casos de uso e testes automatizados usando Selenium. Para isso, vamos usar a plataforma AcordeLab e garantir que todas as ações da pessoa usuária sejam testadas através desses testes automatizados.
Dentro do curso, além dos nossos vídeos, temos as atividades, a comunidade do Discord e o fórum do curso. Aproveite bastante esses recursos!
Nos vemos na primeira aula.
Nesta aula, vamos começar a implementar um processo de automação de testes. Para isso, vamos conhecer um pouco da aplicação que vamos utilizar para elaborar esses testes automatizados.
Vamos utilizar o AcordeLab, uma plataforma para ajudar pessoas que querem aprender mais sobre alguns tipos de instrumento musical. A ideia é criar, usando o OpenAI, um processo de automação de testes para testar a navegação da aplicação com a pessoa usuária final, e garantir que possamos direcionar esforços na experiência da pessoa usuária.
Ao acessar a aplicação AcordeLab pelo navegador, podemos fazer login nela, preenchendo os campos "E-mail" e "Senha", e clicando no botão "Login".
Ao realizar login, seremos direcionados para uma página na qual podemos ter acesso aos cursos disponíveis. No topo da tela, podemos utilizar um campo de busca e filtros para buscar cursos diferentes, dos tipos "Violão", "Piano" ou "Guitarra".
Podemos acessar um desses cursos clicando nele para adicioná-lo ao dashboard.
A partir disso, vamos utilizar o OpenAI para criar um teste automatizado, desde a concepção de um caso de uso até um script que permita a navegação de forma adequada dentro da aplicação.
Vamos configurar o ambiente de desenvolvimento para darmos os nossos primeiros passos nesse processo.
Temos a atividade "Preparando o ambiente", mas neste momento vamos configurar bibliotecas importantes para poder utilizar a parte da OpenAI com o GPT e a parte de automação com o Selene.
O primeiro passo será configurar o ambiente de desenvolvimento para garantir que as bibliotecas que vamos utilizar nesse projeto não gerem nenhuma incompatibilidade, mesmo tendo uma versão diferente da que temos costume de utilizar para outros projetos.
Com o Visual Studio Code aberto no arquivo README.md
, vamos começar abrindo o terminal e, a partir dele, colar o primeiro trecho de código disponível no arquivo MD, também disponível abaixo, que permite criar o ambiente virtual.
python-m venv curso_3_openai
Ao pressionar "Enter", ele vai criar para nós o ambiente curso_3_openai
, mas ainda não temos nenhuma biblioteca instalada.
Antes de começar a fazer as instalações, é importante ativar o ambiente virtual. Se observarmos o terminal, temos apenas o caminho do projeto, D:\Videos - Cursos\Programação Projeto--13663
, mas ainda não temos o ambiente selecionado.
Vamos copiar o segundo trecho de código do arquivo MD, disponível abaixo, que é compatível com o Windows.
curso_3_openai\Scripts\activate
Vamos executá-lo no terminal, e em seguida, conseguiremos observar à esquerda do caminho de diretório o nome do ambiente virtual.
(curso_3_openai) D:\Videos - Cursos\Programação Projeto--13663
Feito isso, vamos fazer a instalação das bibliotecas necessárias para o projeto. Vamos rodar o comando pip
na linha 24 do arquivo MD, com todas as bibliotecas que vão fazer parte desse projeto que vamos desenvolver juntos.
pip install numpy openai python-dotenv tiktoken opencv-python selenium faiss-cpu
Ao executar, o terminal vai começar um processo de instalação. Em alguns casos, a versão do pip
que temos precise ser atualizada. Nesse caso, o próprio terminal vai indicar a necessidade dessa atualização.
Após a execução, se observarmos, tivemos um alerta no próprio terminal indicando que precisamos atualizar a versão do pip
.
[notice] A new release of pip available: 22.3.1 -> 24.0
[notice] To update, run: python.exe -m pip install --upgrade pip
No próprio terminal, vamos copiar o comando que ele sugeriu e colar no terminal para garantir que estejamos com as versões mais atualizadas dos pacotes de instalação.
python.exe -m pip install --upgrade pip
Ao executar, rodaremos mais uma instalação no ambiente de trabalho, até recebermos a mensagem de que a instalação foi concluída com sucesso.
Feito isso, vamos para a parte 2, que é instalar todo o pacote do Selenium. Para isso, é muito importante utilizar o Google Chrome e garantir que tenhamos uma versão compatível.
Uma alternativa, para não precisar ficar checando a versão do Google Chrome, é baixar uma versão de testes. Vamos ao navegador para baixar essa versão de testes que permitirá utilizar o Selenium para automação da navegação da aplicação.
No próprio navegador Google Chrome, podemos escrever "driver selenium" na barra de busca. Alternativamente, nesse caso, podemos ser específicos e buscar diretamente por "driver Chrome".
O primeiro link retornado, chromedriver.chromium.org
, traz algumas informações sobre as versões mais atuais do Google Chrome, tanto para testes, quanto do drive que podemos utilizar para nos conectar com o Selenium.
Vamos clicar nessa opção, e a página exibida vai trazer a seção "Current Releases" com informações importantes sobre a versão que estamos utilizando. Podemos ignorar a versão se baixarmos uma versão de teste específica para utilizar na aplicação.
Vamos clicar no texto "the Chrome for Testing availability dashboard", em vermelho, que traz o dashboard com as versões do Chrome. Na tela exibida, veremos que há várias opções disponíveis.
Vamos rolar essa tela para baixo, até encontrar a seção "Stable", que exibe opções estáveis do Google Chrome. Nela, vamos baixar a versão do Google Chrome compatível com o nosso sistema operacional.
Na gravação deste vídeo, estamos utilizando o Windows, com um processador de 64 bits, então vamos copiar o link da URL por volta da quinta linha.
Binary | Platform | URL | HTTP status |
---|---|---|---|
… | … | … | … |
chrome | win64 | https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.58/win64/chrome-win64.zip | 200 |
… | … | … | … |
Vamos colá-lo em uma aba nova, fazendo com que ele baixe esse arquivo.
Também vamos precisar do driver chromedriver, então, vamos procurar na mesma seção uma versão compatível com o nosso sistema operacional, a versão Windows 64 bits. Ela estará por volta da décima linha.
Binary | Platform | URL | HTTP status |
---|---|---|---|
… | … | … | … |
chromedriver | win64 | https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.58/win64/chromedriver-win64.zip | 200 |
… | … | … | … |
Vamos baixar essa versão também, copiando a URL e também colando em outra aba do navegador.
Após os dois downloads, podemos acessar as pastas baixadas e copiar o driver para dentro do projeto. Devemos garantir também que o Google Chrome esteja descompactado para que possa ser aberto durante o uso da aplicação.
Dentro do explorador de arquivos do computador, na pasta de downloads, onde baixamos os arquivos do chromedriver e do Chrome versão de teste que acabamos de buscar, vamos descompactar esses dois arquivos. Podemos clicar neles com o botão direito do mouse e, com a opção "Extrair tudo", utilizar o descompactador padrão do sistema operacional, para ter acesso às duas pastas já descompactadas.
Vamos acessar a pasta do chromedriver e verificar que em seu interior tem um diretório de mesmo nome, e dentro deste, um chromedriver.exe
. Vamos copiar esse arquivo para dentro da pasta do projeto. Para isso, vamos pressionar "Ctrl+C" nele, e voltar para o diretório do projeto, dentro do Visual Studio.
Agora que já temos acesso ao chromedriver que vamos precisar, vamos acessar o explorador lateral esquerdo. Clicando no ícone de pasta com um símbolo de mais à direita do título do projeto, criaremos um diretório novo, chamado "driver".
Nesse diretório novo, vamos colar o arquivo chromedriver.exe
com "Ctrl+C". Com isso, a IDE exibirá uma caixa de diálogo perguntando se realmente queremos colar esse arquivo. Vamos marcar "Paste" para responder "sim", e em seguida, veremos o arquivo dentro da pasta "driver" pelo explorador lateral.
Podemos fechar a aba desse arquivo que será aberta automaticamente, e desse jeito temos o ambiente preparado para começar a implementar os testes. Até o próximo vídeo!
Após ter o ambiente configurado, estamos de volta na aplicação e vamos entender a importância de criar testes.
Vamos imaginar que temos a aplicação AcordeLab, e precisamos garantir que a pessoa usuária possa se autenticar através do e-mail e da senha para acessar todos os recursos disponíveis.
Esse processo de garantir que a pessoa usuária possa se autenticar representa uma tarefa que precisa ser vencida pela pessoa usuária para poder utilizar a aplicação com todos os seus recursos. Essa tarefa, dentro da engenharia de software, é traduzida como um caso de uso.
O caso de uso é uma tarefa que deve ser feita pela pessoa usuária para garantir que, dentro de um contexto específico, ela possa usar uma aplicação de forma adequada.
Nosso desafio neste curso será criar testes automatizados, com o auxílio da OpenAI, para que ela possa, inicialmente, elaborar esse caso de uso para nós e garantir o aproveitamento disso para gerar os scripts de teste automatizado.
Esse percurso envolve a navegabilidade, ou seja, a capacidade de garantir que, uma vez pressionado o botão "Login", a página de login da aplicação nos direcione para a próxima, garantindo que nenhum recurso será interrompido ou esteja "quebrado".
Acessando o Visual Studio, vamos começar a implementar o necessário para gerar casos de uso. Inicialmente, vamos criar um novo script pelo explorador lateral esquerdo, clicando no ícone de novo arquivo, à direita do título do projeto. Esse script será chamado gerador_casos_uso.py
e estará vazio.
Em seu interior, vamos começar importando alguns recursos desse script necessários para utilizar as bibliotecas da OpenAI para poder se comunicar com o GPT. Vamos copiar o conteúdo abaixo e colar no arquivo com "Ctrl+V".
gerador_casos_uso.py
from openai import OpenAI
from tools import *
from dotenv import load_dotenv
import os
load_dotenv()
cliente = OpenAI(api_key=os.getenv("OPΕΝΑΙ_API_KEY"))
Nesse processo, na linha 2, temos a biblioteca de ferramentas tools
que vamos utilizar para fazer uma leitura de arquivos, que ainda não implementamos. Vamos fazer isso na sequência.
Na linha 1, temos a importação da biblioteca da OpenAI. Na linha 3, fizemos a leitura das variáveis de ambiente, onde estarão as chaves de acesso da API. Na linha 4, importamos o sistema operacional para acessar essas chaves de ambiente, e no método da linha 6, fizemos a leitura delas. Por fim, na linha 8, temos o objeto de cliente criado já numa instância da OpenAI que permite acessar a chave de ambiente.
As variáveis de ambiente estarão disponíveis nos arquivos, portanto, podemos abrir o explorador de arquivos lateral novamente e acessar o .env
disponível para ter acesso à chave de API.
.env
OPENAI_API_KEY = // Código omitido
Lembrando sempre que OPENAI_API_KEY
é uma palavra reservada que funciona como um dicionário, e a chave de API terá que ser gerada na página da OpenAI que você tem acesso para utilizar os recursos do GPT.
Feito isso, podemos fechar a aba da variável de ambiente, e acessar o .gitignore
para garantir que ele tenha a marcação abaixo, impedindo que essa variável de ambiente seja exportada para um repositório público onde outras pessoas desenvolvedoras terão acesso ao projeto e à chave.
.gitignore
*.env
.env
Podemos fechar essa aba e voltar para o gerador-casos-de-uso.py
.
Para gerar casos de uso, vamos utilizar um template pré-formatado. Antes de começar a implementação do método, podemos garantir que esse documento também esteja disponível dentro do diretório.
Vamos abrir novamente o explorador de arquivos, no qual vamos criar uma pasta nova chamada "documentos", e dentro dela vamos colar o documento explicacao_casos.txt
que tem um script explicando o que é um caso de uso e o formato que queremos que a IA gere, e que deverá seguir sempre o padrão.
explicacao_casos.txt
#Formato de Saída
*Nome da Persona*, em *contexto do app*, precisa realizar *tarefa no app* no aplicativo. Logo, *Beneficio Esperado*, para isso e a *descrição detalhada da tarefa realizada*.
Este é um modelo expresso neste formato de saída, o qual esperamos que a IA consiga gerar.
Para importar esse arquivo de texto dentro do projeto, vamos voltar ao explorador de arquivos e criar o script que estava faltando no gerador de casos de uso: o tools
. Vamos criar um novo arquivo na pasta raiz do projeto, que se chamará tools.py
, e dentro dele, vamos colar os dois métodos abaixo, que vão nos ajudar bastante ao longo do desenvolvimento desse projeto.
tools.py
def carrega(nome_do_arquivo):
try:
with open(nome_do_arquivo, "r") as arquivo:
dados = arquivo.read()
return dados
except IOError as e:
print(f"Erro no carregamento de arquivo: {e}")
def salva(nome_do_arquivo, conteudo):
try:
with open(nome_do_arquivo, "w", encoding="utf-8") as arquivo:
arquivo.write(conteudo)
except IOError as e:
print(f"Erro ao salvar arquivo: {e}")
O primeiro método, que começa na linha 1, é o carrega
. Ele recebe o nome de um arquivo ou um caminho de um arquivo como parâmetro. Ele tenta abrir esse arquivo na linha 2, executando a função de abertura de arquivo na linha 3 e guardando os resultados na variável arquivo
.
Uma vez que isso seja possível, ele realiza a leitura desse arquivo e guarda essas informações no formato de uma string na variável dados
e a retorna para quem invocou esse método.
Já o método salva
tem um comportamento muito parecido, mas vai escrever esse arquivo dentro de um diretório informado. O parâmetro informado inicialmente no método salva
, na linha 9, é o nome_do_arquivo
que vai ser salvo, para poder acessá-lo posteriormente. O segundo parâmetro é o conteúdo que vai ser salvo dentro desse arquivo.
Na linha 11, tentamos abrir esse arquivo escrevendo nele algum conteúdo, utilizando o encode UTF-8 para garantir que os caracteres especiais do português do Brasil possam ser implementados de forma adequada. Salvamos esse conteúdo na variável temporária arquivo
e a utilizamos para escrever dentro do caminho que especificamos o conteudo
informado na string de conteúdo.
Se tudo der certo, ele vai realizar esse processo sem nenhum tipo de problema.
Voltando ao script gerador_casos_uso.py
, vamos começar a implementar o método de gerar casos de uso. Para isso, vamos pressionar "Enter" na linha 9, e na linha 10 vamos criar o método def gerar_caso_uso()
.
gerador_casos_uso.py
def gerar_caso_uso():
No momento, ele não tem nenhum parâmetro, mas vai ser responsável pela comunicação com a OpenAI, enviando a requisição para gerar um caso de uso de forma adequada.
Para isso, vamos começar capturando as informações de dentro do arquivo que informa ao modelo da OpenAI como deve ser o formato de um caso de uso. Para isso, dentro do método recém-criado, vamos criar um documento_casos
e para ele, utilizaremos a função carrega()
que implementamos na função de tools
.
gerador_casos_uso.py
def gerar_caso_uso():
documento_casos = carrega()
Para garantir que o caminho de arquivo seja adequado, podemos acessar o explorador de arquivos e clicar com o botão direito do mouse no arquivo que queremos carregar dentro da aplicação, o explicacao_casos.txt
. Na lista suspensa, vamos selecionar "Copy Relative Path" para copiar o caminho relativo desse arquivo.
Podemos fechar o explorador de arquivos e colar essa informação entre os parênteses de carrega()
.
gerador_casos_uso.py
def gerar_caso_uso():
documento_casos = carrega(documentos\explicacao_casos.txt)
Veremos que ela não veio no formato de string, portanto precisamos colocá-la dentro de uma string, adicionando aspas duplas ao seu redor, para acessar esse documento de forma adequada.
gerador_casos_uso.py
def gerar_caso_uso():
documento_casos = carrega("documentos\explicacao_casos.txt")
Em seguida, ainda dentro de gerar_caso_uso()
, vamos colar o prompt seguinte abaixo da linha documento_casos
, mantendo uma linha vazia como separação.
prompt_sistema = f""""
Você é um especialista em desenvolver casos de uso. Você deve adotar o padrão abaixo
para gerar seu caso de uso:
*Nome da Persona*, em *contexto do app*, precisa realizar *tarefa no app* no aplicativo. Logo, *Beneficio Esperado*, para isso e a *descrição detalhada da tarefa realizada*.
Considere os dados de entrada sugeridos pelo usuário.
"""
O resultado pode ser visto abaixo.
gerador_casos_uso.py
def gerar_caso_uso():
documento_casos = carrega("documentos\explicacao_casos.txt")
prompt_sistema = f""""
Você é um especialista em desenvolver casos de uso. Você deve adotar o padrão abaixo
para gerar seu caso de uso:
*Nome da Persona*, em *contexto do app*, precisa realizar *tarefa no app* no aplicativo. Logo, *Beneficio Esperado*, para isso e a *descrição detalhada da tarefa realizada*.
Considere os dados de entrada sugeridos pelo usuário.
"""
Vamos minimizar o terminal, porque não vamos utilizá-lo por enquanto, e verificar o prompt. Ele tem algumas informações importantes para garantir que ele vai gerar um caso de uso de forma adequada.
Esse é um prompt do sistema que pede para o assistente da OpenAI assumir que é um especialista em desenvolver casos de uso e deve adotar o padrão que está abaixo, o mesmo que encaminhamos para ele dentro do processo de identificação do documento feito na linha documento_casos
.
Se não quisermos ler essa instrução como fizemos, podemos apagá-la e aproveitar o documento_casos
, já que importamos ele do arquivo. Vamos adicioná-lo entre chaves, no lugar da instrução.
gerador_casos_uso.py
def gerar_caso_uso():
documento_casos = carrega("documentos\explicacao_casos.txt")
prompt_sistema = f""""
Você é um especialista em desenvolver casos de uso. Você deve adotar o padrão abaixo
para gerar seu caso de uso:
{documento_casos}
Considere os dados de entrada sugeridos pelo usuário.
"""
Após esses passos, vamos criar o prompt de orientação com a solicitação da tarefa que deve ser desenvolvida e interpretada pela OpenAI, permitindo que ela gere o caso de uso.
Abaixo do prompt do sistema, vamos pressionar pular uma linha e criar o seguinte prompt de pessoa usuária.
prompt_usuario = """"
Gere um caso de uso para Ana que deseja realizar login na plataforma AcordeLab.
"""
Ao colá-lo, notaremos uma indentação que não foi intencional, portanto, vamos ajustá-la para alinhar o prompt com o método. Isso garante que na linha 22 tenhamos a solicitação do caso de uso que queremos gerar.
gerador_casos_uso.py
def gerar_caso_uso():
documento_casos = carrega("documentos\explicacao_casos.txt")
prompt_sistema = f""""
Você é um especialista em desenvolver casos de uso. Você deve adotar o padrão abaixo
para gerar seu caso de uso:
{documento_casos}
Considere os dados de entrada sugeridos pelo usuário.
"""
prompt_usuario = """"
Gere um caso de uso para Ana que deseja realizar login na plataforma AcordeLab.
"""
Com o novo script, vamos solicitar que o assistente gere um caso de uso para acessar a plataforma AcordeLab autenticando-se, ou seja, um caso de uso para quem deseja realizar login nessa plataforma.
Feito isso, vamos interagir com a OpenAI com o prompt abaixo, que já apareceu em outros cursos da formação e envolve a ideia de se comunicar com a OpenAI para gerar uma completion.
resposta = cliente.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": prompt_sistema},
{"role": "user", "content": prompt_usuario}
],
temperature=0.5
)
Nesse código, temos uma variável resposta
que aguarda uma resposta, usamos o cliente
já autenticado para gerar uma completion utilizando um modelo padrão através do ChatGPT ou da API da GPT.
Vamos utilizar inicialmente o modelo 3.5 da OpenAI porque vamos trabalhar com o seu refinamento. Apenas esse tipo de modelo tem seu acesso disponível para o público. Ou seja, mesmo que a resposta não venha da forma como esperamos, vamos aprender como melhorar essa resposta utilizando os recursos de refinamento.
Após o modelo, temos como segundo parâmetro dessa completion as mensagens. Temos a primeira mensagem com o papel de sistema (role
system
), onde utilizamos o prompt_sistema
, e a segunda mensagem com o papel de usuário (role
user
), que é a solicitação para geração de caso de uso.
O último atributo é o de temperatura (temperature
). Ele garante que não tenhamos nenhuma oscilação de criatividade que possa prejudicar a geração desse caso de uso por parte da OpenAI.
Por fim, abaixo dos parênteses da completion, vamos pular uma linha e retornar a resposta
do método, acessando as propriedades de choices
que envolvem as respostas que a OpenAI será capaz de gerar, e coletando a resposta na posição [0]
.
Dessa resposta, acessamos a mensagem e desta, o conteúdo.
return resposta.choices[0].message.content
O código completo pode ser consultado abaixo.
gerador_casos_uso.py
def gerar_caso_uso():
documento_casos = carrega("documentos\explicacao_casos.txt")
prompt_sistema = f""""
Você é um especialista em desenvolver casos de uso. Você deve adotar o padrão abaixo
para gerar seu caso de uso:
{documento_casos}
Considere os dados de entrada sugeridos pelo usuário.
"""
prompt_usuario = """"
Gere um caso de uso para Ana que deseja realizar login na plataforma AcordeLab.
"""
resposta = cliente.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": prompt_sistema},
{"role": "user", "content": prompt_usuario}
],
temperature=0.5
)
return resposta.choices[0].message.content
Dessa forma, temos um método capaz de gerar um caso de uso. A seguir, vamos testá-lo para verificar o que ele é capaz de gerar.
O curso OpenAI e Python: otimize o desenvolvimento de testes com IA possui 163 minutos de vídeos, em um total de 56 atividades. Gostou? Conheça nossos outros cursos de IA para Programação em Inteligência Artificial, ou leia nossos artigos de Inteligência Artificial.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.