F1, Python e Streamlit: Construindo um Analisador de Voltas (e os Perrengues no Caminho!)
E aí, galera do TabNews! 👋
Queria compartilhar um projetinho que venho desenvolvendo para juntar duas paixões: Fórmula 1 e programação com Python. A ideia inicial era simples: criar uma ferramenta para aprender a consumir APIs, manipular dados e brincar um pouco com visualização, tudo isso usando dados reais das corridas.
O resultado é um pequeno aplicativo web feito com Streamlit que busca dados da API pública e gratuita da OpenF1.org, calcula algumas estatísticas de desempenho dos pilotos e salva os dados localmente para não sobrecarregar a API.
Link para o Repositório no GitHub: Mandaloriano-Dev/Projeto-F1 (<- Coloque seu link aqui!)
Simulação:
Análise F1 - Exemplos.
O que a Aplicação Faz? 🏁
Basicamente, você seleciona:
Ano: De 2018 até o ano atual.
Evento (Pista): A lista é carregada dinamicamente da API com base no ano selecionado (usando o campo location).
Tipo de Sessão: Race, Qualifying, Sprint, FP1, FP2, FP3.
Piloto: A lista também é carregada da API, mostrando apenas os pilotos que participaram daquela sessão específica.
Ao clicar em "Analisar", o app busca os dados das voltas (se ainda não tiver localmente), calcula e exibe:
- Melhor Volta
- Média de Tempo de Volta
- Consistência (Desvio Padrão dos tempos)
- Velocidade Máxima registrada no Speed Trap (st_speed)
- Número de Pit Stops (Estimado contando as voltas de saída do pit - is_pit_out_lap)
- Um gráfico simples mostrando a evolução dos tempos de volta.
"Legalzices" e Particularidades do Projeto ✨
OpenF1 API: Uma fonte de dados incrível e gratuita! Tem muita informação, desde tempos de volta e setor até telemetria (que não usei ainda). Recomendo explorarem! openf1.org
Streamlit para UI: Para quem vem de análise de dados ou scripts e quer criar uma interface web interativa rápido, é sensacional. Comandos simples como st.selectbox, st.button, st.dataframe fazem a mágica acontecer.
Dropdowns Dinâmicos com Cache: Aprender a usar o @st.cache_data do Streamlit foi chave! Ele evita que a aplicação chame a API toda hora para buscar a lista de eventos do ano ou os pilotos da sessão enquanto o usuário interage com outros elementos. A busca só acontece uma vez por sessão do app (ou até o cache expirar).
"Banco de Dados" em CSV: Para não ficar batendo na API toda hora pelos dados das voltas (que são mais pesados e não mudam), implementei um sistema simples de cache persistente. Na primeira vez que você analisa Ano+Pista+Sessão+Piloto, ele busca na API e salva um CSV detalhado na pasta data/ (com nome padronizado). Nas próximas, ele lê direto do CSV.
Dica BR: Tive que usar sep=';' e decimal=',' no pandas.to_csv para o Excel brasileiro abrir o arquivo corretamente! 😉
Dados Extras: O CSV salva não só o tempo da volta, mas também tempos de setor, velocidades intermediárias (i1, i2), velocidade no speed trap (st_speed), se foi volta de saída do pit (is_pit_out_lap), data/hora e até os códigos dos segmentos de pista (indicando bandeiras, safety car, etc.) - tudo para análises futuras!
Desafios e Aprendizados (Os Perrengues!) 😅
Nem tudo são flores, né? Encontrei alguns desafios interessantes:
Realidade da API vs. Expectativa:
Dados Faltando: Eu achava que o endpoint /laps traria a posição do piloto e a duração do pit stop. Tive que consultar a documentação (e o JSON real) para ver que esses dados vêm de outros endpoints (/position, /pit). Lição: Sempre valide o que a API realmente retorna!
Solução Pit Stop: Para não deixar sem nada, usei o campo is_pit_out_lap (que está no /laps) para estimar o número de paradas. Não é perfeito, mas funciona na maioria dos casos.
Chave Correta: Perdi um tempo até descobrir que o código do piloto vinha como name_acronym e não acronym na resposta do /drivers. Mais uma vez, olhar o JSON!
Erros da API: A API retornou erro 500 ao pedir dados de 2025. Acontece, e o app precisa lidar com isso graciosamente (no caso, não mostrando opções para aquele ano).
Múltiplos Eventos: A busca por location às vezes retorna mais de um "meeting" (ex: GP e Teste). Tive que adicionar lógica para tentar priorizar o GP oficial.
Comportamentos do Streamlit:
Execução Inicial: No começo, o app tentava buscar dados da API assim que carregava, usando os valores padrão dos dropdowns. Resolvi isso adicionando a opção "-- Selecione --" e carregando as listas seguintes apenas condicionalmente.
Erro de Renderização (ArrowTypeError): O st.dataframe deu erro ao tentar exibir minha tabela de estatísticas que tinha tipos de dados misturados (strings e números inteiros). A solução foi converter explicitamente todos os valores da coluna "Valor" para string antes de exibir.
Próximos Passos e Ideias 💡
O projeto foi um ótimo aprendizado, mas sempre dá pra melhorar:
Calcular e exibir melhores tempos por setor.
Usar gráficos mais interativos (Plotly?).
Permitir comparar 2 pilotos lado a lado.
Integrar o endpoint /pit para ter dados reais de duração de pit stop.
Talvez migrar o armazenamento de CSV para SQLite para facilitar consultas mais complexas.
Confere lá o repositório, dêem uma olhada no código e, principalmente, me digam o que acharam!
Link: Mandaloriano-Dev/Projeto-F1
Sugestões, críticas, ideias para melhorar? Alguém mais já brincou com dados da F1 ou com a API da OpenF1? Vamos trocar uma ideia!
Valeu! 🚀