sábado, 1 de outubro de 2016

Os benefícios da generalização e da abstracção

Nestas primeiras aulas dissemos que em Python tudo são objectos. Cada objecto tem um conjunto determinado de atributos, como a identidade, o valor e o tipo, e um conjunto de operações em que podem participar. Os atributos num dado instante definem o estado do objecto, enquanto que as operações determinam o seu comportamento.
Podemos usar estes elementos para usar Python como se fosse um vulgar calculadora que me ajuda a saber o peso ideal de uma pessoa do género masculino.
>>> 72.7 * 1.81 - 58 
        73.58700000000002
>>>
Podemos fazer o mesmo para calcular o peso-ideal de uma pessoa do género feminino. E até podemos escrever um único programa que nos permite calcular o peso ideal de qualquer pessoa.
# Definição
def peso_ideal(altura,genero):
    if genero == 'M':
        return round(72.7 * altura - 58,2)
    else:
        return round(62.1 * altura - 44.7,2)
      
# Uso
print(peso_ideal(1.81,'M'))
print(peso_ideal(1.74,'F'))
Este exemplo simples mostra a vantagem de soluções genéricas. Para as conseguir fazemos uso de uma abstracção procedimental, uma definição (def). Neste exemplo os dados são fornecidos ao programa no momento da chamada do programa através dos argumentos da definição, também designados de parâmetros formais, e o resultado é comunicado a quem o solicitou através do comando de regresso (return). Não tem que ser forçosamente assim.
# Definição

def peso_ideal_2():
    altura = float(input('A sua altura sff: '))
    genero = input('O seu género sff [M/F]: ')
    if genero == 'M':
        print(round(72.7 * altura - 58,2))
    else:
        print(round(62.1 * altura - 44.7,2))
    
    
# Uso
peso_ideal_2()

peso_ideal_2()
 
Como se pode ver a grande diferença entre as duas soluções reside no modo como se processa a entrada dos dados a a comunicação do resultado. Agora usamos input para introduzir os dados e print para comunicar o resultado. Neste exemplo, estão presentes o que designamos de instruções, que de um modo geral podem ser agrupadas em dois grandes grupos: destrutivas e de controlo. No primeiro grupo, estão as instruções de atribuição (=), entrada (input) e saída (print). No segundo grupo, as instruções de sequência (;), condicionais (if) e ciclos ou repetições (for). São os blocos construtores dos programas.
Outro exemplo que quer tratámos envolvia desenho de polígonos regulares. Mostrei como se podia passar de um programa muito simples para desenhar um quadrado:
# Definição
def quadrado():
    turtle.forward(50)
    turtle.right(90)
    turtle.forward(50)
    turtle.right(90)
    turtle.forward(50)
    turtle.right(90)
    turtle.forward(50)
    turtle.right(90)
       
# Uso
quadrado()
para outro programa mais completo.
import turtle

# Nova Definição
def vai_para(x,y):
    turtle.penup()
    turtle.goto(x,y)
    turtle.pendown()
    
def quadrado(x,y,orientacao,cor,lado):
    vai_para(x,y)
    turtle.setheading(orientacao)
    turtle.color(cor)
    turtle.begin_fill()
    for i in range(4):
        turtle.forward(lado)
        turtle.right(90)
    turtle.end_fill()
    turtle.hideturtle()
    
# Uso

quadrado(50, -50, 45,'red',50)
turtle.exitonclick()
Completámos a ideia de abstracção ao mostrar como um único programa podia ser usado para desenhar qualquer polígono regular.
import turtle

# Nova Definição
def vai_para(x,y):
    turtle.penup()
    turtle.goto(x,y)
    turtle.pendown()
    
def poligono_reg(num_lados,x,y,orientacao,cor,lado):
    vai_para(x,y)
    turtle.setheading(orientacao)
    turtle.color(cor)
    turtle.begin_fill()
    angulo = 360//num_lados
    for i in range(num_lados):
        turtle.forward(lado)
        turtle.right(angulo)
    turtle.end_fill()
    turtle.hideturtle()
    
# Uso
poligono_reg(7,50, -50, 45,'red',50)
turtle.exitonclick()
A moral desta história é simples: generalizar + abstrair compensa!

Sem comentários:

Enviar um comentário