Results 1 to 18 of 18

Thread: New VB'er here (help please!)

  1. #1

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    8

    New VB'er here (help please!)

    Hey guys, I am working on a project for school. We have to re-engineer some code my professor gave us and fix the issues and comment it and such. I think I've gotten a handle on most of it however, it states that "X" has to be a number less than 10. When I run the program and enter a number more than 10 the program still runs so I need a way to limit it at 10, yet whenever I write a new If Then statement I get a stack overflow and infinite looping and it crashes. Can anyone give me any help or advise me how to fix this? I'm going to keep working on it.

    Thanks!

    BTW Here is the Code I am working on

    Code:
    If x <= 1 Then
                Factorial = 1
            Else
                Factorial = x * Factorial(x - 1)
            End If
    
    If x > 10 Then
                Factorial = "Pick a number less than 10" 
            Else
                Factorial = x * Factorial(x - 1)
            End If
    
        End Function

  2. #2
    A SQL Server fool GaryMazzone's Avatar
    Join Date
    Aug 2005
    Location
    Dover,NH
    Posts
    7,493

    Re: New VB'er here (help please!)

    Try like this:
    Code:
    If x <= 1 Then
         Factorial = 1
    ElseIf x>1 ANDALSO x < 10
         Factorial = x * Factorial(x - 1)
    Else
         Factorial = "Pick a number less than 10" 
    End If
    Sometimes the Programmer
    Sometimes the DBA

    Mazz1

  3. #3
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333

    Re: New VB'er here (help please!)

    There is no looping going on with the code you posted. Typically a Stack Overflow will be caused by a recursive loop gone wild....there has to be more to the code that what you have shown.

    But, the thing that really jumps out at me is what are you using the same variable for a number and a string? I guess that means Factorial is declared As Variant, right?

  4. #4

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    8

    Re: New VB'er here (help please!)

    To GarryMazzone I will try that out and write back. Thanks.

  5. #5

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    8

    Re: New VB'er here (help please!)

    Alright, well I have tried that out..and after some declaration problems I have fixed the issue and all seems well now! Thanks GarryMazzone! I had "X" originally declared as Double and that was throwing everything off. Now "X" is declared as Object and can properly display the results and the error message. Thanks!

  6. #6
    A SQL Server fool GaryMazzone's Avatar
    Join Date
    Aug 2005
    Location
    Dover,NH
    Posts
    7,493

    Re: New VB'er here (help please!)

    Why would declare x as an Object. Interger is fine for this. The problem is probably how you get the value of x. It would help to see that.
    Sometimes the Programmer
    Sometimes the DBA

    Mazz1

  7. #7

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    8

    Re: New VB'er here (help please!)

    Ok, I will post the whole code. It's not actually that long I just didn't want to make everything crazy looking if I didn't have to. This is what I have as of right now.

    I declared "X" as Object because I was getting StackOverflow errors with the conversion to the String message (that you helped me with before). This made it work. Is this not a very efficient way to go about things?

    Code:
    Public Class Form1
    
        Private Sub btnFactorial_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFactorial.Click
            
            Dim x As Object
            Dim Fact As Object
    
            lblOutput.Text = "To determine the Factorial of a number. " _
                & "Please enter a number less than 10." _
                & "Then, click on the Factorial Button to view the results."
           
            x = Val(txtInput.Text)
    
            Fact = Factorial(x)
            lblOutput.Text = ("")
            lblOutput.Text = ("       " & x & " is   " & Fact)
    
        End Sub
    
        Private Function Factorial(ByRef x As Double) As Object
    
            If x <= 1 Then
                Factorial = 1
            ElseIf x > 1 AndAlso x < 10 Then
                Factorial = x * Factorial(x - 1)
            Else
                Factorial = "Please pick a number less than 10"
            End If
    
        End Function
    
    End Class

  8. #8
    A SQL Server fool GaryMazzone's Avatar
    Join Date
    Aug 2005
    Location
    Dover,NH
    Posts
    7,493

    Re: New VB'er here (help please!)

    The function should be changed like this:
    Code:
      Private Function Factorial(ByRef x As Integer) As Integer
    
            If x <= 1 Then
                Factorial = 1
            ElseIf x > 1 AndAlso x < 10 Then
                Factorial = x * Factorial(x - 1)
            Else
                Factorial = "Please pick a number less than 10"
            End If
    
        End Function
    The code in the button click should be:
    Code:
    Dim x As Integer       
    Dim Fact As Inetger
    
            lblOutput.Text = "To determine the Factorial of a number. " _
                & "Please enter a number less than 10." _
                & "Then, click on the Factorial Button to view the results."
           
    If NOT Inetger.TryParse(Me.txtInput.Text,x) Then
         MessageBox.Show("Please enter a number from 1 to 10 only")
         Me.txtInput.Focus()
         Exit Sub
    End If
    If x < 10 then 
       MessageBox.Show("Only values less then 10 are allowed here.")
       Me.txtInput.Focus()
       Exit Sub
    End If
            Fact = Factorial(x)
            lblOutput.Text = ("")
            lblOutput.Text = ("       " & x & " is   " & Fact)
    Sometimes the Programmer
    Sometimes the DBA

    Mazz1

  9. #9
    Freelancer akhileshbc's Avatar
    Join Date
    Jun 2008
    Location
    Trivandrum, Kerala, India
    Posts
    7,652

    Re: New VB'er here (help please!)

    Here's a bit cleaned version:
    vb.net Code:
    1. Public Class Form1
    2.  
    3.     Private Sub btnFactorial_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFactorial.Click
    4.  
    5.         Dim x As Integer
    6.         Dim Fact As Integer
    7.  
    8.         '~~~ Check if the we are successful in converting the number entered in textbox to a valid integer. If not, display a message. If successful, "x" would contain the converted Integer value
    9.         If Not Integer.TryParse(txtInput.Text, x) Then
    10.             lblOutput.Text = "To determine the Factorial of a number. " _
    11.             & "Please enter a number less than 10." _
    12.             & "Then, click on the Factorial Button to view the results."
    13.         End If
    14.  
    15.         '~~~ Calculate the factorial of "x" and store it in "Fact"
    16.         Fact = Factorial(x)
    17.  
    18.         '~~~ If the number is not >1 and <10, then the function "Factorial" would return "-1". So, we are checking it here. If so, we'll output a message. Otherwise, display the result of the factorial
    19.         If Fact <> -1 Then
    20.             lblOutput.Text = ("       " & x.ToString & " is   " & Fact.ToString)
    21.         Else
    22.             lblOutput.Text = "Please pick a number less than 10"
    23.         End If
    24.  
    25.     End Sub
    26.  
    27.     Private Function Factorial(ByRef x As Integer) As Integer
    28.  
    29.         '~~~ This is an exit condition for the recursive call.
    30.         If x = 1 Then
    31.             Factorial = 1
    32.         ElseIf x > 1 AndAlso x < 10 Then
    33.             Factorial = x * Factorial(x - 1)
    34.         Else
    35.             Factorial = -1
    36.         End If
    37.  
    38.     End Function
    39. End Class
    Last edited by akhileshbc; Oct 20th, 2011 at 12:39 PM. Reason: oops. I think, I was late :D

    If my post was helpful to you, then express your gratitude using Rate this Post.
    And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video)
    My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet

    Social Group: VBForums - Developers from India


    Skills: PHP, MySQL, jQuery, VB.Net, Photoshop, CodeIgniter, Bootstrap,...

  10. #10
    A SQL Server fool GaryMazzone's Avatar
    Join Date
    Aug 2005
    Location
    Dover,NH
    Posts
    7,493

    Re: New VB'er here (help please!)

    Thanks for the catch on the function. I did it on-line and never tested
    Sometimes the Programmer
    Sometimes the DBA

    Mazz1

  11. #11
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333

    Re: New VB'er here (help please!)

    If you add "Option Strict On" to your project, you will get a number of errors immediately returned with what you have.

    On the other hand, this worked just fine for me
    vb.net Code:
    1. Public Class Form1
    2.     Private Function Factorial(ByRef x As Double) As Double
    3.         Dim strFact As String
    4.         If x <= 1 Then
    5.             Factorial = 1
    6.         ElseIf x > 1 AndAlso x < 10 Then
    7.             Factorial = x * Factorial(x - 1)
    8.         Else
    9.             strFact = "Please pick a number less than 10"
    10.             lblOutput.Text = strFact
    11.         End If
    12.  
    13.     End Function
    14.  
    15.     Private Sub btnFactorial_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFactorial.Click
    16.         Dim x As Double
    17.         Dim Fact As Double
    18.  
    19.         lblOutput.Text = "To determine the Factorial of a number. " _
    20.             & "Please enter a number less than 10." _
    21.             & "Then, click on the Factorial Button to view the results."
    22.  
    23.         x = Val(txtInput.Text)
    24.  
    25.         Fact = Factorial(x)
    26.         lblOutput.Text = ("")
    27.         lblOutput.Text = ("       " & x & " is   " & Fact)
    28.  
    29.     End Sub
    30. End Class

  12. #12

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    8

    Re: New VB'er here (help please!)

    Thanks guys! Will look over and re-edit my stuff. Ya'll rock!

  13. #13
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: New VB'er here (help please!)

    Everyone's Factorial functions are wrong. They would only be correct if the function was named FactorialOfANumberLessThanTen. The check that the input is less than ten does not belong in the Factorial function.

    Verify the input is less than ten, then call Factorial.

    And on the subject of the Factorial function... are you aware that this is a concept called recursion? If you were familiar with it then you wouldn't be surprised that a mistype can end up with a StackOverflow exception. When calling itself, a function must be one step closer to the terminating condition (in this case, when you ask for the factorial of 1).

    Recursive functions are always in danger of getting a stack overflow even when coded correctly, if the initial arguments require too many recursions to solve the problem. To avoid this, you can sometimes make the recursive function a tail-recursive function. This means that the recursive call is the last thing the function does and it immediately returns after making it. In our current factorial example, the function looks like this (having stripped it down to just the factorial calculation):

    vbnet Code:
    1. Public Function Factorial(ByVal x As Integer) As Integer
    2.     If x <= 1
    3.         Factorial = 1
    4.     Else
    5.         Factorial = x * Factorial(x - 1)
    6.     End If
    7. End Function

    This is not tail-recursive. After making the recursive call, the function multiplies the returned value by x before returning. However, consider the following alteration, where we introduce an accumulator:

    vbnet Code:
    1. Public Function Factorial2(x As Integer) As Integer
    2.     Return Factorial2Impl(x, 1)
    3. End Function
    4.  
    5. Private Function Factorial2Impl(x As Integer, accumulator As Integer) As Integer
    6.     If x <= 1
    7.         Factorial2Impl = accumulator
    8.     Else
    9.         Factorial2Impl = Factorial2Impl(x - 1, x * accumulator)
    10.     End If
    11. End Function

    You can see that in this version, the FactorialImpl function returns the result of the recursive call immediately. This version is tail-recursive. The multiplication happens before making that recursive call and the result is passed down in the accumulator.

    Now, why is tail-recursion useful? It would seem that you've got as many recursive calls as the first version. The advantage comes because it is possible to perform optimisation on a tail-recursive function to turn it into an iterative function, thereby not consuming stack frames. This optimisation can be done by a compiler automatically (if it is sufficiently smart - not all compilers will be able to do this, and you normally need to explicitly tell those that can that they should)!

    vbnet Code:
    1. Public Function Factorial3(x As Integer) As Integer
    2.     Return Factorial3Impl(x, 1)
    3. End Function
    4.  
    5. Private Function Factorial3Impl(x As Integer, accumulator As Integer) As Integer
    6.     While x > 1
    7.         accumulator *= x
    8.         x -= 1
    9.     End While
    10.     Factorial3Impl = accumulator
    11. End Function

    And thus, at a stroke, your tail-recursive function is rewritten as an iterative function. Another optimisation that will often be possible is to inline the second function:

    vbnet Code:
    1. Public Function Factorial4(x As Integer) As Integer
    2.     Dim accumulator As Integer = 1
    3.     While x > 1
    4.         accumulator *= x
    5.         x -= 1
    6.     End While
    7.     Factorial4 = accumulator
    8. End Function

  14. #14

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    8

    Re: New VB'er here (help please!)

    Thanks again everyone, just got out of class and this is what my final lab looked like. I appreciate all the help.

    Code:
    Public Class Form1
    
        Private Sub btnFactorial_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFactorial.Click
           
            Dim userinput As Double ' Declares userinput as the Double data type :D
            Dim Fact As Double ' Declares Fact as the Double data type ..... haha
    
            ' This line takes the number that is inside the Textbox and puts it as userinput
            userinput = Val(txtInput.Text)
    
            ' This line changes the direction text and sets it to the results of the calculation of the Factorial function. 
            Fact = Factorial(userinput)
            lblOutput.Text = ("")
            lblOutput.Text = ("       " & userinput & " is   " & Fact)
    
            ' This runs an error check to make sure the user inputed a number between 1 and 10. 
    
            If userinput < 1 Then
                lblOutput.Text = "Please pick a number between 1 and 10."
            ElseIf userinput > 10 Then
                lblOutput.Text = "Please pick a number between 1 and 10."
            End If
    
        End Sub
    
        Private Function Factorial(ByRef userinput As Double) As Double
    
            ' This code is the actual Factorial math. Basically what this does is take the userinput whatever it may be
            ' and starts with that (i.e. 5) and then multiply it by each number down until you reach 1 (i.e. 5*4*3*2*1)
            ' Awesome. 
    
            If userinput <= 1 Then
                Factorial = 1
            Else
                Factorial = userinput * Factorial(userinput - 1)
            End If
    
        End Function
    
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            ' Below is just the text that gives the user instructions on how to operate the program. This is loaded
            ' at startup. 
            lblOutput.Text = "To determine the Factorial of a number. " & Chr(13) _
                & "Please enter a number less than 10." & Chr(13) _
                & "Then, click on the Factorial Button to view the results."
    
        End Sub
    
    End Class

  15. #15
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: New VB'er here (help please!)

    Quote Originally Posted by CrisisV View Post
    Code:
            Dim userinput As Double ' Declares userinput as the Double data type :D
            Dim Fact As Double ' Declares Fact as the Double data type ..... haha
    I'm glad that declaring variables causes you so much pleasure???


  16. #16

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    8

    Re: New VB'er here (help please!)

    my professor told us not to do that since it was actually extremely redundant to comment exactly what the code was doing. I felt like being a smart ass. Haha.

  17. #17
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: New VB'er here (help please!)

    Your professor has a very good point. If you stick with programming, then in about 10 or 20 years time you'll understand why Until then, just follow his advice, ok?

  18. #18

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    8

    Re: New VB'er here (help please!)

    Of course Evil. I just know she appreciates humor as well

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width