Link to home
Start Free TrialLog in
Avatar of gilkesy
gilkesy

asked on

More "classy" questions

My functions and classes are increasing in complexity and I'm not sure how to tackle certain problems.

I have a form with 1 drop down list (called "Group Type") and 4 text boxes where people can enter the number of travellers for each age group.

Now I need to validate these text boxes in certain ways. For example I need to check that if a certain group type is chosen (for example "Couple") then there has be at least 2 adults specified in the text boxes.

I have created a function to validate all this:

    Public Shared Function ValidTravellers(ByVal intAdult As Integer, ByVal intDependent As Integer, ByVal strGroupType As String, ByRef messageOut As String) As Boolean

        Dim IsValid As Boolean = True
        Dim intAll As Integer = (intAdult + intDependent)
        If intAll = 0 Then
            messageOut = "Please state how many people of each age group are travelling"
            IsValid = False
        Else
            If strGroupType = "1" Then ' Group Type is Individual
                If intAll > 1 Then
                    messageOut = "You have chosen cover for a single person but have requested cover for more than 1 person"
                    IsValid = False
                End If
            ElseIf strGroupType = "2" Then ' Group Type is Couple
                If intAdult <> 2 Then
                    messageOut = "You have chosen couple cover but have not requested cover for 2 adults. The definition of couple is ""insured and partner living at the same address""."
                    IsValid = False
                ElseIf intDependent <> 0 Then
                    messageOut = "You have chosen couple cover but have requested cover for children. If you require cover for children then please select the Family policy."
                    IsValid = False
                End If
            ElseIf strGroupType = "3" Then ' Group Type is Family
                If intAdult <> 2 Then
                    messageOut = "You have chosen family cover but have not requested cover for 2 adults. The definition of family is 2 adults and 4 dependant children."
                    IsValid = False
                ElseIf intDependent > 4 Then
                    messageOut = "You have chosen family cover but have requested cover for more than 4 children. The definition of family is 2 adults and 4 dependant children."
                    IsValid = False
                ElseIf intDependent = 0 Then
                    messageOut = "You have chosen family cover but have requested cover for 0 children. The definition of family is 2 adults and 4 dependant children."
                    IsValid = False
                End If
            ElseIf strGroupType = "4" Then ' Group Type is Single Parent Family
                If intAdult <> 1 Then
                    messageOut = "You have chosen single parent family cover but have not requested cover 1 adult. The definition of single parent family is 1 adult and up to 4 dependant children"
                    IsValid = False
                ElseIf intDependent > 4 Then
                    messageOut = "You have chosen single parent family cover but have requested cover for more than 4 children. The definition of family is 2 adults and 4 dependant children"
                    IsValid = False
                ElseIf intDependent = 0 Then
                    messageOut = "You have chosen single parent family cover but have requested cover for 0 children. The definition of family is 2 adults and up to 4 dependant children"
                    IsValid = False
                End If
            End If
        End If

        Return IsValid

    End Function


I have to pass to this function the quantities of adults ("intAdult") and dependents ("intDependent").

To get these quantities I have to add together the contents of the textboxes, so I use the following 2 functions to do this:

    Public Shared Function CountAdult(ByVal intUnder65 As Integer, ByVal intUnder70 As Integer, ByVal intUnder75 As Integer, ByVal intUnder81 As Integer, ByVal intUnder90 As Integer) As Integer

        Return (intUnder65 + intUnder70 + intUnder75 + intUnder81 + intUnder90)

    End Function

    Public Shared Function CountDependent(ByVal intUnder18 As Integer, ByVal intUnder3 As Integer, ByVal intStudent As Integer) As Integer

        Return (intUnder18 + intUnder3 + intStudent)

    End Function

These 2 functions just add together the numbers specified in the text boxes.

However, if a text box is left empty then the code falls apart becuase the function needs a number for each variable.

So perhaps I need another function that checks whether the text box has a value and if it doesn't then assign it the quantity of 0. i.e.

If txtUnder65.Text = "" Then intUnder65 = 0

