Need Help properly displaying an array in a listbox - arrays

Public Class Form1
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim Teams() As String = IO.File.ReadAllLines("SBWinners.txt")
Dim Team As String
Dim SteelersWins As Integer = 0
Dim RaidersWins As Integer = 0
Dim PackersWins As Integer = 0
Dim CowboysWins As Integer = 0
Dim GiantsWins As Integer = 0
Dim RamsWins As Integer = 0
Dim RavensWins As Integer = 0
Dim SaintsWins As Integer = 0
Dim FortyNinersWins As Integer = 0
Dim RedskinsWins As Integer = 0
Dim BroncosWins As Integer = 0
Dim PatriotsWins As Integer = 0
Dim ColtsWins As Integer = 0
Dim DolphinsWins As Integer = 0
Dim BearsWins As Integer = 0
Dim JetsWins As Integer = 0
Dim ChiefsWins As Integer = 0
Dim BuccWins As Integer = 0
For Each team In Teams
If team = "Steelers" Then
SteelersWins += 1
End If
If team = "Raiders" Then
RaidersWins += 1
End If
If team = "Packers" Then
PackersWins += 1
End If
If team = "Cowboys" Then
CowboysWins += 1
End If
If Team = "Giants" Then
GiantsWins += 1
End If
If team = "Rams" Then
RamsWins += 1
End If
If team = "Ravens" Then
RavensWins += 1
End If
If team = "Saints" Then
SaintsWins += 1
End If
If team = "Forty-Niners" Then
FortyNinersWins += 1
End If
If team = "Redskins" Then
RedskinsWins += 1
End If
If team = "Broncos" Then
BroncosWins += 1
End If
If team = "Patriots" Then
PatriotsWins += 1
End If
If team = "Colts" Then
ColtsWins += 1
End If
If team = "Dolphins" Then
DolphinsWins += 1
End If
If team = "Bears" Then
BearsWins += 1
End If
If team = "Jets" Then
JetsWins += 1
End If
If Team = "Chiefs" Then
ChiefsWins += 1
End If
If team = "Buccaneers" Then
BuccWins += 1
End If
Next
Dim Wins() As Integer = {SteelersWins, RaidersWins, PackersWins, CowboysWins, GiantsWins, RamsWins, RavensWins, SaintsWins, FortyNinersWins, RedskinsWins,
BroncosWins, PatriotsWins, ColtsWins, DolphinsWins, BearsWins, JetsWins, ChiefsWins, BuccWins}
For Each win In Wins
Array.Sort(Wins)
Array.Reverse(Wins)
lstOutput.Items.Add(win)
Next
End Sub
End Class
What I have right now is code that reads a text file with the names of Superbowl winners, and counts the number of wins by the number of times the team name appears. These wins are then put into an array and sorted in descending order and displayed in a listbox. This all works fine.
My problem is that I need to display the corresponding team name with their number of wins on the same line in the listbox. So, instead of being:
6
5
5
4
4
It needs to be:
6 Steelers
5 49ers
5 Cowboys
4 Giants
4 Packers
And so on.

There are a couple of issues with your code, not the least of which is you are using hard coded names and variables to collect your team information. This is severely limiting if new names are added or names change.
As Plutonix mentioned in the comments you need to use a class to properly identify and collate your information. I also strongly suggest you use a List(of T) collection to contain your data.
The following code does what you desire.
Private Class cls_Team_wins
Public Team_Name As String
Public Wins As Integer
Public Sub New(Name As String)
Team_Name = Name
Wins = 1
End Sub
Public Overrides Function ToString() As String
Return Strings.Right(" " & Wins, 2) & " - " & Team_Name
End Function
End Class
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim Games = New List(Of cls_Team_wins)
Dim Teams() As String = IO.File.ReadAllLines("SBWinners.txt")
For Each Team As String In Teams
If Team <> "" Then
Dim Team_Win As cls_Team_wins = Games.Find(Function(x) x.Team_Name = Team)
If Team_Win Is Nothing Then
Games.Add(New cls_Team_wins(Team))
Else
Team_Win.Wins += 1
End If
End If
Next
Games.Sort(Function(x, y) -x.Wins.CompareTo(y.Wins))
ListBox1.DataSource = Games
End Sub
The class included the team name and win counter. It over-rides the ToString method so the list box knows what to show as text. The New function requires you pass the team name and presets the win counter to one.
The For Loop checks for and ignores blank team names, this can be an issue reading text files, esp on the last line. Otherwise it will either add a new team to the list if it does not already exist, or it will increment the win counter if it does.
Once the list is built it is reverse sorted (Note the minus sign in the "Function" compare statement, that's a little trick that reverses the sort), and finally given to the listbox as a datasource.
Good luck to you :)

