Monday, October 15, 2012

Women in IT


I have come to appreciate the unique perspective each of us brings to the job.  By "perspective" I am going beyond technical skills and programming acumen.  It is that intangible quality that determines our design decisions, the thought process that directs our problem-solving strategy, that dictates how we communicate with our team. 

I feel that unique secret sauce that makes us who we are is involuntarily seeded by our gender.  To get a full breadth of capabilities I think it best if projects have both men and women.  The most successful projects in which I have been involved included a mix of men and women.  I don't think it is simply a coincidence.  I know that it is a key reason for the project's success.  It is therefore regrettable that there aren't more women in our line of work.

I came across a thought-provoking blog post by Ted Neward on this very subject.  In case you aren't familiar with Ted, he is an outstanding technologist.  I got to know Ted back when I used to speak on the NoFluffJustStuff tour.  The thing about Ted is that not only does he have impeccable technical credentials (Java, .net, Android, etc etc) he is not shy to share his opinion.  His presentations are quite an experience -- just be prepared for a side-bar or two on unrelated topics :-)

Here's hoping more women join the IT workforce.

Saturday, January 29, 2011

Can't Git enough

Couple of weeks ago I attended the January offering of GitHub's online Git class taught by Matthew McCullough. I had been using Git for a little over a month and was starting to plateau off. I grokked the basics (at least so I thought) and stayed within the lines. The timing of the course was perfect for me. It helped solidify some concepts, explain the git idiom and presented several aha! moments. It was the kind of course that leaves you energized and exhausted at the same time. Energized because you learned something that you could apply immediately (like during the lunch break :-) and exhausted because you were facing a fire-hose of information for 7 hours!

The course material was well organized starting with just enough background information used to set the stage. Demonstrating Git's pedigree (been around for over 10 years) in the SCM space lent credence to those not impressed with its slavish following in the industry. The material was in resonance with what Matthew was saying -- amplifying his point where necessary, enumerating steps, screenshots where appropriate and links for additional information. Another sign of his thoroughness was demonstrating setup in all major platforms and not leaving the student high and dry having to connect the dots. Over the course of 7 hours (Six 50-min sessions with an hour for break) the class covered everything from setup to 3-stage thinking, branching, remote repos, with just the right amount of peek under-the-hood to explain how Git works.

The format of the course was as hands-on as you wanted it to be. The attendees were provided instructions in advance of the class on setting up their local environment. During the course Matthew helped us connect to the GitHub repository he was referencing. This allowed as to follow along with the steps he was doing as he was doing it! If that wasn't your style you could just watch and listen. It was very stimulating and engaging -- especially when several of us were simultaneously pushing our changes to the same remote repository!!


Matthew McCullough did a first rate job of the online class. It was conducted over WebEx and went over without any major hitch. I was impressed with how Matthew kept up with several stimuli vying for his attention. He addressed the questions being posed over WebEx, emails sent to him andeven tweets all the while staying on course! I wonder if he did a git clone matthew before the class! He answered questions and addressed issues seamlessly as if it were part of the course material.

Matthew belongs to a rare breed that is at the locus of knowledge of the subject, desire to teach and thoroughness of preparation. He set the bar very high at other fora at which I have watched him teach. This Git class did not disappoint. He did his homework and came prepared to teach. From attending several software symposia I can tell you that this is a rare trait. Presenters tend to lean heavily on the content. Yes, content is King. However one should know how to deliver it. Think: Otherwise I could just read the book. Matthew's passion not just for Git but for teaching shone through even at hour-7 of the class!

If you are new to Git you could not do any better than having Matthew as your teacher.

Friday, June 19, 2009

A rose by any other name...

Martin Odersky, Lex Spoon, and Bill Venners have collaborated to venture where everyone has gone before. Yes, I mean the age old story about right way to override the equals method in Java. I see you rolling your eyes with the "I know, I know I must override hashcode method as well" bored refrain.

Spare me a few more minutes and I will convince you that you must give the article a serious once over. I for one got a better appreciation of the complexity of the problem -- if you want it addressed fully.

The article warms up around the 3rd of the four pitfalls they identify
  1. Defining equals with the wrong signature
  2. Changing equals without also changing hashCode
  3. Defining equals in terms of mutable fields
  4. Failing to define equals as an equivalence relation
Pitfall #3 discusses what happens when the state of an object that has been placed in a collection is modified. Typical equalsmethod implementation will result in it disappearing from the collection.

public class Point {
private int x, y;
public Point(int i, int j) { x = i; y = j; }
public int getX() { return x; }
public void setX(int i) { x = i; }
public int getY() { return y; }
public void setY(int i) { y = i; }
@Override public int hashCode() { return 41 * (41 + getX()) + getY(); }
@Override public boolean equals(Object other) {
boolean result = false;
if (other instanceof Point) {
Point that = (Point) other;
result = (this.getX() == that.getX() && this.getY() == that.getY());
}
return result;
}

}
..
HashSet hashSet = new HashSet();
Point p = new Point(1, 2);
hashSet.add(p);
p.setX(12);
System.out.println(hashSet.contains(p)); // <-- Prints false!!

Yep! A forehead smacking moment alright. The article suggests a way around this problem. Which leads us to the 4th pitfall -- that of equivalence. This means that for non-null values, the following is true about the equals method:
  • Reflexivity: x.equals(x)
  • Symmetry: x.equals(y) => y.equals(x)
  • Transitivity:x.equals(y) and y.equals(z) => x.equals(z)
  • Consistence: x.equals(y) always returns the same result
  • x.equals(null) is always false
