MEMec - LEAN
Computação e Programação
(2009/2010 - 1º Semestre)
2º Teste e Exame de 1ª Época
(27 – JAN – 2010) DURAÇÃO: 1h30m (teste) 3h00m (exame)
Leia com atenção os pontos que se seguem:
• Comece por escrever o seu nome e número nesta folha, e número, primeiro e
último nome nas restantes.
• O teste é composto apenas pelas questões assinaladas com a palavra TESTE
(junto à cotação), que são as questões 1–g) a 1-l), 2-a4) a 2-a6), 2-b2), 4-b) e
4-c). A questão 3 é a única que é exclusivamente pertencente ao exame.
• O exame é composto por todas as questões deste enunciado.
• Não desagrafe as folhas.
• Não se tiram dúvidas durante a realização da prova escrita.
• A prova escrita é sem consulta.
• Escreva as suas respostas nos espaços indicados.
• Pode utilizar a última folha como rascunho.
• Inicie a prova apenas quando o docente der indicação.
• Nas perguntas de Verdadeiro e Falso assinale as respostas como
no quadrado
respectivo. Caso queira emendar uma resposta, risque completamente o quadrado
respectivo e coloque à esquerda da opção que considera correcta o símbolo
.
• Cada resposta errada nas perguntas de escolha múltipla desconta metade da
cotação da pergunta na cotação global da prova!
Nome
P1 Escolha múltipla (Exame: 6 valores, Teste: 6 valores)
NOTA IMPORTANTE: cada resposta errada nas perguntas de escolha múltipla desconta metade da cotação da pergunta na cotação global da prova.
1.a) A disciplina de Computação e Programação tem por objectivo maior ensinar: (0.5v) Seleccione a resposta correcta:
A escrever algoritmos em pseudo-código A importância dos computadores na engenharia
O acto de projectar, codificar e cuidar da manutenção de programas A linguagem do Matlab
1.b) A linguagem máquina é: (0.5v)
Seleccione a resposta correcta:
Um conjunto de instruções entendidas por um dado computador Uma linguagem de alto-nível
O conjunto das instruções entendidas por um dado programador A forma de os computadores comunicarem entre si
1.c) Porque é que devem ser dados nomes (identificadores) significativos aos objectos? (0.5v) Seleccione a resposta correcta:
Para não baralhar o Matlab
Para ser mais rápido escrever o código do programa
Para facilitar a leitura nas tarefas de programação e manutenção Porque está definido como uma boa prática de programação Nenhuma das anteriores
X
X
1.d) Em que circunstâncias escolheria utilizar uma estrutura de selecção switch? (0.5v) Seleccione a resposta correcta:
Quando a sequência de instruções a executar depender do valor de várias variáveis e expressões lógicas
Quando a sequência de instruções a executar depender do valor de uma variável do tipo inteiro ou char
Quando a sequência de instruções a executar depender do valor de uma variável real
Nenhuma das anteriores
1.e) Em que circunstâncias escolheria utilizar um ciclo controlado por contador (for)? (0.5v) Seleccione a resposta correcta:
Quando for desconhecido o número de vezes a executar a repetição Quando a sequência de instruções a repetir tiver apenas uma linha
Quando a repetição for para ser executada um número conhecido de vezes Sempre que a repetição for para ser executada mais de 2 vezes
Nenhuma das anteriores
1.f) A abordagem top-down utiliza-se para: (0.5v) Seleccione a resposta correcta:
Definir a sequência de tarefas que resolvem um dado problema
Definir uma lista (não ordenada) de tarefas simples que devem ser cumpridas para se resolver um problema complexo
Tentar dar sentido ao código do programa depois de escrito Nenhuma das anteriores.
X
X
1.g) Uma string em Matlab é tratada como: (0.5v) Seleccione a resposta correcta:
Um cell array de sub-strings
Uma classe de dados própria (diferente dos char)
Um array de inteiros contendo os códigos ASCII dos caracteres Um array comum cujos elementos são da classe char
Nenhuma das anteriores
1.h) Qual das seguintes afirmações distingue um cell array de uma struct ? (0.5v) Seleccione a resposta correcta:
Os dados agrupados numa struct podem pertencer a classes diferentes, ao contrário do que acontece num cell array
Os dados contidos num cell array podem ser percorridos por um ciclo for ao contrário do que acontece numa struct
Os dados agrupados num cell array podem pertencer a classes diferentes, ao contrário do que acontece numa struct
Nenhuma das anteriores.
1.i) A operação de abertura de um ficheiro serve para: (0.5v) Seleccione a resposta correcta:
Apagar o conteúdo do ficheiro
Criar uma estrutura de dados com o conteúdo do ficheiro
Estabelecer uma ligação entre um determinado identificador no nosso programa e o nome do ficheiro no sistema operativo do computador
Estabelecer uma ligação entre um array de dados existente no nosso programa e os dados do ficheiro guardados no disco rígido
TESTE (1.0v) TESTE (1.0v) TESTE (1.0v) X X X
1.j) Uma função recursiva é: (0.5v) Seleccione a resposta correcta:
Uma função com recursos de memória ilimitados
Uma função definida por um caso base e uma chamada a si própria Uma função com um número variável de argumentos de entrada Uma função que executa uma tarefa iterativamente
Nenhuma das anteriores
1.k) O código Matlab associado a um GUI é executado: (0.5v) Seleccione a resposta correcta:
De acordo com as chamadas às funções no script principal
Sequencialmente (as várias funções definidas são executadas em sequência) Repetidamente em ciclo
De acordo com os eventos que ocorrem no GUI Nenhuma das anteriores
1.l) Uma dada função de callback associada a um GUI é executada quando: (0.5v) Seleccione a resposta correcta:
O GUI é inicializado
Ocorre um evento qualquer no GUI
Ocorre um evento no objecto (botão, caixa de edição, etc.) associado à função O Matlab é encerrado sem que o GUI seja fechado
Nenhuma das anteriores
TESTE (1.0v) TESTE (1.0v) TESTE (1.0v) X X X
P2 Análise de código (Exame: 5 valores, Teste: 7 valores)
2.a) Qual é ou quais são os resultados apresentados no monitor, para cada um dos seguintes 6 programas? RESPOSTA: (0.5v) vector = [1 3 7 2 0 4 9 6 8 5]; elem_procurado = 7; indice = 0; for i = 1:length(vector) fprintf('%d', vector(i)); if vector(i) == elem_procurado indice = i; fprintf(' Encontrei!!!'); end fprintf('\n'); end
fprintf('indice = %d\n', indice);
RESPOSTA: (0.5v) vector = 'Alfredinho'; elem_procurado = 'f'; indice = 0; i = 1; while ~indice fprintf('%c', vector(i)); if vector(i) == elem_procurado indice = i; fprintf(' Encontrei!!!'); end fprintf('\n'); i = i + 1; end
fprintf('indice = %d\n', indice);
programa2.m 1 3 7 Encontrei!!! 2 0 4 9 6 8 5 indice = 3 A l f Encontrei!!! indice = 3
RESPOSTA: (0.5v) a = [1 2 3 4 5]; b = ones(size(a)); disp(sum(a)) disp(a*b') disp(a.*b) programa3.m RESPOSTA: (0.5v) TESTE (1.4v) disp(func1(1, 1, 1)) disp(func1(1, 2, 3, 4, 5)) programa4.m
function res = func1(varargin)
res = 0;
for i = 1:nargin,
res = res + varargin{i};
end func1.m 15 15 1 2 3 4 5 3 15
RESPOSTA: (0.5v) TESTE (1.4v)
RESPOSTA: (0.5v) TESTE (1.4v) function res = func3(a, b, f)
res = f(a, b);
end
a = struct('n1','José','n2','Silva'); b.n1 = 'João';
b.n2 = 'Alves'; c = [b a];
disp(c(1).n2(3:end))
programa6.m
func2 = @(a, b) -b/(2*a); disp(func3(3, 12, func2))
programa5.m
func3.m -2
2.b) Modifique os seguintes programas de modo a que estes executem correctamente.
NOTA IMPORTANTE - Para modificar o código deve proceder do seguinte modo:
• Na sua resposta deve apenas indicar o número da linha se o código estiver correcto, caso o código esteja incorrecto deve indicar a linha e a respectiva alteração.
• Caso necessite de adicionar novas linhas numere-as utilizando a linha anterior como base, seguida de um ponto e das letras a, b, etc.
EXEMPLO: RESPOSTA 1: 2: 3: 4: 5: 6: 7: 8: letra = input('Resposta (S/N): ',s); if letra == 's' || letra == 'S' disp('Continuar')
elseif letra == 'n' [ letra == 'N' disp('Parar') else disp(Erro) end 1: letra = input('Resposta (S/N): ','s'); 2: 3:
4: elseif letra == 'n' || letra == 'N' 5: 6: 7: disp('Erro') 8: FIM DE EXEMPLO. RESPOSTA: (1.0v) 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
% Pede ao utilizador N números inteiros, % separa os positivos dos negativos e % grava em ficheiros ASCII separados. posints = [];
negints = [];
for i=1:-10
inputnum = input('Número: ', 's'); num2 = int32(inputnum);
while num2 ~= inputnum disp('Número Inválido!') inputnum = input('Número: '); num2 = int32(inputnum); end
if inputnum < 0
negints = [negints inputnum]; elseif 1: 2: 3: 4: 5: 6: 7: for i=1:10
8: inputnum = input('Número: '); 9: 10: 11: 12: 13: 14: 15: 16: 17: else
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
% Abrir um novo ficheiro para escrita fid = fopen('circulo.dat','r');
radius = input('Introduza o raio: '); %Verificar a entrada
while radius >= 0
radius = input('Introduza o raio: '); end
permt = 2.*pi*radius; area = pi*radius^2;
% Escrever no ficheiro "circulo.dat" fprintf('O perímetro é: %.2f\n', permt); fprintf('A area é: %.2f\n', area);
% Verificar o fecho do ficheiro closeres = fclose(fid);
if closeres = 0
disp('Ficheiro fechado com sucesso') else
disp('Ficheiro não pode ser fechado') end 1: 2: fid = fopen('circulo.dat','w'); 3: 4: 5: 6: while radius < 0 7: 8: 9: 10: 11: 12: 13: fprintf(fid, 'O perímetro é: %.2f\n' 14: fprintf(fid, 'A area é: %.2f\n', 15: 16: 17: 18: if closeres == 0 19: 20: 21: 22: RESPOSTA: (1.0v) TESTE (2.8v) , permt); area);
P3 Análise de Problema e Algoritmo (Exame: 3 valores)
NOTA IMPORTANTE: a robustez dos programas ao tipo de entrada apenas deve ser considerada quando explicitamente pedida no enunciado da pergunta!
3. Projecte o algoritmo de um programa que recebe do utilizador o dia e o mês como valores inteiros e calcule o número de ordem do dia no ano nDia [1, 365]. Assuma que o ano não é bissexto (mês de Fevereiro com 28 dias).
3.a) Abordagem Top-down
Calcula dia (1.0v) ∈ ∈ ∈ ∈ Receber dados do utilizador Executar cálculo Apresentar resultado Pedir dados ao utilizador Ler dados introduzidos
3.b) Esquema de processamento
Entradas: ● Dia – valor inteiro
● Mes – valor inteiro
Saída: ● nDia – valor inteiro
3.c) Algoritmo
(1.5v) (0.2v) (0.5v)
1) Apresentar mensagem ao utilizador pedindo o dia e o mês. 2) Ler os valores introduzidos para Dia e Mes respectivamente. 3) Inicializar nDia = Dia
4) Repetir de Mes_i = 1 até Mes-1 em incrementos de 1 a. Caso Mes_i seja 1, 3, 5, 7, 8, 10 ou 12
i. nDia = nDia + 31
b. Caso Mes_i seja 4, 6, 9 ou 11 i. nDia = nDia + 30
c. Caso Mes_i seja 2
i. nDia = nDia + 28
P4 Codificação (Exame: 6 valores, Teste: 7 valores)
NOTA IMPORTANTE: a robustez dos programas ao tipo de entrada apenas deve ser considerada quando explicitamente pedida no enunciado da pergunta!
4.a) Escreva na linguagem do Matlab uma função chamada meu_menu que apresente ao utilizador as seguintes três opções:
a) Apresentar valores numéricos b) Apresentar gráfico
c) Terminar
A função deve pedir ao utilizador para introduzir a sua opção e deve devolver a opção devidamente validada, ou seja, deve apresentar uma mensagem de erro e repetir o pedido de introdução caso a opção introduzida não seja nenhuma das apresentadas.
(1.6v)
function opcao = meu_menu
fprintf('a) Apresentar valores numéricos\n'); fprintf('b) Apresentar gráfico\n');
fprintf('c) Terminar\n\n'); ciclo = 1;
while ciclo
opcao = input('Introduza a opcao desejada: ','s');
switch opcao
case {'a', 'b', 'c'} ciclo = 0;
otherwise
fprintf('A opcao introduzida não é válida!\n\n'); end
4.b) Escreva na linguagem do Matlab uma função chamada le_ficheiro correspondendo ao seguinte algoritmo:
Pârametros de entrada: - nenhum
Pârametros de saída: dados - array de structs, cada elemento possui os campos .x e .y
Algoritmo:
1) Abrir o ficheiro fich_dados.dat para leitura
2) Verificar o sucesso da operação de abertura do ficheiro, se não for bem sucedida apresentar mensagem de erro adequada e retornar o array dados vazio
3) Inicializar i=1
4) Enquanto não for encontrado o fim do ficheiro repetir a) Ler linha do ficheiro para a string s_linha
b) Converter os 5 primeiros caracteres de s_linha para um valor numérico e atribuir a dados(i).x
c) Converter os 5 caracteres seguintes de s_linha para um valor numérico e atribuir a dados(i).y
d) Incrementar i de uma unidade 5) Fechar o ficheiro fich_dados.dat
6) Verificar o sucesso da operação de fecho do ficheiro, se não for bem sucedida apresentar mensagem de erro adequada
(2.2v) TESTE (3.5v)
function dados = le_ficheiro fid = fopen('fich_dados.dat');
if fid == -1
disp('Erro na abertura do ficheiro.'); dados = []; return end i = 1; while ~feof(fid) s_linha = fgetl(fid); dados(i).x = str2num(s_linha(1:5)); dados(i).y = str2num(s_linha(6:10)); i = i + 1; end close_res = fclose(fid); if close_res ~= 0
disp('O ficheiro não pode ser fechado.');
4.c) Escreva na linguagem do Matlab um script que lê os dados do ficheiro fich_dados.dat
utilizando a função le_ficheiro definida na alínea 4.b), e em seguida apresenta um menu e pede uma opção utilizando a função meu_menu definida na alínea 4.a). De acordo com a opção do utilizador o script deve listar os dados do ficheiro ou apresentar o respectivo gráfico. O script deve executar ciclicamente até o utilizador introduzir a opção c (ver menu da alínea a). O formato de apresentação da listagem é rígido de acordo com o exemplo seguinte:
x y 0.000 0.000 0.349 0.342 0.698 0.642
Respeite no seu programa as posições no ecrã e o número de casas decimais.
Note que a utilização das funções só requer o conhecimento dos respectivos nomes, e parâmetros de entrada e saída que podem ser consultados nos enunciados das alíneas anteriores. Não defina as funções na resposta a esta alínea. (2.2v)
TESTE (3.5v) dados = le_ficheiro; opcao = 'o'; while opcao ~= 'c' opcao = meu_menu; switch opcao case 'a' fprintf(' x y\n'); for i = 1:length(dados)
fprintf('%5.3f %5.3f\n', dados(i).x, dados(i).y); end
case 'b'
plot([dados.x], [dados.y]); end