But then I'm kind of piling function on top of function and things are becoming increasing (and perhaps needlessly) complex.

I hope someone can understand this and point me towards the path of simplicity and enlightenment.

Regards
Stephen
Avatar of monkey3
monkey3

You can use
     Integer.Parse(txtUnder65.Text)

if you are allowing a user to input text, it would be worth handling properly, because we all know what users are like

e.g.
        Dim n As Integer = 0
        Try
            n = Integer.Parse(txtUnder65.Text)
        Catch ex As Exception
        End Try


try these code samples out...

        Dim str As String
        Dim n As Integer

        Try
            str = "sss"
            n = Integer.Parse(str)
            MessageBox.Show("string '" & str & "' as number " & n.ToString())
        Catch ex As Exception
            MessageBox.Show("number '" & str & "' was entered in an incorrect format")
        End Try

        Try
            str = ""
            n = Integer.Parse(str)
            MessageBox.Show("string '" & str & "' as number " & n.ToString())
        Catch ex As Exception
            MessageBox.Show("number '" & str & "' was entered in an incorrect format")
        End Try

        Try
            str = "123"
            n = Integer.Parse(str)
            MessageBox.Show("string '" & str & "' as number " & n.ToString())
        Catch ex As Exception
            MessageBox.Show("number '" & str & "' was entered in an incorrect format")
        End Try

good luck,
m3
Avatar of gilkesy

ASKER

Thanks for your mail.

Am I right in think that I can't use the class "MessageBox" as it is not available to asp.net.
MessageBox is not available in ASP.NET
Plus, you should not have UI elements like MessageBox in your code especially if it is for ASP.NET. There are better ways at logging things.
you are right...can't use messageBoxes in asp.net.  i think that lables or so make a decent substitute given the limitations of asp.net.

but as far as your original problem....have you thought about creating a class library and incorporating it into your asp.net app?  I think that way way...it provides a cleaner seperation of your presentation and business logic.

For example, in your class library, you create 4 different classes.  the first class called Couple.

public class Couples
{
  bool isValid = false;
   //constructor
   public Couples
   {  

   }

   //properties that take the input of your textboxes
   public int PickYourPropertyName
  {
     get
     {
      }
     set
     {
          if (value == 0)
             isValid = false;
     }
  }

public bool IsValid()
{
   if isValid == true
     return true;
   else
     return false;
}

do the same for single, family etc.

and then in your client code (asp.net) you create an instance based on the ddl.

pseudo code:

if ddl.selectedIndex = 0  //couple was selected
//create an instance of your couple class
yourNameSpace.Couple myCouple = new yourNameSpace.Couple()
myCouple.FirstValue = 1;
myCouple.SecondValue = 2;

If myCouple.IsValid == true
//do your thing

code is defn. not complete...but I hope you get the idea of encapsulating all your business logic into your individual classes.  should the complexity increase...it will only increase for only that given category (couple, famlity, singele ect)



yes, that's correct.
sorry for the confusion, i just wrote the code in a windows app as an example of how the code works.

but you can use the try ... catch for your purposes.

you could do something like

Public Shared Function CountDependent() As Integer
        Dim n As Integer = 0
        Try
            n = Integer.Parse(txtUnder18.Text)
        Catch ex As Exception
                'badly formatted number - ignore it
        End Try

        Try
            n += Integer.Parse(txtUnder3.Text)
        Catch ex As Exception
                'badly formatted number - ignore it
        End Try

        Try
            n += Integer.Parse(txtStudent.Text)
        Catch ex As Exception
                'badly formatted number - ignore it
        End Try

