Case Study: Class GradeBook Using a Two-Dimensional Array

Case Study Class GradeBook Using a Two Dimensional Array

In Section 7.6, we presented class GradeBook (Figs. 7.167.17), which used a one-dimensional array to store student grades on a single exam. In most semesters, students take several exams. Professors are likely to want to analyze grades across the entire semester, both for a single student and for the class as a whole.

Storing Student Grades in a Two-Dimensional Array in Class GradeBook

Figures 7.237.24 contain a version of class GradeBook that uses a two-dimensional array grades to store the grades of a number of students on multiple exams. Each row of the array represents a single student's grades for the entire course, and each column represents all the grades the students earned for one particular exam. A client program, such as fig07_25.cpp, passes the array as an argument to the GradeBook constructor. In this example, we use a ten-by-three array containing ten students' grades on three exams.

Five member functions (declared in lines 2327 of Fig. 7.23) perform array manipulations to process the grades. Each of these member functions is similar to its counterpart in the earlier one-dimensional array version of class GradeBook (Figs. 7.167.17). Member function getMinimum (defined in lines 6582 of Fig. 7.24) determines the lowest grade of any student for the semester. Member function getMaximum (defined in lines 85102 of Fig. 7.24) determines the highest grade of any student for the semester. Member function getAverage (lines 105115 of Fig. 7.24) determines a particular student's semester average. Member function outputBarChart (lines 118149 of Fig. 7.24) outputs a bar chart of the distribution of all student grades for the semester. Member function outputGrades (lines 152177 of Fig. 7.24) outputs the two-dimensional array in a tabular format, along with each student's semester average.

Figure 7.23. Definition of class GradeBook with a two-dimensional array to store grades.

(This item is displayed on pages 365 - 366 in the print version)

 1 // Fig. 7.23: GradeBook.h
 2 // Definition of class GradeBook that uses a
 3 // two-dimensional array to store test grades.
 4 // Member functions are defined in GradeBook.cpp
 5 #include  // program uses C++ Standard Library string class
 6 using std::string;
 7
 8 // GradeBook class definition
 9 class GradeBook
10 {
11 public:
12 // constants
13 const static int students = 10; // number of students
14 const static int tests = 3; // number of tests
15
16 // constructor initializes course name and array of grades
17 GradeBook( string, const int [][ tests ] );
18
19 void setCourseName( string ); // function to set the course name
20 string getCourseName(); // function to retrieve the course name
21 void displayMessage(); // display a welcome message
22 void processGrades(); // perform various operations on the grade data
23 int getMinimum(); // find the minimum grade in the grade book
24 int getMaximum(); // find the maximum grade in the grade book
25 double getAverage( const int [], const int ); // find average of grades
26 void outputBarChart(); // output bar chart of grade distribution
27 void outputGrades(); // output the contents of the grades array
28 private:
29 string courseName; // course name for this grade book
30 int grades[ students ][ tests ]; // two-dimensional array of grades
31 }; // end class GradeBook

Member functions getMinimum, getMaximum, outputBarChart and outputGrades each loop through array grades by using nested for statements For example, consider the nested for statement in member function getMinimum (lines 7079). The outer for statement begins by setting student (i.e., the row subscript) to 0, so the elements of row 0 can be compared with variable lowGrade in the body of the inner for statement. The inner for statement loops through the grades of a particular row and compares each grade with lowGrade. If a grade is less than lowGrade, lowGrade is set to that grade. The outer for statement then increments the row subscript to 1. The elements of row 1 are compared with variable lowGrade. The outer for statement then increments the row subscript to 2, and the elements of row 2 are compared with variable lowGrade. This repeats until all rows of grades have been traversed. When execution of the nested statement is complete, lowGrade contains the smallest grade in the two-dimensional array. Member function getMaximum works similarly to member function getMinimum.


Member function outputBarChart in Fig. 7.24 is nearly identical to the one in Fig. 7.17. However, to output the overall grade distribution for a whole semester, the member function uses a nested for statement (lines 127130) to create the one-dimensional array frequency based on all the grades in the two-dimensional array. The rest of the code in each of the two outputBarChart member functions that displays the chart is identical.

Figure 7.24. GradeBook class member-function definitions manipulating a two-dimensional array of grades.

(This item is displayed on pages 366 - 369 in the print version)

 1 // Fig. 7.24: GradeBook.cpp
 2 // Member-function definitions for class GradeBook that
 3 // uses a two-dimensional array to store grades.
 4 #include 
 5 using std::cout;
 6 using std::cin;
 7 using std::endl;
 8 using std::fixed;
 9
