For Loops And Arrays - vb.net

I need a little help. My code is work 99% correctly except for one little thing.
I'm making what's called "Cafeteria Survey" which tallies responses from a ComboBox, which the user inputs them self.
The issue here is that it tallies (places a *) the number 1 less than the number I chose in the ComboBox.
If I add + 1 on the end of SelectedIndex it places the * with the correct number, but it doesn't do it for #10
responses(ratingComboBox.SelectedIndex) += 1
Any help would be fantastic. Thanks in advance.
Here's my code:
Public Class CafeteriaSurveyForm
Dim choices As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Dim responses(0 To 11) As Integer
Dim responseCounter As Integer = 0
' displays histogram
Sub DisplayHistogram()
outputTextBox.Text = ("Rating" & vbTab & "Frequency")
For i As Integer = 0 To choices.GetUpperBound(0)
For ii As Integer = 1 To responses(i)
outputTextBox.Text &= ("*")
Next
outputTextBox.Text &= (vbNewLine & choices(i) & vbTab)
Next
End Sub ' DisplayHistogram
Private Sub CafeteriaSurveyForm_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
ratingComboBox.DataSource = choices
End Sub
Private Sub submitButton_Click(sender As System.Object, e As System.EventArgs) Handles submitButton.Click
responseCounter += 1
responses(ratingComboBox.SelectedIndex) += 1
DisplayHistogram()
End Sub
End Class ' CafeteriaSurveyForm

Your display function is a little backward. Here is what you have now:
For i As Integer = 0 To choices.GetUpperBound(0)
For ii As Integer = 1 To responses(i)
outputTextBox.Text &= ("*")
Next
outputTextBox.Text &= (vbNewLine & choices(i) & vbTab)
Next
For every loop it is writing the asterisks to the previous line (because the new line is done after). If you increase the selected index it wrote them in the correct location but never got to write the asterisks for #10 because it exited the for loop before it got a chance.
This is what it should be:
For i As Integer = 0 To choices.GetUpperBound(0)
outputTextBox.Text &= (vbNewLine & choices(i) & vbTab)
For ii As Integer = 1 To responses(i)
outputTextBox.Text &= ("*")
Next
Next
Or even
For i As Integer = 0 To choices.GetUpperBound(0)
outputTextBox.Text &= vbNewLine & choices(i) & vbTab & New String("*", responses(i))
Next
Now the choices and responses arrays are synced using the same indexes and are accessed during the same loop iteration.

Maybe the error is that Responses(i) is defined to be integers in the range 1 to 11. If that range isn't inclusive that when you increment Responses(i) by 1 for the response 10 you will fall out of that range.

Try this out to see if it gives you the expected output.
Remove the responseCounter variable. It doesn't do anything significant (not any I see anyway).
Change the responses declaration to Dim responses(9) As Integer.
VB.NET uses zero (0) as the lower bound of an array (and almost every other type of collection) so the statement will create an array of integer with ten (10) elements.
Change the For ii As Integer = 1 to responses(i) loop block to outputTextBox.Text &= New String('*', responses(i))

Related

How to use a loop to print a statement a number of times defined by user inputs on visual basic

I would like to make a simple program that does the following
Takes a text input of a string and the number of times it needs to be looped by the program user and produces that loop to output that string the number of times stated. My loop isn't doing that. (New to visual basic loops)
Kindly correct advise where i have gone wrong below:
Public Class Form1
Private Sub cmdLoop_Click(sender As Object, e As EventArgs) Handles cmdLoop.Click
Dim newput As String
Dim numberr As Integer
Dim counter As Integer
newput = txtStatement.Text
numberr = TxtRepeatNum.Text
For counter = 1 To numberr
lbloutput.Text = newput & vbCrLf
Next
End Sub
Your loop is writing numberr times the same string into the text box, with every iteration it overwrites the previous content. Change it to
lbloutput.Text = ""
For counter = 1 To numberr
lbloutput.Text = lbloutput.Text & newput & vbCrLf
Next

Encode and Decode VBA Program

