Visual Basic Selection using a case statement task check - vb.net

Just wondering if what I've done for my visual basic computing homework is correct. Our activity task:
"Activity: Grade Selection using a Case statement
Introduction:
You will use a case statement that will allow a user to enter a grade value as an integer value and return the grade as a letter ranging from A to E.
Selection Logic
If the number entered is between 91-100 the output will be A
If the number entered is between 81 and 90 the output will be B
If the number entered is between 71 and 80 the output will be C
If the number entered is between 61 and 70 the output will be D
If the number entered is between 51 and 60 the output will be E
Anything lower than 50 is a fail
Anything higher than 100 is an incorrect value and they will have to run the program again.
Create the necessary variables
Create necessary outputs telling the user the purpose of the program
Create the code to read in the user's first name
Create the code that reads in the grade as an integer value
Create the code that produces the relevant grade based on the above criteria.
Create the necessary output code to output the user's first name and their grade as a letter of the alphabet"
My code:
Module Module1
Sub Main()
Dim anum As Integer
Dim name As String
Console.WriteLine("This programme converts marks into grades")
Console.WriteLine("Please enter name...")
name = Console.ReadLine
Console.WriteLine("Please enter number of marks...")
anum = Console.ReadLine()
Select Case anum
Case 91 To 100
Console.WriteLine(name & " receives an A.")
Case 81 To 90
Console.WriteLine(name & " receives a B.")
Case 71 To 80
Console.WriteLine(name & " receives a C.")
Case 61 To 70
Console.WriteLine(name & " receives a D.")
Case 51 To 60
Console.WriteLine(name & " receives an E.")
Case Is <= 50
Console.WriteLine(name & ", unfortunately failed.")
Case Is > 100
Console.WriteLine(name & ", this is an incorrect value. Please try again.")
End Select
End Sub
End Module
Would be thankful if someone could just confirm it is correct or tell me if I have done something wrong or need to add something!
Thanks.

Original code seems to be ok Just I've improved it using the correct datatypes, adding basic exception castings, and trying to simplify things:
Module Module1
' Store ranges and chars
ReadOnly TupleList As New List(Of Tuple(Of Short, Short, Char)) From { _
Tuple.Create(51S, 60S, "E"c), _
Tuple.Create(61S, 70S, "D"c), _
Tuple.Create(71S, 80S, "C"c), _
Tuple.Create(81S, 90S, "B"c), _
Tuple.Create(91S, 100S, "A"c) _
}
' Set custom strings formatting
ReadOnly str_OK As String = "{0}, receives an {1}."
ReadOnly str_FAIL As String = "{0}, unfortunately failed."
ReadOnly str_INCORRECT As String = "{0}, this is an incorrect value. Please try again."
Sub Main()
' Initialize user variables with a default value (0)
Dim anum As Short = 0
Dim name As String = 0
Console.WriteLine("This programme converts marks into grades")
Console.WriteLine("Please enter name...")
name = CStr(Console.ReadLine)
Try
Console.WriteLine("Please enter number of marks...")
anum = CShort(Console.ReadLine())
Catch ex As FormatException
Console.WriteLine("Please enter a valid number...")
Environment.Exit(1) ' Exit from application returning an error exitcode
Catch ex As Exception
Console.WriteLine(String.Format("{0}: {1}", _
ex.Message, _
ex.StackTrace))
Environment.Exit(1) ' Exit from application returning an error exitcode
End Try
Select Case anum
Case Is <= 50
Console.WriteLine(String.Format(str_FAIL, name))
Case Is >= 101
Console.WriteLine(String.Format(str_INCORRECT, name))
Case Else ' User value is inside an accepted range
For Each Item As Tuple(Of Short, Short, Char) In TupleList
If (anum >= Item.Item1 AndAlso anum <= Item.Item2) Then
Console.WriteLine(String.Format(str_OK, name, Item.Item3))
Environment.Exit(0) ' Exit from application
' Exit For
End If
Next Item
End Select
Environment.Exit(1) ' Exit from application returning an error exitcode
' ( When Is <= 50 or Is >= 101 )
End Sub
End Module