10 #include  // parameterized stream manipulators
11 using std::setprecision; // sets numeric output precision
12 using std::setw; // sets field width
13
14 // include definition of class GradeBook from GradeBook.h
15 #include "GradeBook.h"
16
17 // two-argument constructor initializes courseName and grades array
18 GradeBook::GradeBook( string name, const int gradesArray[][ tests ] )
19 {
20 setCourseName( name ); // initialize courseName
21
22 // copy grades from gradeArray to grades 
23 for ( int student = 0; student < students; student++ ) 
24 
25  for ( int test = 0; test < tests; test++ ) 
26  grades[ student ][ test ] = gradesArray[ student ][ test ];
27 } // end two-argument GradeBook constructor
28
29 // function to set the course name
30 void GradeBook::setCourseName( string name )
31 {
32 courseName = name; // store the course name
33 } // end function setCourseName
34
35 // function to retrieve the course name
36 string GradeBook::getCourseName()
37 {
38 return courseName;
39 } // end function getCourseName
40
41 // display a welcome message to the GradeBook user
42 void GradeBook::displayMessage()
43 {
44 // this statement calls getCourseName to get the
45 // name of the course this GradeBook represents
46 cout << "Welcome to the grade book for
" << getCourseName() << "!"
47 << endl;
48 } // end function displayMessage
49
50 // perform various operations on the data
51 void GradeBook::processGrades()
52 {
53 // output grades array
54 outputGrades();
55
56 // call functions getMinimum and getMaximum
57 cout << "
Lowest grade in the grade book is " << getMinimum()
58 << "
Highest grade in the grade book is " << getMaximum() << endl;
59
60 // output grade distribution chart of all grades on all tests
61 outputBarChart();
62 } // end function processGrades
63
64 // find minimum grade
65 int GradeBook::getMinimum()
66 {
67 int lowGrade = 100; // assume lowest grade is 100
68
69 // loop through rows of grades array 
70 for ( int student = 0; student < students; student++ ) 
71 { 
72  // loop through columns of current row 
73  for ( int test = 0; test < tests; test++ ) 
74  { 
75  // if current grade less than lowGrade, assign it to lowGrade
76  if ( grades[ student ][ test ] < lowGrade ) 
77  lowGrade = grades[ student ][ test ]; // new lowest grade 
78  } // end inner for 
79 } // end outer for 
80
81 return lowGrade; // return lowest grade
82 } // end function getMinimum
83
84 // find maximum grade
85 int GradeBook::getMaximum()
86 {
87 int highGrade = 0; // assume highest grade is 0
88
89 // loop through rows of grades array 
90 for ( int student = 0; student < students; student++ ) 
91 { 
92  // loop through columns of current row 
93  for ( int test = 0; test < tests; test++ ) 
94  { 
95  // if current grade greater than lowGrade, assign it to highGrade
96  if ( grades[ student ][ test ] > highGrade ) 
97  highGrade = grades[ student ][ test ]; // new highest grade 
98  } // end inner for 
99 } // end outer for 
100
101 return highGrade; // return highest grade
102 } // end function getMaximum
103
104 // determine average grade for particular set of grades
105 double GradeBook::getAverage( const int setOfGrades[], const int grades )
106 {
107 int total = 0; // initialize total
108
109 // sum grades in array
110 for ( int grade = 0; grade < grades; grade++ )
111 total += setOfGrades[ grade ];
112
113 // return average of grades
114 return static_cast< double >( total ) / grades;
115 } // end function getAverage
116
117 // output bar chart displaying grade distribution
118 void GradeBook::outputBarChart()
119 {
120 cout << "
Overall grade distribution:" << endl;
121
122 // stores frequency of grades in each range of 10 grades
123 const int frequencySize = 11;
124 int frequency[ frequencySize ] = { 0 };
125 
126 // for each grade, increment the appropriate frequency
127 for ( int student = 0; student < students; student++ )
128 
129  for ( int test = 0; test < tests; test++ ) 
130  ++frequency[ grades[ student ][ test ] / 10 ]; 
131
132 // for each grade frequency, print bar in chart
133 for ( int count = 0; count < frequencySize; count++ )
134 {
135 // output bar label ("0-9:", ..., "90-99:", "100:" )
136 if ( count == 0 )
137 cout << " 0-9: ";
138 else if ( count == 10 )
139 cout << " 100: ";
140 else
141 cout << count * 10 << "-" << ( count * 10 ) + 9 << ": ";
142
143 // print bar of asterisks
144 for ( int stars = 0; stars < frequency[ count ]; stars++ )
145 cout << '*';
146
147 cout << endl; // start a new line of output
148 } // end outer for
149 } // end function outputBarChart
150
151 // output the contents of the grades array
152 void GradeBook::outputGrades()
153 {
154 cout << "
The grades are:

";
155 cout << " "; // align column heads
156
157 // create a column heading for each of the tests
158 for ( int test = 0; test < tests; test++ )
159 cout << "Test " << test + 1 << " ";
160
161 cout << "Average" << endl; // student average column heading
162
163 // create rows/columns of text representing array grades
164 for ( int student = 0; student < students; student++ )
165 {
166 cout << "Student " << setw( 2 ) << student + 1;
167
168 // output student's grades
169 for ( int test = 0; test < tests; test++ )
170 cout << setw( 8 ) << grades[ student ][ test ];
171
172 // call member function getAverage to calculate student's average;
173 // pass row of grades and the value of tests as the arguments
174 double average = getAverage( grades[ student ], tests );
175 cout << setw( 9 ) << setprecision( 2 ) << fixed << average << endl;
176 } // end outer for
177 } // end function outputGrades

