Trilhas
/
C++
C++
/
Exercícios
/
Atribuindo notas
Atribuindo notas

Atribuindo notas

Exercício de aprendizagem

Introdução

Arrays e vectors

O C++ oferece diferentes contêineres para armazenar elementos do mesmo tipo de forma ordenada. Existe o std::array para contêineres de tamanho fixo e o std::vector, que vem com recursos de redimensionamento dinâmico.

Construção

Quando você declara um array ou um vector, precisa especificar o tipo dos elementos que esse contêiner vai armazenar. Arrays também precisam de um tamanho. Veja estes exemplos para ver a inicialização dos dois tipos de contêiner:

#include <array>
#include <string>

// std::array<element_type, size> variable_name {list of elements}
std::array<std::string, 3> indie_rock {"yeah", "yeah", "yeah"};
// indie_rock contains the elements "yeah" three times

Vectors geralmente precisam de mais espaço, já que alocam memória para crescimento futuro. Você não precisa especificar um tamanho:

#include <vector>

// std::vector<element_type> variable_name {list of elements}
std::vector<int> countdown {3, 2, 1};
// countdown contains the elements 3, 2 and 1

Nota: você ainda não precisa conhecer a mecânica exata por trás do conceito de template, ele terá seu próprio conceito mais adiante na árvore do syllabus.

Acesso aos elementos

Vectors e arrays compartilham as mesmas funções para acessar seus elementos. Você pode usar as funções membro front e back para obter o primeiro e o último elemento do contêiner. Também existem at e o operador [] para acessar elementos específicos.

countdown[0];
// => 3
countdown.at(2);
// => 1
countdown[1] = 4;
// countdown now contains 3, 4 and 1
indie_rock.back() = "yeahs";
// indie_rock is now "yeah", "yeah", "yeahs"

Nota: se você escolher uma posição que não está no intervalo do seu contêiner, o [] pode levar a um comportamento indefinido. A função at lançaria uma exceção, o que pode facilitar sua vida a longo prazo.

Modificadores de vector

Como o vector não tem tamanho fixo, é possível adicionar ou remover elementos. Duas funções comuns para isso são emplace_back e pop_back.

std::vector<std::string> witches {"Holly", "Alyssa", "Shannen"};
witches.pop_back();
// Shannen is no longer with the witches
witches.emplace_back("Rose");
// Rose has joined the team

Capacidade

Você pode verificar se os contêineres estão vazios com a função membro empty. Se quiser saber o número de elementos, pode usar size.

Instruções

Você é um assistente de ensino corrigindo as provas dos alunos. Manter o controle dos resultados manualmente está ficando cada vez mais cansativo e sujeito a erros. Você decide tornar as coisas um pouco mais interessantes montando algumas funções para contar e calcular os resultados da turma.

1. Arredondando as notas

Você até pode dar "crédito parcial" nas questões da prova, mas as notas gerais precisam ser ints. Então, antes de fazer qualquer outra coisa com as notas da turma, você precisa percorrer as notas e transformar qualquer nota double em int.

Crie a função round_down_scores() que recebe um vector de student_scores. O arredondamento pedido pelas escolas é um truncamento. Sorte sua que o C++ consegue converter um tipo em outro com static_cast. A conversão de double para int com static_cast corta qualquer dígito depois da casa decimal. Essa função deve receber o vector de entrada e return um novo vector com todas as notas convertidas para ints.

std::vector<double> student_scores {90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3};
round_down_scores(student_scores)
// => {90, 40, 55, 70, 30, 25, 80, 95, 38, 40}

Existem outros métodos que chegam ao mesmo resultado, mas um cast é algo bem comum de se ver.

int new_PI{static_cast<int>(3.14) + static_cast<int>(0.001592653589)};
// new_PI is 3.

2. Alunos que não passaram

Enquanto você corrigia a prova, percebeu que alguns alunos não estavam indo tão bem quanto você esperava. Mas você se distraiu e esqueceu de anotar exatamente quantos alunos.

Crie a função count_failed_students() que recebe um vector de student_scores. Essa função deve contar quantos alunos não atingiram a nota de aprovação e retornar essa contagem como um número inteiro. Um aluno precisa de uma nota maior que 40 para ser aprovado na prova.

count_failed_students({90,40,55,70,30,25,80,95,38,40});
// => 5

3. Calculando os conceitos

O professor que você auxilia gosta de atribuir conceitos, além das notas numéricas. Como é raro um aluno tirar 100 numa prova, os limites inferiores dos "conceitos" são calculados com base na maior nota obtida, e aumentam de forma uniforme entre a maior nota e o limite de reprovação de <= 40.

Crie a função letter_grades() que recebe a maior nota da prova como parâmetro e retorna um array (não um vector) com os limites inferiores de nota para cada intervalo de conceito "estilo americano": ["D", "C", "B", "A"].

/*Where the highest score is 100, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 55
 56 <= "C" <= 70
 71 <= "B" <= 85
 86 <= "A" <= 100
*/

letter_grades(100);
// => {41, 56, 71, 86}


/*Where the highest score is 88, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 52
 53 <= "C" <= 64
 65 <= "B" <= 76
 77 <= "A" <= 88
*/

letter_grades(88);
// => {41, 53, 65, 77}

4. Relacionando nomes às notas

Você tem as notas da prova em ordem decrescente e os respectivos nomes dos alunos (ordenados na mesma ordem das notas). Você quer relacionar o nome de cada aluno com a nota da prova e imprimir um ranking geral da turma.

Crie a função student_ranking() com os parâmetros student_scores e student_names. Relacione cada nome de aluno no vector student_names com a nota dele no vector student_scores. Você pode assumir que cada vector de argumento está ordenado da maior nota para a menor. A função deve retornar um vector de strings no formato <rank>. <student name>: <student score>.

std::vector<int> student_scores {100, 99, 90, 84, 66, 53, 47};
std::vector<std::string> student_names {"Joci", "Sara","Kora","Jan","Indra","Bern", "Fred"};
student_ranking(student_scores, student_names)
// =>
//  {"1. Joci: 100", "2. Sara: 99", "3. Kora: 90", "4. Jan: 84", "5. Indra: 66", "6. Bern: 53", "7. Fred: 47"}

5. Uma nota "perfeita"

Embora uma nota "perfeita" de 100 seja rara numa prova, é interessante saber se pelo menos um aluno conseguiu atingi-la.

Crie a função perfect_score() com os parâmetros student_scores e student_names. As listas são as mesmas da tarefa 4. A função deve return o primeiro <name> (como string) do aluno que tirou 100 na prova.

Se nenhuma nota 100 for encontrada, uma string vazia "" deve ser retornada.

perfect_score({"Nur", "Tony", "Fatima"}, {90, 80, 100});
// => "Fatima"

perfect_score({"Nur", "Tony"}, {90, 80});
// => ""
Editar via GitHub O link abre em uma nova janela ou aba
C++ Exercism

Tudo pronto para começar Atribuindo notas?

Crie sua conta no Exercism para aprender e dominar C++ com 19 conceitos100 exercícios e mentoria humana de verdade, tudo de graça.