The only thing I would do different than your original code is:
Use "Case Else" in place of "Case Is > 100" for your final Case statement.
This way it would handle an error if someone entered something other than a number.
Good work and good luck!

Related

Why is Visual Basics Console.ReadLine Buggy and can I fix it?

Hey question about a visual basics program, I am using Console.ReadLine into a string but it seems when I get to that part of the program or any part of my console program the keyboard enter key enters twice or something it completly skips a ReadLine and recieves the input.length 0 before I even have a chance to enter a string.
This isnt runable without my full code I dont think but I cant seem to get ReadLine to prompt for a string when it is initially run, it always returns 0 once and then loops normally. Im wondering if that has something to do with my keyboard or keyboard settings for a visual basics program or command line.
I dont think its a keyboard error because when I am entering code into visual basics it works fine and doesnt send two returns. I couldnt get the full code in code blocks.
...
Shared Sub Main()
Dim s As New Space()
Dim Ship As New Ships()
Dim Run As Boolean = True
Dim ChooseName As Boolean = True
Dim ch As Char
Dim PlayerName As String
While Run = True
s.PrintWelcome()
ch = Convert.ToChar(Console.Read())
If ch = "1" Then
While ChooseName = True
Console.WriteLine("Choose a Name Less then 50 Characters: ")
PlayerName = Console.ReadLine()
If PlayerName.Length > 50 Then
Console.WriteLine("Name is to Long!")
ElseIf PlayerName = "Q" Then
Run = False
Exit While
ElseIf PlayerName.Length <= 0 Then
Console.WriteLine("Please Enter a Player name or Q by itself to quit.")
Else
ChooseName = False
Console.WriteLine("PlayerName: " & PlayerName & " PlayerName.Length: {0}", PlayerName.Length)
End If
End While
If Run = True Then
End If
ElseIf ch = "2" Then
ElseIf ch = "3" Then
Run = False
ElseIf ch = "Q" Then
Run = False
Else
s.PrintWelcome()
End If
End While
End Sub
...
I suspect that you really ought to be structuring your code more like this:
Module Module1
Sub Main()
Do
Console.Write("Please select a menu item from 1, 2, 3 or Q to quit: ")
Dim menuSelection = Console.ReadKey()
Dim input As String = Nothing
Console.WriteLine()
Select Case menuSelection.KeyChar
Case "1"c
Console.WriteLine("What did you want to say about 1?")
input = Console.ReadLine()
Case "2"c
Console.WriteLine("What did you want to say about 2?")
input = Console.ReadLine()
Case "3"c
Console.WriteLine("What did you want to say about 3?")
input = Console.ReadLine()
Case "q"c, "Q"c
Exit Do
Case Else
'Do nothing before repeating the prompt.
End Select
If Not String.IsNullOrEmpty(input) Then
Console.WriteLine("You said: " & input)
End If
Loop
End Sub
End Module
The ReadKey call will immediately read the first key entered by the user. Rather than requiring the user to hit Enter after that key, the application writes the line break itself. It then tests the chararacter represented by that key to see if it is a valid menu item. If it is, it does whatever is appropriate for that item, whether that be reading a line of input or quitting. If the key does not represent a valid menu item then it simply loops back to the prompt. Note also that the Char value entered by the user is actually compared to Char literals, the way it should be done, rather than String literals.

Validation to ensure value entered is a integer

