A collection of educational tools for Python
Project description
edupils
Biblioteca de utilitários educacionais em Python para ilustrar conteúdos de programação, matemática e física em notebooks Starboard rodando sobre Pyodide. A API é em português e foi pensada para estudantes do ensino médio.
- Autor: Georges Spyrides
- Licença: MIT
- PyPI:
edupils - Repositório: github.com/georgesms/edupils
Instalação
No ambiente Pyodide/Starboard:
import micropip
await micropip.install("edupils")
Ou em um ambiente Python tradicional (para os módulos que não dependem do browser):
pip install edupils
⚠️ Boa parte dos módulos desenha sobre o
<canvas>da página e depende defrom js import document. Esses módulos só funcionam dentro do Pyodide (Starboard, JupyterLite etc.). Módulos puros de Python (fisica.vetor,fisica.grandezas,desafios.bejeweled) rodam em qualquer lugar.
Estrutura dos pacotes
edupils/
├── constantes.py # cores, dimensões padrão e tradução PT-EN
├── desenho/ # primitivas de desenho sobre <canvas> HTML
├── desafios/ # atividades prontas: tartaruga, labirinto, cinemática…
├── fisica/ # vetores, grandezas com unidades, simulação
├── imagem/ # placeholder para manipulação de imagens
└── sons/ # placeholder para áudio
edupils.constantes
Dicionários de tradução ("vermelho" → "red", "tracejada" → "dashed"),
cores-tema (COR_PRIMARIA, COR_SECUNDARIA) e dimensões padrão do canvas.
Todos os outros módulos consomem essas constantes para que o aluno possa
escrever em português natural.
edupils.desenho
Camada de desenho 2D sobre o <canvas>. Cria três painéis empilhados
(painelFundo, painelAuxiliar, painelFrente) para separar cenário,
trajetórias e atores.
Funções principais (desenho.py):
desenhar_retangulo(x, y, largura, altura, canvas_id, cor_preenchimento)desenhar_circulo(x, y, raio, id_canvas, cor_preenchimento, cor_contorno, largura_contorno)desenhar_arco(...)— arco com ângulos em grausdesenhar_triangulo(x_baricentro, y_baricentro, raio_circunscrito, cor, id_canvas, angulo, proporcao_base)desenhar_linha(inicio_x, inicio_y, fim_x, fim_y, id_canvas, cor, largura, padrao)— aceita"solida","tracejada","pontilhada"escrever_texto(texto, x, y, id_canvas, cor, tamanho, fonte, alinhamento, direcao)
Gerência de painéis (painel.py):
criar_painel(largura, altura, …)— monta a<div>com as três camadasapagar_painel(id_painel)clarear_com_marca_dagua(id_painel, alpha)— usado para criar rastros
edupils.desafios
Atividades completas prontas para usar em sala.
-
tartaruga.py — uma turtle graphics simplificada. A tartaruga é desenhada como triângulo; há
andar,virar,abaixar_caneta/levantar_caneta,voltar_para_casa, além demudar_cor_linha,mudar_padrao_linhaemudar_cor_tartaruga.from edupils.desafios.tartaruga import Tartaruga t = Tartaruga(cor_linha="roxo", padrao_linha="tracejada") t.abaixar_caneta() for _ in range(4): t.andar(80) t.virar(90)
-
labirinto.py — gerador procedural de labirintos (Prim randomizado) com entrada, saída bandeirada e um
Jogadororientado que expõemover,virar("esquerda"/"direita"),redondezas_livres()eesta_livre(direcao). Ao chegar na saída, imprime “Parabéns!!”.from edupils.desafios.labirinto import criar_labirinto_e_jogador lab, p = criar_labirinto_e_jogador() while not p.esta_livre("frente") and p.esta_livre("direita"): p.virar("direita") p.mover(3)
-
cinematica.py — animação 1D/2D do movimento de objetos, com eixos graduados, timestamp e rastro opcional por objeto. O aluno fornece uma
funcao_movimento(t)— escalar para 1D, tupla(x, y)para 2D.from edupils.desafios.cinematica import Animacao anim = Animacao(tempo=8, frames_por_segundo=20) # 1D anim.adicionar_objeto("bola", 0, lambda t: 2*t, cor="roxo", rastro=True) anim.adicionar_objeto("carro", 0, lambda t: 0.5*t**2, forma="triangulo", cor="verde") # 2D (lançamento oblíquo com vetor velocidade acompanhando) anim.adicionar_objeto("projetil", (0, 0), lambda t: (10*t, 20*t - 0.5*9.8*t**2), cor="azul", rastro=True) anim.adicionar_seta("v", origem=lambda t: (10*t, 20*t - 0.5*9.8*t**2), deslocamento=lambda t: (10, 20 - 9.8*t)) await anim.animar()
-
bejeweled.py — gera uma tabela aleatória de emojis (corações, quadrados, círculos em 4 cores) para exercícios de busca/combinação em grades. Puro Python + NumPy.
-
p5.py — cola mínima para usar a p5.js a partir do Python no navegador.
edupils.fisica
Mini-engine física com ênfase em tipagem por grandeza.
- grandezas.py —
Tempo,Posicao,Velocidade,Aceleracao,Massa,Forca,Energiasão subclasses defloatcom unidade e sobrecarga de operadores que respeita dimensões (Velocidade * Tempo → Posicao,Forca / Massa → Aceleracao, soma entre unidades diferentes levantaTypeError). - vetor.py —
Vetor2D comnorma,normalizar,produto_escalar,projetar,perpendicular,aplicar(f)e operadores+ - * /. - forcas.py —
ForcaAtrito,ForcaElastica,ForcaGravitacao,ForcaEletromagnetica,ForcaArrasto(todas herdam deForcaVetorial). - motor.py — loop de simulação com objetos
(
Objeto,Circulo), integração de forças, detecção/resolução de colisões rígidas contra paredes e varredura de colisões entre objetos.
edupils.imagem e edupils.sons
Esqueleto para manipulação de imagens e áudio — ainda não implementados.
TO-DO — extensões da cinematica
Ordem sugerida
| Fase | Tarefa | Esforço | Destrava |
|---|---|---|---|
| 1 | 1. Posição em 2D ✅ | M | NB 08, 09, 10, 11, 13 |
| 2 | 2a. Rastro por objeto (flag booleana) ✅ | P | NB 09, 10, 13 |
| 2 | 3. Setas / vetores ✅ | M | NB 04, 08, 09, 11 |
| 3 | 2b. Rastro com janela (rastro_tempo) |
M | caso circular na NB 13 |
| 3 | 4. Gráfico sincronizado | G | NB 03, 04, 05, 06 |
Fruta mais baixa: 2a. Trocar o deixar_rastro global por flag no objeto
é um mini-refactor do desenhar_rastro — meia tarde de trabalho.
Mas comece pela 1. O 2D é pré-requisito dos outros três: rastro em 1D é só uma linha sobre o eixo (pouco interessante), seta sem 2D só tem um grau de liberdade, e o gráfico contra posição só faz sentido quando há mais de uma coordenada. Fazer o 2D primeiro também barateia o 2a: aí o rastro já nasce útil.
[x] 1. Posição em 2D — NB 08, 09, 10, 11, 13
Alvo: funcao_movimento(t) pode devolver escalar (como hoje) ou tupla
(x, y). Se devolver escalar, assume $y = 0$ — retrocompatível com
NB 01–07.
anim.adicionar_objeto("bolinha", 0, lambda t: t, cor="azul") # 1D
anim.adicionar_objeto("projetil", (0, 0),
lambda t: (10*t, 20*t - 0.5*9.8*t**2), cor="azul") # 2D
Passos (edupils/desafios/cinematica.py):
- Em
Objeto, guardarposicaocomo tupla(x, y)internamente; no construtor, se vier escalar, armazenar(posicao, 0). - Em
Objeto.desenhar, usarposicao[0]eposicao[1]em vez deposicaoealtura. Manter o parâmetroalturasó como offset extra se fizer falta; idealmente, deletar. - Em
Animacao.desenhar_quadro, aceitar o retorno dafuncao_movimentonas duas formas (escalar ou tupla). - Renomear/estender
desenhar_eixo_x→desenhar_eixos, que desenha os dois eixos cartesianos. Manter o comportamento antigo quando nenhum objeto tem $y \ne 0$ (decisão preguiçosa: sempre desenhar os dois — simples e coerente). - Em
Animacao.__init__, adicionardistancia_em_metros_y(ou renomear paradistancia_em_metros=(dx, dy)). - Sanidade: rodar a NB 07 atual sem mexer no código dela.
[x] 2a. Rastro por objeto (flag booleana) — NB 09, 10, 13
Mover a flag deixar_rastro de Animacao para Objeto.
anim.adicionar_objeto("projetil", (0, 0), posicao_xy, cor="azul", rastro=True)
Passos:
- Adicionar parâmetro
rastro=FalseemObjeto.__init__e emAnimacao.adicionar_objeto. - Em
Animacao.desenhar_rastro, iterar só sobre objetos comobj.rastro(em vez do flag global). - Remover
deixar_rastrodeAnimacao.__init__(quebra de API — a NB mais antiga que usa isso precisa de um bump).
[x] 3. Setas / vetores — NB 04, 08, 09, 11
Novo tipo de objeto com origem e deslocamento — ambos funções de $t$ que devolvem tupla.
anim.adicionar_seta(
"v_bolinha",
origem=lambda t: (posicao_x(t), 0),
deslocamento=lambda t: (velocidade(t), 0),
cor="vermelho",
)
Uma única primitiva cobre:
- vetor velocidade/aceleração sobre um objeto (NB 04, 08, 09);
- decomposição em componentes (duas setas ortogonais — NB 08, 09);
- ponteiro de relógio — origem em $(0,0)$, deslocamento $R(\cos\omega t, \sin\omega t)$ (NB 11). Ponteiro é uma seta girando — não precisa de recurso rotacional separado;
- representação de forças (Módulo 2).
Passos:
- Adicionar primitiva
desenhar_seta(x0, y0, dx, dy, id_canvas, cor, largura)em edupils/desenho/desenho.py. Ponta = triângulo pequeno rotacionado comrotacionar_ponto(já existe). Corpo =desenhar_linha. - Criar
class Setaemcinematica.pycomorigem(t),deslocamento(t),cor; expordesenhar(camada). -
Animacao.adicionar_seta(nome, origem, deslocamento, cor)e guardar emself.objetosjunto com os outros (polimorfismo simples — todos respondem adesenhare têm função de $t$). - Tamanho da ponta calibrado em pixels, não em metros (senão some quando o deslocamento é pequeno).
[ ] 2b. Rastro com janela — caso circular (NB 13)
Só necessário quando o rastro se sobrepõe e polui o desenho. Complica porque precisa guardar histórico.
anim.adicionar_objeto("satelite", (R, 0), orbita,
cor="roxo", rastro=True, rastro_tempo=2.0)
Passos:
- Em
Objeto, manterhistorico = dequede(t, x, y). - A cada frame, empilhar a posição; descartar entradas mais antigas
que
rastro_tempo. - Redesenhar o rastro ligando os pontos do histórico com linhas finas (e não mais com snapshot + marca d’água). A marca d’água continua disponível para o modo "rastro infinito" do 2a.
[ ] 4. Gráfico sincronizado — NB 03, 04, 05, 06
Painel novo que compartilha o relógio da animação. Recebe funções de $t$, desenha as curvas, e um cursor vertical desliza conforme a animação avança.
anim.adicionar_grafico(
eixo_y="posição [m]",
curvas={"bolinha": lambda t: posicao(t),
"carro": lambda t: 5 + 2*t},
)
Passos (mais invasivo — painel separado):
- Decidir layout:
<canvas>adicional à direita do atual, ou<div>irmão. Ocriar_paineljá devolve a<div>— extender para comportar uma segunda área de desenho com três camadas próprias (graficoFundo,graficoFrente). - Pré-amostrar as curvas em
adicionar_graficopara descobrir min/max do eixo y (em vez de ficar recalculando no loop). - Desenhar eixos + curvas no
graficoFundouma única vez. - No
desenhar_quadro, redesenhar só o cursor vertical e os pontos(t, curva(t))nograficoFrente. - NB 05 ("soma de pedacinhos"): o aluno constrói as barrinhas com
as primitivas existentes. Se virar padrão, criar depois um
adicionar_barras(t_pontos, alturas, cor)— não priorizar agora.
Publicação
Ver HOWTOBUILD.md. Resumindo: basta incrementar a versão em
setup.py e fazer push para main; o workflow
.github/workflows/workflow.yml constrói a
wheel e publica no PyPI via twine.
Licença
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file edupils-0.1.31.tar.gz.
File metadata
- Download URL: edupils-0.1.31.tar.gz
- Upload date:
- Size: 26.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1af54cf6f3eb42365df4fa43d13888da1b9df8c99c7c8055f56c753d21caa71
|
|
| MD5 |
066d9bf7e05996a89c3258b3097006cb
|
|
| BLAKE2b-256 |
5cbc18b47c82591ade4052e4957b2070d0f9e0c95484abb9693c7b0912c08b42
|
File details
Details for the file edupils-0.1.31-py3-none-any.whl.
File metadata
- Download URL: edupils-0.1.31-py3-none-any.whl
- Upload date:
- Size: 25.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efc3c7e9140e8fd60ddefe175642bf2c56586634ce1b63aff3fcfa3efeac803f
|
|
| MD5 |
97bb57ec178863331b58afa05201cda7
|
|
| BLAKE2b-256 |
6c4658498b32319168c93817dcab5ab91f59eaf75108c09a660638daf7191042
|