Related

VB.net Splitting a 1D array down into a 2D array

I am currently writing a (multiple choice) quiz program using VB.net I have read the answer options in from a .txt file into a single dimension temporary array however I would like to split this down into each question and the answer options for each questions into a 2D array so that (0,0) would be option A for question one and then (0,1) would be Option B for question 1 etc and then (1,0) would be option A for question 2. Below is the method I have tried however I get the error: "Object reference not set to an instance of an object" when adding 1 to a variable when I try and run this section of the code optnum = optnum + 1 Any help would be greatly appreciated, either fixing my code below or suggesting another method.
Dim optnum As Integer
Dim tempq As Integer = 0
Gameload(Phase_3.sounds)
Questionnum = 0
L_start.Hide()
optnum = 0
'splits the temp array down into options for each question
For i = 0 To 39
questions(tempq, optnum) = temparray(i)
optnum = optnum + 1
'there are 4 options for each question
'moves on to the next question when there is 4 options in the question
If optnum = 3 Then
tempq = tempq + 1
optnum = 0
End If
Next
For i = 0 To 3
L_option1.Text = questions(0, i)
Next
question_set()
Edit:
Here is the new full code I am still getting the error: Object reference not set to an instance of an object but now at the next in this section of code.
'''
For optnum = 0 To 3
questions(i, optnum) = temparray(i * 4 + optnum)
Next
'''
Thank you for all the help so far
'''
Public Class Game
Dim submission As Integer
Dim Correct_ans As Integer
Dim temparray() As String
Dim questions(,) As String
Dim Questionnum As Integer
Dim rs As New Resizer
Private Sub Game_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'finds all components on the screen in preperation if the screen resizes
rs.FindAllControls(Me)
L_start.Show()
End Sub
Private Sub Game_Resize(sender As Object, e As EventArgs) Handles Me.Resize
'resizes all components on the screen to same proportions
rs.ResizeAllControls(Me)
End Sub
Sub Gameload(ByVal sounds As String)
Dim pack As String
'reads in the sound pack
pack = My.Resources.ResourceManager.GetString(sounds)
Phase_3.Close()
'splits the pack into an array so that it can be broken down into questions
temparray = pack.Split(","c)
End Sub
Sub L_start_Click(sender As Object, e As EventArgs) Handles L_start.Click
Dim optnum As Integer
Dim tempq As Integer = 0
Gameload(Phase_3.sounds)
Questionnum = 0
L_start.Hide()
optnum = 0
'splits the temp array down into options for each question
For i = 0 To temparray.Count / 4
For optnum = 0 To 3
questions(i, optnum) = temparray(i * 4 + optnum)
Next
Next
For i = 0 To 3
L_option1.Text = questions(0, i)
Next
End Sub
'''
This is just my opinion but I think your aproach would be hard to maintain. I never saw the value of a class until I actually tried one. Maybe this is your chance.
Public Class Quiz
Public Property QuestionNumber As Integer
Public Property Question As String
Public Property AnswerA As String
Public Property AnswerB As String
Public Property AnswerC As String
Public Property AnswerD As String
Public Property CorrectAnswer As String
Public Overrides Function ToString() As String
Return $"Question: {QuestionNumber}.{Question} Answer Choices: {AnswerA}, {AnswerB}, {AnswerC}, {AnswerD} Correct Answer - {CorrectAnswer}"
End Function
End Class
To use your class...
Private QuestionList As New List(Of Quiz)
Private Sub OPCode2()
Dim temparray = File.ReadAllLines("answers.txt")
Dim temparraylocation As Integer
Dim questions = File.ReadAllLines("questions.txt")
Dim correctAnswers = File.ReadAllLines("correct.txt")
For i = 0 To questions.Length - 1
Dim qu As New Quiz
qu.QuestionNumber = i + 1
qu.Question = questions(i)
qu.CorrectAnswer = correctAnswers(i)
qu.AnswerA = temparray(temparraylocation)
temparraylocation += 1
qu.AnswerB = temparray(temparraylocation)
temparraylocation += 1
qu.AnswerC = temparray(temparraylocation)
temparraylocation += 1
qu.AnswerD = temparray(temparraylocation)
temparraylocation += 1
QuestionList.Add(qu)
Next
For Each q In QuestionList
Debug.Print(q.ToString)
Next
End Sub
Where's your declaration for temparray and questions. Will the quiz always have 4 choices and 10 questions?
It might be easier for you to have a nested loop so that i is temparray.count/4 and optnum is 0-3, then you can populate questions(i, optnum) = temparray(i*4+optnum)
Looking at your new code, you haven't initialised the questions variable. Only declared it.
Personally I would change questions to a list(of question), then use Mary's answer.

