Why is my if statement only returning the second result? - vb.net

My calculations work but every time I run the program my output will be the "negative, does not exceed" result. I'm very new to all this so please any suggestions will help.
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim foodname As String = MaskedTextBox1.Text
Dim calories As Integer = MaskedTextBox2.Text
Dim fat As Integer = MaskedTextBox3.Text
Dim calculation As Double = (fat * 9) / calories
Dim positive As String = "which exceeds AHA recommendation"
Dim negative As String = "which does not exceed AHA recommendation"
ListBox1.Items.Clear()
If ((fat * 9) / calories) > (0.3 * 100) Then
ListBox1.Items.Add(foodname & " contains " & FormatPercent(calculation) & " calories from fat, " & positive)
ElseIf ((fat * 9) / calories) < (0.29 * 100) Then
ListBox1.Items.Add(foodname & " contains " & FormatPercent(calculation) & " calories from fat, " & negative)
End If
End Sub
End Class

would this help?
If ((fat * 9) / calories) > (0.3 * 100) Then
ListBox1.Items.Add(foodname & " contains " & FormatPercent(calculation) & " calories from fat, " & positive)
Else
ListBox1.Items.Add(foodname & " contains " & FormatPercent(calculation) & " calories from fat, " & negative)
End If
you have only two options here, no need for 2 conditions. either the first one is true, or it must be the second one

Related

System.IndexOutOfRangeException VB GradeBook

