Converting a Loop projected to an array???

Jblake00

Well-known member
Joined
Sep 27, 2003
Messages
76
Here is the original code.
Code:
 Private Sub btnGtGrades_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGtGrades.Click
        Dim my As IO.StreamReader
        Dim fmtStr As String = "{0,11}{1,4} {2,8}  {3,6}     {4,6}"
        Dim strStudent, Start As String, strLetterGrade As String
        Dim Grade1, Grade2, total As Double
        Dim varEveryonesGrade As Double
        Dim varAverage As Double
        Dim sum As Double
        varAverage = 0
        sum = 0
        If IO.File.Exists("A:\grades.txt") Then
            my = IO.File.OpenText("A:\grades.txt")
            Do While my.Peek <> -1
                Start = my.ReadLine
                strStudent = Start.Substring(0, 11)               
                Grade1 = Start.Substring(12, 4)
                Grade2 = Start.Substring(16, 4)
                varAverage = Math.Round((Grade1 + Grade2) / 2)          
                varEveryonesGrade += varAverage            
                sum += 1
                               Select Case varAverage
                    Case Is >= 90
                        strLetterGrade = "A"
                    Case Is >= 80
                        strLetterGrade = "B"
                    Case Is >= 70
                        strLetterGrade = "C"
                    Case Is >= 60
                        strLetterGrade = "D"
                    Case Is >= 50
                        strLetterGrade = "F"
                End Select
                lstGtGrds.Items.Add(String.Format(fmtStr, strStudent, Grade1, Grade2, varAverage, strLetterGrade))

            Loop
            my.Close()
            varEveryonesGrade = Math.Round(varEveryonesGrade / sum)

            txtDsplyClsAvr.Text = "The class average is " & CStr(varEveryonesGrade)

        Else

            MsgBox("Try putting in the disk that has grades.txt on it!", , "Missing Disk")
        End If
    End Sub

I am suposeto be able to easily convert it to an array, but so far it has not been so easy!!
In this project I need to set up a row for the studentd and two columns for the grades
This is done as
Code:
Dim strStudent() As String
and
Code:
 Dim grades( ,  ) As Double
Also I need a counter so I done
Code:
 Dim Counter As Integer
counter = 0
Then the rest of the dim statements are as before, here is the rest of my code
Code:
 If IO.File.Exists("A:\grades.txt") Then
            my = IO.File.OpenText("A:\grades.txt")
            Do While my.Peek <> -1

                Start = my.ReadLine
                counter += 1
            Loop
            my.Close()
            ReDim strStudent(counter)
            my = IO.File.OpenText("A:\grades.txt")
            strStudent(i) = my.ReadLine
            ReDim Grades(counter, 2)


            strStudent(row) = 1
              Start = my.ReadLine

            strStudent(strLetterGrade) = varAverage
            For i = 2 To counter

                If Grades(1, +2) \ 2 = varAverage Then
                    
                    txtDsplyClsAvr.Text = "The class average is " & CStr(varEveryonesGrade)
                End If

                strStudent = Start.Substring(0, 11)
                 Grade1 = Start.Substring(12, 4)
                 Grade2 = Start.Substring(16, 4)
                 varAverage = Math.Round((Grade1 + Grade2) / 2, 0)
                 varEveryonesGrade += varAverage
                 sum += 1

                Select Case varAverage
                    Case Is >= 90
                        strLetterGrade = "A"
                    Case Is >= 80
                        strLetterGrade = "B"
                    Case Is >= 70
                        strLetterGrade = "C"
                    Case Is >= 60
                        strLetterGrade = "D"
                    Case Is >= 50
                        strLetterGrade = "F"
                End Select
                lstGtGrds.Items.Add(String.Format(fmtStr, strStudent, Grades, varAverage, strLetterGrade))

            Next
            my.Close()
             varEveryonesGrade = Math.Round(varEveryonesGrade / sum)
       Else
        MsgBox("Try putting in the disk that has grades.txt on it!, , Missing Disk")
        End If
I have gotten some strnge results from this when I get it to out put some thing, it comes out something like string.input 0 0 1 0
But I assume that is because I have got the strings to read, store and divide up the infomation.
Then I need to get the columns to divide with each other because that will be were and what my grades are. When that is done that will give me my average. when I attempt to do this I get an error that tod 89 64 cast to double is invalid.
right know my error has to to with the input box. Something about trying to ad info that is less than my array or trying to divide by zero. not sure which one it was. Maybe aia have had both errors, anyway I will check back in the morning and hopefully I will get some advice that will lead me to a solution.
 
