[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

vb.net code help

Posted on 2011-04-28
29
Medium Priority
?
486 Views
Last Modified: 2013-11-27
I am working on a class project, it's an on-line class so instructor help is hard to come by.  I'm not looking for the answer, just a nudge in the right direction.
The project is to create a Prime Number application using For...Next statements and the mod operator.  We are supposed to be able to enter any 2 numbers and the program should display all primes between.  Below is my code so far, do you guys see anything obvious? The error codes work well already. I've got about 8 weeks of experience, so don't laugh too hard!

    Private Sub CalcButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CalcButton.Click

        Dim upper As Integer
        Dim lower As Integer
        Dim squareRoot As Integer

        'Declare variables
        lower = Val(LowerTextBox.Text)
        upper = Val(UpperTextBox.Text)
        squareRoot = Math.Sqrt(UpperTextBox.Text)

        ' Display error messages for invalid bounds
        If lower < 2 OrElse upper < 2 Then
            MessageBox.Show("Bounds must be greater than 1", _
            "Invalid Bounds", MessageBoxButtons.OK, _
            MessageBoxIcon.Error)
        Else
            If lower > Val(upper) Then
                MessageBox.Show("Upper bound cannot be less than lower bound", _
                "Invalid Bounds", MessageBoxButtons.OK, _
                MessageBoxIcon.Error)
            End If
        End If

        For counter As Integer = lower To upper
            For counter2 As Integer = lower To squareRoot
                'Call Prime function
                If Prime(counter, counter2) = True Then ResultsTextBox.AppendText(counter)
            Next
            ResultsTextBox.AppendText(vbCrLf)
        Next
    End Sub

    'Prime function
    Function Prime(ByVal counter As Integer, ByVal counter2 As Integer) As Boolean

        If counter2 Mod counter = 0 Then
            Return True
        Else : Return False
        End If

    End Function
0
Comment
Question by:NotAsSmartAsYou
  • 17
  • 12
29 Comments
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35486320
It ~looks~ like you're attempting to use the Sieve of Eratosthenes?...
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

You need to start with a list of numbers and then eliminate those in the list that are multiples of the previous ones (since they cannot be primes).  I think your instructor wants you to use the Mod() function to determine if one number is a multiple of another.  When done with all the eliminations, the numbers left in the list are prime!
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35486460
That makes alot of sense.  So list all integers in the range, then test each item in that list (that doesn't have a multiple already in the list) to see if it's prime. If it is, append that item to the textbox.  Do I understand what you are saying?
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35486553
You're not really testing each number to see if its prime...

What we're doing is testing each number to see if its a multiple of a previous number (thus eliminating it as a prime).

I think you'll need to start your list out with 2 (even though the entered lower bound might be higher) all go the way to your upper bound.  This is because the values in your range could be multiples of numbers lower than your range.  Once you know a value is actually a prime you just check to see if it is >= lower and <= upper.

Hint: Change the number of your function from Prime() to IsMultiple().  That should help you understand what to do with it!
0
NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

 

Author Comment

by:NotAsSmartAsYou
ID: 35486563
Isn't that kind of what my code is doing?  Here's what I thought was happening, and maybe that's why it's wrong... The first for...next "counter" is going through integers one at a time and doing the mod calculation for each item in the 2nd for...next (counter2). If the mod=0 then return false, otherwise return true (this is backwards in above code but has since been fixed.) If prime = true, then append the integer in the textbox.  
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35486564
*The algorithm section in the Wiki article should be of great help...try to translate that into code.

Do you know how to build a list of the numbers?
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35486571
Sorry, posted at the same time.  I'll try it and get back.. Thanks!
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35486615
Think about this True statement:

    6 Mod 2 = 0

Is 6 Prime?
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35486623
I do not know how to buoild a list of numbers.  I would guess it would be something like
list as integer 2 to upper ???
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35486656
I think I corrected already.  The code in my initial post was backwards.  I switched around true an false. It now says the following...

 If counter2 Mod counter = 0 Then
            Return False
        Else : Return True
        End If

0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35486657
See List(): http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx

Something like:
Dim numbers As New List(Of Integer)
For n As Integer = 2 To upper
    numbers.Add(n)
Next n

Open in new window

0
 

Author Comment

by:NotAsSmartAsYou
ID: 35486701
Need to run and get the kids, I'll work on it shortly.  Thanks!
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35487226
How do I access the list of numbers? numbers.each? Is this supposed to all be in the click event still or under the Prime function?
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35487298
Private Sub CalcButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CalcButton.Click

      Dim upper As Integer
      Dim lower As Integer
      Dim squareRoot As Integer
      Dim numbers As New List(Of Integer)

      For n As Integer = 2 To upper
         numbers.Add(n)
      Next n
      For counter As Integer = lower To upper
         If Prime(numbers.Count, counter) = True Then ResultsTextBox.AppendText(counter)
         ResultsTextBox.AppendText(vbCrLf)
      Next counter
    End Sub

    'Prime function
    Function Prime(ByVal numbers.count As Integer, ByVal counter As Integer) As Boolean

      If numbers.count Mod counter = 0 Then      '(Can I use the list in the function here?)
         Return False
      Else : Return True
      End If

   End Function
   End Class
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35487704
You access the List "by index" with 0 (zero) as the first slot.

For example:

    For i As Integer = 0 To numbers.Count -1
        Debug.Print(i & ": " & numbers(i)) ' <-- outputs to the "Immediate Window" in the IDE
    Next

You can remove an item at a specific Index using the RemoveAt() method:
http://msdn.microsoft.com/en-us/library/5cw9x18z(VS.80).aspx

    numbers.RemoveAt(5) ' <--- removes the sixth element (remember it's zero based)
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35488723
How's the project coming along?...
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35490491
It's due sunday and I had some things going on last night, but back to work today!  I'm a little concerned that I am supposed to complete it using stuff I've already learned, but I don't think he can fault me for completing the project another way.
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35490803
Are you referring to the List(of Integer)?

Have you learned Arrays yet?
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35490856
No lists or arrays. Here are my requirements...

-Implement an appropriate loop to iterate from the lower to upper bound numbers
-Define a function procedure named Prime that returns True if a number is prime, False otherwise.
-Call the Prime function from the button click event procedure
-Send the number to the function as a by-value parameter
-Use an appropriate loop within the function to test whether the number is prime.
-Use an appropriate calculation and/or comparison to determine Prime. You must use the Mod operator.
-If the number is prime, display it in a multiline scrollable TextBox.

-Suggested Method: You can count from 2 to the square root of the number. Use the Mod operator to determine whether the number is divisible by the counter variable’s value (that is, the remainder is 0). If so, the number is NOT prime.
-Notice that you don't need to count all the way to your test number.
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35491006
So, here's where I stand.  I'm trying to get back  to the instructions and I have the following code which displays a list of integers between 2 and the squareroot of the upper bound number.  Not too bad, but definitely not right.  Anyone have any idea where the math or logic is terribly wrong?  Idle, you've been a tremendous help so far.

       Private Sub CalcButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CalcButton.Click

        Dim upper As Integer
        Dim lower As Integer
        Dim squareRoot As Integer

        'Declare variables
        lower = Val(LowerTextBox.Text)
        upper = Val(UpperTextBox.Text)
        squareRoot = Math.Sqrt(UpperTextBox.Text)

        ' Display error messages for invalid bounds
        If lower < 2 OrElse upper < 2 Then
            MessageBox.Show("Bounds must be greater than 1", _
            "Invalid Bounds", MessageBoxButtons.OK, _
            MessageBoxIcon.Error)
        Else
            If lower > Val(upper) Then
                MessageBox.Show("Upper bound cannot be less than lower bound", _
                "Invalid Bounds", MessageBoxButtons.OK, _
                MessageBoxIcon.Error)
            End If
        End If

        'create counter for
        For c As Integer = 2 To squareRoot
            If Prime(c, upper, lower) = True Then ResultsTextBox.AppendText(c)
            ResultsTextBox.AppendText(vbCrLf)
        Next c
    End Sub

    'Prime function
    Function Prime(ByVal c As Integer, ByVal lower As Integer, ByVal upper As Integer) As Boolean

        For i As Integer = lower To upper
            Prime = False
            If c Mod i = 0 Then
                Return False
            Else : Return True
            End If
        Next i

    End Function
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35491030
Ok...got it.

Then your Prime() function should receive just ONE value "PrimeCandidate" (the one being tested).  INSIDE that Prime() function you'll loop from 2 to the Square Root of "PrimeCandidate".  If "PrimeCandidate" Mod {Loop Variable}  = 0 then it's NOT Prime (Return False immediately).  If you make it all the way thru the loop and exit the For...Next block, then you can Return True as the number IS a Prime (we didn't find any factors).

In the Button Click event you can simply loop from lower to upper and call Prime() for each one.
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35491137
I think this code looks solid, but it returns a list of every other number from lower to upper.

16 - 50
17
19
21
23
25 etc... to
49

Anyways, here's the code...

        'create counter for
        For c As Integer = lower To upper
            If Prime(c, squareRoot) = True Then ResultsTextBox.AppendText(c) Else GoTo here
            ResultsTextBox.AppendText(vbCrLf)
here:
        Next c

    End Sub

    'Prime function
    Function Prime(ByVal c As Integer, ByVal squareRoot As Integer) As Boolean

        For i As Integer = 2 To squareRoot
            If c Mod i = 0 Then
                Return False
            Else : Return True
            End If
        Next i

    End Function
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35491183
In your Prime() function, you need to Return True AFTER you pass the "Next i" line.
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35491499
It is almost working! One last issue though. The first number in the output is contingent on the val of upper.  For example, if the range is 2-500, the first prime listed is 23.

2-700 it's 29
2-50 it's 11
400-500 it's 401
2-10000 it's 101
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35491514
Here's the code for the issue listed above...

        'create counter for
        For c As Integer = lower To upper
            If Prime(c, squareRoot) = True Then ResultsTextBox.AppendText(c) Else GoTo here
            ResultsTextBox.AppendText(vbCrLf)
here:
        Next c

    End Sub

    'Prime function
    Function Prime(ByVal c As Integer, ByVal squareRoot As Integer) As Boolean

        For i As Integer = 2 To squareRoot
            If c Mod i = 0 Then
                Return False
            End If
        Next i
        Return True

    End Function
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35492117
Reread my comments here:
http://www.experts-exchange.com/Microsoft/Development/Visual_Studio_Express/Q_26983708.html#35491030

and also this from your requirements:

    -Suggested Method: You can count from 2 to the square root of the number. Use the Mod operator to determine whether the number is divisible by the counter variable’s value (that is, the remainder is 0). If so, the number is NOT prime.
    -Notice that you don't need to count all the way to your test number.

So you need to calculate the "squareroot" value INSIDE Prime() for the value of "c" that was passed in.

I would change your signature of Prime from:

    Function Prime(ByVal c As Integer, ByVal squareRoot As Integer) As Boolean

To:

    Function Prime(ByVal c As Integer) As Boolean

Now declare "squareRoot" inside Prime() and calculate it based on "c" before you enter the For...Next loop.
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35492443
I think I've don what you suggested, but the results are exactly the same, Did I incorporate what you mentioned correctly?

    Private Sub CalcButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CalcButton.Click

        Dim upper As Integer
        Dim lower As Integer

        'Declare variables
        lower = Val(LowerTextBox.Text)
        upper = Val(UpperTextBox.Text)

        ' Display error messages for invalid bounds
        If lower < 2 OrElse upper < 2 Then
            MessageBox.Show("Bounds must be greater than 1", _
            "Invalid Bounds", MessageBoxButtons.OK, _
            MessageBoxIcon.Error)
        Else
            If lower > Val(upper) Then
                MessageBox.Show("Upper bound cannot be less than lower bound", _
                "Invalid Bounds", MessageBoxButtons.OK, _
                MessageBoxIcon.Error)
            End If
        End If

        'create counter for prime number candidates
        For c As Integer = lower To upper
            If Prime(c) = True Then ResultsTextBox.AppendText(c) Else GoTo here
            ResultsTextBox.AppendText(vbCrLf)
here:
        Next c

    End Sub

    'Prime function
    Function Prime(ByVal c As Integer) As Boolean

        'declare variable
        Dim squareRoot As Integer

        'assign value to variable
        squareRoot = Math.Sqrt(Val(UpperTextBox.Text))

        'create counter for factor candidates
        For i As Integer = 2 To squareRoot
            If c Mod i = 0 Then
                Return False
            End If
        Next i
        Return True

    End Function
0
 

Author Comment

by:NotAsSmartAsYou
ID: 35492451
nevermind... saw that it is not calculated before for... next!  Hang on.
0
 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 2000 total points
ID: 35492543
Close...you need the square root of "c"...not upper.

Change:

    squareRoot = Math.Sqrt(Val(UpperTextBox.Text))

To:

    squareRoot = Math.Sqrt(c)

Also, every time someone uses a "Goto" statement, a coder somewhere on the planet goes into convulsions, foams at the mouth, and DIES.  =\

Change:

        For c As Integer = lower To upper
            If Prime(c) = True Then ResultsTextBox.AppendText(c) Else GoTo here
            ResultsTextBox.AppendText(vbCrLf)
here:
        Next c

To:

        For c As Integer = lower To upper
            If Prime(c) = True Then
                ResultsTextBox.AppendText(c.ToString() & vbCrLf)
            End If
        Next c
0
 

Author Closing Comment

by:NotAsSmartAsYou
ID: 35493050
Fantastic! So helpful! Ever consider teaching this stuff?
0

Featured Post

Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes how to programmatically preset the "Pages per Sheet" option that's available with most printer drivers.   This setting lets you do "n-Up" printing, where two, four, or more pages are printed on each sheet of paper. If your …
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question