9 Replies - 4075 Views - Last Post: 02 May 2012 - 04:48 AM Rate Topic: -----

#1 e_i_pi  Icon User is offline

  • = -1
  • member icon

Reputation: 789
  • View blog
  • Posts: 1,676
  • Joined: 30-January 09

Microjerks are at it again

Posted 30 April 2012 - 06:32 PM

Ah my old favourites Microsoft who can't seem to follow a single accepted convention have struck again.

This time I'm writing an expression in VS BI Reporting, and I need to sort records based on actual and potential ratings, which can be NA, 0, 1, 2, 3, 4 or 5. There are four ratings, Safety, Environment, Plant and Outrage. So I figure "Yeah I'll just make a bit string to sort with", like so:
=CInt(Fields!SafetyActCode.Value = "5")
&CInt(Fields!EnvActCode.Value = "5")
&CInt(Fields!PlantActCode.Value = "5")
&CInt(Fields!OutrageActCode.Value = "5")
&CInt(Fields!SafetyActCode.Value = "4")
&CInt(Fields!EnvActCode.Value = "4")
&CInt(Fields!PlantActCode.Value = "4")
&CInt(Fields!OutrageActCode.Value = "4")
&CInt(Fields!SafetyActCode.Value = "3")
&CInt(Fields!EnvActCode.Value = "3")
&CInt(Fields!PlantActCode.Value = "3")
&CInt(Fields!OutrageActCode.Value = "3")
&CInt(Fields!SafetyActCode.Value = "2")
&CInt(Fields!EnvActCode.Value = "2")
&CInt(Fields!PlantActCode.Value = "2")
&CInt(Fields!OutrageActCode.Value = "2")
&CInt(Fields!SafetyActCode.Value = "1")
&CInt(Fields!EnvActCode.Value = "1")
&CInt(Fields!PlantActCode.Value = "1")
&CInt(Fields!OutrageActCode.Value = "1")
&CInt(Fields!SafetyActCode.Value = "0" OR Fields!SafetyActCode.Value = "NA")
&CInt(Fields!EnvActCode.Value = "0" OR Fields!EnvActCode.Value = "NA")
&CInt(Fields!PlantActCode.Value = "0" OR Fields!PlantActCode.Value = "NA")
&CInt(Fields!OutrageActCode.Value = "0" OR Fields!OutrageActCode.Value = "NA")


The expected output for something that has Safety 5, Env 3, Plant NA and Outrage 2 would be:
1000000001000001000000000010

Sounds right doesn't it? Convert a boolean value to an int, it converts true to 1 and false to 0. Concatenate all those ints as strings, and you get a nice sortable bit valued string.

Except here we are in the land of Microsoft, where down is up and up is down. So the actual string I get back is this:
-100000000-100000-10000000000-10
...resulting in me changing my code to this:
=(-CInt(Fields!SafetyActCode.Value = "5"))
&(-CInt(Fields!EnvActCode.Value = "5"))
&(-CInt(Fields!PlantActCode.Value = "5"))
&(-CInt(Fields!OutrageActCode.Value = "5"))
&(-CInt(Fields!SafetyActCode.Value = "4"))
&(-CInt(Fields!EnvActCode.Value = "4"))
&(-CInt(Fields!PlantActCode.Value = "4"))
&(-CInt(Fields!OutrageActCode.Value = "4"))
&(-CInt(Fields!SafetyActCode.Value = "3"))
&(-CInt(Fields!EnvActCode.Value = "3"))
&(-CInt(Fields!PlantActCode.Value = "3"))
&(-CInt(Fields!OutrageActCode.Value = "3"))
&(-CInt(Fields!SafetyActCode.Value = "2"))
&(-CInt(Fields!EnvActCode.Value = "2"))
&(-CInt(Fields!PlantActCode.Value = "2"))
&(-CInt(Fields!OutrageActCode.Value = "2"))
&(-CInt(Fields!SafetyActCode.Value = "1"))
&(-CInt(Fields!EnvActCode.Value = "1"))
&(-CInt(Fields!PlantActCode.Value = "1"))
&(-CInt(Fields!OutrageActCode.Value = "1"))
&(-CInt(Fields!SafetyActCode.Value = "0" OR Fields!SafetyActCode.Value = "NA"))
&(-CInt(Fields!EnvActCode.Value = "0" OR Fields!EnvActCode.Value = "NA"))
&(-CInt(Fields!PlantActCode.Value = "0" OR Fields!PlantActCode.Value = "NA"))
&(-CInt(Fields!OutrageActCode.Value = "0" OR Fields!OutrageActCode.Value = "NA"))



Thanks Microsoft, you really do chomp down the fat one.

Is This A Good Question/Topic? 0
  • +

Replies To: Microjerks are at it again

#2 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2241
  • View blog
  • Posts: 9,416
  • Joined: 29-May 08

Re: Microjerks are at it again

Posted 01 May 2012 - 03:03 AM

The problem was your assumption that following values of True and False.
False = 0
True  = 1



In Boolean Logical the following must be true.
False = Not True
True  = Not False


Where a Not, represents is just inverting all the bits to the Negated version.
 False -> True
  True -> False


So if we use your values for True and False of 1 and 0, then the following happens

0 = Not (1) => 0 = -2 (Wrong)
1 = Not (0) => 1 = -1 (Wrong)



I think all languages False -> 0, and True -> * != 0 .

Most languages base there representation of a Boolean Value on the langauges implementation of a signed Integer, which in vb is Type Integer.

 0 = Not(-1) =>  0 =  0 (Correct)
-1 = Not( 0) => -1 = -1 (Correct)






What I have to say about your cryptic solution.
-CInt(Fields!SafetyActCode.Value = "5")
&CInt(Fields!EnvActCode.Value = "5")



