Results 1 to 6 of 6

Thread: [RESOLVED] Method for conversion, can it be improved?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    May 2002
    Posts
    1,602

    Resolved [RESOLVED] Method for conversion, can it be improved?

    Hey!

    We have a situation where we are using data from a service that is from a non normalized database. In this particular case we are trying to create information to a graph component on what axis to draw and what units. One axix can be displayed with two different units (us and SI) This information is stored in the database as an integer where 1 = SI, 2=US and 12 or 21 is both. Unit is an enum with SI, US or BothSIAndUS

    This small method is what we have dreamt up so far

    Code:
    Private Function GetUnitFromInteger(unitsforAxis As Integer) As Unit
            Dim ints = unitsforAxis.ToString.ToArray().Distinct()
            
            If ints.Count = 2 Then
                Return Unit.BothSIAndUS
            ElseIf ints.Count = 1 Then
                If ints.First() = "1" Then
                    Return Unit.SI
                ElseIf ints.First() = "2" Then
                    Return Unit.US
                Else
                    Throw New NotImplementedException("There is no support for unit: " & ints.First())
                End If
            Else
                Throw New Exception("The integer can either be 1, 2 or 12, or 21")
            End If
        End Function
    The code feels kind of crappy. Is there a better more clean way to parse information of this kind? The code does work but ther are lots of Ifs and magic numbers.

    We have 10 more kinds of similar data where many settings have been cramped into a single integer or string that needs to be splitted into proper objects. We try to do this as close to the db as possible to avoid lots of string parsing in our services or viewmodels.

    this is a really old database, and for now we only support 1, 2, 12, 21, everything else is supposed to throw an exception and the users have to fix it manually.

    /H

  2. #2
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Method for conversion, can it be improved?

    Assuming that 'Unit' is an Enum defined something like that shown below:
    Code:
    Enum Unit
       Undefined = 0
       SI = 1
       US = 2
       BothSIAndUS = 21
    End Enum
    
    Private Function GetUnitFromInteger(unitsforAxis As Integer) As Unit
       Dim ret As Unit = Unit.Undefined
       If [Enum].IsDefined(GetType(Unit), unitsforAxis) Then
          ret = CType(unitsforAxis, Unit)
       End If
       Return ret
    End Function

  3. #3
    Super Moderator FunkyDexter's Avatar
    Join Date
    Apr 2005
    Location
    An obscure body in the SK system. The inhabitants call it Earth
    Posts
    7,957

    Re: Method for conversion, can it be improved?

    1 = SI, 2=US and 12 or 21 is both
    Are you in a position to change the way those values are stored in the DB. If so a more usual way of handling situations where more than one flag can be true is to use bitwise operations.

    So SI = 1, US = 2. If you had a third state you'd assign it to 4, a fourth state would be 8 and so on.

    If you think what that looks like in binary you get:-
    SI = 0001
    US = 0010
    3rd state = 0100
    4th state = 1000

    This is handy because you can now store any combination of flags, so SI and US = 0011 (or 3). US and 4th state = 1010 (or 10).

    In the client you can store those integer value as an enum:-
    Code:
    Enum UnitType
      SI = 1
      US = 2
      3rdState = 4
      4thState = 8
    end Enum
    ...which will make mapping the client to the database much simpler.

    Finally you can now use ANDs and ORs on the value to add or remove flags and to check whether a particular flag is set (not in a position to check this in VB.Net but this works in C# so the syntax will be similar):-
    Code:
    //set a single a flag on
    MyState |= UnitType.US
    
    //Set a couple of flags on
    MyState |= Unittype.SI | UnitType.US
    
    //Check if a given flag is on
    bool UseSIOnAxis = (MyState & UnitType.SI ==  UnitType.SI )
    
    //Set a flag off
    Mystate &= ~UnitType.SI  //~ is the negative of a bit string - not sure what that looks like in VB.
    The best argument against democracy is a five minute conversation with the average voter - Winston Churchill

    Hadoop actually sounds more like the way they greet each other in Yorkshire - Inferrd

  4. #4
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Method for conversion, can it be improved?

    Code:
        <Flags> _
        Enum Unit As Integer
            Undefined = 0
            SI = 1 << 1
            US = 1 << 2
            BothSIAndUS = Unit.SI Or Unit.US
        End Enum
    
        Private Sub UnitDecode(aUnit As Unit)
            If aUnit = Unit.BothSIAndUS Then
            ElseIf aUnit = Unit.SI Then
            ElseIf aUnit = Unit.US Then
            End If
        End Sub
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  5. #5

    Thread Starter
    Frenzied Member
    Join Date
    May 2002
    Posts
    1,602

    Re: Method for conversion, can it be improved?

    Thanks for your suggestions. Yes one idea is definetly to use binaries in the database, but it is a legacy db from the 80's that has been moved intoa sql server, and lots of other systems depend on it, so for now we need to do some kind of conversion.

    Always great to learn how to write smarter code!

    Thanks!

    /H

  6. #6
    Frenzied Member
    Join Date
    May 2014
    Location
    Central Europe
    Posts
    1,388

    Re: [RESOLVED] Method for conversion, can it be improved?

    although i would go with funky's suggestion and update the database field and combine this with dbasnett's enum i do not see anything wrong with a straight forward code if you want to leave the db untouched. you say you only have 1, 2, 12 and 21 right?
    Code:
        Private Function GetUnitFromInteger(unitsforAxis As Integer) As Unit
            Select Case unitsforAxis
                Case 1
                    Return Unit.SI
                Case 2
                    Return Unit.US
                Case 12, 21
                    Return unit.BothSIAndUS
                Case Else
                    Throw New ArgumentException("The integer can either be 1, 2 or 12, or 21")
            End Select
        End Function
    how did you come to cast the int to a string, split it into chars aso?


    edit: ahh.. i think i now know. you are also dealing with values like 12112 right? hmm...
    Last edited by digitalShaman; Apr 23rd, 2015 at 03:00 PM.

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