        Return n
End Function

i would say that is no real benefit of passing the parsed integers to a separate method to add them together, as you will make no savings by doing so.
if you write it as i have here (assuming that this method has access to the text boxes) then you only have to do 1 bit of processing in the calling function to get the result,
i.e.
        'get the total number of dependants
        Dim nDeps as Integer = CountDependent ()

rather than
        'parse the text boxes
        Dim nUnder18 as Integer = 0
        Dim nUnder3 as Integer = 0
        Dim nStudent as Integer = 0
        ...
        'parsing code removed for brevity
        ...
        Dim nDeps as Integer = CountDependent (nUnder18, nUnder3, nStudent)

m3
Avatar of gilkesy

ASKER

How do I let the function (residing in a class file) have access to the text boxes in the form.
ASKER CERTIFIED SOLUTION
Avatar of b1xml2
b1xml2
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
typo
===
Return (message.Length = 0)
next,

      Public Shared Function CountItems(ByVal ParamArray values() As String) As Integer
            Dim value As Double = 0
            Dim result As Double
            For Each value As String In values
                  If Double.TryParse(text, Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, result) Then
                        value += result
                  End If
            Next
            
            Return CInt(value)
      End Function
hmm (slight typo)
============
      Public Shared Function CountItems(ByVal ParamArray values() As String) As Integer
            Dim value As Double = 0
            Dim result As Double
            For Each value As String In values
                  If Double.TryParse(value, Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, result) Then
                        value += result
                  End If
            Next
            
            Return CInt(value)
      End Function

and you just call it like so

Dim adult As Integer = CountItems(txtUnder65.Text,txtUnder55.Text,txtUnder45.Text)
Dim dependant As Integer = CountItems(txtUnder18.Text,txtUnder3.Text)
Avatar of gilkesy

ASKER

Thanks for such a detailed reply. Its all beginning to look too complicated for me but I guess this is the only way to learn.

One thing I notice though is that you have 3 functions sharing the same name "IsValidTravellers". Shouldn't different functions have different names?
well i would actually be tempted to parse the text in your page and pass the resulting integers to a class to do the validation (as below)
or you could pass each of the age group strings to the class for it to do the parsing

Public Class Cover
    Private m_nAdults As Integer
    Private m_nDependants As Integer

    Public Sub New(ByVal nAdults As Integer, ByVal nDependants As Integer)
        m_nAdults = nAdults
        m_nDependants = nDependants
    End Sub

    Public Function IsValidAsSingle(ByRef strMessage As String) As Boolean
        Dim bIsValid As Boolean = True  'assume valid
        If (m_nAdults + m_nDependants) > 1 Then
            strMessage = "You have chosen cover for a single person but have requested cover for more than 1 person"
            bIsValid = False
        End If
        Return bIsValid
    End Function

    Public Function IsValidAsCouple(ByRef strMessage As String) As Boolean
        Dim bIsValid As Boolean = True  'assume valid

        If m_nAdults <> 2 Then
            strMessage = "You have chosen couple cover but have not requested cover for 2 adults. The definition of couple is ""insured and partner living at the same address""."
            bIsValid = False
        ElseIf m_nDependants <> 0 Then
            strMessage = "You have chosen couple cover but have requested cover for children. If you require cover for children then please select the Family policy."
            bIsValid = False
        End If

        Return bIsValid
    End Function

    Public Function IsValidAsFamily(ByRef strMessage As String) As Boolean
        Dim bIsValid As Boolean = True  'assume valid

        If m_nAdults <> 2 Then
            strMessage = "You have chosen family cover but have not requested cover for 2 adults. The definition of family is 2 adults and 4 dependant children."
            bIsValid = False
        ElseIf m_nDependants > 4 Then
            strMessage = "You have chosen family cover but have requested cover for more than 4 children. The definition of family is 2 adults and 4 dependant children."
            bIsValid = False
        ElseIf m_nDependants = 0 Then
            strMessage = "You have chosen family cover but have requested cover for 0 children. The definition of family is 2 adults and 4 dependant children."
            bIsValid = False
        End If

        Return bIsValid
    End Function

    Public Function IsValidAsSingleParentFamily(ByRef strMessage As String) As Boolean
        Dim bIsValid As Boolean = True  'assume valid

