sexta-feira, 13 de outubro de 2017

Teste # 1 - TP1

P1

Quando fazemos :
>>> X = X + 1 
acontece o seguinte. Primeiro o sistema tenta calcular o objecto associado à expressão X + 1. Para tal procura no espaço dos objectos o valor do objecto associado ao nome X. De seguida, incrementa esse valor de uma unidade e associa o novo objecto ao nome X.

P2

Era-nos pedido uma solução para o problema de saber se após o lançamento de um dado n vezes, o número de vezes que saiu um número par é maior do que o valor médio esperado. Podemos resolver este problema pro aproximações, baseando-nos num padrão de programação nosso conhecido: ciclo - acumulador.

def par_impar(n):
    conta_par = 0 # o acumulador
    for i in range(n):
        num = lanca_dado()
        # actualiza o acumulador
    # define resultado
A implementação da simulação do lançamento do dado é trivial:
import random 

def lanca_dado():
    return random.randint(1,6)
Com estes elementos chegamos facilmente à versão final:
import random

def lanca_dado():
    return random.randint(1,6)

def par_impar(n):
    conta_par = 0
    for i in range(n):
        num = lanca_dado()
        if (num == 2) or (num == 4) or (num == 6): # if num in (2,4,6):
            conta_par = conta_par + 1
    if conta_par > n/2:
        return True
    else:
        return False
Notar que o teste de saída de número par pode ser abreviado para if num in (2,4,6):

P3

Queremos um programa que nos permita desenhar figuras como a abaixo.

Pedem para poder parametrizar muita coisa: posição, orientação, número de laços e de segmentos tos, cor, tamanho do lado dos laços, tamanho dos segmentos, etc.

A solução passa por dividir o problema em sub-problemas e não tentar resolver tudo de uma vez. Olhando para a figura vemos laços e uma cauda. Os laços podem ser construídos como dois triângulos ligados por um vértice, enquanto a cauda é uma sequência de segmentos. Vamos resolver cada um dos sub-problemas.

Comecemos pelos triângulos coloridos, algo que fizemos nas aulas.
def tri_cor(posx,posy,orientacao,lado,cor):
    turtle.penup()
    turtle.goto(posx,posy)
    turtle.pendown()
    turtle.setheading(orientacao)
    turtle.fillcolor(cor)
    turtle.begin_fill()
    for i in range(3):
        turtle.forward(lado)
        turtle.left(120)
    turtle.end_fill()
    turtle.hideturtle()
Como se pode ver, iniciamos o programa definindo os parâmetros e depois desenhos o triângulo. O laço resulta de desenharmos dois triângulos percebendo que a orientação de ambos está desfasada de 180 graus.

def laco(posx,posy,orientacao,lado,cor):
    tri_cor(posx,posy,orientacao,lado,cor)
    tri_cor(posx,posy,orientacao + 180,lado,cor)
    turtle.hideturtle()
Passemos à cauda como sequência de segmentos. Desenhar um segmento com uma dada inclinação é trivial.

def seg(posx,posy,comp,orientacao,cor):
    turtle.penup()
    turtle.goto(posx,posy)
    turtle.pendown()
    turtle.setheading(orientacao)
    turtle.pencolor(cor)
    turtle.forward(comp)
    turtle.hideturtle()
Podemos agora juntar as peças do nosso puzzle. Se pensarmos um pouco, a estratégia mais interessante para o nosso programa final consiste em desenhar um segmento e de seguida desenhar um laço, repetindo estas acções o número apropriado de vezes. Daí a solução:

def boneco(n, posx, posy, orientacao,inc,comp,lado,cor):
    turtle.penup()
    turtle.goto(posx,posy)
    turtle.pendown()
    for i in range(n):
        if i % 2 == 0:
            seg(turtle.xcor(),turtle.ycor(),comp,orientacao + inc,cor)
            laco(turtle.xcor(),turtle.ycor(),turtle.heading()-90,lado,cor)
        else:
            seg(turtle.xcor(),turtle.ycor(),comp,orientacao - inc,cor)
            laco(turtle.xcor(),turtle.ycor(),turtle.heading()+90,lado,cor)        
    if n % 2 == 0:
        seg(turtle.xcor(),turtle.ycor(),comp,orientacao + inc,cor)
    else:
        seg(turtle.xcor(),turtle.ycor(),comp,orientacao - inc,cor)
E pronto! O leitor atento notará que o if final se deve à necessidade de desenhar o último segmento da cauda. Por outro lado, note como controlamos a orientação da cauda, e como relacionamos a orientação dos segmentos e dos laços. Finalmente, a cor dos laços e dos segmentos é a mesma, mas é trivial fazer com que tenham cor diferente!

Depois de feito o programa, torna-se evidente que podemos simplificar o desenho dos segmentos:
def boneco(n, posx, posy, orientacao,inc,comp,lado,cor):
    turtle.penup()
    turtle.goto(posx,posy)
    turtle.pendown()
    turtle.pencolor(cor)
    for i in range(n):
        if i % 2 == 0:
            turtle.setheading(orientacao + inc)
            turtle.forward(comp)
            laco(turtle.xcor(),turtle.ycor(),turtle.heading()-90,lado,cor)
        else:
            turtle.setheading(orientacao - inc)
            turtle.forward(comp)
            laco(turtle.xcor(),turtle.ycor(),turtle.heading()+90,lado,cor)
    if n % 2 == 0:
        turtle.setheading(orientacao + inc)
        turtle.forward(comp)
    else:
        turtle.setheading(orientacao - inc)
        turtle.forward(comp) 
E chega… ou talvez não!

Para terminar, e embora não fosse necessário, um pequeno programa para desenhar apenas uma cauda ondulante:
def cauda(n,posx,posy,comp,orienta_1,orienta_2,cor):
    # posiciona
    turtle.penup()
    turtle.goto(posx,posy)
    turtle.pendown()
    turtle.pencolor(cor) 
    for i in range(n):
        if i % 2 == 0 :
            seg(turtle.xcor(),turtle.ycor(),comp, orienta_1,cor)
        else:
            seg(turtle.xcor(),turtle.ycor(),comp, orienta_2,cor)
Note-se como controlamos a orientação dos segmentos.

Sem comentários:

Enviar um comentário