Ezequias Rocha / atlas
Foto de Ezequias Rocha

Ezequias Rocha

Campina Grande, Paraíba

Analista de sistemas e pesquisador no Laboratório de Sistemas de Informação (LSI/UFCG). Bacharel em Ciência da Computação pela UFCG, mestrando. Escreve PyTorch, FastAPI, Node e React, e boa parte disso mexe com coordenadas.

7°13′S 35°53′W16 check-ins, 2019 a 2026

Roteiro de check-ins

O relevo do mapa é gerado; os pontos e a ordem não. Cada ponto é um repositório público dele, ligado ao seguinte na ordem em que o trabalho aconteceu. A grade usa coordenadas em torno da UFCG só como referência de leitura.

    Folhas do atlas

    Nove folhas, da pesquisa à configuração do terminal. Cada uma descreve o que o código faz, lido no próprio repositório.

    Folha 1 de 9, pesquisa, 2024

    replication-ANES

    Replicação em PyTorch de um paper que infere amizades sem supervisão, usando apenas trajetórias de check-in em Nova York.

    O problema

    O artigo é Aspect-oriented unsupervised social link inference on user trajectory data, de Byun, Choi e Kim (Information Sciences, vol. 626, 2023). A pergunta: dadas só as sequências de check-ins de cada usuário no Foursquare de Nova York, quem é amigo de quem? Sem rótulos de amizade no treino.

    A ideia

    Cada check-in vira uma tripla aspecto-orientada, no estilo dos embeddings de grafo de conhecimento. Usuário, POI, tempo, categoria e geografia têm embeddings próprios de 128 dimensões, e projeções do tipo TransH, TransR e TransD levam esses vetores para hiperplanos ou espaços de relação. Dois usuários que frequentam os mesmos lugares, nos mesmos horários da semana, nas mesmas categorias, acabam próximos no espaço aprendido.

    O tempo

    A semana é discretizada em 168 slots, dia × hora, com correção de fuso a partir do offset em minutos que vem no dado. É isso que a grade logo abaixo desta folha demonstra.

    Perdas e amostragem

    • Margin loss entre triplas verdadeiras e corrompidas.
    • Orthogonal loss: mantém o vetor de relação ortogonal ao hiperplano da projeção.
    • Norm loss para segurar a norma dos embeddings.
    • Amostragem negativa com busca binária sobre a CDF da distribuição, O(log n) por amostra.

    O código

    Tamanho
    ~2.400 linhas de Python em 8 módulos
    Modelo
    model.py, 776 linhas
    Treino
    ANES.py
    Dados
    preprocessing.py, data.py
    Suporte
    loss.py, projection.py, graphutils.py, utils.py
    Variantes
    ANES, ANES_GEO, ANES_GEO_YELP, ANES_GEO_Others, LBGC_v4
    Recortes
    NYC_20, 40, 60, 80 e 100, com pares verdadeiros e falsos para treino, validação e teste
    Treino
    lr 1e-4, distância L1, 1000 iterações
    Inspeção
    t-SNE para visualizar o espaço de embeddings

    Slot semanal, a conta

    # dia: 0..6, hora: 0..23 (UTC), offset em minutos
    slot = (dia * 24 + hora + offset_min // 60) % 168

    Forma reduzida da discretização, usada na demonstração abaixo.

    Check-ins viram slots semanais

    Clique numa célula para escolher o horário UTC de um check-in, ou ajuste os campos. A célula azul é o slot local depois da correção de fuso. Os pontos mostram dois usuários fictícios, A e B; onde os dois aparecem no mesmo slot, a borda fica dourada.

    slot local horário UTC usuário A usuário B trajetórias se cruzam

    Folha 2 de 9, ferramentas, setembro de 2026

    turbo-whisper

    Contribuição open source num app de ditado por voz em PyQt6. O apóstrofo virava til em teclado ABNT, e ele descobriu por quê.

    O projeto

    Fork de knowall-ai/turbo-whisper, um ditado no estilo SuperWhisper: OpenAI Whisper, 99 idiomas, atalho global, waveform na tela. Você fala, o texto aparece onde o cursor estiver.

    O bug do teclado ABNT

    A digitação automática usava evdev, que injeta scancodes crus de um teclado US-QWERTY. O sistema traduz esses scancodes pelo layout ativo, então num ABNT a tecla que no layout americano é ' chega como ~. O texto transcrito estava certo; o caminho até a tela é que trocava os caracteres.

    A correção, no commit fix: prefer xdotool/wtype over evdev for auto-typing, inverte a prioridade: primeiro ferramentas que digitam texto, não teclas. Ele detecta Wayland por WAYLAND_DISPLAY ou XDG_SESSION_TYPE, tenta wtype, depois xdotool type --clearmodifiers --delay, e deixa evdev, PyAutoGUI e área de transferência como fallback.

    Os outros commits

    • feat: language selection, headless recording, clearer offline error, +143 linhas em api.py, config.py e main.py.
    • docs: self-hosted setup notes for Pop!_OS: servidor faster-whisper em Docker com CUDA (--gpus all, modelo Systran/faster-whisper-small, porta exposta só em 127.0.0.1, cache do HuggingFace montado como volume), com PipeWire e PortAudio no áudio.

    Ordem de tentativa

    def type_text(text):
        wayland = os.environ.get("WAYLAND_DISPLAY") \
            or os.environ.get("XDG_SESSION_TYPE") == "wayland"
    
        if wayland and shutil.which("wtype"):
            return run(["wtype", text])
    
        if shutil.which("xdotool"):
            return run(["xdotool", "type",
                        "--clearmodifiers", "--delay", DELAY, text])
    
        # evdev manda scancodes US-QWERTY crus:
        # em ABNT, ' sai como ~. Só como último recurso.
        for fallback in (type_evdev, type_pyautogui, paste_clipboard):
            if fallback(text):
                return

    Esquema da lógica descrita no commit, com nomes simplificados. Não é cópia literal do arquivo.

    Servidor local

    Motor
    faster-whisper em Docker
    GPU
    CUDA, --gpus all
    Modelo
    Systran/faster-whisper-small
    Rede
    porta presa a 127.0.0.1
    Sistema
    Pop!_OS, PipeWire, PortAudio

    Folha 3 de 9, backend, 2025

    fast_zero

    Uma API pequena em FastAPI em que o interessante é o entorno: lint estrito, testes com cobertura e tarefas encadeadas.

    A API

    CRUD REST de usuários com FastAPI e Pydantic v2. Os schemas separam o que entra do que sai: UserSchema recebe, UserPublic responde sem senha, UserDB representa o registro, UserList embrulha a listagem. E-mail validado com EmailStr, códigos de resposta por HTTPStatus e 404 tratado quando o usuário não existe.

    O entorno

    • Python 3.14 com Poetry.
    • Ruff com as regras I, F, E, W, PL (pylint) e PT (estilo pytest), em modo preview.
    • pytest e pytest-cov com relatório HTML; TestClient entregue por fixture.
    • taskipy: o lint roda antes do teste e a cobertura em HTML sai depois, sem ninguém lembrar.

    Como as tarefas se encadeiam

    [tool.ruff.lint]
    preview = true
    select = ["I", "F", "E", "W", "PL", "PT"]
    
    [tool.taskipy.tasks]
    pre_test  = "task lint"
    test      = "pytest --cov=fast_zero"
    post_test = "coverage html"

    Esquema da configuração. As regras e os ganchos pre_test e post_test são os do repositório; os comandos estão resumidos.

    Folha 4 de 9, full stack, 2023 a 2024

    clone-tabnews

    Next.js 13 falando com Postgres de verdade, subido por Docker Compose e verificado por teste de integração.

    O banco roda em container definido em infra/compose.yaml, e a aplicação conversa com ele pelo driver pg. O endpoint /api/v1/status existe para responder se o sistema está de pé, e um teste de integração com Jest bate nele contra o banco real, sem mock.

    A base de projeto é cuidada: Prettier, .editorconfig, .nvmrc fixando a versão do Node, deploy contínuo na Vercel.

    Front e API
    Next.js 13, API routes
    Banco
    PostgreSQL via Docker Compose
    Driver
    pg
    Saúde
    GET /api/v1/status
    Testes
    Jest, integração
    Padrão
    Prettier, .editorconfig, .nvmrc
    Deploy
    Vercel

    Folha 5 de 9, full stack, 2020

    Ecoleta

    Marketplace de pontos de coleta de resíduos, buscados por localização. TypeScript em API, web e mobile. 124 commits dele.

    API

    Node e Express com Knex para migrations e seeds sobre SQLite. Validação de entrada com Celebrate e Joi, upload de imagem do ponto com Multer, CORS liberado para os clientes.

    • Express
    • Knex
    • SQLite
    • Celebrate/Joi
    • Multer

    Web

    React com TypeScript. O cadastro do ponto usa mapa Leaflet via react-leaflet para marcar a posição, e a foto entra por arrastar e soltar com react-dropzone.

    • React
    • react-leaflet
    • react-dropzone
    • react-router

    Mobile

    React Native com Expo. Lê a posição com expo-location, mostra os pontos em react-native-maps e abre e-mail para o ponto com expo-mail-composer.

    • Expo
    • react-native-maps
    • expo-location
    • React Navigation

    Folha 6 de 9, full stack e backend, 2020

    DevRadar e be-the-hero

    Dois projetos das Semanas Omnistack: um consulta o Mongo por proximidade e avisa em tempo real, o outro tem a API coberta por teste.

    DevRadar, 123 commits dele

    API
    Express com MongoDB e Mongoose. Busca devs por raio usando consulta geoespacial no Mongo; dados de perfil vêm da API do GitHub via axios.
    Tempo real
    Socket.io notifica em tempo real os devs próximos.
    Web
    React.
    Mobile
    Expo com mapas, localização, WebView e socket.io-client.

    be-the-hero, 122 commits dele

    API
    Express, Knex, SQLite e Celebrate para validar entrada.
    Testes
    Jest e Supertest batendo nas rotas da API, com cross-env para as variáveis de ambiente do teste.
    Web
    React.
    Mobile
    React Native com Expo.

    Folha 7 de 9, ensino, 2020 a 2025

    Ensino de algoritmos

    Trilhas semanais de Aprendizado de Algoritmos com listas no vJudge e vídeos dele resolvendo as questões para os alunos.

    Trilha iniciante

    1. Ad hoc
    2. Two pointers
    3. Soma acumulada
    4. Busca binária
    5. Fila, heap, pilha, set, mapa
    6. GCD, LCM e crivo
    7. Aritmética modular
    8. Exponenciação binária

    Trilha avançada

    1. Segment Tree
    2. Lazy Propagation
    3. Square Root Decomposition e algoritmo de Mo

    O que cada estrutura avançada resolve

    Segment Tree responde consulta de intervalo (soma, mínimo) e atualiza um ponto em O(log n). Lazy Propagation adia a atualização de um intervalo inteiro até alguém descer naquele nó, mantendo O(log n) também para update em faixa. Mo reordena consultas offline por blocos de √n para mover as pontas do intervalo o mínimo possível, em O((n + q)√n).

    ATAL, UFCG

    Em Análise e Técnicas de Algoritmos, soluções de Codeforces organizadas por paradigma: força bruta, backtracking, guloso, divisão e conquista, programação dinâmica e grafos com BFS e DFS.

    Folha 8 de 9, ferramentas, 2022 a 2024

    Neovim e tmux

    O ambiente onde o resto foi escrito: Neovim configurado em Lua e uma config de tmux.

    Linguagem
    LSP para completar, navegar e diagnosticar
    Sintaxe
    Treesitter
    Busca
    Telescope
    Arquivos
    Harpoon para pular entre os poucos que importam
    Git
    Fugitive
    Histórico
    Undotree
    Erros
    Trouble
    Foco
    Zen Mode
    Código
    refactoring
    Segredos
    cloak, que esconde valores de .env na tela

    Folha 9 de 9, estudos e pesquisa, 2019 a 2025

    Estudos de longo prazo

    Repositórios que acompanham anos de aprendizado, do JavaScript do zero aos quizzes de IA na UFCG.

    Web-Estudos

    2019→2025, 844 commits, 479 dele

    JavaScript do zero ao avançado, com map, filter, reduce e o contraste entre imperativo e declarativo. AJAX por XHR, fetch, axios e jQuery. Express, Gulp, Webpack, Vue, React. SQL relacional com joins e agregação, e MongoDB com lookup.

    Python-Estudos

    105 commits dele

    Banco de dados com consultas parametrizadas, inclusive um exercício chamado "selecionar sem SQL injection". CRUD e paginação com limit e offset.

    ia-ufcg

    2022→2023

    Quizzes de Inteligência Artificial da UFCG em Jupyter.

    Menores e primeiros

    2020

    Java no início da UFCG: coisa (Controle Institucional da Situação Acadêmica), agenda-de-contatos, controle-de-alunos. audio-speed-controller, extensão que acelera áudios do WhatsApp Web. ibdmd, datasets para BI com lojas, gerentes e vendas. bin2dec, casa-criativa e doe, da MaratonaDev.

    Números

    Contados em 22 repositórios próprios clonados, sem forks. São cerca de 1.110 commits de autoria dele. O GitHub dele existe desde outubro de 2018, com 50 repositórios públicos e 138 seguidores.

    Perfil de commits por ano

    Desenhado como perfil topográfico: a altitude é o número de commits.

    Volume de código por linguagem

    Bytes nos repositórios próprios. Mede quanto foi escrito, não domínio.

      IA e dados

      Python, PyTorch, scikit-learn, Pandas, NumPy, Jupyter, embeddings de grafos (TransH, TransR, TransD), Whisper e faster-whisper

      Backend

      FastAPI, Pydantic, Node.js, Express, Next.js API routes, Knex, Mongoose, Socket.io

      Frontend e mobile

      TypeScript, React, React Native, Expo, Next.js, Leaflet, Vue

      Bancos

      PostgreSQL, SQLite, MongoDB, MySQL e SQL

      Qualidade e infra

      pytest, Jest, Supertest, Ruff, Prettier, Poetry, Docker, Docker Compose, CUDA, Vercel, Git

      Ambiente

      Linux (Pop!_OS), Neovim em Lua, tmux, Wayland e X11

      Contato

      Os quatro lugares onde ele responde. O código está todo no GitHub; a organização EssentIA, voltada a agentes de IA, tem repositórios privados.