Buscar

P-09_Vetores_parte_1


Prévia do material em texto

Universidade Federal de Ouro Preto
Instituto de Ciências Exatas e Biológicas
Departamento de Computação
BCC701
Programação de Computadores I
Semestre: 2020-02
Aula Prática – Estrutura Homogênea: VETOR (1)
Pré-requisitos:
• Estar familiarizado com o conteúdo das aulas anteriores e ter realizado as tarefas correspondentes.
• Ler as seções 7.1, 7.3.1, 7.3.3 e 7.3.5 do livro texto da disciplina.
• Assistir os v́ıdeos e/ou aulas teóricas correspondentes.
Resumo:
• Aprendemos, até aqui, que uma variável tem a capacidade de armazenar um único valor na memória, por
exemplo: fruta = ‘maç~a’ e quantidade = 5.
• Porém, muitas vezes temos a necessidade de manipular diversos valores que estão relacionados a alguma
caracteŕıstica. Suponha que você precise manipular o nome e a quantidade de várias frutas. Seriam
necessárias várias variáveis para armazenar cada valor.
• A solução ideal para isso é através de vetores. Que é uma estrutura de dados capaz de armazenar vários
valores em uma única variável.
• A principal caracteŕıstica dos vetores é que eles são ditos heterogêneos, o que significa que todos os valores
armazenados em um vetor devem ser de um mesmo tipo. Para manipular os nomes e as quantidades de
frutas, podeŕıamos usar duas variáveis: frutas = [ ‘maç~a’, ‘laranja’, ‘abacaxi’ ] e quantidades
= [ 5, 3, 1 ], por exemplo. Neste caso, o número e a ordem dos elementos pode determinar a relação
entre o nome e a quantidade de cada fruta.
• Para manipular e acessar os valores de forma individual, precisamos utilizar algo que represente única
e exclusivamente um dos elementos do vetor. Isto é feito a partir de sua posição (ou ı́ndice), que é
determinado por um contador de valor inteiro que se inicia por 0 (zero). Por exemplo: frutas[0]
armazena o valor ‘maç~a’, frutas[1] armazena o valor ‘laranja’, e assim por diante.
• Neste nosso exemplo, os nomes das frutas e as suas quantidades podem ser associadas pelo ı́ndice, ou seja,
a terceira fruta se chama frutas[2] (valor ‘laranja’), e a sua quantidade é quantidades[2] (valor 1).
• Algumas operações com vetores que devem ser bem assimiladas:
1 # Criando vetor por atribuição:
2 vetor = [ ] # vetor vazio, não tem nenhum elemento
3 vetor = [ 10, 20, 30, 40 ] # vetor com 4 elementos
4 # Adicionando elementos:
5 vetor.append(100) # novo conteúdo: [ 10, 20, 30, 40, 100 ]
6 vetor.append(300) # novo conteúdo: [ 10, 20, 30, 40, 100, 300 ]
7 # Removendo elementos:
8 vetor.pop(0) # novo conteúdo: [ 20, 30, 40, 100, 300 ]
9 vetor.pop(2) # novo conteúdo: [ 20, 30, 100, 300 ]
10 # Alterando elementos:
11 vetor[1] = 35 # novo conteúdo: [ 20, 35, 100, 300 ]
12 vetor[3] = vetor[3] + 10 # novo conteúdo: [ 20, 35, 100, 310 ]
13 # Quantidade de elementos
14 qtd = len(vetor) # variável qtd assume o valor 4
1
• É muito importante compreender bem a diferença entre os valores armazenados no vetor e os ı́ndices
que representam as suas posições de armazenamento. Normalmente é necessário processar os valores
do vetor determinando um padrão de acesso aos seus ı́ndices. É muito comum fazer isso através de um
laço, onde o contador é responsável por determinar os ı́ndices e o bloco de comandos processa os valores
para cumprir alguma tarefa. No código a seguir nós fazemos o somatório de todos os elementos do vetor
definido anteriormente:
1 soma = 0
2 for i in range(qtd):
3 soma += vetor[i]
4 print(soma)
Neste outro código, processamos o somatório dos valores armazenados em ı́ndices pares:
1 soma = 0
2 for i in range(0, qtd, 2):
3 soma += vetor[i]
4 print(soma)
E neste outro código, processamos o somatório dos valores armazenados em ı́ndices ı́mpares:
1 soma = 0
2 for i in range(1, qtd, 2):
3 soma += vetor[i]
4 print(soma)
Observe que nossa estratégia é usar a sintaxe do range para determinar o padrão de acesso aos ı́ndices,
e para fazer o somatório precisamos usar o valor armazenado no vetor, acessando o ı́ndice determinado
pelo contador.
• Nas Seções 7.3.1, 7.3.3 e 7.3.5 do livro texto da disciplina nós criamos um conjunto de funções úteis
sobre a manipulação de vetores, é muito importante que você compreenda bem o que elas fazem e como
utilizá-las. É recomendável também que você entenda como elas realizam suas tarefas. Um resumo das
funções:
– criarVetor(qtdElementos, valorPadrao): cria e retorna um novo vetor contendo qtdElementos,
todos armazenando o mesmo valor, definido por valorPadrao.
– preencherVetor(valores, tipo): cria e retorna um novo vetor contendo os valores definidos na
string valores, convertidos para o tipo definido por tipo. A string valores segue um padrão, ela
define todos os valores do vetor separados por v́ırgula, por exemplo: ‘10, 20, 30, 40’ gera o vetor
[ 10, 20, 30, 40 ] como resultado da função.
– imprimeVetor(vetor): imprime os elementos do vetor no terminal, ele imprime seguindo o mesmo
padrão de definição do vetor por atribuição, usando os colchetes e separando os elementos por v́ırgula.
• Nesta prática a intenção é reforçar seus conhecimentos em todos estes recursos e praticar sua utilização
na construção de programas que resolvam algum problema espećıfico. Se você não está familiarizado com
os itens listados acima, consulte os pré-requisitos da prática, listados anteriormente.
2
Tarefa 1: Criando vetores com valores definidos pelo usuário
A maioria dos exerćıcios envolvendo vetor começará com a definição dos valores a serem armazenados em
um ou mais vetores. Basicamente, temos duas estratégias para fazer isso. A primeira através da definição de
entradas individuais, e a segunda a partir de uma única entrada e a chamada da função preencherVetor.
No programa a seguir, preenchemos o vetor conhecendo a quantidade de elementos:
1 # código da função imprimeVetor
2
3 qtd = int(input(’Quantidade de elementos: ’))
4 vetor = []
5 for i in range(qtd):
6 valor = int(input(f’Valor {i+1}: ’))
7 vetor.append(valor)
8 print(’Vetor definido: ’, end=’’)
9 imprimeVetor(vetor)
Observe que, uma vez conhecendo o tamanho do vetor, podemos usar um laço for para ler e adicionar
cada valor a ser armazenado no vetor. Antes deste laço temos que criar um vetor vazio. Algumas vezes, não
saberemos a quantidade de elementos, alguma regra será definida para determinar a parada. No programa a
seguir, definiremos valores para o vetor enquanto os valores forem maiores do que zero.
1 # código da função imprimeVetor
2
3 vetor = []
4 i = 0
5 valor = int(input(f’Valor {i+1}: ’))
6 while valor > 0:
7 i += 1
8 vetor.append(valor)
9 valor = int(input(f’Valor {i+1}: ’))
10 print(’Vetor definido: ’, end=’’)
11 imprimeVetor(vetor)
Neste caso, como não sabemos a quantidade de elementos, tivemos que usar o laço while.
A segunda forma de entrada, mais comum em nossos exerćıcios, é a partir da entrada de todos os elementos
em uma única entrada do usuário em uma string e a chamada da função preencherVetor. No exemplo a
seguir, fazemos isso para as frutas definidas no resumo desta prática:
1 # código da função preencherVetor
2
3 frutas = ’maçã, laranja, abacaxi’
4 frutas = preencherVetor(frutas, ’str’)
5 quantidades = ’5, 3, 1’
6 quantidades = preencherVetor(quantidades, ’int’)
7 for i in range(len(frutas)):
8 print(f’− Temos {quantidades[i]} unidades de {frutas[i]}’)
Observe que os dois vetores devem possuir a mesma quantidade de elementos, fizemos um único laço for
(pois conhecemos a quantidade de elementos) para imprimir valores dos dois vetores de forma conjunta (pois
há uma relação entre eles pelo ı́ndice). É importante observar que utilizamos laços conforme a lógica da tarefa
a ser cumprida, não é por estarmos manipulando dois vetores que devemos necessariamente fazer dois laços.
3
O programa anterior pode ser generalizado, fazendo o preenchimento dos dois vetores a partir de entradas
do usuário, basta para isso substituir os valores fixados para as strings por input’s, um para cada vetor,
aproveitamos paravalidar o tamanho dos vetores:
1 # código da função preencherVetor
2
3 frutas = input(’Nomes das frutas: ’)
4 frutas = preencherVetor(frutas, ’str’)
5 quantidades = input(’Quantidades das frutas: ’)
6 quantidades = preencherVetor(quantidades, ’int’)
7 if len(frutas) == len(quantidades):
8 for i in range(len(frutas)):
9 print(f’− Temos {quantidades[i]} unidades de {frutas[i]}’)
10 else:
11 print(’ERRO: Quantidade de elementos incompatível.’)
Veja dois exemplos de execução:
Exemplo 1:
Nomes das frutas: banana, maçã, abacaxi, melão
Quantidades das frutas: 4, 10, 8, 2
− Temos 4 unidades de banana
− Temos 10 unidades de maçã
− Temos 8 unidades de abacaxi
− Temos 2 unidades de melão
Exemplo 2:
Nomes das frutas: banana, maçã, abacaxi, melão
Quantidades das frutas: 10
ERRO: Quantidade de elementos incompatível.
Implemente estes programas no Thonny e execute utilizando o depurador para entender perfeitamente o
que eles fazem em detalhes.
4
Tarefa 2: Associação de valores e ı́ndices
Como vimos, a relação entre ı́ndices e valores armazenados é muito importante na manipulação de vetores.
Eventualmente, os elementos armazenados em um vetor podem representar os ı́ndices de interesse de um outro
valor. Neste exemplo, ilustramos esta situação:
1 valores = [ 1, 5, 10, 4, 12, 6 ]
2 indices = [ 1, 4, 0, 2 ]
3 print(’Valores associados aos índices:’)
4 for i in range(len(indices)):
5 indice = indices[i]
6 valor = valores[indice]
7 print(f’Índice: {indice} >>> Valor: {valor}’)
Observe que as variáveis indice e valor, dentro do laço, são dispensáveis:
1 valores = [ 1, 5, 10, 4, 12, 6 ]
2 indices = [ 1, 4, 0, 2 ]
3 print(’Valores associados aos índices:’)
4 for i in range(len(indices)):
5 print(f’Índice: {indices[i]} >>> Valor: {valores[indices[i]]}’)
Porém, a criação das variáveis pode deixar o código mais “leǵıvel”, ou seja, mais fácil de ser compreendido.
O mais importante é observar que a utilização dos valores armazenados nos vetores e o acesso a eles por
intermédio de seus ı́ndices dependerá na natureza dos dados. Acessamos os valores do vetor valores acessando
ı́ndices obtidos pelos dados contidos no vetor indices.
Muitas vezes utilizamos algum recurso para possibilitar a manipulação de ı́ndices de acordo com alguma
regra. No exemplo a seguir criaremos um vetor que conterá os ı́ndices de valores que respeitem a uma regra
pré-definida: notas maiores do que 6. Em seguida imprimiremos os valores escolhidos.
1 # código da função preencherVetor
2
3 notas = input(’Valores das notas: ’)
4 notas = preencherVetor(notas, ’float’)
5 indices = [ ]
6 for i in range(len(notas)):
7 if notas[i] > 6: # a regra se aplica à nota, não ao índice
8 indices.append(i) # armazenamos o índice, não a nota!
9
10 print(’Notas selecionadas: ’)
11 for i in range(len(indices)):
12 print(f’− {notas[indices[i]]}’)
Observe que, após a entrada e preenchimento das notas, primeiramente processamos as notas no laço da
linha 7, neste laço, i representa ı́ndices do vetor notas, e usamos o laço para preencher o vetor indices com
os valores de i que representam notas maiores do que 6 (a regra definida).
Por outro lado, o segundo processamento tem a tarefa de imprimir apenas as notas selecionadas (que
atendem à regra). Isto é feito no laço da linha 11, onde i representa ı́ndices do vetor indices, que são usados
para permitir o acesso às notas. Neste programa a variável i é apenas uma variável auxiliar utilizada para fazer
o processamento adequado de ı́ndices dos vetores manipulados a cada tarefa, depois de usada para processar
um vetor, ela pode ser aproveitada para processar outro.
5
Veja alguns exemplos de execução:
Exemplo 1:
Valores das notas: 1, 2, 6, 6.5, 7, 7.8, 4, 5, 10
Notas selecionadas:
− 6.5
− 7.0
− 7.8
− 10.0
Exemplo 2:
Valores das notas: 1, 2, 6, 4, 5
Notas selecionadas:
Implemente estes programas no Thonny e execute utilizando o depurador para entender perfeitamente o
que eles fazem em detalhes.
6
Questão 1
Você deve implementar um programa que realiza a leitura das notas dos alunos de BCC701, preenchendo
um vetor de valores reais (sempre haverá pelo menos uma nota). A partir deste vetor, você deve imprimir as
seguintes estat́ısticas da turma: (i) maior nota; (ii) menor nota; (iii) média das notas. Para obter estes valores,
você deve implementar a função estatNotas, que recebe o vetor de notas como argumento de entrada, calcula
e retorna os três valores. Sendo assim, o seu programa principal seguirá o algoritmo:
1. Ler uma string com todos os valores do vetor;
2. Chamar a função preencherVetor (definida na Seção 7.3.3 do livro texto da disciplina);
3. Chamar a função estatNotas (implementada por você);
4. Imprimir os valores retornados pela função estatNotas no terminal (com uma casa decimal).
Exemplo 1:
Notas: 10
Maior nota: 10.0
Menor nota: 10.0
Nota média: 10.0
Exemplo 2:
Notas: 1, 2, 3, 4, 5, 6, 7, 8
Maior nota: 8.0
Menor nota: 1.0
Nota média: 4.5
Exemplo 3:
Notas: 10, 3.56, 9.9, 8.85, 7.45
Maior nota: 10.0
Menor nota: 3.6
Nota média: 8.0
7
Questão 2
Agora você vai criar uma nova versão do programa da questão 1, obtendo as notas dos alunos que estiverem
acima da nota média calculada. Para isso, você implementará uma nova função:
• acimaMedia: recebe como argumentos de entrada um vetor de notas e um valor de corte. A função cria
um novo vetor, contendo os ı́ndices dos elementos que tiverem nota maior do que o valor de corte. Dica:
crie um vetor vazio, depois avalie cada valor armazenado no vetor de entrada, se o valor em questão for
maior que a média, adicione o ı́ndice correspondente no novo vetor.
O programa passará a imprimir as notas acima da média, seguindo o algoritmo:
1. Executar os passos 1 a 4 do algoritmo da questão 1.
2. Chamar a função acimaMedia (implementada por você) passando como argumento o vetor de notas e a
média das notas obtida no passo 3 do algoritmo da questão 1, e recendo o vetor resultante;
3. Imprimir os ı́ndices das notas acima da média, chamando a função imprimeVetor (definida na Seção
7.3.5), passando como argumento o vetor obtido pela chamada à função acimaMedia.
4. Imprimir cada nota que estiver acima da média, usando o vetor de ı́ndices obtido anteriormente. Dica:
percorra todos os elementos do vetor de ı́ndices e imprima o valor correspondente no vetor de notas.
Observe que um vetor contém as notas e o outro contém os ı́ndices das notas a serem consideradas.
Exemplo 1:
Notas: 10
Maior nota: 10.0
Menor nota: 10.0
Nota média: 10.0
Índices das notas acima da média:
[ ]
Notas acima da média:
[ ]
Exemplo 2:
Notas: 1, 2, 3, 4, 5, 6, 7, 8
Maior nota: 8.0
Menor nota: 1.0
Nota média: 4.5
Índices das notas acima da média:
[ 4, 5, 6, 7 ]
Notas acima da média:
[ 5.0, 6.0, 7.0, 8.0 ]
Exemplo 3:
Notas: 10, 3.56, 9.9, 8.85, 7.45
Maior nota: 10.0
Menor nota: 3.6
Nota média: 8.0
Índices das notas acima da média:
[ 0, 2, 3 ]
Notas acima da média:
[ 10.0, 9.9, 8.8 ]
8
Questão 3
Seu programa está fazendo tanto sucesso que agora você vai aprimorá-lo ainda mais, adaptando o programa
da questão 2. Além de ler as notas dos alunos em um vetor, você também vai ler os nomes dos alunos em
um outro vetor. Para cada nota acima da média impressa no terminal, você também vai imprimir o nome do
aluno. Dica: os dois vetores – de notas e de nomes – estão associados pelos seus ı́ndices e, portanto, a nota
do primeiro aluno e seu nome estarão no ı́ndice 0 dos dois vetores, enquanto as do segundo aluno estarão no
ı́ndice 1, e assim por diante.
Exemplo 1:
Notas: 10
Nomes: João
Maior nota: 10.0
Menor nota: 10.0
Nota média: 10.0
Índices das notas acima da média:
[ ]
Notas acima da média:
[ ]
Exemplo 2:
Notas: 1, 2, 3, 4, 5, 6, 7, 8
Nomes: Baltazar, Rolando, Boneco, Zé, Cândida, Catifunda, Capitu,
Ptolomeu
Maior nota: 8.0
Menor nota: 1.0
Nota média: 4.5
Índices das notas acima da média:
[ 4, 5, 6, 7 ]
Notas acima da média:
[ 5.0 (Cândida), 6.0 (Catifunda), 7.0 (Capitu),8.0 (Ptolomeu) ]
Exemplo 3:
Notas: 10, 3.56, 9.9, 8.85, 7.45
Nomes: Batman, Coringa, Sparrow, Smeagol, Chaves
Maior nota: 10.0
Menor nota: 3.6
Nota média: 8.0
Índices das notas acima da média:
[ 0, 2, 3 ]
Notas acima da média:
[ 10.0 (Batman), 9.9 (Sparrow), 8.8 (Smeagol) ]
9
Questão 4
Chegando ao final do semestre, deve-se indicar quais alunos têm direito ao Exame Especial: aqueles com
nota entre 3 (inclusive) e 6 (exclusive). Com isso, você novamente aprimorará seu programa, implementando
a função exameEspecial, que recebe o vetor de notas como argumento de entrada e retorna um novo vetor,
contendo apenas os ı́ndices das notas que forem ≥ 3.0 e < 6.0. Você deve imprimir os ı́ndices das notas para o
Exame Especial, bem como as notas e nomes dos alunos na sáıda do terminal (no programa principal).
Exemplo 1:
Notas: 10
Nomes: João
Maior nota: 10.0
Menor nota: 10.0
Nota média: 10.0
Índices das notas acima da média:
[ ]
Notas acima da média:
[ ]
Índices das notas para Exames Especiais:
[ ]
Notas para Exames Especiais:
[ ]
Exemplo 2:
Notas: 1, 2, 3, 4, 5, 6, 7, 8
Nomes: Baltazar, Rolando, Boneco, Zé, Cândida, Catifunda, Capitu,
Ptolomeu
Maior nota: 8.0
Menor nota: 1.0
Nota média: 4.5
Índices das notas acima da média:
[ 4, 5, 6, 7 ]
Notas acima da média:
[ 5.0 (Cândida), 6.0 (Catifunda), 7.0 (Capitu), 8.0 (Ptolomeu) ]
Índices das notas para Exames Especiais:
[ 2, 3, 4 ]
Notas para Exames Especiais:
[ 3.0 (Boneco), 4.0 (Zé), 5.0 (Cândida) ]
Exemplo 3:
Notas: 10, 3.56, 9.9, 8.85, 7.45
Nomes: Batman, Coringa, Sparrow, Smeagol, Chaves
Maior nota: 10.0
Menor nota: 3.6
Nota média: 8.0
Índices das notas acima da média:
[ 0, 2, 3 ]
Notas acima da média:
[ 10.0 (Batman), 9.9 (Sparrow), 8.8 (Smeagol) ]
Índices das notas para Exames Especiais:
[ 1 ]
Notas para Exames Especiais:
[ 3.6 (Coringa) ]
10

Mais conteúdos dessa disciplina