Do..While...Loop - vb.net

My study book makes the following statement about the code below:
**"The computer evaluates the loop condition in the Do...Loop statment to determine whether the loop instructions should be processed. In this case, the inputsales <> String.Empty condition compares the contenst of the input sales variable to the String.Empty value. As you know the String.Empty value represents a zero length, or empty, string if the inputsales variable is empty, the loop condition evaluates to True and the computer process the loop instructions. *If on the other hand the inputsales variable is not empty, the loop condition evaluates to false and the computer skips over the loop instructions.
Based on the code I think it is the opposite: ...that while the inputsales value is not empty it should evaluate to true and process the loop and if it is empty it should evaluate to false and skip the loop? Please see below. Thanks so much for the help!
Option Explicit On
Option Strict On
Imports System.Globalization
Public Class SalesForm
Private Sub exitButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles exitButton.Click
Me.Close()
End Sub
Private Sub calcButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles calcButton.Click
Const prompt As String = "Enter a sales amount. Click cancel to end."
Const title As String = "Sales Entry"
Dim inputsales As String
Dim sales As Decimal
Dim salesCounter As Integer
Dim salesaccumulator As Decimal
Dim salesAverage As Decimal
Dim isconverted As Boolean
inputsales = InputBox(prompt, title, "0")
**Do While inputsales <> String.Empty
isconverted = Decimal.TryParse(inputsales, NumberStyles.Currency, NumberFormatInfo.CurrentInfo, sales)
If isconverted = True Then
salesCounter = salesCounter + 1
salesaccumulator = salesaccumulator + sales
Else
MessageBox.Show("Please re-entere the sales amount.", "sales Express", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
inputsales = InputBox(prompt, title, "0")
Loop**
If salesCounter > 0 Then
salesAverage = salesaccumulator / Convert.ToDecimal(salesCounter)
averageLabel.Text = salesAverage.ToString("C2")
Label2.Text = salesCounter.ToString
Else
averageLabel.Text = "0"
End If
End Sub
End Class

You are definitely correct, and the book is wrong (hopefully, the author just reversed the true/false by accident; otherwise, I'd get another book). My suggested correction (with a few additions):
As you know, the String.Empty value represents a zero length, or empty, string. If the inputsales variable is not empty, the loop condition evaluates to True, and the computer processes the loop instructions (and then jumps back to the top of the loop and reevaluates the condition). If, on the other hand, the inputsales variable is empty, the loop condition evaluates to False, and the computer skips over the loop instructions (and continues with the first statement after the loop).
As #xanatos said: Congratulations on catching your first bug in someone else's text. So +1 for the question, and I'd say that this seems promising for your programming career. :-)

Yes, you are correct. The loop will be executed when inputsales is non-empty. The description is wrong.

Related

visual basic: Enter some numbers until a negative value is entered to stop the program

private Sub Command1_Click()
a = InputBox("What is the Number ?", "Input Example"," ")
If a = "-1" Then
End If
End Sub
the whole question is: Enter some numbers until a negative value is entered to stop the program(stop running the what is your number thing). then find the average of the entered numbers.
What I want to do, for now, I want to know how can I make my "a" variable accept any negative value like in the code above it stops when I enter -1 but I want to stop when I enter -3, -10, or any negative value.
There are some helpful answers down below
If you are expecting the usual input to be text then you can use the Double.TryParse method to check if a number was entered. If it was, then you can check if that number is negative, and exit the application if so:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim userMsg As String
userMsg = Microsoft.VisualBasic.InputBox("What is your message?", "Message Entry Form", "Enter your message here", 500, 700)
If userMsg <> "" Then
Dim x As Double
If Double.TryParse(userMsg, x) AndAlso x < 0 Then
Application.Exit()
End If
MessageBox.Show(userMsg)
Else
MessageBox.Show("No Message")
End If
End Sub
The AndAlso operator only looks at the second argument if the first evaluated to True.
If you would like to repeat some portion of code till specific condition is met, you need to use:
While...End While Statement (Visual Basic)
or
Do...Loop Statement (Visual Basic)
It's also possible to write conditional loop using For... Next statement
Dim myNumber As Integer = 0
Dim mySum As Integer = 0
Dim myCounter As Integer = 0
Do
Dim answer As Object = InputBox("Enter integer value", "Getting average of integer values...", "")
'check if user clicked "Cancel" button
If answer <> "" Then
'is it a number?
If Int32.TryParse(answer, myNumber)
If myNumber >=0 Then
mySum += myNumber
myCounter += 1
Else
Exit Do
End If
End If
End If
Loop
Dim average As Double = mySum/myCounter
'you can display average now
Tip: Do not use InputBox, because this "control" is VisualBasic specific. Use custom Form instead. There's tons of examples on Google!

How to make error message appear when 2nd number in division is equal to 0 using functions VB.Net

I'm trying to get return false when a/b where b is equal to 0 so that my error message appears to the user. So far I've managed to do a check within my sub but I need the check to be within the function. Currently, I get a infinity as the result, when for example 7 is divided by 0. I've basically made a pretty basic calculator and would appreciate any help.
Function:
Private Function validationCheck() As Boolean
' The following checks if the two fields are numerical values, are not blank and if the 2nd number is not zero
'The latter is for the purpose of division
'If the fields meet the above conditions then true is returned
'Else if either one is not met, then false is returned
If IsNumeric(txt1stNumber.Text) And txt1stNumber.Text <> "" And IsNumeric(txt2ndNumber.Text) And txt2ndNumber.Text <> "" Then
Return True
Else
Return False
End If
End Function
Division Sub
Private Sub btnDivide_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDivide.Click
'The following sub is the code for the division button.
'First it checks whether false is returned from the ValidationCheck funtion
'If so, an error message is shown
'Else if true is returned, then the values are divided together to form the result
If validationCheck() = False Then
MsgBox("Please enter a numerical value for both fields. Also, field cannot be left blank.")
ElseIf validationCheck() = True Then
lblResult.Text = Val(txt1stNumber.Text) / Val(txt2ndNumber.Text)
End If
You can add one more condition into you function to evaluate txt2ndNumber.Text like this, then if the number b is 0 or 00 like this this will also return false.
Private Function validationCheck() As Boolean
If IsNumeric(txt1stNumber.Text) And txt1stNumber.Text <> "" And IsNumeric(txt2ndNumber.Text) And txt2ndNumber.Text <> "" Then
Dim number As Double = txt2ndNumber.Text
If number = 0 Then
Return False
Else
Return True
End If
Else
Return False
End If
End Function

Automatic decimal places in textbox

It looks very strange, but I can't find an online solution for my problem! At least in VB.NET.
Here's the deal:
I have a TextBox in a form (limited to numbers by a KeyPress event) and want to keep two decimal places as long as the user inputs his data.
For example, if the TextBox is blank, then, when the user presses, let's say, "2", the TextBox shows "0,02". Then, if the user presses "7", the TextBox shows "0,27". Then again, by pressing "6", it shows "2,76" and so on...
I managed to do this for one decimal place with the code:
Select Case Me.TextBox.Text
Case ""
Case ","
Me.TextBox.Text = ""
Case Else
Me.TextBox.Text = Strings.Left(Replace(Me.TextBox.Text, ",", ""), Strings.Len(Replace(Me.TextBox.Text, ",", "")) - 1) & "," & Strings.Right(Replace(Me.TextBox.Text, ",", ""), 1)
Me.TextBox.SelectionStart = Len(Me.TextBox.Text)
End Select
Please note that: 1. This code's running on a TextChanged event; 2. I'm from Portugal and here we use a comma (",") instead of a dot (".") for the decimal separator.
Could you help me to adjust my piece of code to work properly with two decimal places?
Any help will be very appreciated. And, as always, thank you all in advance.
Here's a custom class I've made which does what you require:
Public Class FactorDecimal
Private _value As String = "0"
Public DecimalPlaces As Integer
Public Sub AppendNumber(ByVal Character As Char)
If Char.IsNumber(Character) = False Then Throw New ArgumentException("Input must be a valid numerical character!", "Character")
_value = (_value & Character).TrimStart("0"c)
End Sub
Public Sub RemoveRange(ByVal Index As Integer, ByVal Length As Integer)
If _value.Length >= Me.DecimalPlaces + 1 AndAlso _
Index + Length > _value.Length - Me.DecimalPlaces Then Length -= 1 'Exclude decimal point.
If Index + Length >= _value.Length Then Length = _value.Length - Index 'Out of range checking.
_value = _value.Remove(Index, Length)
If _value.Length = 0 Then _value = "0"
End Sub
Public Overrides Function ToString() As String
Dim Result As Decimal
If Decimal.TryParse(_value, Result) = True Then
'Divide Result by (10 ^ DecimalPlaces) in order to get the amount of decimal places we want.
'For example: 2 decimal places => Result / (10 ^ 2) = Result / 100 = x,xx.
Return (Result / (10 ^ Me.DecimalPlaces)).ToString("0." & New String("0"c, Me.DecimalPlaces))
End If
Return "<parse error>"
End Function
Public Sub New(ByVal DecimalPlaces As Integer)
If DecimalPlaces <= 0 Then DecimalPlaces = 1
Me.DecimalPlaces = DecimalPlaces
End Sub
End Class
It works by letting you append numbers to form a long string of numerical characters (for example 3174 + 8 = 31748), then when you call ToString() it does the following:
It parses the long number string into a decimal (ex. "31748" => 31748.0)
It divides the decimal by 10 raised to the power of the amount of decimals you want (for example: 2 decimals => 31748.0 / 102 = 317.48).
Finally it calls ToString() on the decimal with the format 0.x - where x is a repeating amount of zeros depending on how many decimals you want (ex. 2 decimals => 0.00).
NOTE: This solution adapts to the current system's culture settings and will therefore automatically use the decimal point defined in that culture. For example in an American (en-US) system it will use the dot: 317.48, whereas in a Swedish (sv-SE) or Portuguese (pt-PT) system it will use the comma: 317,48.
You can use it like this:
Dim FactorDecimal1 As New FactorDecimal(2)
Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
If Char.IsNumber(e.KeyChar) = False Then
e.Handled = True 'Input was not a number.
Return
End If
FactorDecimal1.AppendNumber(e.KeyChar)
TextBox1.Text = FactorDecimal1.ToString()
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
Dim TargetTextBox As TextBox = DirectCast(sender, TextBox)
e.SuppressKeyPress = True
Select Case e.KeyData 'In order to not block some standard keyboard shortcuts (ignoring paste since the pasted text won't get verified).
Case Keys.Control Or Keys.C
TargetTextBox.Copy()
Case Keys.Control Or Keys.X
TargetTextBox.Cut()
Case Keys.Control Or Keys.A
TargetTextBox.SelectAll()
Case Keys.Back, Keys.Delete 'Backspace or DEL.
FactorDecimal1.RemoveRange(TextBox1.SelectionStart, If(TextBox1.SelectionLength = 0, 1, TextBox1.SelectionLength))
TextBox1.Text = FactorDecimal1.ToString()
Case Else
e.SuppressKeyPress = False 'Allow all other key presses to be passed on to the KeyPress event.
End Select
End Sub
Online test: http://ideone.com/fMcKJr
Hope this helps!
Thank you #Visual Vincent. Your method works fine. However I managed to find a simpler way of doing what I asked by the following code:
Private Sub TextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox.KeyPress
If Not Char.IsDigit(e.KeyChar) And Not Char.IsControl(e.KeyChar) Then
e.Handled = True
End If
End Sub
Private Sub TextBox_TextChanged(sender As Object, e As EventArgs) Handles TextBox.TextChanged
Select Case Val(Replace(Me.TextBox.Text, ",", "."))
Case 0 : Me.TextBox.Text = ""
Case Else
Me.TextBox.Text = Format(Val(Replace(Me.TextBox.Text, ",", "")) / 100, "0.00")
Me.TextBox.SelectionStart = Len(Me.TextBox.Text)
End Select
End Sub
This piece of code look suspicious simple to me. For now it works fine and does the trick exactly how I wanted. Maybe there's something missing to me, or maybe I wasn't clear enough on the description of my goal.
If you find any flaw on my method, please feel free to point it! I'll appreciate it very much.

Code iterating through whole string in hangman

How can I stop my code from iterating through a whole string stating whether the input from the user matches that of the random string bearing in mind this is for a hangman game, I want the code to just display once if the user's chosen letter is either correct or incorrect rather than displaying up too eight times.
Sub letterInput()
For i As Integer = 0 To randomWord.Length - 1
If userInput = randomWord(i) Then
MessageBox.Show("correct")
ElseIf userInput <> randomWord(i) Then
MessageBox.Show("incorrect")
Label4.Text = counter
Exit for
End If
Next
End Sub
Sub wordGeneration()
Dim wordUsed As Array = {"pizza", "noodle", "zombie", "object", "rowin", "running", "elephant", "lion"}
Dim random As New Random
randomWord = wordUsed(random.Next(0, 9))
Label2.Text = randomWord
End Sub
What I meant in the comments was that you just need to replace your for loop with a simple if/else. String.Contains checks the whole string already, so there is no need to iterate through each letter anymore:
Sub letterInput()
If randomWord.Contains(userInput) Then
MessageBox.Show("correct")
Else
MessageBox.Show("incorrect")
Label4.Text = counter
End If
End Sub

Random Generator in Loop

I am having some problems with an assignment. The case project is:
Create an application that allows the user to guess a random number generated by the computer. When the user makes an incorrect guess, the application should move an image either upr or down, depending on how the guess compares to the random number. If the random number is greater than the user's guess, the application should move the image up to indicate that the user needs to guess a higher number. If the random number is less than the user's guess, the application should move the image down to indicate that the user needs to guess a lower number. The game ends when the user guesses the random number. However, the application should allow the user to stop the game prematurely. When that happens the application should siplay the random number.
I have tried every which way I can think of including using a textbox instead of an inputbox and playing around with the syntax - but just can't seem to get it right. Advice would be much appreciated. Thanks.
My code:
Public Class Form1
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Me.Close()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Number As Integer
Dim inputNumber As Integer
Dim answer As Integer
Dim isconverted As Boolean
Dim computerchoice As New Random
answer = computerchoice.Next(1, 20)
inputNumber = InputBox("Please guess number", "Random Number Game")
Do
isconverted = Integer.TryParse(inputNumber, Number)
If isconverted = True Then
If answer = Number Then
MessageBox.Show("You Win")
ElseIf answer > Number Then
PictureBox1.SetBounds(0, 90, 0, 0, BoundsSpecified.Y)
ElseIf answer < Number Then
PictureBox1.SetBounds(0, 220, 0, 0, BoundsSpecified.Y)
End If
Else
MessageBox.Show("Please enter a valid number between 1 - 20 only")
End If
inputNumber = InputBox("Please guess number", "Random Number Game")
Loop While answer <> Number
MessageBox.Show("Answer:" & answer.ToString)
End Sub
End Class
Your code actually almost worked. A few things though:
The only thing that really didn't work was the picture moving up and down. All you have to do for that is to increment/decrement the .Top property.
Because you converted your input to a number at the beginning of the loop and not evaluating till the end, you were looping through an extra time after you got the right answer.
The number comparison after the conversion was redundant, since you know they got the number if they exit the loop.
If you're new to Visual Studio and don't know about breakpoints and other debugging, it is worth it to look into those. With these tools you can pause your code at given points in your program, look at the values variables hold, and step through your code line-by-line.
Here's the working code:
Do
If isconverted = True And Number >= 1 And Number <= 20 Then
If answer > Number Then
PictureBox1.Top -= 10
ElseIf answer < Number Then
PictureBox1.Top += 10
End If
Else
MessageBox.Show("Please enter a valid number between 1 - 20 only")
End If
inputNumber = InputBox("Please guess number", "Random Number Game")
isconverted = Integer.TryParse(inputNumber, Number)
Loop While (answer <> Number)
MessageBox.Show("You Win! The answer is " & answer.ToString)