sexta-feira, 13 de outubro de 2017

Teste # 1 - TP1

P1

Quando fazemos :
1.>>> 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.

1.def par_impar(n):
2.    conta_par = 0 # o acumulador
3.    for i in range(n):
4.        num = lanca_dado()
5.        # actualiza o acumulador
6.    # define resultado
A implementação da simulação do lançamento do dado é trivial:
1.import random
2. 
3.def lanca_dado():
4.    return random.randint(1,6)
Com estes elementos chegamos facilmente à versão final:
01.import random
02. 
03.def lanca_dado():
04.    return random.randint(1,6)
05. 
06.def par_impar(n):
07.    conta_par = 0
08.    for i in range(n):
09.        num = lanca_dado()
10.        if (num == 2) or (num == 4) or (num == 6): # if num in (2,4,6):
11.            conta_par = conta_par + 1
12.    if conta_par > n/2:
13.        return True
14.    else:
15.        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.
01.def tri_cor(posx,posy,orientacao,lado,cor):
02.    turtle.penup()
03.    turtle.goto(posx,posy)
04.    turtle.pendown()
05.    turtle.setheading(orientacao)
06.    turtle.fillcolor(cor)
07.    turtle.begin_fill()
08.    for i in range(3):
09.        turtle.forward(lado)
10.        turtle.left(120)
11.    turtle.end_fill()
12.    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.

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

1.def seg(posx,posy,comp,orientacao,cor):
2.    turtle.penup()
3.    turtle.goto(posx,posy)
4.    turtle.pendown()
5.    turtle.setheading(orientacao)
6.    turtle.pencolor(cor)
7.    turtle.forward(comp)
8.    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:

01.def boneco(n, posx, posy, orientacao,inc,comp,lado,cor):
02.    turtle.penup()
03.    turtle.goto(posx,posy)
04.    turtle.pendown()
05.    for i in range(n):
06.        if i % 2 == 0:
07.            seg(turtle.xcor(),turtle.ycor(),comp,orientacao + inc,cor)
08.            laco(turtle.xcor(),turtle.ycor(),turtle.heading()-90,lado,cor)
09.        else:
10.            seg(turtle.xcor(),turtle.ycor(),comp,orientacao - inc,cor)
11.            laco(turtle.xcor(),turtle.ycor(),turtle.heading()+90,lado,cor)       
12.    if n % 2 == 0:
13.        seg(turtle.xcor(),turtle.ycor(),comp,orientacao + inc,cor)
14.    else:
15.        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:
01.def boneco(n, posx, posy, orientacao,inc,comp,lado,cor):
02.    turtle.penup()
03.    turtle.goto(posx,posy)
04.    turtle.pendown()
05.    turtle.pencolor(cor)
06.    for i in range(n):
07.        if i % 2 == 0:
08.            turtle.setheading(orientacao + inc)
09.            turtle.forward(comp)
10.            laco(turtle.xcor(),turtle.ycor(),turtle.heading()-90,lado,cor)
11.        else:
12.            turtle.setheading(orientacao - inc)
13.            turtle.forward(comp)
14.            laco(turtle.xcor(),turtle.ycor(),turtle.heading()+90,lado,cor)
15.    if n % 2 == 0:
16.        turtle.setheading(orientacao + inc)
17.        turtle.forward(comp)
18.    else:
19.        turtle.setheading(orientacao - inc)
20.        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:
01.def cauda(n,posx,posy,comp,orienta_1,orienta_2,cor):
02.    # posiciona
03.    turtle.penup()
04.    turtle.goto(posx,posy)
05.    turtle.pendown()
06.    turtle.pencolor(cor)
07.    for i in range(n):
08.        if i % 2 == 0 :
09.            seg(turtle.xcor(),turtle.ycor(),comp, orienta_1,cor)
10.        else:
11.            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