Programas

De GNU Octave
Ir para: navegação, pesquisa

Steve jobs how to think.png

Para resolver problemas mais ou menos complexos, em vez de se escreverem os comandos um a um, podemos agrupar esses mesmos comandos num programa. Na literatura inglesa do Octave (e do MATLAB) chamam scripts a estes programas. Ou seja, uma script é esta sequência de comandos guardados. Nesta documentação vamos usar o termo programa para designar uma script.

Os comandos são guardados num documento com a extensão .m. Tudo o que se escreve na linha de comandos do Octave, pode-se escrever num programa. Depois de prontos, os programas podem ser executados quantas vezes se quiser, e podem ser enviados para outros colegas, para executarem o mesmo programa.

Portanto, sempre que haja necessidade de repetir diversas vezes as mesmas operações, torna-se mais interessante juntar essas operações num programa.

Um programa é invocado pelo seu nome, sem a extensão .m. Ao ser invocado, todas as instruções são processadas, como se tivessem sido lançadas na linha de comandos do Octave.

Para que queremos os programas

Os programas têm como vantagem o facto de se escreverem 1 vez e depois se poderem executar muitas vezes.

Imagine que pretende calcular a distância entre dois pontos P e Q à superfície da terra, sabendo as coordenadas dos mesmos (latitude e longitude).

Illustration of great-circle distance.svg.png

Se for preciso calcular essa distância apenas uma vez, escreve-se uma sequência de comandos da seguinte forma:

agueda = [40.5832343,-8.4542053];
aveiro = [40.6393801,-8.6533827];
 
graus2radianos = pi/180.0;
# phi = 90 - latitude
phi1 = (90.0 - agueda(1))*graus2radianos;
phi2 = (90.0 - aveiro(1))*graus2radianos;
# theta = longitude
theta1 = agueda(2)*graus2radianos;
theta2 = aveiro(2)*graus2radianos;
aux = sin(phi1)*sin(phi2)*cos(theta1-theta2) + cos(phi1)*cos(phi2);
arco = acos(aux);
metros = arco * 6378137

E se for preciso calcular a distância entre Braga e Vila Real? Escrevem-se de novo todos os comandos? E se for novamente preciso calcular a distância entre Viana do Castelo e Ponte de Lima?

Para reaproveitar as fórmulas que foram escritas, escreve-se um programa, uma única vez. Depois o mesmo é executado quantas vezes quiseremos, mas com dados diferentes. Isto é, sempre que corrermos o programa, pedimos aos utilizador que nos diga qual é o ponto de origem e destino.

Na prática, as instruções anteriores são transformadas no seguinte programa, que é guardado num documento distancia.m:

# ver as coordenadas no openstreetmap.org ou no maps.google.pt
origem = input("Ponto de origem? (vetor [latitude, longitude]): ");
destino = input("Ponto de chegada? (vetor [latitude, longitude]): ");
grau2radianos = pi/180.0;
# phi = 90 - latitude
phi1 = (90.0 - origem(1))*grau2radianos;
phi2 = (90.0 - destino(1))*grau2radianos;
# theta = longitude
theta1 = origem(2)*grau2radianos;
theta2 = destino(2)*grau2radianos;
aux = sin(phi1)*sin(phi2)*cos(theta1-theta2) + cos(phi1)*cos(phi2);
arco = acos(aux);
metros = arco * 6378137;
printf("Distancia entre os pontos %.1f metros\n", metros);

Depois, pode-se executar o programa quantas vezes se quiser, da seguinte forma:

>> distancia
Ponto de origem? (vetor [latitude, longitude]): [41.5472695,-8.4464405]
Ponto de chegada? (vetor [latitude, longitude]): [41.3018331,-7.7971441]
Distancia entre os pontos 60694.1 metros
>>

Primeiro programa

O exemplo anterior tem uma fórmula de cálculo complicada. Vamos começar com programas com cálculos mais simples.

O primeiro programa que vamos escrever sistematiza o cálculo da área de um retângulo. Obviamente é um cálculo muito simples, mas a ideia é começar com um programa (uma script) muito pequeno.

# calcula a area de um retangulo, dada a largura e o comprimento
# para executar o programa, basta escrever:
# arearetangulo
#
largura = input("Largura?\n");
comprimento = input("Comprimento?\n");
area = largura * comprimento;
printf("A área é: %g\n", area);

Em primeiro lugar, é preciso escrever as instruções apresentadas num editor de texto qualquer. Qualquer editor serve, desde que guarde o documento em formato de texto. TEM QUE FICAR GUARDADO COM O NOME arearetangulo.m e obrigatoriamente na pasta onde está a executar o Octave.

Depois de guardado o programa na pasta atual do Octave, executa-se o mesmo escrevendo apenas o nome (sem a extensão). Exemplo:

>> arearetangulo
Largura?
90
Comprimento?
120
A área é: 10800

Se o programa não correr, confirme que o mesmo está a ser gravado com a extensão .m e está na pasta atual. Para tal, da mesma forma que temos os comandos who e whos para ver que variáveis estão definidas, temos um comando what para saber que programas estão definidos.

