Case Study: Class GradeBook Using a Two-Dimensional Array
Case Study Class GradeBook Using a Two Dimensional Array
In Section 7.8, we presented class GradeBook (Fig. 7.14), 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
Figure 7.18 contains 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 a grade on one of the exams the students took during the course. An application such as GradeBookTest (Fig. 7.19) 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 methods perform array manipulations to process the grades. Each method is similar to its counterpart in the earlier one-dimensional array version of class GradeBook (Fig. 7.14). Method getMinimum (lines 5270) determines the lowest grade of any student for the semester. Method getMaximum (lines 7391) determines the highest grade of any student for the semester. Method getAverage (lines 94104) determines a particular student's semester average. Method outputBarChart (lines 107137) outputs a bar chart of the distribution of all student grades for the semester. Method outputGrades (lines 140164) outputs the two-dimensional array in a tabular format, along with each student's semester average.
Figure 7.18. GradeBook class using a two-dimensional array to store grades.
(This item is displayed on pages 316 - 319 in the print version)
1 // Fig. 7.18: GradeBook.java 2 // Grade book using a two-dimensional array to store grades. 3 4 public class GradeBook 5 { 6 private String courseName; // name of course this grade book represents 7 private int grades[][]; // two-dimensional array of student grades 8 9 // two-argument constructor initializes courseName and grades array 10 public GradeBook( String name, int gradesArray[][] ) 11 { 12 courseName = name; // initialize courseName 13 grades = gradesArray; // store grades 14 } // end two-argument GradeBook constructor 15 16 // method to set the course name 17 public void setCourseName( String name ) 18 { 19 courseName = name; // store the course name 20 } // end method setCourseName 21 22 // method to retrieve the course name 23 public String getCourseName() 24 { 25 return courseName; 26 } // end method getCourseName 27 28 // display a welcome message to the GradeBook user 29 public void displayMessage() 30 { 31 // getCourseName gets the name of the course 32 System.out.printf( "Welcome to the grade book for %s! ", 33 getCourseName() ); 34 } // end method displayMessage 35 36 // perform various operations on the data 37 public void processGrades() 38 { 39 // output grades array 40 outputGrades(); 41 42 // call methods getMinimum and getMaximum 43 System.out.printf( " %s %d %s %d ", 44 "Lowest grade in the grade book is", getMinimum(), 45 "Highest grade in the grade book is", getMaximum() ); 46 47 // output grade distribution chart of all grades on all tests 48 outputBarChart(); 49 } // end method processGrades 50 51 // find minimum grade 52 public int getMinimum() 53 { 54 // assume first element of grades array is smallest 55 int lowGrade = grades[ 0 ][ 0 ]; 56 57 // loop through rows of grades array 58 for ( int studentGrades[] : grades ) 59 { 60 // loop through columns of current row 61 for ( int grade : studentGrades ) 62 { 63 // if grade less than lowGrade, assign it to lowGrade 64 if ( grade < lowGrade ) 65 lowGrade = grade; 66 } // end inner for 67 } // end outer for 68 69 return lowGrade; // return lowest grade 70 } // end method getMinimum 71 72 // find maximum grade 73 public int getMaximum() 74 { 75 // assume first element of grades array is largest 76 int highGrade = grades[ 0 ][ 0 ]; 77 78 // loop through rows of grades array 79 for ( int studentGrades[] : grades ) 80 { 81 // loop through columns of current row 82 for ( int grade : studentGrades ) 83 { 84 // if grade greater than highGrade, assign it to highGrade 85 if ( grade > highGrade ) 86 highGrade = grade; 87 } // end inner for 88 } // end outer for 89 90 return highGrade; // return highest grade 91 } // end method getMaximum 92 93 // determine average grade for particular set of grades 94 public double getAverage( int setOfGrades[] ) 95 { 96 int total = 0; // initialize total 97 98 // sum grades for one student 99 for ( int grade : setOfGrades ) 100 total += grade; 101 102 // return average of grades 103 return (double) total / setOfGrades.length; 104 } // end method getAverage 105 106 // output bar chart displaying overall grade distribution 107 public void outputBarChart() 108 { 109 System.out.println( "Overall grade distribution:" ); 110 111 // stores frequency of grades in each range of 10 grades 112 int frequency[] = new int [ 11 ]; 113 114 // for each grade in GradeBook, increment the appropriate frequency 115 for ( int studentGrades[] : grades ) 116 { 117 for ( int grade : studentGrades ) 118 ++frequency[ grade / 10 ]; 119 } // end outer for 120 121 // for each grade frequency, print bar in chart 122 for ( int count = 0; count < frequency.length; count++ ) 123 { 124 // output bar label ( "00-09: ", ..., "90-99: ", "100: " ) 125 if ( count == 10 ) 126 System.out.printf( "%5d: ", 100 ); 127 else 128 System.out.printf( "%02d-%02d: ", 129 count * 10, count * 10 + 9 ); 130 131 // print bar of asterisks 132 for ( int stars = 0; stars < frequency[ count ]; stars++ ) 133 System.out.print( "*" ); 134 135 System.out.println(); // start a new line of output 136 } // end outer for 137 } // end method outputBarChart 138 139 // output the contents of the grades array 140 public void outputGrades() 141 { 142 System.out.println( "The grades are: " ); 143 System.out.print( " " ); // align column heads 144 145 // create a column heading for each of the tests 146 for ( int test = 0; test < grades[ 0 ].length; test++ ) 147 System.out.printf( "Test %d ", test + 1 ); 148 149 System.out.println( "Average" ); // student average column heading 150 151 // create rows/columns of text representing array grades 152 for ( int student = 0; student < grades.length; student++ ) 153 { 154 System.out.printf( "Student %2d", student + 1 ); 155 156 for ( int test : grades[ student ] ) // output student's grades 157 System.out.printf( "%8d", test ); 158 159 // call method getAverage to calculate student's average grade; 160 // pass row of grades as the argument to getAverage 161 double average = getAverage( grades[ student ] ); 162 System.out.printf( "%9.2f ", average ); 163 } // end outer for 164 } // end method outputGrades 165 } // end class GradeBook |
Figure 7.19. Creates GradeBook object using a two-dimensional array of grades, then invokes method processGrades to analyze them.
(This item is displayed on pages 321 - 322 in the print version)
1 // Fig. 7.19: GradeBookTest.java 2 // Creates GradeBook object using a two-dimensional array of grades. 3 4 public class GradeBookTest 5 { 6 // main method begins program execution 7 public static void main( String args[] ) 8 { 9 // two-dimensional array of student grades 10 int gradesArray[][] = { { 87, 96, 70 }, 11 { 68, 87, 90 }, 12 { 94, 100, 90 }, 13 { 100, 81, 82 }, 14 { 83, 65, 85 }, 15 { 78, 87, 65 }, 16 { 85, 75, 83 }, 17 { 91, 94, 100 }, 18 { 76, 72, 84 }, 19 { 87, 93, 73 } }; 20 21 GradeBook myGradeBook = new GradeBook( 22 "CS101 Introduction to Java Programming", gradesArray ); 23 myGradeBook.displayMessage(); 24 myGradeBook.processGrades(); 25 } // end main 26 } // end class GradeBookTest
|
Methods getMinimum, getMaximum, outputBarChart and outputGrades each loop through array grades by using nested for statementsfor example, the nested enhanced for statement from the declaration of method getMinimum (lines 5867). The outer enhanced for statement iterates through the two-dimensional array grades, assigning successive rows to parameter studentGrades on successive iterations. The square brackets following the parameter name indicate that studentGrades refers to a one-dimensional int arraynamely, a row in array grades containing one student's grades. To find the lowest overall grade, the inner for statement compares the elements of the current one-dimensional array studentGrades to variable lowGrade. For example, on the first iteration of the outer for, row 0 of grades is assigned to parameter studentGrades. The inner enhanced for statement then loops through studentGrades and compares each grade value with lowGrade. If a grade is less than lowGrade, lowGrade is set to that grade. On the second iteration of the outer enhanced for statement, row 1 of grades is assigned to studentGrades, and the elements of this row 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 lowest grade in the two-dimensional array. Method getMaximum works similarly to method getMinimum.
Method outputBarChart in Fig. 7.18 is nearly identical to the one in Fig. 7.14. However, to output the overall grade distribution for a whole semester, the method here uses a nested enhanced for statement (lines 115119) 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 methods that displays the chart is identical.
Method outputGrades (lines 140164) 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.19 shows the result, which resembles the tabular format of a professor's physical grade book. Lines 146147 print the column headings for each test. We use a counter-controlled for statement here so that we can identify each test with a number. Similarly, the for statement in lines 152163 first outputs a row label using a counter variable to identify each student (line 154). Although array indices start at 0, note that lines 147 and 154 output test + 1 and student + 1, respectively, to produce test and student numbers starting at 1 (see Fig. 7.19). The inner for statement in lines 156157 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. Note that an enhanced for statement can be nested in a counter-controlled for statement, and vice versa. Finally, line 161 obtains each student's semester average by passing the current row of grades (i.e., grades[ student ]) to method getAverage.
Method getAverage (lines 94104) takes one argumenta one-dimensional array of test results for a particular student. When line 161 calls getAverage, the 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.19, the argument grades[ 1 ] represents the three values (a one-dimensional array of grades) stored in row 1 of the two-dimensional array grades. Remember that a two-dimensional array is an array whose elements are one-dimensional arrays. Method 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 103).
Class GradeBookTest That Demonstrates Class GradeBook
The application in Fig. 7.19 creates an object of class GradeBook (Fig. 7.18) using the two-dimensional array of ints named gradesArray (declared and initialized in lines 1019). Lines 2122 pass a course name and gradesArray to the GradeBook constructor. Lines 2324 then invoke myGradeBook's displayMessage and processGrades methods to display a welcome message and obtain a report summarizing the students' grades for the semester, respectively.