lessCode.net
Links
AFFILIATES
Thursday
Aug222013

Bug? Content-Based Correlation in Windows Workflow Foundation

This one caused me quite a bit of grief this week – maybe I can save someone else some pain. When configuring content-based correlation in the Workflow (4.0/4.5) designer, I think there’s a subtle bug in the dialog that allows you to choose the correlation key and XPath expression used to establish correlation on a Receive or SendReply activity.

image

It manifests itself when the workflow engine attempts to apply the correlation query at runtime:

A correlation query yielded an empty result set. Please ensure correlation queries for the endpoint are correctly configured.

 

It only occurs under the following conditions:

  • The message or parameter that contains the correlation is a complex DataContract (i.e. not a primitive value type).
  • That DataContract type is derived from another base class DataContract.
  • The correlation property comes from the base class.
  • The base class DataContract and the derived class DataContract are in different namespaces.

 

Under these conditions, the Add Correlation Initializers dialog sets the namespace of the property as being defined in the namespace of the derived class, not the base class.

Fortunately the fix is easy – you can manually edit the XAML to refer to the namespace of the base class instead, e.g:

<XPathMessageQuery x:Key="key1">
<XPathMessageQuery.Namespaces>
 <ssx:XPathMessageContextMarkup>
    <x:String x:Key="xg0">http://schemas.datacontract.org/2004/07/ClassLibrary2</x:String>
    <x:String x:Key="xgSc">http://tempuri.org/</x:String>
 </ssx:XPathMessageContextMarkup>
</XPathMessageQuery.Namespaces>sm:body()/xgSc:StartResponse/xgSc:StartResult/xg0:Id</XPathMessageQuery>
Monday
Mar252013

Did Verisign revoke their own certificate?

image

Wednesday
Mar132013

Google is shutting down Reader

http://googleblog.blogspot.com/2013/03/a-second-spring-of-cleaning.html

Wait, what? This is Google’s best product, and they’re shit-canning it?

This has to rank up there with Fox’s decision to cancel Firefly

Friday
Feb012013

What’s My Super Bowl Pool Box Worth?

A bit of fun for this Super Bowl weekend. If you’re unfamiliar with a Super Bowl pool, the basics are simple:

Draw a 10 x 10 grid. One axis represents the AFC team, the other represents the NFC team. Participants pay a fixed amount for each of the 100 boxes. A payoff is set for each quarter of the game. Each row of the grid is randomly assigned a digit from 0-9, and likewise for each column of the grid. At the end of each quarter of the game, the final digit of each team’s score is used to determine the winning box for that quarter, and the owner of that box gets the loot.

The interesting question for box owners after the box numbers are assigned is: How much am I likely to win with these numbers? Moreover, if you’d entered the same pool every year since the Super Bowl began (ie. a pool with the same per-quarter payoffs), and happened to get the same numbers every year, how much would you have won in total? Obviously this is a contrived scenario, but an analysis of the history of Super Bowl scores makes for some interesting observations.

The nature of the scoring system in American Football is obviously the biggest factor in determining the “value” of a box: 3 (field goal) & 7 (touchdown + extra point), and their multiples, 6, 9, 4 and 1 seem likely to be winners. Also, the person who owns the 0-0 box stands to potentially win the entire pot before a ball is kicked or thrown, if two lousy offenses can’t score, or if the scoring goes in sets of touchdown, extra point, field goal. But if you think you have good numbers, a safety or a missed extra point are likely to ruin your day.

So, how much is my box worth in the above scenario?

