<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1150179455008593965</id><updated>2012-02-16T11:01:39.230-08:00</updated><category term='ruby'/><category term='pictures'/><category term='google app engine'/><category term='javascript'/><category term='pocketcellar'/><category term='decorators'/><category term='bugs'/><category term='quote'/><category term='wine'/><category term='self-organized teams'/><category term='Agile lessons learned'/><category term='guice'/><category term='agile'/><category term='backlog'/><category term='python'/><category term='desire'/><category term='rails'/><category term='piicture'/><category term='app engine'/><category term='linux'/><category term='mycellar'/><category term='i18n'/><category term='jQuery'/><category term='smugmug'/><category term='retrospective'/><category term='php'/><category term='programming'/><category term='hierarchy'/><category term='how-to'/><category term='compass'/><category term='Lessons learned'/><category term='montreal'/><category term='pair programming'/><category term='ruby on rails'/><category term='challenge everything'/><category term='android'/><category term='scss'/><category term='scrum'/><category term='commitment'/><category term='peter principle'/><category term='winelog'/><category term='coaching'/><category term='opinion'/><category term='Django'/><category term='html'/><category term='experience feedback'/><category term='unit testing'/><category term='sosoft'/><category term='JSF'/><category term='heroku'/><category term='ubuntu'/><category term='management'/><category term='pocket cellar'/><title type='text'>Nicholas Lemay's blog.</title><subtitle type='html'>A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects.

