Case Study: GradeBook Using an Array to Store Grades

Một phần của tài liệu Visual C 2012 How to Program _ www.bit.ly/taiho123 (Trang 352 - 357)

2. When the app executes, another compiler (known as the just-in-time compiler

8.9 Case Study: GradeBook Using an Array to Store Grades

This section further evolves classGradeBook, introduced in Chapter 4 and expanded in Chapters 5–6. Recall that this class represents a grade book used by an instructor to store and analyze a set of student grades. Previous versions of the class process a set of grades entered by the user, but do not maintain the individual grade values in instance variables of the class. Thus, repeat calculations require the user to re-enter the same grades. One way to solve this problem would be to store each grade entered in an individual instance of the class. For example, we could create instance variablesgrade1,grade2, …,grade10in class

GradeBookto store 10 student grades. However, the code to total the grades and determine the class average would be cumbersome, and the class would not be able to process any more than 10 grades at a time. In this section, we solve this problem by storing grades in an array.

Storing Student Grades in an Array in ClassGradeBook

The version of classGradeBook(Fig. 8.15) presented here uses an array of integers to store the grades of several students on a single exam. This eliminates the need to repeatedly in- put the same set of grades. Variablegrades(which will refer to an array ofints) is declared as an instance variable in line 7—therefore, eachGradeBookobject maintains its own set of grades. The class’s constructor (lines 14–18) has two parameters—the name of the course and an array of grades. When an app (e.g., classGradeBookTestin Fig. 8.16) creates aGradeBookobject, the app passes an existingintarray to the constructor, which assigns the array’s reference to instance variablegrades(line 17). The size of arraygradesis de- termined by the class that passes the array to the constructor. Thus, aGradeBookobject 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

Software Engineering Observation 8.1

When a method receives a reference-type parameter by value, a copy of the object’s reference is passed. This prevents a method from overwriting references passed to that method. In the vast majority of cases, protecting the caller’s reference from modification is the desired behavior. If you encounter a situation where you truly want the called procedure to modify the caller’s reference, pass the reference-type parameter using keyword

ref—but, again, such situations are rare.

Software Engineering Observation 8.2

In C#, references to objects (including arrays) are passed to called methods. A called method receiving a reference to an object in a caller can interact with, and possibly change, the caller’s object.

variable grades of class GradeBook, all the class’s methods can access the elements of

gradesas needed to perform various calculations.

1 // Fig. 8.15: GradeBook.cs

2 // Grade book using an array to store test grades.

3 using System;

4

5 public class GradeBook 6 {

7 8

9 // auto-implemented property CourseName 10 public string CourseName { get; set; } 11

12 // two-parameter constructor initializes

13 // auto-implemented property CourseName and grades array 14 public GradeBook( string name, int[] gradesArray )

15 {

16 CourseName = name; // set CourseName to name 17

18 } // end two-parameter GradeBook constructor 19

20 // display a welcome message to the GradeBook user 21 public void DisplayMessage()

22 {

23 // auto-implemented property CourseName gets the name of course 24 Console.WriteLine( "Welcome to the grade book for\n{0}!\n",

25 CourseName );

26 } // end method DisplayMessage 27

28 // perform various operations on the data 29 public void ProcessGrades()

30 {

31 // output grades array 32

33

34 // call method GetAverage to calculate the average grade 35 Console.WriteLine( "\nClass average is {0:F}", );

36

37 // call methods GetMinimum and GetMaximum

38 Console.WriteLine( "Lowest grade is {0}\nHighest grade is {1}\n",

39 , );

40

41 // call OutputBarChart to display grade distribution chart 42

43 } // end method ProcessGrades 44

45 // find minimum grade 46 public int GetMinimum()

47 {

48 int lowGrade = grades[ 0 ]; // assume grades[ 0 ] is smallest 49

Fig. 8.15 | Grade book using an array to store test grades. (Part 1 of 3.)

private int[] grades; // array of student grades

grades = gradesArray; // initialize grades array

OutputGrades();

GetAverage()

GetMinimum() GetMaximum()

OutputBarChart();

8.9 Case Study:GradeBookUsing an Array to Store Grades 313

50 51 52 53 54 55 56 57

58 return lowGrade; // return lowest grade 59 } // end method GetMinimum

60

61 // find maximum grade 62 public int GetMaximum()

63 {

64 int highGrade = grades[ 0 ]; // assume grades[ 0 ] is largest 65

66 // loop through grades array 67 foreach ( int grade in grades )

68 {

69 // if grade greater than highGrade, assign it to highGrade 70 if ( grade > highGrade )

71 highGrade = grade; // new highest grade 72 } // end for

73

74 return highGrade; // return highest grade 75 } // end method GetMaximum

76

77 // determine average grade for test 78 public double GetAverage()

79 {

80 int total = 0; // initialize total 81

82 83 84 85

86 // return average of grades

87 return ( double ) total / grades.Length;

88 } // end method GetAverage 89

90 // output bar chart displaying grade distribution 91 public void OutputBarChart()

92 {

93 Console.WriteLine( "Grade distribution:" );

94

95 // stores frequency of grades in each range of 10 grades 96 int[] frequency = new int[ 11 ];

97 98 99 100 101

Fig. 8.15 | Grade book using an array to store test grades. (Part 2 of 3.)

// loop through grades array foreach ( int grade in grades ) {

// if grade lower than lowGrade, assign it to lowGrade if ( grade < lowGrade )

lowGrade = grade; // new lowest grade } // end for

// sum grades for one student foreach ( int grade in grades )

total += grade;

// for each grade, increment the appropriate frequency foreach ( int grade in grades )

++frequency[ grade / 10 ];

MethodProcessGrades

MethodProcessGrades(lines 29–43) contains a series of method calls that result in the output of a report summarizing the grades. Line 32 calls methodOutputGradesto display the contents of arraygrades. Lines 126–128 in methodOutputGradesuse aforstatement to output the student grades. Aforstatement, rather than aforeach, must be used in this case, because lines 127–128 use counter variablestudent’s value to output each grade next to a particular student number (see Fig. 8.16). Although array indices start at 0, an instruc- tor would typically number students starting at 1. Thus, lines 127–128 output

student + 1as the student number to produce grade labels"Student 1: ","Student 2: "

and so on.

MethodGetAverage

MethodProcessGradesnext calls methodGetAverage(line 35) to obtain the average of the grades in the array. MethodGetAverage(lines 78–88) uses aforeachstatement to to- tal the values in arraygradesbefore calculating the average. The iteration variable in the

foreach’s header (e.g., int grade) indicates that for each iteration, intvariablegrade takes on a value in arraygrades. The averaging calculation in line 87 usesgrades.Length

to determine the number of grades being averaged.

102 // for each grade frequency, display bar in chart 103 for ( int count = 0; count < frequency.Length; ++count )

104 {

105 // output bar label ( "00-09: ", ..., "90-99: ", "100: " ) 106 if ( count == 10 )

107 Console.Write( " 100: " );

108 else

109 Console.Write( "{0:D2}-{1:D2}: ", 110 count * 10, count * 10 + 9 );

111

112 // display bar of asterisks

113 for ( int stars = 0; stars < frequency[ count ]; ++stars ) 114 Console.Write( "*" );

115

116 Console.WriteLine(); // start a new line of output 117 } // end outer for

118 } // end method OutputBarChart 119

120 // output the contents of the grades array 121 public void OutputGrades()

122 {

123 Console.WriteLine( "The grades are:\n" );

124 125 126 127 128

129 } // end method OutputGrades 130 } // end class GradeBook

Fig. 8.15 | Grade book using an array to store test grades. (Part 3 of 3.)

// output each student's grade

for ( int student = 0; student < grades.Length; ++student ) Console.WriteLine( "Student {0,2}: {1,3}",

student + 1, grades[ student ] );

8.9 Case Study:GradeBookUsing an Array to Store Grades 315

MethodsGetMinimumandGetMaximum

Lines 38–39 in methodProcessGradescall methodsGetMinimumandGetMaximumto de- termine the lowest and highest grades of any student on the exam, respectively. Each of these methods uses aforeach statement to loop through arraygrades. Lines 51–56 in method GetMinimum loop through the array, and lines 54–55 compare each grade to

lowGrade. If a grade is less thanlowGrade,lowGradeis set to that grade. When line 58 executes,lowGradecontains the lowest grade in the array. MethodGetMaximum(lines 62–

75) works the same way as methodGetMinimum. MethodOutputBarChart

Finally, line 42 in methodProcessGradescalls methodOutputBarChartto display a dis- tribution chart of the grade data, using a technique similar to that in Fig. 8.6. In that ex- ample, 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 99–100 use a technique similar to that in Figs. 8.7 and 8.8 to calculate the frequency of grades in each category. Line 96 declares variablefrequencyand initializes it with an array of 11ints to store the frequency of grades in each grade category. For eachgradein arraygrades, lines 99–100 increment the appropriate element of thefrequencyarray. To determine which element to increment, line 100 divides the currentgradeby 10, using integer division. For example, ifgradeis85, line 100 incrementsfrequency[8]to update the count of grades in the range 80–89. Lines 103–117 next display the bar chart (see Fig. 8.6) based on the values in arrayfrequency. Like lines 24–25 of Fig. 8.6, lines 113–114 of Fig. 8.15 use a value in arrayfrequencyto determine the number of asterisks to display in each bar.

ClassGradeBookTestThat Demonstrates ClassGradeBook

The app of Fig. 8.16 creates an object of class GradeBook (Fig. 8.15) using int array

gradesArray (declared and initialized in line 9). Lines 11–12 pass a course name and

gradesArrayto theGradeBookconstructor. Line 13 displays a welcome message, and line 14 invokes theGradeBookobject’sProcessGradesmethod. The output reveals the sum- mary of the 10 grades inmyGradeBook.

1 // Fig. 8.16: GradeBookTest.cs

2 // Create a GradeBook object using an array of grades.

3 public class GradeBookTest 4 {

5 // Main method begins app execution 6 public static void Main( string[] args )

7 {

8 9 10

11 GradeBook myGradeBook = new GradeBook(

12 "CS101 Introduction to C# Programming", gradesArray );

13 myGradeBook.DisplayMessage();

14 myGradeBook.ProcessGrades();

15 } // end Main

16 } // end class GradeBookTest

Fig. 8.16 | Create aGradeBookobject using an array of grades. (Part 1 of 2.)

// one-dimensional array of student grades

int[] gradesArray = { 87, 68, 94, 100, 83, 78, 85, 91, 76, 87 };

Một phần của tài liệu Visual C 2012 How to Program _ www.bit.ly/taiho123 (Trang 352 - 357)

Tải bản đầy đủ (PDF)

(1.020 trang)