strStudent(strLetterGrade) = varAverage
You probably need to convert this strLetterGrade into a Long, or some type of integer with a Parse method.
But, it doesnt seem like this starts off with anything in it. :confused:
Where are you computing the average?
You can close my after you read that one line from it right before you redim Grades. :)
 
which line are you getting the error on? It looks like you need to split the line from the file into sperate parts before parsing into a double.
 
I am trying to comput the average with,If Grades(1, +2) \ 2 = varAverage Then...And I beleive the error was here.
Code:
 lstGtGrds.Items.Add(String.Format(fmtStr, strStudent, Grades, varAverage, strLetterGrade))
 
Ok lets start over.. Here is my code now.
Code:
Dim my As IO.StreamReader
        Dim fmtStr As String = "{0,11}{1,4} {2,8}  {3,6}     {4,6}"
        Dim strStudent() As String
        Dim i As Integer
        Dim row As Double
        Dim Start As String, strLetterGrade As String
        Dim col, Grades(,) As Double
        Dim g1, g2 As Double
        Dim total As Double
        Dim varEveryonesGrade As Double
        Dim varAverage As Double
         Dim f As Double
          Dim s As Double
        Dim sum As Double
        Dim counter As Integer
        varAverage = 0
        sum = 0
        counter = 0
        
        If IO.File.Exists("A:\grades.txt") Then
            my = IO.File.OpenText("A:\grades.txt")
            Do While my.Peek <> -1
                strStudent(i) = my.ReadLine

                counter += 1
            Loop
            my.Close()
            ReDim strStudent(counter)
            my = IO.File.OpenText("A:\grades.txt")
            strStudent(i) = my.ReadLine
            ReDim Grades(counter, 2)
            strStudent(row) = 1
            Grades(g1, g2) = 2
            g1 = Start.Substring(12, 4)
            g2 = Start.Substring(16, 4)
            varAverage = Grades(g1, +g2) \ 2
            strStudent(strLetterGrade) = varAverage
            For i = 1 To counter

                If Grades(g1, +g2) \ 2 = varAverage Then
                    varEveryonesGrade += varAverage
                    varEveryonesGrade = Math.Round(varEveryonesGrade / sum)


                    txtDsplyClsAvr.Text = "The class average is " & CStr(varEveryonesGrade)
                End If

                sum += 1

                Select Case varAverage
                    Case Is >= 90
                        strLetterGrade = "A"
                    Case Is >= 80
                        strLetterGrade = "B"
                    Case Is >= 70
                        strLetterGrade = "C"
                    Case Is >= 60
                        strLetterGrade = "D"
                    Case Is >= 50
                        strLetterGrade = "F"
                End Select
                lstGtGrds.Items.Add(String.Format(fmtStr, strStudent, g1, g2, varAverage, strLetterGrade))

            Next
            my.Close()
            varEveryonesGrade = Math.Round(varEveryonesGrade / sum)

        Else

            MsgBox("Try putting in the disk that has grades.txt on it!, , Missing Disk")

        End If
The problem now is I am outofbounds with my array index.
And it has to do with my trying to add g1 and g2. I think.
Any way I got to take a coffee break and think about it.
 
in the line
Code:
Grades(g1, +g2)
could you not just use
Code:
Grades(g1, g2)
also on the lines

Code:
g1 = Start.Substring(12, 4)
g2 = Start.Substring(16, 4)
the variable Start doesnt appear to be initialized before you use it.

and in
Code:
strStudent(strLetterGrade) = varAverage
strLetterGrade doesnt appear to be initalize either - as well as it being a string not an integer (as pointed out by IcePlug earlier)

also not sure what
Code:
If Grades(g1, +g2) \ 2 = varAverage Then
     varEveryonesGrade += varAverage
     varEveryonesGrade = Math.Round(varEveryonesGrade / sum)
     txtDsplyClsAvr.Text = "The class average is " &  CStr(varEveryonesGrade)
End If
is doing at all

and which line are you getting the Index out of bounds error?

the variable sum only seems to be being used as a loop counter but is declared as a double - any reason why?
 
No I am not sure why I had sum as double. It is a counter or was. I may need to do away with it now? Ok lets start over. I made a new text file that contains names only. one name per line. Here is my idea that is the first part of my program. So what I want it to do is simply add the names to a list box in column. But the names are actually the begining of the rows and the grades are the columns. At any rate so far I am haveing no luck.
I almost had it working and changed some things about the text reader and really messed it up.
any way if I could work out the first part first the I could go on to the rest of it.
Here is my thoughts.
Code:
 dim the stream reader
