Tuesday, November 8, 2011

Dynamic Positioning of Overlay

jQuery Tools Overlay can be positioned statically when used out of the box, by setting top and left properties.

The good news is that the configuration can be overwritten in onBeforeLoad event handler. This is how an overlay can be positioned next to its trigger:


jQuery('.overlayTrigger').overlay({
   ...

   onBeforeLoad: function() {
      var overlay = this.getOverlay();
      var trigger = this.getTrigger();
      var overlayConfig = this.getConf();

      //position overlay
      overlayConfig.top = trigger.offset().top 
            - overlay.outerHeight() 
            - jQuery(document).scrollTop();
      overlayConfig.left = trigger.offset().left 
            - overlay.outerWidth() 
            - jQuery(document).scrollLeft();

      //... flip popup over when appropriate
      if (overlayConfig.top < 0)
          overlayConfig.top = trigger.offset().top 
                + trigger.outerHeight() 
                - jQuery(document).scrollTop();
      if (overlayConfig.left < 0)
          overlayConfig.left = trigger.offset().left 
                + trigger.outerWidth() 
                - jQuery(document).scrollLeft();
   }
});

Rendering of HyperLink

I have been using HyperLink control recently and have found its MSDN documentation incomplete.

The HyperLink control can be displayed as text or an image. Use the Text property to specify the text to display for the HyperLink control.

If both the Text and ImageUrl properties are set, the ImageUrl property takes precedence. If the image is unavailable, the text in the Text property is displayed. In browsers that support ToolTip functionality, the Text property also becomes the ToolTip.

I needed to insert some other controls into the child Controls of HyperLink and that is what is not covered in MSDN.

There are actually three mutually exclusive branches in rendering of HyperLink.

  1. If ImageUrl is set, an Image is rendered (Text property possibly used for an alternate text),
  2. children Controls are rendered when available, (there is presumably more to it, but I have not analyzed it further,)
  3. and finally plain Text is output otherwise.

By the way, ILSpy has proved useful in revealing the HyperLink internals.

Tuesday, June 14, 2011

Pex and unit testing

Everyone says that Pex generates unit tests. I am not sure if it holds. Pex knows what does your code do, but it definitely does not know what it should do.


Still I see three situations Pex can be really useful with.


  • It can report you exceptions caused by inputs you have not thought of.

  • When your code coverage is lower than you would expect, you may use Pex to see what paths you have not considered.

  • When you want to refactor a component that is not covered with unit tests, you can use unit tests generated by Pex to ensure you do not break the original functionality.


Wednesday, April 6, 2011

Learning F# with "Pex for fun"

Microsoft Research has published Pex for fun. It is a puzzle game. The only thing you are initially given is a signature of a function and you have to work out the implementation. There is an "Ask Pex!" button that will provide you some hints about how close you are. Wonderful!

There are couple of drawbacks though, such as that sometimes you are not given negative answers (inputs for which your implementation does not provide expected outputs), which is not very helpful. The most ugly thing I have found is how ChallengeFactorial puzzle behaves. Even the most stupid implementation (returning 0) is said to exceed the time-limit, thus effectively preventing you from succeeding.

Nevertheless, I like Pex for fun very much! And I find it especially useful when learning F# as it makes you explore the possibilities of the language.

Saturday, January 15, 2011

Sudoku solver in Prolog

Noticing sudoku almost everywhere, I thought it might be a good excercise to develop a sudoku solver. I spend a bit of time thinking and remembered that it could go easily in Prolog. So I started playing.


Sudoku has simple rules, every row, every column and every marked block contains numbers 1 to 9, each exactly once. Hence my first idea:

sudoku(Plan) :-
get_rows( Plan, Rows), % Plan = Rows,
get_columns( Plan, Columns), % transpose( Plan, Columns),
get_blocks( Plan, Blocks),
% every row, every column, every block is actually permutation of 1..9
maplist( permutation([1,2,3,4,5,6,7,8,9]), Rows),
maplist( permutation([1,2,3,4,5,6,7,8,9]), Columns),
maplist( permutation([1,2,3,4,5,6,7,8,9]), Blocks).


I am afraid the first idea, did not give any answer in reasonable time. I remembered that in large backtracking you need to fail as soon as possible. The second attempt

sudoku(Plan) :-
rows( Plan, []),
% columns are OK thanks to rows predicate
get_blocks( Plan, Blocks),
maplist( permutation([1,2,3,4,5,6,7,8,9]), Blocks).

rows( [], _).
rows( [ActualRow|RowsBelow], RowsAbove) :-
% instantiate free variables in the actual row
permutation( [1,2,3,4,5,6,7,8,9], ActualRow),
% only allow meaningful rows
maplist( constrain_difs( ActualRow), RowsAbove),
rows( RowsBelow, [ActualRow|RowsAbove]).

constrain_difs( [], []).
constrain_difs( [X|Xs], [Y|Ys]) :-
X \= Y,
constrain_difs( Xs, Ys).

had a great improvement. Immediately after the free variables were instantiated in the ActualRow, there was a constraint that the ActualRow had to be different from any RowsAbove on every column. As an effect, any row that would obviously break the sudoku was rejected soon and resulting columns were following the sudoku rules.


The second version responded in few seconds already.


Notes:

  • I have been using SWI-Prolog.

  • While browsing the documentation I discovered another sudoku solver in clpfd library, that limited variables to 1..9 domain and then used clpfd:all_distinct predicate. Elegant and fast.


Updated on 4 Mar 2011: Format of examples updated.














A sudoku example
521379468
46  15 7 
3  68425 
893526147
  6 4 9 3
 4 9 1  6
2   63895
 841 7  2
  5 9 7 4












... and solved
521379468
468215379
379684251
893526147
156748923
742931586
217463895
984157632
635892714