-Robert A. Heinlein</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>91</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4775976656723101921</id><published>2011-11-18T23:33:00.000-08:00</published><updated>2012-01-24T17:25:39.078-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lessons learned'/><title type='text'>The greatest work days of my life</title><content type='html'>Thus far,&lt;br /&gt;&lt;br /&gt;I feel pretty lucky about how my career as a software developer has turned out so far. A few years into the game, I already feel I have experienced things a lot of people will never have the chance to experience in their lifetime.&lt;br /&gt;&lt;br /&gt;Thus far, I have lived through a few especially memorable moments.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Agile 2010&lt;/h3&gt;&lt;br /&gt;One, while working on an Agile project management tool, I got the privilege to represent the product at the Agile 2010 conference. It was my forst major conference and my first time meeting potential customers on-site and face-to-face. This is a far cry from coding all day in a cubicle like some of our teachers made out our careers to be. For me, this event was very exhilarating and was a total blast. To top it off, it all occurred at Disney Land !&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Agile Tour &amp;amp; Confoo&lt;/h3&gt;&lt;br /&gt;Another very exhilarating was animating a workshop on Scrum &amp;amp; paper prototyping alongside one of my colleagues at two different conferences. I HATED presentations at school. They really bring me out of my confort zone. Nerver the less, the feeling you get once you see the people engaging in your workshop and the small high afterwards is fantastic. Highly recommended for anyone seeking to come out of their shells. On a plus side, presenting on a subject really forces you to learn more about it which is a major bonus.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;My greatest work day ever&lt;/h3&gt;&lt;br /&gt;Funny things is that, the greatest work day included elements from the previous two experiences. &lt;br /&gt;&lt;br /&gt;A little background info first. My first consulting mandate, for multiple reasons, was a very harsh experience. A baptism in fire if you will. Due to the combination of multiple factors, the working environment turned out to be by far the most unpleasant one I have had to deal with thus far in my life. &lt;br /&gt;&lt;br /&gt;However, my partners and I thought we could truly make a difference if allowed to prove that we could help on multiple levels. &lt;br /&gt;&lt;br /&gt;We were ready to offer technical coaching and courses to the team to bring their technical level to the required level. We knew of multiple techniques that would help managers be much more efficient in the way they dealt with their team members while helping team moral and overall employee satisfaction.&lt;br /&gt;&lt;br /&gt;The first step however, was to confront middle and upper-management who were loosely involved in the project and paint them a clear picture of how bad the project and the  employee's moral really was and get their buy-in.&lt;br /&gt;&lt;br /&gt;So here we were, all 5 of us, during 2 consecutive hours presenting to managers and explaining to them how bad their results were and why. We confronted them on micro-management issues, employee turn overs, lack of training and a bunch of other issues they were directly or indirectly responsible for. &lt;br /&gt;&lt;br /&gt;It was an honest discussion. Every argument was backed by facts and were witnessed by multiple people. Rarely in my life had I felt more like I was doing the right thing. We were not hiding the truth like most employees would. &lt;br /&gt;&lt;br /&gt;We were confronting people responsible for this and we were really doing so in order to help them. Actually, by doing that presentation, we were risking our contracts there, in the name of doing the right thing. When we left the meeting that day, it felt so surreal, yet we were on a cloud.&lt;br /&gt;&lt;br /&gt;Hopefully, I will be writing a similar in 5 years, and think to myself : "I can't believe how far I have come" once again. If my limited experience has taught me anything, I will have to stay out of the cubicles, get our of my confort zone and make it happen :)&lt;br /&gt;&lt;br /&gt;Nick.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4775976656723101921?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4775976656723101921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4775976656723101921' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4775976656723101921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4775976656723101921'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/09/greatest-work-days-of-my-life.html' title='The greatest work days of my life'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-5979104691546265898</id><published>2011-11-18T22:51:00.000-08:00</published><updated>2011-11-18T19:53:01.604-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='how-to'/><title type='text'>Using private constructors in Ruby.</title><content type='html'>&lt;h3&gt;Why make a construtor private in Ruby ?&lt;/h3&gt;&lt;br /&gt;The other day I was having fun practicing my Ruby skills with the &lt;a href="http://programmingpraxis.com/2011/07/01/feet-and-inches/"&gt;Feet and Inches exercise&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;While building out my tests, I wanted to have a nice API from which to run the main program. Through numerous tests and refactorings, my final result ended up looking like this  :&lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;  it "should convert 12 inches to 1 foot" do&lt;br /&gt;    CarpentersMeasurement.of(12.inches).should == "1 foot"&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As it often starts out with procedural code, I started out with a static method as en entry point. As my initial object's responsibility grew, I wanted to  create an instance of this object.&lt;br /&gt;&lt;br /&gt;However, I wished that the user of my class would only use the "of" method directly. The "new" method for me should not be available yet to users of this class. &lt;br /&gt;&lt;br /&gt;For this purpose, I wanted the constructor to be private, like we often do in Java &lt;a href="http://www.natpryce.com/articles/000769.html"&gt;when creating builder objects&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How do we make a construtor private in Ruby ?&lt;/h3&gt; &lt;br /&gt;Simply, make the :new method private. In my case, the final result looks a little bit like this : &lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;class CarpentersMeasurement&lt;br /&gt;&lt;br /&gt;  private_class_method :new&lt;br /&gt; &lt;br /&gt;  def self.of number_of_inches&lt;br /&gt;    new(number_of_inches)&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nick.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-5979104691546265898?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/5979104691546265898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=5979104691546265898' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5979104691546265898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5979104691546265898'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/09/using-private-constructors-in-ruby.html' title='Using private constructors in Ruby.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2918402385392987564</id><published>2011-10-09T15:28:00.000-07:00</published><updated>2011-10-09T15:32:22.316-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>You may kiss the bride part 2</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_nt398X#1520254687_2n5kjnb"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/i-2n5kjnb/0/M/DSC0067-M.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2918402385392987564?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2918402385392987564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2918402385392987564' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2918402385392987564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2918402385392987564'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/10/you-may-kiss-bride-part-2.html' title='You may kiss the bride part 2'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-8740502422468588095</id><published>2011-09-18T14:10:00.000-07:00</published><updated>2011-09-19T04:00:40.027-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='decorators'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='google app engine'/><title type='text'>Unit Testing Exceptions In Python</title><content type='html'>Lately, I've been doing a lot of Ruby development. One of my favorite Ruby tools is the &lt;a href="http://rspec.info/"&gt;RSpec BDD framework&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One thing I really like about RSpec is that you express your specification in a form closely resembling the form you would use in a conversation with other developers or a client.&lt;br /&gt;&lt;br /&gt;This syntax for even goes for testing exceptions :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;describe CarpentersMeasurement do&lt;br /&gt;&lt;br /&gt;  it "should raise an exception on negative number of inches" do&lt;br /&gt;    lambda{CarpentersMeasurement.of(-1.inch)}.should raise_error InvalidLengthError&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This made me think about Python tests. Oftentimes, I would see something like : &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;    @istest&lt;br /&gt;    def should_raise_an_exception_when_attempting_to_convert_a_negative_number(self):&lt;br /&gt;        try:&lt;br /&gt;            DistanceInMiles.calculated_from(-5, "km")&lt;br /&gt;            self.fail("should raise when converting from negative number")&lt;br /&gt;        except:&lt;br /&gt;            pass&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;While working, I find this try:except: block pattern not to be very elegant.&lt;br /&gt;&lt;br /&gt;Python's Unitttest module does come bundled with a very useful &lt;a href="http://docs.python.org/library/unittest.html#unittest.TestCase.assertRaises"&gt;assertRaises assertion&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Unfortunately, the method call statement is not wrapped in another method like in Rspec using Ruby's lambda expression. This means you cannot call the method directly using "()", otherwise this will execute the method and throw the exception.&lt;br /&gt;&lt;br /&gt;Instead, You use a pointer towards the method like this : &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;    @istest&lt;br /&gt;    def should_raise_an_exception_when_attempting_to_convert_a_negative_number(self):&lt;br /&gt;        self.assertRaises(NegativeNumberException, DistanceInMiles.calculated_from, -5, "km")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In most situations, I find this solution very elegant. Unfortunately, there are cases when using this form is a total pain. &lt;br /&gt;&lt;br /&gt;For example when testing a constructor that throws exceptions. &lt;br /&gt;&lt;br /&gt;One common example of this is &lt;a href="http://code.google.com/appengine/docs/python/datastore/datamodeling.html"&gt;Google App Engine Model&lt;/a&gt; instances, which throw exceptions when the values specified to the constructor are not legal according to the models attributes definition.  &lt;br /&gt;&lt;br /&gt;Ideally, using BDD/TDD you would write unit tests to validate these. Since the first parameter of a constructor in Python is self, it becomes really ugly to test an __init__ method. &lt;br /&gt;&lt;br /&gt;In &lt;a href="http://www.junit.org/"&gt;Junit 4&lt;/a&gt;, one pattern for testing exception that I liked was this : &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;    @Test(expected = NumberFormatException.class)&lt;br /&gt;    public void should_throw_an_exception_when_parsing_a_sentence() throws Exception {&lt;br /&gt;        Integer.parseInt("This not a number...");&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Since it is so easy to create decorators in Python, I use the following decorator to test exceptions being thrown, just like my &lt;a href="http://code.google.com/appengine/docs/python/datastore/datamodeling.html"&gt;Google App Engine Models&lt;/a&gt; for example :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;def should_raise(exception):&lt;br /&gt;   def should_raise_decorator(decorated_function):&lt;br /&gt;       def decorated(self, *args, **kwargs):&lt;br /&gt;           self.assertRaises(exception, decorated_function, self, *args, **kwargs)&lt;br /&gt;       return decorated&lt;br /&gt;   return should_raise_decorator&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Using this decorator, the previous example can be written as this :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;  @istest&lt;br /&gt;  @should_raise(NegativeNumberException)&lt;br /&gt;    def should_raise_an_exception_when_attempting_to_convert_a_negative_number(self):&lt;br /&gt;        DistanceInMiles.calculated_from(-5, "km")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can see a working example of this &lt;a href="https://github.com/nicholaslemay/Unit-Testing-Exceptions-In-Python-Blog/blob/master/DistanceInMilesTests.py"&gt;on my Github account&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-8740502422468588095?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/8740502422468588095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=8740502422468588095' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8740502422468588095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8740502422468588095'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/09/unit-testing-exception-in-python.html' title='Unit Testing Exceptions In Python'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-9008210695271753115</id><published>2011-08-09T08:44:00.001-07:00</published><updated>2011-08-22T19:03:58.348-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><category scheme='http://www.blogger.com/atom/ns#' term='i18n'/><title type='text'>Keeping Ruby on Rails I18n files DRY with fallbacks.</title><content type='html'>So you're Ruby on Rails App is finally getting some well deserved attention in the market you are hitting and think it's time to attack new markets. You already have all your text in internalization files(right....RIGHT?). Let's suppose it's all in a file called &lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;en.yml&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Now you think to yourself, since all these countries speak the same language, wouldn't it be nice if I could just have my country specific keys in country specific file and have all the common stuff in a language file of its own. &lt;br /&gt;&lt;br /&gt;Well guess what ? It's super easy to setup in Rails. &lt;br /&gt;&lt;br /&gt;Simply add the following lines in your Environment.rb in the initializer section &lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;  require "i18n/backend/fallbacks"&lt;br /&gt;  I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)&lt;br /&gt;  #I18n.default_locale = "en" #add only if you need a different default &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, when a user access your sites using let's say the &lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;en-GB&lt;/span&gt;&lt;/span&gt; locale or &lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;en-US&lt;/span&gt;&lt;/span&gt; locale, you can use country specific expressions or pricing options in the &lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;en-GB.yml&lt;/span&gt;&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;en-US.yml&lt;/span&gt;&lt;/span&gt; file. You can then leave all the common stuff in the en.yml file to which the key resolution will fallback if it cannot find the value in the more specific file. If you specify a default locale,  the order of a resolution for a user using the en-GB locale would be en-GB -&gt; en -&gt; default-Locale.&lt;br /&gt;&lt;br /&gt;Again, another nice and clean way of keeping your Rails App DRY.&lt;br /&gt;&lt;br /&gt;Nicholas.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-9008210695271753115?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/9008210695271753115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=9008210695271753115' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9008210695271753115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9008210695271753115'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/08/keeping-ruby-on-rails-i18n-files-dry.html' title='Keeping Ruby on Rails I18n files DRY with fallbacks.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4945958292767006745</id><published>2011-07-26T06:19:00.000-07:00</published><updated>2011-07-27T09:41:34.278-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='experience feedback'/><title type='text'>Feedback on using JSF Mojarra to build an enterprise application.</title><content type='html'>&lt;h2&gt;Background&lt;/h2&gt;&lt;br /&gt;For the past six month, I had the pleasure of being part of a team whose mandate is to lower the data entry time of the creation of their insurance groups by replacing parts of an existing system by a brand new one. &lt;br /&gt;&lt;br /&gt;Thus was born a brand new Web application whose main objective is to improve usability and user experience. Pretty neat stuff and right up my alley !&lt;br /&gt;&lt;br /&gt;Our project add a few side-objectives. One of which was to test out the new technological stack the organization was pushing forward. The proposed stack was said to be a pretty common one for a Java environment : &lt;br /&gt;&lt;br /&gt;- Spring. Cool. &lt;br /&gt;- Hibernate. Cool. &lt;br /&gt;- JSF. JSF ? I'm a pretty up-to-date guy but had yet to have heard of JSF by that point. No to worry, I'm always willing to try out some new stuff. The proposed implementation was Oracle's own default : &lt;a href="http://javaserverfaces.java.net/"&gt;Mojarra&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The application&lt;/h2&gt;&lt;br /&gt;The application is your standard enterprise application. Its a series of forms, organized to follow a particular work flow with your basic C.R.U.D. operations. The forms however, bind to domain objects with a lot of business logic. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;JSF : The good&lt;/h2&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;Installation&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;All things considered, it was not that hard to get up and running. Within a few hours we had something worthwhile up and running. Nothing as simple as &lt;a href="http://guides.rubyonrails.org/command_line.html#rails-new"&gt;Rails' new command&lt;/a&gt; or &lt;a href="https://docs.djangoproject.com/en/dev/intro/tutorial01/#creating-a-project"&gt;Django's startproject&lt;/a&gt; but still, how often will you be starting a new project, right ?  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;URL mapping configuration&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Having seen the insane amount of XML written to support a JSF 1.x app, I was getting scared I was gonna live through all of it myself. Actually, with JSF 2.x, we did not have to configure any of our URLs in XML. Hitting a URL like /blog/new.xhtml accessed the matching file directly. Pretty cool.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;Bean validation &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Using JPA annotations on our domain objects, it was pretty simple to declare the restrictions on the fields of our domain objects. To our great pleasure, the integration of these validations with the JSF life cycle when submitting our forms and the display of errors afterwards was very well done.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;JSF : The bad&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;Weird choices regarding Web standards&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;When you use JSF, it will generate IDs for you, generally concatenating the id of the parent element with the id of the child element. Fortunately for TDD fanatics like us, these URLs are predictable enough to allow their use in our end-to-end testing. &lt;br /&gt;&lt;br /&gt;What's sad though, is that the delimiting character they chose is ":". This character has a special meaning in CSS. Thus, when using the default ids generated by JSF in our JavaScript, in our CSS or in our test we were running into all kind of problems. Afterwards, we discovered that you can easily override the delimiter by a more friendly character like "_". Why such a character was not the default is beyond me.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;Lack of support for REST&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Frameworks like Django, Rails and SpringMVC allow you to create controllers that are bound to a specific URL and that will provide a different response based on the data type requested by the client.&lt;br /&gt;&lt;br /&gt;This way, you can GET the URL /blogs/jsf-feedback and be presented a web page. Later on, you could expose the same resource in an XML format using the URL /blogs/jsf-feedback.xml  to let people use your application as a web service. This is pretty simple stuff, that allows your application to grow beyond its original scope and be more future-proof towards emerging technologies.(I mean, who knew 10 years ago it would be helpful to expose some of your resources in JSON?)&lt;br /&gt;&lt;br /&gt;With JSF everything is binded to the view. If you hit /blogs/index.xhtml it will first parse that xhtml document and set its different values. Only after that will it execute the associated method of its "controller". While this works OK for a Web application, it kills the possibility of having your application double as a web service. Furthermore, since your URLs are binded to views, they prohibit restful URLs like /people/us/texas/dallas. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;Use of the wrong HTTP verbs &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Coming from a REST background, I have come to appreciate using the Web the way it was meant to be. However, using JSF tags that cause to interact with the server will mostly translate into an HTTP POST. &lt;br /&gt;&lt;br /&gt;In a lot of examples, you will still see anchor links towards other pages being wrapped into a from that does a POST(!) to the server. Apparently, this is an heritage from JSF 1.X, but it still lingers in examples of JSF 2.X. Forget about PUT or DELETE also.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;No ifs &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Long story short, JSF does not include the basic if statement that is used in most templating languages. While there is a way to control whether to display information or not, it is most unorthodox.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;JSF : The ugly&lt;/h2&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;JSF makes it impossible to unit test views. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Having spent some of my time working with &lt;a href="http://djangoproject.com"&gt;Django&lt;/a&gt;, &lt;a href="http://www.rubyonrails.org/"&gt;Rails&lt;/a&gt; and to a lesser extent &lt;a href="http://static.springsource.org/spring/docs/2.0.x/reference/mvc.html"&gt;Spring MVC&lt;/a&gt; (with Velocity templates), I now understand the use and importance of&lt;a href="https://github.com/nicholaslemay/hibou/blob/master/spec/views/children/show.html.haml_spec.rb"&gt; unit testing your views&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Unfortunately, JSF makes it impossible to test your rendering by itself.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Mojarra is buggy&lt;/h3&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Note : These issues are most likely Mojarra-specific and might not apply to other implementations of JSF.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;The h:panelGroup bug.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;While using JSF, we just kept seeing weird bugs popping up. For example, JSF's h:panelGroup tag is used to generate a span or a div. In some circumstances, it did not generate the closing tag of our divs, thus breaking the content of our page and in some instances its layout entirely. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;The nested loop bug:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;While trying to iterate over a nested list, we tried many different approaches. All of them failed. Apparently, nested loops are not (well?) supported. We ended up giving up and using the dataTable tag which works pretty well. &lt;br /&gt;&lt;br /&gt;Unfortunately, it uses tables for everything. Its a sad thing when your framework gets in the way of producing semantically correct HTML.&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The flash scope bug:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;To anyone who has used Rails, your surely have used the flash notice. A neat thing about JSF is that they implemented their version of flash scope. In the documentation, they even give credit to Rails for the idea. Unfortunately, in our version of Mojarra, it was totally broken. We ended up re-writing a custom implementation. It did not take too long, but was a complete annoyance to have to re-write something so basic. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;Community&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Being new to JSF, I did spend a fair amount of time "Googling" around. Unfortunately, there seems to be no hype whatsoever behind JSF or Mojarra. The low number of people on &lt;a href="http://java.net/projects/javaserverfaces/lists"&gt;Mojarra's mailing list &lt;/a&gt;seem to indicate a very low interest by the Java community.&lt;br /&gt;&lt;br /&gt;Very few blogs, tutorial or screencasts are available. Most often than not, I would end up on &lt;a href="http://www.roseindia.net/jsf/dataTable.shtml"&gt;roseindia.net&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;When most of the examples comes from such a lackluster site filled with publicity, it's pretty depressing.&lt;br /&gt;&lt;br /&gt;It seems people have spent more building &lt;a href="http://ptrthomas.wordpress.com/2009/05/15/jsf-sucks/"&gt;sites to complain about JSF&lt;/a&gt; then on how to use it efficiently.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;Documentation&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Coming from a Django and Rails background, I was accustomed to having great documentation. I mean, Django comes with &lt;a href="https://docs.djangoproject.com/en/1.3/intro/tutorial01/"&gt;its own thorough tutorial&lt;/a&gt; and a &lt;a href="http://www.djangobook.com/en/2.0/"&gt;free book&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Rails comes with a &lt;a href="http://api.rubyonrails.org/"&gt;kickass doc&lt;/a&gt; and an &lt;a href="http://guides.rubyonrails.org/"&gt;awesome guide&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;JSF Mojarra comes&lt;a href="http://javaserverfaces.java.net/users.html"&gt; with this &lt;/a&gt;. In 2011, I think its pretty inexcusable. Heck, it says to start with the JSF2 DataSheet in the first line but the link has been broken forever.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The end result&lt;/h2&gt;&lt;br /&gt;After six months spent on the project, I can gladly say that we managed to develop a pretty good application. Up to that point we have met our objectives. We've tested the app with the user and have drastically cut their data entry time. The usability tests we have made has gathered mostly positive feedback thus far. &lt;br /&gt;&lt;br /&gt;So I'll go on record and say &lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;it is possible to build a very capable application in spite of using JSF.&lt;/span&gt;&lt;/span&gt; However, from my six month experience, I could not recommend using JSF to build web applications similar to the one we built, knowing all the other great alternatives that are freely available.&lt;br /&gt;           &lt;br /&gt;Feel free to comment with your own experience with JSF. &lt;br /&gt;Nick&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4945958292767006745?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4945958292767006745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4945958292767006745' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4945958292767006745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4945958292767006745'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/07/feedback-on-using-jsf-mojarra-to-build.html' title='Feedback on using JSF Mojarra to build an enterprise application.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2948350301792312817</id><published>2011-07-24T17:55:00.001-07:00</published><updated>2012-01-25T04:45:40.482-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Homemade pizza</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/Food/18204839_D54dRw#1399031471_gNwC8PR"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/Food/i-gNwC8PR/0/M/pizza-M.jpg" style="cursor: hand; cursor: pointer; float: left; height: 450px; margin: 0 10px 10px 0; width: 374px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear: both; float: left;"&gt;&lt;br /&gt;Prosciutto, aragula, tomatoes, mozarella and a little love.&lt;br /&gt;-Nick&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2948350301792312817?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2948350301792312817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2948350301792312817' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2948350301792312817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2948350301792312817'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/07/homemade-pizza.html' title='Homemade pizza'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-5716948866785514452</id><published>2011-07-10T07:33:00.000-07:00</published><updated>2011-07-10T07:55:34.753-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pocketcellar'/><category scheme='http://www.blogger.com/atom/ns#' term='wine'/><category scheme='http://www.blogger.com/atom/ns#' term='pocket cellar'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Releasing PocketCellar V1.4</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-DCrb6QAnn7Q/TX7awf7uGFI/AAAAAAAAAHU/bNbuCljyjsQ/s1600/waiter.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 209px; height: 320px;" src="http://4.bp.blogspot.com/-DCrb6QAnn7Q/TX7awf7uGFI/AAAAAAAAAHU/bNbuCljyjsQ/s320/waiter.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5584141114726553682" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hey folks,&lt;br /&gt;         we've just released a brand new version of &lt;a href="http://www.mycellar.net/"&gt;PocketCellar&lt;/a&gt; for Android.&lt;br /&gt;&lt;br /&gt;This new version allows you to export your wines list. This way, you can edit your list of wines in a user friendly CSV format via Excel or Libre Office.&lt;br /&gt;&lt;br /&gt;This also protects you from losing all of your data, should you change or lose your phone. &lt;br /&gt;&lt;br /&gt;Interested ? Simply &lt;a href="http://www.mycellar.net/"&gt;download PocketCellar&lt;/a&gt; from the market. It's free.&lt;br /&gt;&lt;br /&gt;Enjoy your tasting responsibly ! &lt;br /&gt;Nicholas Lemay&lt;br /&gt;&lt;br /&gt;ps: We've only had access to 4 different types of HTC phones, 1 Motorola and 1 Samsung to do our platform testing prior to this release. If you encounter any issue with our app, please report them. Thanks !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-5716948866785514452?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/5716948866785514452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=5716948866785514452' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5716948866785514452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5716948866785514452'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/07/releasing-pocketcellar-v14.html' title='Releasing PocketCellar V1.4'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-DCrb6QAnn7Q/TX7awf7uGFI/AAAAAAAAAHU/bNbuCljyjsQ/s72-c/waiter.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-9059113884127466220</id><published>2011-06-13T03:54:00.000-07:00</published><updated>2012-01-25T04:45:51.174-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Corner Overtake</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/F1-Grand-Prix-2011/17518459_ZGJ4rh#1333374076_dSpGrkZ"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/F1-Grand-Prix-2011/i-dSpGrkZ/0/M/DSC0421-M.jpg" style="cursor: hand; cursor: pointer; float: left; height: 450px; margin: 0 10px 10px 0; width: 374px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-9059113884127466220?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/9059113884127466220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=9059113884127466220' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9059113884127466220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9059113884127466220'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/06/corner-overtake.html' title='Corner Overtake'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7047439215658766103</id><published>2011-05-22T14:23:00.000-07:00</published><updated>2012-01-25T04:46:06.063-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>All We Really Needed</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#1302397282_bsdRLMr"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/i-bsdRLMr/0/M/csc0281-M.jpg" style="cursor: hand; cursor: pointer; float: left; height: 399px; margin: 0 10px 10px 0; width: 600px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7047439215658766103?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7047439215658766103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7047439215658766103' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7047439215658766103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7047439215658766103'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/05/all-we-really-needed.html' title='All We Really Needed'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7235611782905708526</id><published>2011-05-22T14:20:00.000-07:00</published><updated>2012-01-25T04:46:20.225-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>The Way</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#1302392981_t49Tj5H"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/i-t49Tj5H/0/M/dsc0177-M.jpg" style="cursor: hand; cursor: pointer; float: left; height: 450px; margin: 0 10px 10px 0; width: 354px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7235611782905708526?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7235611782905708526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7235611782905708526' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7235611782905708526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7235611782905708526'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/05/way.html' title='The Way'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2698277721558781305</id><published>2011-05-22T14:17:00.001-07:00</published><updated>2012-01-25T04:46:31.761-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>1000th Game</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#1302397001_4RFSHLX"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/i-4RFSHLX/0/M/dsc0112-M.jpg" style="cursor: hand; cursor: pointer; display: block; float: left; height: 450px; text-align: center; width: 299px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2698277721558781305?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2698277721558781305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2698277721558781305' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2698277721558781305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2698277721558781305'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/05/1000th-game.html' title='1000th Game'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2592116979433624769</id><published>2011-04-28T17:03:00.000-07:00</published><updated>2011-04-29T15:43:54.906-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pocketcellar'/><category scheme='http://www.blogger.com/atom/ns#' term='wine'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Releasing PocketCellar V1.2</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-DCrb6QAnn7Q/TX7awf7uGFI/AAAAAAAAAHU/bNbuCljyjsQ/s1600/waiter.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 209px; height: 320px;" src="http://4.bp.blogspot.com/-DCrb6QAnn7Q/TX7awf7uGFI/AAAAAAAAAHU/bNbuCljyjsQ/s320/waiter.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5584141114726553682" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hey folks,&lt;br /&gt;         we've just released a brand new version of &lt;a href="http://www.mycellar.net/"&gt;PocketCellar&lt;/a&gt; for Android.&lt;br /&gt;&lt;br /&gt;This new version allows you to take pictures of your wines and consult them at anytime.&lt;br /&gt;&lt;br /&gt;At the restaurant and want to remember a wine you're enjoying ? Snap a picture of it.&lt;br /&gt;&lt;br /&gt;Want to buy a wine at the liquor store but can't remember that great wine you had last week. Fire up your Android and consult the picture you took.&lt;br /&gt;&lt;br /&gt;Love taking tasting notes but are on a rush ? Snap a picture of your wine and complete your tasting notes afterwards.&lt;br /&gt;&lt;br /&gt;Interested ? Simply &lt;a href="http://www.mycellar.net/"&gt;download PocketCellar&lt;/a&gt; from the market. It's free !&lt;br /&gt;&lt;br /&gt;Enjoy your tasting responsibly ! &lt;br /&gt;Nicholas Lemay&lt;br /&gt;&lt;br /&gt;ps: We've only had access to 4 different types of HTC phones, 1 Motorola and 1 Samsung to do our platform testing prior to this release. If you encounter any issue with our app, please report them. Thanks !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2592116979433624769?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2592116979433624769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2592116979433624769' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2592116979433624769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2592116979433624769'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/04/releasing-pocketcellar-v12.html' title='Releasing PocketCellar V1.2'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-DCrb6QAnn7Q/TX7awf7uGFI/AAAAAAAAAHU/bNbuCljyjsQ/s72-c/waiter.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-8694171192266280430</id><published>2011-04-25T18:03:00.000-07:00</published><updated>2012-01-26T05:09:18.616-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Agile Lessons Learned 16 : Step Into The Light</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#883243145_stA4B"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/pinkFloyd/883243145_stA4B-S.jpg" style="cursor: hand; cursor: pointer; float: left; height: 300px; margin: 0 10px 10px 0; width: 245px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This week I fell upon some old code I wrote back in 2006 when I was first learning Python. What a mess. I could not believe I was so proud of this code back then. &lt;br /&gt;&lt;br /&gt;I remember being very proud of the fact that each and every single method, no matter how small or how high on McCabe's cyclomatic complexity was thoroughly commented. &lt;br /&gt;&lt;br /&gt;Back then, I was told this would greatly help other developers maintain the code. Well let me tell you what, I wrote the whole darn thing myself and the comments did not help me out that much understand this code today. Talk about wasted time.&lt;br /&gt;&lt;br /&gt;Time I could have spent writing automated tests. I spent the better part of two years building a system from the ground up WITHOUT a single automated acceptance test. The system as a whole had a single class written using TDD and about two dozen unit tests ever executed on it.&lt;br /&gt;&lt;br /&gt;Did it work ? Yes. Can I prove it to you ? Probably, but with great difficulty. &lt;br /&gt;&lt;br /&gt;Would I like to maintain a system like that ? Not in a lifetime. The cold hard truth is that by the standards I have today, this code is terrible. &lt;br /&gt;&lt;br /&gt;Was I a slacker ? Not at all. Quite the other way around actually. Back then, this code was a clean as any other code I had ever seen at that point in my life. I really did work hard on making this system the best I could. I even got praised on the results.&lt;br /&gt;&lt;br /&gt;So is this blog a twisted way to tell the world I'm a better developer than I was 5 years ago ? Nope. Actually, it's a praise to the developers I've met in the past 5 years. You see, 5 years ago I was not doing any pair-programming. I spent most of my days listening to indie rock* in my cubicle while writing Python all by myself.&lt;br /&gt;&lt;br /&gt;Of course I was good. I was never challenged by anybody except when I went out of my way to get some help. Then it was back to more rock'n Python.&lt;br /&gt;&lt;br /&gt;Then I met developers who were way better than me. First they put me through code reviews. Then I was pointed towards the right books. Then those crazy guys at Pyxis showed me how to do continuous pair programming. &lt;br /&gt;&lt;br /&gt;It might seem intimidating to be constantly under the spotlight. I, for one, would never trade back the spotlight for my old cubicle. &lt;br /&gt;&lt;br /&gt;So what are you waiting for ? Step out of your cubicle and step into the light. Grab the best developer your team has to offer and ask him to work with him. You'll be surprised at how much you can learn in a single session.&lt;br /&gt;&lt;br /&gt;Who knows, you just might show him a dew things too.&lt;br /&gt;&lt;br /&gt;In the meantime, thanks to Xavier, Frank, J-F, J-S, Ben, Ernst, Patrice, J-C, the Marcouz, Vince, Bob, M-A, Carl, Nico, Phil, Monica, Cheng and all the others I have forgotten with whom I had the chance to pair with in the past few years. &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;What I know now, I owe to you.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Nick&lt;br /&gt;&lt;br /&gt;*I do admit it was a heck of a period for me music-wise, discovering the likes of Arcade Fire, the Black Keys, the Flaming Lips, Wolf Parade, DeVotchka, Interpol, Clap Your Hands Say Yeah, Bloc Party, etc. Music I still listen to today.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-8694171192266280430?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/8694171192266280430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=8694171192266280430' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8694171192266280430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8694171192266280430'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/04/agile-lessons-learned-15-step-into.html' title='Agile Lessons Learned 16 : Step Into The Light'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2069124406957370144</id><published>2011-04-01T16:15:00.000-07:00</published><updated>2011-04-01T16:26:24.369-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Gotta Love Open Source Operating Systems</title><content type='html'>Just bought a wireless adapter this week to replace my piece of junk with very low connectivity that came from the same company that provided me with the most frustrating router I've ever dealt with(I will remain polite and not state the company's name.). &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anyhow, I plugged in the USB adapter on my Ubuntu 10.10 box and lo and behold it got detected right away. So much for the proprietary stuff. &lt;br /&gt;&lt;br /&gt;Then I tried to connect to my wireless network. No-Go. Crap. Booted up the laptop. 3 minutes later I was on &lt;a href="http://ubuntuforums.org/"&gt;Ubuntu forums&lt;/a&gt; and somebody pointed me towards &lt;a href="https://bugs.launchpad.net/ubuntu/maverick/+source/linux-firmware/+bug/595455"&gt;this bug&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;One minute later I had it fixed. 5 minutes later I am publishing this blog from my Ubuntu 10.10 box. Man I just love this open source stuff. People helping each other. Having the power to fix stuff by yourself. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;I'm not a this or that, but open-source, was OUR idea.&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Nick.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2069124406957370144?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2069124406957370144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2069124406957370144' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2069124406957370144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2069124406957370144'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/04/gotta-love-open-source-operating.html' title='Gotta Love Open Source Operating Systems'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2393702552801234200</id><published>2011-02-20T05:31:00.000-08:00</published><updated>2011-03-14T20:23:31.094-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='mycellar'/><category scheme='http://www.blogger.com/atom/ns#' term='pocketcellar'/><category scheme='http://www.blogger.com/atom/ns#' term='winelog'/><category scheme='http://www.blogger.com/atom/ns#' term='wine'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Releasing PocketCellar  for Android.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-DCrb6QAnn7Q/TX7awf7uGFI/AAAAAAAAAHU/bNbuCljyjsQ/s1600/waiter.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 209px; height: 320px;" src="http://4.bp.blogspot.com/-DCrb6QAnn7Q/TX7awf7uGFI/AAAAAAAAAHU/bNbuCljyjsQ/s320/waiter.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5584141114726553682" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hey folks,&lt;br /&gt;         for the past few months some of my friends and I gathered every two weeks for a few hours around a couple of glasses of wine to learn about mobile application development. We wanted to see how the best practices we have learned in Web development could be applied in this booming platform. &lt;br /&gt;&lt;br /&gt;Along the way, we implemented a solution using of the practices we've learned from Test Driven Design(TDD/BDD) and Domain Driven Design(DDD). We had a lot of fun. It even gave birth to a small, open-source testing DSL named &lt;a href="http://code.google.com/p/loquacious-droid/"&gt;Loquacious Droid&lt;/a&gt;. It's still very rough but you get a sneak peek out here. You are invited to contribute if you find the project interesting. &lt;br /&gt;&lt;br /&gt;As our practice project we decided to develop a simple and easy to use wine application. All of us have the same issue. We go to a restaurant, try a bottle of wine, love it and then we try to remember it's name. Then we go out shopping for wine and have already forgot all the nice bottles of wine we tried to note but never got around to.&lt;br /&gt;&lt;br /&gt;Worst, we've even bought bottles of wine twice only to find out later that we had already bought it once and did not like it.&lt;br /&gt;&lt;br /&gt;We also started enjoying reviewing wines with our friends. Learning more about the different subtleties between wines is a really fun activity. However, dragging our taste logs with us proved to be too much of an hassle. Half of the time, we would forget to bring it or write our notes on a paper we would later lose. &lt;br /&gt;&lt;br /&gt;Thus came &lt;a href="http://www.mycellar.net/"&gt;PocketCellar&lt;/a&gt;. It's an Android application that we bring everywhere with us. When someone recommends a wine, we can always note it. When we buy a wine, we always have access to our list of past recommendations. It's pretty handy thus far. There is a lot more features coming up soon also !&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mycellar.net/"&gt;PocketCellar&lt;/a&gt; is a free application. You can try it our by &lt;a href="http://www.mycellar.net/"&gt;downloading it from here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Enjoy your tasting ! &lt;br /&gt;Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2393702552801234200?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2393702552801234200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2393702552801234200' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2393702552801234200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2393702552801234200'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/02/releasing-pocketcellar-for-android.html' title='Releasing PocketCellar  for Android.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-DCrb6QAnn7Q/TX7awf7uGFI/AAAAAAAAAHU/bNbuCljyjsQ/s72-c/waiter.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-6091283659706170768</id><published>2011-01-19T11:02:00.000-08:00</published><updated>2011-01-19T12:14:15.025-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='montreal'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='heroku'/><category scheme='http://www.blogger.com/atom/ns#' term='scss'/><category scheme='http://www.blogger.com/atom/ns#' term='compass'/><title type='text'>Hassle-Free Deployment of SCSS on Heroku</title><content type='html'>&lt;blockquote&gt;When working on a new application, the first deployment to staging is likely to be the most troublesome -  Jez Humble, David Farley in Continuous Delivery&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;While working on project Hibou, we decided it was high time for us to include SCSS in our stack. We quickly started using started using &lt;a href="https://github.com/chriseppstein/compass"&gt;Compass&lt;/a&gt; and thus far it has served us very well. &lt;br /&gt;&lt;br /&gt;Working on &lt;a href="http://hibou.heroku.com/"&gt;Hibou&lt;/a&gt; is currently a part-time affair for &lt;a href="http://pyxis-tech.com/en/our-team?add_tag=equipe.Sosoft"&gt;team Sosoft&lt;/a&gt;. This brings a different kind of challenge to our team. &lt;br /&gt;&lt;br /&gt;Usually, we like to deploy our changes as soon as possible in a production-like environment(daily or even more frequently). Unfortunately, we now deliver much less frequently. Maybe every few days or even only once a week. (Which might sound incredibly fast to a lot of people who are not yet using continuous delivery)&lt;br /&gt;&lt;br /&gt;After a few increments, we started noticing that we got an error message once we tried the software on our staging version deployed on &lt;a href="http://heroku.com"&gt;Heroku&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It was obvious that there was something different between our development platform and our deployed instance since none of the team members reported the issue on their development machine and we ALL have different setups.&lt;br /&gt;&lt;br /&gt;After investigation, it was discovered that our issue was caused by the fact that we now used SCSS, meaning our CSS were now generated on the server based on the SCSS files. Up to that point, we were unaware of the fact that &lt;a href="http://heroku.com"&gt;Heroku&lt;/a&gt; offered read-only disk access. Our development environement was not replicating that environement at all.&lt;br /&gt;&lt;br /&gt;For those interested, we started using the &lt;a href="https://github.com/pedro/hassle"&gt;Hassle gem&lt;/a&gt; to solve our issue.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The longer the release cycle, the longer the development team has to make incorrect assumptions before the deployment occurs, and the longer it will take to fix them -  Jez Humble, David Farley in Continuous Delivery&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;After reflection, we were really happy with that fact that although we are not working on the project as often as we would like to, we are delivering as often as we can. &lt;br /&gt;&lt;br /&gt;This really reinforces the idea that we are not done until things are deployed and in production. &lt;br /&gt;&lt;br /&gt;It also reinforces our belief that we need to ship as early as possible, and keep our feedback loop as fast as possible, no matter what we are doing. &lt;br /&gt;&lt;br /&gt;-Nicholas&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-6091283659706170768?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/6091283659706170768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=6091283659706170768' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6091283659706170768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6091283659706170768'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/01/hassle-free-deployment-of-scss-on.html' title='Hassle-Free Deployment of SCSS on Heroku'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2959940509952091848</id><published>2011-01-18T08:20:00.000-08:00</published><updated>2011-01-18T05:44:23.181-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='montreal'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='sosoft'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>AOP in Python and Ruby(Without A Framework)</title><content type='html'>This is a follow-up on my blog about &lt;a href="http://nicholaslemay.blogspot.com/2011/01/dependency-injection-in-ruby-without.html"&gt;Framework-free dependency injection in Ruby&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Alright. So you've heard of AOP and never tried it before in Ruby or Python. Or maybe you tried it in Java a few years back when it was the new buzz word using an exotic framework and quit before it ever got working.&lt;br /&gt;&lt;br /&gt;Today, I'll present a rather simple way of doing method interception or AOP using Python and Ruby.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Your application&lt;/h3&gt;&lt;br /&gt;Suppose you are in the following context:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;You are building a killer Twitter client. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;You are using a &lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;fictional&lt;/span&gt;&lt;/span&gt; MVC framework &lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;similar&lt;/span&gt;&lt;/span&gt; to Django* or Spring MVC. No Ruby on Rails** allowed :) &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Your controller methods need to return a response that the framework will process to produce the HTTP response.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Your user needs to be logged in in order to access most of the functionalities of your Web app.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;You are working on an existing App and are introducing the second method of your controller and it now looks like this :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;class TweetsController:&lt;br /&gt;&lt;br /&gt;  def display_users_tweets(self, request):&lt;br /&gt;      user = request.user&lt;br /&gt;      if not user.is_logged_in:&lt;br /&gt;          return redirection_to(login_page)&lt;br /&gt;      user_tweets = Tweets.get_all_tweets_for_this(user)&lt;br /&gt;      return rendered_template(tweets_template, using=user_tweets)&lt;br /&gt;    &lt;br /&gt;  def display_users_most_popular_tweets(self, request):&lt;br /&gt;      user = request.user&lt;br /&gt;      if not user.is_logged_in:&lt;br /&gt;          return redirection_to(login_page)&lt;br /&gt;      users_most_popular_tweets = Tweets.get_the_most_popular_tweets_for_this(user)&lt;br /&gt;      return rendered_template(most_popular_tweets_template, using=users_most_popular_tweets)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Alright. Not too bad. But in only two short methods we already have some code duplication.&lt;br /&gt;&lt;br /&gt;Then you think to yourself : "I know, I'll use my charming IDE and extract methods" and get the following result :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;class TweetsController:&lt;br /&gt;   def required_login_redirection(request):&lt;br /&gt;       if not request.user.is_logged_in:&lt;br /&gt;           return redirection_to(login_page)&lt;br /&gt;       return None&lt;br /&gt;  &lt;br /&gt;   def __user_tweets_template_rendered_for_this(self, user):&lt;br /&gt;       user_tweets = Tweets.get_all_tweets_for_this(user)&lt;br /&gt;       return rendered_template(tweets_template, using=user_tweets)&lt;br /&gt;  &lt;br /&gt;   def display_users_tweets(self, request):&lt;br /&gt;       user = request.user&lt;br /&gt;       return required_login_redirection_for(user) or self.__user_tweets_template_rendered_for_this(user)&lt;br /&gt;&lt;br /&gt;   def __most_popular_tweets_template_rendered_for_this(self, user):     &lt;br /&gt;       users_most_popular_tweets = Tweets.get_the_most_popular_tweets_for_this(user)&lt;br /&gt;       return rendered_template(most_popular_tweets_template, using=users_most_popular_tweets)&lt;br /&gt;  &lt;br /&gt;   def display_users_most_popular_tweets(self,request):&lt;br /&gt;       user = request.user&lt;br /&gt;       return required_login_redirection_for_this(user) or self.__most_popular_tweets_template_rendered_for_this(user)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is much cleaner. We have encapsulated the redirection verification logic responsibility in a single method.&lt;br /&gt;&lt;br /&gt;This work pretty well for our simple case. But what if we had more calls in the controller methods ? What would we do then ?&lt;br /&gt;&lt;br /&gt;The issue with what we did is, we did not attack the problem from its root.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;Requiring the user to be logged in is a precondition for executing this method. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then, wouldn't it be nice to be able to require the user to be logged in &lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;prior&lt;/span&gt;&lt;/span&gt; to a single line of code being executed in each of these methods ?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;AOP and Python decorators to the rescue&lt;/h3&gt;&lt;br /&gt;This is one of the times when AOP, method interception, wrapper methods or decorators come in handy.&lt;br /&gt;&lt;br /&gt;Remember the days when we had comments like these on top of our functions ?&lt;br /&gt;/*******************************************&lt;br /&gt;* Pre-condition : x most be a positive int&lt;br /&gt;********************************************/&lt;br /&gt;&lt;br /&gt;Wouldn't it be nice if you could replace all of this dead text with&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt; executable&lt;/span&gt;&lt;/span&gt; code ?&lt;br /&gt;&lt;br /&gt;With Python, you can do so by using decorators.&lt;br /&gt;&lt;br /&gt;Your controller would then end up looking like this :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;class TweetsController:&lt;br /&gt;  @requires_user_to_be_logged_in&lt;br /&gt;  def display_users_tweets(self, request):&lt;br /&gt;      user_tweets = Tweets.get_all_tweets_for_this(user)&lt;br /&gt;      return rendered_template(tweets_template, using=user_tweets)&lt;br /&gt;&lt;br /&gt;  @requires_user_to_be_logged_in&lt;br /&gt;  def display_users_most_popular_tweets(self,request):&lt;br /&gt;      users_most_popular_tweets = Tweets.get_the_most_popular_tweets_for_this(user)&lt;br /&gt;      return rendered_template(most_popular_tweets_template, using=users_most_popular_tweets)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Wow. Me likes that ! If you've never written a decorator in Python here is a quick tutorial on how I wrote this decorator.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Python decorator example&lt;/h3&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;def requires_user_to_be_logged_in(function):&lt;br /&gt;    def requires_user_to_be_logged_in_wrapper(self,request, *args, **keyWordArgs):&lt;br /&gt;      if request.user.is_logged_in:&lt;br /&gt;          return function(self,request, *args, **keyWordArgs)&lt;br /&gt;      return redirection_to(login_page)&lt;br /&gt;    return requires_user_to_be_logged_in_wrapper  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Some explanation :&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The first method requires_user_to_be_logged_in is the decorator itself.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;That method receives the function that it decorates as its sole parameter&lt;/li&gt;&lt;br /&gt;&lt;li&gt;requires_user_to_be_logged_in_wrapper is an inner function that receives the parameter with whom the original method was called&lt;/li&gt;&lt;br /&gt;&lt;li&gt;If you look at the return statements, you can see that we alter the return value of the original method only if the user is not logged in; otherwise, the original method is called exactly as if called without decoration since the precondition&lt;br /&gt;was respected&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;AOP and decorators in Ruby&lt;/h3&gt;&lt;br /&gt;Alright. Now that we have seen how cool implementing a decorator in Python is, let's see how we could do this in Ruby.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;class TweetsController&lt;br /&gt;&lt;br /&gt;  def display_tweets&lt;br /&gt;    puts "tweet tweet tweet"&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def display_users_most_popular_tweets&lt;br /&gt;     display_tweets&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  display_users_most_popular_tweets = requires_login(:display_users_most_popular_tweets)&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the above example, we simply take the display_users_most_popular_tweets function, and reassign it to the original method decorated by the requires_login function.&lt;br /&gt;&lt;br /&gt;How do we decorate the method ?&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;def requires_login(func_name)&lt;br /&gt;  old_method = instance_method(func_name)&lt;br /&gt;    define_method(func_name) do |*args|&lt;br /&gt;      if user_is_logged_in&lt;br /&gt;        old_method.bind(self).call(*args)&lt;br /&gt;      else&lt;br /&gt;        redirect_to_login_page&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Just like in the Python example, we use an if statement to see whether or not not we need to do a redirection. If not, we call the original method using the same parameters it was originally called with. Otherwise we override the call completely and call the redirect_to_login_page method.&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay. &lt;br /&gt;&lt;br /&gt;* Of course if you are using Django you already know about the very useful @login_required decorator. &lt;br /&gt;&lt;br /&gt;** If you are using Rails, you could use the kick-ass before_filter in your controller and apply the requirement to be logged in to the proper controller methods.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2959940509952091848?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2959940509952091848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2959940509952091848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2959940509952091848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2959940509952091848'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/01/aop-in-python-and-rubywithout-framework.html' title='AOP in Python and Ruby(Without A Framework)'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-8357748983510774060</id><published>2011-01-13T05:29:00.000-08:00</published><updated>2011-01-13T05:59:50.355-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='montreal'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='sosoft'/><title type='text'>Montreal's Ruby Community and Team Sosoft</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.montrealonrails.com/"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 127px; height: 90px;" src="http://3.bp.blogspot.com/_vJCcAtCDEM8/TS8CZVq0P2I/AAAAAAAAAG0/X5lLOhCJObk/s200/montrealrb.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5561666699162566498" /&gt;&lt;/a&gt;&lt;br /&gt;Are you or someone you know looking for Ruby developers but have a hard time finding quality developers ?&lt;br /&gt;&lt;br /&gt;Have you been looking to move from Java, PHP or Python to Ruby, but have yet to find someone to take the lead within your team ?&lt;br /&gt;&lt;br /&gt;Maybe you're just looking for a team to develop your kick-ass Web App idea and have heard Rails could help you get done faster ?&lt;br /&gt;&lt;br /&gt;Next Tuesday at the Crim in Montreal will be held the &lt;a href="http://www.montrealonrails.com/2011/01/ruby-developer-crisis/"&gt;next monthly meetup of Montreal.Rb&lt;/a&gt;. The theme of the event ? The Montreal Ruby developer crisis. Apparently, people are on the search for Ruby/Rails developers and have a hard time finding them.&lt;br /&gt;&lt;br /&gt;Well guess what ? A bunch of developers from Montreal's Ruby community will be there. I'll be joined with the rest of team Sosoft(&lt;a href="http://pyxis-tech.com/fr/notre-equipe/vincent-tence"&gt;Vincent Tencé&lt;/a&gt;, &lt;a href="http://pyxis-tech.com/fr/notre-equipe/xavier-to"&gt;Xavier&lt;/a&gt;, &lt;a href="http://pyxis-tech.com/fr/notre-equipe/eric-mignot"&gt;Éric Mignot&lt;/a&gt; and &lt;a href="http://pyxis-tech.com/fr/notre-equipe/marc-andre-thibodeau"&gt;Marc-André&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Have an interest in Ruby ? Come on Tuesday night and have a talk with us !&lt;br /&gt;&lt;br /&gt;ps: Bien que toutes les communications sur Montreal.Rb soient en anglais, il y a beaucoups de conversation à y avoir la bas avec des francophones comme moi. Alors venez en grand nombre ! &lt;br /&gt;&lt;br /&gt;If you can't make it there and would want to have a talk with us, you can always &lt;a href="mailto:sosoft@pyxis-tech.com"&gt;reach us here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;- Nicholas&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-8357748983510774060?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/8357748983510774060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=8357748983510774060' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8357748983510774060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8357748983510774060'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/01/montreal-ruby-community-and-team-sosoft.html' title='Montreal&apos;s Ruby Community and Team Sosoft'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_vJCcAtCDEM8/TS8CZVq0P2I/AAAAAAAAAG0/X5lLOhCJObk/s72-c/montrealrb.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-6850176773278286371</id><published>2011-01-12T09:07:00.001-08:00</published><updated>2011-01-12T10:24:00.704-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='montreal'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='sosoft'/><category scheme='http://www.blogger.com/atom/ns#' term='backlog'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Finally, the Solution For a Bug Free Backlog(part 3)</title><content type='html'>&lt;a href="http://pyxis-tech.com/docs/4c8e27d01a692/source/mszablowski.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img border="0" alt="" src="http://pyxis-tech.com/docs/4c8e27d01a692/source/mszablowski.png" style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 595px; height: 195px;"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is a question I received from Etienne &lt;a href="http://nicholaslemay.blogspot.com/2010/12/finally-solution-for-bug-free.html"&gt;in part 2&lt;/a&gt;.&lt;br /&gt;&lt;blockquote&gt;"But when there's a problem with the behavior of a New Feature, how do you call that?"&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;It depends. When talking about a new feature, my guess is that you are talking about a feature that has yet to have been released.&lt;br /&gt;&lt;br /&gt;In that case, even when using the bug type in a backlog, I would never raise a bug on a feature that has yet to have been released. The feature is not delivered, thus the bug is simply remaining work that has yet to have been addressed in order to be able to deliver the feature. &lt;br /&gt;&lt;br /&gt;In that case, I would either add the details of the strange behavior in one of the existing tasks or create a new task to the story related to this behavior. &lt;br /&gt;&lt;br /&gt;One strange thing that I have seen being done was team members raising a bug mid-sprint to be fixed later in the sprint or in another sprint(!) for a feature that got broke by the development of a new feature.&lt;br /&gt;&lt;br /&gt;Why people would do this is beyond me. This is &lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;allowing the software to regress on purpose !&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I would rather follow the &lt;a href="http://en.wikipedia.org/wiki/Primum_non_nocere"&gt;Primum non nocere(first do no harm)&lt;/a&gt; maxim that is used in medicine. &lt;br /&gt;&lt;br /&gt;Ideally, introducing a new feature should never make the software regress. At least not on purpose. Of course, there will always be times unwanted behavior is introduced without us knowing.&lt;br /&gt;&lt;br /&gt;As always, having a fully automated test suite goes a long way in making it much easier for a team to discover the regression they are introducing as they go along and to make adjustments along the path.&lt;br /&gt;&lt;br /&gt;I'll be back soon with more feedback on how we are using our bug free backlog within &lt;a href="http://pyxis-tech.com/fr/notre-equipe?add_tag=equipe.Sosoft"&gt;team Sosoft&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Feel free to give us your feedback on our approach. Maybe we're just a bunch of loonies after all :)&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-6850176773278286371?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/6850176773278286371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=6850176773278286371' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6850176773278286371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6850176773278286371'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/01/finally-solution-for-bug-free.html' title='Finally, the Solution For a Bug Free Backlog(part 3)'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7757830157208565378</id><published>2011-01-10T07:21:00.000-08:00</published><updated>2011-01-10T08:18:23.743-08:00</updated><title type='text'>I Love The Web</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_vJCcAtCDEM8/TSsxPZW53dI/AAAAAAAAAGg/QsmDPKq8Tl0/s1600/map.jpeg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 86px;" src="http://4.bp.blogspot.com/_vJCcAtCDEM8/TSsxPZW53dI/AAAAAAAAAGg/QsmDPKq8Tl0/s200/map.jpeg" border="0" alt=""id="BLOGGER_PHOTO_ID_5560592305493761490" /&gt;&lt;/a&gt;&lt;br /&gt;This morning, I was looking at my Google Analytics report. Out of curiosity, I went into the map overlay section to see where the visitors came from. &lt;br /&gt;&lt;br /&gt;This made me realize that people from 91 different countries have read my blog. I think this is bloody awesome ! I just love the Web. Many thanks to all of have read my blog thus far. I hope I make it worth your while.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-Nicholas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7757830157208565378?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7757830157208565378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7757830157208565378' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7757830157208565378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7757830157208565378'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/01/i-love-web.html' title='I Love The Web'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_vJCcAtCDEM8/TSsxPZW53dI/AAAAAAAAAGg/QsmDPKq8Tl0/s72-c/map.jpeg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2092596550763558653</id><published>2011-01-06T11:14:00.000-08:00</published><updated>2011-01-06T16:20:29.202-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='guice'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Dependency Injection in Ruby Without a Framework</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm5.static.flickr.com/4012/4260909316_7d1a3127f1.jpg"&gt;&lt;img style="float: left; margin: 0pt 10px 10px 0pt; cursor: pointer; width: 250px; height: 166px;" src="http://farm5.static.flickr.com/4012/4260909316_7d1a3127f1.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Lately,&lt;br /&gt;     I've been toying around with native Android application development using Java. &lt;br /&gt;&lt;br /&gt;It got me hooked on using &lt;a href="http://code.google.com/p/roboguice/"&gt;RoboGuice&lt;/a&gt; and &lt;a href="http://code.google.com/p/google-guice/"&gt;Google Guice&lt;/a&gt;. Coming from a dynamic language background, it got me thinking as to why I never felt the need for a &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;dependency injection&lt;/a&gt; framework before. Guess what? Ruby and Python both come with their own built-in dependency injection framework! Heresy? &lt;br /&gt;&lt;br /&gt;Well let's check out this small example and see if it's the case or not. &lt;br /&gt;&lt;br /&gt;Let's say you have a small application that allows you to display all the books present in your database.&lt;br /&gt;&lt;br /&gt;Let's say your Book class looks a little something like this : &lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;class Book&lt;br /&gt;  attr_reader :title, :author&lt;br /&gt;&lt;br /&gt;  def initialize(title, author)&lt;br /&gt;    @title = title&lt;br /&gt;    @author = author&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and that the class that allows you to visualize your Books looks a little something like this :&lt;br /&gt; &lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;class VisualBookListing&lt;br /&gt;&lt;br /&gt;  def initialize(booksCollection = RubyBooksCollection)&lt;br /&gt;      @books_collection = booksCollection.new&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def display&lt;br /&gt;    @books_collection.get_all_books.each{ |book| &lt;br /&gt;      puts "%s written by : %s " %[book.author, book.title]&lt;br /&gt;    }  &lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;By using RubyBooksCollection as the default parameter value, it becomes the default implementation of the BooksCollection your BookListing's class is expecting to receive. &lt;br /&gt;&lt;br /&gt;This would take the place of the following line you would often see in a Google Guice module &lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;bind(BooksCollection.class).to(RubyBooksCollection.class);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Although, unlike in Java, you do not have the advantages and disadvantages associated with the declaration of your interface. &lt;br /&gt;&lt;br /&gt;Unfortunately, the default implementation of our RubyBooksCollection is this : &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;class RubyBooksCollection&lt;br /&gt;&lt;br /&gt;  def get_all_books&lt;br /&gt;    return Database.get_ruby_books&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When we'll want to write a unit test for our VisualBookListing, this means we'll have to setup a database. Our test is now an integrated instead of being a unit test.&lt;br /&gt;&lt;br /&gt;Our VisualBooksListing could not care less whether or not our data comes from a database, a text file or holy intervention. &lt;br /&gt;&lt;br /&gt;Plus we get the hassle of setting up a database with the added bonus of making our test slower. &lt;br /&gt;&lt;br /&gt;What to do then ? One solution could be to write a mocked BooksCollection to use instead of our RubyBooksCollection. It should be pretty easy to pass around since the dependency is injected through the constructor. &lt;br /&gt;&lt;br /&gt;How could we do this ? You could use one of the many awesome mocking framework. Here's an example I came up with without the use of any framework : &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;class MockedBooksCollection&lt;br /&gt;   def get_all_books&lt;br /&gt;      growing_object_oriented_software = Book.new "Growing OO Software", "Steve Freeman"&lt;br /&gt;      domain_driven_design = Book.new "Domain Driven Design", "Eric Evans"&lt;br /&gt;      return [growing_object_oriented_software, domain_driven_design]&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In your test, you would simply do assertions based on the result of this call to the VisualBookListing : &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;testBookListingDisplay = VisualBookListing.new library = MockedBooksCollection&lt;br /&gt;testBookListingDisplay.display&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;whereas in prod, you would do a little something like this&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;productionBookListing = VisualBookListing.new&lt;br /&gt;productionBookListing.display&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This make it a little simpler than with &lt;a href="http://code.google.com/p/google-guice/"&gt;Guice&lt;/a&gt;, where you would have to create a new context for your tests**. &lt;br /&gt;&lt;br /&gt;So there you go, &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;dependency injection&lt;/a&gt; in Ruby, without the need for a framework, and all the added benefits.&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay of &lt;a href="mailto:sosoft@pyxis-tech.com"&gt;team Sosoft&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;**If you are interested, there is a nice little library called &lt;a href="http://code.google.com/p/mycila/wiki/MycilaTesting"&gt;MycilaTesting&lt;/a&gt; written by &lt;a href="http://code.google.com/u/mathieu.carbou/"&gt;Mathieu Carbou&lt;/a&gt; that facilitates testing context creation. The syntax of the tests produced look a little like this : &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;@GuiceContext(LibraryTests.LibraryTestsModule.class)&lt;br /&gt;public class LibraryTests extends MycilaJunit4Test{&lt;br /&gt;&lt;br /&gt;        @Inject SomeLibraryDependency someLibraryDependency;&lt;br /&gt;        //You write your tests here &lt;br /&gt;          &lt;br /&gt;        public static final class LibraryTestsModule extends AbstractModule {&lt;br /&gt;        &lt;br /&gt;            protected void configure() {                        &lt;br /&gt;                bind(SomeLibraryDependency.class).to(MockedLibraryDependency.class);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2092596550763558653?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2092596550763558653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2092596550763558653' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2092596550763558653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2092596550763558653'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2011/01/dependency-injection-in-ruby-without.html' title='Dependency Injection in Ruby Without a Framework'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4012/4260909316_7d1a3127f1_t.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-3365561805615042952</id><published>2010-12-23T13:00:00.000-08:00</published><updated>2012-01-24T17:27:06.523-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Finally, the Solution For a Bug Free Backlog(part 2)</title><content type='html'>&lt;a href="http://pyxis-tech.com/docs/4c8e27d01a692/source/mszablowski.png"&gt;&lt;img alt="" border="0" src="http://pyxis-tech.com/docs/4c8e27d01a692/source/mszablowski.png" style="cursor: pointer; float: left; height: 195px; margin: 0pt 10px 10px 0pt; width: 595px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's a follow up to &lt;a href="http://nicholaslemay.blogspot.com/2010/12/finally-solution-for-bug-free-backlog.html"&gt;part 1 of this series.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We've decided to keep only these two types of issues in our backlog : &lt;br /&gt;&lt;br /&gt;- New Feature &lt;br /&gt;- Improvement.&lt;br /&gt;&lt;br /&gt;A new feature can be either a new story or even something people might see as a "bug".&lt;br /&gt;&lt;br /&gt;The whole discussion stemmed from two broken links at the base of &lt;a href="https://github.com/testinfected/hibou"&gt;our Hibou webapp&lt;/a&gt;. We had 0 test for these. None. &lt;br /&gt;&lt;br /&gt;They were added in a rush in the footer of our web page at the end of &lt;a href="http://www.codapalooza.com/"&gt;Codapalooza&lt;/a&gt;. And I mean really, how many people do you know who have written tests for a link towards your companies website and your team's website.&lt;br /&gt;&lt;br /&gt;Well guess what ? The only part of the whole app we did not test was broken as hell and nobody knew.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;A quick reflex would have been to raise a bug, fix the bug and close the issue.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We had a discussion and tried to push things forward. Why didn't we have a test for this ? What were we trying to accomplish by adding these two links ? &lt;br /&gt;&lt;br /&gt;This got us thinking in a logical manner and we figured out that these two links were actually a feature. &lt;br /&gt;&lt;br /&gt;We had added these link as a marketing feature in order to promote our team and company.&lt;br /&gt;&lt;br /&gt;We then took the bug and wrote a story that looked a little like this :  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;As a marketer, I would like to see marketing of our organization and team throughout our website in order to promote our team.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Having a story, we can then sit down with our marketing buddy, fiund out what his real needs are and then develop the feature accordingly. All of this using TDD/BDD of course.&lt;br /&gt;&lt;br /&gt;What do we use improvements for ? I'll let you know in a little while. &lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-3365561805615042952?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/3365561805615042952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=3365561805615042952' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/3365561805615042952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/3365561805615042952'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/12/finally-solution-for-bug-free.html' title='Finally, the Solution For a Bug Free Backlog(part 2)'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-5316438288778093192</id><published>2010-12-22T06:56:00.000-08:00</published><updated>2012-01-24T17:29:10.357-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='backlog'/><title type='text'>Finally,  the Solution For a Bug Free Backlog</title><content type='html'>&lt;a href="http://pyxis-tech.com/docs/4c8e27d01a692/source/mszablowski.png"&gt;&lt;img alt="" border="0" src="http://pyxis-tech.com/docs/4c8e27d01a692/source/mszablowski.png" style="cursor: pointer; float: left; height: 185px; margin: 0pt 10px 10px 0pt; width: 595px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This morning, I found a little bug in our Ruby on Rails app code-named &lt;a href="https://github.com/testinfected/hibou"&gt;Hibou&lt;/a&gt; that we developped as &lt;a href="http://codapalooza.com/teams/pyxis-sosoft/"&gt;team sosoft&lt;/a&gt; during &lt;a href="http://www.codapalooza.com/"&gt;Codapalooza&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Business as usual right ? I fired up Jira and added a new issue in our GreenHopper backlog. Done. I went back to my mails.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pyxis-tech.com/en/our-team/eric-mignot"&gt;Eric&lt;/a&gt; then came over and we had a talk. He suggested that I not only remove the bug from our backlog, but that we remove the bug type entirely from our project.&lt;br /&gt;&lt;br /&gt;I was a bit dumbfounded. More talk ensued.&lt;br /&gt;&lt;br /&gt;Guess what ? &lt;span style="font-weight: bold;"&gt; A few minutes later, he had me convinced and we did remove bugs entirely from our backlog&lt;/span&gt;. Wondering why we did this ? Wondering how we will keep track of the bugs found by our users ? Wondering how we will keep track of the bugs being fixed ? You think we're loonies ?&lt;br /&gt;&lt;br /&gt;Well I don't feel like giving away all the answers now. If you guys are interested, let's continue this conversation and see where we end up.&lt;br /&gt;&lt;br /&gt;- Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-5316438288778093192?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/5316438288778093192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=5316438288778093192' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5316438288778093192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5316438288778093192'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/12/finally-solution-for-bug-free-backlog.html' title='Finally,  the Solution For a Bug Free Backlog'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-5523585069916931233</id><published>2010-11-18T12:35:00.001-08:00</published><updated>2012-01-25T04:47:07.486-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Miller</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#1095939775_RCRuW"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/DSC0206/1095939775_RCRuW-M.jpg" style="cursor: hand; display: block; float: left; height: 450px; margin: 0px auto 10px; text-align: cursor:pointer; width: 355px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-5523585069916931233?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/5523585069916931233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=5523585069916931233' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5523585069916931233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5523585069916931233'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/11/miller.html' title='Miller'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2749070566980940223</id><published>2010-11-18T12:30:00.000-08:00</published><updated>2012-01-25T04:47:19.753-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Number 8</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#1095940485_9qXVU"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/DSC0038/1095940485_9qXVU-M.jpg" style="cursor: hand; cursor: pointer; display: block; float: left; height: 450px; margin: 0px auto 10px; text-align: center; width: 299px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2749070566980940223?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2749070566980940223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2749070566980940223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2749070566980940223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2749070566980940223'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/11/number-8.html' title='Number 8'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-8636600814458643363</id><published>2010-11-16T11:57:00.001-08:00</published><updated>2010-11-16T12:00:43.674-08:00</updated><title type='text'>Overheard at a hockey game.</title><content type='html'>&lt;blockquote&gt;&lt;br /&gt;Dad, isn't Alex Ovechkin the greatest hockey player in the world ?&lt;br /&gt;Yeah son, I think he is.&lt;br /&gt;Then why are all these people booing him dad ?&lt;br /&gt;Because he's the greatest player in the world son.&lt;br /&gt;Touché.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Nick&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-8636600814458643363?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/8636600814458643363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=8636600814458643363' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8636600814458643363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8636600814458643363'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/11/overheard-at-hockey-game.html' title='Overheard at a hockey game.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-9183380631570009165</id><published>2010-11-09T17:16:00.001-08:00</published><updated>2012-01-26T05:06:23.756-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Agile Lessons Learned #15 : Coding Poetry</title><content type='html'>&lt;blockquote&gt;A person who won't read has no advantage over one who can't read. - Mark Twain &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Following &lt;a href="http://www.dalouche.com/wordpress/2010/10/20/are-your-skills-up-to-date/"&gt;Sami's post on developer's skills&lt;/a&gt;, I will be following up today with a skill that is usually underestimated when people think of the &lt;a href="http://pyxis-tech.com/en/expertise"&gt;skills to look for in a developer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;When I first took up programming, I was told I needed to be great in math. Fine. How about vocabulary ? Writing skills ? Wait. Knowledge of the English language ?  What does that have to do with talking to a computer ?&lt;br /&gt;&lt;br /&gt;Having been involved in the writing of &lt;a href="http://en.wikipedia.org/wiki/Enterprise_software"&gt;enterprise applications&lt;/a&gt; for the past few years, it is my belief that these are skills that will deeply affect a developer's value within a team.&lt;br /&gt;&lt;br /&gt;Not sure yet ? Alright here we go with a few examples :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;An example in data modeling&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Let's say you are building a fairly simple system to manage a library. How would you call the artifacts found in the &lt;span style="font-style: italic;"&gt;library&lt;/span&gt; ?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Books&lt;/span&gt; right ?  Hmm..How about &lt;span style="font-family: 'courier new'; font-size: 85%; font-weight: bold;"&gt;magazines&lt;/span&gt; ? &lt;span style="font-family: 'courier new'; font-size: 85%; font-weight: bold;"&gt;Newspapers&lt;/span&gt; ? You might be tempted to introduce an abstract concept like a &lt;span style="font-family: 'courier new'; font-size: 85%; font-weight: bold;"&gt;document&lt;/span&gt;. Wait. How about &lt;span style="font-family: 'courier new'; font-size: 85%; font-weight: bold;"&gt;movies&lt;/span&gt; and &lt;span style="font-family: 'courier new'; font-size: 85%; font-weight: bold;"&gt;audio tapes&lt;/span&gt; ?&lt;br /&gt;&lt;br /&gt;After a while someone comes out of the blue and proposes to call it a &lt;span style="font-family: 'courier new'; font-size: 85%; font-weight: bold;"&gt;Published Work&lt;/span&gt; since everything in the library is a work that has been published in some sort of media. And then two weeks later nobody working on the system or using it can understand what the hell a work is.&lt;br /&gt;&lt;br /&gt;Inspired by &lt;a href="http://pyxis-tech.com/en/expertise/domain-driven-design-ddd"&gt;Domain Driven Design &lt;/a&gt; I would recommend you checkout how to build a &lt;a href="http://jamesshore.com/Agile-Book/ubiquitous_language.html"&gt;ubiquitous language&lt;/a&gt; that serves all the people involved in the&amp;nbsp;use or construction of the software.&lt;br /&gt;&lt;br /&gt;To do so, however, requires people to have a deep enough vocabulary to know which concept to propose, understand the meaning and power of certain word. They can then build &amp;nbsp;a dictionary of what these terms mean in the context of the application they are concerned with.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;The choice of a programming language influences expressibility&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ideally, one would pick out languages that favors an expressibility that is very close to the native language.&lt;br /&gt;&lt;br /&gt;Let's say that I want a program that gives me the following result :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;The sorted list of names, in upper case, for all the names in the list that are longer than 5 characters long. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(I recommend you read the above statement 3 times in your head )&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Then read this Python snippet out loud&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;sorted(name.inUpperCase() for name in listOfNames if lengthOf(name) &amp;gt; 5)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Doesn't it just sound like a sentence ? Or how about this Ruby example :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: ruby"&gt;5.times { print "Hurray!" }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Don't these two examples sound like something most people could understand and maintain ? Even a non-programmer could get what this code does.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Mold&amp;nbsp;your design to express the domain.&amp;nbsp;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Here is an example of how your level of English expressiveness influences the quality of your solution.&lt;br /&gt;&lt;br /&gt;Using&amp;nbsp;&lt;a href="http://docs.djangoproject.com/en/dev/topics/db/models/"&gt;Django's models&lt;/a&gt;&amp;nbsp;as an example&lt;br /&gt;&lt;br /&gt;Would you prefer to have to maintain this code&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;Publications.objects.all().filter(author__name="George Orwell")&lt;br /&gt;#over this code :&lt;br /&gt;Library.get_all_book_written_by(georgeOrwell)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;My guess is most of us would pick #2. Yet both examples are valid. The second one is simply more expressive.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;Orthography&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Doesn't it just distract you when you see a bunch of orthographic mistakes in your code ?&lt;br /&gt;&lt;br /&gt;Seeing&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;user.getInWitchNightborhoodHesBorn()&lt;br /&gt;//instead of&lt;br /&gt;user.getNeighborhoodInWhichHeWasBorn()&lt;br /&gt;//is just distracting&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We would do a great service to our fellow colleagues if we'd take time to review our code properly and make sure it contains as few orthographic errors as possible. Modern IDE's like Rubymine and IntelliJ can greatly help warn you of your typos.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;Not knowing the natural language in which the software is developed can lead to weird code &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Just for laughs, never underestimate the humor that can come out when someone is coding in a language he does not master, especially when it's not his native tongue.&lt;br /&gt;&lt;br /&gt;I have once seen this code written in Java :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: ruby"&gt;private PartsHandler _ph;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Needless to say, our &lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;"private parts handler"&lt;/span&gt;&lt;/span&gt; did not have a long life in our system :)&lt;br /&gt;&lt;br /&gt;Hopefully, I've given some of you the interest in improving your skills. Guess what ? Part of the reason for me writing these long blog posts is just me wanting to improve my writing skills.&lt;br /&gt;&lt;br /&gt;Nicholas Lemay.&lt;br /&gt;&lt;br /&gt;References :&lt;br /&gt;&lt;a href="http://www.pyxis-tech.com/en/expertise"&gt;Agile expertise&lt;/a&gt; from Pyxis.&lt;br /&gt;&lt;a href="http://gettingreal.37signals.com/ch08_Wordsmiths.php"&gt;Getting Real&lt;/a&gt; by 37 signals&lt;br /&gt;&lt;a href="http://trempet.uqam.ca/Enseignement/Cours/inf5151/Hiver2008/NotesdeCours/MODULE%20No%2002-2008.htm"&gt;Qu'est-ce qu'un livre ?&lt;/a&gt; by Ivan Maffezzini&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-9183380631570009165?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/9183380631570009165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=9183380631570009165' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9183380631570009165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9183380631570009165'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/11/agile-lessons-learned-14-coding-poetry.html' title='Agile Lessons Learned #15 : Coding Poetry'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-285148031960444836</id><published>2010-11-08T06:31:00.000-08:00</published><updated>2010-11-08T06:34:35.970-08:00</updated><title type='text'>Interesting Quote I Heard Recently</title><content type='html'>"ALL ANIMALS ARE EQUAL, BUT SOME ARE MORE EQUAL THAN OTHERS"&lt;br /&gt;- George Orwell, Animal Farm&lt;br /&gt;&lt;br /&gt;"The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which."&lt;br /&gt;- George Orwell, Animal Farm&lt;br /&gt;&lt;br /&gt;"Don't be so gloomy. After all it's not that awful. Like the fella says, in Italy for 30 years under the Borgias they had warfare, terror, murder, and bloodshed, but they produced Michelangelo, Leonardo da Vinci, and the Renaissance. In Switzerland they had brotherly love - they had 500 years of democracy and peace, and what did that produce? The cuckoo clock." &lt;br /&gt;&lt;br /&gt;Orson Welles in the Third Man.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-285148031960444836?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/285148031960444836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=285148031960444836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/285148031960444836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/285148031960444836'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/11/interesting-quote-i-heard-recently.html' title='Interesting Quote I Heard Recently'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-6631781725303254977</id><published>2010-10-14T12:17:00.000-07:00</published><updated>2010-10-14T12:19:18.086-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='quote'/><title type='text'>You can quote me on that one.</title><content type='html'>&lt;blockquote&gt;Instead of trying to figure out how much software we can build, maybe we should ask ourselves how little software we really need. &lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-6631781725303254977?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/6631781725303254977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=6631781725303254977' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6631781725303254977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6631781725303254977'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/10/you-can-quote-me-on-that-one.html' title='You can quote me on that one.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-6523417640458335440</id><published>2010-10-13T09:17:00.000-07:00</published><updated>2010-10-13T09:19:27.640-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Giant Shrooms</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#1042949042_8qkMY"&gt;&lt;img style="display:block; margin:0px auto 10px; float:left;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/DSC0662/1042949042_8qkMY-S.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-6523417640458335440?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/6523417640458335440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=6523417640458335440' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6523417640458335440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6523417640458335440'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/10/giant-shrooms.html' title='Giant Shrooms'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2355964486272434989</id><published>2010-10-08T05:43:00.000-07:00</published><updated>2012-01-26T04:58:48.221-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='opinion'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><title type='text'>Agile Lessons Learned #14 : Craftsmanship</title><content type='html'>&lt;blockquote&gt;War is too important a matter to be left to the military. - Georges Clemenceau&lt;/blockquote&gt;&lt;br /&gt;In between college and university, I spent a couple of years working for a major truck leasing company. I was mostly surrounded by passionate individuals who were specialized as diesel service technicians.&lt;br /&gt;&lt;br /&gt;Most of the time, I heard nothing but compliments from the drivers who enjoyed the extra care these technicians took. They knew that it was this care that kept them out of the trouble on the long roads.  They had a pretty good trust relationship going on.&lt;br /&gt;&lt;br /&gt;Once I entered the IT business however, I experienced something completely different. People cutting corner wasn't even considered special. It's actually pretty much the norm of the industry from what I have experienced thus far. Things seem to have gotten so out of control, that you can expect from day to day to  be asked by someone to botch your job in order to meet some ludicrous demands.  Why is that so ?&lt;br /&gt;&lt;br /&gt;Is building quality software so unimportant ? The billions of dollars spent annually worldwide on developing software seem to say that at least a few people do need properly built software.&lt;br /&gt;&lt;br /&gt;Is software so easy to build that anyone, anywhere can tell you how to build it properly ? I have serious doubt about that.&lt;br /&gt;&lt;br /&gt;I see many people practicing mechanics, plumbing or electricity during the week-end. While not easy, we could at least say these are activity are at accessible degree of difficulty to most people. Whereas I know much fewer people taking up programming as a pastime. I also full well that the turnover rate in school is pretty high is computer science.&lt;br /&gt;&lt;br /&gt;Funny things is, I have yet to meet someone who would readily tell a mechanics not to fasten his bolts properly because he is short on time. I have never see  someone tell his plumber not to cut the water before plugging in the the new dishwasher.&lt;span style="font-style: italic; font-weight: bold;"&gt; &lt;/span&gt;I have sure as hell never seen anyone tell the electrician to leave the electricity on while he's doing his job.&lt;br /&gt;&lt;br /&gt;Then why is it that so many managers, clients or other project stakeholders feel the need to tell developers how to do their job ? Worst, why is is that so many of us, think we are expected to say yes to these ludicrous demands ?&lt;br /&gt;&lt;br /&gt;Georges Clemenceau was once quoted as saying that &lt;span style="font-style: italic;"&gt;"War was too important a matter to be left to the military&lt;/span&gt;". I think software development is too important a matter to be left up to people who do not know a single thing about it. I truly hope the software community can take matter into their own hands and try to fix this situation. We need to become professionals now, so that we can be viewed and recognized as professionals in the future.&lt;br /&gt;&lt;br /&gt;That's why I'm very pleased to see movements like the &lt;a href="http://manifesto.softwarecraftsmanship.org/"&gt;software craftsmanship movement&lt;/a&gt;&amp;nbsp;that tries to raise the level of professionalism in our industry. I also think the&amp;nbsp;&lt;a href="http://agilemanifesto.org/"&gt;Agile movement &lt;/a&gt;will improve the bond between the professions involved in developing software.&lt;br /&gt;&lt;br /&gt;We are all in this together after all.&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;br /&gt;&lt;br /&gt;For more on the subject, I would highly recommend &lt;a href="https://sites.google.com/site/unclebobconsultingllc/books"&gt;Uncle Bob's Clean Coder book&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2355964486272434989?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2355964486272434989/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2355964486272434989' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2355964486272434989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2355964486272434989'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/10/agile-lessons-learned-12-craftsmanship.html' title='Agile Lessons Learned #14 : Craftsmanship'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4691564170240563836</id><published>2010-09-27T10:46:00.000-07:00</published><updated>2010-09-27T10:50:01.363-07:00</updated><title type='text'>I'll be presenting @Agile Tour 2010 in Montreal.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.agiletour.org/fr/programme-conference-agile-tour-2010-montreal.html#simulationscrumavecprototypagepapier"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 255px; height: 121px;" src="http://www.agiletour.org/sites/default/files/AT2010_resources/at2010speaker.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Further details to come. In the meantime, you can read the &lt;a href="http://www.agiletour.org/fr/programme-conference-agile-tour-2010-montreal.html#simulationscrumavecprototypagepapier"&gt;description here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4691564170240563836?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4691564170240563836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4691564170240563836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4691564170240563836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4691564170240563836'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/09/ill-be-presenting-agile-tour-2010-in.html' title='I&apos;ll be presenting @Agile Tour 2010 in Montreal.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7366108636851949098</id><published>2010-09-20T15:08:00.000-07:00</published><updated>2010-09-22T17:28:24.305-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Automating your HTML validation using PyQuery is Awesome.</title><content type='html'>I've recently started including view tests in my TDD/BDD pratice. &lt;br /&gt;&lt;br /&gt;In my Django views(templates) tests, I needed a tool to help me test the presence of certain DOM elements. One of my favorite ways to locate DOM element in an HTML document is by using CSS selectors in &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;I started looking around for a Python implementation of &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; and found a great library called &lt;a href="http://pypi.python.org/pypi/pyquery"&gt;PyQuery&lt;/a&gt; that (thus far at least) has let me manipulate my views as DOM object just like I wanted to.&lt;br /&gt;&lt;br /&gt;One way that I've used it thus it this far is to test that every single one of my template contains only valid HTML once rendered. When doing TDD/BDD with all my template I start out by writing a test that looks a bit like the following one :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;class NewBlogTemplateTests(unittest.TestCase):&lt;br /&gt;&lt;br /&gt;    def __getNewBlogTemplateRendered(self):&lt;br /&gt;        return render_to_string('blog/newBlog.html', { 'newBlogForm': NewBlogForm() })&lt;br /&gt;&lt;br /&gt;    def itShouldContainOnlyValidHtml(self):&lt;br /&gt;        theNewBlogTemplate = self.__getNewBlogTemplateRendered()&lt;br /&gt;        assert_that(theNewBlogTemplate, is_(containingValidHTMLOnly()))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Behind the scenes, containingValidHTMLOnly is an &lt;a href="http://code.google.com/p/hamcrest/wiki/TutorialPython"&gt;Hamcrest&lt;/a&gt; matcher I have written using &lt;a href="http://pypi.python.org/pypi/pyquery"&gt;PyQuery&lt;/a&gt; and &lt;a href="http://github.com/jbalogh/bosley/blob/f64cfeb739954311c36b357d657c227e6d9646a2/bosley/tests/multipart.py"&gt;Multipart&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;I will dig more into &lt;a href="http://code.google.com/p/hamcrest/wiki/TutorialPython"&gt;Hamcrest&lt;/a&gt;'s expressive power in a future blog.&lt;br /&gt;&lt;br /&gt;Here is the source code : &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;from hamcrest.core.base_matcher import BaseMatcher&lt;br /&gt;from pyquery.pyquery import PyQuery&lt;br /&gt;from helpers.tests import Multipart&lt;br /&gt;&lt;br /&gt;class ContainsValidHTML(BaseMatcher):&lt;br /&gt;    &lt;br /&gt;    def __init__(self):&lt;br /&gt;        pass&lt;br /&gt;&lt;br /&gt;    def _matches(self, template):&lt;br /&gt;        responseFromW3 = Multipart.post_multipart('validator.w3.org', '/check', {'fragment': template} )&lt;br /&gt;        pyQuery = PyQuery(responseFromW3)&lt;br /&gt;        return pyQuery('#congrats') != []&lt;br /&gt;&lt;br /&gt;    def describe_to(self, description):&lt;br /&gt;        description.append_text('ContainsValidHTML')&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;containingValidHTMLOnly = ContainsValidHTML&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;W3c compliant HTML guaranteed by my automated test and my continuous integration build. I think this is pretty darn awesome ! Thanks PyQuery ! Special thanks to &lt;a href="http://blog.jeffbalogh.org/post/89619207/pyquery-a-jquery-like-library-for-python"&gt;Jeff Balogh&lt;/a&gt; for teaching me in &lt;a href="http://blog.jeffbalogh.org/post/89619207/pyquery-a-jquery-like-library-for-python"&gt;his blog&lt;/a&gt; this awesome use of PyQuery.&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7366108636851949098?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7366108636851949098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7366108636851949098' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7366108636851949098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7366108636851949098'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/09/automating-your-html-validation-using.html' title='Automating your HTML validation using PyQuery is Awesome.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-843457689038330356</id><published>2010-09-20T05:00:00.000-07:00</published><updated>2010-09-20T05:06:24.342-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>That's Still True To Her</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#1005363165_BWvBg"&gt;&lt;img style="display:block; margin:0px 10px; text-align:left;cursor:pointer; cursor:hand;width: 299px; height: 450px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/isis2/1005363165_BWvBg-M.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-843457689038330356?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/843457689038330356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=843457689038330356' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/843457689038330356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/843457689038330356'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/09/thats-still-true-to-her.html' title='That&apos;s Still True To Her'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-1428206123687114735</id><published>2010-09-06T05:53:00.000-07:00</published><updated>2010-09-20T05:07:07.152-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>The HTML button element  vs  the input with the type button.</title><content type='html'>A few days back, I relearned that there was an HTML button element. Here a a great blog post about the difference between the button element and the input that we usually use :&lt;br /&gt;&lt;br /&gt;http://particletree.com/features/rediscovering-the-button-element/&lt;br /&gt;and a good stackoverflow thread on it : &lt;br /&gt;http://stackoverflow.com/questions/469059/button-vs-input-typebutton-which-to-use&lt;br /&gt;&lt;br /&gt;Enjoy !&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-1428206123687114735?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/1428206123687114735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=1428206123687114735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1428206123687114735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1428206123687114735'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/09/html-button-element-vs-input-with-type.html' title='The HTML button element &lt;button&gt; vs &lt;/button&gt; the input with the type button.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-5912236509115921099</id><published>2010-08-30T10:47:00.000-07:00</published><updated>2012-01-26T04:47:05.410-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><title type='text'>Agile Lessons Learned #13 : Making Room For Passion</title><content type='html'>&lt;blockquote&gt;The autonomous individual, striving to realize himself and prove his worth, has created all that is great in literature, art, music, science and technology. The autonomous individual, also, when he can neither realize himself nor justify his existence by his own efforts, is a breeding call of frustration -Eric Hoffer&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;In Agile literature, a lot of focus in placed on team members needing to organize themselves. But what about the managers role in providing a proper environment ?&lt;br /&gt;&lt;br /&gt;In every management class I've followed, one of the chief concerns was that managers need to be leaders. Leadership is often summed up as being able to motivate other people into performing better than they normally would without your intervention. &lt;br /&gt;&lt;br /&gt;Things that push me towards greater accomplishments are when I am passionate about what I'm doing.&lt;br /&gt;&lt;br /&gt;I feel that as a software developer, my profession feels much more inspiring when it is viewed as being a craft that I need to perfect rather than being a series of tasks that need to be done.&lt;br /&gt;&lt;br /&gt;Thus for me, part of a perfect manager's role would be to put in place a working environment where individuals can live out their passion and perfect their craftsmanship while staying in line with the company's objectives. &lt;br /&gt;&lt;br /&gt;Are you lucky enough to be working in such en environment ? Here are a few questions that might help you figure it out : &lt;br /&gt;&lt;br /&gt;In your current project, how much influence do you have in the outcome of the project ? Do you feel like a driver, a passenger or a bystander ?&lt;br /&gt;&lt;br /&gt;Is becoming better at your job valued in your company's culture or viewed as being overzealous ?&lt;br /&gt;&lt;br /&gt;In the past 5 years you've spent at your job, did you truly acquire 5 years of experience or was it just the same year repeating itself 5 times ?&lt;br /&gt;&lt;br /&gt;How many new things have you learned in the past year ? How do you think the next year will be ?&lt;br /&gt;&lt;br /&gt;If you could produce a short list of your work-related passions, how many can you practice while being at your current job?&lt;br /&gt;&lt;br /&gt;Last but not least, did your manager ever take the time to actually know what truly motivates you and your fellow colleagues ? If he did, how well did he respond with his actions ?&lt;br /&gt;&lt;br /&gt;Luckily for me, I answered favorably to most of the questions. Did you ?&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-5912236509115921099?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/5912236509115921099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=5912236509115921099' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5912236509115921099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5912236509115921099'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/08/agile-lessons-learned-12-making-room.html' title='Agile Lessons Learned #13 : Making Room For Passion'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-1209976223160725467</id><published>2010-08-27T04:57:00.000-07:00</published><updated>2010-08-27T04:59:49.534-07:00</updated><title type='text'>Martin Fowler On Feature Branching</title><content type='html'>&lt;blockquote&gt;Feature Branching is a poor man's modular architecture, instead of building systems with the ability to easy swap in and out features at runtime/deploytime they couple themselves to the source control providing this mechanism through manual merging. &lt;br /&gt;&lt;br /&gt;--Dan Bodart&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Here is a great article on when you should or should not do feature branches.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://martinfowler.com/bliki/FeatureBranch.html"&gt;http://martinfowler.com/bliki/FeatureBranch.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-1209976223160725467?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/1209976223160725467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=1209976223160725467' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1209976223160725467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1209976223160725467'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/08/martin-fowler-on-feature-branching.html' title='Martin Fowler On Feature Branching'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-6689276139740387490</id><published>2010-08-23T15:34:00.000-07:00</published><updated>2010-08-26T05:13:40.484-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Java, Python And Ruby : The Battle For Collection Simplicity</title><content type='html'>Following my colleague Mathieu's excellent post "&lt;a href="http://pyxis-tech.com/blog/2010/08/21/dear-java-please-let-me-work/"&gt;Dear Java Please Let Me Work&lt;/a&gt;"  I've decided to write a small comparative between Java's implementation of the different collection types compared to Python's and Ruby's. In this comparative study, I will take a slightly naive approach and put myself in the shoes of a newbie trying to learn all three languages. &lt;br /&gt;&lt;br /&gt;First let's look  at the UML diagram of Java's collection hierarchy to try and find out what we need to get started.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikibooks/en/c/ca/Java_collection_implementation.jpg"&gt;&lt;img style="float: left; margin: 0pt 10px 10px 0pt; cursor: pointer; width: 600px; height: 577px;" src="http://upload.wikimedia.org/wikibooks/en/c/ca/Java_collection_implementation.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ok. Where to start. Alright, I'll try declaring a simple array to hold my planning poker fibonacci numbers in Java:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;int[] fibonacci = { 0, 1, 3, 5, 8, 13, 21, 34 };&lt;br /&gt;&lt;br /&gt;ArrayList&amp;lt;integer&amp;gt; fibonacci = new ArrayList&amp;lt;integer&amp;gt;();&lt;br /&gt;fibonacci.add( new Integer(0) );&lt;br /&gt;&lt;br /&gt;Vector&amp;lt;integer&amp;gt; fibonacci = new Vector&amp;lt;integer&amp;gt;();&lt;br /&gt;fibonacci.add(new Integer(0));&lt;br /&gt;&lt;br /&gt;Stack fibonacci=new Stack();&lt;br /&gt;fibonacci.push(new Integer(10));&lt;br /&gt;&lt;br /&gt;List fibonacci = new LinkedList();&lt;br /&gt;fibonacci.add(new Integer(i));&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Wow. Sure had a lot of choices. So many ways to do the same thing. That would be quite confusing for a newbie.&lt;br /&gt;&lt;br /&gt;Alright let's give Java's dictionaries a chance.&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;Hashtable fibonacci = new Hashtable();&lt;br /&gt;fibonacci.put( "zero", new Integer(0) );&lt;br /&gt;&lt;br /&gt;HashMap fibonacci = new HashMap();&lt;br /&gt;fibonacci.put( "One", new Integer(1) );&lt;br /&gt;&lt;br /&gt;enum Fibonacci{Zero, One, Two}&lt;br /&gt;&lt;br /&gt;EnumMap&amp;lt;fibonnacci, integer=0&amp;gt; fibonacci = new EnumMap&amp;lt;fibonnacci, integer=0&amp;gt;(Fibonnacci.class);&lt;br /&gt;sizeMap.put(Fibonacci.Zero,new Integer(0));&lt;br /&gt;&lt;br /&gt;Map&amp;lt;string, integer=0&gt; fibonacci = new WeakHashMap&amp;lt;string, integer=0&amp;gt;();&lt;br /&gt;map.put(new String("Zero"), new Integer(0));&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Still so many choices. Still seems too complicated for my liking.&lt;br /&gt;&lt;br /&gt;That made me wonder though, how many people actually use the WeakHashMap ? I mean seriously, who would  go in a design meeting and say "Hey guys, I think we should use the weak hash map over the regular hashmap this time." Doesn't sound quite right does it ?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Alright, let's see how this would look in Python.&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;fibonacci = [1,2,3,5,8,13,21,32]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Oh. Only one way to declare things ? Yeah there's only one way to declare arrays, lists, stacks and queues in python. Simple as that. YOU decide how you use it. Makes sense right ?&lt;br /&gt;&lt;br /&gt;How bout dictionaries ?&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;fibonacci = {"zero":0, "one":1}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Only one way too. How sweet.&lt;br /&gt;&lt;br /&gt;Got some free time and want to try out tuples? Python actually supports tuples right out of the box. Many other language do not...&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;fibonacci = (("zero",0),("one",1))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ok that went by too fast. How about some Ruby then ?&lt;br /&gt;&lt;br /&gt;To declare an array, you can do it in either fashions :&lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;fibonacci = Array.new([0, 1, 3, 5, 8, 13, 21, 34 ])&lt;br /&gt;fibonacci = [0, 1, 3, 5, 8, 13, 21, 34 ]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nice, simple and concise. I like that.&lt;br /&gt;&lt;br /&gt;Now let's move to hashes shall we ?&lt;br /&gt;&lt;pre class="brush: ruby"&gt;&lt;br /&gt;fibonacci =Hash["zero"=&gt;0, "one"=&gt;1]&lt;br /&gt;fibonacci = {"zero"=&gt;0, "one"=&gt;1}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That was easy. &lt;br /&gt;&lt;br /&gt;All this double teaming kinda makes me feel sorry for Java.&lt;br /&gt;&lt;br /&gt;Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-6689276139740387490?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/6689276139740387490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=6689276139740387490' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6689276139740387490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6689276139740387490'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/08/java-python-and-ruby-battle-for.html' title='Java, Python And Ruby : The Battle For Collection Simplicity'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-5829983833115674033</id><published>2010-08-16T12:08:00.001-07:00</published><updated>2010-08-16T12:10:10.247-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Magic Kingdom</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#971108957_ous3N"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 600px; height: 369px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/DSC0296/971108957_ous3N-M.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-5829983833115674033?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/5829983833115674033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=5829983833115674033' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5829983833115674033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5829983833115674033'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/08/magic-kingdom.html' title='Magic Kingdom'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-222391353273874721</id><published>2010-08-16T12:06:00.000-07:00</published><updated>2010-08-16T12:10:33.145-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Disney's Epcot At Night</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#971111485_VfJx6"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 199px; height: 300px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/DSC0588/971111485_VfJx6-S.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-222391353273874721?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/222391353273874721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=222391353273874721' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/222391353273874721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/222391353273874721'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/08/disneys-epcot-at-night.html' title='Disney&apos;s Epcot At Night'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4227137096825116651</id><published>2010-07-28T19:01:00.000-07:00</published><updated>2010-07-28T19:02:39.179-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>You may kiss the bride</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#950996887_L8sPg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 239px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/DSC0057/950996887_L8sPg-S-1.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4227137096825116651?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4227137096825116651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4227137096825116651' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4227137096825116651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4227137096825116651'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/07/you-may-kiss-bride.html' title='You may kiss the bride'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-1761015673152655887</id><published>2010-07-28T19:00:00.001-07:00</published><updated>2010-07-28T19:02:56.859-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Preparing for the wedding.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#951001705_QPkKG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 199px; height: 300px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/DSC0004/951001705_QPkKG-S.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-1761015673152655887?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/1761015673152655887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=1761015673152655887' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1761015673152655887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1761015673152655887'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/07/oh-no.html' title='Preparing for the wedding.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7487382501527531195</id><published>2010-07-28T18:58:00.000-07:00</published><updated>2010-07-28T18:59:54.157-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Mirror mirror on the wall</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#951000585_Cz46K"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 199px; height: 300px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/DSC0003/951000585_Cz46K-S.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7487382501527531195?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7487382501527531195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7487382501527531195' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7487382501527531195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7487382501527531195'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/07/mirror-mirror-on-wall.html' title='Mirror mirror on the wall'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-9048423806634882574</id><published>2010-07-20T14:34:00.000-07:00</published><updated>2010-07-20T15:37:38.894-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='app engine'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>App Engine Unique Constraint</title><content type='html'>While preparing the best practice series for Django, we decided to do the application using both &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt; on &lt;a href="http://code.google.com/appengine/"&gt;App Engine&lt;/a&gt; and using Django's default ORM with &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt;. While developing the App, we ran into a little problem: how do you handle a unique constraint using App Engine ? We found a bit of help on the net, but none of the answers helped us significantly. Here is what we came up with :&lt;br /&gt;&lt;br /&gt;First, we wrote the required unit test :&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;  @istest&lt;br /&gt;  def ItShouldHaveAUniqueName(self):&lt;br /&gt;      car1 = Car(name="corolla" )&lt;br /&gt;      car1.save()&lt;br /&gt;&lt;br /&gt;      try:&lt;br /&gt;          car2 = Car(name="corolla" )&lt;br /&gt;          self.fail("It Should Have A Unique Name")&lt;br /&gt;      except UniqueConstraintValidationException:&lt;br /&gt;          pass&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then we wrote the following model :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;&lt;br /&gt;class Car(db.Model):&lt;br /&gt;  name = db.StringProperty(required=True)&lt;br /&gt;&lt;br /&gt;  def __init__(self,*args, **kwargs):&lt;br /&gt;      super(Car, self).__init__(*args, **kwargs)&lt;br /&gt;      loadingAnExistingCar = ("key" in kwargs.keys() or "key_name" in kwargs.keys())&lt;br /&gt;      if not loadingAnExistingCar:&lt;br /&gt;          self.__makeSureTheCarsNameIsUnique(kwargs['name'])&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def __makeSureTheCarsNameIsUnique(self, name):&lt;br /&gt;      existingCarWithTheSameName = Car.GetByName(name)&lt;br /&gt;      if existingCarWithTheSameName:&lt;br /&gt;          raise UniqueConstraintValidationException("Car should be unique by name")&lt;br /&gt;&lt;br /&gt;  @staticmethod&lt;br /&gt;  def GetByName(name):&lt;br /&gt;      return Car.all().filter("name", name).get()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It is really important to note that we verify first that we are not loading an existing Car before.&lt;br /&gt;&lt;br /&gt;As always, we wrote static methods for the different query methods. This makes them ultra easy to mock in controller tests. It also makes them reusable from controller method to controller method if need be. Finally, if they need to be changed, because of a bug of an implementation change, they only need to be changed once.&lt;br /&gt;&lt;br /&gt;That is all.&lt;br /&gt;&lt;br /&gt;Nicholas&lt;br /&gt;&lt;br /&gt;If you have any feedback, feel free to give it. I will add all your  suggestions to this blog to make it more helpful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-9048423806634882574?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/9048423806634882574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=9048423806634882574' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9048423806634882574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9048423806634882574'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/07/app-engine-unique-constraint.html' title='App Engine Unique Constraint'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2637694371267170572</id><published>2010-07-19T10:31:00.000-07:00</published><updated>2010-07-20T15:35:56.832-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Django Best Practices Article Series Coming Soon</title><content type='html'>Sorry for the lack of recent updates. We are working on a series of articles explaining the best practices of web design using Django. Hope to post it soon. It'll be worth the wait.&lt;br /&gt;&lt;br /&gt;Nicholas&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2637694371267170572?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2637694371267170572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2637694371267170572' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2637694371267170572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2637694371267170572'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/07/django-best-practices-article-series.html' title='Django Best Practices Article Series Coming Soon'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2566541812024074045</id><published>2010-06-29T05:25:00.000-07:00</published><updated>2010-06-29T05:30:41.706-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>People love exploding stuff.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#914871318_NdHZ3"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 600px; height: 340px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/fireworks/914871318_NdHZ3-M.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2566541812024074045?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2566541812024074045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2566541812024074045' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2566541812024074045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2566541812024074045'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/06/people-love-exploding-stuff.html' title='People love exploding stuff.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2433884166173726513</id><published>2010-06-23T16:41:00.001-07:00</published><updated>2010-06-29T05:36:07.359-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>First drive</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#911536442_k8GqE"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 325px; height: 450px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/golf/911536442_k8GqE-M.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2433884166173726513?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2433884166173726513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2433884166173726513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2433884166173726513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2433884166173726513'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/06/first-drive.html' title='First drive'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-964384606229255064</id><published>2010-06-23T16:36:00.000-07:00</published><updated>2010-06-29T05:36:32.011-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Putting</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#911537563_4Trik"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 300px; height: 450px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/put/911537563_4Trik-M.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-964384606229255064?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/964384606229255064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=964384606229255064' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/964384606229255064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/964384606229255064'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/06/putting.html' title='Putting'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-6676648148885246029</id><published>2010-06-23T11:58:00.001-07:00</published><updated>2010-06-29T05:37:04.339-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>It's a nice day for a (black &amp;)white wedding</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#909317726_xA9sY"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 278px; height: 450px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/wedding/909317726_xA9sY-M.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-6676648148885246029?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/6676648148885246029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=6676648148885246029' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6676648148885246029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6676648148885246029'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/06/its-nice-day-for-black-wedding.html' title='It&apos;s a nice day for a (black &amp;)white wedding'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4617596588790413159</id><published>2010-06-18T11:38:00.000-07:00</published><updated>2012-01-26T04:40:22.193-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><category scheme='http://www.blogger.com/atom/ns#' term='self-organized teams'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Agile Lessons Learned #12 : Harry the crap collector</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_vJCcAtCDEM8/TB97NhMgmBI/AAAAAAAAADk/JdzlkTvUys8/s1600/garbageNYC.jpeg"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5485238343339907090" src="http://4.bp.blogspot.com/_vJCcAtCDEM8/TB97NhMgmBI/AAAAAAAAADk/JdzlkTvUys8/s320/garbageNYC.jpeg" style="cursor: pointer; float: left; height: 208px; margin: 0pt 10px 10px 0pt; width: 320px;" /&gt;&lt;/a&gt;&lt;br /&gt;Vince came back home today only to be greeted by firetrucks. He was quickly relieved to learn that his brand new condo was not on fire. Unfortunately, for his neighbor Harry, the fire marshal was there expelling him from his own home until he got his mess together.&lt;br /&gt;&lt;br /&gt;When Vince found Harry he was in a terrible state of mind. You see, 78 years old Harry had been collecting all the newspapers he could get his hands on ever since his wife had died. Twenty-six years of newspaper stacked up against the walls of a smoking&amp;nbsp;neighbor&amp;nbsp;was too much and a nervous neighbor made a phone call to the local fire department.&lt;br /&gt;&lt;br /&gt;All this turmoil shook up Vince inside. When he came back to work Monday, he started thinking about all the mess that was accumulating in his own project.&lt;br /&gt;&lt;br /&gt;He made the following list of all that was accumulating around him :&lt;br /&gt;- The backlog had tons of duplicate items&lt;br /&gt;- A ton of stories were planned for but not estimated&lt;br /&gt;- The main domain classes of the application were starting to have more responsibilities than the company's C.E.O.&lt;br /&gt;- The code produced by the interns had not been peer reviewed for weeks&lt;br /&gt;- The users documentation was dated by two revisions&lt;br /&gt;&lt;br /&gt;Vince then went to see his Product Owner and told him about the issue. He was pretty pissed off to learn this at first. After a long discussion, he brought the team together, talked about what was most urgent and they estimated the cost/benefit of tackling each issue.&lt;br /&gt;&lt;br /&gt;He then added the elements with the best return on the investment at the top of the backlog. He even started chipping in where he could help the team address some issues. Within a few months, the situation was very promising and the team was no longer nervous about bringing up issues. Actually, they felt encouraged to do so.&lt;br /&gt;&lt;br /&gt;A year later, most of his teams at FreeFall were engulfed in crap that had accumulated sprint after sprint. Always planning to fix it later, they never ever did.&lt;br /&gt;&lt;br /&gt;Meanwhile this team just glided through the problems at a steady pace. It seemed like nothing could stop them in their tracks. For the team members, the project just felt like a train anybody would love to embark on. Their biggest pride, was that it was their own.&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4617596588790413159?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4617596588790413159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4617596588790413159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4617596588790413159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4617596588790413159'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/06/agile-lessons-learned-11-harry-crap.html' title='Agile Lessons Learned #12 : Harry the crap collector'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_vJCcAtCDEM8/TB97NhMgmBI/AAAAAAAAADk/JdzlkTvUys8/s72-c/garbageNYC.jpeg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-1716473560008253791</id><published>2010-05-31T19:35:00.000-07:00</published><updated>2010-07-22T14:05:04.170-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>I Love My Dynamic Sandboxes</title><content type='html'>One of the neatest tricks of dynamic languages like Python, Ruby, Javascript or even PHP is that you can try any snippet of code in your own little sandbox before you actually use it. This is great for exploring APIs that do not have a clear documentation, for learning purposes or for small proofs of concepts.&lt;br /&gt;&lt;br /&gt;Let's take a very simple example. Let's say you come from a C# background and are very found of LINQ. You would like to know how this expression would translate in your dynamic language of choice. Here's a way to do it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;LINQ expression&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;blockquote&gt;from name in names&lt;br /&gt;where name.Length &gt; 3&lt;br /&gt;orderby name&lt;br /&gt;select name.ToUpper()&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Python.&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Assuming you are runing on a Unix machine simply type Python command. Once in the interactive interpreter, you are free to do pretty much anything you want with the language. You can import any eggs you have installed and anything that is in your PYTHONPATH. You can even add paths to your PYTHONPATH on the fly if you want to. At the prompt you would simply type the commands you want until you get the desired result.&lt;br /&gt;&lt;br /&gt;Here's a way to translate the above expression in the interactive interpreter :&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;blockquote&gt;&gt;&gt;&gt; names = [ "guy","jean","bob","serge","jacques","yvon"]&lt;br /&gt;&gt;&gt;&gt; sorted(name.upper() for name in names if len(name) &gt;3)&lt;br /&gt;['JACQUES', 'JEAN', 'SERGE', 'YVON']&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pretty concise expression wouldn't you say? The last line is python outputting you the result of you query. Neat huh ?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;RUBY&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Ruby had it's own interpreter. It's called IRB. On most UNIX machines, you will need to install it, unlike python. It pretty much works the same way as the Python interactive interpreter.&lt;br /&gt;&lt;br /&gt;You start it by calling IRB. Then you have access to pretty much anything you'd like just like in Python.&lt;br /&gt;The console looks like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;blockquote&gt;irb&gt;names = [ "guy","jean","bob","serge","jacques","yvon"]&lt;br /&gt;irb&gt; names.select {|name| name.length() &gt;3}.each{ |name| name.upcase}.sort&lt;br /&gt;=&gt; ["JACQUES", "JEAN", "SERGE", "YVON"]&lt;/blockquote&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;IRB also kindly print out the results.&lt;br /&gt;&lt;br /&gt;By the way, all the examples above are built into the language without the need of anything like LINQ.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;Javascript/jQuery&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As far as Javascript in concerned, the way to have some fun is to use the FireFox add-on called FireBug.&lt;br /&gt;&lt;br /&gt;One there, simply go into the console section and any Javascript library that is available in the page you are currently viewing will be accessible. For this example, we will be using the powerful jQuery library directly from the jQuery.com site. Isn't that sweet. Wanna resolve the above LINQ query using FireBug as your sandbox ? After some fiddling here is the solution I came up with :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;br /&gt;var names = [ "guy","jean","bob","serge","jacques","yvon"];&lt;br /&gt;jQuery.grep(names, function(name){return name.length &gt; 3})&lt;br /&gt;    .map(function(name,i){return name.toUpperCase()})&lt;br /&gt;    .sort()&lt;br /&gt;&lt;br /&gt;FireBug kindly prints out the result of my execution as this :&lt;br /&gt;&lt;br /&gt;["JACQUES", "JEAN", "SERGE", "YVON"]&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PHP&lt;/span&gt;&lt;br /&gt;How bout some PHP ? PHP comes with it's own interpreter.  Simply type php -a in a console. It's not as cool as Python's or Ruby's but it does a decent enough job. So how does this expression translate in PHP ? Well, it's definitely more verbose, but at least you got to try it out in a sandbox first to minimize any surprises from the quirks in the language.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;blockquote&gt;php &gt; function toUpper($name){return strtoupper($name);}&lt;br /&gt;php &gt; function longerThanThree($name){return strlen($name)&gt;3;}&lt;br /&gt;php &gt; $names = array("guy","jean","bob","serge","jacques","yvon");&lt;br /&gt;php &gt; $filteredNames = array_map("toUpper",array_filter($names,"longerThanThree"));&lt;br /&gt;php &gt; sort($filteredNames);&lt;br /&gt;php &gt; print_r($filteredNames);&lt;br /&gt;Array&lt;br /&gt;(&lt;br /&gt;   [0] =&gt; JACQUES&lt;br /&gt;   [1] =&gt; JEAN&lt;br /&gt;   [2] =&gt; SERGE&lt;br /&gt;   [3] =&gt; YVON&lt;br /&gt;) &lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There you go. Mission accomplished. Had you done the exercise yourself, you just would of quickly learned how to write a snippet of code in 5 different languages !&lt;br /&gt;&lt;br /&gt;I think this is all pretty neat. As an added bonus, besides the PHP example, all solutions are very elegant and were discovered using trial and error as a learning tool. Something that is unfortunately not available in non-dynamic languages.&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-1716473560008253791?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/1716473560008253791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=1716473560008253791' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1716473560008253791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1716473560008253791'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/05/i-love-playing-in-my-sandbox.html' title='I Love My Dynamic Sandboxes'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-5071892499285239627</id><published>2010-05-30T06:38:00.001-07:00</published><updated>2012-01-25T04:48:20.189-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Inside out</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#883243145_stA4B"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/pinkFloyd/883243145_stA4B-S.jpg" style="cursor: hand; cursor: pointer; float: left; height: 300px; margin: 0 10px 10px 0; width: 245px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-5071892499285239627?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/5071892499285239627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=5071892499285239627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5071892499285239627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5071892499285239627'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/05/inside-out.html' title='Inside out'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-6642492321447932264</id><published>2010-05-30T06:36:00.001-07:00</published><updated>2012-01-25T04:48:37.140-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>That'll keep you going for the show....</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#883250173_kki7i"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/spectators/883250173_kki7i-S.jpg" style="cursor: hand; cursor: pointer; float: left; height: 300px; margin: 0 10px 10px 0; width: 199px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-6642492321447932264?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/6642492321447932264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=6642492321447932264' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6642492321447932264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6642492321447932264'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/05/thatll-keep-you-going-for-show.html' title='That&apos;ll keep you going for the show....'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-777696646109074260</id><published>2010-05-30T06:33:00.000-07:00</published><updated>2010-05-30T06:35:56.955-07:00</updated><title type='text'>Beach</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#883242364_x8wV2"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 189px; height: 300px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/ideal/883242364_x8wV2-S.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-777696646109074260?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/777696646109074260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=777696646109074260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/777696646109074260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/777696646109074260'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/05/beach.html' title='Beach'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2445669236270356062</id><published>2010-04-21T09:09:00.000-07:00</published><updated>2012-01-26T16:50:15.292-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><title type='text'>Agile lessons learned #11 : Tony the one trick pony</title><content type='html'>&lt;blockquote&gt;&lt;br /&gt;A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects. -Robert A. Heinlein&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-4rcPj3QMY-Y/TyH0hLaN2dI/AAAAAAAAAJI/swvoZMs__nk/s1600/pony.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="168" src="http://3.bp.blogspot.com/-4rcPj3QMY-Y/TyH0hLaN2dI/AAAAAAAAAJI/swvoZMs__nk/s320/pony.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Like most children, Tony had to pick a sport. Not being the athletic type he decided to pick up baseball just like most kids in the neighborhood. It was his one and only passion. He daydreamed about playing baseball in school and practice all winter while waiting for the next spring camp.&lt;br /&gt;&lt;br /&gt;When the local professional team moved away, most kids quit playing baseball and went back to either playing soccer or hockey.&lt;br /&gt;&lt;br /&gt;Tony kept on playing for a season or two, then quit playing sports altogether having a hard time finding a league for players his age.&lt;br /&gt;&lt;br /&gt;When it came to his professional life, Tony had the same attitude. When doing an internship in college, the quality bug bit him and he decided to become a full-fledged tester. Having secured a job in the country's number one employer, he now saw it as a personal challenge to be the best tester on every team he ever dealt with. He most often was. &lt;br /&gt;&lt;br /&gt;When projects started shifting to object-oriented programming, he started feeling a bit behind the curve. When the teams shifted to Web design, he was really lost, but still kept helping the teams by finding bugs manually.&lt;br /&gt;&lt;br /&gt;When the teams started adopting Agile practices, developers started taking quality more seriously and started writing their own tests. Tony felt terrible. Sure he was still finding bugs here and there, but the quality was really getting better and he felt more and more useless. He then had a talk with Maxim, the ScrumMaster who was leading the Agile initiative.&lt;br /&gt;&lt;br /&gt;Maxim explained to him that instead of being threatened by change, he should embrace it. After all, he was the one championing for better quality all these year when nobody else cared. Now that everybody cared about it, maybe he could have a leadership role within this new team.&lt;br /&gt;&lt;br /&gt;Tony decided to give it a try. He talked to the programmers about learning about testing and developing using those new web frameworks. After a couple of weeks of pair-programming, Tony was actually the one driving the developers about not skipping tests and doing rigid TDD. He was also being a terrific aid to the product owner with all of his exploratory testing.&lt;br /&gt;&lt;br /&gt;Even more so, with his years of experience doing testing, he was always the one thinking about corner cases during the planning sessions and in his pair-programming sessions. Without him knowing, he was one his team's biggest asset. Tony wasn't just a one trick pony after all.&lt;br /&gt;&lt;br /&gt;Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2445669236270356062?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2445669236270356062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2445669236270356062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2445669236270356062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2445669236270356062'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/04/agile-lessons-learned-10-tony-one-trick.html' title='Agile lessons learned #11 : Tony the one trick pony'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-4rcPj3QMY-Y/TyH0hLaN2dI/AAAAAAAAAJI/swvoZMs__nk/s72-c/pony.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4926774042272973236</id><published>2010-04-21T09:04:00.001-07:00</published><updated>2010-04-21T09:08:29.637-07:00</updated><title type='text'>Usability lessons learned: Who's driving who?</title><content type='html'>Tax season. What better way to welcome the warmer weather than filling out tax forms. Forget about the return of birds, the blossoming of trees, driving with the windows down or the reappearance of short skirts. Spring calls for serious work. To make matters worst, this year I could not manage to find out how much interest I payed on my student loans during the past year.&lt;br /&gt;&lt;br /&gt;I wasn't able to do it through my bank's online service even though I remembered doing so  the previous years. I felt pretty bad about myself, considering I'm a supposed to be an IT specialist and all.&lt;br /&gt;&lt;br /&gt;I called the customer support in shame only to be told that &lt;span style="font-weight:bold;"&gt;my information was indeed available online&lt;/span&gt;. I felt even worst. The very nice lady on the phone walked me through these very precise steps :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;1- Go into my monthly statements&lt;br /&gt;2- Select the account from which I pay my loans&lt;br /&gt;3- Select the month of December&lt;br /&gt;4- Go to the bottom of my statement&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is where my information was hiding all along ?!? How intuitive, right? You would have figured that one out, right ? You might wonder why someone would decide to hide this info this deep since it makes no sense at all right? Well it does in a certain way. If you look at the 4 steps above and translate them into an SQL query, it does look more natural. It would look something like this :&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Select SUM(interests) from Account where date &gt;= 2009 and date &lt;=2010.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Makes more sense now ? This is what happens when software is developed backwards. When the back end drives the front end.&lt;span style="font-weight:bold;"&gt; Instead of having the natural user interactions dictate the way it should be implemented, we have the implementation dictating the interactions.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Take radios as another example. Just like &lt;a href="http://trempet.uqam.ca/Enseignement/Cours/inf5151/Hiver2008/NotesdeCours/MODULE%20No%2021%20radio%20et%20baignoires.htm"&gt;one of my university teachers&lt;/a&gt; used to point out, most users could not care less about radio frequencies. Yet they had to learn about them in order to use a radio properly. Even though it was less natural to use as a result, it was more cost efficient to bind the user directly to the choice of frequency without an abstraction layer.&lt;br /&gt;&lt;br /&gt;When designing interfaces, a good practice would be to always ask yourself : &lt;span style="font-weight:bold;"&gt;Who's driving who ? &lt;/span&gt;Is the implementation driving the interaction or vice versa?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;In other words, are you trying to fit the tool to the user or fit the user to the tool ?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For more on this subject, I would invite you to read &lt;a href="http://trempet.uqam.ca/Enseignement/Cours/inf5151/Hiver2008/NotesdeCours/MODULE%20No%2021%20radio%20et%20baignoires.htm"&gt;this article&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4926774042272973236?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4926774042272973236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4926774042272973236' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4926774042272973236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4926774042272973236'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/04/usability-lessons-learned-whos-driving.html' title='Usability lessons learned: Who&apos;s driving who?'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-218877474145901644</id><published>2010-04-11T07:08:00.000-07:00</published><updated>2012-01-26T16:52:50.673-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><title type='text'>Agile Lessons Learned #10: Skunk code.</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-d6TES9j1SfA/TyH1UtPOf0I/AAAAAAAAAJQ/0revzAQB33M/s1600/pepelepew.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-d6TES9j1SfA/TyH1UtPOf0I/AAAAAAAAAJQ/0revzAQB33M/s1600/pepelepew.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;After a few months of Agile coaching things were starting to look brighter over at FreeFall inc. The Agile process was slowly but surely settling into place. Problem was, even though the team was pumping an all out effort, their capacity to deliver was shameful. Tim had managed to convince FreeFall to hire Andrew, an Agile developer to give more technical coaching to the team.&lt;br /&gt;&lt;br /&gt;"Man, I can't believe this. The build machine is dying on me again !" Shouted Andrew&lt;br /&gt;"Again!? What did you do ? "&lt;br /&gt;"I'm running the analyzer on our code. The code is so bad that ALL the code analyzers are dying on me"&lt;br /&gt;"You're running this on a 486 with floppies or what?" Asked Tim.&lt;br /&gt;"If only I was. This machine is state of the art. Cost them a fortune. Man, it really looks like we have a serious case of skunk code here." said Andrew&lt;br /&gt;&lt;br /&gt;"Skunk code ? What's that?" asked Tim&lt;br /&gt;"Well you know some animals have defense mechanisms more evolved than others. The skunk for one, well, it just plain stinks. Most of it's defense comes from just plain stinking so bad you won't dare approach it."&lt;br /&gt;&lt;br /&gt;"I see. How does it relate to code ? "&lt;br /&gt;"Well you see, code usually starts with the best intentions. Than people introduce small flaws here and there."&lt;br /&gt;"Ever heard of the &lt;span style="font-weight: bold;"&gt;broken window principle&lt;/span&gt; ?"&lt;br /&gt;"Can't say I have." said Tim perplex&lt;br /&gt;"Well it's a pretty simple theory. You break the window of a building and leave it like that. For some reason, people will notice the lack of care and in turn will start to take less care of the rest of the building. Within a year the place might actually start to fall apart."&lt;br /&gt;&lt;br /&gt;"Interesting, looks like what we have here. How does that relate to my skunk smelling code though ? "&lt;br /&gt;"Well you see, at some point the code base so bad, &amp;nbsp;it will contain so many "code smells", people will be so repressed by it that nobody will dare touch it."&lt;br /&gt;"It thus becomes protected from ever being touched. Just like a skunk."&lt;br /&gt;&lt;br /&gt;"I see. What should we recommend to the client ?"&lt;br /&gt;"Well for one they could stop adding more smells to this mess."&lt;br /&gt;"Any new code has very little reason to be messy."&lt;br /&gt;"How could they prevent that ?" - Asked Tim&lt;br /&gt;"&lt;span style="font-weight: bold;"&gt;Behaviour Driven development&lt;/span&gt; or &lt;span style="font-weight: bold;"&gt;Test Driven Development,&lt;/span&gt; properly applied, should help a lot." &lt;br /&gt;"Learn how to use &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt;, &lt;a href="http://www.greenpeppersoftware.com/"&gt;GreenPepper&lt;/a&gt;, &lt;a href="http://http//en.wikipedia.org/wiki/XUnit"&gt;xUnit&lt;/a&gt;, &lt;a href="http://rspec.info/"&gt;Rspec&lt;/a&gt; or whatever else you can think of and learn how to use it and why."&lt;br /&gt;"&lt;span style="font-weight: bold;"&gt;Pair programming&lt;/span&gt; should also be mandatory on most if not all coding activities. Try it out. Most people can't go back to their old ways once they try it."&lt;br /&gt;"&lt;b&gt;Code reviews&lt;/b&gt; should also be mandatory before ANY code goes to production."&lt;br /&gt;"Running the &lt;b&gt;analyzers&lt;/b&gt; on the code can also give a hand, although it cannot replace the above practices. Give a look at &lt;a href="http://www.sonarsource.org/"&gt;Sonar&lt;/a&gt; and the likes and find out what can help you or not."&lt;br /&gt;&lt;br /&gt;"That's nice. How about the existing code ?"&lt;br /&gt;"Well that's gonna have to wait till I get my build machine running properly."&lt;br /&gt;&lt;br /&gt;- Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-218877474145901644?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/218877474145901644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=218877474145901644' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/218877474145901644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/218877474145901644'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/04/agile-lessons-learned-8-skunk-code.html' title='Agile Lessons Learned #10: Skunk code.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-d6TES9j1SfA/TyH1UtPOf0I/AAAAAAAAAJQ/0revzAQB33M/s72-c/pepelepew.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7237038506468533593</id><published>2010-04-10T17:07:00.000-07:00</published><updated>2012-01-25T04:47:59.258-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='piicture'/><title type='text'>Closer</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#832567129_taQGe"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/unCouple/832567129_taQGe-S.jpg" style="cursor: hand; cursor: pointer; float: left; height: 300px; margin: 0 10px 10px 0; width: 264px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7237038506468533593?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7237038506468533593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7237038506468533593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7237038506468533593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7237038506468533593'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/04/closer.html' title='Closer'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-478834757956033620</id><published>2010-04-10T17:02:00.001-07:00</published><updated>2012-01-25T04:48:49.725-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Tangled up in blue.</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#832566764_iiAqQ"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/stuck/832566764_iiAqQ-S.jpg" style="cursor: hand; cursor: pointer; float: left; height: 266px; margin: 0 10px 10px 0; width: 400px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-478834757956033620?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/478834757956033620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=478834757956033620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/478834757956033620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/478834757956033620'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/04/tangled-up-in-blue.html' title='Tangled up in blue.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2253459966210929190</id><published>2010-04-10T16:59:00.001-07:00</published><updated>2012-01-25T04:49:51.533-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Livin' on a prayer</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#832584252_AvZwA"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/prayer/832584252_AvZwA-S.jpg" style="cursor: pointer; float: left; height: 300px; margin: 0pt 10px 10px 0pt; width: 200px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2253459966210929190?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2253459966210929190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2253459966210929190' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2253459966210929190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2253459966210929190'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/04/livin-on-prayer.html' title='Livin&apos; on a prayer'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7743604638807420280</id><published>2010-03-31T08:58:00.000-07:00</published><updated>2010-03-31T08:59:35.601-07:00</updated><title type='text'>Fixing missing plugin out of date problem in Maven.</title><content type='html'>&lt;pre&gt;whe you get an error like this :&lt;br /&gt;&lt;br /&gt;The plugin 'org.apache.maven.plugins:maven-idea-plugin' does not&lt;br /&gt;exist or no valid version could be found&lt;br /&gt;&lt;br /&gt;Simply execute this command :&lt;br /&gt;mvn -U idea:idea&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cheers !&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7743604638807420280?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7743604638807420280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7743604638807420280' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7743604638807420280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7743604638807420280'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/03/fixing-missing-plugin-out-of-date.html' title='Fixing missing plugin out of date problem in Maven.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-6869988652025199949</id><published>2010-03-30T08:47:00.000-07:00</published><updated>2012-01-26T17:07:45.093-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><title type='text'>Agile Lessons Learned #9: Muscle Memory</title><content type='html'>&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-nf4RJMSpC9Y/TyHrJ8Q7BuI/AAAAAAAAAJA/lFWAJUCnT4E/s1600/Colorado-experiment.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/-nf4RJMSpC9Y/TyHrJ8Q7BuI/AAAAAAAAAJA/lFWAJUCnT4E/s200/Colorado-experiment.jpg" width="176" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 21px;"&gt;The muscle memory theory&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 21px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In 1973, the Colorado experiment was conducted in order to test the effectiveness of brief and extremely intense exercise. The pictured subject, Casey Viator was  a de-trained bodybuilder coming off a year long layoff following sickness. By the end of the 28th day of the experiment, he had gained 63 pounds of muscle and lost over 17 pounds of fat. The results have often been attributed to "muscle memory".&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The theory behind muscle memory is that for it's own preservation, the body always tries to maintain a certain balance. For example, it will make you sweat when it is hot outside to try and maintain your body's temperature in a safe range.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In order to grow bigger muscle, one has to truly overloaded his muscle in order to give the body the signal it needs to adapt since it is no longer apt to meet the demands made upon it. Over a period of time, once the body grows accustomed to a certain level of muscle size/strength it then becomes the new balanced level the body tries to maintain.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;When someone gets sick or&amp;nbsp;under-eats, his body has to regress back to lower levels of size/strength since the muscles are less important than the current stress imposed on it.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But with proper stimulation and nutrition, it can grow back to the previous maximum levels in less time than it first took to reach those levels because the body is searching to be balanced again.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;When it comes to human behaviour, the same phenomenon is visible. Just like with with muscular balance, the mind seems to try and maintain a person in it's psychological comfort zone as some sort of defence mechanism. Once taken out of the comfort zone, it often triggers the reflex of going back to the old ways of doing things, no matter if it the previous behavior has a positive effect on the person or not.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 130%;"&gt;Transitioning to Agile practices as an example&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;When putting forth a transition in an enterprise such behavioral patterns must be understood and dealt with. Let's take an Agile transition that takes employees who are used to a very hierarchical environment and are moving into self-organized teams as our example.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 130%;"&gt;The team&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;For starters, let's take a look at something at task assignment. &amp;nbsp;Many people are accustomed to having tasks assigned to themselves. They might have a hard time dealing with the simple responsibility of self-task assignment. Actually, a lot of people will look around for somebody to assign something to them or pretend they are committing to something while in fact they are letting everybody else decide and are taking what is left.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Dealing with the Product Owner on the appropriate scope of a sprint is something a lot of team members find hard at first. Telling no to somebody who is asking you to do more stuff is not the usual behaviour most of us are accustomed to.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Actually, most of us have been accustomed to saying yes by default. Here are some examples: When we were young, we were expected to do what our parents asked us to do. In school, we were supposed to act the way the teacher asked. At work, we are supposed to accomplish whatever work we are asked to do. See a behavioural pattern there ?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;On the technical side, it is quite adventurous to ask developers with 20 years of experience who have never written a single test in their lives to change their methods. Asking them to do all their programming using test driven&amp;nbsp;development, where not a single line of code is written without a test written to test it first is quite a challenge.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Unfortunately, you will often find programmers skipping tests altogether, even though they are aware of the benefits. In extreme dissonant cases, some will be sabotaging their own work by writing fake tests, deleting existing tests or commenting them out.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In all cases, these people were taken out of their comfort zone. Even though they knew it was for their own good, they retreated to their old ways where they feel comfortable and not&amp;nbsp;threatened.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 130%;"&gt;Managers&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;It also works the other way around. Having power over people is something that is seemingly very hard to let go of. In Agile teams, management is often seem as a mix of visionaries, servant leaders&amp;nbsp;and&amp;nbsp;umbrellas protecting the team.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;It requires a lot more skills to be a successful manager in an Agile environment than to simply be able to dispatch work effectively.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;It also involves the humbling task of letting go some of the grasp some managers often have over 'their' employees(micro-management). It is only too common to hear stories about managers embracing Scrum, only to find them minutes later behaving exactly like they did before.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This is often done in spite of them being aware that their previous behavior is unproductive and is part of what conducted the requirement for change in the first place.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Just like with weight training, it takes a long period of stimulus for the body to recognize the current state as a&amp;nbsp;desirable&amp;nbsp;state that the body should try to maintain.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;It is the same with change, the longer you keep at it, the more it will feel natural and it will just become the new habit. Remember, some things you think of as habits now might have been uncomfortable at first too.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&amp;nbsp;Just stay out of your&amp;nbsp;comfort&amp;nbsp;zone long enough, and that zone will become your new comfort zone.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;-Nicholas Lemay&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-6869988652025199949?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/6869988652025199949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=6869988652025199949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6869988652025199949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6869988652025199949'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/03/agile-lessons-learned-8-muscle-memory.html' title='Agile Lessons Learned #9: Muscle Memory'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-nf4RJMSpC9Y/TyHrJ8Q7BuI/AAAAAAAAAJA/lFWAJUCnT4E/s72-c/Colorado-experiment.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-932991519546166433</id><published>2010-03-13T06:56:00.000-08:00</published><updated>2012-01-25T04:49:28.499-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Maurice "Rocket" richard</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#808824181_6WBAu"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/richard/808824181_6WBAu-M.jpg" style="cursor: hand; cursor: pointer; display: block; height: 450px; margin: 0px auto 10px; text-align: center; width: 299px;" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-932991519546166433?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/932991519546166433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=932991519546166433' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/932991519546166433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/932991519546166433'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/03/maurice-rocket-richard.html' title='Maurice &quot;Rocket&quot; richard'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-9002689129387085595</id><published>2010-02-15T20:50:00.000-08:00</published><updated>2010-02-15T21:05:11.413-08:00</updated><title type='text'>A possible solution to 360 evaluations.</title><content type='html'>Recent blog posts made on the Pyxis blog clearly show that there is a lack of trust towards the true usefulness of 360 degree evaluations. A couple of months ago, I was about to prepare my first 360  evaluation that was geared towards evaluating my own work at Pyxis over the last 6 months. As I prepared to do so, I asked my caddy to guide me through this process. To make things easier to grasp, we simply wrote down the goals I was trying to accomplish with the evaluation and grouped the by theme to see how we should deal with them.&lt;br /&gt;&lt;br /&gt;Once simplified, the goal of my evaluations came down to two main themes :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;1- Get an evaluation of my performance in order for me to be able to deal my salary for the next year.&lt;br /&gt;2- Get proper feedback in order to get better within the next year.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So far so so good right? A regular 360 should help me meet those goals right ? Right ? Wrong. Totally wrong. The two goals are exactly that, two different goals and should be tackled differently. The first goal is there to evaluate whether or not I have performed to the levels that were expected by my employer and whether or not I should be rewarder accordingly. How is a subjective evaluation based on generic questions gonna help me do so ? Let's say my job for the past year had been to be a product owner of a software developed at Pyxis. Let's say my goals were to bring it to market within the first 6 months, to break even with the development costs within the next 3 months and to make a profit for the last 3 months of the year.&lt;br /&gt;&lt;br /&gt;What does me having 3/5 or 5/5 on being a team player, having verbal skills, technical skills or management in a questionnaire have to do with me meeting my objectives? How about nil, zero, nada, zilch ? What might actually matters for this point is whether or not I have met those goals. Unfortunately, for most employees,those goals are seldom set in advance and/or are very seldom very clear. Too often, we learn the expectations once we get to our evaluation. Much like we set the condition of success for the user stories we develop during the XP/Scrum planning game, we most definitely should s&lt;span style="font-weight:bold;"&gt;et the expectations far in advance&lt;/span&gt;. Then and only then can somebody be evaluated fairly.&lt;br /&gt;&lt;br /&gt;As far as number 2 goes, in order for me to get better I need proper feedback. But feedback on what actually? In my limited experience with 360 evaluations, more often than not, when someone is asked to rate a colleague on a question along the lines of "Shows commitment to the project" they will come up with an example on when the person showed or lacked commitment to the project. Actually, they might of forgotten all about the project and might rate you on whether or not they like you as a person or not. Why not reverse the situation and come up with the examples and then &lt;span style="font-weight:bold;"&gt;ask the questions based on a particular event&lt;/span&gt; ? &lt;br /&gt;&lt;br /&gt;Let's say I worked with Marc on a project for 3 months. Within that time a lot has come and gone. Asking him a random question will render a random answer. But if I want specific feedback in order to get better on a particular subject, I can plan accordingly. If instead I'd ask him : "On that project, we didn't meet our deadline for 3 consecutive sprints. Do you think I showed the proper commitment ? If not, how did you feel about it what what would you suggest I should change ?" This should trigger memories based on those event and more specific feedback on a more precise theme. &lt;br /&gt;&lt;br /&gt;Like some suggested, &lt;span style="font-weight:bold;"&gt;the feedback should be done face to face&lt;/span&gt;. You might not want to go all the way and do it in groups, but that's an interesting avenue to say the least.&lt;br /&gt;&lt;br /&gt;Also, not having the two conflicting goals might help both goals being reached. Let's say my annual raise is based on my 360. Why should I be inclined to ask the "questions that hurt" to somebody ? If I get negative feedback I might get scared of not getting my pay raise. Who would want that? On the other hand, if I use it only for a genuine goal of getting better, I have at least one reason less not to ask the real questions. &lt;br /&gt;&lt;br /&gt;Also, &lt;span style="font-weight:bold;"&gt;by setting your goals far in advance, you will have less excuse not the meet them&lt;/span&gt;. Actually, you might ask for more frequent feedback from your peers, since you have a clear goal and getting better will help you meet your goal. You will get better, and both you as an individual and the enterprise you work for will flourish from that.&lt;br /&gt;&lt;br /&gt;I hope this small recollection of a conversation I had with my caddy can help you guys, or keep this interesting conversation alive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-9002689129387085595?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/9002689129387085595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=9002689129387085595' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9002689129387085595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9002689129387085595'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/02/possible-solution-to-360-evaluations.html' title='A possible solution to 360 evaluations.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7618727111449637427</id><published>2010-02-15T08:31:00.000-08:00</published><updated>2012-01-25T04:49:09.721-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Stream.</title><content type='html'>&lt;div style="background-color: black; padding-top: 20px; text-align: center;"&gt;&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#645633507_VCuxJ"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/ruisseau/788870123_sKafJ-M.jpg" style="border-width: 3px; cursor: pointer; display: block; height: 450px; margin: 20px auto 0px; padding: 20px; text-align: center; width: 319px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="color: white;"&gt;Took this picture this weekend @Mirabel.&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7618727111449637427?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7618727111449637427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7618727111449637427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7618727111449637427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7618727111449637427'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/02/stream-of-gold.html' title='Stream.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4627125298843049979</id><published>2010-02-03T18:49:00.000-08:00</published><updated>2010-02-03T19:18:33.514-08:00</updated><title type='text'>Using Eclipse + PHPUnit as an automatic testing tool like autotest.</title><content type='html'>Here's a quick tip that is so simple that I cannot believe I waited so long to implement it. Within a couple of configuration clicks within Eclipse, you can have yourself a tool that is almost as powerful as Ruby's &lt;a href="http://github.com/seattlerb/autotest-rails"&gt;Autotest&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For those who don't know, a tool like autotest allows you to have your whole test suite run every time you modify a file within you project and save it. This reduces the amount of focus change you have to do between you BDD/Unit test tool and the code you are working on. This also encourages taking baby steps as you can get feedback for every single line that you will ever write !&lt;br /&gt;&lt;br /&gt;The steps here take for granted that you are running a Debian based Linux operating system. Most steps could be replicated on a Mac Os or on a Windows of if the steps are followed in the same order but with the appropriate commands and path changes.&lt;br /&gt;&lt;br /&gt;First Download and install &lt;a href="http://www.eclipse.org/pdt/"&gt;PDT&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Install php5 using&lt;br /&gt;sudo apt-get install php5&lt;br /&gt;sudo apt-get install php5-cli&lt;br /&gt;&lt;br /&gt;Install phpunit using&lt;br /&gt;&lt;br /&gt;sudo apt-get install php-pear&lt;br /&gt;sudo pear channel-discover pear.phpunit.de&lt;br /&gt;pear remote-list -c phpunit&lt;br /&gt;sudo pear install phpunit/PHPUnit&lt;br /&gt;&lt;br /&gt;Wow that was quick !&lt;br /&gt;Now you are ready to set up your Eclipse in order to have it run your test suite every time you modify a file !&lt;br /&gt;&lt;br /&gt;First open Eclipse.&lt;br /&gt;Click on Project-&gt;Properties&lt;br /&gt;Then click on Builders on the left.&lt;br /&gt;&lt;br /&gt;You should see an image similar to this one&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_vJCcAtCDEM8/S2o6v1zC0jI/AAAAAAAAABI/5_mfCcuJ6d8/s1600-h/CreateNewBuilder.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 360px;" src="http://2.bp.blogspot.com/_vJCcAtCDEM8/S2o6v1zC0jI/AAAAAAAAABI/5_mfCcuJ6d8/s400/CreateNewBuilder.png" alt="" id="BLOGGER_PHOTO_ID_5434220493945360946" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Create a builder with a name similar to the one I have created by clicking on new.&lt;br /&gt;You should see a screen similar to this one.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_vJCcAtCDEM8/S2o691-b47I/AAAAAAAAABQ/-N0n0hYUzVA/s1600-h/ConfiguringBuilder.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 315px;" src="http://3.bp.blogspot.com/_vJCcAtCDEM8/S2o691-b47I/AAAAAAAAABQ/-N0n0hYUzVA/s400/ConfiguringBuilder.png" alt="" id="BLOGGER_PHOTO_ID_5434220734511309746" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;A quick note on the variables used in the configuration :&lt;br /&gt;&lt;br /&gt;/usr/bin/php is the path towards the php executable on your machine&lt;br /&gt;{$workspace_loc} is the path towards you workspace&lt;br /&gt;&lt;br /&gt;/usr/bin/phpunit is the path towards my installed phpunit executable(on windows it would be your .bat file)&lt;br /&gt;&lt;br /&gt;--include-path "${project_loc}"  is being used to add an include path to the php.ini file that is loaded by my php executable. For my project, I need to add the path towards my project. It might be different for you&lt;br /&gt;&lt;br /&gt;/home/nick/workspacePHP/SUTA/expectations/ExpectationsSuite.php is the absolute path towards the test suite I want to run every time I save a file in my project.&lt;br /&gt;&lt;br /&gt;Finally all you need to do , is to click on the Build Options tab and select the&lt;br /&gt;option as seen on this picture&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_vJCcAtCDEM8/S2o7NPehQmI/AAAAAAAAABY/aFFG-_HWau8/s1600-h/AutoBuildsOption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 320px;" src="http://2.bp.blogspot.com/_vJCcAtCDEM8/S2o7NPehQmI/AAAAAAAAABY/aFFG-_HWau8/s400/AutoBuildsOption.png" alt="" id="BLOGGER_PHOTO_ID_5434220999054803554" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;That's it. Now there is a reason less for you not doing any TDD using PHP !&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For more info on PHPUnit's test suite &lt;a href="http://www.phpunit.de/manual/3.1/en/organizing-test-suites.html"&gt;click here.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4627125298843049979?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4627125298843049979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4627125298843049979' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4627125298843049979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4627125298843049979'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/02/using-eclipse-phpunit-as-automatic.html' title='Using Eclipse + PHPUnit as an automatic testing tool like autotest.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_vJCcAtCDEM8/S2o6v1zC0jI/AAAAAAAAABI/5_mfCcuJ6d8/s72-c/CreateNewBuilder.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-9207484973870766996</id><published>2010-02-01T21:24:00.000-08:00</published><updated>2012-01-25T19:27:39.095-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><title type='text'>Agile Lessons Learned #8 : Looking under the hood.</title><content type='html'>&lt;a href="http://farm3.static.flickr.com/2165/2002396040_3c849704ba_m_d.jpg"&gt;&lt;img alt="" border="0" src="http://farm3.static.flickr.com/2165/2002396040_3c849704ba_m_d.jpg" style="cursor: hand; cursor: pointer; float: left; height: 167px; margin: 0 10px 10px 0; width: 240px;" /&gt;&lt;/a&gt;&lt;br /&gt;Mike came over to Dan's house the other day. Mike had called him to give him a hand with a new secret project of his. &lt;br /&gt;"What the hell is he up to" Olly thought to himself. Mike always had these crazy programming projects in mind. &lt;br /&gt;&lt;br /&gt;"At least I might even learn a thing or two from the silly bastard" Mike whispered as he rang the bell to Mike's house. He got no answer. Mike tried again and still no answer. He tried Dan's cell phone and still no answer. Finally, as he left to go to his car he heard some loud music blasting from the garage.&lt;br /&gt;&lt;br /&gt;"Well, I stand up next to a mountain. And I chop it down with the edge of my hand..." Mike recognized Jimmy Hendrix blasting through the old stereo.&lt;br /&gt;&lt;br /&gt;"Dan !? DAAAAAAAN ! Are you there !?" Screamed Mike as he tried to be louder than the speakers.&lt;br /&gt;"Yeah, I'm down here "&lt;br /&gt;"Man I'm turning down that radio or we're both going deaf by the end of the hour."&lt;br /&gt;"What are you up to Dan ?"&lt;br /&gt;"I'm disassembling my outboard"&lt;br /&gt;"WHAT ? Why ?"&lt;br /&gt;"It's completely seized. Guess a piston is jammed. Gotta figure out why."&lt;br /&gt;"Oh, didn't know you were so versed in the fine art of marine mechanics."&lt;br /&gt;"You're making fun of me ?"&lt;br /&gt;"Well no. But since you called me I though we were gonna discuss a new software project. Something built around that Jazzy new web framework you were talking about."&lt;br /&gt;"Django ? Nah man the only Django you'll hear for the time being is on the radio."&lt;br /&gt;"Ok then, why are we here ? "&lt;br /&gt;"Aren't you pleased that you are here and listening to Hendrix play the guitar ?"&lt;br /&gt;&lt;br /&gt;"Actually right now all I hear now is both of us running our mouths. So what's the deal Dan? "&lt;br /&gt;"Well actually, I called you up for a very important mecha..programming lesson."&lt;br /&gt;"Oh really. Which is ?"&lt;br /&gt;"Well, you see most new programmers are afraid to dig up code."&lt;br /&gt;"It's like they believe the code they did not write is some kind of not understandable piece of work written by mystical beings."&lt;br /&gt;"Well if you saw some of the code I've seen you'd know some code is so bad it's like it came out pre-obfuscated..."&lt;br /&gt;"That's besides the point. The point I'm trying to make is this : How many times have you stopped in your track of understanding a library or piece of external code works because you were afraid to dig in ? "&lt;br /&gt;"Many times"&lt;br /&gt;"How often do you see it at work ? "&lt;br /&gt;"All the time."&lt;br /&gt;"Do you think it slows down your progress"&lt;br /&gt;"Definitely."&lt;br /&gt;"There you go, lessons learned my boy."&lt;br /&gt;&lt;br /&gt;"Now would you be so kind to roll up those sleeves of your and give me a hand removing the crank from this bad boy."&lt;br /&gt;"Ah man. I knew I shouldn't have gotten myself into this." grunted Mike as they lifted the crank.&lt;br /&gt;"You see now Mike, a compression ring completely blew off one of the piston and got jammed in the cylinder."&lt;br /&gt;"You just saved me 400$ worth of mechanics right there."&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-9207484973870766996?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/9207484973870766996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=9207484973870766996' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9207484973870766996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/9207484973870766996'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/02/agile-lessons-learned-7-dig-deeper.html' title='Agile Lessons Learned #8 : Looking under the hood.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-231535875020005045</id><published>2010-01-13T19:29:00.000-08:00</published><updated>2012-01-26T16:55:15.842-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><title type='text'>Agile Lessons Learned #7 : It takes two to tango.</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/statue001-copy/328903995_kBWRR-S.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="131" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/statue001-copy/328903995_kBWRR-S.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;In early April 1999, FreeFall inc's first major Web project was canned. Andrew, the lead tech on this project was now without a project to work on.&lt;br /&gt;&lt;br /&gt;Around that time,&amp;nbsp;professional&amp;nbsp;wrestling was the biggest thing on prime time TV. Andrew and his college buddies would gather on Monday nights to watch the rasslin.&lt;br /&gt;&lt;br /&gt;"Man, that old guy is just becoming a parody of his former self." Said Andrew&lt;br /&gt;"Whad do you mean" said Mike&lt;br /&gt;"Just look at him! He couldn't wrestle his way out of a paper bag. He's dragging all the young guys down. All of his latest matches have the crowd booing him out of the building."&lt;br /&gt;"Oh really ?  "How about his up and coming opponent; are they any good or just a bunch of jobbers ? "&lt;br /&gt;"Oh man they're great. They are doing this new fast-paced Japanese style of wrestling."&lt;br /&gt;"Oh ok. Couldn't they just make him look good ? The whole thing is staged after all you know..."&lt;br /&gt;&lt;br /&gt;"Look at them, they are booing &lt;span style="font-weight: bold;"&gt;both&lt;/span&gt; guys now. And they're cutting up the match short. "&lt;br /&gt;"One.....two....threeeeeeeeee ! It's all over !" said the commentator with some despair in his voice.&lt;br /&gt;"Finally it's over. Out with the dinosaur. Man I wish I could get rid of the dinosaurs I'm working with within a three count." Said Andrew.&lt;br /&gt;&lt;br /&gt;Andrew went on explaining how terrible it was to work with guys that were so behind the curve and so slow.&lt;br /&gt;&lt;br /&gt;"I wish I could help but this is pretty desperate. Management won't unblock any budget for training courses or for coaching."&lt;br /&gt;"That's sad. Ever tried doing some pair-programming with these guys?" said Mark&lt;br /&gt;"Pair programming? What's that ? "&lt;br /&gt;"Well basically two programmer sit together in front of a single computer and program together. Each of them has a specific role. The pilot and copilot, just like in a rally."&lt;br /&gt;&lt;br /&gt;"The pilot pretty much executes the coding, while the copilot takes notes of what the duo wants to accomplish, reviews what the pilot is doing and gives feedback on the work being done."&lt;br /&gt;"At a frequent interval, each of them alternate the roles. This breaks monotony and keeps you refreshed. How often have you felt drained after a long session of programming ?"&lt;br /&gt;"All the time !" admitted Andrew&lt;br /&gt;"Well this will help out. Also, this process will protect you from yourself. Meaning that with continuous peer review, it it much harder for you to justify introducing weird bits of code into the software "just to make it work".&lt;br /&gt;&lt;br /&gt;"Every time you try to do it , someone else will be there to catch it." said Mark&lt;br /&gt;"Actually after a while, most realize that the quality of their work starts going up. Way up."&lt;br /&gt;"Finally, working with a real human rather than working alone with a computer makes the whole programming process more human."&lt;br /&gt;"You will have to experience it for yourself to believe me, but you'd have a hard time going back to locking yourself away in a cubicle after a couple of weeks of pair programming."&lt;br /&gt;&lt;br /&gt;"That sounds great but how will that help me with elderlies? I mean won't they just slow me down?" said Andrew&lt;br /&gt;"At first yes, like anything new there is a learning period. But after a while, all the discussions brought by the continuous exchanges will bring the other guys up to speed like you wouldn't believe."&lt;br /&gt;&lt;br /&gt;"You know Andrew, it's true what they say : it really does takes two to tango."&lt;br /&gt;"What do you mean ?" wondered Andrew&lt;br /&gt;"Remember when we used to say that a particular wrestler was so good he could have a four-star match wrestling against a broomstick ?"&lt;br /&gt;"Yeah"&lt;br /&gt;"What it means is that if you really are as good as you pretend to be, it's your job to make other people better than they could ever be by themselves."&lt;br /&gt;"Who knows, you might even learn a trick or two from the old dogs."&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-231535875020005045?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/231535875020005045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=231535875020005045' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/231535875020005045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/231535875020005045'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2010/01/agile-lessons-learned-6-it-takes-two-to.html' title='Agile Lessons Learned #7 : It takes two to tango.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-3407778217061277294</id><published>2009-12-16T18:52:00.001-08:00</published><updated>2012-01-26T16:59:58.840-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><title type='text'>Agile Lessons Learned #6 : Waiting for a superman</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-PJNj6de44QY/TyH20tnTIDI/AAAAAAAAAJY/uw0QAK9eKAI/s1600/Superman.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="206" src="http://2.bp.blogspot.com/-PJNj6de44QY/TyH20tnTIDI/AAAAAAAAAJY/uw0QAK9eKAI/s320/Superman.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;As far as he could remember Marc always dreamed of being a pilot. After a few years of service as a bush pilot in the northern most par of the country, he finally got a break working for a regional transporter.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;In April that year, his engine was due for it's 3500 hour overhaul. Pat, the senior &lt;br /&gt;technician at Aviair Regional Airlines performed the overhaul, a routine job for him by then.&lt;br /&gt;&lt;br /&gt;As the FAA later found out, Pat got pressure from management to do the overhauls faster than usual as they really needed to get those planes off the ground during the harsh financial times of the enterprise. This caused him to leave a pressure hose on that was requiring change but that would also have required ordering a new piece and further delays.&lt;br /&gt;&lt;br /&gt;Unfortunately for Marc, the hose blew up mid-flight three weeks later while flying above mountains. He now had to decide whether he would crash in a farmer's field or in a country road nearby. Marc made a quick decision and decide to head towards the farmer's field.&lt;br /&gt;&lt;br /&gt;He managed to pull off a near perfect belly-landing in a field that was way rougher than anticipated. When the emergency crew got on the site of the crash they found Marc unconscious and half-disfigured. Had he been a lesser pilot, all 13 of his passengers would have died that day. &lt;br /&gt;&lt;br /&gt;Later that year, Marc got decorated for his heroic actions, as he saluted his former coworkers in the assistance for a last time. He saw this as his farewell, the accident having impaired his eye sight beyond possible repair, leaving him unable&amp;nbsp;to get medical clearance and thus revoking his pilot's license.&lt;br /&gt;&lt;br /&gt;As the news of his heroic act got around, Marc started to be asked to give speeches about his heroic act across the country. Marc was not seeking publicity, and although he appreciated all the warm feedback he got, he always politely turned&amp;nbsp;the offers down.&lt;br /&gt;&lt;br /&gt;One day, he got a call from Peter, a friend of his that was now a project manager at FreeFall inc. After the usual salutations, Peter got around asking Marc for a motivational speech.&lt;br /&gt;&lt;br /&gt;"It might even bring out a hero or two out of my employees ! You kno, the project really is in disarray." Said Peter&lt;br /&gt;"Well I don't know much about software development actually." Said Marc&lt;br /&gt;"But why do you need heroes ? " Marc continued.&lt;br /&gt;"Well everything is wrong. I really need someone to take the lead and fix our major issues. We have quality issues like you wouldn't believe." Said Peter, with his voice getting more desperate.&lt;br /&gt;&lt;br /&gt;"OK. Why do you need heroes? "&lt;br /&gt;"Because we have quality issues...I already told you that."&lt;br /&gt;"Ok so you wouldn't need heroes if you had no quality issues right?"&lt;br /&gt;"What do you mean?"&lt;br /&gt;"Well the only reason I'm unfortunately perceived as a hero is that I managed to do my job properly when someone was forced to slack the quality of his work " &lt;br /&gt;"I was doing my job properly for years prior to my accident, but you never heard of me in the news did you?"&lt;br /&gt;"Of course not but..."&lt;br /&gt;&lt;br /&gt;"Now, if their was no quality problem, your staff would only have to do their job and everything would be business as usual right ?" Argued Marc&lt;br /&gt;"Well yeah."&lt;br /&gt;"Anything you could do to help the quality of the software your guys are building right now ?"&lt;br /&gt;"Well the guys were talking about getting more time to do more unit testing and automated builds the other day, maybe I should give these guys a talk."&lt;br /&gt;"Who knows, might save you from having to deal with super heroes. Grown men wearing tights usually don't go over well in office meetings "&lt;br /&gt;"Point taken. Thanks Marc!"&lt;br /&gt;&lt;br /&gt;- Nicholas Lemay.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-3407778217061277294?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/3407778217061277294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=3407778217061277294' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/3407778217061277294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/3407778217061277294'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/12/agile-lessons-learned-5-waiting-for.html' title='Agile Lessons Learned #6 : Waiting for a superman'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-PJNj6de44QY/TyH20tnTIDI/AAAAAAAAAJY/uw0QAK9eKAI/s72-c/Superman.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-6165433742004985275</id><published>2009-10-20T19:25:00.000-07:00</published><updated>2009-11-07T06:43:55.622-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Splitting Django Models into multiple files.</title><content type='html'>In Django once one of your project's apps is getting large, you will undoubtedly start to have numerous models in your standard &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;models.py&lt;/span&gt;&lt;/span&gt; file.&lt;br /&gt;&lt;br /&gt;Say you have the following in your models.py file :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;models.py*&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;from django.db import models&lt;br /&gt;&lt;br /&gt;class Publisher(models.Model):&lt;br /&gt;&lt;br /&gt;      name = models.CharField(max_length=30)&lt;br /&gt;      address = models.CharField(max_length=50)&lt;br /&gt;      city = models.CharField(max_length=60)&lt;br /&gt;      state_province = models.CharField(max_length=30)&lt;br /&gt;      country = models.CharField(max_length=50)&lt;br /&gt;      website = models.URLField()&lt;br /&gt;&lt;br /&gt;class Author(models.Model):&lt;br /&gt;&gt;&gt;&gt;&gt;first_name = models.CharField(max_length=30)&lt;br /&gt;      &gt;&gt;&gt;&gt;last_name = models.CharField(max_length=40)&lt;br /&gt;&gt;&gt;&gt;&gt;email = models.EmailField()&lt;br /&gt;&lt;br /&gt;class Book(models.Model):&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt;&gt;title = models.CharField(max_length=100)&lt;br /&gt;&gt;&gt;&gt;&gt;authors = models.ManyToManyField(Author)&lt;br /&gt;&gt;&gt;&gt;&gt;publisher = models.ForeignKey(Publisher)&lt;br /&gt;  &gt;&gt;&gt;&gt;publication_date = models.DateField()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You start by creating the following python packages** by having the following file file structure on your file system:&lt;br /&gt;&lt;br /&gt;yourProjectsName&lt;br /&gt;----settings.py&lt;br /&gt;----urls.py&lt;br /&gt;----yourAppsName&lt;br /&gt;--------__init__.py&lt;br /&gt;--------models&lt;br /&gt;------------__init__.py&lt;br /&gt;&lt;br /&gt;Then you can add Author.py, Book.py and Publisher.py  under you models package. You should now have the following structure :&lt;br /&gt;--------models&lt;br /&gt;------------__init__.py&lt;br /&gt;------------Author.py&lt;br /&gt;------------Book.py&lt;br /&gt;------------Publisher.py&lt;br /&gt;&lt;br /&gt;In each of the respective classes, copy each of the the classes contained in you models.py file(Author, Book and Publisher). Don't forget the imports! ***&lt;br /&gt;&lt;br /&gt;The within each classes, you need to specify for which application the model is. The name should be the same as the the name of your app's package and the one specified in your projects settings.py file.&lt;br /&gt;&lt;br /&gt;For example, if your apps was named books, your would have the resulting&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Books.py file&lt;/span&gt; :&lt;br /&gt;&lt;br /&gt;from django.db import models&lt;br /&gt;&lt;br /&gt;class Book(models.Model):&lt;br /&gt;      &gt;&gt;&gt;&gt;title = models.CharField(max_length=100)&lt;br /&gt;      &gt;&gt;&gt;&gt;authors = models.ManyToManyField(Author)&lt;br /&gt;      &gt;&gt;&gt;&gt;publisher = models.ForeignKey(Publisher)&lt;br /&gt;      &gt;&gt;&gt;&gt;publication_date = models.DateField()&lt;br /&gt;&lt;br /&gt;  &gt;&gt;&gt;&gt;class Meta:&lt;br /&gt;      &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;app_label = 'books'&lt;br /&gt;&lt;br /&gt;That is it ! Once you start splitting your models, you will wonder what took you so long !&lt;br /&gt;&lt;br /&gt;* Example taken from the &lt;a href="http://www.djangobook.com/en/2.0/chapter05/"&gt;excellent and free Django Book&lt;/a&gt;&lt;br /&gt;** More on &lt;a href="http://www.network-theory.co.uk/docs/pytut/Packages.html"&gt;python packages&lt;/a&gt;&lt;br /&gt;*** You could use the &lt;a href="http://pydev.org/"&gt;excellent pydev eclipse plugin&lt;/a&gt; which will help remind you of missing imports.&lt;br /&gt;--Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-6165433742004985275?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/6165433742004985275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=6165433742004985275' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6165433742004985275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/6165433742004985275'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/10/separating-django-models-into-multiple.html' title='Splitting Django Models into multiple files.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-5110464663714232792</id><published>2009-10-12T13:29:00.001-07:00</published><updated>2012-01-25T04:43:46.839-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Imagine.</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#678675808_5bHBh"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/photos/678675808_5bHBh-S.jpg" style="cursor: hand; cursor: pointer; float: left; height: 266px; margin: 0 10px 10px 0; width: 400px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-5110464663714232792?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/5110464663714232792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=5110464663714232792' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5110464663714232792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5110464663714232792'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/10/imagine.html' title='Imagine.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-5548441479899316803</id><published>2009-10-12T13:02:00.000-07:00</published><updated>2012-01-25T04:43:35.463-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Finally some art in my picture gallery.</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#678645672_oYcie"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/photos/678645672_oYcie-S.jpg" style="cursor: hand; cursor: pointer; float: left; height: 266px; margin: 0 10px 10px 0; width: 400px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-5548441479899316803?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/5548441479899316803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=5548441479899316803' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5548441479899316803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/5548441479899316803'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/10/finally-some-art-in-my-picture-gallery.html' title='Finally some art in my picture gallery.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7316107380249074584</id><published>2009-10-05T07:47:00.000-07:00</published><updated>2009-10-05T07:48:45.899-07:00</updated><title type='text'>Creating a remote branch on your GIT repository</title><content type='html'>Geoff Leone has a great article on how to create a GIT branch on your remote GIT repo. Enjoy!&lt;br /&gt;&lt;br /&gt;http://www.zorched.net/2008/04/14/start-a-new-branch-on-your-remote-git-repository/&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7316107380249074584?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7316107380249074584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7316107380249074584' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7316107380249074584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7316107380249074584'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/10/creating-remote-branch-on-your-git.html' title='Creating a remote branch on your GIT repository'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7527276008599702244</id><published>2009-09-27T19:30:00.000-07:00</published><updated>2012-01-25T04:43:24.074-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Sunset at the vineyard.</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#663154043_upyyP"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/photos/663154043_upyyP-S.jpg" style="cursor: hand; cursor: pointer; float: left; height: 266px; margin: 0 10px 10px 0; width: 400px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7527276008599702244?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7527276008599702244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7527276008599702244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7527276008599702244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7527276008599702244'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/09/sunset-at-vineyard.html' title='Sunset at the vineyard.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4092249331004234962</id><published>2009-09-24T12:30:00.000-07:00</published><updated>2009-09-24T12:32:04.060-07:00</updated><title type='text'>Git Error - "git fatal: empty ident"</title><content type='html'>If you ever come accross this error, save yourself the time and money and follow the instructions below : &lt;br /&gt;&lt;br /&gt;$&gt; sudo chfn -f "John Doe" userjohndoe&lt;br /&gt;&lt;br /&gt;Thanks to http://evaisse.com/post/52748922/git-error-git-fatal-empty-ident for the tip.&lt;br /&gt;&lt;br /&gt;- Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4092249331004234962?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4092249331004234962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4092249331004234962' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4092249331004234962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4092249331004234962'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/09/git-error-git-fatal-empty-ident.html' title='Git Error - &quot;git fatal: empty ident&quot;'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-3057967536729559817</id><published>2009-09-18T13:12:00.000-07:00</published><updated>2009-09-30T06:12:36.573-07:00</updated><title type='text'>Setting up PostgreSQL on Ubuntu.</title><content type='html'>Here's how to install a fresh version of PostgreSQL on Ubuntu to be used with Django or Ruby On Rails :&lt;br /&gt;&lt;br /&gt;sudo apt-get install postgresql&lt;br /&gt;sudo apt-get install pgadmin3&lt;br /&gt;&lt;br /&gt;Edit your &lt;br /&gt;/etc/postgresql/8.3/main/pg_hba.conf and change the following line from&lt;br /&gt;&lt;br /&gt;local all all ident sameuser&lt;br /&gt;&lt;br /&gt;to :&lt;br /&gt;local all all md5&lt;br /&gt;&lt;br /&gt;Then &lt;span style="font-weight:bold;"&gt;reset your postgresql&lt;/span&gt; by exceuting the folowing line :&lt;br /&gt;sudo /etc/init.d/postgresql-8.3 restart&lt;br /&gt;&lt;br /&gt;Afterwards you can follow the instructions here to set a password for your postgres user :&lt;br /&gt;https://help.ubuntu.com/community/PostgreSQL&lt;br /&gt;&lt;br /&gt;Thanks to http://linuxdesk.wordpress.com/2008/10/10/ident-authentication-failed-for-user-postgresql/ for this helpfull tip.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-3057967536729559817?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/3057967536729559817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=3057967536729559817' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/3057967536729559817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/3057967536729559817'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/09/setting-up-postgresql-on-ubuntu.html' title='Setting up PostgreSQL on Ubuntu.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-399121207600897830</id><published>2009-09-10T18:42:00.001-07:00</published><updated>2009-11-07T06:45:17.481-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smugmug'/><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>Ragin bull in New York</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#678674358_nXnHU"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 265px;" src="http://nicholaslemay.smugmug.com/photos/678674358_nXnHU-S.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-399121207600897830?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/399121207600897830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=399121207600897830' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/399121207600897830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/399121207600897830'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/09/ragin-bull-in-new-york.html' title='Ragin bull in New York'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-1971362672118102525</id><published>2009-09-10T18:36:00.001-07:00</published><updated>2009-10-12T13:33:31.467-07:00</updated><title type='text'>A single missed step away from having mutant turtles in New york</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#678674912_pq2D6"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 266px;" src="http://nicholaslemay.smugmug.com/photos/678674912_pq2D6-S.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-1971362672118102525?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/1971362672118102525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=1971362672118102525' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1971362672118102525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1971362672118102525'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/09/one-step-towards-having-mutant-turtles.html' title='A single missed step away from having mutant turtles in New york'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-3844854161545957819</id><published>2009-09-08T08:23:00.000-07:00</published><updated>2012-01-26T17:06:34.687-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Agile Lessons Learned #5 : Adult day care(part 2)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-1CRIR57WjqY/TyH3_CZHGxI/AAAAAAAAAJo/q02zL6GmDQE/s1600/cubicles.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-1CRIR57WjqY/TyH3_CZHGxI/AAAAAAAAAJo/q02zL6GmDQE/s200/cubicles.jpg" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;Henry figured, one of the major problems of his team was communication problems. All his team members were dispatched throughout the office floor in small cubicles with sliding doors.&lt;br /&gt;&lt;br /&gt;The entire place was so quiet you sometimes felt like somebody had actually died.&lt;br /&gt;&lt;br /&gt;He still couldn't get his discussion with Tim out of his mind and he booked a dinner between the two on Friday which concluded with Tim coming in at FreeFall for a couple of month to drive an Agile transition.&lt;br /&gt;&lt;br /&gt;The team got off to a slow start, but eventually they got carried away and Tim had to step in and show them how to take the time to learn everything at a proper pace.&lt;br /&gt;&lt;br /&gt;"Baby steps, guys. Baby steps, that's the only way my boys " Tim said. As Henry tried to conceal his laughter.&lt;br /&gt;"What's so funny ? " asked Tim.&lt;br /&gt;"Well I find it amusing that you're telling the boys to take baby steps, while they're in day care"&lt;br /&gt;"Day care ? "&lt;br /&gt;"Well you know, we've got this running gag about FreeFall being a daycare center for adults and our cubicles play the role our parks did when we were young."&lt;br /&gt;"I get the picture." said Tim slightly amused.&lt;br /&gt;&lt;br /&gt;On Monday, Henry came in earlier than usual. Five minutes in and he was already purple in the face and storming towards Tim.&lt;br /&gt;"Are you out of your mind ?"&lt;br /&gt;"You just tore down our entire teams' cubicles and replaced them with folding tables ? &amp;nbsp;Some of my employees have lost their window privileges and are now sitting together with the interns. How am I supposed to justify this to my boss ? The union guys will tear me a new..."&lt;br /&gt;"Come on Henry. These are just silly cubicles. Give me a chance to prove that what I'm doing has value. I'll meet up with the team and I'll commit myself to two things :"&lt;br /&gt;"First : I'll do my best to make this work for the next two weeks"&lt;br /&gt;"Second : If the results are not here and they don't like it, they can have they old ways back. I'm willing to put my head on the log"&lt;br /&gt;&lt;br /&gt;Two weeks later during during the sprint review, most of the team members praised ScrumMaster for taking out the cubicles, which all recognized was an impediment to the team's success.&lt;br /&gt;&lt;br /&gt;At the end of the following sprint, the entire team decided to head out for lunch and beers at the local terrace. The sun was warm, the beer was cold, the staff was lovely and the discussions were great. After a few suds they realized they had seriously busted their lunch time. They could not have cared less. The team spirit was great.&lt;br /&gt;&lt;br /&gt;They eventually started looking like outcasts to the rest of the floor. Eventually the lunch and beer became a staple of this team and even as the team members came and went, the tradition seemed to hold on.&lt;br /&gt;&lt;br /&gt;When they left the office last Friday, the entire place went back to it's dead silence state.&lt;br /&gt;&lt;br /&gt;Had he kept his office's door open, you could have heard Pete, the other manager, cussing the director.&amp;nbsp;His team had been dysfunctional for months and now things were starting to get personal. And now his&amp;nbsp;&amp;nbsp;director was cutting off his budget.&lt;br /&gt;&lt;br /&gt;Pete thought he had the perfect plan. He had been working for the past few weeks on a secret team building activity with some outside firm. All it took was a 4 hour at a remote location which his boss would not finance.&lt;br /&gt;&lt;br /&gt;Sadly for Pete, had he followed in Henry's footsteps, his team would be doing team-building 35 hours a week every week, instead of 4 hours per year.&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-3844854161545957819?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/3844854161545957819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=3844854161545957819' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/3844854161545957819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/3844854161545957819'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/07/agile-lessons-learned-adult-day.html' title='Agile Lessons Learned #5 : Adult day care(part 2)'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-1CRIR57WjqY/TyH3_CZHGxI/AAAAAAAAAJo/q02zL6GmDQE/s72-c/cubicles.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-3356091989795293956</id><published>2009-09-01T19:46:00.000-07:00</published><updated>2012-01-26T17:06:10.770-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><category scheme='http://www.blogger.com/atom/ns#' term='self-organized teams'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Agile Lessons Learned #4 : Adult day care(part 1)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-1CRIR57WjqY/TyH3_CZHGxI/AAAAAAAAAJo/q02zL6GmDQE/s1600/cubicles.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-1CRIR57WjqY/TyH3_CZHGxI/AAAAAAAAAJo/q02zL6GmDQE/s200/cubicles.jpg" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Henry had been working for FreeFall for the past 4 years. As with most Monday mornings, Henry was late. He dreaded Mondays. He never came in on time. But he couldn't have cared less. None of his employees did. Neither did his superiors.&lt;br /&gt;&lt;br /&gt;Actually, it was expected for the higher ups to come in late. They called it working in the boss' timezone. As Henry dreadfully packed his frozen lunch into his reusable bag, he kissed his wife goodbye.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;"What's wrong honey ?" she said&lt;br /&gt;"Nothing special honey, it's Monday you know."&lt;br /&gt;"Don't worry about it sweetheart, you'll be be back in no time"&lt;br /&gt;"Yeah", he said with despair in his voice. "Right after adult day care..."&lt;br /&gt;"&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;Adult day care?&lt;/span&gt;&lt;/span&gt;" she said "What do you mean ?"&lt;br /&gt;"That's a phrase the guys coined up at work."&lt;br /&gt;"You know, just like when we were young our parents would drop us to day care " he asked&lt;br /&gt;"Yeah..."&lt;br /&gt;"Well our job is just like it. The difference is barely noticeable really..."&lt;br /&gt;"You're kidding me right" she said with a puzzled face&lt;br /&gt;"I'm not joking around. When we were kids our parents would drop us there in the morning and pick us up in the afternoon. At work, we take the commune and it drops us there&amp;nbsp;in the morning and they pick us back up in the evening"&lt;br /&gt;"Ok and ?"&lt;br /&gt;"At day care, the lady would drop each of us in our own little parks with a bunch of toys so we wouldn't bother each other"&lt;br /&gt;He took a break to see if she was still following him.&lt;br /&gt;"Well you see at work we each have our own little cubicles or closed offices and we have our computer to play with until our time is done and we can go back home"&lt;br /&gt;She clearly had heard enough.&lt;br /&gt;"Enough with your childish stories. You're just trying to get late to work. The sooner you leave the house the sooner you'll be done with it."&lt;br /&gt;"Of to work you go " She said as she kissed him on the cheek.&lt;br /&gt;&lt;br /&gt;As he made his way down the aisle of, he saw a familiar face.&lt;br /&gt;&lt;br /&gt;It was Tim, a former FreeFall employee who had been one of Henry's peers before the team got dismantled.&lt;br /&gt;&lt;br /&gt;Tim went on explaining that he had recently made a career change and had become a Scrum Master. He went on the main aspects of Scrum during the entire ride. For Henry, the commune had never gone by so fast.&lt;br /&gt;&lt;br /&gt;Henry was skeptical at first, but he really got hooked on the team aspects of Scrum. He thought about how well his former team used to do and how motivated they were when they first joined FreeFall.&lt;br /&gt;&lt;br /&gt;[&lt;a href="http://nicholaslemay.blogspot.com/2009/07/agile-lessons-learned-adult-day.html"&gt;Continued here&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-3356091989795293956?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/3356091989795293956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=3356091989795293956' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/3356091989795293956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/3356091989795293956'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/07/agile-lessons-learned-episode-1-adult.html' title='Agile Lessons Learned #4 : Adult day care(part 1)'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-1CRIR57WjqY/TyH3_CZHGxI/AAAAAAAAAJo/q02zL6GmDQE/s72-c/cubicles.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-1194247911395201451</id><published>2009-08-15T11:40:00.000-07:00</published><updated>2009-08-15T11:46:59.865-07:00</updated><title type='text'>Fireworks have a heart too</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/gallery/5370852_c2mUn#594969563_EeSnz"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 266px;" src="http://nicholaslemay.smugmug.com/photos/594969563_EeSnz-S.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.blogger.com/%3Chttp://nicholaslemay.smugmug.com/photos/594969563_EeSnz-S.jpg%22"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-1194247911395201451?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/1194247911395201451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=1194247911395201451' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1194247911395201451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/1194247911395201451'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/08/blog-post.html' title='Fireworks have a heart too'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-8554739766564445626</id><published>2009-08-01T06:29:00.000-07:00</published><updated>2012-01-26T17:06:59.482-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='retrospective'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><category scheme='http://www.blogger.com/atom/ns#' term='desire'/><category scheme='http://www.blogger.com/atom/ns#' term='commitment'/><title type='text'>Agile Lessons Learned #3 : The red pill.</title><content type='html'>&lt;blockquote&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;A man's life is primarly interesting when he has failed.&lt;/div&gt;&lt;div style="text-align: center;"&gt;For it's a sign that he tried to surpass himself.&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;-- George Clemenceau.&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Cy7tki-cFbw/TyH3avJ-xDI/AAAAAAAAAJg/uY_YrtzZhZY/s1600/red-pill.jpeg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-Cy7tki-cFbw/TyH3avJ-xDI/AAAAAAAAAJg/uY_YrtzZhZY/s320/red-pill.jpeg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Tim was an agile coach. One morning he bumped into Andrew, a senior manager over at FreeFall inc, a Fortune 500 company.&lt;br /&gt;&lt;br /&gt;"Hey Tim ! How bout that Agile thing ? Do you guys still do the Scrum in the morning ?&lt;br /&gt;"I don't know how to put this Andrew, but we don't 'do the Scrum' in the morning. &lt;br /&gt;Being Agile is way more than doing daily meetings."&lt;br /&gt;"Oh really? What else is there to the Scrum ?"&lt;br /&gt;"You might wanna grab a doughnut with that coffee, I've got a few things to show you"&lt;br /&gt;&lt;br /&gt;Tim went on explaining the different aspects of Scrum, the roles and the different ceremonies. But he knew the selling point to the manager was the continuous improvement brought by the frequent inspection and adaptation the teams puts itself through.&lt;br /&gt;&lt;br /&gt;You see, with Scrum all you problems will become apparent. Think of the problems as cream being poured into a coffee. If you just keep on pouring and stirring all the time everything gets blended in a confused mess. But if you take time to stop stirring, you'll get a clearer view of what's actually in your glass. &lt;br /&gt;&lt;br /&gt;For this to happen here are some important steps :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Courage :&lt;/span&gt;&lt;br /&gt;You can call yourself Agile if you want to. For that matter you can call a cat a dog if you want to. But you are not Agile without frequent introspection and a true and deep desire to be better tomorrow than you are today. &lt;br /&gt;&lt;br /&gt;This all start with courage. Courage to admit that you can be wrong. Courage to tell someone else that he/she was wrong. Courage to truly listen when someone is criticizing you. Courage to take what is on the table and make yourself a better you. A better team starts with a better you.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Desire :&lt;/span&gt;&lt;br /&gt;Why do you desire to become better today than you were yesterday ? What is you're source of motivation ? Are you so disgusted by you current situation ? Have you known better and want to recreate it ? Most importantly, do you see change as a desirable thing ? As a source of motivation ? &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Failure must be an option:&lt;/span&gt;&lt;br /&gt;If you are now allowed to fail, you cannot become better. You must be allowed to fail in order to be able to freely admit your failure in order to get feedback to help yourself get better. You should never seek failure, but you should not fear it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;A warning :&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once you start into this continuous self-introspection game you will be cursed. Most likely for life.&lt;br /&gt;You see once you start, all the problems your team is facing will start to emerge and gain visibility. It will then be your choice to address them or not.&lt;br /&gt;&lt;br /&gt;As Morpheus told Neo :&lt;br /&gt;&lt;br /&gt;"You take the blue pill, the story ends, you wake up in your bed and believe whatever you want to believe. You take the red pill, you stay in Wonderland, and I show you how deep the rabbit hole goes.&lt;br /&gt;&lt;br /&gt;So what's it gonna be ? The red pill or the blue pill ? Cause once you take the red pill, there is no turning back.&lt;br /&gt;&lt;br /&gt;Nicholas Lemay&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-8554739766564445626?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/8554739766564445626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=8554739766564445626' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8554739766564445626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8554739766564445626'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/11/agile-lessons-learned-3-red-pill.html' title='Agile Lessons Learned #3 : The red pill.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-Cy7tki-cFbw/TyH3avJ-xDI/AAAAAAAAAJg/uY_YrtzZhZY/s72-c/red-pill.jpeg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4920328725591419018</id><published>2009-07-10T19:23:00.000-07:00</published><updated>2012-01-24T18:10:05.166-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='hierarchy'/><category scheme='http://www.blogger.com/atom/ns#' term='peter principle'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><category scheme='http://www.blogger.com/atom/ns#' term='self-organized teams'/><title type='text'>Agile Lessons Learned #2 : In Peter we trust(ed).</title><content type='html'>&lt;br /&gt;Chris is a professional fishing guide. He actually gets paid to do what men work all year round to get to do for a single week. He came and picked up last Friday before the sun had even lifted. &lt;br /&gt;&lt;br /&gt;By 7h30 they both had caught their trout quotas and started chilling in the back of the boat looking for catfish.&lt;br /&gt;&lt;br /&gt;"Man can you believe I actually get payed to do this ?"&lt;br /&gt;"Yeah, ain't that a shame !"&lt;br /&gt;"So are you still the Master at your job?"&lt;br /&gt;"If you mean, SCRUM master then yes.I still am."&lt;br /&gt;"Oh excuse me, master of the scrums"&lt;br /&gt;"So when are you getting promoted to being God ?" Chris laughed.&lt;br /&gt;&lt;br /&gt;"Oh you mean just like Peter right ?"&lt;br /&gt;&lt;br /&gt;Peter was their former boss when they both were working in a warehouse back in college. The guy had no manners, no formal education but a truckload of ambitions. He went from broom-boy to foreman within his first year. Within five years, he was in charge of the entire shipping department. &lt;br /&gt;&lt;br /&gt;Before he hit the age of thirty, he was in charge of the entire regional section of the now multi-national enterprise. He used to have the following saying : &lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;"When I wake up, I tell God He can go back to sleep. I'm in charge now."&lt;/span&gt;&lt;/span&gt;. He repeated this phrase so often that he started believing his own hype.&lt;br /&gt;&lt;br /&gt;"Actually, I'm not in charge of anyone" said Tim.&lt;br /&gt;"Really ? "&lt;br /&gt;"Actually, I don't even have what you'd call a superior ? "&lt;br /&gt;"You're serious?"&lt;br /&gt;"Yeah. In Scrum the team is self-organizing."&lt;br /&gt;"Actually, baring similar talent, experience and other qualities, not a single one member is more important than another one. "&lt;br /&gt;"Wow, if Peter heard of this idea he'd blow a gasket!"&lt;br /&gt;"Damn straight."&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;Tim went on explaining the finer advantages of self-organizing teams :&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Members are more committed to the success of the project since they were all deeply involved in the decisions process. Feeling they have a certain amount of control of the project's destiny they rapidly get more and more involved and committed to the project.&lt;/li&gt;&lt;li&gt;No hierarchy means the people accountable for the success of the project are the ones working on it. This removes the pressure put on the teams through their superior who's usually the person that's accountable for the project's success yet is the person who has the less influence on the actual day-today work being done.&lt;/li&gt;&lt;li&gt;Self-organizing teams lets creative mind break loose. In teams where the job in imposed, the creative people in a team are stuck waiting for their boss to tell them how to do things instead of letting the ideas emerge from the most imaginative people of the group, whoever that may be.&lt;/li&gt;&lt;li&gt;In a traditional team, communication is centered around the superior. He/she is the communication bottleneck of the entire team.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;He also went on explaining how Scrum as a process is so well suited for self-organized teams:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Frequent inspections means the members skill progress more rapidly. As a side effect, team members build more confidence in themselves, empowering them to grow even more through the project.&lt;/li&gt;&lt;li&gt;Frequent releases means rapid adjustments. Teams do experience failures. But they are short lived and since they come from a short investment do not take as long to recover from.&lt;/li&gt;&lt;li&gt;The roles are well defined and expectations towards each of the teams members are set from the get-go.&lt;/li&gt;&lt;li&gt;Communication is encouraged through daily stand up meetings, sprint reviews and other activities. Also open space working areas and pairing is heavily promoted from many Scrum praticionners.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;"Wow that looks great said Chris. Too bad I never experienced self-organized teams when I was working ... I mean when I had a real job...You know what I mean."&lt;br /&gt;"You think it would of made things different ?"&lt;br /&gt;"Maybe. Wonder how a guy like Peter would fare in such an environment. That guy must have been promotted to C.E.O. by now"&lt;br /&gt;"Actually Peter got fired the other week"&lt;br /&gt;"REALLY?!"&lt;br /&gt;"Yeah saw his profile on LinkedIn. He was looking for a new job."&lt;br /&gt;"Wow. Must of stepped on too many toes."&lt;br /&gt;"Hehehe. Ever heard of the &lt;span style="font-weight: bold;"&gt;Peter principle&lt;/span&gt;?"&lt;br /&gt;"Can't say I have."&lt;br /&gt;"It came from a guy named &lt;span style="font-weight: bold;"&gt;DR Laurence J Peters&lt;/span&gt;. He wrote a book about the subject. It can actually be summed up to this: &lt;span style="font-weight: bold;"&gt;"In a Hierarchy Every Employee Tends to Rise to His Level of Incompetence"&lt;/span&gt; meaning that in a hierarchy, the best member of a certain level is usually promoted to a superior level. Thus someone will keep on getting promoted until he his no longer good enough to be promoted any further. Thus reaching his own level of incompetence.&lt;br /&gt;"Damn, Peter sure did have the right name."&lt;br /&gt;"Indeed he did, indeed he did" said Tim laughing.&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4920328725591419018?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4920328725591419018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4920328725591419018' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4920328725591419018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4920328725591419018'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/10/in-peter-we-trusted.html' title='Agile Lessons Learned #2 : In Peter we trust(ed).'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-2465663839179982767</id><published>2009-07-01T07:02:00.000-07:00</published><updated>2012-01-24T17:51:41.163-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='challenge everything'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='coaching'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile lessons learned'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Agile Lessons Learned #1 : Challenge Everything.</title><content type='html'>&lt;blockquote style="font-style: italic;"&gt;Grown-ups never understand anything by themselves, and it is tiresome for children to be always and forever explaining things to them - Le petit prince by Antoine de Saint Exupéry&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#615702326_dQMJm"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/escalade/615702326_dQMJm-S-1.jpg" style="cursor: pointer; float: left; height: 300px; margin: 0pt 10px 10px 0pt; width: 247px;" /&gt;&lt;/a&gt;&lt;br /&gt;Jonathan was in a rut. Despite his best efforts on FreeFall’s brand  new mega-project, nothing seemed to click. Everything just felt wrong.  He could not quite put his finger on it, but he just knew something was  going terribly wrong. Feeling powerless, everyday he got more and more  anxious about the whole ordeal. &lt;br /&gt;&lt;br /&gt;Once the project started to go haywire, FreeFall started to panic. Despite losing millions on the project, the had&amp;nbsp;a very limited budget for outside contributors. They decided to hire Erol as a single Agile coach to do  an assessment of the situation.&lt;br /&gt;&lt;br /&gt;One day Jonathan and Erol met at the cafeteria where Erol had  basically set up his office. Erol felt there was no better place to  start conversations with people than the cafeteria. Things that people  would never of said in meetings, Erol was told in a matter of  minutes. This jump-started his information collection like nothing else.&lt;br /&gt;&lt;br /&gt;“I know you are here to help us” said Jonathan.&lt;br /&gt;“I also feel that everything seems wrong but I can’t quite put my finger  on it. Can you help me out ?"&lt;br /&gt;“If you’ve got five minutes, I’ve got a real story that might help you.”&lt;br /&gt;&lt;br /&gt;Jonathan grabbed himself a coffee while Erol told him the following  story:&lt;br /&gt;&lt;br /&gt;“When I was young, I grew up in Haiti. I lived on the same street as all  of my family. This was great when parties were thrown. We’d just get  all together outside and party until the sun came up and then we’d party  some more.”&lt;br /&gt;“Christmas tradition was to cook a huge turkey based on the family  recipe that came all the way from my great-grandmother.”&lt;br /&gt;“The final step of the recipe was to chop a part of the turkey off  before putting it in the oven”&lt;br /&gt;&lt;br /&gt;“When she was six, my sister asked my mother why she was cutting off a  part of the turkey. She said it was because her mother did it like  that”&lt;br /&gt;“So my sister asked my grandmother why she did it like that.”&lt;br /&gt;“She said because her great-grand mother did it like that.”&lt;br /&gt;“She then went on to see her great grand-mother”&lt;br /&gt;“She asked her why she cut off a part of her turkey”&lt;br /&gt;“She said, that she used to do it like that because her oven was too  small to fit a turkey back then”&lt;br /&gt;&lt;br /&gt;“You see, for generations, my family had been throwing away a part of  their turkey for no good reason. If my sister did not challenge every  member of my family until she found the root of the problem, we would of  been throwing away turkey for generations to come even though the  answer had lied next door for years.”&lt;br /&gt;“Maybe I should start challenging what seems wrong” – said Jonathan&lt;br /&gt;“Maybe you should Jon, maybe you should…”&lt;br /&gt;&lt;br /&gt;-Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-2465663839179982767?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/2465663839179982767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=2465663839179982767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2465663839179982767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/2465663839179982767'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/11/agile-lessons-learned-4-challenge.html' title='Agile Lessons Learned #1 : Challenge Everything.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-248094603356569108</id><published>2009-05-21T18:48:00.001-07:00</published><updated>2011-01-10T10:56:49.539-08:00</updated><title type='text'>Summer's a coming.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/Other/My-Gallery/5370852_c2mUn#382962993_KRofr"&gt;&lt;img style="cursor: pointer; width: 400px; height: 266px;" src="http://nicholaslemay.smugmug.com/Other/My-Gallery/whaleBoat/382962993_KRofr-S.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;"&lt;strong&gt;Care About Your Craft&lt;/strong&gt;" - pragmatic programmer.&lt;br /&gt;&lt;br /&gt;Boating season is upon us. I've just passed my boating exam. I'll spare the details. The less said about the entire procedure the better.  I'm keeping this one short as to simply force myself to update this blog more often. But I'll leave you that preceding quote to ponder upon.&lt;br /&gt;&lt;br /&gt;- Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-248094603356569108?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/248094603356569108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=248094603356569108' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/248094603356569108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/248094603356569108'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/05/summers-coming.html' title='Summer&apos;s a coming.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-8002599446215718913</id><published>2009-01-20T17:39:00.000-08:00</published><updated>2009-05-24T06:50:00.008-07:00</updated><title type='text'>Ergonomy(lessons learned)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/photos/457614688_xsbhN-M.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 270px; height: 179px;" src="http://nicholaslemay.smugmug.com/photos/457614688_xsbhN-M.jpg" alt="" border="0" /&gt;&lt;/a&gt;This week, the &lt;a href="http://www.salonautomontreal.com/en/index"&gt;Montreal auto show&lt;/a&gt; is being held at the &lt;a href="http://www.congresmtl.com/"&gt;palais des congrès&lt;/a&gt;. For many people, it's their first peek at the many cars they will be shopping for during the year.&lt;br /&gt;&lt;br /&gt;While listening to the people voicing their opinions while trying out the different cars, it was obvious that a car's interior design, it's "ergonomy" could very well be a deal maker or a deal breaker. Many people were not commenting on how powerful a particular car's motor was or on well it handled in a stiff curve.&lt;br /&gt;&lt;br /&gt;From simply sitting in the car, getting out and getting an overall "feel" on the car's interior design a lot of people either walked away from the car or stayed to look further at the cars spec sheet that contained the price, the fuel consumption, available accessories etc. Features on which you would expect most people to base their decision to make a 15K$ + investment.&lt;br /&gt;&lt;br /&gt;All of this made me think about software design article named "&lt;a href="http://www.codinghorror.com/blog/archives/001022.html"&gt;Nobody cares what you code looks like&lt;/a&gt;." People will not care how well something is built if it is not appealing to them first. Car designers and software designers alike are victim of this reality. They say you do not judge a book by it's cover. In Montreal that day, there sure was a lot of people  judging a car by it's interior.&lt;br /&gt;&lt;br /&gt;- Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-8002599446215718913?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/8002599446215718913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=8002599446215718913' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8002599446215718913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/8002599446215718913'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/01/ergonomylessons-learned.html' title='Ergonomy(lessons learned)'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4598768781687166183</id><published>2009-01-20T16:25:00.000-08:00</published><updated>2012-01-23T20:07:03.850-08:00</updated><title type='text'>Entrepreneurship dualism.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nicholaslemay.smugmug.com/photos/401002570_rakUs-L.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 359px; height: 238px;" src="http://nicholaslemay.smugmug.com/photos/401002570_rakUs-L.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;"Keep your eyes on the stars, and your feet on the ground."&lt;br /&gt;                                                                                                 - Theodore Roosevelt&lt;br /&gt;&lt;br /&gt;Why is it that that the very things that drive so many away from large companies and out to start their own business, sooner or later become part of their own endeavour ? Flexibility, freedom of choice, lack of hierarchy and bureaucracy are often cited amongst reason why people start their own business. Oftentimes, it is done in reaction to one's disgust of his current situation.&lt;br /&gt;&lt;br /&gt;You would be hard pressed to find a large number of entrepreneurs whose dream is to build up a large enterprise devoided of a humane nature. Yet, how many times have you had to deal with a small enterprise gone big where every task and every decision seemed to be money-driven at the expense of everything else ? How is that so ? Does that not go against most entrepreneurs own "raison d'être" ?&lt;br /&gt;&lt;br /&gt;Entrepreneurs watching their own creation turn into a profit-at-all-cost entity devoided of any vision and soul are not leaders. They are merely bystanders. Extraordinary leaders will take their organisation into the next level without compromising their deepest beliefs. &lt;br /&gt;&lt;br /&gt;- Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4598768781687166183?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4598768781687166183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4598768781687166183' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4598768781687166183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4598768781687166183'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/01/entrepreneurship-dualism.html' title='Entrepreneurship dualism.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7420962131936609935</id><published>2009-01-13T06:34:00.000-08:00</published><updated>2009-05-24T06:50:35.949-07:00</updated><title type='text'>Quote of the day.</title><content type='html'>Quote of the day : "Experience does not prevent you from doing the same mistake over and over again. From all accounts, all it does is allow you to recognize a mistake once you have done it again"&lt;br /&gt;&lt;br /&gt;- Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7420962131936609935?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7420962131936609935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7420962131936609935' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7420962131936609935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7420962131936609935'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/01/quote-of-day-experience-does-not.html' title='Quote of the day.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-4716821744595937694</id><published>2009-01-06T16:10:00.000-08:00</published><updated>2009-05-24T06:50:55.043-07:00</updated><title type='text'>M or : The complexity of simplicity.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_vJCcAtCDEM8/SWPzHE1_4RI/AAAAAAAAAAQ/ttXbEr7P2L4/s1600-h/m.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 274px; height: 320px;" src="http://1.bp.blogspot.com/_vJCcAtCDEM8/SWPzHE1_4RI/AAAAAAAAAAQ/ttXbEr7P2L4/s320/m.jpg" alt="" id="BLOGGER_PHOTO_ID_5288337690347954450" border="0" /&gt;&lt;/a&gt;From the one letter title to the credit-less ending of the first disc, the movie M shines through the details emanating from it's perceivable simplicity.&lt;br /&gt;&lt;br /&gt;Made in 1931 as &lt;a href="http://www.imdb.com/name/nm0000485/"&gt;Fritz Lang's&lt;/a&gt; first non-silent movie, it is rather mind-boggling to realize that sound techniques used during this movie are still being used today, and sometimes with less impact than during a movie made over 75 years ago. Fans of &lt;a href="http://www.imdb.com/name/nm0000233/"&gt;Quentin Tanrantino's&lt;/a&gt; &lt;a href="http://www.imdb.com/title/tt0266697/"&gt;Kill Bill&lt;/a&gt; will soon spot similarities between the use of sound for two of the movies evil  character.&lt;br /&gt;&lt;br /&gt;As for the plot, while straightforward, it keeps the viewers engaged in seeing how it will develop. Instead of building the suspense slowly and building the end into a crescendo, the authors opted to give away details as the movie goes along. Nevertheless, one can't help but feel a sense of intrigue as to what will happen next.&lt;br /&gt;&lt;br /&gt;As for the subject matters of this movie, they are still as relevant as they were 75 years ago. The debates being portrayed, especially the ones concerning the death penalty and the frustrations stemming from the treatment reserved to the mentally ill criminals could still be used within modern films.&lt;br /&gt;&lt;br /&gt;Other themes, like honor among thieves and portraying the criminals and policemen as shades of gray instead of black and white are as present in this movie as in more recent classics as &lt;a href="http://www.imdb.com/title/tt0060196/"&gt;The Good, the Bad and the Ugly(1966&lt;/a&gt;) and &lt;a href="http://www.imdb.com/title/tt0105236/"&gt;Reservoir Dogs(1992).&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.imdb.com/title/tt0022100/"&gt;M&lt;/a&gt; is rated at number #45 on &lt;a href="http://www.imdb.com/chart/top?tt0022100"&gt;IMDB's top 250&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;- Nicholas Lemay&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-4716821744595937694?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/4716821744595937694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=4716821744595937694' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4716821744595937694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/4716821744595937694'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2009/01/m-or-complexity-of-simplicty.html' title='M or : The complexity of simplicity.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_vJCcAtCDEM8/SWPzHE1_4RI/AAAAAAAAAAQ/ttXbEr7P2L4/s72-c/m.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150179455008593965.post-7083633380571989878</id><published>2008-10-09T06:34:00.000-07:00</published><updated>2012-01-25T04:43:04.364-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pictures'/><title type='text'>My first blog post ever.</title><content type='html'>&lt;a href="http://nicholaslemay.smugmug.com/photos/380788020_vmPk6-L.jpg"&gt;&lt;img alt="" border="0" src="http://nicholaslemay.smugmug.com/photos/380788020_vmPk6-L.jpg" style="cursor: pointer; width: 320px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150179455008593965-7083633380571989878?l=nicholaslemay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nicholaslemay.blogspot.com/feeds/7083633380571989878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1150179455008593965&amp;postID=7083633380571989878' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7083633380571989878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1150179455008593965/posts/default/7083633380571989878'/><link rel='alternate' type='text/html' href='http://nicholaslemay.blogspot.com/2008/10/my-first-blog-post-ever.html' title='My first blog post ever.'/><author><name>nicholaslemay</name><uri>http://www.blogger.com/profile/06681271236386408007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