I want a validation method that ensures that value entered is valid, it must be a integer (can include negative) and must not be blank. I have written this code, however not correct, can someone help me please. Thank you
If (b <> Integer Or " ") Then
Console.WriteLine("Value entered must be a number")
End If
new code:
Line98:
Console.WriteLine("Please input the value of, B:")
b = Console.ReadLine()
If Not Integer.TryParse(b, New Integer) Then
Console.WriteLine("Value entered must be a number")
GoTo Line98
End If
so i used a select statement, and if a user enters "abckak" any non numerical data i get an error Unhandled Exception: System.InvalidCastException: Conversion from string "gakjdg" to type 'Integer' is not valid.
how could this be fixed, this is a quick example of my code
Console.WriteLine("..........Main Menu..........")
Console.WriteLine("Please input 1 ")
Console.WriteLine("Please input 2")
Console.WriteLine("Please input 3 ")
Console.WriteLine("Please input 4 ")
Console.WriteLine("Please input 5 for Help")
Console.WriteLine("Please input 6 to Exit")
Console.WriteLine("Please enter your choice: ")
Choice = Console.ReadLine()
Select Case Choice
case1; etc
Case Else
Console.WriteLine("Error: " & Choice & " is not a option, Please try again")
Look into Integer.TryParse, it will try and parse the string into a integer if it can, if it can't it wont throw an exception...
Dim b As Integer
Console.WriteLine("Please input the value of, B:")
If Not Integer.TryParse(Console.ReadLine(), b) Then
Console.WriteLine("Value entered must be a number")
GoTo Line98
End If
If it can parse the input from the user, then b would be the value from the parse, otherwise the value of b is still 0...
Edit Per Comment
Dim b As Integer
Do Until b > 0
Console.WriteLine("Please input the value of, B:")
If Not Integer.TryParse(Console.ReadLine(), b) OrElse b <= 0 Then
Console.WriteLine("Value entered must be a number and not equal 0")
GoTo Line98
End If
Loop

For loop for bowling score array