Creating an Array of a class with an attribute integer(), all instances in the array, are overwritten with data of last instance added

I am returning an array of the instance Trendclass, which includes three attributes. The datapoints_array is supposed to contain values. Unfortunately the datapoints of all instances are replaced as soon as a new one is added to the array, while timestamp and column_name remain as they are (as presented in Console). Is there a logical mistake? Am desperately trying to find a solution.
The Code is the following:
Module Module1
Sub Main()
testTrendclass()
End Sub
Public Function testTrendclass() As TrendClass()
Dim array_length As Integer = 5
Dim Trend_array(array_length) As TrendClass
Dim duration As Integer = 10
Dim datapoints_array(duration) As Integer
For i = 0 To array_length
For i2 = 0 To 5
datapoints_array(i2) = i * i2
Next
Trend_array(i) = New TrendClass With {
.column_name = "ISO1_MICRA1810_" & i,
.datapoints = datapoints_array,
.timestamp = System.DateTime.Now().AddDays(i)
}
Console.WriteLine("current_data_array")
For i2 As Integer = 0 To 4
Console.WriteLine("data_array: " & Trend_array(i).datapoints(i2))
Next
Console.WriteLine(vbLf & vbLf)
Next
For i = 0 To Trend_array.Count() - 1
Console.WriteLine("column_name: " & Trend_array(i).column_name)
For i2 As Integer = 0 To 4
Console.WriteLine("data_array: " & Trend_array(i).datapoints(i2))
Next
Console.WriteLine("timestamp: " & Trend_array(i).timestamp & vbLf)
Next
Console.ReadLine()
Return Trend_array
End Function
Public Class TrendClass
Public Property timestamp As DateTime
Public Property datapoints As Integer()
Public Property column_name As String
End Class
End Module
Found the solution... Data is inserted ByReference, and therefore is overwriting its own values. Declaring the datapoints_array inside the for loop solved the problem:
Public Function testTrendclass() As TrendClass()
Dim array_length As Integer = 5
Dim Trend_array(array_length) As TrendClass
Dim duration As Integer = 10
For i = 0 To array_length
Dim datapoints_array(duration) As Integer
For i2 = 0 To 5
datapoints_array(i2) = i * i2
Next

A practically irrelevant just mildly interesting algorithm and how do I get the logic to work?