There a of Casting both Explicit and Implicit casting Boolean -> Integer -> Integer -> String and lot of noise. Making it hard and error-prone (since you're hoping the ordering of the operators in what you intended).

To make it much easier to read and understand,create some method.
I create a couple of dedicated Extension Methods.

First converting a Boolean into a 0 or 1.
 
Imports System.Runtime.CompilerServices
Public Module BooleanExts
  <Extension()> Public Function To0_1(b As Boolean) As Integer
    Return If(b, 1, 0)
  End Function
  <Extension()>


Using this approach makes,
Spoiler


And when you want a create a Bit String Representation of a collection of Boolean.
  Public Function ToBitString(Booleans As IEnumerable(Of Boolean)) As String
    Dim BitRepresentation As New Text.StringBuilder(Booleans.Count + 1)
    For Each b In Booleans
      BitRepresentation.Append(b.To0_1.ToString)
    Next
    Return BitRepresentation.ToString
  End Function
End Module



Makes the following rewrite's intent, I think, much clearer.
Spoiler


Remember source-code is for Humans to read not Computers.
Was This Post Helpful? 2
  • +
  • -

#3 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5780
  • View blog
  • Posts: 12,596
  • Joined: 16-October 07

Re: Microjerks are at it again

Posted 01 May 2012 - 04:41 AM

Hmm... looks like Access. Ick.

Why convert when you can just be explicit?
IFF(Fields!SafetyActCode.Value = "5","1","0")



I agree with AdamSpeight2008. I have actually seen -1 for a boolean false. But, really, all you need is an agreement of what is false ( or true ) and what isn't for boolean logic to be happy. You can do the 0/1 shuffle in some languages, like C, when that is explicit behavior. However, such behavior can never really be assumed.
Was This Post Helpful? 2
  • +
  • -

#4 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2241
  • View blog
  • Posts: 9,416
  • Joined: 29-May 08

Re: Microjerks are at it again

Posted 01 May 2012 - 04:52 AM

baavgai The function based approach is better to maintain, less error prone.

If we used the extension method, I provide above.
(Fields!SafetyActCode.Value = "5").To0_1


or used called like a standard method.
To0_1( Fields!SafetyActCode.Value = "5" )


Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5780
  • View blog
  • Posts: 12,596
  • Joined: 16-October 07

Re: Microjerks are at it again

Posted 01 May 2012 - 05:49 AM

View PostAdamSpeight2008, on 01 May 2012 - 06:52 AM, said:

baavgai The function based approach is better to maintain, less error prone.


I agree. I don't know enough of the guts of the system in question to offer that style of code. Just, without knowing much, I would have gone with some kind of case to get the explicit value I wanted rather than assume implicit correctness.

If I did do a stand alone function, I'd let the value be passed, too.
Public Function To0_1(f As Field, s As String) As Integer
    Return If((f.Value = s), 1, 0)
End Function



So:
To0_1(Fields!SafetyActCode,"5")


Was This Post Helpful? 0
  • +
  • -

#6 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2241
  • View blog
  • Posts: 9,416
  • Joined: 29-May 08

Re: Microjerks are at it again

Posted 01 May 2012 - 05:58 AM

The ! is the Dictionary Lookup Operator.

This post has been edited by AdamSpeight2008: 01 May 2012 - 05:59 AM

Was This Post Helpful? 0
  • +
  • -

#7 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5780
  • View blog
  • Posts: 12,596
  • Joined: 16-October 07

Re: Microjerks are at it again

Posted 01 May 2012 - 06:17 AM

Fine: f("Value")?

I have mentioned that there ain't enough beer in the world to make VB syntax pretty? ;)
Was This Post Helpful? 0
  • +
  • -

#8 e_i_pi  Icon User is offline

  • = -1
  • member icon

Reputation: 789
  • View blog
  • Posts: 1,676
  • Joined: 30-January 09

Re: Microjerks are at it again

Posted 01 May 2012 - 11:14 PM

Groan I just lost a massive reply I made due to a 503 error. Thankfully, I can sum it up pretty easily...

View PostAdamSpeight2008, on 01 May 2012 - 09:03 PM, said:

0 = Not (1) => 0 = -2 (Wrong)
1 = Not (0) => 1 = -1 (Wrong)



...

 0 = Not(-1) =>  0 =  0 (Correct)
-1 = Not( 0) => -1 = -1 (Correct)


WTF

I should have taken waaaaaaay more drugs during Logic 101. I don't see how those two pairs of statements make any sense whatsoever. This looks suspiciously like gypsy magic.
Was This Post Helpful? 0
  • +
  • -

#9 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2241
  • View blog
  • Posts: 9,416
  • Joined: 29-May 08

Re: Microjerks are at it again

Posted 02 May 2012 - 01:28 AM

Let says we're on a 32bit platform, that represents integer numbers using the 2-Compliment representation.

And the Operation NOT is flip each bit of the number to it's compliment.

Integer  In Binary
    1    00000000 00000000 00000000 00000001 (Your value for True)
   -2    11111111 11111111 11111111 11111110 NOT  

    0    00000000 00000000 00000000 00000000 
   -1    11111111 11111111 11111111 11111111 NOT



The True wtf is why you didn't consult the documentation or check your assumations hold's true first with a little bit of code.
Console.WriteLine("False:= {0}",CInt(False))
Console.WriteLine(" True:= {0}",CInt(True))


Was This Post Helpful? 2
  • +
  • -

#10 e_i_pi  Icon User is offline

  • = -1
  • member icon

Reputation: 789
  • View blog
  • Posts: 1,676
  • Joined: 30-January 09

Re: Microjerks are at it again

Posted 02 May 2012 - 04:48 AM

Okay that makes more sense. Still I hate Microsoft and everything it stands for :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1