Dim names() As String = {"student"}
        Dim i, keepCount As Integer
keepCount = 0
If IO.File.Exists("a:\name.txt") Then
            names(i) = myReader.ReadToEnd()
            Do While myReader.Peek <> -1
                keepCount += 1
                myReader.ReadLine()

            Loop
            my.Close()

            ReDim names(keepCount)
            myReader = IO.File.OpenText("a:\name.txt")
            myReader.ReadLine()
            lstBox.Items.Clear()
            For i = 1 To keepCount
                names(i) = myReader.ReadLine


                lstBox.Items.Add(names(i))
            Next
if I could get that to work then perhaps I could build from there.
 
firstly
Code:
names(i) = myreader.ReadToEnd()
will read the entire file into the first item of the names array - probably not what you intended.

Try something like...

Code:
Dim myReader As System.IO.StreamReader
		Dim names() As String
		Dim i As Integer = 0
		Dim line As String

		myReader = IO.File.OpenText("a:\name.txt")
		lstBox.Items.Clear()

		Do

			ReDim Preserve names(i)
			line = myReader.ReadLine
			names(i) = line
			If Not line Is Nothing Then lstBox.Items.Add(names(i))
			i += 1
		Loop Until line = Nothing

although you may be able to do it easier using string.split
Code:
Dim myReader As System.IO.StreamReader
Dim names() As String
Dim line As String

myReader = IO.File.OpenText("a:\names.txt")
lstBox.Items.Clear()

line = myReader.ReadToEnd
names = line.Split(Environment.NewLine)
lstBox.DataSource = names
although you may need to mess with the line.Split(...) bit to get the correct line terminator in.
 
Ok keep that in mind for the next part not sure if I got to use the split command yet. I got the first part finally, here it is.
Code:
 Private Sub btn1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn1.Click
        Dim my As IO.StreamReader
        Dim names() As String = {"student"}
        Dim i, keepCount As Integer
        Dim start As String
        keepCount = 0
        
        If IO.File.Exists("a:\name.txt") Then
            my = IO.File.OpenText("A:\name.txt")
            Do While my.Peek <> -1
                start = my.ReadLine
                keepCount += 1
                
            Loop
            my.Close()
            my = IO.File.OpenText("a:\name.txt")

            ReDim names(keepCount)
            For i = 1 To keepCount
                names(i) = CStr(my.ReadLine)
                lstBox.Items.Add(names(i))
            Next
            my.Close()

        End If

    End Sub
End Class
of I realize that many of you are much more advance than I am at this sort of thing. But hey when I started I knew absolutely nothing about programing and know at least I know a little.
I have to add a nested loop to what I got so far, also some grades to the text file. then I am going to have to get them into zones, that display the name 2 grades an average and a letter grade. then I have to display the average of the class in a text box.
The most confusing thing to me was mentioned before. It is the part were I divide the 2 grades to get the average. As I was asked before and someone didnt understand what I was doing.
Well the idea is (grade1 + grade2) /2 or " is divided by 2 " and that gives the average. only thing I am unsure of if that is how it is done in this program. Maybe it is more like row1 & col 4 + col 5 / 2 = average ????
 
You really dont need to open and read the file twice - see my above post (1st sample) on how to do it opening the file only once.

you could also use the split command to split the line you read in into its seperate columns.
Code:
dim vals() as string
vals = line.split(" " )    will split on space
based on your example earlier of a line being tod 89 64
vals(0) would = tod
vals(1) would = 89
and vals(2) would = 64
 
Ok I see your point. Unfornunately I have a set of guidelines that I have to go by. I have learned these guidelines take a simple problem and make a mountain out of a mole hill. so in another words I have to have name() or student() as a string and grades(,) as double,however he said we had thus far used substring(0,11) and did hint that we would have to figure out another way to do it. So now you have me wandering if. vals(student) and vals(grade1, grade2) would work out? at any rate fixing to try something on the second part
 
Ok I added the grades to the file and when I used the script from above that showed all names and grades.
So I dug thought my collection of pages that I printed off from the micrsoft vb sight and came up with this. I change the line
Code:
names(i) = CStr(my.ReadLine)
To this
Code:
names(i) = my.ReadLine.ToCharArray(0, 11)
Walla names without the grades.
Btw I am not ignoreing what you are saying about opening and closeing the streamreader, but as I said before, " I got certain guidelines I must folllow."... I am quit certain you and many others could do the program in "probably" 10 minutes...
But I think that it has to do with keep up with the counter. Well I have for afternoons to figure the rest out. Btw this I quite a challange for someone who is a framer and also dropped out of high school in the tenth grade.
I am trying to become a computer tech, before my back gets more degenerating and heriated disk than it already has.
So far the with the programs I have done excellent with, but I freeze up on the test,,,,,errrrr.
Any links that may help me learn are welcome. I do well on remembering what I read as long as I is simplified to to were a beginer to an intermediate level of understanding. I am definitly not ready for to advanced programing skills yet.
But hay I am getting there, slowly but surely.
 
