Computação e Programação (2009/2010-1º Semestre) 2º Exame: 2010-02-10 DURAÇÃO: 3 horas MEMec - LEAN 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. Não desagrafe as folhas. Não se tiram dúvidas durante a realização da prova. A prova é sem consulta. Escreva as suas respostas nos espaços indicados (e se necessário, no verso da página). Pode utilizar as duas últimas folhas em branco como rascunho; Nas perguntas de Verdadeiro e Falso assinale as respostas como no quadrado respectivo. Caso queira emar 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)! Inicie a prova apenas quando o docente der indicação. Nome Número 1/16
2/16
P1 Escolha múltipla (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) Qual das seguintes janelas no MATLAB exibe o registo dos comandos introduzidos pelo utilizador? Command Window History Window Main Window Command History 1.b) Quantos bytes são alocados para uma variável do tipo int8 em MATLAB? Seleccione a resposta correcta: 1 2 4 8 1.c) O que é o âmbito de uma variável (scope): (0.5) É a capacidade que uma variável possui de se chamar a si própria. É a possibilidade de distinção entre nomes de variáveis escritas em letras minúsculas e maiúsculas É a visibilidade e tempo de vida de variáveis locais e globais É o valor (conteúdo) da variável Nenhuma das anteriores 1.d) Considere a variável x = 1234.5678. Qual é a saída produzida no ecrã pela instrução: fprintf('%+0.8f',x) 1234.56780000 +1234.56780000 +1234.5678 1234.5678 Nenhuma das anteriores 3/16 Número: Primeiro e Último Nome:
1.e) Qual dos seguintes elementos representa um operador relacional em MATLAB? && xor ~ = 1.f) Qual das seguintes afirmações distingue um cell array de uma struct? Os dados contidos num cell array podem ser percorridos por um ciclo for ao contrário do que acontece numa struct. Os dados agrupados numa struct podem pertencer a classes diferentes, ao contrário do que acontece num cell array. Os dados agrupados num cell array podem pertencer a classes diferentes, ao contrário do que acontece numa struct. Os dados contidos num cell array podem ser apresentados directamente pelo comando fprintf, ao contrário do que acontece numa struct. 1.g) O caracter de controlo %u é utilizado para formatar a saída de variáveis do tipo: Real sem especificação do sinal. Lógico. Cadeia de carácteres. Inteiro sem especificação do sinal. 1.h) O comando fscanf é uma instrução de leitura de ficheiros, so utilizada para: Ler uma cadeia de carácteres do ficheiro especificado linha a linha até ao carácter of line. Ler dados formatados a partir de um ficheiro para variáveis compativeis com o formato especificado. Ler dados a partir de uma folha de cálculo com extensão.xls. Ler dados formatados a partir de um ficheiro para variáveis compativeis com o formato especificado, so o resultado armazenado num cell array. 4/16
1.i) O método de ordenação denominado por inserção linear consiste em: Ordenar os elementos da própria lista em ordem ascente, ou descente, consoante os valores sejam positivos, ou negativos, respectivamente. Ordenar os elementos da própria lista por pesquisa e trocas sucessivas dos máximos (mínimos) para as posições de extremo até toda a lista estar ordenada. Deixar a lista original na sua ordem e construir uma nova lista onde os elementos da lista original são sucessivamente colocados ato à sua ordenação. Deixar a lista original na sua ordem e apenas actualizar um vector com índices que ordenam a lista original. 1.j) Um Object Handle, se utilizado para a programação de GUIs, corresponde a: Apontador para uma estrutura com atributos e propriedades de todas as componentes existentes na GUI. Apontador para uma estrutura com o histórico da sequência de evento até ao disparo da callback. Apontador para uma estrutura com os atributos e propriedades da componente que disparou a callback. 1.k) Na estrutura da GUI a parte Opening Function do código contém: Seleccione a resposta correcta: Tarefas que não se relacionam directamente com os eventos gerados pela figura ou componentes. Tarefas para inicializar o GUIDE da GUI. Tarefas exectudas pela GUI antes do acesso do utilizador. 1.l) A componente Button Group da GUI permite? Agrupar componentes do tipo radio buttons ou toggle buttons. Agrupar qualquer tipo de componente. Construir toolbars para agrupar componentes do tipo save ou print a serem usados na janela da GUI. 5/16 Número: Primeiro e Último Nome:
P2 Análise e depuração de código em MATLAB (5 valores) 2.a) Apresente o(s) resultado(s) enviado(s) para o monitor em cada um dos seguintes casos? vector = 'padx'; elem_procurado = 'd'; indice = 0; for i = 1:length(vector) fprintf('%s', vector(i)); if vector(i) == elem_procurado indice = i; fprintf(' Encontrei!!!'); fprintf('\n'); fprintf('indice = %d\n', indice); RESPOSTA: p a d Encontrei!!! x indice = 3 matriz = [1 3 5; 2 4 6]; fprintf('%3.1f \t %3.1f \t %3.1f \n', matriz); RESPOSTA: 1.0 2.0 3.0 4.0 5.0 6.0 for k=1:33 if ~mod(k,6) fprintf('x = %d \n', k) NOTA: a função mod devolve o resto da divisão inteira x = 6 x = 12 x = 18 x = 24 x = 30 RESPOSTA: 6/16
disp(myfun1(2, 2, 2)) disp(myfun1(2, 4, 6, 8)) 6 20 RESPOSTA: myfun1.m function res = myfun1(varargin) res = 0; for i = 1:nargin, res = res+ varargin{i}; myfun2 = @(a,b,c,x) a*x^2+b*x+c; RESPOSTA: disp(myfun3(2,2,2,1,myfun2)) 6 MyFun3.m function res = myfun3(a1,a2,a3,a4,f) res = f(a1,a2,a3,a4); aluno = struct('nome', 'Silva, Joao',... 'ID', 12345, 'Nota', 15); outroaluno = struct('nome', 'Melo, Rui',... 'ID', 12123, 'Nota', 13); aluno = [aluno, outroaluno]; fprintf('nome: %s\nid: %d\nnota: %f\n',... aluno(2).nome, aluno(2).id, aluno(2).nota) RESPOSTA: Nome: Melo, Rui ID: 12123 Nota: 13.00 7/16 Número: Primeiro e Último Nome:
2.b) Cada um dos programas seguintes tem cinco erros. Assinale e corrija os erros em cada caso para que os programas 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. 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' else disp('parar') disp(erro) RESPOSTA 1: letra = input('resposta(s/n): ','s'); 2: 3: 4: elseif letra == 'n' letra == 'N' 5: 6: 7: disp('erro') 8: 1: 2: 3: 4: 5: 6: 7: % Lê a variável dadosalunos a partir de % um ficheiro, de seguida apresenta o % número e a média das notas dos testes % realizados por cada aluno load alunos.mat 1: 2: 3: 4: 5: 6: 7: RESPOSTA: (1.0v) 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: (r,c) = size(dadosalunos); for i = 1:r aluno(i).id = dadosalunos(i1); for j = 1:c-1 aluno(i).teste(j) = dadosalunos(i,j+1); fprintf('aluno Média Testes\n') for i = 1:r media = mean aluno(i).teste; fprintf('%d %.2f\n',aluno(i),id,media) 8: [r c] = size(dadosalunos); 9: 10: aluno(i).id = dadosalunos(i,1); 11: 12: 13: 14: 15: 16: 17: 18: media = mean(aluno(i).teste); 19:fprintf('%d %.2f\n',aluno(i).id,media) 20: 21: 8/16
1: 2: 3: 4: 5: 6: 7: 8: % Lê dados médicos de pacientes a partir % de um ficheiro e apresenta no ecrã fid = fopen('pacientes.dat'); if fid == -1 error('ficheiro não abriu.') else 1: 2: 3: 4: 5: 6: 7: 8: RESPOSTA: (1.0v) 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: C = textscan('%s %f %f'); nome = char(c(1)); % Nome sis = C{2}; % Pressão Sistólica dia = C{3}; % Pressao Diastólica for i = 1:length(dia) doente.nome(i) = nome(i,:); doente(i).pressao.sistolica = sis(i); doente(i).pressao.diastolica = dia{i}; fprintf('%s %.2f %.2f\n',... doente(i).nome,... doente(i).pressao.sistolica,... doente(i).pressao.diastolica) closeresult = fclose(fid); if closeresult == 0 error('o ficheiro não foi encerrado!') 9: C = textscan(fid,'%s %f %f'); 10: nome = char(c{1}); % Nome 11: 12: 13: 14: 15: doente(i).nome = nome(i,:); 16: 17: doente(i).pressao.diastolica=dia(i); 18: 19: 20: 21: 22: 23: 24: 25: if closeresult ~= 0 26: 27: 28: 29: 30: 31: 9/16 Número: Primeiro e Último Nome:
P3 Análise de Problema e Algoritmo (3 valores) NOTA IMPORTANTE: a robustez dos programas ao tipo de entrada apenas deve ser considerada quando explicitamente pedida no enunciado da pergunta! 3. Escreva o algoritmo para um programa que recebe do utilizador um valor inteiro não negativo, calcule o seu factorial de forma recursiva e apresenta o resultado no ecrã. O cálculo recursivo do factorial é dado por: 3.a) Abordagem Top-down (1.0v) Mensagem a pedir n Introdução de dados Ler n Cálculo do Factorial Cálculo do factorial com função fact Validação de n Apresentação do resultado 10/16
3.b) Esquema de processamento Entradas: n (0.2v) Saídas: factorial 3.c) Algoritmo do corpo principal do programa: (1.5v) 1. Pedir o valor de n 2. Ler n 3. Se n < 0 a. Apresentar mensagem de erro 4. Caso contrário a. Calcular factorial = fact(n) b. Apresentar valor de factorial 5. Terminar Algoritmo da função factorial = fact(n) do programa: 1. Se n = 0 a. Factorial = 1 2. Caso Contrário a. Factorial = n fact(n-1) 3. Terminar 11/16 Número: Primeiro e Último Nome:
P4 MATLAB (6 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 um script (m file), que apresente ao utilizador um menu com 2 opções: 1) Introduzir as coordenadas em x e y do canto inferior esquerdo e do canto superior direito de um rectângulo, 2) Terminar. Caso o utilizador escolha a opção 1), as coordenadas devem ser guardadas num array de estruturas denominado rectangulo. Cada estrutura deve possuir dois campos, um para cada ponto, e cada campo deve ser constituído por um array 1 2. Após guardar os valores, o script deve voltar ao menu, dando a possibilidade de definir mais rectângulos ou de terminar a execução. Caso o utilizador escolha a opção 2), o programa deve guardar o array de estruturas rectangulo num ficheiro denominado dados_rectangulos.mat, e depois terminar a sua execução. O programa só deve terminar após a opção 2), caso contrário deve pedir novos dados para criar outro rectângulo. (2.0v) rectangulo = []; while 1 fprintf('coordenadas do rectangulo\n'); fprintf('1 - Novas Coordenadas\n'); fprintf('2 - Terminar\n'); opcao = input('opção = '); switch opcao case 1 fprintf('introduzir coordenadas\n'); rect_aux.cantoie = input('canto Inferior Esquerdo [x y]: '); rect_aux.cantosd = input('canto Superior Direito [x y]: '); rectangulo = [rectangulo; rect_aux]; case 2 save dados_rectangulos.mat rectangulo return case default fprintf('opção Errada.\n'); 12/16
4.b) Escreva uma função (m file), denominada testaarray, que receba como argumento um array. A função deve verificar se o array é um vector coluna (qualquer que seja o seu comprimento) e que é composto apenas por valores inteiros. Caso não se verifiquem uma ou as duas condições uma mensagem de erro deve ser enviada, e a função termina a sua execução. Caso as duas condições sejam verdadeiras, a função deve devolver o array testado. (2.0v) [NOTAS: round(z) retorna o valor inteiro mais próximo de z; size(m) retorna as dimensões de M; error(mensagem) apresenta uma mensagem de erro, interropo a execução do programa]. function array = testaarray(array) [n_linhas n_colunas] = size(array); if n_colunas~=1 n_linhas <= n_colunas error('não é vector coluna.') for k = 1:l if sum(round(array)-array) ~= 0 error('não são elementos inteiros') ou function array = testaarray(array) [n_linhas n_colunas] = size(array); if n_colunas~=1 n_linhas <= n_colunas error('não é vector coluna.') for k = 1:n_linhas if round(array(k))-array(k) ~= 0 error('não são elementos inteiros') 13/16 Número: Primeiro e Último Nome:
4.c) Uma série geométrica é dada por, Escreva um script em MATLAB que calcule os n primeiros termos da série e apresenta um gráfico com a evolução de x (deve utilizar as funções stem, title, xlabel, ylabel). O script deve pedir ao utilizador os parâmetros da série, que deverão ser validados tal que n > 0 e r 1. O programa só deve terminar após opção do utilizador, caso contrário deve pedir novos dados para cálculo. (2.0v) while 1 serie = []; vector_n = []; fprintf('parâmetros da série:\n'); n = input(' n = '); a = input(' a = '); r = input(' r = '); if n > 0 && r ~= 1 for k = 1:n serie(k) = a * r^(k-1); vector_n(k) = (k-1); stem(vector_n,serie); title('série Geométrica'); xlabel('termo da série'); ylabel('valores da série'); else disp('erro nos parâmetros da série.') opcao = input('escreva 0 para terminar, ou 1 para continuar: '); if ~opcao break 14/16
15/16 Número: Primeiro e Último Nome:
16/16