in my programming class I have to create a program which allows the user in order to enter a sentence, with the buttons "Encode" and "Decode" as options. So, for "Encode", you have to translate the sentence into Asc numbers (already did this). However, I'm currently stuck on the "Decode" section, for you have to use a For loop and an array to separate the Asc numbers by spaces, then translate them into characters one by one. Here's what I have so far:
Public Class Form1
Dim Message As String
Dim NewMessage As String
Dim Part As String
Dim Part2 As Integer
Dim Letter As String
Dim Length As String
Dim ints() As Integer
Dim intlength As Integer
Private Sub btn_Enter_Click(sender As Object, e As EventArgs) Handles btn_Enter.Click
Message = txt_Message.Text
Length = Message.Length() - 1
If rbn_Encode.Checked = True Then
For Num As Integer = 0 To Length
Letter = Message(Num)
Me.lbl_Code.Text = lbl_Code.Text & Asc(Letter) & " "
Next
End If
If rbn_Decode.Checked = True Then
For Num As Integer = 0 To intlength Step 1
If Message(Num) <> " " Then
Part = Part & Message(Num)
Else
NewMessage = NewMessage & ChrW(Part) & " "
End If
Next
Me.lbl_Code.Text = NewMessage
End If
End Sub
Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click
Application.Exit()
End Sub
End Class
I've been stuck on this for about 2 week, and I'm still clueless. Thank you for your help and have a wonderful day.
This might seem to veer off the topic of the question, but it all meanders towards a better answer.
OK there are a few issues with your code. Firstly, make sure that "Option Strict" is on - have a look here. This will force you to convert types properly and reduce the potential for problems. Bearing the above in mind,
Dim Length As String
should be
Dim Length As Integer
on to the next bit
Each procedure should have a single responsibility. Your btn_Enter.Click event handler includes code for encoding text and decoding numbers. These should be separated out into their own procedures. In a relatively short bit of code like yours, it's not too much of a problem, but even here, it makes things a little fuzzier. Have a look at the code below. There are more issues, but we'll look at them in a moment. The code below is a bit clearer and more maintainable.
Private Sub btn_Enter_Click(sender As Object, e As EventArgs) Handles btn_Enter.Click
Message = txt_Message.Text
Length = Message.Length() - 1
If rbn_Encode.Checked = True Then
EncodeTextToAscii()
End If
If rbn_Decode.Checked = True Then
DecodeToText()
End If
End Sub
Private Sub DecodeToText()
For Num As Integer = 0 To intlength Step 1
If Message(Num) <> " " Then
Part = Part & Message(Num)
Else
NewMessage = NewMessage & ChrW(Part) & " "
End If
Next
Me.lbl_Code.Text = NewMessage
End Sub
Private Sub EncodeTextToAscii()
For Num As Integer = 0 To Length
Letter = Message(Num)
Me.lbl_Code.Text = lbl_Code.Text & Asc(Letter) & " "
Next
End Sub
Next.
In your code to encode the string as ASCII, you store the resulting data directly in the label lbl_Code's text property. The user interface should never be used as the primary store for data. It's bad practice and potentially allows the user to change data accidentally - in textboxes for example. In the case of a label, it's not to important, but it's far better to get into the good habits.
To store your encoded ASCII numbers, you can use the array ints, but as your code stands, the declaration of ints is just that. There is no space in the array to store data. So, in the Encode procedure, you need to resize ints to the same as the number of characters in the string.
So now we have ..
Private Sub EncodeTextToAscii()
ReDim ints(Length)
For Num As Integer = 0 To Length
Letter = Message(Num)
ints(Num) = Asc(Letter)
Next
End Sub
Finally onto the meat of your question. The Decode procedure can now be written as this ..
Private Sub DecodeToText()
NewMessage = ""
For Each asciiNumber As Integer In ints
NewMessage = NewMessage & ChrW(asciiNumber) & " "
Next
Me.lbl_Code.Text = NewMessage
End Sub
Instead of mucking around getting the length of a loop and getting the ascii number in each element of an array, you can simplyfy it using a For Each statement. You dont need to know the length of the array. It just loops over the whole length. Much easier.
As an excercise, try applying the For Each idea to the Encode procedure. :-)

Visual basic For Next not repeating and not incrementing by 1

I am currently working on a homework assignment for Visual basic. The homework is to display the square value of only the odd numbers 1-9. I have to use a For Next to do so as specified by the assignment. I do not want the answer but a point to the right direction. Here is my code currently it only displays the square value of 9 but will not display the square value of the other odd numbers. I have done a couple tutorials but I can not figure out why it ill not continue the loop.
Public Class MainForm
Private Sub exitButton_Click(sender As Object, e As EventArgs) Handles exitButton.Click
Me.Close()
End Sub
Private Sub displayButton_Click(sender As Object, e As EventArgs) Handles displayButton.Click
'Start/end values and retainer for the values
Dim startVal As Integer
Dim endVal As Integer
Dim squareVal As Integer
startVal = 1
endVal = 9
'For loop to separate the odd and even numbers to square the odd numbers.
For _val As Integer = startVal To endVal Step 1
If _val Mod 2 <> 0 Then
squareVal = _val * _val
squaresLabel.Text = squareVal.ToString() & ControlChars.NewLine
_val += 1
Else
squaresLabel.Text = _val.ToString() & ControlChars.NewLine
_val += 1
End If
Next _val
End Sub
End Class
You are overwriting the text stored in squaresLabel each pass through the loop. Look at the assignment statement:
squaresLabel.Text = squareVal.ToString() & ControlChars.NewLine
I think you are just repeating the calculation not actually output each value. So I suggest you define an array and store them inside of it. Also do trouble shooting for each value. Hope it helps.

how to exit a loop to another loop?

