Reputation: 21
Coding newbie. I had a project last week that required user input of 4 grades, and then calculating the average of all 4 grades, and the average with the lowest grade dropped (already turned in btw). Requirements were a For Next loop and a Do While loop to calculate the averages. I used the For Next loop to get the total of the 4 grades and then calculated average.
Declare variables, constant, and array
Const intMAX_SUBSCRIPT As Integer = 3
Dim intGrades(intMAX_SUBSCRIPT) As Integer
Dim intTotal As Integer = 0 'holds the total of grades
Dim dblAverage As Double 'holds the average of all 4 grades
Dim intCount As Integer 'loop counter
Dim intLowest As Integer 'holds the lowest score
'assign grades to array slots
intGrades(0) = CInt(txtGrade1.Text)
intGrades(1) = CInt(txtGrade2.Text)
intGrades(2) = CInt(txtGrade3.Text)
intGrades(3) = CInt(txtGrade4.Text)
'Loop to calculate average in grades array
'get total of all grades
For intCount = 0 To (intGrades.Length - 1)
intTotal += intGrades(intCount)
Next
'use floating-point div to find average
dblAverage = intTotal / intGrades.Length
This worked as it should. I then used the following to find the lowest grade:
intLowest = intGrades(0)
'Search for the lowest grade in the array
For intCount = 1 To (intGrades.Length - 1)
If intGrades(intCount) < intLowest Then
intLowest = intGrades(intCount)
End If
Next
This too worked as it should. Now for the problem I had: getting a Do While to calculate the new average with the lowest score dropped. This is where I need help:
Dim intNewTotal As Integer = 0 'holds the new total of the 3 highest grades
Dim dblNewAverage As Double 'holds the new average with the lowest score dropped
Dim intNewCount As Integer = 0 'loop counter
Do While intNewTotal <= (intTotal - intLowest)
intNewTotal = intNewTotal + intGrades.Length - 1
intNewCount += 1
Loop
dblNewAverage = intNewTotal / 3
The math is close, but not quite. With grades of 100, 100, 80, and 100 I get the following results: Average of all 4 = 95, Average with lowest score dropped = 101. The new average is always one higher than it should be. What can I do to fix this? I really want to understand so that I can fix this problem if it happens again. Thanks!
Upvotes: 1
Views: 3840
Reputation: 5269
The problem is with this line of code:
intNewTotal = intNewTotal + intGrades.Length - 1
Instead of adding the grade value, you add the length of the intGrades
array until you reach the Do while condition: intNewTotal <= (intTotal - intLowest)
I understand your question is for academic purpose so if you really need to use a Do While loop to calculate the average, I would use it that way (untested):
Dim index As Int = 0
Do While index <= intMAX_SUBSCRIPT
If (intGrades(index) <= intLowest) Then
intNewTotal += intGrades(index)
intNewCount += 1
End if
index += 1
Loop
dblNewAverage = intNewTotal / intNewCount
Edit
Dropping the lowest grade may be interpreted 2 different way. If you have values 80, 80, 100, 110 you may want to drop only one of the 80 value, or both of them. My code above is dropping both of them. If you want to remove only one of them, then your should set the starting index to 1 to skip the first item and remove the if condition:
Dim index As Int = 1
Do While index <= intMAX_SUBSCRIPT
intNewTotal += intGrades(index)
index += 1
Loop
dblNewAverage = intNewTotal / (intGrades.Length - 1)
Upvotes: 1
Reputation: 156
Dim j As New List(Of Int32)
Dim sum As Int32 = 0
For i = 1 To 4 '4 number of textboxes
j.Add(CType(Controls.Item("txtGrade" + i.ToString), TextBox).Text)
sum += Val(CType(Controls.Item("txtGrade" + i.ToString), TextBox).Text)
Next
j.Sort()
Dim intLowest As Int32 = j(0)
Dim avg As Int32 = sum / j.Count
Upvotes: 0
Reputation: 415665
This may be homework, in which case you won't understand any of this anyway. But if you're actually trying to learn how a pro would do it, the code would look more like this:
Dim Grades As New List(Of Integer) From {CInt(txtGrade1.Text), CInt(txtGrade2.Text), CInt(txtGrade3.Text), CInt(txtGrade4.Text)}
Dim Total As Integer = Grades.Sum()
Dim Average As Double = Grades.Average() 'holds the average of all 4 grades
Dim Lowest As Integer = Grades.Min() 'holds the lowest score
Dim NewAverage As Double = CDbl(Total - Lowest) / (Grades.Count - 1)
And drop the silly type prefixes on your variable names. They used to be popular and made sense back before Option Strict
was the default, but now even Microsoft's own style guidelines recommend against them.
Upvotes: 1