I was in the shower yesterday, and an idea hit me. It's a mathematical pattern or set of rules to find a list of integers.
The practical application of this pattern or whatever you could call it is up to the super mathematicians, I just wanted to see if I could make a program that could find it.
At the moment I'm using VB.net as it's what I HAVE to use for college right now, but im open to C++ as well.
So, the rules of this pattern are:
You get an Integer as your "factor", and multiply it by itself as many times as you like. This creates a list of numbers that you use as namespaces or what I'd call "containers".
If the factor was say, 2, the list would look like this - 4, 8, 16, 32, 64 etc. (excluding the base factor).
Now under each item of the list you place all integers that could fit inside it. If the number of the container is 8 for example, every number from 1 to 7 would be listed.
However the rules go further than that.
A number inside the container cannot be listed if;
it's = 1 or 2
it's = any number in the container before
it's = the factor before
or is divisible by any number in the container before.
For example
[4]-[8]-[16]-[32]
3 7 13 31
5 12 29
11 26
9 25
6 23
4 19
3 17
14
10
7
5
As you can see the numbers you get are always different. So I was working on a form in VS 2015, that allowed you to enter the factor, and the number of iterations (how long the list went) in the list.
The issue is, as you might of guessed by the fact that I'm actually doing this in the first place, is that my logic isn't all that great. As a programer I am a begginer, and as a logical thinker I am not the best.
See below what I've tried out so far. It's just what was in between the button sub:
Dim iteration As Integer = EtrIterationCount.Text
Dim factor As Integer = EtrNumericFactor.Text
Dim Container()() As Integer = New Integer(iteration)() {}
ReDim Container(iteration)(1)
Dim Contents() As Integer = New Integer() {}
Dim Base As Integer = factor
For X = 1 To iteration - 1
Container(X)(1) = New Integer()
Base = Base * factor
Container(X)(0) = Base
Next
Container(0)(0) = factor
For X = 0 To iteration - 1
Dim Test As Integer = Container(X)(0)
Dim Num = Test
For Num = Num To 0 Step -1
If X = 0 Then
For W = Num To 0 Step -1
If Not Test = 1 Then
Contents(W) = Test
End If
Next
Array.ConstrainedCopy(Contents, Contents.Length, Container, Container(X)(1), Contents.Length)
ElseIf X >= 1 Then
For W = Num To 0 Step -1
For J = 0 To Contents.Length - 1
If Not Contents(J) Mod Container(X - 1)(1) = 0 Then
If Not Test = 1 And Test = Container(X)(0) And Contents.Contains(Test) Then
Contents(W) = Test
End If
End If
Next
Next
Array.ConstrainedCopy(Contents, Contents.Length, Container, Container(X)(1), Contents.Length)
End If
Test = Test - 1
MsgBox(Container(X)(1))
Next
Next
What I have basically tried to do, is something I've not done before, and create a jagged/nested array, the first array acting as the container listing all the iterations and its first row containing the factored numbers, the second row containing the array with the list of values.
It was suggested by a first that I use Vectors, or a class of vectors to sort out this problem, but I haven't got the foggiest how to do that.
If anything I would like this to be practice on how to deal with arrays and maybe teach me some logic that I'm missing.
There are probably several ways to do this, many of them better than what I came up with, but a Dictionary(Of Integer, List(Of Integer)) will suffice to hold the data:
Option Infer On
Option Strict On
Module Module1
Sub Main()
Console.Write("Factor: ")
Dim factor = CInt(Console.ReadLine())
Console.Write("Iterations: ")
Dim iters = CInt(Console.ReadLine())
Dim result As New Dictionary(Of Integer, List(Of Integer))
Dim thisSection = factor
Dim prevSection = 0
For i = 2 To iters + 1
thisSection = thisSection * factor
result.Add(thisSection, New List(Of Integer))
For j = 3 To thisSection - 1
Dim isDivisible = False
If prevSection > 0 Then
If j Mod prevSection = 0 Then
isDivisible = True
End If
If Not isDivisible Then
For Each n In result(prevSection)
If j Mod n = 0 Then
isDivisible = True
Exit For
End If
Next
End If
End If
If Not isDivisible Then
result(thisSection).Add(j)
End If
Next
prevSection = thisSection
Next
For Each de In result
Console.WriteLine("[" & de.Key.ToString() & "] " & String.Join(", ", de.Value.OrderByDescending(Function(x) x)))
Next
Console.ReadLine()
End Sub
End Module
Sample output:
Factor: 2
Iterations: 4
[4] 3
[8] 7, 5
[16] 13, 12, 11, 9, 6, 4, 3
[32] 31, 29, 25, 23, 19, 17, 14, 10, 7, 5
A List is pretty much like an array, but you can add to it without knowing the number of entries in advance (it increases its capacity automatically).
The variable names I used could probably be more descriptive.
Incidentally, in your example you have 26 in the [32] column, but 13 (=26/2) is in the [16] column.
Also check this out. It uses the Chain pattern. More easy to add new rule.
Module Module1
Sub Main()
Dim results As New Dictionary(Of Integer, List(Of Integer))
Dim initialValue As Integer = 2
Dim multiplier As Integer = 4
For i As Integer = 2 To multiplier + 1
results.Add(Convert.ToInt32(initialValue ^ i), New List(Of Integer))
Next
For dictionaryIndex As Integer = 0 To results.Count - 1
Dim currentFactor As Integer = results.Keys(dictionaryIndex)
For testValue As Integer = 1 To currentFactor - 1
Dim chain As New ChainOfRules()
chain.AddRule(New NotInValuesRule(testValue, 1, 2))
If (dictionaryIndex > 0) Then
Dim previousFactor As Integer = results.Keys(dictionaryIndex - 1)
chain.AddRule(New NotInValuesRule(testValue, results(previousFactor).ToArray))
chain.AddRule(New NotInValuesRule(testValue, previousFactor))
chain.AddRule(New NotDivisibleListRule(testValue, results(previousFactor).ToArray))
End If
If (chain.Process) Then
results(currentFactor).Add(testValue)
End If
Next
Next
For Each pair As KeyValuePair(Of Integer, List(Of Integer)) In results
Console.WriteLine()
Console.WriteLine("Factor: {0}", pair.Key)
Console.WriteLine("-------------------")
For Each i As Integer In pair.Value
Console.WriteLine("Value: {0}", i)
Next
Next
Console.ReadLine()
End Sub
' Rules
Public Interface IRule
Function Apply() As Boolean
End Interface
Public Class NotInValuesRule
Implements IRule
Private Property Value As Integer
Private Property ValuesList As List(Of Integer)
Public Sub New(value As Integer, ParamArray valuesList As Integer())
Me.Value = value
Me.ValuesList = valuesList.ToList()
End Sub
Public Function Apply() As Boolean Implements IRule.Apply
Return Not ValuesList.Contains(Value)
End Function
End Class
Public Class NotDivisibleListRule
Implements IRule
Private Property Value As Integer
Private Property ValuesList As List(Of Integer)
Public Sub New(value As Integer, ParamArray valuesList As Integer())
Me.Value = value
Me.ValuesList = valuesList.ToList
End Sub
Public Function Apply() As Boolean Implements IRule.Apply
Dim result As Boolean = True
For Each previousValue As Integer In ValuesList
result = result And (Value Mod previousValue <> 0)
Next
Return result
End Function
End Class
Public Class ChainOfRules
Private Property Rules As New List(Of IRule)
Public Sub AddRule(rule As IRule)
Rules.Add(rule)
End Sub
Public Function Process() As Boolean
Dim result As Boolean = True
For Each Rule As IRule In Rules
result = result And Rule.Apply()
Next
Return result
End Function
End Class
End Module