Anyone know why I can not get a new word when the "for" loop reaches the limit?
the intention is that the loop rotate every new word
but something very wrong'm doing
================================
Private Sub getWord()
Static wordCount As Integer
Dim txtLines As String()
txtLines = TextBox1.Text.Split(CChar(vbCrLf))
If (wordCount < txtLines.Count) Then
WebBrowser1.Navigate("http://www.bing.com/search?q=" & txtLines(wordCount) & "&first=1&FORM=PERE")
wordCount = wordCount + 1
End If
End Sub
Dim i As Integer
Dim max As Integer = 40
Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
If i >= max Then
getWord()
End If
If (WebBrowser1.ReadyState = WebBrowserReadyState.Complete) Then
For i As Integer = 1 To 40 Step 10
WebBrowser1.Navigate("http://www.bing.com/search?q=" & txtLines(wordCount) & "&first=" & i & "&FORM=PERE")
Next
Dim PageElement As HtmlElementCollection = WebBrowser1.Document.GetElementsByTagName("a")
Dim lk As String
For Each lks As HtmlElement In PageElement
lk = lks.GetAttribute("href")
ListBox1.Items.Add(lk)
Next
End If
End Sub
I'm not entirely sure that I understand your question, but I'll take a stab at it.
If you're not getting the expect values from the loop could it be that when you use For i As Integer = 1 To 40 Step 10 that you only get 1, 11, 21, 31, but that you're expecting five values? Perhaps you need to do this:
For i As Integer = 1 To 41 Step 10

Splitting a string based on a set length of characters

MVC 3. Vb.net. Part of my app generates PDF files using Itextsharp. Some strings are too long to go onto the background image correctly. So I basically need to split this string when its over 26 characters long and when it splits it cant split in the middle of a word. from there I will use newline to add the string to the right to the next line... Any ideas that might point me in the right direction.. I did start bulding the function that I will pass the string into test for length and then pass back the string after it finishes but I am stummped after that..
Private Function stringLength(ByVal _string As String) As String
If _string.Length < 26 Then
_string.Split(
End If
End Function
I'm sure there's a million different ways to do this.
You basically need to get all of your words split by the space into a list. After that, you just need to keep checking if the current word plus a space plus the next word reach your threshold or not, and if it does, you move to the next line. Once you have all of your lines, then you rejoin the list into a single string again.
Private Function LimitWidth(ByVal text As String, ByVal maxCharacters As Integer) As String
Dim words As List(Of String) = text.Split(" "c).ToList()
If text.Length < maxCharacters OrElse words.Count = 1 Then
Return text
Else
Dim lines As New List(Of String)
Dim currentLine As String = words(0)
For i As Integer = 1 To words.Count - 1
If (currentLine & " " & words(i)).Length > maxCharacters Then
lines.Add(currentLine)
currentLine = words(i)
If i = words.Count - 1 Then
lines.Add(currentLine)
End If
Else
If i = words.Count - 1 Then
lines.Add(currentLine & " " & words(i))
End If
currentLine &= " " & words(i)
End If
Next
Return String.Join(Environment.NewLine, lines.ToArray())
End If
End Function
To Test:
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
MessageBox.Show(LimitWidth("This is a really long sentence " & _
"meant to demonstrate how to split " & _
"the words into a confined character length.", 26))
End Sub
It sounds like you are asking for a word wrap function.
Since I feel that it's better to answer in a way that promotes learning than to just give answers, I have for you a link that walks you through the process of using Test Driven Development (TDD) to solve this problem. It just so happens that the word wrap problem is a popular coding kata, and Robert C. Martin wrote a somewhat silly fictional story about a developer being taught how to use TDD to solve the word wrap kata.
The code examples are in Java, but it should be trivial to read and translate.
http://thecleancoder.blogspot.com/2010/10/craftsman-62-dark-path.html
The goofy bits are skip-able. Just jump down to the sentences right before the first code snippet.
I would add to it handling of multiline input text with following:
Private Function LimitWidth(ByVal text As String, ByVal maxCharacters As Integer, SplitSign As String) As String
Dim Output As String = ""
Dim OrgLines As List(Of String) = text.Split(Environment.NewLine).ToList()
For x As Integer = 1 To OrgLines.Count - 1
Dim words As List(Of String) = OrgLines(x).Split(" "c).ToList()
If text.Length < maxCharacters OrElse words.Count = 1 Then
Output += OrgLines(x)
Else
Dim lines As New List(Of String)
Dim currentLine As String = words(0)
For i As Integer = 1 To words.Count - 1
If (currentLine & " " & words(i)).Length > maxCharacters Then
lines.Add(currentLine)
currentLine = words(i)
If i = words.Count - 1 Then
lines.Add(currentLine)
End If
Else
If i = words.Count - 1 Then
lines.Add(currentLine & " " & words(i))
End If
currentLine &= " " & words(i)
End If
Next
Output += String.Join(SplitSign, lines.ToArray())
End If
Next
Return Output
End Function
use:
LimitWidth("your text", 80, Environment.NewLine)