1. 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

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 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> e r<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.
  • pu ou penup — caneta para cima (não desenha).
  • pd ou pendown — caneta para baixo (desenha).
  • cCOLOR — muda a cor da caneta para COLOR (ex.: cred, cblue, ou c#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:
  1. Transformar o token em minúsculas (para aceitar F100, f100, Pu, etc.) com tok = tok.lower().
  2. Checar tokens completos (como pu e pd) antes de tratar o primeiro caractere, porque pu começa com p e pode confundir se compararmos só a primeira letra.
  3. Para comandos do tipo fN, pegar cmd = tok[0] e arg = tok[1:]. Em seguida tentar converter arg para número (float(arg)); se falhar, reportar erro e pular o comando. Usar try/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 frente d unidades (desenha se a caneta estiver em baixo).
  • backward(d) move para trás d.
  • right(a) e left(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/except ao 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() (ou screen.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):
  1. Importar o módulo turtle.
  2. Criar o objeto t = turtle.Turtle() e screen = turtle.Screen().
  3. Opcional: configurar velocidade inicial t.speed(6).
  4. Fazer tokens = [tok.strip() for tok in programa.split(':') if tok.strip()].
  5. Para cada tok em tokens:
    • Fazer low = tok.lower().
    • Se low for 'pu' ou 'penup': t.penup() e continuar.
    • Se low for 'pd' ou 'pendown': t.pendown() e continuar.
    • Se low começar com 'c' e tiver algo depois: t.color(low[1:]).
    • Se low começar com 'f', 'b', 'r' ou 'l': tentar arg = float(low[1:]) e aplicar a ação correspondente.
    • Se low começar com 's': tentar ajustar velocidade com t.speed(int(arg)).
    • Caso contrário: avisar que o token é desconhecido.
  6. 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:
    1. f100 -> vai 100 para frente (desenha).
    2. r90 -> gira 90º à direita.
    3. Repetir 4 vezes — isso traça um quadrado de lado 100.
      Se você rodar executa com 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,Y para mover para coordenadas absolutas usando t.goto(X, Y) (parse arg como 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()

Exercícios relacionados