We now present the first version of a GradeBook
class that instructors can use to maintain students’ grades on an exam and display a grade report that includes the grades, class average, lowest grade, highest grade and a grade distribution bar chart. The version of class GradeBook
presented in this section stores the grades for one exam in a one-dimensional array. In Section 8.10, we present a second version of class GradeBook
that uses a two-dimensional array to store students’ grades for several exams.
array
in Class GradeBook
Figure 8.14 shows the output that summarizes the 10 grades we store in an object of class GradeBook
(Fig. 8.15), which uses an array
of integers to store the grades of 10 students for a single exam. The array grades
is declared as an instance variable in line 7 of Fig. 8.15—therefore, each GradeBook
object maintains its own set of grades.
The constructor (lines 14–18) receives the name of the course and an array of grades. When an app (e.g., class GradeBookTest
in Fig. 8.16) creates a GradeBook
object, the app passes an existing int
array to the constructor, which assigns the array’s reference to instance variable grades
(Fig. 8.15, line 17). The size of grades
is determined by the class that passes the array to the constructor. Thus, a GradeBook
can process a variable number of grades—as many as are in the array in the caller. The grade values in the passed array could have been input from a user at the keyboard or read from a file on disk (as discussed in Chapter 17). In our test app, we simply initialize an array with a set of grade values (Fig. 8.16, line 9). Once the grades are stored in instance variable grades
of class GradeBook
, all the class’s methods can access the elements of grades
as needed to perform various calculations.
ProcessGrades
and OutputGrades
Method ProcessGrades
(Fig. 8.15, lines 29–43) contains a series of method calls that result in the output of a report summarizing the grades. Line 32 calls method OutputGrades
to display the contents of array grades
. Lines 139–143 in method OutputGrades
use a for
statement to output the student grades. We use a for
statement, rather than a foreach
, because lines 141–142 use counter variable student
’s value to output each grade next to a particular student number (see Fig. 8.14). Although array indices start at 0, an instructor would typically number students starting at 1. Thus, lines 141–142 output student + 1
as the student number to produce grade labels "Student 1: "
, "Student 2: "
and so on.
GetAverage
Method ProcessGrades
next calls method GetAverage
(line 35) to obtain the average of the grades in the array. Method GetAverage
(lines 82–94) uses a foreach
statement to total the values in array grades
before calculating the average. The iteration variable in the foreach
’s header indicates that for each iteration, grade
takes on a value in array grades
. The average calculation in line 93 uses grades.Length
to determine the number of grades being averaged. Note that we initialized total as a double
(0.0
), so no cast is necessary.
GetMinimum
and GetMaximum
Lines 38–39 in method ProcessGrades
call methods GetMinimum
and GetMaximum
to determine the lowest and highest grades of any student on the exam, respectively. Each of these methods uses a foreach
statement to loop through array grades
. Lines 51–58 in method GetMinimum
loop through the array, and lines 54–57 compare each grade to lowGrade
. If a grade is less than lowGrade
, lowGrade
is set to that grade. When line 60 executes, lowGrade
contains the lowest grade in the array. Method GetMaximum
(lines 64– 79) works the same way as method GetMinimum
.
OutputBarChart
Finally, line 42 in method ProcessGrades
calls method OutputBarChart
to display a distribution chart of the grade data, using a technique similar to that in Fig. 8.7. In that example, we manually calculated the number of grades in each category (i.e., 0–9, 10–19, …, 90–99 and 100) by simply looking at a set of grades. In this example, lines 102–108 use a technique similar to that in Figs. 8.8 and 8.9 to calculate the frequency of grades in each category. Line 102 declares variable frequency
and initializes it with an array of 11 int
s to store the frequency of grades in each grade category. For each grade
in array grades
, lines 105–108 increment the appropriate element of the frequency
array. To determine which element to increment, line 107 divides the current grade
by 10, using integer division. For example, if grade
is 85
, line 107 increments frequency[8]
to update the count of grades in the range 80–89. Lines 111–130 next display the bar chart (see Fig. 8.7) based on the values in array frequency
. Like lines 27–30 of Fig. 8.7, lines 124–127 of Fig. 8.15 use a value in array frequency
to determine the number of asterisks to display in each bar.
GradeBookTest
That Demonstrates Class GradeBook
Lines 11–12 of Fig. 8.16 create an object of class GradeBook
(Fig. 8.15) using int
array gradesArray
(declared and initialized in line 9 of Fig. 8.16). Line 13 displays a welcome message, and line 14 invokes the GradeBook
object’s ProcessGrades
method. The output reveals the summary of the 10 grades in myGradeBook
.
A test harness (or test app) creates an object of the class to test and provides it with data, which could be placed directly into an array with an array initializer, come from the user at the keyboard or come from a file (as you’ll see in Chapter 17). After initializing an object, the test harness uses the object’s members to manipulate the data. Gathering data in the test harness like this allows the class to manipulate data from several sources.