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.
def rect_cor(posx,posy,lado1,lado2,cor):
    # Atributos
    turtle.penup()
    turtle.goto(posx,posy)
    turtle.pendown()
    turtle.fillcolor(cor)
    turtle.begin_fill()
    for i in range(4):
        if i%2 == 0:
            turtle.forward(lado1)
        else:
            turtle.forward(lado2)
        turtle.left(90)
    turtle.end_fill()
    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!
def flor(num_petalas, posx,posy,lado1,lado2,cor):
    """Desenha uma flor cujas pétalas são rectângulos coloridos."""
    for i in range(num_petalas):
        rect_cor(posx,posy,lado1,lado2,cor)
        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?
def petala(posx, posy, raio, angulo,cor):
    """ Desenho de uma pétala."""
    # Atributos
    turtle.penup()
    turtle.goto(posx,posy)
    turtle.pendown()
    turtle.fillcolor(cor)
    turtle.begin_fill()
    # Desenha
    turtle.circle(raio,angulo)
    turtle.setheading(turtle.heading() + 180 - angulo)
    turtle.circle(raio,angulo)
    turtle.setheading(turtle.heading() + 180 - angulo)
    # Termina
    turtle.end_fill()
    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.
def flor_geral(num_petalas,posx,posy, raio, angulo,cor):
    """Desenha uma flor."""
    for i in range(num_petalas):
        petala(posx,posy,raio, angulo,cor)
        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:
def conta_car(caractere, cadeia):
    """ Número de ocorrências de caractere em cadeia."""
    conta = 0
    for car in cadeia:
        if car == caractere:
            conta = conta +1
    return conta
Agora o nosso problema original é trivial: contamos para um caso, contamos para o outro e comparamos.
def igual(car_1, car_2,cadeia):
    conta_1 = conta_car(car_1, cadeia)
    conta_2 = conta_car(car_2, cadeia)
    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
def igual_c1_c2(car_1,car_2,cadeia):
    conta_1 = cadeia.count(car_1)
    conta_2 = cadeia.count(car_2)
    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:
def igual_a_b(cadeia):
    """
    Numa cadeia em que existem 'a', 'b' e 'c' 
    verifica se o número de 'a's é igual ao número de 'b's.
    """
    conta_a = 0
    conta_b = 0
    for car in cadeia:
        if car == 'a':
            conta_a = conta_a + 1
        elif car == 'b':
            conta_b = conta_b + 1
    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