So, what does your code look like now?
And where are those grades coming from? Have you already averaged those?
Seems as though, since grades is a 2D array, you would be using a nested for loop on the grades. :-\
 
Yes That is what I am atempting. here is the code now.
But is not showing or adding the grades or the rest of the items.
Code:
 Dim my As IO.StreamReader
        Dim fmtStr As String = "{0,11}{1,4} {2,8}  {3,6}     {4,6}"
        Dim grades(,) As Double
        Dim f As Double
        Dim s As Double
        Dim grade1, grade2, total As Double
        Dim varAverage As Double
        Dim sdtLetterG As Double
        Dim names() As String
        Dim student As String
        Dim i, keepCount As Integer
        Dim start As String
        keepCount = 0
        
        If IO.File.Exists("a:\name.txt") Then
            my = IO.File.OpenText("A:\name.txt")
            Do While my.Peek <> -1
                start = my.ReadLine
                keepCount += 1


            Loop
            my.Close()
            my = IO.File.OpenText("a:\name.txt")


            ReDim names(keepCount)
            ReDim grades(keepCount, 2)
            For i = 1 To keepCount
                start = my.ReadLine
                names(i) = start.ToCharArray(0, 11)

                lstBox.Items.Add(names(i))
            Next
            For keepCount = f To s
                 
                f = grades(f, 2) = start.Substring(12, 4)
                f = grade1
                lstBox.Items.Add(f)
                
                s = grades(1, s) = start.Substring(16, 4)
                s = grade2
                lstBox.Items.Add(s)
                varAverage = Math.Round((grade1 + grade2) / 2)
                total += varAverage




            Next
            total = Math.Round(varAverage / keepCount)
            For sdtLetterG = 1 To keepCount

            Next
            Select Case varAverage
                Case Is >= 90
                    sdtLetterG = "A"
                Case Is >= 80
                    sdtLetterG = "B"
                Case Is >= 70
                    sdtLetterG = "C"
                Case Is >= 60
                    sdtLetterG = "D"
                Case Is >= 50
                    sdtLetterG = "F"
            End Select

            lstBox.Items.Add(String.Format(fmtStr, names(i), grade1, grade2, varAverage, sdtLetterG))

            my.Close()
            varAverage = Math.Round((grade1 + grade2) / 2)
            total += varAverage


            total = Math.Round(total / keepCount)

            txtDsplyClsAvr.Text = "The class average is " & CStr(total)

        Else

            MsgBox("Try putting in the disk that has grades.txt on it!", , "Missing Disk")
            lstBox.Items.Add(String.Format(fmtStr, names(i), grade1, grade2, varAverage, sdtLetterG))


        End If

    End Sub
 
[VB] Dim my As IO.StreamReader
Dim fmtStr As String = "{0,11}{1,4} {2,8} {3,6} {4,6}"
Dim grades(,) As Double
Dim row, col As Integer
Dim f As Double
Dim s As Double
Dim grade1, grade2, total As Double
Dim varAverage As Double
Dim sdtLetterG As Double
Dim names() As String = {"0,11", "{1,4}", "{2,8} ", "{3,6} ", "{4,6} "}

Dim student As String
Dim i, keepCount As Integer
Dim start As String
keepCount = 0

If IO.File.Exists("a:\name.txt") Then
my = IO.File.OpenText("A:\name.txt")
Do While my.Peek <> -1
start = my.ReadLine
keepCount += 1


Loop
End If

my.Close()


my = IO.File.OpenText("a:\name.txt")
ReDim names(keepCount)
ReDim grades(grade1, grade2)
For i = 1 To keepCount

start = my.ReadLine
names(i) = start.Substring(0, 11)
lstBox.Items.Add(names(i))


Next

If IO.File.Exists("a:\name.txt") Then
my = IO.File.OpenText("A:\name.txt")
Do While my.Peek <> -1

For varAverage = keepCount To 2
varAverage += Math.Round(grades(Grade1, + Grade2)) / 2)
Next

start = my.ReadLine
grade1 = start.Substring(12, 4)
lstBox.Items.Add(grade1)
grade2 = start.Substring(16, 4)
lstBox.Items.Add(grade2)
lstBox.Items.Insert(grade1, grade2)




