# Exercise 7-2

Extend the program in S4.2.3/64 to assign letter grades by ranges:

A 90-100
B 80-89.99...
C 70-79.99...
D 60-69.99...
F < 60


# Solution

The strategy:

1. Make a copy of the entire projects from Solution to Exercise 4-0. (i.e. the sample programs in Chapter 4 of the textbook).
3. In the main program, use the getletterGrade function to compute the student’s string letterGrade. Have an associative array letterGradeCount that maps a string (letter grade) to integer (to keep track of letter grade occurrences).

## The Program

Here summarises the entire Code::Block Project, including the header and source files.

### Source Files

#### main.cpp


#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#include <map>
#include "Student_info.h"

using std::cin;
using std::cout;
using std::endl;
using std::domain_error;
using std::max;
using std::setprecision;
using std::sort;
using std::streamsize;
using std::string;
using std::vector;
using std::map;

int main()
{
vector<Student_info> students;
Student_info record;
string::size_type maxlen = 0;   // the length of the longest name

// read and store all the student's data.
// Invariant:   students contain all the student records read so far
//              maxlen contains the length of the longest name in students
{
// find the length of longest name
maxlen = max(maxlen, record.name.size());
students.push_back(record);
}

// alphabetize the student records
sort(students.begin(), students.end(), compare);

// write the names and grades
for (vector<Student_info>::size_type i = 0;
i != students.size(); ++i)
{
//write the name, padded on teh right to maxlen + 1 characters
cout << students[i].name
<< string(maxlen + 1 - students[i].name.size(), ' ');

try
{
streamsize prec = cout.precision();
<< setprecision(prec) << " (" << letterGrade << ")";
}
catch (domain_error e)
{
cout << e.what();
}
cout << endl;
}
cout << "\nLetter Grade Summary" << endl;
for (map<string, int>::const_iterator i = letterGradeCount.begin();
cout << i->first << ": " << i->second << endl;

return 0;
}




#include <string>

using std::string;

// (For Exercise 7-2)

string ret;

ret = "A";
ret = "B";
ret = "C";
ret = "D";
else
ret = "F";

return ret;
}




#include <stdexcept>
#include <vector>
#include "median.h"
#include "Student_info.h"

using std::domain_error;
using std::vector;

// definitions for the grade functions from S4.1/52, S4.1.2/54, S4.2.2/63

// compute a student's overall grade from midterm and final exam
double grade(double midterm, double final, double homework)
{
return 0.2 * midterm + 0.4 * final + 0.4 * homework;
}

// compute a student's overall grade from midterm and final exam grades
// and vector of homework grades.
// this function does not copy its argument, because median (function) does it for us.
// (S4.1.2/54)
double grade(double midterm, double final, const vector<double>& hw)
{
if (hw.size() == 0)
throw domain_error("student has done no homework");
}

// this function computes the final grade for a Student_info object
// (S4.2.2/63)
{
}


#### median.cpp

// source file for the median function
#include <algorithm>
#include <stdexcept>
#include <vector>

using std::domain_error;
using std::sort;
using std::vector;

// compute the median of a vector<double>
// (S4.1.1/53)
double median(vector<double> vec)
{
typedef vector<double>::size_type vec_sz;

vec_sz size = vec.size();
if (size == 0)
throw domain_error("median of an empty vector");

sort(vec.begin(),vec.end());

vec_sz mid = size/2;

return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
}



#### Student_info.cpp


#ifndef GUARD_STUDENT_INFO_H
#define GUARD_STUDENT_INFO_H

// Student_info.h
#include <iostream>
#include <string>
#include <vector>

struct Student_info
{
std::string name;
double midterm, final;
std::vector<double> homework;
};

bool compare(const Student_info&, const Student_info&);

#endif // GUARD_STUDENT_INFO_H

</p>

#ifndef GUARD_GETLETTERGRADE_H

#include <string>





#include <vector>
#include "Student_info.h"



#### median.h

#ifndef GUARD_MEDIAN_H
#define GUARD_MEDIAN_H

// median.h - final version
#include <vector>
double median(std::vector<double>);

#endif // GUARD_MEDIAN_H



#### Student_info.h


#ifndef GUARD_STUDENT_INFO_H
#define GUARD_STUDENT_INFO_H

// Student_info.h
#include <iostream>
#include <string>
#include <vector>

struct Student_info
{
std::string name;
double midterm, final;
std::vector<double> homework;
};

bool compare(const Student_info&, const Student_info&);

#endif // GUARD_STUDENT_INFO_H



## Test Program

I test the program by submitting a list of sample student grades. The program automatically compute and display the numeric and letter grades. It also creates a letter grade summary to count occurances per letter grade.

johnny   90 90 90 90 90
jason    85 85 85 85 85
billy    82 82 82 82 82
fred     80 80 80 80 80
frank    70 70 70 70 70
jay      66 66 66 66 66
bob      60 60 60 60 60
mary     50 50 50 50 50
ann      40 40 40 40 40
bill     30 30 30 30 30
goat     10 10 10 10 10
dog      0  0  0  0  0
^Z
^Z
ann    40 (F)
bill   30 (F)
billy  82 (B)
bob    60 (D)
dog    0 (F)
frank  70 (C)
fred   80 (B)
goat   10 (F)
jason  85 (B)
jay    66 (D)
johnny 90 (A)
mary   50 (F)

A: 1
B: 3
C: 1
D: 2
F: 5



# Reference

Koenig, Andrew & Moo, Barbara E., Accelerated C++, Addison-Wesley, 2000