So I get this error when trying to run my code "System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'" I am not exactly sure what the issue is. The user should be able to enter 3 assignment grades and then see the averages
I marked the line where I get the error with 'THIS IS THE ERROR'
Public Class GradeBook
Dim grade(9, 2) As Integer 'Store 10 student grades on 3 tests'
Dim studentCount As Integer = 0 'Number of students entered'
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
End Sub
Private Sub SubmitButton_Click(sender As Object, e As EventArgs) Handles SubmitButton.Click
grade(studentCount, 0) = Convert.ToInt32(Assignment1TextBox.Text)
grade(studentCount, 1) = Convert.ToInt32(Assignment2TextBox.Text)
grade(studentCount, 2) = Convert.ToInt32(Assignment3TextBox.Text)
Dim output As String = "Student " & studentCount & vbTab
For column = 0 To grade.GetUpperBound(1)
If LetterRadioButton.Checked = True Then
output &= vbTab & LetterGrade(grade(studentCount, column))
Else
output &= vbTab & grade(studentCount, column)
End If
Next
output &= vbTab & CalculateStudentAverage(studentCount)
GradeListBox.Items.Add(output)
studentCount += 1
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
End Sub
Function LetterGrade(ByVal grade As Double) As String
Dim output As String = ""
Select Case grade
Case Is >= 90
output = "A"
Case Is >= 80
output = "B"
Case Is >= 70
output = "C"
Case Is >= 60
output = "D"
Case Is >= 50
output = "E"
End Select
Return output
End Function
Function CalculateStudentAverage(ByVal row As Integer) As String
Dim gradeTotal As Integer = 0
For column = 0 To grade.GetUpperBound(1)
gradeTotal += grade(row, column) 'THIS IS THE ERROR'
Next
Dim studentAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
studentAverage = LetterGrade(gradeTotal / (grade.GetUpperBound(1) + 1))
Else
studentAverage = String.Format("{0:F}", (gradeTotal / grade.GetUpperBound(1) + 1))
End If
Return studentAverage
End Function
Function CalculateClassAverage() As String
Dim classTotal As Integer = 0
For row = 0 To studentCount - 1
For column = 0 To grade.GetUpperBound(1)
classTotal += grade(row, column)
Next
Next
Dim classAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
classAverage = LetterGrade(classTotal / (studentCount * (grade.GetUpperBound(1) + 1)))
Else
classAverage = String.Format("{0:F}", (classTotal / (studentCount * (grade.GetUpperBound(1) + 1))))
End If
Return classAverage
End Function
Sub displayBarChart()
GradeListBox.Items.Clear()
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
For row = 0 To studentCount - 1
Dim output As String = "Student " & row & vbTab
For column = 0 To grade.GetUpperBound(1)
If LetterRadioButton.Checked = True Then
output &= vbTab & LetterGrade(grade(row, column))
Else
output &= vbTab & (grade(row, column))
End If
Next
output &= vbTab & CalculateStudentAverage(studentCount)
GradeListBox.Items.Add(output)
studentCount += 1
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
Assignment1TextBox.Clear()
Assignment2TextBox.Clear()
Assignment3TextBox.Clear()
If studentCount = grade.GetUpperBound(0) + 1 Then
InputGradeGroupBox.Enabled = False
End If
Next
End Sub
End Class
To be honest, I suspect you're going about it in a way not suited to OOP. Using arrays for multiple peices of data is prone to error and harder to maintain later.
Lets have a think about how you want to represent your data. You have a bunch of students. In a more complete example each student would have a name, personal details such as address, a list of the courses they're taking and for each course, a list of assignments and scores for each assignment which can also be represented as a grade.
So in essence you have a class called Student and the various bits of information are properties of that student.
Finally you have a list of these students
In your code, you simply have a student number and three assignment scores.
Your basic student class should have the properties of Number, Test1Score, Test2Score and Test3Score. You would also want to be able to get the grade from each score, the average of all the scores and the average of all the grades.
The code below defines the Student class with that information in mind
Friend Class Student
Public Property Number As Integer
Public Property Test1Score As Integer
Public Property Test2Score As Integer
Public Property Test3Score As Integer
Public Function Test1Grade() As String
Return LetterGrade(Test1Score)
End Function
Public Function Test2Grade() As String
Return LetterGrade(Test2Score)
End Function
Public Function Test3Grade() As String
Return LetterGrade(Test3Score)
End Function
Friend Shared Function LetterGrade(ByVal grade As Double) As String
Dim output As String = ""
Select Case grade
Case Is >= 90
output = "A"
Case Is >= 80
output = "B"
Case Is >= 70
output = "C"
Case Is >= 60
output = "D"
Case Is >= 50
output = "E"
Case Else
output = "F"
End Select
Return output
End Function
Friend Function AverageScore() As Double
Return (Test1Score + Test2Score + Test3Score) / 3
End Function
Friend Function AverageGrade() As String
Dim avgscore As Double = AverageScore()
Return LetterGrade(avgscore)
End Function
End Class
The function LetterGrade is Shared so that it can be used in your main form to calculate the average grade for the entire class.
OK Next think about how you want your program to work. You'll need a list of students, so at the beginning of your form class , you'll need this..
Public Class Form1
Private Students As New List(Of Student)
This way, instead of trying to keep track of your variable studentCount you can just use the .Count property of the List e.g Students.Count. You wont need to any adding to it as the Students list keeps track of it automatically.
Next, you'll want the function that calculates the average score/grade of the class..
Function CalculateClassAverage() As String
Dim classTotal As Integer = 0
For Each tmpStudent As Student In Students
With tmpStudent
classTotal += .Test1Score + .Test2Score + .Test3Score
End With
Next
Dim classAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
classAverage = Student.LetterGrade((classTotal / Students.Count) / 3)
Else
classAverage = String.Format("{0:F}", (classTotal / (Students.Count)) / 3)
End If
Return classAverage
End Function
As you can see, there are a number of differences here because of the way your data is stored, but you should be able to follow it. One difference is the With statement, this allows you to save on typing. inside the With.. End With block, instead of typing tmpstudent.Test1Score etc, you can just type .Test1Score
The other thing of note is this line ..
classAverage = Student.LetterGrade( ... etc
You may think that there has been no declaration of a variable called Student. There IS a class, but not a variable. What this is actually doing is calling the LetterGrade function that is shared in the Student class definition.. Have a look at shared functions.
Next is the code to display the information in the ListBox. I haven't changed the name even though it is misleading btw.
Sub displayBarChart()
GradeListBox.Items.Clear()
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
For Each tmpstudent As Student In Students
Dim output As String = "Student " & tmpstudent.Number & vbTab
With tmpstudent
If LetterRadioButton.Checked = True Then
output &= .Test1Grade & vbTab & .Test2Grade & vbTab & .Test3Grade & vbTab & .AverageGrade
Else
output &= .Test1Score & vbTab & .Test2Score & vbTab & .Test3Score & vbTab & .AverageScore
End If
End With
GradeListBox.Items.Add(output)
AverageLabel.Text = CalculateClassAverage()
Next
If Students.Count = 10 Then
InputGradeGroupBox.Enabled = False
End If
End Sub
More use of the With..End With statements again, but the rest should be straighforward to follow.
A little extra bit of code.. When you click on the LetterRadioButton, the data in the listBox and ClassAveragelabel are refreshed with the appropriate letters/grades
Private Sub LetterRadioButton_CheckedChanged(sender As Object, e As EventArgs) Handles LetterRadioButton.CheckedChanged
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
End Sub
Finally, to bring it all together, you have the code for the button click..
Private Sub SubmitButton_Click(sender As Object, e As EventArgs) Handles SubmitButton.Click
Dim tmpStudent As New Student With {.Number = Students.Count + 1,
.Test1Score = Convert.ToDouble(Assignment1TextBox.Text),
.Test2Score = Convert.ToDouble(Assignment2TextBox.Text),
.Test3Score = Convert.ToDouble(Assignment3TextBox.Text)}
Dim output As String = "Student " & tmpStudent.Number & vbTab
With tmpStudent
If LetterRadioButton.Checked = True Then
output &= vbTab & .Test1Grade & vbTab & .Test2Grade & vbTab & .Test3Grade
Else
output &= vbTab & .Test1Score & vbTab & .Test2Score & vbTab & .Test3Score
End If
End With
Students.Add(tmpStudent)
If LetterRadioButton.Checked Then
output &= vbTab & tmpStudent.AverageGrade
Else
output &= vbTab & tmpStudent.AverageScore
End If
GradeListBox.Items.Add(output)
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
Assignment1TextBox.Clear()
Assignment2TextBox.Clear()
Assignment3TextBox.Clear()
End Sub
Hopefully in addition to my comment to your question, this provides a slightly better insight of OOP.

Transitioning from recordset to dataset

I'm working on a project of trying to update from VB6 to VS.Net.. I'm very iffy and lost on how the recordset is supposed to be functioning in this piece of code, so of course that doesn't help with trying to do the same action with a dataset. I would be most grateful if someone could explain this and advise on how to proceed implementing with a dataset. It's the "Recordset!" portion that is really throwing me off.
Private Sub cmdTemp_Click()
Dim sz As String
If txtTemp >= 0 Then
sz = "Update ProdSheet set Temp = " & txtTemp & " "
sz = sz & "Where Prod like '" & adoSchedList.Recordset!Prod & "' "
adoLoggedDBExecute sz
Else
MsgBox "Enter a Value for the Temperature you wish to update"
End If
End Sub
this is my attempt in VS 2017
Private Sub CmdTemp_Click(sender As Object, e As EventArgs) Handles CmdTemp.Click
Dim sz As String
With TxtTemp
If IsNumeric(.Text) Then
If Val(.Text) >= 0 Then
sz = "Update ProdSheet set Temp = " & TxtCheck.Text & " "
sz = sz & "Where Prod = #!Prod "
LoggedDBExecute(conn, sz)
MsgBox("Worked")
End If
Else
MsgBox("Please enter a numeric value!")
End If
End With
End Sub

Why is skipping the else part of my code?

'REQUIREMENTS:Write a Visual Basic procedure called CalculateTotalCost that reads user-entered data from the txtQuantity and txtUnitCost TextBox controls. The CalculateTotalCost procedure should convert the text entered in the two TextBox controls into numbers. It should then multiple the two numbers together, apply the appropriate discount based on the quantity ordered, and display the result in the lblTotalCost Label control.
The following error-checking rules apply:
a. The text entered by the user in the txtQuantity TextBox control must represent a non-negative Integer. If it does not, the procedure should output the phrase “Invalid quantity!” in the lblTotalCost Label control and no further processing should take place.
b. The text entered by the user in the txtUnitCost TextBox control must represent a non-negative Double. If it does not, the procedure should output the phrase “Invalid unit cost!” in the lblTotalCost Label control and no further processing should take place.
Assuming no user input errors, the properly discounted total presented in the lblTotalCost Label control should be displayed in currently format. The display should contain a leading currency symbol (depending on how the computer was set up, this will probably be a dollar sign) and exactly two trailing digits after the included decimal point.
Public Class Form1
Private Sub lblTotalCost_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblTotalCost.Click
'Author: Eric Konga_ 14200694 _BCIT/3_ The Papaua New Guinea University of Technology
' this program will read read user entered data from the two text boxes on the form and
' will calcualte (Multiply) the two numbers together and will then apply the appropriate discount
'based on the quantity ordered, and display the result(Total Cost) in the Label control.
'Declaring Variables as strings. This sets will out put to the screen the appropriate percentages
'based the quantity ordered.
Dim strDiscount As String
Dim strDiscount1 As String
Dim strDiscount2 As String
Dim strDiscount3 As String
Dim strDiscount4 As String
'declaring variables as integer, double and long. this sets of program will output to the screen
'
Dim intQuantity As Integer
Dim dblUnitCost As Double
Dim dblTotalCost As Double
'Assigning Variables
strDiscount = "0%"
strDiscount1 = "20%"
strDiscount2 = "30%"
strDiscount3 = "40%"
strDiscount4 = "50%"
' This is a mathematical calculator that calculates the TotalCost (TC).
intQuantity = txtQuantity.Text
dblUnitCost = txtUnitCost.Text
dblTotalCost = intQuantity * dblUnitCost
If intQuantity <= 9 Then
lblTotalCost.Text = "The Total Cost is: $" & String.Format("{0:n2}", dblTotalCost) & " and it's " & strDiscount & _
" Discount."
ElseIf intQuantity <= 19 Then
lblTotalCost.Text = "The Total Cost is: $" & String.Format("{0:n2}", dblTotalCost) & " and it's " & strDiscount1 & _
" Discount."
ElseIf intQuantity <= 49 Then
lblTotalCost.Text = "The Total Cost is: $" & String.Format("{0:n2}", dblTotalCost) & " and it's " & strDiscount2 & _
" Discount."
ElseIf intQuantity <= 99 Then
lblTotalCost.Text = "The Total Cost is: $" & String.Format("{0:n2}", dblTotalCost) & " and it's " & strDiscount3 & _
" Discount."
ElseIf intQuantity >= 100 Then
lblTotalCost.Text = "The Total Cost is: $" & String.Format("{0:n2}", dblTotalCost) & " and it's " & strDiscount4 & _
" Discount."
' under this condition, it will only execute if the integer(QTY) is negative or
'the unser entered float(UC) is negative.
Else
lblTotalCost.Text = (" Invalid Quantity!" & " or Ivalid Unit Cost!")
End If
End Sub
End Class
Because your first if condition is <= 9. This includes all negative integers.

Visual Basic invalid cast runtime error

I'm new at Visual Basic, doing an assignment right now. This is the code I have
Sub Main()
Console.Write("Please let me know your nickname: ")
Dim name As String = Console.ReadLine()
Console.WriteLine("Thank you " + name + "!")
Console.WriteLine()
Console.Write("How many litres " + name + "<only whole litres please>? ")
Dim litres As Integer = Console.ReadLine()
Console.Write("Premium quality? <y/n>: ")
Dim ans As Char = Console.ReadLine()
Dim prem As Boolean
If ans = "y" Then
prem = True
ElseIf ans = "n" Then
prem = False
End If
Console.WriteLine()
Console.WriteLine("WELCOME TO APU'S GAS STATION")
Console.Write("Quality: ")
If prem = True Then
Console.Write("Premium")
Else : Console.Write("Regular")
End If
Dim price As Double = 12.44
Console.WriteLine("Quantity <l>: " + litres)
Console.WriteLine("Price per l: " + price)
Console.WriteLine("Sum to pay: " + litres * price)
Console.ReadLine()
End Sub
At runtime I can input all data no problem, but then I get an error that I can roughly translate to "invalid cast of the string "Quantity : " to type 'Double'.
I'm not so sure what is going on, would appreciate pointers.
to avoid this problem you can use
Console.WriteLine("Quantity <l>: " + litres.ToString)
Or you can use
Console.WriteLine("Quantity <l>: " + CStr(price))
I fixed your code, this should work :
Sub Main()
Console.Write("Please let me know your nickname: ")
Dim name As String = Console.ReadLine()
Console.WriteLine("Thank you " & name & "!")
Console.WriteLine()
Console.Write("How many litres " & name & "<only whole litres please>? ")
Dim litres As Integer = Console.ReadLine()
Console.Write("Premium quality? <y/n>: ")
Dim ans As Char = Console.ReadLine()
Dim prem As Boolean
If ans = "y" Then
prem = True
ElseIf ans = "n" Then
prem = False
End If
Console.WriteLine()
Console.WriteLine("WELCOME TO APU'S GAS STATION")
Console.Write("Quality: ")
If prem = True Then
Console.Write("Premium")
Else : Console.Write("Regular")
End If
Dim price As Double = 12.44
Console.WriteLine("Quantity <l>: " & litres)
Console.WriteLine("Price per l: " & price)
Console.WriteLine("Sum to pay: " & (litres * price))
Console.ReadLine()
End Sub

how to order a text file without using array and query

I'm trying to order a text file which contain numbers and rewrite it in other textile without using query of array
i try to do it using a comparing statement but in the end it only write one number in the new text file
to make it clear the program is to find the median number in that file which is something i can't do without reordering the file descending or ascending
This is what i did
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sw As IO.StreamReader = IO.File.OpenText("Numbers.txt")
Dim sr As IO.StreamWriter = IO.File.CreateText("Numbers2.txt")
Dim num As Double
Dim min As Double = CDbl(sw.ReadLine)
Dim line As String = sw.ReadLine
Do Until sw.EndOfStream
num = CDbl(sw.ReadLine)
If min > num Then
sr.WriteLine(num)
End If
Loop
sr.Close()
End Sub
Well, of curse I have no idea how your text file looks, I can't help without his string format
So I made two functions who will help about the median program
the program is to find the median number in that file
You can test this code just add 1 button in a frame that's all (I wrote some strings for test, you can change it)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Button1.Text = "20; 30; 50; 40; 10; 80; 90; 70" Then 'A pair list of simple numbers
Button1.Text = "20; 30; 50; 40; 80; 90; 70" 'Odd list of simple numbers
Else
If Button1.Text = "20; 30; 50; 40; 80; 90; 70" Then
Button1.Text = "18; 91,123; 47,789; 29; 35; 78.456; 91; 84" 'A test with a mix of some decimal separators mistakes
Else
If Button1.Text = "18; 91,123; 47,789; 29; 35; 78.456; 91; 84" Then
Button1.Text = "25.45; 78; 10.123; 65; 27.485; 78; 19; 41; 26" 'Another odd test
Else
Button1.Text = "20; 30; 50; 40; 10; 80; 90; 70"
End If
End If
End If
Dim StringList As String = Button1.Text
Me.Text = "Medan of " & StringList & " = " & MedianOf(StringList, "; ") 'Using "; " (; + space) separator (can be changed)
End Sub
Private Function MedianOf(ByVal StrLine As String, ByVal Separator As String) As Double
Dim Nb As Double
Dim Str As String = StrLine
'Write all values in the good order with the next function down here e.g.(from "23; 12; 78; ..." to "12; 23; 78; ...")
StrLine = GetOrderOf(StrLine, Separator)
'Counts how many values StrLine contains
Dim ValuesInString = System.Text.RegularExpressions.Regex.Split(StrLine, "\" & Separator).GetUpperBound(0) + 1
'Check ValuesInString count odd's (calculated with different ways)
If ((ValuesInString And 1) = 1) = True Then
Nb = CDbl(System.Text.RegularExpressions.Regex.Split(StrLine, "\" & Separator)(ValuesInString \ 2))
MessageBox.Show("ODD:" & Environment.NewLine & "First String = " & Str & Environment.NewLine & "Ordered string = " & StrLine & Environment.NewLine & "*** Median value = " & Nb & " ***")
Else
Nb = (CDbl(System.Text.RegularExpressions.Regex.Split(StrLine, "\" & Separator)((ValuesInString / 2) - 1)) + CDbl(System.Text.RegularExpressions.Regex.Split(StrLine, "\" & Separator)(ValuesInString / 2))) / 2
MessageBox.Show("PAIR:" & Environment.NewLine & "First String = " & Str & Environment.NewLine & "Ordered string = " & StrLine & Environment.NewLine & "(" & StrLine.Split(Separator)((ValuesInString / 2) - 1) & "+" & StrLine.Split(Separator)(ValuesInString / 2) & ")/2 = " & Nb)
End If
'MessagesBoxes were added only for a best understanding of how it works
'Should be disabled if tests are ok
Return Nb
End Function
Private Function GetOrderOf(ByVal Line As String, ByVal Separator As String) As String
If Separator = "." Or Separator = "," Then MessageBox.Show("Wrong... so Wrong separator")
Line = Line.Replace(".", ",")
Dim Line_InOrder As String = ""
Dim Str As String = ""
Dim Nb As Double = 0
Do While Line.Length > 0
Nb = 0
If Line.Contains(Separator) Then
For Each St As String In System.Text.RegularExpressions.Regex.Split(Line, "\" & Separator)
If CDbl(St) > Nb Then
Nb = CDbl(St)
Str = St
End If
Next
Else
Str = Line
Line &= Separator
End If
If Line.Contains(Str & Separator) Then
Line = Replace(Line, Str & Separator, "", , 1)
Else
Line = Replace(Line, Separator & Str, "", , 1)
End If
If Line_InOrder.Length = 0 Then
Line_InOrder = Str
Else
Line_InOrder = Str & Separator & Line_InOrder
End If
Loop
Return Line_InOrder
End Function