Loop


lstBox.Items.Add(varAverage)
varAverage = grades(grade1, grade2) / 2 = start.Substring(12, 8)
lstBox.Items.Add(grades(grade1, grade2))


varAverage = Math.Round((grade1 + grade2) / 2)
total += varAverage

Do Until my.Peek <> -1



total = Math.Round(varAverage / keepCount)
For sdtLetterG = 1 To keepCount

Next
Select Case varAverage
Case Is >= 90
sdtLetterG = "A"
Case Is >= 80
sdtLetterG = "B"
Case Is >= 70
sdtLetterG = "C"
Case Is >= 60
sdtLetterG = "D"
Case Is >= 50
sdtLetterG = "F"
End Select

lstBox.Items.Add(String.Format(fmtStr, names(i), grade1, grade2, varAverage, sdtLetterG))

my.Close()

total += varAverage


total = Math.Round(total / keepCount)

txtDsplyClsAvr.Text = "The class average is " & CStr(total)

Else

MsgBox("Try putting in the disk that has grades.txt on it!", , "Missing Disk")
lstBox.Items.Add(names(i), grade1, grade2, varAverage, sdtLetterG))
End If
[/VB]
This code produces all of my names and grades, however it is not seperating them into the rows and columns. Instead it is placeing the grades under the names? Aslo I have no idea on how to get the names grades, averages, and letterGrade into zones as I done on the program before?
 
In order to get the data to show up on the same line, youll probably have to use a Tab and add everything to the listbox that you want to be on a row at once.
Or, you can use some sort of table/grid control.

Youll also need to bring back your counter while you read the file to get the grades.
lstBox.Items.Add(names(i) & " - " & grade1 & " - " & grade2)
or something similar to that.

And I dont know what you mean by a zone.
:)
 
Here is the final code for that program.
Code:
Private Sub btn1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn1.Click

        Dim my As IO.StreamReader
        Dim fmtStr As String = "{0,1}{1, 4}{2,5} {3,6}  {4,11}  {5,4}{6,3}"  BTW HERE IS WHAT MAKES THE ZONES!!
        Dim student, start, temp, strLetterGrade, studentName() As String
        Dim intCount, name, row, col, average As Integer
        Dim total, grades(,), intStart As Double
        intCount = 0
        If IO.File.Exists("A:grades.txt") Then
            my = IO.File.OpenText("A:grades.txt")
            Do While my.Peek <> -1
                student = my.ReadLine
                intCount += 1

            Loop
        


            my.Close()
            my = IO.File.OpenText("A:grades.txt")
            ReDim studentName(intCount)
            ReDim grades(intCount, 2)
                   Array.Sort(studentName)
            For name = 1 To intCount
                start = my.ReadLine
                studentName(name) = start.Substring(0, 11)
                intStart = 12
                For col = 1 To 2
                    grades(name, col) = start.Substring(intStart, 4)
                    intStart = intStart + 4
                    average += CInt(grades(name, col))

                Next
                average = cint(grades(name, 1) + grades(name, 2)
                average = average / 2
                Select Case average
                    Case Is >= 90
                        strLetterGrade = "A"
                    Case Is >= 80
                        strLetterGrade = "B"
                    Case Is >= 70
                        strLetterGrade = "C"
                    Case Is >= 60
                        strLetterGrade = "D"
                    Case Is >= 50
                        strLetterGrade = "F"
                End Select
                total = Math.Round(average + total / intCount)
                lstGrades.Items.Add(String.Format(fmtStr, studentName(name), grades(name, 1), "", grades(name, 2), average, "", strLetterGrade))
                average = 0

            Next

            Select Case total
                Case Is >= 90
                    strLetterGrade = "A"
                Case Is >= 80
                    strLetterGrade = "B"
                Case Is >= 70
                    strLetterGrade = "C"
                Case Is >= 60
                    strLetterGrade = "D"
                Case Is >= 50
                    strLetterGrade = "F"
            End Select
            total = Math.Round(total / intCount, 0)
            txtDsplyClsAvr.Text = "The class average is " & CStr(total) & " " & (strLetterGrade)

            my.Close()
        Else
            MsgBox("Try putting in the disk that has grades.txt on it!", , "Missing Disk")
        End If


    End Sub
End Class
Now to figure out how to make it sort into an aphabetical order and make the grades follow along too.
 
Looks like youre going to need to make your own Sorting.
You may be able to make a copy of the array, sort one of them, and then find where the names have moved by looking at the old array, then the new array, and then moving the grades in the grade array by the same amount :).
 
Back
Top