Member function outputGrades (lines 152177) also uses nested for statements to output values of the array grades, in addition to each student's semester average. The output in Fig. 7.25 shows the result, which resembles the tabular format of a professor's physical grade book. Lines 158159 print the column headings for each test. We use a counter-controlled for statement so that we can identify each test with a number. Similarly, the for statement in lines 164176 first outputs a row label using a counter variable to identify each student (line 166). Although array indices start at 0, note that lines 159 and 166 output test + 1 and student + 1, respectively, to produce test and student numbers starting at 1 (see Fig. 7.25). The inner for statement in lines 169170 uses the outer for statement's counter variable student to loop through a specific row of array grades and output each student's test grade. Finally, line 174 obtains each student's semester average by passing the current row of grades (i.e., grades[ student ]) to member function getAverage.


Figure 7.25. Creates a GradeBook object using a two-dimensional array of grades, then invokes member function processGrades to analyze them.

(This item is displayed on pages 370 - 371 in the print version)

 1 // Fig. 7.25: fig07_25.cpp
 2 // Creates GradeBook object using a two-dimensional array of grades.
 3
 4 #include "GradeBook.h" // GradeBook class definition
 5
 6 // function main begins program execution
 7 int main()
 8 {
 9 // two-dimensional array of student grades
10 int gradesArray[ GradeBook::students ][ GradeBook::tests ] =
11 { { 87, 96, 70 },
12 { 68, 87, 90 },
13 { 94, 100, 90 },
14 { 100, 81, 82 },
15 { 83, 65, 85 },
16 { 78, 87, 65 },
17 { 85, 75, 83 },
18 { 91, 94, 100 },
19 { 76, 72, 84 },
20 { 87, 93, 73 } };
21
22 GradeBook myGradeBook(
23 "CS101 Introduction to C++ Programming", gradesArray );
24 myGradeBook.displayMessage();
25 myGradeBook.processGrades();
26 return 0; // indicates successful termination
27 } // end main
 
 Welcome to the grade book for
 CS101 Introduction to C++ Programming!

 The grades are:

 Test 1 Test 2 Test 3 Average
 Student 1 87 96 70 84.33
 Student 2 68 87 90 81.67
 Student 3 94 100 90 94.67
 Student 4 100 81 82 87.67
 Student 5 83 65 85 77.67
 Student 6 78 87 65 76.67
 Student 7 85 75 83 81.00
 Student 8 91 94 100 95.00
 Student 9 76 72 84 77.33
 Student 10 87 93 73 84.33

 Lowest grade in the grade book is 65
 Highest grade in the grade book is 100

 Overall grade distribution:
 0-9:
 10-19:
 20-29:
 30-39:
 40-49:
 50-59:
 60-69: ***
 70-79: ******
 80-89: ***********
 90-99: *******
 100: ***
 

Member function getAverage (lines 105115) takes two argumentsa one-dimensional array of test results for a particular student and the number of test results in the array. When line 174 calls getAverage, the first argument is grades[ student ], which specifies that a particular row of the two-dimensional array grades should be passed to getAverage. For example, based on the array created in Fig. 7.25, the argument grades[ 1 ] represents the three values (a one-dimensional array of grades) stored in row 1 of the two-dimensional array grades. A two-dimensional array can be considered an array whose elements are one-dimensional arrays. Member function getAverage calculates the sum of the array elements, divides the total by the number of test results and returns the floating-point result as a double value (line 114).


Testing Class GradeBook

The program in Fig. 7.25 creates an object of class GradeBook (Figs. 7.237.24) using the two-dimensional array of ints named gradesArray (declared and initialized in lines 1020). Note that line 10 accesses class GradeBook's static constants students and tests to indicate the size of each dimension of array gradesArray. Lines 2223 pass a course name and gradesArray to the GradeBook constructor. Lines 2425 then invoke myGradeBook's displayMessage and processGrades member functions to display a welcome message and obtain a report summarizing the students' grades for the semester, respectively.





C++ How to Program
C++ How to Program (5th Edition)
ISBN: 0131857576
EAN: 2147483647
Year: 2004
Pages: 627
Simiral book on Amazon

Flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net