Wednesday, August 13, 2008

Wordle

Johnatan Feinberg, a Senior Software Engineer at IBM, has developed what he calls "a toy for generating word clouds", choosing from different layout schemas, fonts and colors. The name of the toy is Wordle; also check out the blog if you want to stay tuned.

These are two examples obtained parsing a slightly modified version of my cv. As the software is an applet and there's not a "save as image" option and the printscreen leads to low quality images, I printed the clouds using PDFCreator, then enlarged it and selected the content with the snapshot tool. The final step involved some cropping and resizing in Photoshop.


My next step will probabily be a Photoshop session to blend the clouds with one of my pictures to get a sort of visual cv, maybe this could contribute to the "wow this guy's a class act!" attitude during interviews :-)

Web 2.0

In this very popular video Michael Wesch, Assistant Professor of Cultural Anthropology at Kansas State University, explains his vision of Internet today.



And here's another nice video by the Commoncraft guys that explains RSS "in plain English"

Monday, August 11, 2008

Growing Object-Oriented Software

Steve Freeman and Nat Pryce are posting online parts of a book they're working on, called Growing Object-Oriented Software, Guided by Tests. Should anyone be interested in giving feedback, they provide a Yahoo discussion group.

Rise of the phoenix

The Spandau Ballet are today's background music of mine. Match them with a photography site and you never know what can come out...


I only pray that before I die
Just like a phoenix I will rise and fly
Tell me who's to blame
Oh, I'm a man, now I'm a man in chains

The quote comes from "Man in chains", in the "Through the Barricades" album. The picture actually is ordinary incense smoke colored on the computer; Graham Jeffery describes all the details here. If you are wondering why it makes me think of a rising phoenix I guess you'll have to consult a Rorschach inkblot test expert.

It's all about tact... more or less

How do you tell someone she's not helping? Well Ken Schwaber has a pretty straightforward way of doing it:


