I have a pretty basic program as an assignment (I'm a beginner so it's still tricky for me) that requires you to enter a decimal value, and have a check box do a calculation and then show the result in different labels. I'm constantly getting errors when I checkthe check box with no values added.
Private Sub chkGST_CheckedChanged(sender As Object, e As EventArgs) Handles chkGST.CheckedChanged
'get txtDollarAmt*const dGST (0.07D) display lblGSTOutput. txtDollarAmt+dGST, display lblTotalOutput
Dim dAmt As String
dAmt = Decimal.Parse(txtDollarAmt.Text)
If chkGST.Checked = True Then
lblGSTOutput.Text = dAmt * dGST
End If
End Sub
Dim dAmt As Decimal
If Decimal.TryParse(txtDollarAmt.Text, dAmt) Then
If chkGST.Checked = True Then
lblGSTOutput.Text = dAmt * dGST
End If
End If
Before trying to parse the text(Convert it to Decimal), check if it is null.
Use Try Catch block.
instead of this line.
dAmt = Decimal.Parse(txtDollarAmt.Text)
Use this-
Try
dAmt = Decimal.Parse(txtDollarAmt.Text)
Catch e As FormatException
End Try
Related
I need some help with my code in a Rectangle calculator... So I made a rectangle area calculator that features Length, Width, Area, Number of Rectangles, and Smallest Rectangle... I am also creating a catch bock that handles invalid-cast extractions 2 of them... Also a A expectation class when the value of the result is greater then 1 Million... Here is my code
Public Class Form1
Dim area As Decimal
Dim numberofRectangles As Integer
Dim smallestRectangle As Decimal
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Try
Dim length As Decimal = CDec(txtLength.Text)
Dim width As Decimal = CDec(txtWidth.Text)
Dim Area As Decimal = width * length
Dim numberofRectangles As Integer = numberofRectangles + 1
Dim smallestRectangle As Decimal = Math.Min(smallestRectangle, Area)
txtArea.Text = Area.ToString("n2")
txtNumberOfRectangles.Text = numberofRectangles.ToString
txtSmallestRectangle.Text = smallestRectangle.ToString("n2")
txtLength.Select()
Catch ex As InvalidCastException
MessageBox.Show("Please check entries for valid numeric data",
ex.GetType.ToString)
Catch ex As OverflowException
MessageBox.Show("Please check to make sure entries aren't too large.",
ex.GetType.ToString)
Catch ex As Exception
MessageBox.Show(ex.Message & vbNewLine & vbNewLine & ex.StackTrace,
ex.GetType.ToString)
If area < 1000000000 Then
Throw New FormatException("The rectangle Is too large!")
Return
End If
Finally
End Try
End Sub
For one I am having a error where my smallest rectangle is at 999,999,999,00 and For the expectation when the value of the result is greater then 1 Million I am having trouble as you can probably see from the code. Looking for some advice on my code
Edit: Fix the top part Now getting 0.00 in the smallest rectangle box
Should I being using me.compute somehwhere aswell
You misspelled smallestRecntangle - this is why you have needed to redeclare it - it's different to the class variable smallestRectangle. For this reason, you never set smallestRectangle to anything other than 999999999.
Also - you can use a value called Decimal.MaxValue to do the same thing as 999999999, but using the actual maximum possible decimal number. However, I would recommend instead you use Decimal? and assign to null initially. In code, have a check which "is if smallestRectangle is null, then set smallestRectangle, otherwise set it to the minimum of smallestRectangle and area".
Exception handling is for unexpected errors that are out of your control. We can test the user input so we don't need exception handling for that.
ex.GetType.ToString
This doesn't make sense. If you want to display the Exception message you can use and ampersand & and ex.Message. ex.ToString generally provides more information than you want a user to see.
TryParse will check if the string provided in the first parameter can be converted. It returns True or False. If True it will assign the converted string to the second parameter.
numberofRectangles += 1
is a shortcut way of writing
numberofRectangle = numberofRectangles + 1
The only line of code that could throw an exception is the area calculation so we will limit the Try block to that line.
Your main problem was using the Dim statement for numberofRectangles and smallestRectangle inside the Sub. These variables loose there value at End Sub. They only exist inside the Sub. Although Dim has the same meaning as Private for declaring Class level varaibles, Private is preferred. Dim is used for local variable in a method.
To avoid the problem of having smallest rectangle always being zero, I checked the count and set smallestRectangle to the first rectangles area. After that Math.Min takes over.
Private numberofRectangles As Integer
Private smallestRectangle As Decimal
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim length As Decimal
Dim width As Decimal
If Not Decimal.TryParse(txtLength.Text, length) Then
MessageBox.Show("Please check entries for valid numeric data")
Exit Sub
End If
If Not Decimal.TryParse(txtWidth.Text, width) Then
MessageBox.Show("Please check entries for valid numeric data")
Exit Sub
End If
Dim Area As Decimal
Try
Area = width * length
Catch ex As OverflowException
MessageBox.Show("Please check to make sure entries aren't too large." &
ex.Message)
Exit Sub
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
numberofRectangles += 1
If numberofRectangles < 2 Then
smallestRectangle = Area
Else
smallestRectangle = Math.Min(smallestRectangle, Area)
End If
txtArea.Text = area.ToString("n2")
txtNumberOfRectangles.Text = numberofRectangles.ToString
txtSmallestRectangle.Text = smallestRectangle.ToString("n2")
txtLength.Select()
End Sub
I am attempting to make a random number generator in VB 16 in Visual Studio, but every time I run this I keep getting 71, I've tried making it public, sharing it and several other things, but it won't work. I am trying to make a program that has the user guess a randomly generated number, and continue guessing until they get it, but for some reason the exact same number is chosen each time. It won't work properly specifically in window app forms. How do I get a random number each time?
Public Shared Randomize()
Dim value As Integer = CInt(Int((100 * Rnd()) + 1))
Public Sub EnterBtn_Click(sender As Object, e As EventArgs) Handles EnterBtn.Click
Dim entervalue As String = EnterTxt.Text
Dim chances As Integer
Select Case entervalue
Case > value
ResTxt.Text = "Too big"
chances += 1
Case < value
ResTxt.Text = "Too small"
chances += 1
Case = value
ResTxt.Text = "Well done, you got it in " & chances & " tries"
End Select
End Sub
You were close! Here's a working example modifying your original logic:
Private random As Random = New Random()
Private value As Integer
Private chances As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
value = random.Next(1, 100)
chances = 0
End Sub
Private Sub EnterBtn_Click(sender As Object, e As EventArgs) Handles EnterBtn.Click
Select Case EnterTxt.Text
Case > value
chances += 1
ResTxt.Text = "Too big"
Case < value
chances += 1
ResTxt.Text = "Too small"
Case = value
chances += 1
ResTxt.Text = "Well done, you got it in " & chances & " tries"
'and reset for next attempt
value = random.Next(1, 100)
chances = 0
End Select
End Sub
Since your code is not correct it is hard to pinpoint the problem. It is also not clear what the code is supposed to do.
Try this
Private Shared PRNG As New Random ' add this
value = PRNG.Next(1, 101)'this will set value to a random number between 1 and 100 inclusive
Here's some skeleton code for you:
Dim rnd As New Random()
For i as Integer = 0 to 10
Console.WriteLine("{0,15:N0}", rnd.Next())
Next
Notice the rnd.Next() thing. Hope it helps.
I am working on a little tool that allows the selection of a single file. Where it will calculate the SHA2 hash and shows it in a simple GUI then takes the value and checks if that hash is listed in a blacklist text file. If it is listed then it will flag it as dirty, and if not it will pass it as clean.
But after hitting Google for hours on end and sifting through many online sources I decided let's just ask for advise and help.
That said while my program does work I seem to run into a problem, since no matter what I do ,it only reads the first line of my "blacklist" and refuses to read the whole list or to actually go line by line to see if there is a match.
No matter if I got 100 or 1 SHA2 hash in it.
So example if I were to have 5 files which I add to the so called blacklist. By pre-calculating their SHA2 value. Then no matter what my little tool will only flag one file which is blacklisted as a match.
Yet the moment I use the reset button and I select a different (also blacklisted) file, it passes it as clean while its not. As far as I can tell it is always the first SHA2 hash it seems to flag and ignoring the others. I personally think the program does not even check beyond the first hash.
Now the blacklist file is made up very simple.
*example:
1afde1cbccd2ab36f90973cb985072a01ebdc64d8fdba6a895c855d90f925043
2afde1cbccd2ab36f90973cb985072a01ebdc64d8fdba6a895c855d90f925043
3afde1cbccd2ab36f90973cb985072a01ebdc64d8fdba6a895c855d90f925043
4afde1cbccd2ab36f90973cb985072a01ebdc64d8fdba6a895c855d90f925043
....and so on.
So as you can see these fake example hashes are listed without any details.
Now my program is suppose to calculate the hash from a selected file.
Example:
somefile.exe (or any extension)
Its 5KB in size and its SHA2 value would be:
3afde1cbccd2ab36f90973cb985072a01ebdc64d8fdba6a895c855d90f925043
Well as you can see I took the third hash from the example list right?
Now if I select somefile.exe for scanning then it will pass it as clean. While its blacklisted. So if I move this hash to the first position. Then my little program does correctly flag it.
So long story short I assume that something is horrible wrong with my code, even though it seems to be working.
Anyway this is what I got so far:
Imports System.IO
Imports System.Security
Imports System.Security.Cryptography
Imports MetroFramework.Forms
Public Class Fsmain
Function SHA256_SIG(ByVal file_name As String)
Return SHA256_engine("SHA-256", file_name)
End Function
Function SHA256_engine(ByRef hash_type As String, ByRef file_name As String)
Dim SIG
SIG = SHA256.Create()
Dim hashValue() As Byte
Dim filestream As FileStream = File.OpenRead(file_name)
filestream.Position = 0
hashValue = SIG.ComputeHash(filestream)
Dim hash_hex = PrintByteArray(hashValue)
Stream.Null.Close()
Return hash_hex
End Function
Public Function PrintByteArray(ByRef array() As Byte)
Dim hex_value As String = ""
Dim i As Integer
For i = 0 To array.Length - 1
hex_value += array(i).ToString("x2")
Next i
Return hex_value.ToLower
End Function
Private Sub Browsebutton_Click(sender As Object, e As EventArgs) Handles Browsebutton.Click
If SampleFetch.ShowDialog = DialogResult.OK Then
Dim path As String = SampleFetch.FileName
Selectfile.Text = path
Dim Sample As String
Sample = SHA256_SIG(path)
SignatureREF.Text = SHA256_SIG(path)
Using f As System.IO.FileStream = System.IO.File.OpenRead("blacklist.txt")
Using s As System.IO.StreamReader = New System.IO.StreamReader(f)
While Not s.EndOfStream
Dim line As String = s.ReadLine()
If (line = Sample) Then
Result.Visible = True
SignatureREF.Visible = True
Result.Text = "Dirty"
Resetme.Visible = True
RemoveMAL.Visible = True
Else
Result.Visible = True
SignatureREF.Visible = True
Result.Text = "Clean"
Resetme.Visible = True
RemoveMAL.Visible = False
End If
End While
End Using
End Using
End If
End Sub
Private Sub Fsmain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Result.Visible = False
SignatureREF.Visible = False
Resetme.Visible = False
RemoveMAL.Visible = False
End Sub
Private Sub Resetme_Click(sender As Object, e As EventArgs) Handles Resetme.Click
Selectfile.Text = Nothing
SignatureREF.Text = Nothing
Result.Visible = False
SignatureREF.Visible = False
Resetme.Visible = False
RemoveMAL.Visible = False
End Sub
Private Sub RemoveMAL_Click(sender As Object, e As EventArgs) Handles RemoveMAL.Click
Dim ask As MsgBoxResult = MsgBox("Would you like to remove the Dirty file?", MsgBoxStyle.YesNo, MessageBoxIcon.None)
If ask = MsgBoxResult.Yes Then
System.IO.File.Delete(Selectfile.Text$)
Else
MsgBox("You sure you want to keep this file?")
Dim filepath As String = IO.Path.Combine("c:\Dirty\", "Dirty.txt")
Using sw As New StreamWriter(filepath)
sw.WriteLine(" " & DateTime.Now)
sw.WriteLine(" " & Selectfile.Text)
sw.WriteLine(" " & SignatureREF.Text)
sw.WriteLine(" " & Result.Text)
sw.WriteLine("-------------------")
sw.Close()
End Using
End If
End Sub
End Class
So if any of you guys can have a look at it and point out errors, or even can come up with a fix that would be great.
The simplest thing you can do to make your procedure working, is testing whether a defined condition is verified. Terminate the test if that condition is met.
Using a boolean variable, report the result of the test and take action accordingly.
The Using statement takes care of disposing the StreamReader.
You could modify you procedure this way:
Private Sub Browsebutton_Click(sender As Object, e As EventArgs) Handles Browsebutton.Click
If SampleFetch.ShowDialog <> DialogResult.OK Then Exit Sub
Dim sample As String = SHA256_SIG(SampleFetch.FileName)
SignatureREF.Text = sample
Dim isDirty As Boolean = False
Using reader As StreamReader = New StreamReader("blacklist.txt", True)
Dim line As String = String.Empty
While reader.Peek() > 0
line = reader.ReadLine()
If line = sample Then
isDirty = True
Exit While
End If
End While
End Using
If isDirty Then
'(...)
RemoveMAL.Visible = True
Result.Text = "Dirty"
Else
'(...)
RemoveMAL.Visible = False
Result.Text = "Clean"
End If
End Sub
If you have a String and you want to test whether it matches a line of a text file then you can use this simple one-liner:
If IO.File.ReadLines(filePath).Contains(myString) Then
Full disclosure, I'm working on an assignment for COP2170, but the additional feature isn't apart of the assignment just trying to stretch a little further...
I'm trying to add 5 test scores and output the average of the 5 scores, that part works just fine. In addition I'm trying to add an additional feature that will allow the user to enter less than 5 scores and the program will still output the average of whatever scores were entered.
So this works:
And this works:
The problem I'm running into is if the first score is omitted and the rest are filled in, it doesn't work:
Here's the code I've got so far:
Public Class frmTestScoreAverage
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim decScore1, decScore2, decScore3, decScore4, decScore5 As Double ' decScore1-5 to hold test scores1-5
Dim decScoreAverage As Double ' to hold test score average
Dim intDivideBy As Double = 5 ' declare intDivideBy variable with starting value of 5
lblStatusLabel.Text = String.Empty 'set error message to empty string
Try
' Read user input convert to double and assign value to variable
decScore1 = Convert.ToDouble(txtScore1.Text)
decScore2 = Convert.ToDouble(txtScore2.Text)
decScore3 = Convert.ToDouble(txtScore3.Text)
decScore4 = Convert.ToDouble(txtScore4.Text)
decScore5 = Convert.ToDouble(txtScore5.Text)
' Calculate average
decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy
'display result
lblResult.Text = CStr(decScoreAverage)
Catch
' Display error message, asks for all scores
lblStatusLabel.Text = "Please enter all test scores"
'Calculate average even without all scores
For Each c As TextBox In Me.Controls.OfType(Of TextBox)() 'loop through each textbox in form see: http://stackoverflow.com/a/13504361/1947286
If c.Text = String.Empty Then intDivideBy -= 1 'If text equals empty string, Then decrement intDivideBy
Next
'catch divide by zero error
Try
'calculate average
decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy 'add test scores and divide to find average
'display result
lblResult.Text = CStr(decScoreAverage)
Catch
lblStatusLabel.Text = "Please enter at least one test score"
End Try
End Try
End Sub
End Class
I'm pretty sure the problem has to do with the way I'm finding the average:
decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy
Is there a way to find the average that will allow for empty variables in any arrangement?
The problem you are having is that Convert.ToDouble(txtBox.text) (with empty string, will make Convert throw an Exception.
Add a validation that the string isn't empty or use TryParse to see if the Textbox value is parseable to a number.
Either
If not String.IsNullOrEmpty(txtBox.Text) then
Convert.ToDouble(txtBox.text)
Or
dim value as Double
if Double.TryParse(txtBox.Text, value) then
avg += value
When the first one is empty, it goes to the Catch part of the code, then you try to calculate the avg, but the values of the Txtbox are not assigned to the declarations you made, so when it tries to do the average
decScore1 = Convert.ToDouble(txtScore1.Text) // Exception here to Catch
decScore2 = Convert.ToDouble(txtScore2.Text) // Not evaluated
decScore3 = Convert.ToDouble(txtScore3.Text) // Not evaluated
decScore4 = Convert.ToDouble(txtScore4.Text) // Not evaluated
decScore5 = Convert.ToDouble(txtScore5.Text) // Not evaluated
Theses do not have any value, in return this doesn't do what you want
decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy
UPDATE
(Vb code not tested)
Function GetTextValue(dim score as string) as Double
dim value as Double = 0
if (Double.TryParse(score, value))
return value
else
return value
End Function
This
decScore1 = Convert.ToDouble(txtScore1.Text)
Becomes
decScore1 = GetTextValue(txtScore1.Text)
I suggest you store reference to each textbox in an array. You'll see why at the end of this example.
Public Class frmTestScoreAverage
Public Sub New()
Me.InitializeComponent()
Me.boxes = {Me.txtScore1, Me.txtScore2, Me.txtScore3, Me.txtScore4, Me.txtScore5}
End Sub
Private boxes As TextBox()
The common way to validate user input in winforms is to handle the Validating event, usually combined with the error provider class as mentioned by Hans Passant.
Private Sub HandleScoreValidating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles txtScore1.Validating, txtScore2.Validating, txtScore3.Validating, txtScore4.Validating, txtScore5.Validating
With DirectCast(sender, TextBox)
If ((Not String.IsNullOrEmpty(.Text)) AndAlso (Not Double.TryParse(.Text, 0.0R))) Then
e.Cancel = True
'Alert or set error provider:
'Me.ErrorProvider1.SetError(DirectCast(sender, Control), "Not double")
Else
e.Cancel = False
'Clear error provider:
'Me.ErrorProvider1.Clear()
End If
End With
End Sub
Now, back to the textbox array. Create a new list of double and iterate the textbox array. If the text isn't empty, parse and add the value to the list. At the end, use the Average extension method to get the average value.
Private Sub HandleCalculate(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim values As New List(Of Double)
For Each box As TextBox In Me.boxes
If (Not String.IsNullOrEmpty(box.Text)) Then
values.Add(Double.Parse(box.Text))
'Else
' values.Add(0.0R)
End If
Next
Dim average As Double = values.Average()
'....
End Sub
End Class
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.