sexta-feira, 18 de outubro de 2013

Teste 1 - TP3

Pergunta 1 Uma cadeia de caracteres é uma sequência (tem ordem), homogénea (cada elemento é um caracter) e imutável (não é possível alterar o seu valor). Pergunta 2 Estamos perante mais um caso de olhar e ver. E o que vemos? Uma flor formada por pétalas. E o que são as pétalas: rectângulos coloridos. Precisamos então um programa para desenhar rectângulos. Depende do valor de cada lado e da cor. Mas também vemos que os quadrados têm uma posição. Daí o programa.
01.def rect_cor(posx,posy,lado1,lado2,cor):
02.    # Atributos
03.    turtle.penup()
04.    turtle.goto(posx,posy)
05.    turtle.pendown()
06.    turtle.fillcolor(cor)
07.    turtle.begin_fill()
08.    for i in range(4):
09.        if i%2 == 0:
10.            turtle.forward(lado1)
11.        else:
12.            turtle.forward(lado2)
13.        turtle.left(90)
14.    turtle.end_fill()
15.    turtle.hideturtle()
Pensemos agora na flor. O que vemos são várias pétalas, todas da mesma cor, que dão uma volta completa de 360 graus. Se usar como parâmetro o número de pétalas então vou repetir a acção de desenhar uma pétala tendo o cuidado de ir actualizando a orientação. Mas de quanto? Para que dê uma volta completa com as pétalas igualmente espaçadas ... 360 a dividir pelo número de pétalas!
1.def flor(num_petalas, posx,posy,lado1,lado2,cor):
2.    """Desenha uma flor cujas pétalas são rectângulos coloridos."""
3.    for i in range(num_petalas):
4.        rect_cor(posx,posy,lado1,lado2,cor)
5.        turtle.right(360/num_petalas)
Problema resolvido. Antes de passar ao ultimo problema vamos ver se conseguimos fazer melhor. afinal uma pétala rectangular não é muito realista. E que tal esta?
01.def petala(posx, posy, raio, angulo,cor):
02.    """ Desenho de uma pétala."""
03.    # Atributos
04.    turtle.penup()
05.    turtle.goto(posx,posy)
06.    turtle.pendown()
07.    turtle.fillcolor(cor)
08.    turtle.begin_fill()
09.    # Desenha
10.    turtle.circle(raio,angulo)
11.    turtle.setheading(turtle.heading() + 180 - angulo)
12.    turtle.circle(raio,angulo)
13.    turtle.setheading(turtle.heading() + 180 - angulo)
14.    # Termina
15.    turtle.end_fill()
16.    turtle.hideturtle()
A tarefa mais complicada na solução acima foi a gestão da orientação da tartaruga. Na solução apresentada garantimos que a orientação inicial e final coincidem. E agora o programa principal.
1.def flor_geral(num_petalas,posx,posy, raio, angulo,cor):
2.    """Desenha uma flor."""
3.    for i in range(num_petalas):
4.        petala(posx,posy,raio, angulo,cor)
5.        turtle.right(360/num_petalas)   
Muito semelhante ao anterior. Executando o código para valores aceitáveis podemos desenhar lindas flores.
Pergunta 3 Temos uma cadeia de caracteres que pode conter ‘a’s ‘b’s e ‘c’s. Mas só queremos contar os dois primeiros e saber se aparecem em igual número. Como podemos contar o número de vezes que um caracter aparece numa cadeia? Percorrendo a cadeia, caractere a caractere, e somando um, sempre que for igual ao caractere de referência:
1.def conta_car(caractere, cadeia):
2.    """ Número de ocorrências de caractere em cadeia."""
3.    conta = 0
4.    for car in cadeia:
5.        if car == caractere:
6.            conta = conta +1
7.    return conta
Agora o nosso problema original é trivial: contamos para um caso, contamos para o outro e comparamos.
1.def igual(car_1, car_2,cadeia):
2.    conta_1 = conta_car(car_1, cadeia)
3.    conta_2 = conta_car(car_2, cadeia)
4.    return conta_1 == conta_2
Quem conhecer os métodos que existem para as cadeias de caracteres acha que perdemos tempo a implementar a função de contagem conta_car. Não precisamos dela: bastava fazer apenas
1.def igual_c1_c2(car_1,car_2,cadeia):
2.    conta_1 = cadeia.count(car_1)
3.    conta_2 = cadeia.count(car_2)
4.    return conta_1 == conta_2
Trata-se de uma solução genérica e elegante. Mas também era aceitável uma solução para o caso específico de ‘a’s e de ‘b’s e sem modularizar. Por exemplo:
01.def igual_a_b(cadeia):
02.    """
03.    Numa cadeia em que existem 'a', 'b' e 'c'
04.    verifica se o número de 'a's é igual ao número de 'b's.
05.    """
06.    conta_a = 0
07.    conta_b = 0
08.    for car in cadeia:
09.        if car == 'a':
10.            conta_a = conta_a + 1
11.        elif car == 'b':
12.            conta_b = conta_b + 1
13.    return conta_a == conta_b
Qual das versões é melhor? Antes de responder imagine uma nova situação: em vez de apenas dois caracteres eram 5. Que solução preferia agora?

Sem comentários:

Enviar um comentário