I am trying to create a bowling program that will display the scores given in a multi-line text box. I've manage to get the program giving an output, but when it runs it skips asking for new inputs and just gives 5 0s on seperate lines and nothing else. I'm completely lost, any help is very much appreciated
EDIT: Sorry should have changed errors to reflect the programs changes, it looks like this now. It gives 0's instead of using the value I gave it, but it does ask for each input now.
For gameNumber As Integer = 1 To 5 Step 1
lblEnterScore.Text = "Enter Score for game #" & gameNumber
Dim Testint As Integer ' define an Integer for testing
Try
Testint = CInt(txtScoreInput.Text) ' try to convert whatever they entered to Int
Catch
MessageBox.Show("Entry is not an Integer") ' If you are here then the CInt failed for some reason, send a message
txtScoreInput.SelectAll()
txtScoreInput.Focus()
Exit Sub
End Try
If txtScoreInput.Text.Contains(".") Then
MsgBox("Bowling Score must be a whole number.")
txtScoreInput.SelectAll()
txtScoreInput.Focus()
Exit Sub
End If
If txtScoreInput.Text > MAXIMUM_SCORE Or txtScoreInput.Text < MINIMUM_SCORE Then
MsgBox("Bowling Score must be between 1 and 300.")
txtScoreInput.SelectAll()
txtScoreInput.Focus()
Exit Sub
End If
scoreInput(gameNumber) = CInt(txtScoreInput.Text)
' and store it in the array
' and increment the gamecounter for the next time through the loop
Next
'btnEnterScore.Enabled = False
' place the good score into the multi-line textbox
txtScoreOutputs.Text = gameScore & vbCrLf & txtScoreOutputs.Text
End Sub
If it was me, here's what I would do... Just a suggestion; I also cut out over half of your code and stopped it from throwing exceptions as well... You can put this in a click event or where ever you need it as well. You can modify this as well to take as many as you want from user input as well not just limit them from entering score's. Your user also has the option to get out of that loop when they choose to do so as well, not keeping them inside the loop...
Private ScoreLists As New List(Of Integer) 'Hold your inputted values
Private Const MAXIMUM_SCORE As Integer = 300 'Max score
Private Const MINIMUM_SCORE As Integer = 1 'Min score
Private blnStop As Boolean = False
Try
For gameNumber As Integer = 1 To 5
Dim intScore As Integer = 0
Do Until (intScore >= MINIMUM_SCORE And intScore <= MAXIMUM_SCORE) OrElse blnStop
If Not Integer.TryParse(InputBox("Please enter a score for game # " & gameNumber.ToString), intScore) Then
If MsgBox("Bowling Score must be a whole number. Stop getting scores?.", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
blnStop = True
Exit For
End If
End If
Loop
ScoreLists.Add(intScore)
Next
'Display the results...
For i As Integer = 0 To ScoreLists.Count - 1
txtScoreOutputs.Text &= ScoreLists.Item(i.ToString)
Next
ScoreLists.Clear()
Catch ex As Exception
End Try
Construct your logic like this (pseudo):
Loop
{
AskUserForInput()
ProcessUserInput()
}
The loop part will control how many scores the user is prompted to enter. The AskUserForInput() function will prompt the user to type in a new score, and the ProcessUserInput() function will get the value and store it in an array or print it to the screen, etc.
Your current logic is not waiting for any new user input before trying to add to the scores. You are also getting zeros because you're setting the txtScoreOutputs with gameScore, which doesn't look like it's been set to the user's input.

Check if a string variable has an integer value

I am working on a project which allows kids to send a message to Santa. Unfortunately, if they enter a string instead of an integer in the AGE field, the program crashes and returns Conversion from string "[exampleString]" to type 'Double' is not valid.
Is there any way to check if they have entered an integer or not? This is the code.
If childAge > 0 And childAge < 150 Then
fmSecA2 = "Wow! You are already " & childAge & " years old? You're growing to be a big " & childGender & " now! "
Else
fmSecA2 = "Erm, I couldn't really understand your age. Are you making this up? Ho ho ho!"
End If
Thanks,
Kai :)
A very simple trick is to try parse the string as an Integer. If it succeeds, it is an integer (surprise surprise).
Dim childAgeAsInt As Integer
If Integer.TryParse(childAge, childAgeAsInt) Then
' childAge successfully parsed as Integer
Else
' childAge is not an Integer
End If
Complementing Styxxy's response, if you dont need a result just replace it by vbNull:
If Integer.TryParse(childAge, vbNull) Then
You could perform the following two tests to be reasonably certain that the input you're getting is an integer:
If IsNumeric(childAge) AndAlso (InStr(1, childAge, ".") <> 0) Then
fmSecA2 = "Wow! You are already " & childAge & " years old? You're growing to be a big " & childGender & " now! "
If childAge < 0 OrElse childAge > 150 Then
fmSecA2 = "I don't believe it's possible to be" & childAge & " years old..."
End If
Else
fmSecA2 = "Erm, I couldn't really understand your age. Are you making this up? Ho ho ho!"
The InStr function returns zero if it doesn't find the string that is being looked for, and so when combining that test with IsNumeric, you also rule out the possibility that some floating point data type was entered.
IsNumeric is built into VB, and will return a true/false
If IsNumeric(childAge) AndAlso (childAge > 0 And childAge < 150) Then
fmSecA2 = "Wow! You are already " & childAge & " years old? You're growing to be a big " & childGender & " now! "
Else
fmSecA2 = "Erm, I couldn't really understand your age. Are you making this up? Ho ho ho!"
End If
You can use this.
Sub checkInt()
If IsNumeric(Range("A1")) And Not IsEmpty(Range("A1")) Then
If Round(Range("A1"), 0) / 1 = Range("A1") Then
MsgBox "Integer: " & Range("A1")
Else
MsgBox "Not Integer: " & Range("A1")
End If
Else
MsgBox "Not numeric or empty"
End If
End Sub
Working from Styxxy's answer, if you parse as a byte rather than an integer, then it also checks negative ages and maximum age of 255 all in one go.
Dim childAgeAsByte As Byte
If Byte.TryParse(childAge, childAgeAsByte) Then
' childAge successfully parsed as Byte
Else
' childAge is not a Byte
End If
Kristian
Dim Input
Input = TextBox1.Text
If Input > 0 Then
............................
............................
Else
TextBox2.Text = "Please only enter positive integers"
End If
Try
If TextBox1.Text > 0 Then
Label1.Text = "Integer"
End If
Catch ex As Exception
Label1.Text = "String"
End Try
With this you can put anything in TextBox1, if you put text then you get Label1 is string and if you put number then you get it's integer
In .Net you may use GetType() to determine the data type of a variable.
Dim n1 As Integer = 12
Dim n2 As Integer = 82
Dim n3 As Long = 12
Console.WriteLine("n1 and n2 are the same type: {0}",
Object.ReferenceEquals(n1.GetType(), n2.GetType()))
Console.WriteLine("n1 and n3 are the same type: {0}",
Object.ReferenceEquals(n1.GetType(), n3.GetType()))
' The example displays the following output:
' n1 and n2 are the same type: True
' n1 and n3 are the same type: False
Based on the above sample you can write a code snippet:
If childAge.GetType() = "Integer" then '-- also use childAge.GetType().Name = "Int32"
' do something
End if
Reference MSDN

