6.5. GradeBook Case Study: Select...Case Multiple-Selection StatementChapter 5 presented the If...Then single-selection statement and the If...Then...Else double-selection statement. Occasionally, an algorithm contains a series of decisions that test a variable or expression separately for each value that the variable or expression might assume. The algorithm then takes different actions based on those values. Visual Basic provides the Select...Case multiple-selection statement to handle such decision making. GradeBook Class with Select...Case Statement to Count A, B, C, D and F Grades.Figure 6.9 contains an enhanced version of the GradeBook class introduced in Chapter 4 and further developed in Chapter 5. The new version not only calculates the average of a set of numeric grades entered by the user, but uses a Select...Case statement to determine whether each grade is the equivalent of an A, B, C, D or F and to increment the appropriate grade counter. The class also displays a summary of the number of students who received each grade. An extra counter is used to display the number of students who received a perfect score of 100 on the exam. Figure 6.10 shows a sample execution of the GradeBookTest module that uses an object of class GradeBook to process a set of grades. Figure 6.9. GradeBook class uses Select...Case statement to count A, B, C, D and F grades.
Figure 6.10. GradeBookTest creates a GradeBook object and invokes its methods.
Like earlier versions of the class, class GradeBook (Fig. 6.9) declares instance variable courseNameValue (line 4) and contains property CourseName (lines 2241) and method DisplayMessage (lines 4447), which access the course name and display a welcome message to the user, respectively. The class also contains a constructor (lines 1618) that initializes the course name. This version of class GradeBook declares instance variables total (line 5) and gradeCounter (line 6), which keep track of the sum of the grades entered by the user and the number of grades entered, respectively. Lines 711 declare counter variables for each grade category. Line 12 declares perfectScoreCount, a counter for the number of students who received a perfect score of 100 on the exam. The class maintains total, gradeCounter and the six counters as instance variables so that they can be used or modified in any of the class's methods. Note that the class's constructor (lines 1618) sets only the course name; the remaining instance variables are Integers and are initialized to 0 by default. This version of class GradeBook contains three additional methodsInputGrades, IncrementLetterGradeCounter and DisplayGradeReport. Method InputGrades (lines 5068) reads an arbitrary number of integer grades from the user using sentinel-controlled repetition and updates instance variables total and gradeCounter. The method calls method IncrementLetterGradeCounter (lines 7187) to update the appropriate lettergrade counter for each grade entered. Note that method IncrementLetterGradeCounter is declared Privatewe will discuss why later in the section. Method DisplayGradeReport (lines 90113) outputs a report containing the total of all the grades entered, the average of the grades, the number of students who received each letter grade and the number of students who received a perfect score. Let's examine these methods in more detail. Lines 5153 in method InputGrades prompt the user to enter a grade, which is assigned to variable grade. In this example, we are using any negative number as a sentinel. The While statement (lines 5667) executes if there is more data to input (i.e., if the grade is not a sentinel value). Line 57 adds grade to total. Line 58 increments gradeCounter. The DisplayGradeReport method uses these variables to compute the average. Line 61 calls method IncrementLetterGradeCounter to increment the appropriate letter-grade counter based on the numeric grade entered. Lines 6466 prompt the user and input the next grade. Method IncrementLetterGradeCounter uses a Select...Case statement (lines 7286) to determine which counter to increment. In this example, we assume that the user enters a valid grade in the range 0100. A grade in the range 90100 represents an A, 80 89 represents a B, 7079 represents a C, 6069 represents a D and 059 represents an F. Line 72 Select Case grade begins the Select...Case statement. The expression following the keywords Select Case (in this case, grade) is called the controlling expression. The controlling expression is compared sequentially with each Case. If a matching Case is found, the code in the Case executes, then program control proceeds to the first statement after the Select...Case statement (line 87). Common Programming Error 6.3
The first Case statement (line 73) determines whether the value of grade is equal to 100. If this is true, the statements in lines 7475 execute, incrementing both aCount (because a grade of 100 is an A) and perfectScoreCount. Note that a Case statement can specify multiple actionsin this case, incrementing both aCount and perfectScoreCount. The next Case statement (line 76) determines whether grade is between 90 and 99 inclusive. In this case, only aCount is incremented (line 77). Keyword To specifies the range; lines 7883 use this keyword to present a series of similar Cases. Each case increments the appropriate counter. Common Programming Error 6.4
If no match occurs between the controlling expression's value and a Case label, the optional Case Else (lines 8485) executes. We use the Case Else in this example to process all controlling-expression values that are less than 60, that is, all failing grades. If no match occurs and the Select...Case does not contain a Case Else, program control simply continues with the first statement after the Select...Case. Case Else commonly is used to deal with invalid input. When employed, the Case Else must be the last Case. The required End Select keywords terminate the Select...Case statement. Note that the body parts of the Select...Case statement are indented to emphasize structure and improve program readability. Error-Prevention Tip 6.4
Types of Case StatementsCase statements also can use relational operators to determine whether the controlling expression satisfies a condition. For example Case Is < 0 uses keyword Is along with the relational operator, <, to test for values less than 0. Multiple values can be tested in a Case statement where the values are separated by commas, as in Case 0, 5 To 9 which tests for the value 0 or values in the range 59. GradeBookTest Module That Demonstrates Class GradeBookModule GradeBookTest (Fig. 6.10) creates a GradeBook object (line 7). Line 9 invokes the object's DisplayMessage method to output a welcome message to the user. Line 10 invokes the object's InputGrades method to read grades from the user and keep track of the sum of all the grades entered and the number of grades. Recall that method InputGrades also calls method IncrementLetterGradeCounter to keep track of the number of students who received each letter grade. Line 11 invokes method DisplayGradeReport of class GradeBook, which outputs a report based on the grades entered (as in the sample execution in Fig. 6.10). Line 94 of class GradeBook (Fig. 6.9) determines whether the user entered at least one gradethis helps us avoid dividing by zero. If so, line 96 calculates the average of the grades. Lines 99109 then output the totals of all the grades, the class average, the number of students who received each letter grade and the number of students who received a perfect score. If no grades were entered, line 111 outputs an appropriate message. Note that module GradeBookTest (Fig. 6.10) does not directly call GradeBook method IncrementLetterGradeCounter (lines 7187 of Fig. 6.9). This method is used exclusively by method InputGrades of class GradeBook to update the appropriate lettergrade counter as each new grade is entered by the user. Method IncrementLetterGradeCounter exists solely to support the operation of class GradeBook's other methods and thus is declared Private. Methods declared Private can be called only by other members of the class in which the Private methods are declared. Such Private methods are commonly referred to as utility methods or helper methods. Using the With StatementThe With statement allows you to make multiple references to the same object in a concise manner. For example, we can replace lines 911 of Fig. 6.10 (which all reference the same object, gradeBook1) with With gradeBook1 .DisplayMessage() ' display welcome message .InputGrades() ' read grades from user .DisplayGradeReport() ' display report based on grades End With These lines of code are collectively known as a With statement block. At the beginning of the block, we specify the object (gradeBook1) that we will be using in the block. The With statement allows you to access an object's members in the block without having to specify the name of the object before the dot separator, e.g., .DisplayMessage() instead of gradeBook1.DisplayMessage(). Select...Case Statement UML Activity DiagramFigure 6.11 shows the UML activity diagram for the general Select...Case statement. Again, note that (besides an initial state, transition arrows, merges, a final state and several notes) the diagram contains only action states and decisions. Figure 6.11. Select...Case multiple-selection statement UML activity diagram.
In Chapter 11, Object-Oriented Programming: Polymorphism, we present a more elegant method of implementing multiple-selection logic. We use a technique called polymorphism to create programs that are often clearer, more manageable, and easier to extend than programs that use Select...Case logic. |