Monday, April 16, 2007

Fiddling with Eclipse (Day 14) : bashing the documentation

Well finally I've witnessed the traffic of my blog dwindling from 50 to 0 (and mysteriously rising back to 5) this week.  I guess the trick that uses the 102 class to generate traffic is not a long term strategy.  A long time strategy would involve me blogging daily which I still find pretty difficult...

What have I been doing between my last entry and now is a full throttle in the thesis project.  I slacked during this weekend but in general I have been working pretty hard and I aim to have most of the tool finished by May 1!  Sounds too ambitious?  Well if I don't finish the tool by then I'm totally doomed (doomed = not able to work at the new place!... not exactly apocalyptic yet).

My secret ambition though, however, is to blog about my project during this time.  I have been wanting to do it since Apr 1, but it got delayed since I was too lazy to do it.  But I guess by 1) not cooking my dinner (and not my lunch and perhaps even breakfast, 2) by not watching Youtube or my feed at www.live.com or the NHL playoff it's indeed a feasible goal!

So... ready for my Eclipse blasphemy?

The Eclipse IDE, although sponsored by the Eclipse Foundation (IBM in disguise) and provides one of the best support among all the open source projects, sucks in documentation!

An Eclipse expert may say, "What is this guy talking about?  Can you go to help.eclipse.org to find out everything you need to know!"

This is 50% true...until you reach the internal API.  Then, unfortunately, you're on your own...

One of the objectives of the project is to reuse and expand the Eclipse refactoring API.  In particular, I was very interested in the Extract Method Refactoring.  However, Extract Method Refactoring is part of the internal API.  No documentation... so I have to resort to my F3 strategy.

Normally, F3 strategy works quite well because the associated is documented and you can also peel away the most-often-vague javadoc comments by looking at the source itself!

However, the internal API does not provide you with that luxury!  Most horribly, the code itself has NO documentation!  Which makes me wonder: did the Eclipse team purposely stripe away the comments (cuz it's also impossible to work collaboratively without comments and eclipse is not a one-man show), or... the developers just don't comment the code?  But it's the I-B-M that we are talking about, not a 2 people SourceForge project!

I remembered spending the first 5-6 days in the end of March just peeling away the internal refactoring API.  And days were waste because 1) reading code is not fun and make you sleepy 2) I constantly get distracted by the intricacy (I didn't use the ConcernMapper :'( )  Those were the days when I coded nothing and felt a total despair.

It was only when I found a refactoring tutorial of Eclipse that I grasped a glimpse of hope.  Mind you, the refactoring code described is NOTHING like what it is in the actual eclipse code.  Not only is it a stripped down version but the code structure is completely different!  Luckily, this article, which was published on February 5, 2007, gave me enough of a headstart to bootstrap myself (which also implies that had I started earlier it would take me much longer to generate this info...).  But those folks at UT, and UCS must have a real hard time.

Eclipse Hint #1:

Well here is a problem that took me around 2 hours to get around.

I was trying to highlight some text inside a SourceViewer.  One natural way is to use TextPresentation object to store the change and apply to the SourceViewer:

SourceViewer.changeTextPresentation(TextPresentation)

The trick is... I need to highlight some of the text in red, then inside this chunk of text, a subset will then be encode in blue.

So my trick was...

TextPresentation t = new TextPresentation();
for ( ... a selected group of text ...)
   t.addStyleRange(...red font...);
sourceViewer.changeTextPresentation(t);
// then
t = new TextPresentation(); // recreate t again 
for ( ... a subset which overlap the original text ...)
   t.addStyleRange(...green font...);
sourceViewer.changeTextPresentation(t); 

This strategy, although looks innocent, didn't work out, because some texts that were supposedly highlighted in red appear in black.  However, if I comment out the second part, then the highlight goes back to normal.

The interest thing is, the texts that were highlighted in red but appeared in black, did not overlap with the texts that were highlighted in green.

I played around with this code for 2 hours trying to peel/debug the problem is but since the code doesn't crash (it just doesn't 'appear' nice for me) I had a hard time solving the bug.

In the end, I found out that it's not wise to call changeTextPresentation() twice.. it's essentially redrawing the source viewer twice... so I only called changeTextPresentation()  once instead when I put all the changes into the TextPresentation object.  Since that TextPresentation crashes if you add overlapping changes to it, I used replaceStyleRange() instead of addStyleRange()..

Then... everything... just....works...

Morale: Make the code works first and think about optimizing it later.  I avoided using replaceStyleRange() because it's multitudes more complex than addStyleRange().  But once I used it, it saved me a whole night of work!

More to come: how-to-code-a-function: side-effect???

Wednesday, April 04, 2007

Brain Teaser: Solve This Math Word Puzzle

I came across this piece of puzzle today and then I decided to abandon my project and write a solution for it:

Each letter stands for a 1-digit number. No two letters may stand for the same number. Find a value for each letter from the following set: 0, 1, 4, 5, 6, 7, 8, 9.


'' ASK

+ GAVE

-------

' USED

The answer can be found here.

The concept is simple but the code is more verbose than what I thought... here is my python solution. Can anyone achieve one that is less verbose?



def permutation(num_list):

if (len(num_list) == 1 or len(num_list) == 0):
return [num_list];
permutation_list = [];

for i in range(len(num_list)):
list_copy = num_list * 1 # deep copy
item = list_copy.pop(i)
one_less_perm_list = permutation(list_copy)
for j in range(len(one_less_perm_list)):
permutation_list.append([item]+ one_less_perm_list[j])
return permutation_list


def solve_puzzle():

combination = permutation([0, 1, 4, 5, 6, 7, 8, 9])
var_list = ['A', 'S', 'K', 'G', 'V', 'E', 'D', 'U']

for i in range(len(combination)):
assignment = combination[i]
set_of_answer = dict([(var_list[j], assignment[j]) for j in range(len(var_list))])
if set_of_answer['G'] + 1 != set_of_answer['U']:
continue
if (set_of_answer['A']*2)%10 != set_of_answer['S'] and (set_of_answer['A']*2)%10 != set_of_answer['S']-1 :
continue
if set_of_answer['K']==0 or set_of_answer['E']==0:
continue
ret = set_of_answer['K'] + set_of_answer['E']
if (ret%10 != set_of_answer['D']):
continue

carryover = ret/10
ret = set_of_answer['S'] + set_of_answer['V'] + carryover
if (ret%10 != set_of_answer['E']):
continue

carryover = ret/10
ret = set_of_answer['A']*2 + carryover
if (ret%10 != set_of_answer['S']):
continue
print set_of_answer

print solve_puzzle()





But amazingly the PowerShell solution is so elegant! Too bad that it's not yet available to Vista and...wouldn't be open-sourced to Unix. Or else we can get ride of Bash or C-shell! Guess that this day won't come in near future...