Thanks to Michael J. Vizdos for the cartoon (and all the interesting stuff you'll find on his site).

Friday, August 8, 2008

Why I hate Javascript

Basically because I don't know it... and I don't want to get aquainted with it!!! Maybe it is because I'm so accustomed to the Java language, maybe because I'm dumb, maybe for a combination of these and several other factors. Anyway, I'll post some tips and some scripts that, albeit very easy, drove me crazy simply because I couldn't find their right syntax.

If you need to create an object in Java you must have a particular class and call its constructor using the "new" keyword (Yes, we can also use a factory method, a creation method, the newInstance method of the class, or other stuff, let's not be pedantic):
public class MyObject {
private String attr1;
private int attr2;
public MyObject(String attr1, int attr2) {
this.attr1 = attr1;
this.attr2 = attr2;
}
public String toString() {
return attr1 + " " + attr2;
}
}

...
MyObject obj = new MyObject(myString, myInt);
System.out.println(obj.toString());
...
In Javascript you simply create an object and add properties and methods to it:
personObj = new Object();
personObj.firstname = "John";
personObj.lastname = "Doe";
personObj.age = 50;
personObj.eyecolor = "blue";
But the interesting thing comes with methods. If you want to invoke a method in Java it must exist as public (yes, also default, or protected for subclasses, you could use reflection, I'm simplyfing for simplicity's sake!) in a class assignable to the object. In Javascript you simply add it:
addressObj.myOwnMethod = myOwnMethod;
If you want to call that method you use the syntax
addressObj.myOwnMethod();
BTW, all semicolons at the end of the lines are optional, just to make things weirder. And what happens when you call a method? you are really calling a function defined elsewhere, something like
function myOwnMethod() {
...
}
If your function has parameters, its declaration would be something like
function myOwnMethod(par1, par2) {
...
}
and if you want to call it you use the syntax
myObject.myOwnMethod(par1, par2)
What if you want to hide the parameters of the function you call, e.g. you ask a shipment for its cost, which is calculated on the basis of some attributes of the shipment itself? In Java you simply ask it to the shipment instance:
double shipmentCost = myShipment.getCost()
In Javascript you do the same, but it works in a slightly different way (maybe that's not the only one, but it is the only one I managed to get working). You have a method in the object without parameters, as one would expect, you have a function without parameters, as one would NOT expect, that gets called from the object when you invoke its method and it uses the "this" keyword... The "this" in a function!!! and it does not refer to the function but to the object that invoked it! how counterintuitive!
...
// inside the definition of an object (if using a template=
// or simply after the instantiation of an object
myShipment.getShippingCost = getShippingCost
...

// outside the definition of the object
function getShippingCost() {
var cost = 0;
if (this.DestinationAddress == "Boston") {
cost = (this.ShippingType == "STD") ? 100 : 200;
} else if (this.DestinationAddress == "Seoul") {
cost = (this.ShippingType == "STD") ? 500 : 1000;
}
return cost;
}

...
// somewhere else...
myShipment.getShippingCost();
It just gives me a headache... it's such a juggling act trying to learn Ajax technologies while keeping your mental health...

A simple RegExp to validate e-mail

Paul Warren presents a very simple regular expression that can be used to validate any e-mail address; as everybody can easily see, it satisfies all the grammar described in RFC822.
(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]
+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?
:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(
?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(
?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[
^\"\r\\]|\\.|(?:(?:\r\n)?[\t]))*"(?:(?:\r\n)?[ \t])*))*@(
?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:
(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\
r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(
?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\
r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?
:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\
]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\
r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?
:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\
\]|\\.)*\](?:(?:\r\n)?[\t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[
^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?
=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n
)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\]
\000-\031]+(?:(?:(?:\r\n)?[\t])+|\Z|(?=[\["()<>@,;:\\".\
[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:
(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?
:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\
\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(
?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)
?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:
[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(
?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[
\t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()
<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\
["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[
\t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000
-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]
))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r
\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r
\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\
\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)
?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\]\000-\031]+(?:(?:(?:\r
\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\
\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r
\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.
|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?
[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[
\t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\
](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;
:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<
>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])
*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?
:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])
*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](
?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\
\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@
,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)
)*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031
]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[
([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?
[ \t])*(?:[^()<>@,;:\\".\[\]\000-\031]+(?:(?:(?:\r\n)?[ \
t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\]
(?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()
<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"
(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:
\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>
@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?
:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".
\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:
\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:
\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:
(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[
\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])
*)(?:,\s*(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\
n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\
.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\
n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)
?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|
(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[
\t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \
t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\]
(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:
\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>
@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*
))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n) ?[ \t])
*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](
?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\
\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@
,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)
)*(?:,@(?:(?:\r\n)?[\t])*(?:[^()<>@,;:\\".\[\] \000-\031]
+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[(
[^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[
\t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \
t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\]
(?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()
<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"
(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:
\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>
@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?
:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".
\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:
\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:
\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:
(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[
\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])
*))*)?;\s*)

Thursday, August 7, 2008

W3Schools Javascript Quiz

Just completed the W3Schools Javascript Quiz and got 17 correct answers out of 20, which makes 85%, in 3:00 minutes. The computer tells me I can be proud of myself, but the acid test will come when I need to use it in a production environment...

A new use for Google Maps

Surfing around the web looking for Ajax applications I decided to try Google Maps paying attention to the technical stuff beyond it (want to see the code? try JSView, a Firefox plugin - BTW, I hope that the Google guys obfuscated it, because if that's the way they actually code... urgh! I can't understand anything!).

Anyway, I typed my address, hit the button and bang, the map smoothly appeared under my eyes: wow, awesome! And it is so easy to move around, and the responses you get are so fast! On the left there are additional informations, like pictures of places situated in the vicinity of the point identified using your search string. Another additional information is represented by personal maps, which is a nice feature that enables you to pinpoint interesting places. I saw such a map and decided to check it and... I could not believe it... I'll report an abstract of the description so you can get an idea yourself:

XXX is a 22 years old, pretty, blonde, long wavy hair, likeable, a very easygoing girl. She stands near YYY, under the railway bridge coming from ZZZ, pity she's a little plump.


I entered puzzled mode and went like "Ow, there must be some mistake... let me check this guy's maps..." and in the beginning everything looked fine, some restaurants and stuff, but going on you find a (probably) incomplete list of all the harlots he pays visits (among other things) to... and for each one he provides not only the location but also a brief description.

<ironic mode>Now, that's a service! (pun not intended) if you're looking for new friendships, including foreign cultures representatives, you have another ace in the hole (ehm... pun not intended)</ironic mode>

Wednesday, August 6, 2008

Collected Java Practices

Here's yet another site with some collected practices for Java Programming. I just surfed over some practices without diving into details, but I decided to read the "data is king" practice, as it clearly opposes to the "database is a detail" saying.

I pretty much agree with everything but I feel a shiver down my spine when I read the following sentence:

the data is always validated before being entered into the database (this cannot be stressed enough)

What's wrong with it? well, nothing at all, on the contrary! but it gets creepy when you put it with another sentence:

applications should never assume that they "own" the data. Databases are independent processes, and are built to interact with many clients applications, not just one

That forces me to meditate. IMHO, the first sentence is a perfect example of a too unused good theory, the second one describes a too diffused bad practice.


If data must always be validated (and it should!), and databases should interact with many client applications, each application must ensure the same data validation process happens. That means duplication, and (IMHO) it smells.

One could easily agree that moving the data validation process into the database would suffice to solve the problem, for example using stored procedures, triggers and rules. But then, the database should support these means, which leaves out, for example, flat files. Moreover, switching to a different database would be very difficult.

So what? as always, a very consolidated habit of communicating between peers can come to help: as it is a fact that many applications write to the very same database, everybody who is involved should ensure that the overlapping areas are as small as possible and that they deal with data in the same way, either with "database programming" or "people synchronization", thus reducing duplications and error sprouting.

Another solution can be one application exposing services used by the other ones, but sometimes this is not desirable or applicable.

That said, I want to stress the "no silver bullet" concept: "data is king" surely is a good advice but it cannot be taken as an absolute truth but as a general rule. The same applies, for example, to GRASPs: when you have to decide which class should create a new instance of another class, should you follow the Creator pattern or the Expert pattern? it depends, but the important thing here is that they can lead to very different results, each of which would have its proper rights to stand as a correct solution. It is our responsibility to derive our decisions on the basis of all our knowledge and experience - there's no magic involved, even if sometimes a design comes out naturally, just because "you know it's right": this lucky feeling comes from experience and a very long try-and-fail process. Only keep in mind that what you do can, most of the times, be further improved :-) so be humble and ask... you might be surprised!

Getting rid of HTML tags in a String

Today I found a post which proposes a simple trick based on regular expressions to get rid of all HTML tags from a String:

String noHTMLString = htmlString.replaceAll("\\<.*?>","");

All excited, and test-infected, I hurried to write a simple test:

@Test
public void testMinoreMaggiore() {
String instance = "<a href="...">3 è minore( < ) di 4 e maggiore ( > ) di 1</a>";
String expResult = "3 è minore ( < ) di 4 e maggiore ( > ) di 1";
String result = instance.replaceAll("\\<.*?>","");
assertEquals(expResult, result);
}

Not unexpectedly, the test failed. I couldn't help posting it to the author, hoping he won't see me as an insufferable know-it-all but as a mere proofreader...

Hello, World!

<sarcastic>Ever came within an ace of understanding those damned patterns, but never really got them? Here's your solution: the classic and boring Hello World refactored to patterns - the ultimate experience!</sarcastic>

public interface MessageStrategy {
public void sendMessage();
}

public abstract class AbstractStrategyFactory {
public abstract MessageStrategy createStrategy(MessageBody mb);

}

public class MessageBody {

Object payload;

public Object getPayload() {
return payload;
}

public void configure(Object obj) {
payload = obj;
}

public void send(MessageStrategy ms) {
ms.sendMessage();
}
}

public class DefaultFactory extends AbstractStrategyFactory {

private DefaultFactory() {
;
}

static DefaultFactory instance;

public static AbstractStrategyFactory getInstance() {
if (instance == null) {
instance = new DefaultFactory();
}
return instance;
}

public MessageStrategy createStrategy(final MessageBody mb) {
return new MessageStrategy() {
MessageBody body = mb;

public void sendMessage() {
Object obj = body.getPayload();
System.out.println((String) obj);
}
};
}
}

public class HelloWorld {

public static void main(String[] args) {
MessageBody mb = new MessageBody();
mb.configure("Hello World!");
AbstractStrategyFactory asf = DefaultFactory.getInstance();
MessageStrategy strategy = asf.createStrategy(mb);
mb.send(strategy);
}
}

The original post is here. Let me add a disclaimer for the overexcited with their eyes rolling, thrilled about the whole thing and eager to refactor all their codebase: don't try this at home.

Tuesday, August 5, 2008

Can you really program?

If you answered yes (and I reckon also the worst programmer in the world did) sooner or later you could be held to account to this assertion; just in case, you can pay a visit here and try some of the tests; when you finish the first ones you can be ranked against many other programmers all over the world.

Monday, August 4, 2008

Ken Schwaber explains Scrum

Ever wondered what this Scrum method everybody seems to be talking about is? Well you happen to be lucky, as I run by chance into this conference in which Ken Schwaber, who co-developed this agile process with Jeff Sutherland, introduces it during the Google Tech Days in 2006.



As a former rugby player (thus a sort of a scrum master), my favourite line is in the introduction, where he says Scrum is an event in the game of rugby where people get together and politely discuss ownership of a ball. It might sound fun and weird, but... that's exactly how it happens!

Anyway, one of the best things I've heard is that, even if Scrum takes a lot of ideas from a particular project in which only the best of the best people were involved, Scrum perfectly works with idiots, and that makes everybody a candidate: there are no excuses! Scrum can be used by everyone, and not only for software project. Last weekend my wife was reading me an endless list of things I should have done in the next couple of days and I told her: "Hey! You'd better prioritize it, because there's no way I could possibily get all this stuff done by Sunday evening!". We had a backlog, we had a timeboxed iteration. She acted as a product owner, choosing what I should do; she acted as a scrum master, checking my progresses and shielding me from my kids who wanted to play outside in the garden in which I was tearing the soil; I acted as a team, as the picture shows. We had a Scrum project!

Another very interesting thing is about the transparency of the project: everyone knows where the team is at all times. This can be frightening, because somebody in the upper management can realize they choose a very bad way to spend their money (actually the money of the company) after just a copule of months of a three year project. But this transparency can give you all the informations you need to take the most beneficial decisions for the whole organization. And this happens iteration after iteration!

Last but not least, a note on quality. Sustainable pace is not only advocated in XP, it should be an unbreakable rule. Studies show that increasing work up to 12-14 hours a day can lead to increase defects rate by 60%, and a good team should say no to dropping quality, because it can only bring pain and suffering in the long run.

Free Ajax and Web 2.0 Programming (with Passion) Online Course

That's the fourth online course offered by Sang Shin I attend; the official page of the course is here.

Friday, August 1, 2008

Swimming in deep (brown) water

Pampers towels are wonderful. Ideal Standard XL bowls are wonderful. My sons are wonderful.

Only, you don't have to put them together, as they don't exactly go hand in hand. Ask my wife for further explanations about the title of the post.

BTW, I will never stress enough the importance of living in a small town which provides you with a neighbour deep involved (believe me when I say I really mean it) in the cleaning of sewers... thanks again!!!

Gain a better understanding of code

What motivates us to refactor? Joshua Kerievski asks (and answers) himself this very same question. One of the reasons he gives is to "gain a better understanding of code". To quote:

Sometimes we look at code and have no idea what it does or how it works. Even if someone could stand next to us and explain the code, the next person to look at it could also be totally confused. Is it best to write a comment for such code? No. If the code isn't clear, it's an odor that needs to be removed by refactoring, not by deodorizing the code with a comment.

I'd like to stress the second part of the quote. Is this the way we behave? I'd like to say yes, but too often I don't. The most recurring reason for which this happens is that the typical codebase on which you experience this problem has no test harness. I know, I know, I did not only buy the Feathers', I also read and studied it: everything looks neat and beautiful, but sometimes the processes described can be really exhausting, and you obviously come to fear changes (which is against XP values, for example).

Now, to everyone who thinks Star Wars to be just a useless bunch of movies, I'll show you how it can help you experiences professionals through. Powerful master Yoda said:

Fear is the path to the dark side.

The dark side is represented by hacks'n'comments. When you find them, you should follow Darth Sidious' advice:

Wipe them out. All of them.


Extreme as it might look, this is by far the best solution in the long run. And... May the force be with you.

Our scrum mistress graduates

Better late than never, I'm more than proud to announce that on July 15, 2008 Manuela finally graduated with a more than deserved 108 out of 110, and thus owes me a beer. On her thesis you can find the following stripe:


This and many more on the wonderful Persichetti Bros' blog.