Only numbers, disallow letters -user input

I am writing a console application which requires user input of certain values. I want to disallow any letter input. The console automatically writes "Conversion from string "b" to type 'Integer' is not valid." but I want the console to display my personal message "Not a valid number, please try again." how can I do that?
I've tried many different keywords and phrases but none work. Maybe I'm doing it wrong (not unlikely) or maybe it's just meant for something else. Either way I need help.
To recap: User input in a console that only allows numbers not letters, and will display my message.
I didn't want to post my code since people always pick on it, but here it is. Please note that there MUST be an exception. It is homework and I NEED an exception and this is one way a user can screw up. Please don't tell me not to use an exception.
Module Module1
Sub Main()
Try
System.Console.WriteLine("Input up to 10 valid numbers to have them mathematically averaged.")
For Index = 0 To 9
Dim Input As IList
Input = Console.ReadLine()
Next Index
If ' here is where I want to add that numbers only Then
Throw New exception("Not a valid number, please try again.")
Else
System.Console.WriteLine("Now averaging numbers...")
Dim average As Double = (n + n + n + n + n + n + n + n + n + n) / 10
Console.WriteLine("The average of " & n & "," & n & "," & n & "," & n & "," & n & "," & n & "," & n & "," & n & "," & n & " and " & n & " is " & average & ".", "Calculation")
End If
Catch e As Exception
System.Console.WriteLine(e.Message)
End Try
End Sub
End Module
Dim inputString = Console.ReadLine
If Integer.TryParse(inputString, num) Then
DoSomething(num)
Else
Console.WriteLine("Not a valid number, please try again.")
End If
Here's one way to do it, honoring your requirements:
Module Module1
Sub Main()
System.Console.WriteLine("Input valid numbers seperated by spaces to have them mathematically averaged.")
Dim inputArray As String() = System.Text.RegularExpressions.Regex.Replace(Console.ReadLine().Trim(), "\s{2,}", " ").Split(New Char() {" "})
Dim values As New ArrayList
Dim sum As Integer
For i As Integer = 0 To inputArray.Length - 1
Try
sum = sum + Integer.Parse(inputArray(i), Globalization.NumberStyles.Integer)
values.Add(inputArray(i))
Catch ex As Exception
Console.WriteLine(String.Format("The value ""{0}"" is not a valid number and will be ignored. ExceptionMessage: {1}", inputArray(i), ex.Message))
End Try
Next
Dim average As Decimal = sum / values.Count
Console.WriteLine(vbCrLf)
Console.WriteLine(String.Format("The average of ""{0}"" is {1}", Join(values.ToArray, ", "), average))
Console.WriteLine(vbCrLf)
Main()
End Sub
End Module
Well for starters, the Try - Catch should be inside the input gathering For loop. As your program is written now, as soon as one wrong value is entered execution jumps to the catch and your program ends! If you try casting your input to an decimal you won't need to throw an exception manually, it will be thrown automatically if your input is not an decimal! Try casting the current console input as a decimal and then add that number to your list.
Dim inputNumber as Decimal = CDec(Console.ReadLine())
Input.Add(inputNumber)
Also n will be the same number every time so how you are doing it won't work (look up the basics of how a list works, how to add elements to a list and how to display list elements)