Um programa, qualquer programa, é um manipulador de objectos. Ao programador compete tomar várias decisões. A primeira, é determinar quais são e
como vão ser comunicados ao programa, os objectos a manipular e, ainda,
como é que este devolve o resultado. A segunda, claro está, é saber como transforma os dados no resultado.
Suponhamos o seguinte exemplo:
desenvolva um programa que, dado o comprimento dos dois lados de um triângulo rectângulo que formam um ângulo de 90 graus (os catetos), determina o comprimento do terceiro lado, a hipotenusa. Neste exemplo, os objectos de entrada (os
dados) são o comprimento dos dois lados e, o objecto à saída (o
resultado) é o comprimento da hipotenusa. Em relação à primeira questão acima referida,
em geral, nós temos
três possibilidades para introduzir os dados e outras
três para os por cá fora. A figura ilustra a situação.
Para a
entrada temos as seguintes três hipóteses:
- através dos parâmetros de entrada: def hipotenusa(lado_1,lado_2): ...
- recorrendo à instrução de entrada no interior do programa: lado_1=input('lado 1 sff: ')
- ler, a partir do interior do programa, de um ficheiro externo:fich=open('lados.txt','r')
Para a saída, mais três hipóteses:
- através da instrução de fim do programa: return h
- recorrendo à instrução de impressão para o canal de saída: print h
- escrever, a partir do interior do programa, num ficheiro externo, que foi aberto para escrita:fich.write(h)
Todas estas possibilidades de entrada saída, podem ser combinadas entre si! A decisão sobre o que escolher depende da
natureza do problema e dos dados, e do
local onde estes podem ser obtidos. Esqueçamos por agora os ficheiros (a tratar em breve nas aulas teoricas), e concentre-mo-nos nas outras quatro alternativas. Do lado da
entrada a opção deve ser guiada pela existência ou não de
interactividade entre o programa e o utilizador. Do lado da
saída, a decisão depende de saber
quem vai precisar do resultado. Se tivermos liberdade nestas matérias a
regra a seguir é a de optar pelo que caso mais geral e menos dependente do utilizador. Se o meu programa puder obter os dados de outro programa e se imprimir o resultado não for o objectivo, então o par
parâmetros de entrada / return deve ser a nossa opção.
Em função do que foi dito o seu programa terá a seguinte
assinatura:
def hipotenusa(lado_1,lado_2):
--- código aqui
return hipo
Passemos agora à segunda questão que foi mencionada no início: como
transformar os dados no resultado. E isto é o domínio privilegiado da área de resolução de problemas. Neste caso simples é fácil identificar os dados, a incógnita e o modo como se relacionam através do
Teorema de Pitágoras: o quadrado da hipotenusa é igual à soma do quadrado dos catetos.
h^2 = \sqrt{l_1^2 + l_2^2)
Logo a nossa solução é baseada nesse pressuposto. Mas antes de apresentarmos a solução pensemos mais um pouco na frase
raiz quadrada da soma do quadrado dos catetos. Ela diz-nos que precisamos de operações auxiliares. Em
programação, isso leva normalmente ao
uso de operações pré-definidas na linguagem ou à utilização (ou definição) de programas auxiliares. Posto tudo isto, aqui vai então a nossa solução:
import math
def quadrado(n):
return n**2
def soma(n1,n2):
n = n1 + n2
return n
def hipotenusa(x,y):
hipo = math.sqrt(soma(quadrado(x), quadrado(y)))
return hipo
def main():
lado_1 = input('lado 1: ')
lado_2 = input('lado 2: ')
print 'Hipotenusa: ',hipotenusa(lado_1, lado_2)
if __name__ =='__main__':
main()
Que
comentários breves se nos oferece fazer? As definições explícitas para as operações
quadrado e
soma podem ser reutilizadas noutros contextos. No caso de devolverem o resultado por impressão e não por
return, essa possibilidade seria perdida! Usamos o método pré-definido
sqrt do módulo
math, o que obriga à sua importação. Finalmente, construímos um programa principal, de nome
main que isola e faz de interface com o potencial utilizador. É aqui que optamos, neste caso, por introduzir os dados e imprimir o resultado. Estamos assim perante um
modelo de programação geral!
O que devemos evitar?
import math
def hipotenusa():
lado_1 = input('lado 1: ')
lado_2 = input('lado 2: ')
print math.sqrt(lado_1 **2 + lado_2 **2)
hipotenusa()
Nesta solução temos interactividade na entrada dos dados. Isso impede o nosso programa de receber as suas entradas de outro programa. Ao usarmos a instrução de impressão também não podemos auxiliar outros programas que precisam deste cálculo. Perdemos ainda modularidade ao não usar programas independentes para o cálculo da soma e do quadrado. Mas não ganhamos nada? Sim , ganhamos! Associámos um nome a três instruções. Assim, cada vez que for preciso basta usar o nome e não precisamos escrever as ditas instruções. Atenção no entanto. Isto é apenas um exemplo ilustrativo do conceito. Cada problema é um caso e deve ser ponderado sempre a melhor maneira de introduzir e devolver os objectos.
O que não devemos usar! De todo!
import math
lado_1 = input('lado 1: ')
lado_2 = input('lado 2: ')
print math.sqrt(lado_1 **2 + lado_2 **2)
O que ganhamos nesta abordagem? Nada.