Saturday, December 26, 2009

ruby koans

Nice stuff to get introduced with the ruby programming language : http://github.com/edgecase/ruby_koans

I finally got to install git and use it to download some code.

While i was doing the exercices on ubuntu, i got to learn some vi tricks.

I wrote a .exrc file in my /home directory with just one line in it :

:set number

So now i get to see line numbers when i edit the test files with vi.

And i remembered the 'w' command that gets me to the end of the following word, cool.

Tuesday, November 3, 2009

agile tour in geneva (part 1 of 2)

Hi,

not much happening 'round here, eh?

I've been reading mailing lists a lot these days, that did not leave much time or energy to write myself.

But then I was at the Agile Tour in Geneva on October 12th, if that's not something to write about...

So i'll have a go at it while my ubuntu 9.10 download slowly completes.

All the sessions were in french from what I heard. I had a great time. Lots of sessions were people-oriented rather than technology/practices oriented. I'd have liked to see more technical workshops, but it was really nice anyway.

Here's the website's description of the sessions. Most of the slides and some video are available.

I'll just write some about the sessions I attended. There were always three sessions simultaneously, and i found it often quite hard to choose.


C1 : tips for creating a self-organizing team.
Yves Hanoulle from Belgium gave the talk. He came with his wife and kids, that was fun. From the various tips he gave I remembered three :

Check-in (and check-out). Let people know you're there and you're available to work. Tell them briefly what emotional state you're in. It should enable you to let the emotions go away and concentrate on your work/team.

The decider. When a decision has to be taken during a meeting, someone makes a proposition, and everybody should either give thumbs-up, flat palm or thumbs down. If thumbs-up are in a minority, the decision is rejected. Otherwise, the person who made the proposition should talk to the people who gave the thumbs down. Without asking them why they gave the thumbs-down. But asking them what would make them support the proposition.
Yves said that it was a very effective way to get decisions real fast. I like the idea. Not everybody in the room seemed convinced.

Talking stick. When there's a conflict between two persons : one of them holds a talking stick (or marker or whatever). As long as that person holds the artefact, the other person should ask questions to try and understand the person's position. When the artefact holder feels that he/she has been understood, he/she gives the talking stick to the other person and the roles are reversed.


B2 Introduction aux Core Protocols

Emmanuel Etasse gave us a short introduction to the Core Protocols, and then tried to get feedback from us on a recording of two guitarists playing Hotel California. I found the feedback to be mostly pretty negative. Then he explained the Perfection Game to us. It's an exercise in getting constructive feedback on some piece of work or performance.

Person A presents his/her work to person B. Then person B gives a grade (on a scale of 10) to person A and has to justify two things : what she liked about the work that made her give that grade. And what person A could have done in order for her to give the maximum grade.

I really liked the idea. In essence the ideas communicated might be the same as in 'natural' negative feedback ("you did this wrong, and this and that, ..."), but i feel it could be much more positive and interesting for the person receiving the feedback.

