Diferenças entre edições de "Programas"

De GNU Octave
Ir para: navegação, pesquisa
(Análise do código)
(Exercícios)
Linha 226: Linha 226:
 
=== Exercícios ===
 
=== Exercícios ===
  
# Escreva uma script para calcular a velocidade de um veículo, dada a distância percorrida em Km e o tempo em minutos.
+
# Escreva um programa para calcular a velocidade de um veículo em Km/h, dada a distância percorrida em Km e o tempo em minutos.
 
<syntaxhighlight>
 
<syntaxhighlight>
 
# quero calcular a velocidade sabendo a:
 
# quero calcular a velocidade sabendo a:
Linha 238: Linha 238:
 
printf("Os %d Km foram percorridos a %.2f Km/h\n", distancia, velocidade);
 
printf("Os %d Km foram percorridos a %.2f Km/h\n", distancia, velocidade);
 
</syntaxhighlight>
 
</syntaxhighlight>
# Escreva uma script que calcula a idade de uma pessoa, sabendo o ano de nascimento. Sugestão: use <syntaxhighlight>str2num(datestr(now, "YYYY"))</syntaxhighlight> para ir buscar o ano atual.
+
# Escreva um programa que calcula a idade de uma pessoa, sabendo o ano de nascimento. Sugestão: use <syntaxhighlight>str2num(datestr(now, "YYYY"))</syntaxhighlight> para ir buscar o ano atual.
# Dado o valor em Fahreneit, calcule a correspondente temperatura em Celcius, escrevendo uma script para o efeito.
+
# Dado o valor em Fahreneit, calcule a correspondente temperatura em Celcius, escrevendo um programa para o efeito.
# Escreva uma script que realize a conversão de polegadas para centímetros
+
# Escreva um programa que realize a conversão de polegadas para centímetros.
# Dado um valor em libras, escreva uma script que calcule o valor correspondente em quilos
+
# Dado um valor em libras, escreva uma script que calcule o valor correspondente em quilos.
# Escreva um programa que receba uma palavra e coloque todos os caracteres da palavra em maiúsculas. Usar a função "toupper"
+
# Escreva um programa que receba uma palavra e coloque todos os caracteres da palavra em maiúsculas. Usar a função "toupper".
# Desenvolva uma script que receba uma palavra como parâmetro e retorne o número de vogais desta palavra. Usar a função "regexpi"
+
# Desenvolva um programa que receba uma palavra como parâmetro e retorne o número de vogais desta palavra. Usar a função "regexpi".
# 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 ===
 
=== Âmbito das variáveis ===

Revisão das 14h58min de 12 de dezembro de 2017

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 o programa 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. Dentro do programa, em cada instrução usa-se ';' no final para suprimir a apresentação dessa instrução. 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.


Programa para gerar gráficos

Escreva o seguinte programa grafico.m:

# perguntar o clube ao utilizador
clube = input("Diga o nome do clube: ", "s")
# perguntar os resultados
vitorias = input ("Numero de vitorias: ")
empates = input ("Numero de empates: ")
derrotas = input ("Numero de derrotas: ")
 
contagem = [ vitorias, empates, derrotas]
 
resultados = {'Vitorias', 'Empates', 'Derrotas'}
 
# tres cores: dourado, rosa, vermelho
# dourado: rgb(255,215,0) --> 255/255, 215/255, 0/255
# rosa: rgb(255,192,203) --> 255/255, 192/255, 203/255
# vermelho: rgb(255,0,0)
colormap ([ 1,0.84314,0; 1,0.75294,0.79608; 1,0,0 ]);
 
# mostrar o grafico
pie(contagem, resultados, [0,0,1])
title(clube)
 
# perguntar se quer imprimir o grafico
imprimir = yes_or_no("Quer imprimir (para PDF)? ")
if (imprimir == 1)
   print grafico.pdf
endif


Exercícios

  1. Escreva um programa para calcular a velocidade de um veículo em Km/h, 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 um programa 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 um programa para o efeito.
  3. Escreva um programa 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 um programa que receba uma palavra como parâmetro e retorne o número de vogais desta palavra. Usar a função "regexpi".

Â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);