Issue learning For...Next loop - vb.net

The following is an exercise I am having trouble with.
The button’s Click event procedure should display the number of integers from 14 to 23 in one of the labels and the sum of those integers in the other label. Code the procedure using the For…Next statement. Save the solution and then start and test the application. (The procedure should display the numbers 10 and 185.)
I'm able to display the sum 185 but not understanding how to display the amount of numbers (10) between 14 to 23. Any help is appreciated.
Public Class frmMain
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
Dim intSum As Integer
For intNum As Integer = 14 To 23
lblShow.Text = lblShow.Text & intNum.ToString & " "
intSum += intNum
lblSum.Text = intSum.ToString
Next
End Sub
End Class

Just declare sum and count local variables and increment them appropriately in the For. You need only update the Label.Text once after the calculations have been done
Dim intSum As Integer
Dim intCount As Integer
For intNum As Integer = 14 To 23
intSum += intNum
intCount += 1
Next
lblSum.Text = intSum.ToString()
lblShow.Text = intCount.ToString()
I understand your homework has the For requirement, but .NET has some functionality built in which can produce a list of numbers, sum them, and count them.
Dim start = 14
Dim finish = 23
Dim numbers = Enumerable.Range(start, finish - start + 1)
lblSum.Text = numbers.Sum().ToString()
lblShow.Text = numbers.Count().ToString()
Both methods produce your required output

display the number of integers from 14 to 23
This can be interpreted in a couple of ways:
Display the count of integers between the two numbers (e.g. 23 - 14)
Display each individual integer between the two numbers (e.g. 14, 15, 16, etc.)
If it is the former, then simply subtract the larger number from the smaller number and display that value in a label:
LabelIntegerCount.Text = (23 - 147).ToString()
If it is the latter, then inside of your For/Next loop append the currently iterated counter to the label:
For intNum As Integer = 14 To 23
LabelIntegerCount.Text &= intNum.ToString() & Environment.NewLine
' ...
Next

Related

Visual Basic: Simple Counter with leading Zero

I am trying to create a simple counter that increases when the button is clicked.
What I would like is when the counter is clicked it displays "01", "02" etc.
I can create it already with "1", "2", but I would like to have a leading zero.
I have searched and found I can do this by converting the label to a string, but I cant seem to get the value to count?
If I change "count.text = counter" to "count.text = cot" it will display "01", but wont count. I'm guessing this is due to the fact its only displaying what is currently in the string but not increasing the value?
If I could get any guidance that would be great!
Many thanks!
Dim counter As Integer = 1
Dim cot As String = String.Format("{0:00}", counter)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
counter = cot + 1
count.Text = counter
End Sub
PadLeft is the key.
Dim number as Integer = 12
Console.WriteLine(number.ToString().PadLeft(2, "0")). ' prints 12
number = 2
Console.WriteLine(number.ToString().PadLeft(2, "0")). ' prints 02
The problem is, that you don't update your formatted number properly. It's only initialized a single time.
To increment the counter, use counter += 1 or counter = counter + 1 first. This will add 1 to the current value of the integer variable. Then modify the text of your Label by calling that formatting code again: count.Text = String.Format("{0:00}", counter).
This should get you started...
it converts the string into an integer. increments the number, converts it back into a string and then checks for a leading 0, if not found it adds it.
I will let you convert it into your button click for practise, as it should help you have a good understanding of the conversion between types :)
Sub string_counter()
Dim string_counter As String
string_counter = "00"
For x = 0 To 10
Debug.Print string_counter
string_counter = Int(string_counter) + 1
string_counter = Str(string_counter)
If Left(Trim(string_counter), 1) <> "0" Then
string_counter = "0" + Trim(string_counter)
End If
Next x
End Sub

Fill combobox with time values

I want fill my combobox with time values like (08:00, 08:10, 08:20 until 09:50) step=10 minutes but the result is like (8:00, 8:10, 8:20, 8:30, 9:-20,9:-10, 9:00, 9:10, 9:20).
My code doesn't show the value like 8:40, 8:50 and he also show negative value like 9:-20, 9:-10).
So please how can I resolve this problem?
Heure_rdv.Items.Clear()
Dim nbr_minute2 As String
For i = 480 To 590 Step 10
Dim nbr_heure As Integer = cint(i / 60)
Dim nbr_minute As Integer = (i - (nbr_heure * 60))
nbr_minute2 = CStr(nbr_minute) + "0"
If ((i - (nbr_heure * 60)) = 0) Then
Heure_rdv.Items.Add(CStr(nbr_heure) + ":" + nbr_minute2)
Else
Heure_rdv.Items.Add(CStr(nbr_heure) + ":" + CStr(nbr_minute))
End If
Next
This is how I should do try it in VBA.
Should be similar in VB.NET
DIM i As Integer 'Counter 1
Dim ii As Integer 'Counter 2
' make 1st loop for hours
for i = 8 To 9
' mkae 2nd loop for minutes
for ii = 0 To 50 Step 10
'
Heure_rdv.Items.Add(i & ":" & ii)
next
next
This could be done with fewer lines of code using linq
Dim steps = Enumerable.Range(0,6)
Dim items as List(Of String) = new List(Of String)()
items.AddRange(steps.Select(Function(x) "08:" & (x * 10).ToString("D2")))
items.AddRange(steps.Select(Function(x) "09:" & (x * 10).ToString("D2")))
Heure_rdv.DataSource = items
First we create a list of integers from 0 to 5 (6 elements), then using these elements we create the strings required multiplying each element of the integer list by ten and converting the result to a two digit string. We do this one time for the 8 hour and one time for the 9. Finally we could set the combo datasource to the resulting list of strings.