// Per-quarter points scored for every superbowl - AFC,NFC
let quarterPoints = [
    ([ 0;10; 0; 0],[ 7; 7;14; 7]);
    ([ 0; 7; 0; 7],[ 3;13;10; 7]);
    ([ 0; 7; 6; 3],[ 0; 0; 0; 7]);
    ([ 3;13; 7; 0],[ 0; 0; 7; 0]);
    ([ 0; 6; 0;10],[ 3;10; 0; 0]);
    ([ 0; 3; 0; 0],[ 3; 7; 7; 7]);
    ([ 7; 7; 0; 0],[ 0; 0; 0; 7]);
    ([14; 3; 7; 0],[ 0; 0; 0; 7]);
    ([ 0; 2; 7; 7],[ 0; 0; 0; 6]);
    ([ 7; 0; 0;14],[ 7; 3; 0; 7]);
    ([ 0;16; 3;13],[ 0; 0; 7; 7]);
    ([ 0; 0;10; 0],[10; 3; 7; 7]);
    ([ 7;14; 0;14],[ 7; 7; 3;14]);
    ([ 3; 7; 7;14],[ 7; 6; 6; 0]);
    ([14; 0;10; 3],[ 0; 3; 0; 7]);
    ([ 0; 0; 7;14],[ 7;13; 0; 6]);
    ([ 7;10; 0; 0],[ 0;10; 3;14]);
    ([ 7;14;14; 3],[ 0; 3; 6; 0]);
    ([10; 6; 0; 0],[ 7;21;10; 0]);
    ([ 3; 0; 0; 7],[13;10;21; 2]);
    ([10; 0; 0;10],[ 7; 2;17;13]);
    ([10; 0; 0; 0],[ 0;35; 0; 7]);
    ([ 0; 3;10; 3],[ 3; 0; 3;14]);
    ([ 3; 0; 7; 0],[13;14;14;14]);
    ([ 3; 9; 0; 7],[ 3; 7; 7; 3]);
    ([ 0; 0;10;14],[ 0;17;14; 6]);
    ([ 7; 3; 7; 0],[14;14; 3;21]);
    ([ 3;10; 0; 0],[ 6; 0;14;10]);
    ([ 7; 3; 8; 8],[14;14;14; 7]);
    ([ 0; 7; 0;10],[10; 3; 7; 7]);
    ([14; 0; 7; 0],[10;17; 8; 0]);
    ([ 7;10; 7; 7],[ 7; 7; 3; 7]);
    ([ 7;10; 0;17],[ 3; 3; 0;13]);
    ([ 0; 0; 6;10],[ 3; 6; 7; 7]);
    ([ 7; 3;14;10],[ 0; 0; 7; 0]);
    ([ 0;14; 3; 3],[ 3; 0; 0;14]);
    ([ 3; 0; 6;12],[ 3;17;14;14]);
    ([ 0;14; 0;18],[ 0;10; 0;19]);
    ([ 0; 7; 7;10],[ 0; 7; 7; 7]);
    ([ 0; 7; 7; 7],[ 3; 0; 7; 0]);
    ([ 6;10; 6; 7],[14; 0; 3; 0]);
    ([ 0; 7; 0; 7],[ 3; 0; 0;14]);
    ([ 3;14; 3; 7],[ 0; 7; 0;16]);
    ([10; 0; 7; 0],[ 0; 6;10;15]);
    ([ 0;10; 7; 8],[14; 7; 0;10]);
    ([ 9; 0; 6; 6],[ 0;10; 7; 0]); 
    ([ 3; 3;17; 8],[ 7;14; 7; 6]); 
    ([ 8;14;14; 7],[ 0; 0; 8; 0]); 
    ([ 0;14;10; 0],[ 0;14; 0;14]); 
    ([ 0; 7; 0; 3],[10; 3; 3; 8]); 
    ([ 0;21; 7; 0],[ 0; 3; 6;19]); 
    ([ 9;13; 7;12],[ 3; 9;14; 7]); 
    ([ 0; 0; 3; 0],[ 0; 3; 0;10]); 
    ([ 3; 7;10; 0],[ 7; 3; 0;21]); 
    ]
 
// Dollars to win at the end of each quarter
let prizes = [| 50; 125; 75; 250 |]
 
let total points = Seq.scan (+) (List.head points) (List.tail points)
 
let modulo = fun i -> i % 10
let modulos points = Seq.map modulo (total points)
let quarterModulos = Seq.map (fun (afc, nfc) -> modulos afc, modulos nfc) quarterPoints
 
let payoff : int[,] = Array2D.zeroCreate 10 10
 
let payQuarter (afc, nfc, prize) = payoff.[nfc,afc] <- payoff.[nfc,afc] + prize
let payGame (afc, nfc) = Seq.iter payQuarter (Seq.zip3 afc nfc prizes)
 
Seq.iter payGame quarterModulos

for i in 0 .. 9 do 
  for j in 0 .. 9 do
    printf "%5d" payoff.[i,j]
  printf "\n"

This snippet is also runnable at repl.it. The results are interesting:

image

43% of the possible outcomes seem to have never occurred in the Super Bowl.

0 and 7 are indeed big winners, and 7 – 4 is by far the most valuable box. However, its reciprocal 4 – 7 is one of the least valuable of the winning boxes.

Tuesday
Jan292013

Another Simple Way to Tinker with F#

From Microsoft Research – tryfsharp.org, a very cool site for testing and sharing F# code, complete with a built-in JavaScript charting engine. I just posted the Discount Curve sample to try it out.

Can’t figure out how to get the time axis to render dates, though - the DoJo chart needs the data to be numeric, and I don’t see a way to use a label function to do the conversion back to date, although the library itself seems to support it