With clear and concise examples, the article explains the complications of these contracts and how to implement them.

Tuesday, April 07, 2009

Run a single JUnit test method in Eclipse

Goes to show you, that you can teach an old dog new tricks. After years of using Eclipse I stumbled across a feature I am sure has existed since the glory days of Visual Age.

I had added yet another test method to a large JUnit TestCase class. I wanted to just run and re-run the new method 'til I had it just right without having to run all the other methods as well.

Yes of course, I could comment out all the other methods or just remove the @Test annotation. Back in the JUnit 3 days we have all -- at one time or another -- disabled tests by changing the "test" prefix of the test methods.

Somehow today, all these seemed abhorrent.

I wondered what would happen if I simply highlighted the method I wanted to test, and selected Run As > JUnit Test from the context menu.

Voila! That was the ticket!! It ran just the test I had wanted run.

As a bonus it even added TestCase.method_name as a "Run Configuration" for ease of future use.

FTW!

Friday, February 27, 2009

Mockito: Most helpful stacktrace

One of the things I have admired about the Spring framework is its helpful error messages. Yeah, of all the things I could point to, I picked that....However, work with me here. What I mean is that when things go wrong when using Spring, it spits out error messages that are full sentences that make sense and point the developer in the proper direction. None of the NoClassDefFoundError but not telling who which freaking class.

Now, I think Mockito -- the Java mocking framework -- has taken over the mantle of "King of error messages". Earlier today I had a new unit test I had just written fail. I didn't have to dig too much to find the error because Mockito pointed the way with the following stacktrace.

org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unifinished stubbing detected!
E.g. toReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Also make sure the method is not final - you cannot stub final methods.
at
etc. etc.

How cool is that! Hats off, Mockito-team. This developer appreciates the extra few minutes you took to put together that message. It helped me immensely.

Wednesday, February 18, 2009

Tab navigating the Mac UI

It was driving me nuts when I got my MacBook that I could not use the tab button to navigate across a form. Let alone forms, on a browser page, I could only tab between the address bar and the search field. To go anywhere else, I had to reach for the mouse. Aaargh!!

Surely the operating system that was God's gift to humanity could do better than that! It took a fair amount of Googling for me to find the obscure setting that controls it.

Here's what you need to do in order to be able to tab away across the entire screen.

Bring up the System Preferences window and select Keyboard & Mouse from the Hardware Category.



From the "Keyboard & Mouse" panel, select the "Keyboard Shortcuts" tab. The magical setting is at the bottom of that tab. Allow "Full keyboard access" by selecting the "All controls" radio button.



As this panel shows, you can impress your colleagues by toggling this setting using CTRL+Fn+F7.

The question remains, who in their right mind thought that the default setting was to be "Text boxes and lists only"!!

Friday, February 13, 2009

JUnit 3 & JUnit 4: Oil & water

Version 4 of the popular JUnit test framework has been available for use for quite some time (In fact, it is up to version 4.5). However, many projects have a wealth of JUnit 3-style tests and developers may choose to continue using it. If, on the other hand, you decide to dip your toes in JUnit 4 waters, make it a complete immersion. Don't try to mix and match.

As you may be aware, couple of the touted "benefits" of JUnit 4 are the obviation of extending the TestCase class and the identification of test and lifecycle methods (setUp and tearDown) using Java 5 annotations. For example, the following is a valid JUnit 4-style test case (minus the necessary imports):

public class BusinessLogicTests {
  @Before
  public void do_this_before_every_test() {
    // set up logic goes here
  }

  @After
  public void clean_up_after_a_test() {
    // teardown logic goes here
  }

  @Test
  public void addition() {
    assertEquals("Invalid addition", 2, 1+1);
  }
}

Observe how

  • The class does not extend TestCase

  • The "setup" and "tearDown" methods are identified by annotations

  • The test method does not require a "test" prefix and is also annotated


I'll let you be the judge of whether this is an improvement on JUnit 3. What I want to alert you to are the perils of subconciously mixing JUnit-3 and JUnit-4 style programming. Consider the following test case:

public class BusinessLogicTests extends TestCase {
  @Before
  public void do_this_before_every_test() {
    // set up logic goes here
  }

  @After
  public void clean_up_after_a_test() {
    // teardown logic goes here
  }

  @Test
  public void testAddition() {
    assertEquals("Invalid addition", 2, 1+1);
  }

  @Test
  public void subtraction() {
    assertEquals("Invalid subtraction", 1, 1-1);
  }
}

This will result in a green-bar even though there is an error in the test of subtraction. Can you guess why?

It was that pesky little extends TestCase that I added from force of habit. The flips the switch to JUnit-3, which knows nothing about annotations, ignores my setup and teardown methods and looks for methods prefixed by test. It completely ignores the method named subtraction!

And of course, conversely, the following is just a plain old Java class that won't be acknowledged by either JUnit-3 or JUnit-4.

public class BusinessLogicTests {
  public void testAddition() {
    assertEquals("Invalid addition", 2, 1+1);
  }
}

Final word of advice, if you are using Struts Test Case, you have no choice but to write JUnit-3 style tests since the parent class of the framework (MockStrutsTestCase) extends Junit-3's TestCase.

Tweety thoughts

    follow me on Twitter