Skip to main content

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.

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 de from 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 graus
  • desenhar_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 camadas
  • apagar_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 de mudar_cor_linha, mudar_padrao_linha e mudar_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 Jogador orientado que expõe mover, virar("esquerda"/"direita"), redondezas_livres() e esta_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.desenho import painel, painel_grafico       # os dois canvases
    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))
    # gráfico sincronizado (exige painel_grafico mostrado numa célula)
    anim.adicionar_grafico(
        eixo_y="posição [m]",
        curvas={"bola": lambda t: 2*t, "carro": lambda t: 0.5*t**2},
        cores={"bola": "roxo", "carro": "verde"},
    )
    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.pyTempo, Posicao, Velocidade, Aceleracao, Massa, Forca, Energia são subclasses de float com unidade e sobrecarga de operadores que respeita dimensões (Velocidade * Tempo → Posicao, Forca / Massa → Aceleracao, soma entre unidades diferentes levanta TypeError).
  • vetor.pyVetor 2D com norma, normalizar, produto_escalar, projetar, perpendicular, aplicar(f) e operadores + - * /.
  • forcas.pyForcaAtrito, ForcaElastica, ForcaGravitacao, ForcaEletromagnetica, ForcaArrasto (todas herdam de ForcaVetorial).
  • 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, guardar posicao como tupla (x, y) internamente; no construtor, se vier escalar, armazenar (posicao, 0).
  • Em Objeto.desenhar, usar posicao[0] e posicao[1] em vez de posicao e altura. Manter o parâmetro altura só como offset extra se fizer falta; idealmente, deletar.
  • Em Animacao.desenhar_quadro, aceitar o retorno da funcao_movimento nas duas formas (escalar ou tupla).
  • Renomear/estender desenhar_eixo_xdesenhar_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__, adicionar distancia_em_metros_y (ou renomear para distancia_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=False em Objeto.__init__ e em Animacao.adicionar_objeto.
  • Em Animacao.desenhar_rastro, iterar só sobre objetos com obj.rastro (em vez do flag global).
  • Remover deixar_rastro de Animacao.__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 com rotacionar_ponto (já existe). Corpo = desenhar_linha.
  • Criar class Seta em cinematica.py com origem(t), deslocamento(t), cor; expor desenhar(camada).
  • Animacao.adicionar_seta(nome, origem, deslocamento, cor) e guardar em self.objetos junto com os outros (polimorfismo simples — todos respondem a desenhar e 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, manter historico = deque de (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.

[x] 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. O criar_painel já 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_grafico para descobrir min/max do eixo y (em vez de ficar recalculando no loop).
  • Desenhar eixos + curvas no graficoFundo uma única vez.
  • No desenhar_quadro, redesenhar só o cursor vertical e os pontos (t, curva(t)) no graficoFrente.
  • 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

edupils-0.1.32.tar.gz (27.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

edupils-0.1.32-py3-none-any.whl (26.7 kB view details)

Uploaded Python 3

File details

Details for the file edupils-0.1.32.tar.gz.

File metadata

  • Download URL: edupils-0.1.32.tar.gz
  • Upload date:
  • Size: 27.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for edupils-0.1.32.tar.gz
Algorithm Hash digest
SHA256 5f90ad5e77c28333810f73d7295f6696f3d8bebeb53ae0bc59762a306db8ec23
MD5 124aee8c4008278d038d0e4f0b454233
BLAKE2b-256 e0a419c6988e064f44dabd65327ade818138f0bfe996af1816c85abe87987406

See more details on using hashes here.

File details

Details for the file edupils-0.1.32-py3-none-any.whl.

File metadata

  • Download URL: edupils-0.1.32-py3-none-any.whl
  • Upload date:
  • Size: 26.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for edupils-0.1.32-py3-none-any.whl
Algorithm Hash digest
SHA256 7c60bd6eedd3c28e2a4d8e3e9dcee5f808b132c4a7fd4961f57525238b852073
MD5 1667092f8b1c355def63efe6c9c70d40
BLAKE2b-256 6c07657f9a05d7dbc978eb9070fbf7ef52298336afa34777f03218379d2629c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page