verifying an answer?
- Hi everyone, I'm new to the forum. I do have a little knowledge of Visual Basic but not a lot. Currently I am trying to help a former teacher of mine. She has created a program that allows her students to study for tests. She has the program set up so that it is a fill in the blank format so to provide a little more of a challenge for the students. She has the textboxes set up so that they are line up right below where the word should be; however, she and myself have been trying to find some information online that will allow the program to check the answer and make sure it matches the missing word. We've been searching all over for a couple weeks now with no luck, which brings me to starting this thread. The only source of code that we have found looks like this:
That is the only code that we have found that would allow our program to check the answer to see if it is correct, but we get an error with the code. Is there any other way to do this? I'm not specifically asking for code just a little help with the problem, but any help given will be appreciated by the both of us.Function CheckAnswers() As Integer Dim Errors As Integer = 0 For i As Integer = 0 To NumberofBlanks - 1 If AnswerList(i).ToUpper <> WordArray(SelectedWords(i)).ToUpper Then Errors += 1 Next If Errors = 0 Then MsgBox("Congratulations. Please select the next paragraph") Else MsgBox("You got " & Errors.ToString & " Incorrect. Please try again or move on to the next") End If Return Errors End Function
Respuestas
- What is the error message and exactly where is it occurring?
The code is comparing each item in the AnswerList array with the corresponding item in the SelectedWords array and counting one error for each mismatch.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:33
- It means that one of those arrays has not been initialised correctly. You should examine each of the arrays to see what type it is, and to see what values it contains. One of them will indicate nothing. You can examine variables by hovering the mouse over each one, or by selecting the variable, right clicking and add it to Watch. The Watch window shold open for you as soon as you add something to watch.
Note that my first description is not quite correct - it should be : The code is comparing each item in the AnswerList array with the item in the WordArray array nominated by the corresponding item in the SelectedWords array, and counting one error for each mismatch. There are three arrays involved - AnswerList, WordArray and SelectedWords.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:33
- What happens if you select any of the array names and right click and choose Add Watch? Note that I am assuming that you are doing this when you try to run the progeram and it stops at the error.
Nothing is not the same as zero - your message indicates that the item has never been initialised to any value. Zero is probably a valid value for some of your variables, but Nothing is invalid and will create an error.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:33
- You need to find the code whereWordArray is being initialised - that is, loaded with its values. Either that code is wrong, or is not being executed. You may wish to post the code associated with the initialiation of WordArray if you can't see what might be wrong in setting it up, or you could step through it lione by line to see what is happening and why it is still nothing.
Please don't mix the different versions of your code, as your errors will multiply, not reduce.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:33
- WordArray contains all the words in the text. SelectedWords contains the word number of the words that were selected - eg, 5,8,10,11. AnswerList contains the answers.
If the text is:
Now is the time for all good men to come to the party
then Answerlist(0) (the first answer) is compared to Word WordArray(SelectedWord(0)) which is WordArray(5) which is 'all". AnswerList(1) (the second answer) is compared to Word WordArray(SelectedWord(1)) which is WordArray(8) which is "men", and so on.
Did the error still occur when WordArray had a count of 13?- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
- Then you should look at each item in the array and see whether any of them is blank. If the array contains the full 13 words of the text (one in each element) numbered 0 to 12 then the problem is not with WordArray but with one of the other variables.
Are you sure that the error message does not identify the exact variable that is involved?- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
- ToUpper is a string function and does not need to be decalred. If you can't identify the variable in error from the error message, you need to look at each variable on that line in the same way that you have looked at WordArray. Can you confirm that WordArray is an array of string and SelectedWords is an array of Integer?
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
An array comparison using one indexer is perfectly valid. The SelectedWords array is sorted, and the AnswerList is required to be in the order of the selected words. This is not a comparison of each A() with any B() - it is a comparison of each A() with the corresponding B(). The comparison does not need two indexers.
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
- There will be, say, 12 words. A selected number (say, 4) will be blanked out. SelectedWords contains the (sorted) list of blanked word numbers - that is, the index in WordArrray of those words that are blanked. That's why the comparison is between the answer array element asn the WordArray item indexed by the corresponding element in SelectedWords.
So Answer(0) is compared to WordArray(SelectedWords(0)), etc.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
The problem is probably with the indexing of SelectedWords - because it is a list not an array then an indexing error will give a null reference error instead of an array bounds error. How many blanks are there? What is the value of I and numberofblanks? Provide the code (the whole loop) surrounding the place where SelectedWords.Add(...) is occurring.
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
- I think you have mixed up the code from two different, but apparently similar, programs.
In the code posted above you are creating a number of text boxes which I presume are for the user to type the answers into.
You original code expected the answers to be in an array called AnswerList.
You should either copy the answers from the text boxes into the AswerList array, or you can access the text box answers directly using code changes like this:
Instead of
If AnswerList(i).ToUpper <> WordArray(SelectedWords(i)).ToUpper Then Errors += 1
use
If TextBoxes(i).Text.ToUpper <> WordArray(SelectedWords(i)).ToUpper Then Errors += 1- EditadoAcamar miércoles, 04 de noviembre de 2009 0:53
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
- Is my assumption that the answers are in the textboxes and not in the AnswerArray correct?
Are you sure that all questions had been answered before this routine executes? If the routine runs before the hidden words have been seelcted, you will get the error that you have indicated. Note that the code posted here includes no error checking, eg for doing the operations in teh right sequence. That is all still to be added.
What was the value of the index (i)? What was the Count for each of the arrays (TextBoxes, WordArray and SelectedWords)?- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:31
- This is the complete code for the problem. It includes some basic error checking, for instance for trying to check before there is an answer. It requires a text box (txtMemoryText) and four buttons - cmdShow (displays the full text) cmdHide (Displays the text with selected words hidden) cmdCheck (checks the answers against the hidden words) and cmdNext (moves on to the next string. I have provided 5 sample strings to show how you might arrange to provide multiple text paragraphs - this will have to be modified to suit the actual source of your text.
You will have to independentaly validate the spelling and accuracy of the texts.
Public Class Form1 Dim Qtext(5) As String Dim QPointer As Integer = 0 Dim TextBoxes As New List(Of TextBox) Dim NumberofBlanks As Integer = 5 Dim WordArray() As String Dim SelectedWords As New List(Of Integer) Dim Rand As New Random(12345) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Qtext(0) = "In 1775 British forces defeated the colonial forces under the command of Prescott beseiging Boston at the battle of Bunker Hill" Qtext(1) = "In 1805 Nelson defeated the French and Spanish fleets at the battle of Trafalgar" Qtext(2) = "In 1815 Wellington defeated the French at the battle of Trafalgar, leading an army known as the Seventh Coalition" Qtext(3) = "In 1880 British forces under Roberts inflicted a massive defeat on local forces led by Ayub Khan at the Battle of Kandahar" Qtext(4) = "In 1900 Baden-Powell and an army that was raised from local manpower held the town of Mafeking against Boer forces for 217 days until releived by British Forces" End Sub Private Sub cmdShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdShow.Click For Each t As TextBox In TextBoxes Me.Controls.Remove(t) Next TextBoxes.Clear() txtMemoryText.Text = Qtext(QPointer) End Sub Private Sub CMDHide_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdHide.Click txtMemoryText.Text = "" WordArray = Split(Qtext(QPointer), " ") Dim NumberCount As Integer = 0 SelectedWords.Clear() Do Dim randomNumber As Integer randomNumber = Rand.Next(0, WordArray.Length) ' Ensure this random number was not already selected If (Not SelectedWords.Contains(randomNumber)) Then SelectedWords.Add(randomNumber) NumberCount += 1 End If SelectedWords.Sort() Loop While (NumberCount < NumberofBlanks) For I As Integer = 0 To WordArray.Count - 1 If Not SelectedWords.Contains(I) Then txtMemoryText.Text &= WordArray(I) & " " Else txtMemoryText.Text &= "-------- " End If Next For I As Integer = 0 To NumberofBlanks - 1 Dim T As New TextBox Me.Controls.Add(T) T.Top = txtMemoryText.Top + txtMemoryText.Height + 10 T.Width = 60 T.Left = txtMemoryText.Left + (T.Width + 10) * I TextBoxes.Add(T) Next End Sub Private Sub cmdCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCheck.Click If TextBoxes.Count = 0 Then MsgBox("You must hide the answers before checking") Exit Sub End If Dim Errors As Integer = 0 For i As Integer = 0 To NumberofBlanks - 1 If TextBoxes(i).Text.ToUpper <> WordArray(SelectedWords(i)).ToUpper Then Errors += 1 Next If Errors = 0 Then MsgBox("Congratulations. Please select the next paragraph") Else MsgBox("You got " & Errors.ToString & " Incorrect. Please try again or move on to the next") End If End Sub Private Sub cmdNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdNext.Click QPointer = (QPointer + 1) Mod 5 cmdShow_Click(Me, New System.EventArgs) End Sub End Class
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:31
- I don't understand what you are trying to do. TryAgain means show the text string so the user can try again to memorise it - it doesn't mean hide a different set of words. So I can't see a reason for combining TryAgain and Hide - they are two separate steps in the process and should occur at two different times.
In any case, you can't just take some code from one program and combine with code from another - it won't wok. If the code already provided doesn't work the way you want, it should be changed to make it work correctly. But you can't take working bits from one program and stick them into another and expect the result to work properly. You could, however, use the above example as a guide to what you need to do to modify your own program to work the way you want. But in that case we would need to know exactly what your modified code looks like.
A stack overflow probably means you have a function that calls itself.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:31
- That's correct - Try Again should give the student a new attempt at learning the words. But it shouldn't hide the words - it should leave them displayed (Show) so the student can learn them. When the student has learnt them, the student then selects Hide, a different set of words will be hidden, and the student enters their guesses. There is nothing in the current code that just selects the same words to hide - I don't understand where that comment comes from.
If you really want a function that repeats Show and then immediately executes Hide, just use these lines:
cmdShow_Click(Me, New System.EventArgs)
cmdHide_Click_1(Me, New System.EventArgs)
but I can't think of any reason why you would want to do this.
The code above will not work, but if it did it wouldn't do anything different than Hide does - selects a new set of words to hide using the same text. Unless, perhaps, you are concerened that the old guesses are still visible when the ne words are hidden - obviously they are not relevant to the new hidden words. In that case simply add the following line at the start of the Hide function:
cmdShow_Click(Me, New System.EventArgs)
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:31
- That sounds reasonable. I might quibble with the label "Try again" when there is no option to try the first time, but that doesn't affect the functionality. If you use the code I used for those four buttons it will work as described - Show shows the full text, TryAgain hides the selected words and reveals the text boxes for entering the naswers, Check examines the text boxes and indicates the result, and Next points to the next text string and executes a Show. TryAgain can be repeated as often as required and will hide a different set of words each time it is executed. Check also checks that the text has been hidden and gives a message if it hasn't, so you can't Check without first trying.
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:30
- You have indicated above that your TryAgain procedure is equivalent to my Hide procedure. So you should be using the code that I provided in the Hide procedure.
The code you have above is a corrupted version of what I suggested for a TryAgain procedure when you posted code for the procedure that was an amalgamation of my code for Show and Hide. I said at the time that I couldn't understand why you would want to do this, because it seemed poinless to show the full text again without allowing the user time to read it, but that if you wanted to do that you wouldn't amalgamate the code from the two procedures, you would just call the two procedures in turn. So I suggested.
cmdShow_Click(Me, New System.EventArgs)
cmdHide_Click_1(Me, New System.EventArgs)
You have changed this in a manner similar to the change you made to the Next procedure, so that it calls itself - you will get a stack overlfow if you use that code.
Go through your TryAgain code again, comparing it line by line to what I posted for Hide, remebering that the only problem you are now trying to track down is why the same words get hidden each time the procedure runs, instead of a different random set of words. It is a single small error left over from when you tried to build the TryAgain procedure using that amalgamation of Show and Hide.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:30
- Please compare these two portions:
1. The code that I provided:
txtMemoryText.Text = ""
WordArray = Split(Qtext(QPointer), " ")
Dim NumberCount As Integer = 0
SelectedWords.Clear()
Do
Dim randomNumber As Integer
randomNumber = Rand.Next(0, WordArray.Length)
If (Not SelectedWords.Contains(randomNumber)) Then
SelectedWords.Add(randomNumber)
NumberCount += 1
End If
SelectedWords.Sort()
Loop While (NumberCount < NumberofBlanks)
2. The code that you have posted:
txt2memorize.Text = ""
WordArray = Split(TextSet1, " ")
Dim NumberCount As Integer = 0
SelectedWords.Clear()
Dim Rand As New Random(12345)
Do
Dim randomNumber As Integer
randomNumber = Rand.Next(0, WordArray.Length)
If (Not SelectedWords.Contains(randomNumber)) Then
SelectedWords.Add(randomNumber)
NumberCount += 1
End If
SelectedWords.Sort()
Loop While (NumberCount < NumberofBlanks)
Remember that the problem is that the random numbers aren't random - they are a repeat of what was selected last time.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:29
Todas las respuestas
- What is the error message and exactly where is it occurring?
The code is comparing each item in the AnswerList array with the corresponding item in the SelectedWords array and counting one error for each mismatch.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:33
- When I hit the check button it turns this code yellow:The box beside it says NullReferenceException was unhandled. Object reference not set to an instance of an object.
If AnswerList(i).ToUpper <> WordArray(SelectedWords(i)).ToUpper Then
Everything I have found about the NullReferenceException came up with the same result. They all said to set it equal to Nothing. That doesn't make any sense to me, but I did what it said and it gave me this error. Before I did that it had some other kind of NullReferencException that said something about it being equal to I think 0. - It means that one of those arrays has not been initialised correctly. You should examine each of the arrays to see what type it is, and to see what values it contains. One of them will indicate nothing. You can examine variables by hovering the mouse over each one, or by selecting the variable, right clicking and add it to Watch. The Watch window shold open for you as soon as you add something to watch.
Note that my first description is not quite correct - it should be : The code is comparing each item in the AnswerList array with the item in the WordArray array nominated by the corresponding item in the SelectedWords array, and counting one error for each mismatch. There are three arrays involved - AnswerList, WordArray and SelectedWords.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:33
- You have to explain a little better how are the textbox.texts put into an array and which array is it WordArray or SelectedWords ? What little you have posted isn't enough .
coding for fun Be a good forum member mark posts that contain the answers to your questions or those that are helpful
Please format the code in your posts with the
button . Makes it easier to read . Every number I put my mouse over it says Integer represents a 32 bit integer. I have a couple of things that are equal to 0 but if I change the numbers I still receive the same error. Am I misunderstanding something about this Nothing statement thing?
- What happens if you select any of the array names and right click and choose Add Watch? Note that I am assuming that you are doing this when you try to run the progeram and it stops at the error.
Nothing is not the same as zero - your message indicates that the item has never been initialised to any value. Zero is probably a valid value for some of your variables, but Nothing is invalid and will create an error.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:33
- I copied and pasted the code that DeMolay8613 was using into a new project just to see how it works the way you originally intended it and I got it to show the same error that I'm getting and it says that WordArray is equal to Nothing. I've compared it to my program and found the one that is equal to Nothing. What should I do next?
- You need to find the code whereWordArray is being initialised - that is, loaded with its values. Either that code is wrong, or is not being executed. You may wish to post the code associated with the initialiation of WordArray if you can't see what might be wrong in setting it up, or you could step through it lione by line to see what is happening and why it is still nothing.
Please don't mix the different versions of your code, as your errors will multiply, not reduce.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:33
- Ok, then what I will do is I will post DeMolay8613's code and I will just compare it to mine because since that is where the code for the CheckAnswers originally come from and it will be fairly easy to fix mine once I see how the original code is fixed. I hope that makes sense.
I ran the program again but this time I didn't find anything at all that was equal to Nothing. WordArray was equal to 13 which was the number of words in the text. I"m confused now. Hi everyone, I'm new to the forum. I do have a little knowledge of Visual Basic but not a lot. Currently I am trying to help a former teacher of mine. She has created a program that allows her students to study for tests. She has the program set up so that it is a fill in the blank format so to provide a little more of a challenge for the students. She has the textboxes set up so that they are line up right below where the word should be; however, she and myself have been trying to find some information online that will allow the program to check the answer and make sure it matches the missing word. We've been searching all over for a couple weeks now with no luck, which brings me to starting this thread. The only source of code that we have found looks like this:
That is the only code that we have found that would allow our program to check the answer to see if it is correct, but we get an error with the code. Is there any other way to do this? I'm not specifically asking for code just a little help with the problem, but any help given will be appreciated by the both of us.Function CheckAnswers() As Integer Dim Errors As Integer = 0 For i As Integer = 0 To NumberofBlanks - 1 If AnswerList(i).ToUpper <> WordArray(SelectedWords(i)).ToUpper Then Errors += 1 Next If Errors = 0 Then MsgBox("Congratulations. Please select the next paragraph") Else MsgBox("You got " & Errors.ToString & " Incorrect. Please try again or move on to the next") End If Return Errors End Function
You write that you have missing words and a list of the users answers but I see AnswerList , WordArray and SelectedWords . You don't care to explain and/or show code about them how they are created or defined or what they are . Well fine I don't need to know I have better things to do anyway .
coding for fun Be a good forum member mark posts that contain the answers to your questions or those that are helpful
Please format the code in your posts with the
button . Makes it easier to read .- WordArray contains all the words in the text. SelectedWords contains the word number of the words that were selected - eg, 5,8,10,11. AnswerList contains the answers.
If the text is:
Now is the time for all good men to come to the party
then Answerlist(0) (the first answer) is compared to Word WordArray(SelectedWord(0)) which is WordArray(5) which is 'all". AnswerList(1) (the second answer) is compared to Word WordArray(SelectedWord(1)) which is WordArray(8) which is "men", and so on.
Did the error still occur when WordArray had a count of 13?- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
- Yes it still occured when it had a count of 13.
- Then you should look at each item in the array and see whether any of them is blank. If the array contains the full 13 words of the text (one in each element) numbered 0 to 12 then the problem is not with WordArray but with one of the other variables.
Are you sure that the error message does not identify the exact variable that is involved?- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
Which one is considered to be the exact variable? Also when I look at WordArray in the Watch thing at the bottom they are numbered from 0 to 12 and every word is there and in the correct order just like they should be.
- Is one variable highlighted, or the whole line? Is there anything in Details that indicates the variable involved?
- Hallo bamakid,
It is impossible to compare two arrays to each other in one for loop and one indexer (there are special cases it's possible but not in this situation)
So or you have to extend your loop with another loop or simply do it like this (it is not complete because you have to make that first more loop correct).
Function CheckAnswers() As Integer Dim Errors As Integer = 0 For Each selectedWord As String In WordArray 'I don't know the method you've used for that For i As Integer = 0 To AnswerList.length - 1 If AnswerList(i).ToUpper.Trim <> selectedWord.ToUpper.Trim Then Errors += 1 Next Next If Errors = 0 Then MsgBox("Congratulations. Please select the next paragraph") Else MsgBox("You got " & Errors.ToString & " Incorrect. Please try again or move on to the next") End If Return Errors End Function
Success
Cor - The whole line is highlighted beginning with the word If and goes through the word Then.
Would the fact that ToUpper is not declared have any effect on this error? Also when I add AnswerList to the Watch thing at the bottom I click on the button that lets me view all of the parts of the array and it's numbered from 0 to 5 and each part of the array has a value of Nothing. Just thought I'd give you all possible problems that I just have noticed. - Did you see my reply?
Success
Cor Yes, I did after I posted my reply.
- ToUpper is a string function and does not need to be decalred. If you can't identify the variable in error from the error message, you need to look at each variable on that line in the same way that you have looked at WordArray. Can you confirm that WordArray is an array of string and SelectedWords is an array of Integer?
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
An array comparison using one indexer is perfectly valid. The SelectedWords array is sorted, and the AnswerList is required to be in the order of the selected words. This is not a comparison of each A() with any B() - it is a comparison of each A() with the corresponding B(). The comparison does not need two indexers.
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
- I am still trying to figure out the design of this . I mean you have 12 words lets say and 12 textboxes . Can't you just compare the first word with the first textbox ? Does the program allow the teacher to pick words to blank out ?
coding for fun Be a good forum member mark posts that contain the answers to your questions or those that are helpful
Please format the code in your posts with the
button . Makes it easier to read . - There will be, say, 12 words. A selected number (say, 4) will be blanked out. SelectedWords contains the (sorted) list of blanked word numbers - that is, the index in WordArrray of those words that are blanked. That's why the comparison is between the answer array element asn the WordArray item indexed by the corresponding element in SelectedWords.
So Answer(0) is compared to WordArray(SelectedWords(0)), etc.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
+ WordArray {Length=13} String()
+ AnswerList {Length=6} String()
+ SelectedWords Count = 5 System.Collections.Generic.List(Of Integer)
That is what it says in the watch thing at the bottom of the screen.The problem is probably with the indexing of SelectedWords - because it is a list not an array then an indexing error will give a null reference error instead of an array bounds error. How many blanks are there? What is the value of I and numberofblanks? Provide the code (the whole loop) surrounding the place where SelectedWords.Add(...) is occurring.
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
- Name Value Type
+ WordArray {Length=13} String()
+ AnswerList {Length=6} String()
+ SelectedWords Count = 5 System.Collections.Generic.List(Of Integer)
i 0 Integer
NumberofBlanks 5 Integer
There are 5 blanks as shown above.
I believe that should cover everything that you asked for.Private Sub TryAgain1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TryAgain1.Click 'Occurs when the user clicks the Hide button 'Clears the displayed text txt2memorize.Text = "" 'Creates an array of words from the text WordArray = Split(TextSet1, " ") 'Initialize the counter for the number of words being processed Dim NumberCount As Integer = 0 'ADDITION. Clear the selected words list SelectedWords.Clear() Dim Rand As New Random(12345) 'Copied from previous code. Finds random words to hide. Do Dim randomNumber As Integer 'Gets next random number. randomNumber = Rand.Next(0, WordArray.Length) 'Ensures this random number was not already selected If (Not SelectedWords.Contains(randomNumber)) Then 'Adds it to the list of random word numbers SelectedWords.Add(randomNumber) 'and increments the counter (so we know when to stop) NumberCount += 1 End If 'Sorts the word numbers SelectedWords.Sort() Loop While (NumberCount < NumberofBlanks) 'Displays the text with blanks for selected words 'For all the words in the word array - For I As Integer = 0 To WordArray.Count - 1 'If it has _not_ been selected to hide, show it If Not SelectedWords.Contains(I) Then txt2memorize.Text &= WordArray(I) & " " Else 'If it _has_ been selected to hide, show a few dashes instead txt2memorize.Text &= "------" End If Next Dim TextBoxes As New List(Of TextBox) 'For each hidden word For I As Integer = 0 To NumberofBlanks - 1 'Create a text box for it Dim T As New TextBox 'Add the text box to the form Me.Controls.Add(T) 'Set the position and sixe of the new text box T.Top = txt2memorize.Top + txt2memorize.Height + 10 T.Width = 60 T.Left = txt2memorize.Left + (T.Width + 10) * I 'Add it to the list of answer text boxes (s we can refer to it when needed) TextBoxes.Add(T) Next End Sub
- I think you have mixed up the code from two different, but apparently similar, programs.
In the code posted above you are creating a number of text boxes which I presume are for the user to type the answers into.
You original code expected the answers to be in an array called AnswerList.
You should either copy the answers from the text boxes into the AswerList array, or you can access the text box answers directly using code changes like this:
Instead of
If AnswerList(i).ToUpper <> WordArray(SelectedWords(i)).ToUpper Then Errors += 1
use
If TextBoxes(i).Text.ToUpper <> WordArray(SelectedWords(i)).ToUpper Then Errors += 1- EditadoAcamar miércoles, 04 de noviembre de 2009 0:53
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:32
- I guess I'm not as good at comparing code and editing it to work with something else as much as I thought I was. lol
I tried what you said and it gave me this error:
Error 1 'ToUpper' is not a member of 'System.Windows.Forms.TextBox'.
It said that on the ToUpper that is right after the TextBoxes(i) - I noticed that you edited your post and so I made the changes that you said and so my error changed to ArgumentOutOfRangeException was unhandled. Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
I'm fixing to look it up and see what I can find out. - Is my assumption that the answers are in the textboxes and not in the AnswerArray correct?
Are you sure that all questions had been answered before this routine executes? If the routine runs before the hidden words have been seelcted, you will get the error that you have indicated. Note that the code posted here includes no error checking, eg for doing the operations in teh right sequence. That is all still to be added.
What was the value of the index (i)? What was the Count for each of the arrays (TextBoxes, WordArray and SelectedWords)?- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:31
- Once again i has a value of 0. The count for TextBoxes is 0. The Count for WordArray is 13. The count for SelectedWords is 5. See if this answers your question about the answers.
http://s265.photobucket.com/albums/ii238/hughesco09/?action=view¤t=textboxanswers.jpg - That indicates that the function is executing before the words are being hidden. The textboxes are only created when the words are hidden (the TryAgain routine, above). You need to ensure that the routines are execute din teh correct sequence.
You could put a test at the top of the routine to exit immediately if the textboxes count is zero. Ok, I just noticed that you edited one of your posts. To clarify what it is doing here is what happens.
When I start the program the only thing shown is a blank textbox and the 3 buttons.
When I hit Try Again button the words appear with blanks and with the 5 blank textboxes below that.
I enter my answers in the 5 textboxes and hit the Check Answers button and the error appears.- This is the complete code for the problem. It includes some basic error checking, for instance for trying to check before there is an answer. It requires a text box (txtMemoryText) and four buttons - cmdShow (displays the full text) cmdHide (Displays the text with selected words hidden) cmdCheck (checks the answers against the hidden words) and cmdNext (moves on to the next string. I have provided 5 sample strings to show how you might arrange to provide multiple text paragraphs - this will have to be modified to suit the actual source of your text.
You will have to independentaly validate the spelling and accuracy of the texts.
Public Class Form1 Dim Qtext(5) As String Dim QPointer As Integer = 0 Dim TextBoxes As New List(Of TextBox) Dim NumberofBlanks As Integer = 5 Dim WordArray() As String Dim SelectedWords As New List(Of Integer) Dim Rand As New Random(12345) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Qtext(0) = "In 1775 British forces defeated the colonial forces under the command of Prescott beseiging Boston at the battle of Bunker Hill" Qtext(1) = "In 1805 Nelson defeated the French and Spanish fleets at the battle of Trafalgar" Qtext(2) = "In 1815 Wellington defeated the French at the battle of Trafalgar, leading an army known as the Seventh Coalition" Qtext(3) = "In 1880 British forces under Roberts inflicted a massive defeat on local forces led by Ayub Khan at the Battle of Kandahar" Qtext(4) = "In 1900 Baden-Powell and an army that was raised from local manpower held the town of Mafeking against Boer forces for 217 days until releived by British Forces" End Sub Private Sub cmdShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdShow.Click For Each t As TextBox In TextBoxes Me.Controls.Remove(t) Next TextBoxes.Clear() txtMemoryText.Text = Qtext(QPointer) End Sub Private Sub CMDHide_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdHide.Click txtMemoryText.Text = "" WordArray = Split(Qtext(QPointer), " ") Dim NumberCount As Integer = 0 SelectedWords.Clear() Do Dim randomNumber As Integer randomNumber = Rand.Next(0, WordArray.Length) ' Ensure this random number was not already selected If (Not SelectedWords.Contains(randomNumber)) Then SelectedWords.Add(randomNumber) NumberCount += 1 End If SelectedWords.Sort() Loop While (NumberCount < NumberofBlanks) For I As Integer = 0 To WordArray.Count - 1 If Not SelectedWords.Contains(I) Then txtMemoryText.Text &= WordArray(I) & " " Else txtMemoryText.Text &= "-------- " End If Next For I As Integer = 0 To NumberofBlanks - 1 Dim T As New TextBox Me.Controls.Add(T) T.Top = txtMemoryText.Top + txtMemoryText.Height + 10 T.Width = 60 T.Left = txtMemoryText.Left + (T.Width + 10) * I TextBoxes.Add(T) Next End Sub Private Sub cmdCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCheck.Click If TextBoxes.Count = 0 Then MsgBox("You must hide the answers before checking") Exit Sub End If Dim Errors As Integer = 0 For i As Integer = 0 To NumberofBlanks - 1 If TextBoxes(i).Text.ToUpper <> WordArray(SelectedWords(i)).ToUpper Then Errors += 1 Next If Errors = 0 Then MsgBox("Congratulations. Please select the next paragraph") Else MsgBox("You got " & Errors.ToString & " Incorrect. Please try again or move on to the next") End If End Sub Private Sub cmdNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdNext.Click QPointer = (QPointer + 1) Mod 5 cmdShow_Click(Me, New System.EventArgs) End Sub End Class
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:31
What I did was I combined the code for the hide that you just provide with the try again code I already had and just made them one whole sub that happens when you hit the Try Again button. However if you hit the try again button and then enter your answers and hit the check button it says that I must hide the answers.
Then when I hit the next button I get an error saying StackOverflowException was unhandled. An unhandled exception of type 'System.StackOverflowException' occurred in Chapter 8 Review.exe- I don't understand what you are trying to do. TryAgain means show the text string so the user can try again to memorise it - it doesn't mean hide a different set of words. So I can't see a reason for combining TryAgain and Hide - they are two separate steps in the process and should occur at two different times.
In any case, you can't just take some code from one program and combine with code from another - it won't wok. If the code already provided doesn't work the way you want, it should be changed to make it work correctly. But you can't take working bits from one program and stick them into another and expect the result to work properly. You could, however, use the above example as a guide to what you need to do to modify your own program to work the way you want. But in that case we would need to know exactly what your modified code looks like.
A stack overflow probably means you have a function that calls itself.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:31
- The purpose that I had in mind for the Try Again button was to give the student another try at learning the material, but the program would reselect new words to remove. Because if it just removed the same words again then that would make it too easy and the student wouldn't actually be learning anything.
Private Sub TryAgain1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TryAgain1.Click Dim TextBoxes As New List(Of TextBox) For Each t As TextBox In TextBoxes Me.Controls.Remove(t) Next TextBoxes.Clear() txt2memorize.Text = TextSet(QPointer) 'Occurs when the user clicks the Hide button 'Clears the displayed text txt2memorize.Text = "" 'Creates an array of words from the text WordArray = Split(TextSet(QPointer), " ") 'Initialize the counter for the number of words being processed Dim NumberCount As Integer = 0 'ADDITION. Clear the selected words list SelectedWords.Clear() Dim Rand As New Random(12345) 'Copied from previous code. Finds random words to hide. Do Dim randomNumber As Integer 'Gets next random number. randomNumber = Rand.Next(0, WordArray.Length) 'Ensures this random number was not already selected If (Not SelectedWords.Contains(randomNumber)) Then 'Adds it to the list of random word numbers SelectedWords.Add(randomNumber) 'and increments the counter (so we know when to stop) NumberCount += 1 End If 'Sorts the word numbers SelectedWords.Sort() Loop While (NumberCount < NumberofBlanks) 'Displays the text with blanks for selected words 'For all the words in the word array - For I As Integer = 0 To WordArray.Count - 1 'If it has _not_ been selected to hide, show it If Not SelectedWords.Contains(I) Then txt2memorize.Text &= WordArray(I) & " " Else 'If it _has_ been selected to hide, show a few dashes instead txt2memorize.Text &= "------" End If Next 'For each hidden word For I As Integer = 0 To NumberofBlanks - 1 'Create a text box for it Dim T As New TextBox 'Add the text box to the form Me.Controls.Add(T) 'Set the position and sixe of the new text box T.Top = txt2memorize.Top + txt2memorize.Height + 10 T.Width = 60 T.Left = txt2memorize.Left + (T.Width + 10) * I 'Add it to the list of answer text boxes so we can refer to it when needed) TextBoxes.Add(T) Next End Sub
- That's correct - Try Again should give the student a new attempt at learning the words. But it shouldn't hide the words - it should leave them displayed (Show) so the student can learn them. When the student has learnt them, the student then selects Hide, a different set of words will be hidden, and the student enters their guesses. There is nothing in the current code that just selects the same words to hide - I don't understand where that comment comes from.
If you really want a function that repeats Show and then immediately executes Hide, just use these lines:
cmdShow_Click(Me, New System.EventArgs)
cmdHide_Click_1(Me, New System.EventArgs)
but I can't think of any reason why you would want to do this.
The code above will not work, but if it did it wouldn't do anything different than Hide does - selects a new set of words to hide using the same text. Unless, perhaps, you are concerened that the old guesses are still visible when the ne words are hidden - obviously they are not relevant to the new hidden words. In that case simply add the following line at the start of the Hide function:
cmdShow_Click(Me, New System.EventArgs)
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:31
- I created the Show button. I was just afraid that it might look like too much if I had 4 buttons, but I guess you gotta do what you gotta do so the program will run correctly. I'm still getting the Stack Overflow Exception when I hit the next button. It happens on this code:
You said had to do with calling on itself and I looked the code up and it has to call on it self for the syntax to be correct. That is if I understood correctly what the help said. It has to have the Next1_Click because that tells the program that it happens when you click on the button and it has to have the Me because it's happening in the same form that the button is in. So I'm not quite sure why it throws this exception.Next1_Click(Me, New System.EventArgs)
- What is your code for the Next button click event? The code I posted was:
Private Sub cmdNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdNext.Click QPointer = (QPointer + 1) Mod 5 cmdShow_Click(Me, New System.EventArgs) End Sub - It's basically the exact same thing. lol
I figured that if I needed your code to make the Check button work then it would be best use your Next button code too that way it all flows together better.Private Sub Next1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Next1.Click QPointer = (QPointer + 1) Mod 5 Next1_Click(Me, New System.EventArgs) End Sub - It's not the same thing at all. You are calling the function from within itself. That's what's causing the stack overlfow. I don't understand what you were expecting to accomplish by changing the code like this. When the next button is clicked the counter is incremented to point to the next text item, and the Show comand is executed. Is that what should happen?
- I changed it to Show1_Click and it worked. I understand what yoiu mean now about the counter is incremented to execute the show command.
- One last thing...I've noticed that when I press the hide button it does remove 5 words; however, 2 of the words are ALWAYS side by side so it looks like one large blank..I'm afraid that the students might get confused by this...is there like a function or something that I can use to tell it not to pick words that are side by side? I figured there might be like some kind of If statement or a Function that I could use that would allow this.
- I have tested it here and there are not always two blanks adjacent, although obviously it does happen at times. If it happens every time for your code then you need to examine the way that you are retrieving the random numbers. When it does happen it is not one large blank - the dashes are clearly separated by a space. If this isn't happening in your code, please look at the following lines in the Hide routine to make sure there isn't a mistake:
You can easily change the number of spaces surrounding the dashes.If Not SelectedWords.Contains(I) Then txtMemoryText.Text &= WordArray(I) & " " Else txtMemoryText.Text &= "-------- " End If
I think it is safer to use the String.Compare() function
You can tell it to ignore Case and it handls nulls.
Note that it returns an integer not a boolean
http://msdn.microsoft.com/en-us/library/zkcaxw5y.aspx
Dim strA As String
Dim strB As String
Dim ignoreCase As Boolean
Dim returnValue As Integer
returnValue = String.Compare(strA, _
strB, ignoreCase)
If it's just missing you can simply use the String.IsnullOrEmpty() method.
' This example demonstrates the String.IsNullOrEmpty() method
Imports System
http://msdn.microsoft.com/en-us/library/system.string.isnullorempty.aspxClass Sample
Public Shared Sub Main()
Dim s1 As String = "abcd"
Dim s2 As String = ""
Dim s3 As String = NothingConsole.WriteLine("String s1 {0}.", Test(s1))
Console.WriteLine("String s2 {0}.", Test(s2))
Console.WriteLine("String s3 {0}.", Test(s3))
End Sub 'MainPublic Shared Function Test(s As String) As [String]
If [String].IsNullOrEmpty(s) = True Then
Return "is null or empty"
Else
Return String.Format("(""{0}"") is not null or empty", s)
End If
End Function 'Test
End Class 'Sample
'
'This example produces the following results:
'
'String s1 ("abcd") is not null or empty.
'String s2 is null or empty.
'String s3 is null or empty.
'- I simply changed it from dashes to underscores and added a space at the end. We mentioned before aboutt how if you press show and then press try again after you have already tried it once then it should hide a new set of words..well it's not doing that it just hides the same words over and over and over again.
It does not behave like that here. Every time the Hide function is executed (whether called as a function or by pressing a button) a new set of words is hidden. Your original version of the TryAgain function will, however, have exactly this problem. As indicated previously, that routine won't work. If you haven't changed it as per my suggestion you will get the same words hidden each time.
The original code already had a space at the end of the line of dashes for the blank words, so there may have been an error in transcribing it.- Here is the code that I have:
I compared it to what you had and it looks the same unless I accidently overlooked something. But if it is the same as what you have then why would it do this?Private Sub TryAgain1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TryAgain1.Click 'Occurs when the user clicks the Hide button 'Clears the displayed text txt2memorize.Text = "" 'Creates an array of words from the text WordArray = Split(TextSet(QPointer), " ") 'Initialize the counter for the number of words being processed Dim NumberCount As Integer = 0 'ADDITION. Clear the selected words list SelectedWords.Clear() Dim Rand As New Random(12345) 'Copied from previous code. Finds random words to hide. Do Dim randomNumber As Integer 'Gets next random number. randomNumber = Rand.Next(0, WordArray.Length) 'Ensures this random number was not already selected If (Not SelectedWords.Contains(randomNumber)) Then 'Adds it to the list of random word numbers SelectedWords.Add(randomNumber) 'and increments the counter (so we know when to stop) NumberCount += 1 End If 'Sorts the word numbers SelectedWords.Sort() Loop While (NumberCount < NumberofBlanks) 'Displays the text with blanks for selected words 'For all the words in the word array - For I As Integer = 0 To WordArray.Count - 1 'If it has _not_ been selected to hide, show it If Not SelectedWords.Contains(I) Then txt2memorize.Text &= WordArray(I) & " " Else 'If it has been selected to hide, show a few dashes instead txt2memorize.Text &= "______ " End If Next 'For each hidden word For I As Integer = 0 To NumberofBlanks - 1 'Create a text box for it Dim T As New TextBox 'Add the text box to the form Me.Controls.Add(T) 'Set the position and sixe of the new text box T.Top = txt2memorize.Top + txt2memorize.Height + 10 T.Width = 60 T.Left = txt2memorize.Left + (T.Width + 10) * I 'Add it to the list of answer text boxes so we can refer to it when needed) TextBoxes.Add(T) Next End Sub
- I don't know what part of my code you are comparing to, but i never had anything like that for a tryagain routine. It is similar to the routine that I had for the Hide button click (which I think is the same as what you are trying to do in the tryagain routine). This code looks a lot like the code that I have already advised will not work when you first posted it.
The code I had for the tryagain routine was:
cmdShow_Click(Me, New System.EventArgs)
cmdHide_Click_1(Me, New System.EventArgs)
which I have tested and confirmed as working. - Ok, so you said that you had 4 buttons in your program correct? What are they? Show, Hide, Check and Next?
- Yes. You can pick the buttons I am using from the functions that handle button clicks.
I also have 4 buttons: Show, Try Again, Check Answers, and Next.
My Sow should be the same as your Show. My Try Again should be the same as your Hide, my Check Answers the same as your Check and my Next the same as your Next.- That sounds reasonable. I might quibble with the label "Try again" when there is no option to try the first time, but that doesn't affect the functionality. If you use the code I used for those four buttons it will work as described - Show shows the full text, TryAgain hides the selected words and reveals the text boxes for entering the naswers, Check examines the text boxes and indicates the result, and Next points to the next text string and executes a Show. TryAgain can be repeated as often as required and will hide a different set of words each time it is executed. Check also checks that the text has been hidden and gives a message if it hasn't, so you can't Check without first trying.
- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:30
- Will you look over the last piece of code that I posted on the Try Again button please and make sure that I didn't miss anything when I compared it to your hide button. I may have overlooked something which is causing it to remove the same words over and over again.
- Wait why is your hide labeled hide_click_1 ? Wouldn't just be hide_click?
- The label for the button click event is irrelevant. It can be hide_click or hide_click_1 or just hide or anything at all (actually hide might not work, but that's a different issue). You can choose whatever unique, convenient label you want.
- I have looked over it and you have missed something - that's why I have said (twice) that the code you have posted for the tryagain routine will not work. Replace it with the code I had in the hide routine.
PS - I actually mentioned where you need to look for the problem. - Oh, sorry. I just misunderstood what you meant. So the only thing that will be in the TryAgain1_Click is this:
Show1_Click(Me, New System.EventArgs) TryAgain1_Click(Me, New System.EventArgs)
- You have indicated above that your TryAgain procedure is equivalent to my Hide procedure. So you should be using the code that I provided in the Hide procedure.
The code you have above is a corrupted version of what I suggested for a TryAgain procedure when you posted code for the procedure that was an amalgamation of my code for Show and Hide. I said at the time that I couldn't understand why you would want to do this, because it seemed poinless to show the full text again without allowing the user time to read it, but that if you wanted to do that you wouldn't amalgamate the code from the two procedures, you would just call the two procedures in turn. So I suggested.
cmdShow_Click(Me, New System.EventArgs)
cmdHide_Click_1(Me, New System.EventArgs)
You have changed this in a manner similar to the change you made to the Next procedure, so that it calls itself - you will get a stack overlfow if you use that code.
Go through your TryAgain code again, comparing it line by line to what I posted for Hide, remebering that the only problem you are now trying to track down is why the same words get hidden each time the procedure runs, instead of a different random set of words. It is a single small error left over from when you tried to build the TryAgain procedure using that amalgamation of Show and Hide.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:30
- I have went through both of our codes line by line over and over again and it looks exactly the same to me.
Hi,
Bamakid, can you not create a new question thread in this forum so more persons can help you, this thread is now to long to investigate what is told to you and what not.
Put in the new thread the code you have so far
Success
Cor- Please compare these two portions:
1. The code that I provided:
txtMemoryText.Text = ""
WordArray = Split(Qtext(QPointer), " ")
Dim NumberCount As Integer = 0
SelectedWords.Clear()
Do
Dim randomNumber As Integer
randomNumber = Rand.Next(0, WordArray.Length)
If (Not SelectedWords.Contains(randomNumber)) Then
SelectedWords.Add(randomNumber)
NumberCount += 1
End If
SelectedWords.Sort()
Loop While (NumberCount < NumberofBlanks)
2. The code that you have posted:
txt2memorize.Text = ""
WordArray = Split(TextSet1, " ")
Dim NumberCount As Integer = 0
SelectedWords.Clear()
Dim Rand As New Random(12345)
Do
Dim randomNumber As Integer
randomNumber = Rand.Next(0, WordArray.Length)
If (Not SelectedWords.Contains(randomNumber)) Then
SelectedWords.Add(randomNumber)
NumberCount += 1
End If
SelectedWords.Sort()
Loop While (NumberCount < NumberofBlanks)
Remember that the problem is that the random numbers aren't random - they are a repeat of what was selected last time.- Marcado como respuestabamakid1025 jueves, 05 de noviembre de 2009 7:29
- First of all I didn't finish this code:
Right now in my program for that line I have:WordArray = Split(TextSet1, " ")<br/>
I also took out the line that goes:WordArray = Split(TextSet(QPointer), " ")
So now my code looks like this:Dim Rand As New Random(12345)
txt2memorize.Text = "" Dim NumberCount As Integer = 0 SelectedWords.Clear() Do Dim randomNumber As Integer randomNumber = Rand.Next(0, WordArray.Length) If (Not SelectedWords.Contains(randomNumber)) Then SelectedWords.Add(randomNumber) NumberCount += 1 End If SelectedWords.Sort() Loop While (NumberCount < NumberofBlanks)
- Ok. I guess when I took out the Dim Rand as New Random code it fixed the problem because now it all works like it's supposed to. Thanks.
- Note that if you had been using Option Strict On the error would have been listed as a warning (Variable x hides a variable declared in an enclosing block). Although it does slow you down somewhat when originally entering the code, it more than pays for itself when looking for errors like this.
Thank you for everything Acamar! I'm so happy that I can show my former teacher that her program is finished and all she has to do is change the words in the text whenever she starts a new chapter. Once again thank you!