        If m_nAdults <> 1 Then
            strMessage = "You have chosen single parent family cover but have not requested cover 1 adult. The definition of single parent family is 1 adult and up to 4 dependant children"
            bIsValid = False
        ElseIf m_nDependants > 4 Then
            strMessage = "You have chosen single parent family cover but have requested cover for more than 4 children. The definition of family is 2 adults and 4 dependant children"
            bIsValid = False
        ElseIf m_nDependants = 0 Then
            strMessage = "You have chosen single parent family cover but have requested cover for 0 children. The definition of family is 2 adults and up to 4 dependant children"
            bIsValid = False
        End If

        Return bIsValid
    End Function

End Class

m3
gilkesy, read the comments to decide which one to call. We have method overloading in VB.NET
Avatar of gilkesy

ASKER

What does "method overloading" mean?
method overloading means that you can have more than one method with the same name on the condition that the method signatures do not match. A method signature is the arguments and the type

Public Sub DoMyMethod(ByVal name As String, ByVal number As Integer)
  'do stuff
End Sub

Public Sub DoMyMethod(ByVal name As String)
  DoMyMethod(name,0)
End Sub

which can be condensed in VB.NET to

Public Sub DoMyMethod(ByVal name As String, Optional ByVal number As Integer = 0)

End Sub

However, where the args do not really match in any way, overloading is pretty important

as in
Public Sub DoMyMethod(ByVal value As Integer)

End Sub

Public Sub DoMyMethod(ByVal value As Guid)

End Sub
Avatar of gilkesy

ASKER

Hi b1xml2

I've been going though your suggestion and I sort of think I understand what is going on. However there is a problem with "CountItems" function:

    Public Shared Function CountItems(ByVal ParamArray values() As String) As Integer
        Dim value As Double = 0
        Dim result As Double
        For Each value As String In values
            If Double.TryParse(value, Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, result) Then
                value += result
            End If
        Next

        Return CInt(value)
    End Function

I'm getting an error message that says:

"Variable 'value' hides a variable in an enclosing block"


Im passing the values to the function like this:

        Dim adult As Integer = ValidationProcess.CountItems(txtUnder65.Text, txtUnder70.Text, txtUnder75.Text, txtUnder81.Text, txtUnder90.Text)
        Dim dependent As Integer = ValidationProcess.CountItems(txtUnder18.Text, txtUnder3.Text, txtStudent.Text)
that is because you have defined value twice...

Dim value As Double = 0 'first definition
...
       For Each value As String In values 'second definition

try naming them differently,
e.g.
dim dValue as Double = 0 'd denotes a double
...
       For Each strValue As String In values 'str denotes a string

m3
Avatar of gilkesy

ASKER

Is there a problem in that:

The variable "value" is being assigned the value 0 (zero)

Then in a loop were assigning each value of the array to the variable "strValue".

But...

We are then adding together the contents of the "value" variable so were always going to get 0 (zero)
Avatar of gilkesy

ASKER

Its OK, I've realised the problem. This works OK:

    Function CountItems(ByVal ParamArray values() As String) As Integer
        Dim value As Double = 0
        Dim result As Double
        For Each strValue As String In values
            If Double.TryParse(strValue, Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, result) Then
                value += result
            End If
        Next
        Return CInt(value)
    End Function
Avatar of gilkesy

ASKER

Also, one last thing:

The third function "IsValidTravellers" returns this:

Return (message.Length > 0)

However, this doesnt seem to work. When I changed the above to this it work:

        Dim blnIsValid As Boolean = True

        If (message.Length > 0) Then
            blnIsValid = False
        End If

        Return blnIsValid

But I would have thought that just having "Return (message.Length > 0)" would return either true or false As the function returns a boolean value.

yep, that is what i said in comment Date: 05/19/2005 10:55AM GMT
sorry gilkesy, that was in reference to your comment Date: 05/19/2005 11:46AM GMT

m3 :)
ack!!!
Public Shared Function CountItems(ByVal ParamArray values() As String) As Integer
        Dim number As Double = 0
        Dim result As Double
        For Each value As String In values
            If Double.TryParse(value, Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, result) Then
                number += result
            End If
        Next

        Return CInt(number)
    End Function