I am trying to figure out how to get a message box to show only specific words from a text file, which contains all of the words within the dictionary. I have tried various different ways, but cannot get it to work, but I do think I am on the right track so just need some pointers.
Basically, there is a scrambled up string, which is different every time, and is contained within a label. I want the program to only show words which contains the letters inside the scrambled string, but not sure how to achieve this?
Here is the code that I have so far:
Private Sub btnAnswers_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnswers.Click
Dim hash As List(Of String) = New List(Of String)(System.IO.File.ReadAllLines("C:\Users\Katie\Documents\Project\dictionary.txt"))
Dim Letters As String
Dim OneCharacter As String
Dim Found As Boolean
Dim item As String
Dim AllCharacters As String
Found = False
Letters = lblLetters.Text
For i = 0 To Letters.Length - 1
OneCharacter = Letters.Substring(i, 1)
For Each item In hash
If item.Contains(OneCharacter) Then
Found = True
AllCharacters = OneCharacter
Else
Found = False
End If
MsgBox(item)
Next
Next i
End Sub
The message box does show up words, from the dictionary, but words can contain letters that are not present in the label string, so my code is wrong. Can anyone help? Apologies, but I am new to programming.
With a simple modification to the previous answer you can restrict the output to only words that contain only the scrambled letters:
Private Sub btnAnswers_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim hash As List(Of String) = New List(Of String)(System.IO.File.ReadAllLines("C:\Users\Katie\Documents\Project\dictionary.txt"))
Dim Letters As String = lblLetters.Text
For Each item As String In hash
Dim word As String = item.ToLower()
For i = 0 To Letters.Length - 1
Dim OneCharacter As Char = Char.ToLower(Letters(i))
While word.Contains(OneCharacter)
word = word.Remove(word.IndexOf(OneCharacter), 1)
End While
Next
If (word.Length = 0) Then
'The given dictionary entry includes all the letters in the label. No more iterations will be performed
MsgBox(item)
Exit For
End If
Next
End Sub
With this code if the scrambled letters contain 'bok' then "book" will get selected. However removing the while loop and leaving only the remove statement, will ensure that only the exact number of each different letter will match. so that 'obok' will be needed to match "book".
As suggested by Steven Doggart, you have to invert the loop nesting. What you want is going through all the dictionary entries and, for each of them, checking if it contains all the letters in the string. Your loop structure is not allowing to do that.
I have performed the required updates in your code. Bear in mind that this code ignores caps ("A" is the same than "a").
Private Sub btnAnswers_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim hash As List(Of String) = New List(Of String)(System.IO.File.ReadAllLines("C:\Users\Katie\Documents\Project\dictionary.txt"))
Dim Letters As String = lblLetters.Text
For Each item As String In hash
Dim Found As Boolean = True
For i = 0 To Letters.Length - 1
Dim OneCharacter As String = Letters.Substring(i, 1)
Dim itemToLower As String = item.ToLower()
If Not itemToLower.Contains(OneCharacter.ToLower()) Then
Found = False
Exit For
End If
Next i
If (Found) Then
'The given dictionary entry includes all the letters in the label. No more iterations will be performed
MsgBox(item)
Exit For
End If
Next
End Sub
This code looks for keys containing all the characters in the given label (not at the contrary), that is: with a label "dict", "dictentry" would be right.
In any case, the whole point of my answer is not delivering a code which you just have to execute; the point of this code is helping you to understand what you did wrong and how to start doing things right. If you are not interested in this exact functionality, you woud have to edit my code such that what you want can be accomplished; or, ideally, you would be writing your own code completely from scratch.
You're calling MsgBox(item) outside of the if statement that determines whether the current word contains the current character. Which means it's going to pop up for every letter, every word. Move MsgBox(item) inside the first half of the if statement if you only want it to show when the letter is actually found in the word.
I'd also suggest following Steven Doggart's advice and reversing the way the loops are nested. If the characters are the outer loop, you could get the message box multiple times per word (e.g., if your letters are "sdf" and one of the words is "foods," it will pop up 3 times).
For Each item In hash
For i = 0 To Letters.Length - 1
OneCharacter = Letters.Substring(i, 1)
If item.Contains(OneCharacter) Then
Found = True
AllCharacters = OneCharacter
MsgBox(item)
Else
Found = False
End If
Next
Next
Related
I am trying to write a VB.Net application that needs to pull the text from a specific tag:
<span data-reactid="85">172,890,000</span>
and then enter the text found 172,890,000 into a textbox on the form.
In Textbox1, you enter the Stock Symbol you want to search.
The data for "TTM - Total Revenue" will always be held within the:
<span data-reactid="85">172,890,000</span> tag. Regardless of stock you check.
In RichTextBox1, is the downloaded source code for the url.
TextBox2 is where it pulls "TTM". I will probably change it to a label as it's a constant value. I cant put the number in the variable as it will vary on the company, i.e. the value entered into TextBox1.
TextBox3 is going to show the value I really need. The 172,890,000 held in the
<span data-reactid="85">172,890,000</span> tag.
I was wondering how to search for the string within RichTextBox1, and pull the next 7 characters after the end of the string if that would work?
My code so far is:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Source As String
Dim ttm1 As String
Dim ttmrev As String
Source = New System.Net.WebClient().DownloadString("https://finance.yahoo.com/quote/" + TextBox1.Text + "/financials?p=" + TextBox1.Text)
ttm1 = <span data-reactid="65">ttm</span>
ttmrev = <span data-reactid="85"></span>
RichTextBox1.Text = Source
If RichTextBox1.Find(ttm1) Then
TextBox2.Text = "ttm".ToUpper
End If
End Sub
End Class
As usual in coding, there are always many ways to accomplish the same end result. One way is to use a Regex.
For example:
Imports System.Text.RegularExpressions
Sub Main
' In place of a static string here, place the exact line you want to search instead.
Dim str As String = "<span data-reactid=""85"">172,890,000</span>"
' Search for the match
showMatch(str, "(\d+),?(\d+),?(\d+)")
End Sub
Sub showMatch(ByVal text As String, ByVal expr As String)
' Make sure you're expression looks the way you want it
Debug.WriteLine("The Expression: " + expr)
' Declare the variable and do the regex match
Dim mc As MatchCollection = Regex.Matches(text, expr)
Dim m As Match
' Handle the result however you wish; for example instead of a loop, since
' there should only be 1 result you could just do
' something like: TextBox3.Text = m.ToString()
For Each m In mc
Debug.WriteLine(m)
Next m
End Sub
The above regex will find any number that matches for example:
172,890,000
890,000
000
2,80,000
etc.
Another choice might be to use a WebBrowser control, fetch the source into it, and play around with the innerHtml as needed.
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
TextBox2.Text = TextBox1.Text ^ 2
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
TextBox1.Text = Nothing
TextBox2.Text = Nothing
End Sub
End Class
The code above outputs squares of any single values input in textbox1 but i need some help in inputting a couple of values separated by commas and then output the squares of those individual values eg 3,4 the output 9,16
I'm not going to do it all for you, because this looks like homework, but here are some pointers:
TextBox2.Text = TextBox1.Text ^ 2
1) Turn on Option Strict, by placing Option Strict On at the top of your code file or by putting it in the project properties Compile tab. This will help you be more rigorous with your coding. Here you're taking a string (TextBox1.Text) and having VB auto convert it to a number (which might fail), squaring it, and then auto converting it back to a string to store in TextBox2.Text. This is bad news all round; always be crystal clear in your own mind and explicit in your coding about the difference between various data types.A string containing numbers is not the same thing as a number!
2) Rename your textboxes after you drop them on a form. Nothing is more frustrating than to read a block of code where the variable names are irrelevant garbage. You will find this when you come back to some complex code in 6 months and think "what the..."; renaming a textbox so it is called resultTextBox or inputTextBox takes seconds and makes your code instantly more comprehensible to both you and anyone you call in to help out with it
separated by commas
The following line of code will split a string into an array of strings, on comma:
Dim csv = "3,6"
Dim arr = csv.Split(","c)
Console.WriteLine(arr(0)) 'prints 3
Console.WriteLine(arr(1)) 'prints 6
The following line of code will convert a string to an integer:
Dim s = "3"
Dim i = Convert.ToInt32(s)
Maths operations can now be performed on it
i = i * i 'square it
The following line of code will turn an integer into a string:
Dim i as Integer = 3
Dim s as String = i.ToString() 's is now "3"
The following line of code will loop through an array, appending the values in the array to a string variable, and adding commas. Finally it trims off the excess trailing comma
Dim s as New String
For Each x as String in arr
s = s & x & ","
Next x
s = s.TrimEnd(","c)
Here is another way too, using the String.Join helper method:
Dim s as String = String.Join(","c, arr)
I have a text file and I wish to make code that puts the numbers into an array.
The program is required to read the data for each member from the text file. The program then uses this data to find then display the biggest value. The names of every member who has a value more than 70% of the largest is to be written on an empty text file so that the file can be printed out later.
Nikolai,Bryant,145.6
Susan,Brown,34.2
Teressa,Jones,398.5
Martin,Daly,256.9
Ross,Durrant,409.0
Greg,Watson,99.2
Wendy,Russell,87.4
Pamela,Adkins,73.6
Ian,Hunter,385.7
James,Kerr,505.2
Lesley,Wallace,68.4
Kim,Pettigrew,256.4
Steven,Johnstone,23.4
Ali,Hussain,12.1
Hasan,Abbas,302.0
Jacek,Nowak,199.9
Mirka,Kowalski,176.8
Rudo,Hyper,120.2
Tisa,Sullivan,484.2
Albert,Nvodo,385.8
So far all I have is this:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim FILE_NAME As String = "H:\S5\Computing\Programming\members.txt"
Dim objReader As New System.IO.StreamReader(FILE_NAME)
End Sub
End Class
You will need to add Imports System.IO at the top of you code file. This has a File class which contains the .ReadAllLines method. This method will return an array of all the lines in the text file.
'String.Split' will return an array of of the fields in the line which were delimited (separated) by a comma. The small c after "," tells the compiler that this is Char which what the .Split method expects.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim FILE_NAME As String = "H:\S5\Computing\Programming\members.txt"
Dim lines = File.ReadAllLines(FILE_NAME)
'Declare an array to hold your numbers VB arrays are declared arr(UBound)
'UBound is upper bound referring to highest index
'The highest index would be 1 less the lenght because indexes start at 0
Dim numbers(lines.Length - 1) As Single
Dim index As Integer 'Will be the index for the numbers array
'From the lines array we can loop through each line
For Each s As String In lines
Dim fields = s.Split(","c)
'Your fields array will have 3 elements, a first name at position (index) 0, last name at 1 and number at 2
'You only want the number - but it is not a number yet, it is still a string
'So we do a CSng to change it to a Single
numbers(index) = CSng(fields(2))
index += 1 'shortcut way to write index = index + 1
Next
For Each n As Single In numbers
Debug.Print(n.ToString)
Next
End Sub
The .TexFieldParser suggested by #jmcilhinney in comments has some extra features which would come in handy but this should get you started.
start=AKS-RHzlSXSftLGYdBNk.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1&
For every instance of the word 'start' I need to be able to get the text after the first full stop, right up until the & symbol. E.g. 'eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1'.
There will be more than one instance of this. They will need to be appended to a listbox.
What is the simplest/quickest way to do this? (Using possibly streamreader - text file)
The simplest and quickest way will be to read each line, and check if it .StartsWith("start="). If so, then get the .IndexOf(".") and the .IndexOf("&", <whereever the first indexOf was>). Get the .SubString which encompasses those two values. I'm sure you can write the code yourself from that ;)
I tested this function with a button click, output text each line on a textbox. I am sure you can adapt this to your code.
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
txtResults.Text = ""
Dim ParseString As String
ParseString = "start=123341.23124&kjdshfkjsdaksdstart=1231.2321312&kadhskjashdkjastart=1231.23126789898&skjdfhkjsd"
Dim Delimiters() As String = New String() {"start="}
Dim Words() As String
Words = ParseString.Split(Delimiters, CompareMethod.Text)
For Each Part In Words
Dim Middle As String
Middle = Part.Split(".").Skip(1).Take(1).FirstOrDefault()
Dim Good As String
Good = Middle.Split("&").FirstOrDefault()
txtResults.Text += Good + vbNewLine
Next
End Sub
Output was
23124
2321312
23126789898
Added 31104 lines to a string and ran, took about 11 seconds to run on my laptop. Might be too slow for your app?
I'm close to getting this to work, but currently can't get any output to display in the listbox. I had it working, but needed to move some things around to get the join function to work.
In my program, a user enters input into a textbox and an array is displayed in a listbox based on what they type in. For example, if they type in "a", all foods (in the textfile that is connected to the program) that start with "a" will be displayed.
When there is output, I need to find a way to name this array (which is created based on what the user inputs) and join all of the items in the listbox (example: foods stacked on top of each other in the listbox will be shown at the bottom as a string).
I am posting the code that I have thus far; all of the errors that I'm getting (and potentially my logic errors) are just in the first public class until the end of the first if-next statement:
Public Class frmFoods
Dim foods() As String = IO.File.ReadAllLines("foods.txt")
Private Sub btnDisplay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisplay.Click
Dim Letter As String = txtLetter.Text.ToUpper
Dim smallerarray() As Array
Dim userarray As String
lstOutput.Items.Clear()
If IsNumeric(txtLetter.Text) = False Then
For Each food As String In foods
smallerarray = listfoods(Letter)
lstOutput.Items.Add(Letter)
userarray = Join(smallerarray, ", ")
lstOutput.Items.Add(userarray)
Next
ElseIf IsNumeric(txtLetter.Text) = True Then
MessageBox.Show("Please enter a letter.")
Else
MessageBox.Show("The text box is empty")
End If
End Sub
Function listfoods(ByVal letter As String) As String()
Dim foodarray(foods.Count - 1) As String
Dim counter As Integer = 0
For Each food As String In foods
If food.StartsWith(letter) Then
foodarray(counter) = food
counter += 1
End If
Next
ReDim Preserve foodarray(counter - 1)
Return foodarray
End Function
you need to save the results of the listfoods function in a dictionary or similar and associate it with a key if you want to 'Name' it, although its not clear why you need to do this
As for listing the foods starting with the particular letter, you just need to iterate your result of the function listfoods and separate each one by a comma don't you?
What you have now will create many lists of each food as you are getting the list of food beginning with a particular letter for each food.. As I understand the question you only need to do that once.
Example:
Private Sub btnDisplay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisplay.Click
Dim Letter As String = txtLetter.Text.ToUpper
Dim smallerarray() As Array
Dim userarray As String
lstOutput.Items.Clear()
If IsNumeric(txtLetter.Text) = False Then
'get all items from the file which begin with the letter the user chose
smallerarray = listfoods(Letter)
'add that letter to the output listbox
lstOutput.Items.Add(Letter)
'join all of the elements which begin with that letter
'into a single comma separated string
userarray = Join(smallerarray, ", ")
'add that string to the output
lstOutput.Items.Add(userarray)
ElseIf IsNumeric(txtLetter.Text) = True Then
MessageBox.Show("Please enter a letter.")
Else
MessageBox.Show("The text box is empty")
End If
End Sub
it would probably be useful for you to step through the code and see the values of the variable at each place and compare this with what you expect to see if you can see where the actual value differs from what your logically expect so you can start to identify where the issue is