- Crie sua própria linguagem para plotar no turtle através da manipulação de strings. Seu código deverá ter uma rotina executa, que dado um programa como argumento, executa os comandos contidos nesse programa. Exemplo:
programa = 'f100:r90:f100:r90:f100:r90:f100:r90'
executa(programa) # chamada da rotina executa
programa = 'f100:r90:f100:r90:f100:r90:f100:r90'
executa(programa) # chamada da rotina executa
Passo 1
O enunciado pede que eu crie “minha própria linguagem” para controlar a tartaruga (turtle) através de strings, e que essa implementação tenha uma rotina chamada
Informações relevantes fornecidas:
executa que receba um programa (string) e faça a tartaruga executar os comandos. O enunciado me deu um exemplo de programa: programa = 'f100:r90:f100:r90:f100:r90:f100:r90' e a chamada executa(programa).Informações relevantes fornecidas:
- O programa é uma string com comandos separados por
:(no exemplo). - O exemplo usa comandos do tipo
f<number>er<number>(provavelmente “forward” e “right”), repetidos para desenhar algo (um quadrado).
O que é pedido: - Implementar a rotina
executa(programa)que interpreta a string de comandos e usa turtle para desenhar conforme os comandos.
Passo 2
Como vamos interpretar a string? Primeiro conceito básico de manipulação de strings: divisão em tokens. Para pegar cada comando separado por
: usamos a operação de “split” (em Python programa.split(':')). Isso gera uma lista de pedaços que precisamos percorrer na ordem. Também é importante remover espaços extras de cada token com strip() e ignorar tokens vazios (caso a string tenha :: ou espaços no começo/fim). Exemplo prático (pseudo):'f100:r90' -> ['f100', 'r90']- aplicar
strip()e ignorar''.
Passo 3
Quais comandos vamos aceitar? Vou definir uma linguagem simples e suficiente para a prova (é fácil de memorizar e implementar):
fN— andar para frente N unidades.bN— andar para trás N unidades.rA— girar à direita A graus.lA— girar à esquerda A graus.puoupenup— caneta para cima (não desenha).pdoupendown— caneta para baixo (desenha).cCOLOR— muda a cor da caneta para COLOR (ex.:cred,cblue, ouc#ff0000).sV— ajusta velocidade para V (inteiro ou float aceito pelo turtle).
Esses comandos cobrem o exemplo e deixam a linguagem utilizável e fácil de estender. Na prova, expliquei o que cada comando faz em palavras simples — isso já vale.
Passo 4
Como extrair o número ou a cor do token? Método:
- Transformar o token em minúsculas (para aceitar
F100,f100,Pu, etc.) comtok = tok.lower(). - Checar tokens completos (como
puepd) antes de tratar o primeiro caractere, porquepucomeça compe pode confundir se compararmos só a primeira letra. - Para comandos do tipo
fN, pegarcmd = tok[0]earg = tok[1:]. Em seguida tentar converterargpara número (float(arg)); se falhar, reportar erro e pular o comando. Usartry/excepté boa prática para não quebrar todo o programa por um token ruim.
Exemplo prático: token'f100'->cmd = 'f',arg = '100',dist = float('100')->100.0.
Passo 5
Mapeamento das ações para funções do turtle (conceito de mapeamento):
fN->t.forward(N)bN->t.backward(N)rA->t.right(A)lA->t.left(A)pu->t.penup()pd->t.pendown()cCOLOR->t.color(COLOR)(o turtle aceita nomes de cores ou hex)sV->t.speed(V)
Vou explicar o que cada função do turtle faz, porque a prova pode pedir:
forward(d)move a tartaruga para frentedunidades (desenha se a caneta estiver em baixo).backward(d)move para trásd.right(a)eleft(a)giram a tartaruga em graus (sentido horário ou anti-horário).penup()faz a tartaruga se mover sem desenhar;pendown()volta a desenhar.color(x)altera a cor da caneta e do traço subsequente.speed(v)controla a velocidade de desenho (valores típicos 0-10).
Passo 6
Robustez e validação (dicas para a prova):
- Ignorar tokens vazios e espaços.
- Usar
try/exceptao converter números para evitar crash. - Imprimir mensagens de aviso quando um token for inválido para facilitar depuração (em prova, isso mostra cuidado com tratamento de erros).
- Evitar usar funções bloqueantes no meio do loop; normalmente criamos a turtle, executamos todos os comandos e no final chamamos
turtle.done()(ouscreen.mainloop()), que mantém a janela aberta.
Passo 7
Agora uma explicação passo a passo do algoritmo que o código
executa seguirá (pseudo passo a passo):- Importar o módulo
turtle. - Criar o objeto
t = turtle.Turtle()escreen = turtle.Screen(). - Opcional: configurar velocidade inicial
t.speed(6). - Fazer
tokens = [tok.strip() for tok in programa.split(':') if tok.strip()]. - Para cada
tokemtokens:- Fazer
low = tok.lower(). - Se
lowfor'pu'ou'penup':t.penup()e continuar. - Se
lowfor'pd'ou'pendown':t.pendown()e continuar. - Se
lowcomeçar com'c'e tiver algo depois:t.color(low[1:]). - Se
lowcomeçar com'f','b','r'ou'l': tentararg = float(low[1:])e aplicar a ação correspondente. - Se
lowcomeçar com's': tentar ajustar velocidade comt.speed(int(arg)). - Caso contrário: avisar que o token é desconhecido.
- Fazer
- Depois do loop, chamar
turtle.done()para manter a janela aberta até o usuário fechar.
Passo 8
Exemplo prático e interpretação interna usando o exemplo do enunciado:
- Programa:
'f100:r90:f100:r90:f100:r90:f100:r90' - Tokens:
['f100', 'r90', 'f100', 'r90', 'f100', 'r90', 'f100', 'r90'] - Execução passo a passo:
f100-> vai 100 para frente (desenha).r90-> gira 90º à direita.- Repetir 4 vezes — isso traça um quadrado de lado 100.
Se você rodarexecutacom esse programa verá um quadrado desenhado — ótimo para testar.
Passo 9
Dicas rápidas para a prova (truques que valem pontos):
- Escreva um comentário curto explicando a linguagem (ex.: “fN forward, rA right, pu penup…”) — ajuda corretor.
- Mostre tratamento de erros com
try/except. - Faça o código curto e legível; em situação de prova prefira clareza à otimização.
- Se quiser estender, adicione
mX,Ypara mover para coordenadas absolutas usandot.goto(X, Y)(parseargcomo duas coordenadas separadas por vírgula).
Passo 10
Segue o código final da rotina
executa(programa). Ele implementa tudo que expliquei: parsing por :, comandos f,b,r,l,pu,pd,c,s, validação e mensagens de erro amigáveis. Você só precisa colar isso num arquivo .py e executar — a janela do turtle vai aparecer mostrando o desenho.Resposta
def executa(programa):
"""
Interpreta e executa um programa string para turtle.
Linguagem suportada:
- fN : forward N unidades
- bN : backward N unidades
- rA : right A graus
- lA : left A graus
- pu : penup
- pd : pendown
- penup : penup (alias)
- pendown: pendown (alias)
- cCOLOR: set color (ex: cred, c#ff0000, cblue)
- sV : set speed para V (inteiro ou float)
Comandos separados por ':' (ex: 'f100:r90:f100:r90')
"""
import turtle
t = turtle.Turtle()
screen = turtle.Screen()
t.speed(6) # velocidade inicial razoável
# separar tokens por ':' e limpar espaços vazios
tokens = [tok.strip() for tok in programa.split(':') if tok.strip()]
for tok in tokens:
low = tok.lower()
# comandos que são palavras inteiras primeiro
if low in ('pu', 'penup'):
t.penup()
continue
if low in ('pd', 'pendown'):
t.pendown()
continue
# comando de cor: começa com 'c' seguido do nome/hex da cor
if low.startswith('c') and len(low) > 1:
color = tok[1:] # manter case original para hex como #FF0000 se quiser
try:
t.color(color)
except Exception:
print(f"Aviso: cor inválida '{color}' em token '{tok}' — ignorando.")
continue
# outros comandos: primeira letra define, resto é argumento
cmd = low[0]
arg = tok[1:] # manter parte original pode ser útil para cores; aqui é número
if cmd in ('f', 'b', 'r', 'l', 's'):
if arg == '':
print(f"Aviso: faltou argumento numérico em '{tok}' — ignorando.")
continue
try:
val = float(arg)
except Exception:
print(f"Aviso: argumento inválido '{arg}' em token '{tok}' — ignorando.")
continue
if cmd == 'f':
t.forward(val)
elif cmd == 'b':
t.backward(val)
elif cmd == 'r':
t.right(val)
elif cmd == 'l':
t.left(val)
elif cmd == 's':
# turtle.speed aceita 0-10 ou outros; cast para int se preferir
try:
t.speed(int(val))
except Exception:
t.speed(val)
continue
# se chegou aqui, comando desconhecido
print(f"Aviso: comando desconhecido '{tok}' — ignorando.")
# manter a janela aberta até o usuário fechar
turtle.done()