Using check digit algorithm to determine whether a value inputed is valid?

I am writing code for a form that is supposed to determine whether a value inputted by the user is valid as a check digit. They input a 13 digit number and it should determine whether or not the last value is valid as a check digit. I have written in the code for the check digit algorithm but I'm having trouble with comparing the value that the algorithm found with what the user input. I have tried using the substring method to compare the 13th number given by the user with the check digit that the algorithm determined but I am having issues with the syntax of everything.
This is the code I have been working on:
Private Sub btnValidate_Click(sender As Object, e As EventArgs) Handles btnValidate.Click
Dim intDigit As Integer
Dim intTotalOdd As Integer
Dim intTotalEven As Integer
Dim intGrandTotal As Integer
Dim intRemainder As Integer
Dim intCheckDigit As Integer
If txtNumber.Text.Length = 13 Then
For intOdd As Integer = 1 To 11 Step 2
intTotalOdd += (intDigit * 3)
Next intOdd
For intEven As Integer = 0 To 10 Step 2
intTotalEven += intDigit
Next intEven
intGrandTotal = intTotalOdd + intTotalEven
intRemainder = intGrandTotal Mod 10
If intRemainder <> 0 Then
intCheckDigit = 10 - intRemainder
End If
If txtNumber.Text.Substring(12, 13) = intCheckDigit Then
lblStatus = "Valid"
Else
lblStatus = "Not Valid"
End If
End If
End Sub
I think the way I'm doing it should work but I don't have very much to reference on how I would go about making the syntax work. Will the way that I'm trying to do it work or do I need to go about it in a different way?

Trying to shorten code in VB.NET

One of my assignments in vb.net is to make a program that takes in 15 inputted "test scores", returns the average, and then returns the corresponding letter grade. I am trying to make this as short as possible, and I remembered a code format that I can use when I am coding in Python (simple example with only three scores):
counter = 0
number = 0
test1,test2,test3 = 0,0,0
for i in [test1,test2,test3]:
print("Enter a test score")
i = int(input())
counter += i
number += 1
average = counter/number
Is there such a code format in VB.NET?
Yes.
Here is a simple sample code which asks user to input number of items and then items one by one. At the end it calculates average of numbers.
Console.WriteLine("Enter number of Items")
Dim numberOfItems As Integer
If Integer.TryParse(Console.ReadLine(), numberOfItems) Then
Dim items As New List(Of Decimal)()
For i As Integer = 1 To numberOfItems
Console.WriteLine("Enter number {0}", i)
Dim num As Decimal
If Decimal.TryParse(Console.ReadLine(), num) Then
items.Add(num)
End If
Next
Console.WriteLine("Average is " + items.Average())
Console.ReadLine()
End If
Please note that I've not included any type of error handling.

Random numbers in array without any duplicates