>> what
M-files in directory /home/jgr/Documentos/Aulas/13141S/OCV:
 
   arearetangulo.m       espiral.m             ocv.m
   calculavelocidade.m   idade.m               unnamed2.m
>>

Alternativamente, pode usar os comandos mais genéricos para saber qual a pasta atual (reveja a forma de saber e mudar a pasta atual) e depois inspecionar os ficheiros .m da pasta fazendo:

dir *.m

Se precisar, pode descarregar a versão deste programa arearetangulo.m disponível em http://octave.di.uminho.pt/images/files/.

Análise do código

Analisando a script anterior, podemos desde já salientar alguns aspectos importantes.

  1. Pode-se (e deve-se!) acrescentar comentários. Os comentários são escritos após o símbolo '#' ou '%'. Após este símbolo e até ao fim da linha, é considerado comentário.
  2. As variáveis são GLOBAIS. Isto é, NUNCA use o nome do programa para uma variável ou vice versa. Este perigo está explicado de forma detalhada na seção #Âmbito das variáveis.
  3. Ao executar a script, usa-se ';' no final das instruções para suprimir a apresentação desse resultado. O mesmo acontece quando se usa a linha de comandos. Experimente a diferença entre usar ou não o ';' no fim das instruções.
octave:1> b=10
b =  10
octave:2> b=b+20;
octave:3>
Importância dos comentários

Os comentários incluídos nos programas são fundamentais. Todas as linguagens de programação incluem o suporte à inclusão de comentários porque... os programas geralmente são complexos e difíceis de ler! Os comentários são apenas para serem interpretados pelos humanos e não pelo computador. Por isso, devem ser legíveis e explicar o que faz o programa e como o faz.

Até os programadores têm dificuldade em ler o seu próprio código após algum tempo. Por isso, é fundamental escrever comentários na altura em que se escreve o código e justificar as decisões tomadas.

O Octave tira partido dos comentários para dar alguma informação sobre o que faz um programa.

Neste primeiro programa, começámos por por alguns comentários. Por isso, geralmente depois de usar o comando what para saber que programas estão disponíveis, usamos o comando help para saber o que faz um dado programa.

>> what
M-files in directory /home/jgr/Documentos/Aulas/13141S/OCV:
 
   arearetangulo.m       espiral.m             ocv.m
   calculavelocidade.m   idade.m               unnamed2.m
>> help arearetangulo
`arearetangulo' is a script from the file /home/jgr/Documentos/Aulas/13141S/OCV/arearetangulo.m
 
 calcula a area de um retangulo, dada a largura e o comprimento
 para executar o programa, basta escrever:
 arearetangulo
 
 
Additional help for built-in functions and operators is
available in the on-line version of the manual.  Use the command
`doc <topic>' to search the manual index.
 
Help and information about Octave is also available on the WWW
at http://www.octave.org and via the help@octave.org
mailing list.
>>

Repare que o Octave mostra os comentários colocados no início do programa. Por isso, comece sempre os programas com alguns comentários.


Exercícios

  1. Escreva uma script para calcular a velocidade de um veículo, dada a distância percorrida em Km e o tempo em minutos.
# quero calcular a velocidade sabendo a:
# distancia (km)
# tempo (minutos)
distancia = input("Indique os Kms percorridos: ");
tempo = input("Indique os minutos gastos: ");
# preciso de transformar minutos em horas
horas = tempo/60;
velocidade = distancia/horas;
printf("Os %d Km foram percorridos a %.2f Km/h\n", distancia, velocidade);
  1. Escreva uma script que calcula a idade de uma pessoa, sabendo o ano de nascimento. Sugestão: use
    str2num(datestr(now, "YYYY"))
    para ir buscar o ano atual.
  2. Dado o valor em Fahreneit, calcule a correspondente temperatura em Celcius, escrevendo uma script para o efeito.
  3. Escreva uma script que realize a conversão de polegadas para centímetros
  4. Dado um valor em libras, escreva uma script que calcule o valor correspondente em quilos
  5. Escreva um programa que receba uma palavra e coloque todos os caracteres da palavra em maiúsculas. Usar a função "toupper"
  6. Desenvolva uma script que receba uma palavra como parâmetro e retorne o número de vogais desta palavra. Usar a função "regexpi"
  7. Escreva uma script que leia um vetor e calcule seu desvio padrão usando apenas as funções "sum" e "length"

Âmbito das variáveis

Na seguinte script idade.m, utiliza-se uma variável idade que tem o mesmo nome que a script. Neste caso, temos uma sobreposição que é vivamente desaconselhada. No caso concreto, depois de correr a script, a mesma não poderá ser novamente executada, porque idade passa a ser uma referência para a variável e não para a script.

# idade.m
# script octave
# calcular a idade de uma pessoa
#
# ESTA SCRIPT TEM UM ERRO.
# Esta script usa uma variável global 'idade' que é igual ao nome da script 'idade.m'.
# Não se deve usar variáveis em scripts iguais aos nomes das scripts.
#
# Desta forma, só se consegue chamar a script uma vez
# Depois disso, 'idade' passa a ser uma referência para a variável e não para a script.
ano = input("Ano de nascimento?\n");
idade = 2012 - ano;
printf("Você tem %d anos de idade\n", idade);