Grade Array Averager troubles

I am currently in an IT curriculum in college. Advance Visual Basic 2010 is a requirement however, I am not a programmer. I have been struggling to find my way through VB but this last assignment has me stumped.I am able to get the first name into the array and the 5 grades for that name . At that point, the loop will continue to ask for the next name and that names 5 grades and so on until the 4th name and grades are entered and then it should display all 4 names and grade averages in the listbox.
Here is the assignment...
Write a program that will input four students’ names and average five test grades for each student. The program should have an array for the students name and then a two-dimensional array for all their grades.
Your program should ask for the students name and then five test scores for that student.
Create a method that does the averaging and pass the arrays to that method. That method can also output the student name and average in a list box.
Call a method to figure up the average once you get all the grades. Do not figure it up as you get the information!! You’ll get a big ole zero if you do! Then have that same method output the results into the list box:
After 4 days of struggling with this, here is what I have come up with so far. Any guidance is greatly appreciated. Thank you in advance.
Public Class Form1
Private Sub btnNames_Click(sender As System.Object, e As System.EventArgs) Handles btnNames.Click
Dim NamesList(3) As String
Dim GradeArray(4) As Integer
Dim x As Integer
Dim y As Integer
Dim Sum As Integer
Dim Avg As Integer
For y = 0 To NamesList(3)
NamesList(x) = InputBox("Enter student number " & y + 1 & "'s name:", "Enter a name")
Next
For y = 0 To GradeArray.Length - 1
GradeArray(y) = InputBox("Enter grade number " & y + 1 & " for " & NamesList(0) & " in the box:", "Enter the grades")
Next
For Each item In GradeArray
Sum = Sum + item
Next
Avg = Sum / 5
lstAverages.Text = Avg.ToString
End Sub
Private Sub btnExit_Click(sender As System.Object, e As System.EventArgs) Handles btnExit.Click
Me.Close()
End Sub
End Class
I had nothing else better to do, so I took up giving it a try... Also this includes per as you stated: 4 students - 5 grades each, array for students names and a 2D array to hold all their grades. There's a method that passes these to it and performs the averaging of the students grades and then spits them to a listbox as requested ... Happy Coding!
P.S. I didn't do any error handling either, you may want to add that or at least implement something to handle such cases ...
Public Class Form1
Private arrStudents(3) As String 'Student's name array (4)
Private arrScores(3, 4) As Integer 'Students scores (5 each)
'Start getting the data we need
Private Sub btnGetStudents_Click(sender As Object, e As EventArgs) Handles btnGetStudents.Click
Dim strStudent As String = String.Empty
Dim intScore As Integer = 0
Dim intPlace As Integer = 0
'Get the students name...
For i As Integer = 0 To arrStudents.Length - 1
Do Until strStudent <> String.Empty
strStudent = InputBox("Please enter student's name: ", "Gather Student Grades")
Loop
arrStudents(i) = strStudent
'Reset our variable...
strStudent = String.Empty
'Get the students grades...
For s As Integer = 0 To arrScores.Length - 1
Do Until intScore > 0
intScore = CInt(InputBox("Please enter student's scores: ", "Gather Student Scores"))
Loop
If (intPlace = 4 AndAlso i = arrStudents.Length) Then
intPlace = 0
arrScores(i, s) = intScore
intScore = 0
ElseIf intPlace = 4 Then
intPlace = 0
arrScores(i, s) = intScore
intScore = 0
Exit For
Else
arrScores(i, intPlace) = intScore
intPlace += 1
End If
'Reset our variables...
intScore = 0
Next
Next
'Calculate and output the data to the listbox...
GetStudentAverages(arrStudents, arrScores)
End Sub
'Function to average per student grades and then display them all in the listbox...
Private Sub GetStudentAverages(ByVal arStudent As Array, ByVal arScore As Array)
Dim strStudentData As String = String.Empty
Dim intAverage As Integer = 0
Dim intPlace As Integer = 0
'Start averaging the students scores and then add them to the listbox...
For i As Integer = 0 To arStudent.Length - 1
For g As Integer = 0 To arScore.Length - 1
If intPlace = arStudent.Length Then
intAverage += arScore(i, intPlace)
Exit For
Else
intAverage += arScore(i, intPlace)
intPlace += 1
End If
Next
intAverage = CInt(intAverage / 5)
intPlace = 0
'Output the student information...
ListBox1.Items.Add("Student: " & arStudent(i).ToString & " Average: " & intAverage.ToString)
intAverage = 0
Next
End Sub
End Class