I'm trying to randomize an array from numbers 0 to 51 using loops but I just cannot seem to pull it off. My idea was that
Generate a Random Number
Check if this random number has been used by storing the previous in an array
If this random number has been used, generate new random number until it is not a duplicate
If it's not a duplicate, store it
My attempt:
Dim list(51) As Integer
Dim templist(51) As Integer
For i As Integer = 0 To 51 Step 1
list(i) = i
Next i
Do While counter <= 51
p = rand.Next(0, 52)
templist(counter) = p
For n As Integer = 0 To 51 Step 1
p = rand.Next(0, 52)
If templist(n) = p Then
Do While templist(n) = p
p = rand.Next(0, 52)
Loop
templist(n) = p
Else
templist(n) = p
End If
Next
counter += 1
Loop
For n As Integer = 0 To 51 Step 1
ListBox1.Items.Add(templist(n))
Next
It will be a lot easier if you just have a list of all of the possible numbers (0 to 51 in your case), then remove the number from the list so it can't be picked again. Try something like this:
Dim allNumbers As New List (Of Integer)
Dim randomNumbers As New List (Of Integer)
Dim rand as New Random
' Fill the list of all numbers
For i As Integer = 0 To 51 Step 1
allNumbers.Add(i)
Next i
' Grab a random entry from the list of all numbers
For i As Integer = 0 To 51 Step 1
Dim selectedIndex as Integer = rand.Next(0, (allNumbers.Count - 1) )
Dim selectedNumber as Integer = allNumbers(selectedIndex)
randomNumbers.Add(selectedNumber)
allNumbers.Remove(selectedNumber)
' Might as well just add the number to ListBox1 here, too
ListBox1.Items.Add(selectedNumber)
Next i
If your goal is to get the numbers into ListBox1, then you don't even need the "randomNumbers" list.
EDIT:
If you must have an array, try something like this:
Function RandomArray(min As Integer, max As Integer) As Integer()
If min >= max Then
Throw New Exception("Min. must be less than Max.)")
End If
Dim count As Integer = (max - min)
Dim randomNumbers(count) As Integer
Dim rand As New Random()
' Since an array of integers sets every number to zero, and zero is possibly within our min/max range (0-51 here),
' we have to initialize every number in the array to something that is outside our min/max range.
If min <= 0 AndAlso max >= 0 Then
For i As Integer = 0 To count
randomNumbers(i) = (min - 1) ' Could also be max + 1
Next i
End If
Dim counter As Integer = 0
' Loop until the array has count # of elements (so counter will be equal to count + 1, since it is incremented AFTER we place a number in the array)
Do Until counter = count + 1
Dim someNumber As Integer = rand.Next(min, max + 1)
' Only add the number if it is not already in the array
If Not randomNumbers.Contains(someNumber) Then
randomNumbers(counter) = someNumber
counter += 1
End If
Loop
Return randomNumbers
End Function
This is good enough for your assignment, but the computer scientist in my hates this algorithm.
Here's why this algorithm is much less desirable. If zero is in your range of numbers, you will have to loop through the array at least 2N times (so 104+ times if you are going from 0 to 51). This is a best case scenario; the time complexity of this algorithm actually gets worse as the range of numbers scales higher. If you try running it from 0 to 100,000 for example, it will fill the first few thousand numbers very quickly, but as it goes on, it will take longer and longer to find a number that isn't already in the list. By the time you get to the last few numbers, you could potentially have randomly generated a few trillion different numbers before you find those last few numbers. If you assume an average complexity of 100000! (100,000 factorial), then the loop is going to execute almost ten to the half-a-millionth power times.
An array is more difficult to "shuffle" because it is a fixed size, so you can't really add and remove items like you can with a list or collection. What you CAN do, though, is fill the array with your numbers in order, then go through a random number of iterations where you randomly swap the positions of two numbers.
Do While counter <= 51
p = rand.Next(0, 52)
While Array.IndexOf(list, p) = -1
p = rand.Next(0, 52)
End While
counter += 1
Loop
Haven't written VB in about 5 years, but try this out:
Function GetRandomUniqueNumbersList(ByVal fromNumber As Integer, ByVal toNumber As Integer) As List(Of Integer)
If (toNumber <= fromNumber) Then
Throw New ArgumentException("toNumber must be greater than fromNumber", toNumber)
End If
Dim random As New Random
Dim randomNumbers As New HashSet(Of Integer)()
Do
randomNumbers.Add(random.Next(fromNumber, toNumber))
Loop While (randomNumbers.Count < toNumber - fromNumber)
Return randomNumbers.ToList()
End Function
Ok, that was painful. Please someone correct it if I made any mistakes. Should be very quick because it's using a HashSet.
First response to forum on stackoverflow - be gentle.
I was looking for a way to do this but couldn't find a suitable example online.
I've had a go myself and eventually got this to work:
Sub addUnique(ByRef tempList, ByVal n, ByRef s)
Dim rand = CInt(Rnd() * 15) + 1
For j = 0 To n
If tempList(j) = rand Then
s = True
End If
Next
If s = False Then
tempList(n) = rand
Else
s = False
addUnique(tempList, n, s)
End If
End Sub
Then call the sub using:
Dim values(15) As Byte
Dim valueSeen As Boolean = False
For i = 0 To 15
addUnique(values, i, valueSeen)
Next
This will randomly add the numbers 1 to 16 into an array. Each time a value is added, the previous values in the array are checked and if any of them are the same as the randomly generated value, s is set to true. If a value is not found (s=false), then the randomly generated value is added. The sub is recursively called again if s is still true at the end of the 'For' loop. Probably need 'Randomize()' in there somewhere.
Apologies if layout is a bit wobbly.