Then we formed groups of 5/6 people, and one person in each group talked during 5 minutes about a topic of his choosing (i'll stop with the "his/her" here, from what i remember there were only males in the room...). Then everybody was supposed to give feedback using the rules of the Perfection Game. But in my group nobody gave a grade, people started with a few things they liked about the topic (but even that seemed negative to me) and then just listed all the things they thought the talker had done wrong :)

It's hard to change one's mindset.


C3 Spécifications et Planning : éxécution dans un monde Agile

Fun (and a bit crowded) session with Stéphane Tavera and Jacques Couvreur. They talked about user stories and estimations. Then we tried to write user stories for the construction of Jacques' house. I found the choice of example a bit awkward, it would be hard to refactor a building...

I enjoyed Stéphane's soundbites :
iterative : slices of time
incremental : slices of product/functionality
user story <> use case
as a ..., i want to ..., so that ...
card / conversation / confirmation
yesterday's weather
story points
optional scope contract

A guy in the audience was bent on discussing budget issues and that took away the time reserved for planning (poker), too bad.

As with lots of other sessions, I found the questions and interactions following the questions often as valuable or more valuable than the presentations themselves.

And that ended the morning's sessions.

Karmic Koala has been running on my freshly installed VMWare for some time now and it's time to go to bed. Hopefully I'll get to write something about the afternoon part of the conference quite soon.

night,
nico

Monday, June 29, 2009

add a simple tool tip with a div title and jquery wrap

This week I spent some time trying to add a 'tooltip' to some textareas in a list.

I spent quite some time adapting a jquery script i found, finally made it work almost correctly in internet explorer 6, only to find out that it did not work as expected in ie7.

Finally I opted for a much easier solution : wrapping the textareas in a div with a title attribute containing the content of the textarea, like this :

<div title="test"><textarea>test</textarea></div>

(see html title attribute doc)

If you let the mouse rest a second over the textarea, the tool tip appears.



I did not have access directly to the code generating the textareas, but I could do it nicely with jquery. Let's say my textareas were called 'textarea_1', 'textarea_2', and so on. Here is the line i came up with :

$("textarea[name^='textarea_']").each(function (){jQuery(this).wrap('<div title="' + this.value + '"></div>')})

$("textarea") selects all textareas. (jquery element selector)

$("textarea[name^='textarea_']") selects every textarea whose name starts with 'textarea_'. (jquery 'attribute starts with' selector)

The 'each' function iterates over the selected elements. (jquery each)

'this' refers to the DOM element.

jQuery(this) turns the DOM element into a jQuery object. (jQuery)

The 'wrap' function allowed me to wrap each textarea inside a div. (wrap)

A last step : replacing quotes in the content so that text containing quotes would not be incomplete :

$("textarea[name^='textarea_']").each(function (){jQuery(this).wrap('<div title="' + this.value.replace('"', '&quot;') + '"></div>')})

Oh, that replaces only the first quote it finds... We need to use a 'global' search :

$("textarea[name^='textarea_']").each(function (){jQuery(this).wrap('<div title="' + this.value.replace(/"/g, '&quot;') + '"></div>')})

I only just found out I'd missed the global search, will go correct my code. Writing this post will have been useful to me, at least.

Tuesday, June 9, 2009

infinite loop in an sql server trigger

Hi.

I've spent some time writing sql server triggers these days and I made the same mistake twice in a month, so I thought I'd keep a note about it here.

In these triggers I have a main loop on the records that were inserted / updated / deleted.

To write this loop I :
  • defined a cursor CurIns on the special 'inserted' table
  • fetched the elements and put them into variables (FETCH CurIns INTO @var1, @var2, ...)
  • iterated with a

WHILE(@@FETCH_STATUS = 0)
BEGIN
[...]
END


At the end of the loop I had to write the FETCH CurIns INTO [...] again, not very DRY.

Nor especially pretty.

For some rows I did not want to execute the whole loop, so I used the CONTINUE keyword, as I would in php :

foreach ($array as $element) {
[...]
if (doNotNeedToHandleThis($element)) {
continue;
}
[...]
}


I tested my trigger via the browser, and the page just kept loading and loading and loading.

I had an infinite loop, because I should have called the FETCH CurIns INTO [...] before CONTINUEing. So my @@FETCH_STATUS was always zero, and the loop kept iterating on the same row.

So instead of writing the FETCH statement a third time I just enclosed the body of my loop in an IF block.

Beautiful.

I found it hard to avoid repetition, in these triggers.

Oh, and the process seemed to just go on and on, I don't know if there is a timeout for this kind of thing. To find out the process id :

EXEC sp_who2 'Active'


I found the SPID based on the time and user and asked the DBA to kill it.

Tuesday, June 2, 2009

promotion

A recruiting agency called me last week to see if i'd be interested in working as a 'php analyst-developer' for one of their clients.

The recruiter told me what she thought were the nice sides of the company, and particularly that there were opportunities to get promoted to 'business analyst' or 'project manager'.

Am i to conclude that developer is a lousier job than BA or PM?

Sunday, May 24, 2009

how to remove attributes from html tags using php and regular expressions

Here's a problem my colleague had friday : he needed to strip the attributes from h2 and td tags in an html document.

There were several different kinds of attributes and they might change in the future, so we figured using regular expressions would be nicer than using the str_replace function.

Here's a little function to check that the 'strip' function we are writing does the job correctly :


function checkStripping()
{
$a = array();
$a['<h2 style="blabla">'] = '<h2>';
$a['<h2 style="blabla, bla bla">'] = '<h2>';
$a['<td style="blablabli, bla bla">'] = '<td>';
foreach ($a as $before => $after) {
if (strip($before) == $after) {
echo '.';
} else {
echo '<br />F (strip(' . htmlspecialchars($before)
. ') was expected to be '
. htmlspecialchars($after) . ' and is '
. htmlspecialchars(strip($before)) . ')';
}
}
}


It turns out the testing function will be much longer than the one that does the job...
Had we used a unit testing framework like PHPUnit it would have been shorter.

Now here's the function we first came up with to do the stripping :


function strip($s)
{
$pattern = array('<h2.*>', '<td.*>');
$replacement = array('<h2>', '<td>');
return preg_replace($pattern, $replacement, $s);
}


It uses the php function preg_replace which allows us to define what strings should replace what regular expressions in a text.

The 'tricky' part for us was defining the regular expression. We started by writing it this way :

'<h2.*>' (a)

We wanted to say our pattern was made of
  • '<h2'
  • any character zero or more times (.*)
  • the closing '>'.
That didn't work, it gave us '<<h2>' instead of '<h2>', and we couldn't understand why.

Then we wrote it this way :

'/<h2[^>]*/>' (b)

Instead of the dot (.) to signify 'any character', we chose '[^>]' to mean 'any character expect for the closing >'.
And i remembered that i'd always seen regular expressions used with some character at the beginning and at the end, so i added those '/' at the beginning and at the end.

And pattern (b) worked! So we looked no further.

Last night I decided to finally have a go at writing a blog on programming. I doubt it will be of interest to anybody, but you never know.

Now I've found that at least it's been useful to me, because now that i've described our problem, i figured out why pattern (a) didn't work, and how pattern (b) could be simplified.

I think pattern (a) did not work because we omitted those characters (here '/', but we could have chosen something else) around our regular expression. PHP must have thought that '<' served that purpose, so it looked for 'h2.*>' and replaced what it found with '<h2>'. So that explains why we ended up with '<<h2>' as a result. (you can read more about those delimiters on php.net)

And so replacing the dot with '[^>]' is not necessary, so the final version of our function would be :


function strip($s)
{
$pattern = array('/<h2.*/>', '/<td.*/>');
$replacement = array('<h2>', '<td>');
return preg_replace($pattern, $replacement, $s);
}


Of course I'll be glad to have feedback if anyone reads this and knows a better way to do it.



Monday, May 25th edit: my unit tests were not good enough, it turns out the '.*' is greedy and my function as it is would replace '<h2>title</h2>' with '<h2>'.
Adding a question mark after the '.*' does the trick, so the function should be :


function strip($s)
{
$pattern = array('/<h2.*?/>', '/<td.*?/>');
$replacement = array('<h2>', '<td>');
return preg_replace($pattern, $replacement, $s);
}