summing elements of a .txt file array in VB.net

College student in an advanced VB class who is turning to a forum for help - I've found a few examples of code but am having a hard time figuring this one out.. any and all help is appreciated :)
This application imports a .txt file stored in the bin, debug folder called data.txt
..20 records, 3 lines per record, the last line is the student's grade, I need to average the grades by summing each records grade and dividing by 20 and then displaying on the lstbox showing the average.
So far I've got..
Dim objReader As IO.StreamReader
Dim intFill As Integer
Dim intCount As Integer = 0
Dim intAverage As Integer
Dim strLocationAndNameOfFile As String = "data.text"
If IO.File.Exists(strLocationAndNameOfFile) = True Then
objReader = IO.File.OpenText(strLocationAndNameOfFile)
Else
MsgBox("The file is not available. Restart the program when the file is avilable", , "Error")
Me.Close()
End If
If IO.File.Exists(strLocationAndNameOfFile) Then
objReader = IO.File.OpenText(strLocationAndNameOfFile)
Do While objReader.Peek <> -1
_strName(intCount) = Convert.ToString(objReader.ReadLine())
_strItemID(intCount) = Convert.ToString(objReader.ReadLine())
_intGrade(intCount) = Convert.ToInt32(objReader.ReadLine())
intCount += 1
Loop
objReader.Close()
End If
For intFill = 0 To (_strName.Length - 1)
*'intAverage = SUM OF ALL AVERAGES / LENGTH OF ARRAY -1*
Me.lstAverage.Items.Add(intAverage.ToString())
While looping to read the grades sum them up
Dim total as Integer
Do While objReader.Peek <> -1
_strName(intCount) = Convert.ToString(objReader.ReadLine())
_strItemID(intCount) = Convert.ToString(objReader.ReadLine())
_intGrade(intCount) = Convert.ToInt32(objReader.ReadLine())
total += _intGrade(intCount)
intCount += 1
Loop
And then just divide by 20 or _intGrade.Length
intAverage = total / _intGrade.Length
So many issues, as much as I loathe doing other's homework I want you to see what this could look like
Public Function GetAverageGrade(ByVal filename As String) As Double
Dim totalGrade As Integer = 0
Dim lineCount As Integer = 0
Dim line As String
Using rdr As New IO.StreamReader(filename)
While (line = rdr.ReadLine()) IsNot Nothing
lineCount += 1
If lineCount Mod 3 = 0 Then totalGrade += Convert.ToInt32(line)
End While
End Using
Return totalGrade / (lineCount / 3.0)
End Function
Of course, you probably want to do more with that data than just get the average grade. So an even better option is build code that reads it all in as a set of records:
Public Class GradeItem
Public Property Name As String
Public Property Item As String
Public Property Grade As Integer
End Class
and then
Public Iterator Function ReadGradeItems(ByVal fileName As String) As IEnumerable(Of GradeItem)
Using rdr As New IO.StreamReader(fileName)
While rdr.Peek() <> -1
Yield New GradeItem With {.Name = rdr.ReadLine(), .Item= rdr.ReadLine(), .Grade = Convert.ToInt32(rdr.ReadLine()}
End While
End Using
End Function
and now put it all together:
Dim grades As IEnumerable(Of GradeItem) = ReadGradeItems("data.text")
lstAverage.Items.Add(grades.Select(Function(g) g.Grade).Average())

Resources