I'm a beginner in vb and I'm wondering why this code doesn't work.
I wrote the function which I can't seem to find why it doesn't. When I run the program, it seems to print out nothing.
I am supposed to find all the prime numbers between 1 and the input
Option Strict On
Public Class Lab4
Dim endCounter As Integer
Dim sum As Integer
Dim msg As String
Dim input As Integer
Public Function isPrime(input As Integer) As Boolean
endCounter = input - 1
For primeCounter As Integer = 1 To endCounter
If input Mod primeCounter <> 0 Then
Return True
Else
Return False
End If
Next
Return False
End Function
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub
Private Sub btnPrime_Click(sender As Object, e As EventArgs) Handles btnPrime.Click
input = Convert.ToInt32(txtNumber.Text)
msg = "The prime numbers are: "
If input < 0 Then
msg = "Number cannot be negative!"
For inputCounter As Integer = 1 To input
If isPrime(inputCounter) = True Then
msg += inputCounter & " "
End If
Next
MsgBox(msg, , "Prime Number")
End Sub
End If
End Class
This test will always immediately return something on the very first test:
Public Function isPrime(input As Integer) As Boolean
endCounter = input - 1
For primeCounter As Integer = 1 To endCounter
If input Mod primeCounter <> 0 Then
Return True
Else
Return False
End If
Next
Return False
End Function
because you use Return immediately after the 'has modulus' line. Remove the Return True and else lines, so it only returns False if a modulus value is found. The very last line should be Return True – no modulus values are found, so it is a prime.
For this to work, you need to change your test to
If input Mod primeCounter == 0 Then
and change the start test from 1 to 2.
You don't need to test against 1, and you don't need to test all the way up to input or (you probably misunderstood something there) input - 1. The most logical endpoint is ceil(sqrt(input)), the next higher number of the square root of your starting value.
Related
Module PrimePairs
Public Function IsPrime(n As Long) As Boolean
Console.WriteLine("Please enter the value: ")
n = Console.ReadLine()
n = Math.Abs(n) ' Allows to consider negative prime numbers
If n < 2 Then ' Disallows -1, 0, 1
Return False
End If
Dim i As Long
i = 2
While i < n ' Note that for n = 2 we don't enter the loop and thus return True.
If n Mod i = 0 Then
Return False
End If
i += 1
End While
Return True
End Function
Public Function PrimePairs(ByVal n As Long, ByVal n2 As Long) As Integer
Dim count As Integer = 0
Console.ReadLine()
If n Mod 2 = 0 Then
For i = 1 To (n / 2) + 1
n2 = n - i
If IsPrime(i) And IsPrime(n2) = True Then
count += 1
End If
Next
Else
n2 = n - 2
If IsPrime(n2) = True Then
count = +1
End If
End If
Console.WriteLine("The result is:", count)
Return n
End Function
End Module
I want my code to calculate how many prime number twins can write the input I gave.
The problem is that your project actually does not contain a Sub Main(), as the error states.
You defined two functions in the Module Program, but console applications need a predefined entry point, which usually is the Main method.
The compiler is telling you that your project is not valid because it didn't find any entry point.
Just add a Sub Main() to get your project working, then call your functions from that method.
Example:
Option Strict On
Module Program
Sub Main(args As String())
Console.WriteLine("Please enter the value: ")
Dim input As String = Console.ReadLine()
Dim number As Long
If Long.TryParse(input, number) Then // More about this function in the answer below
Dim prime As Boolean = IsPrime(number)
If prime Then
Console.WriteLine(number & " is prime.")
Else
Console.WriteLine(number & " is not prime.")
End If
End If
Console.ReadLine()
End Sub
Function IsPrime(n As Long) As Boolean
n = Math.Abs(n) ' Allows to consider negative prime numbers
If n < 2 Then ' Disallows -1, 0, 1
Return False
End If
Dim i As Long = 2
i = 2
While i < n ' Note that for n = 2 we don't enter the loop and thus return True.
If n Mod i = 0 Then
Return False
End If
i += 1
End While
Return True
End Function
End Module
Also, I suggest you to enable Option Strict On as I added at the beginning of file. This prevents the compiler from doing implicit casts and forces you to explicitly declare your variables.
E.g., your line of code
n = Console.ReadLine()
is not valid with Option Strict On, because n is supposed to be a long, but Console.ReadLine() returns a string.
If you are a beginner, this will allow you to better understand how programming works and will help you to avoid errors - take good habits from the beginning, you can thank me later ;)
That's why I changed your code withLong.TryParse(input, number): this function returns true if provided input can be cast (=converted) to a long, and assigns the casted value to number variable.
There's a lot more I'd like to suggest you, but I would go off-topic.
I have done extensive research on using recursion in VB.NET (I am using 2015) in order complete a homework assignment. In my desperation, I even asked my professor for help!
I am trying to write a program that will calculate 1! through 12!, and post the results in a list box. The method I am using is based on the following example (sent to me by my prof):
var integer n, result
n = 0
For 1 to 12 do
n = n + 1
write (n, ‘! equals ‘, Fact(n)
End For
Function Fact (ByVal n as Integer)
if (n = 0) then Fact = 1
else Fact = n * Fact (n-1)
End If
End Function
http://www.softwareandfinance.com/VB/Factorial_Recursion.html
My issue is with my call statement for the function (I named it Factorial). Here is the section of the code where I am getting the error message:
For intN = 1 To 12
intFact = Factorial()
lstFactorialsAnswers.Items.Add(intN & "! = " & intFact)
Next
Thank you for your insights.
In response, I removed the "Dim Factorial as Int64" declaration. I also added "intN" as a parameter in the function call. The new error message is "Argument not specified for parameter 'intFact' of 'Public Function Factorial(intN As Integer, intFact As Integer) As Long'.
Here is the revised code:
Public Class frmFactorialMath
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim intN As Integer
Dim intFact As Integer
intN = Convert.ToInt32(txtN)
For intN = 1 To 12
If intN = 1 Then
lstFactorialsAnswers.Items.Add(intN & "! = " & 1)
Else
intFact = Factorial(intN)
lstFactorialsAnswers.Items.Add(intN & "! = " & intFact)
End If
Next
End Sub
Function Factorial(ByVal intN As Integer, intFact As Integer) As Long
If (intN = 0) Then
Return 1
Else
intFact = intN * Factorial(intN - 1)
Return intFact
End If
End Function
Here is the solution to the issue(s) I was having:
Option Strict On
Public Class frmFactorialMath
' This event handler calculates the factorials for numbers 1 through 12.
' A list showing the answers is compiled and displayed.
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim intN, intFact As Integer
For intN = 1 To 12
intFact = Factorial(intN)
lstFactorialsAnswers.Items.Add(intN.ToString() & "! = " & intFact.ToString())
Next
End Sub
' This Function performs the calculations using recursion.
Function Factorial(ByVal intFact As Integer) As Integer
If intFact = 1 Then
Return 1
Else
' This "Do While" loop ends the recursion, eliminating an infinite loop.
Do While intFact > 1
Return intFact * Factorial(intFact - 1)
Loop
End If
End Function
What is wrong with this perfect number function?
The method is supposed to decide whether the input number is/is not a perfect number. The answer is supposed to be all the perfect numbers from 1 to the input.
For example: 1 - 100 the answer would be 6 and 28
Public Function isPerfect(myInput As Integer) As Boolean
endCounter = myInput \ 2
sum = 1
For perfectCounter As Integer = 2 To endCounter
If myInput Mod perfectCounter = 0 Then
sum += perfectCounter
If sum = myInput Then
Return True
End If
End If
Next
Return False
End Function
Private Sub btnPerfect_Click(sender As Object, e As EventArgs) Handles btnPerfect.Click
input = Convert.ToInt32(txtNumber.Text)
msg = "The perfect numbers between 1 and " & input & " are : "
For inputCounter As Integer = 0 To input
If isPerfect(inputCounter) = True Then
msg += inputCounter & " "
End If
Next
MsgBox(msg, , "Perfect Number")
txtNumber.Focus()
txtNumber.Text = Nothing
End Sub
You have at least a couple of problems:
You are validating the perfect number inside the loop, before you've even finished summing the divisors.
For instance...
If sum = myInput Then
Return True
End If
The above should be checked after the loop.
More importantly, because you are setting endCounter to myInput \ 2, you are not summing all the divisors. Maybe you did this as an optimization. But if so, you forgot something along the way.
A quick fix is to change the endCounter assignment to:
endCounter = myInput - 1
Also, to avoid getting back 1 as a valid perfect number, I would initialize sum to 0, and would start the loop normally at 1 instead of 2.
So your function could look something like:
Public Function isPerfect(myInput As Integer) As Boolean
Dim endCounter As Integer = myInput - 1
Dim sum As Integer = 0
For perfectCounter As Integer = 1 To endCounter
If myInput Mod perfectCounter = 0 Then
sum += perfectCounter
End If
Next
Return sum = myInput
End Function
I'm sure you could optimize this further if you want to.
(*) Consider turning on Option Explicit as well.
Here is the correct implementation of isPerfect:
Public Function isPerfect(myInput As Integer) As Boolean
dim Sum as Integer = 1
For i as Integer = 2 To myInput / 2
If myInput Mod i = 0 Then Sum = Sum + i
Next
Return Sum = myInput
End Function
I keep getting a error and because of this my code wont work. The error is "Function 'DisplayArray' doesn't return a value on all code paths. A null reference exception could occur at run time when the result is used". I can't get rid of this error. I'm new to programming, can anyone help?
Private Function DisplayArray() As String
Dim j As Integer = 0
ReDim Preserve Array(UpperSub)
Dim AddNum As Double = 0.0
txtAddNum.Focus()
If Double.TryParse(txtAddNum.Text, AddNum) Then
If AddNum > 100 Then
MessageBox.Show("Number must be below 100")
ElseIf AddNum < 0 Then
MessageBox.Show("Number must be above 0")
Else
Array(UpperSub) = CDec(AddNum)
UpperSub = UpperSub + 1
End If
Else
MessageBox.Show("Value has to be a number")
End If
txtAddNum.Clear()
txtDisplay.Clear()
For j = 0 To UpperSub - 1
txtDisplay.Text = txtDisplay.Text _
& CStr(Array(j)) & ControlChars.NewLine
Next
txtNumberOfScores.Text = CStr(UpperSub)
End Function
A Function is designed to return a result, using the Return keyword. Your Function does not have a Return statement. Since none of the possible code paths (determined by branching on the If statements as well as the flow from beginning to end) return a value, you're getting this part of the error message: "Function 'DisplayArray' doesn't return a value on all code paths."
The second part of the error message means that if you tried to assign the return value of the Function to a variable, like this:
Dim result As String = DisplayArray()
You'd get a null value, as nothing is returned from the function.
The simplest solution is to change from a Function to a Sub. Subs in VB.NET do not return a value. So change
Private Function DisplayArray() As String
To
Private Sub DisplayArray()
And
End Function
To
End Sub
Note that the As String() in the Function declaration says this method will return a value that is a String, and the Sub has no return value (again, because it doesn't return a value).
To make this a Function that returns a value, you'll have to return at least one value from the method. Here's an example:
Private Function DisplayArray() As String
Dim j As Integer = 0
ReDim Preserve Array(UpperSub)
Dim AddNum As Double = 0.0
txtAddNum.Focus()
If Double.TryParse(txtAddNum.Text, AddNum) Then
If AddNum > 100 Then
MessageBox.Show("Number must be below 100")
Return String.Empty
ElseIf AddNum < 0 Then
MessageBox.Show("Number must be above 0")
Return String.Empty
Else
Array(UpperSub) = CDec(AddNum)
UpperSub = UpperSub + 1
txtAddNum.Clear()
txtDisplay.Clear()
For j = 0 To UpperSub - 1
txtDisplay.Text = txtDisplay.Text _
& CStr(Array(j)) & ControlChars.NewLine
Next
Return CStr(UpperSub)
End If
Else
MessageBox.Show("Value has to be a number")
Return String.Empty
End If
End Function
Essentially, if the validation fails, an empty string is returned. If the validation passes, the rest of the code is executed and the string value of UpperSub is returned.
You could then assign it to the TextBox like this:
txtNumberOfScores.Text = DisplayArray()
The above is a simple example based on your posted code, intended to show you how to return values from a Function. Adjust it to fit your needs (or use a Sub instead). Given that you want to update the display of the txtDisplay with the array and txtNumberOfScores as well you should do fine with a Sub.
Private Sub btntambah_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btntambah.Click
Dim n As Integer
For n = 0 To lv1.Items.Count - 1
If lv1.Items(n).Text = txtkdbrng.Text Then
MsgBox("Data Buku Sudah Ada Dalam List")
Exit Sub
End If
Next
lv1.Items.Add(txtkdbrng.Text)
lv1.Items(n).SubItems.Add(txtnmbrng.Text)
lv1.Items(n).SubItems.Add(txtharga.Text)
lv1.Items(n).SubItems.Add(txtjmlhhrg.Text)
lv1.Items(n).SubItems.Add(txttotal.Text)
lv1.Items(n).SubItems.Add(txtjmlpsn.Text)
lv1.Items(n).SubItems.Add(txtspesifikasi.Text)
txttotal.Text = Format(CDbl(Total()), "###, ###, ###")
ClearBarang()
txtkdbrng.Focus()
End Sub
Function Total() As Double
Dim ttl As Double = 0
If Not Double.TryParse(txttotal.Text, Total) Then
Total = 0
End If
End Function
Private Sub btncetak_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btncetak.Click
If txtnosph.Text = "" Or lv1.Items.Count = 0 Then
MsgBox("Data Belum Lengkap", MsgBoxStyle.Information, "INFORMASI")
Else
Dim nilaikembali1, nilaikembali2 As Integer
objsph.PNoSph = txtnosph.Text
objsph.PTglSph = Format(dtpsph.Value, "yyy-MM-dd")
objsph.PKdCs = txtkdcstmr.Text
nilaikembali1 = objsph.Simpan()
'menyimpan ke tabel Ada menggunakan perulangan
For x As Integer = 0 To lv1.Items.Count - 1
objada.PNoSph = txtnosph.Text
objada.PKdBrg = lv1.Items(x).SubItems(1).Text
objada.PKdBrg = CDbl(lv1.Items(x).SubItems(2).Text)
objada.PKdBrg = CDbl(lv1.Items(x).SubItems(3).Text)
nilaikembali2 = objada.Simpan()
Dim objbarang As New ClsBarang
objbarang.PKdBrg = lv1.Items(x).SubItems(0).Text
Next
If nilaikembali1 = 1 And nilaikembali2 = 1 Then
MsgBox("Data Berhasil Disimpan", MsgBoxStyle.Information, "INFORMASI")
End If
ClearForm()
ClearBarang()
ClearCustomer()
txtnosph.Text = objsph.AutoNumber
End If
End Sub
The problem is with this code:
Function Total() As Double
Dim ttl As Double = 0
If Not Double.TryParse(txttotal.Text, Total) Then
Total = 0
End If
End Function
First off you are using the less well known VB6 style implicit return variable that matches the name of the function, instead use the declared Double in your code named ttl and return the value, like this:
Function Total() As Double
Dim ttl As Double = 0
If Double.TryParse(txttotal.Text, ttl) Then
Return ttl
Else
' Attempted conversion of text to Double type failed
' Do something here, raise error, alert user, etc.
' Returning zero may or may not be acceptable, if it is return zero
Return 0
End If
End Function
Using the Return syntax produces much clearer code, in that it does not assume the reader of your code knows the implicit variable that matches the name of the function concept. Always use Return in a Function.
Note: If a total value of zero is not indicative of a problem, then you will need to alter your function to return Nullable(Of Double) instead of just Double and then you can alter the Else portion of the TryParse() result to this:
Function Total() As Nullable(Of Double)
Dim ttl As Double = 0
If Double.TryParse(txttotal.Text, ttl) Then
Return ttl
Else
' Attempted conversion of text to Double type failed
' So return null
Return Nothing
End If
End Function
Now the caller of your Total function will need to account for Nothing being returned and react accordingly.
This means the variable being explicitly or implicitly casted/converted to double is actually an empty string and cannot be proceed.