Thursday, January 10, 2013

Patterns for successful training sessions


I have been doing quite a number of sessions over the last few years. Theses are the techniques / patterns that appear to me to be most successful:
  1. Shock and Awe: Make very clear that you are the boss and no one has to question your knowledge or approach. Become mildly aggressive when first critical words come up. More aggression is hardly necessary, but increase aggression level when desired. 
  2. Smoke Grenade: When asked stuff you have no idea about, do not admit it or even ask if someone else has a clue, but rather talk about a lot of complicated stuff that does not make much sense but makes you look smart. Will very likely cause confusion, but of course the one asked is to blame as you are obviously smart and the other one is just not smart enough to understand. If the guy asking is actually dumb enough to admit that he/she did not understand and asks you to explain again switch to (3).
    1. There is at least one variation of this pattern, where you do not admit that you have to clue, but rather put the question back to your audience, like "Can someone else answer that question?". More mild and probably applicable in isolation of the other patterns as well.
  3. Humiliation: If someone asks stuff and makes comments that might become tricky for you, make fun of her/him in front of the others. For example: "Ok, for Larry I am going to explain it one more time, maybe this time he gets it. Finally!". Works best as follow up for (2). Make sure you have applied (1) so that no one dares to take sides with poor Larry.
  4. Betrayal: Probably one of the more wimpy techniques. This is about not keeping what you promised. This could be not answering a certain question that you postponed by saying "We will come to that later", but you had no clue how to ever answer that question. Or it could be a certain topic that you might feel too shaky to handle. There are two variants of this pattern
    1. "Forgetting" to keep the promise or "loosing" the paper that should remind you of something
    2. At the very end of the session, mentioning that it was just too much stuff and you could not possibly handle the other stuff you had promised
I am pretty sure there are more patterns that I have observed, but yet failed to fully identify. Please help me by leaving comments about what you have experienced or identified and I will extend the list. 

And, yes, before anyone complains: This is indeed meant like ;)

As a footnote and most surprisingly, if I had paid more attention, I could have learned about those patterns in high-school already, because all of them had been applied to me by my teachers at that time :)  

Thursday, November 1, 2012

Adding Google Analytics to my angular.js based site

Added code snipped emitted from Google Analytics App to index.html, then added this to main controller
    $scope.$on('$viewContentLoaded', function(event) {
        $window._gaq.push(['_trackPageview', $location.path()]);
    });

Done. Full tracking just works. Amazing!

Tuesday, May 1, 2012

What kind of developer are you?


(1) Russian technology or Dr. Simplify

public Customer save(Customer customer) {
  inject();
  try {
    check(customer);
    Customer saved = customerService.save(customer);
    return customerDao.detach(saved);
  } catch (Exception e) {
    Messages messages = handleException(e);
    customer.setMessages(messages);
    return customer;
  }
}

(2) Mr/Mrs 2003


public Customer save(Customer customer) {
  return new BoundaryTemplate() {

    @Override
    public Customer wrap(Customer customer) {
      check(customer);
      Customer saved = customerService.save(customer);
      return customerDao.detach(saved);
    }
  }.executeOn(customer);
}

(3) Human minifier


@BoundaryWrapper
public Customer save(Customer customer) {
  check(customer);
  Customer saved = customerService.save(customer);
  return customerDao.detach(saved);
}

I have a strong bias that might surprise you, but please give me your votes before I confess.

Why do we need another compiler generator?

A conversation I had with Terence Parr, the creator of ANTLR, about why there is a new version of ANTLR.

Tuesday, February 1, 2011

Test all your states

I never even thought I would write a post about unit tests.

Why? Because it is such a dogmatic approach, invented by people far from practical experience. The dogmatic application of Test Driven Development would for sure have ruined my company and any single project that I worked on.

That was the disclaimer :)

But...

when you have a library that is actually easy to test because it has a relatively small and well defined interface, it might be a good idea to add unit tests. Even when you are in a hurry and just hack that shit away, a test driven approach might be useful (just notice my use of the word "might").

If you actually do so I'd advice to write tests for every state (do not care for 100% code coverage - it does not say anything and might even be misleading) that comes to your mind even if you think it is ridiculous. I know, depending on the input, this might be impractical, but you can at least try.

Let me give you an example from my current open source project the "Java Minimal Template Engine".

I remember I was thinking about an else inside a foreach while I already had a test for an if without the else part inside a foreach. Obviously two different states. First: simple if inside foreach, second if with else block inside foreach.

I thought, I know the code that evaluates that stuff and I know that it really does not make a difference if the else is inside a foreach or not. And I had a test for that else outside a foreach. And I was right. I skipped the test. Code worked.

Time passed.

I refactored the complete core of the template engine. I felt save to do so as I had a good bunch of unit tests.

After the refactoring, it did make a difference if that else was inside that foreach and - of course - I sill had no test for it. All tests passed after refactoring. But I made a really silly mistake in the refactored code and else inside foreach was broken. And it wasn't me who discovered that ;)

See the point? Just because you know the code and you know it does not make a difference now, does not mean this will remain true when time passes and the code changes. It might not even be you who changes that code.

Those tests are there to protect you, so either take them seriously or skip them completely. So: Test all your states.

Against any dogmatic approach

I am just against any dogmatic approach to anything.

Because dogmatic approaches do not work. If they did even AI might eventually succeed (I no longer believe in it).

Because it is arrogant and maybe ignorant to even suggest or advice a dogmatic approach to others.

This is a dogmatic approach? Then this is the only viable exception :)

Monday, January 24, 2011

Parsing very simple expressions in Java

You might say parsing such a simple expression

function(param1, param2)
(and the like) is easy even if you want escaping of special characters and quoted parts. At least that's what I said.

Obvious approaches include using standard Java classes
  1. StringTokenizer
  2. Scanner
  3. Regular Expressions (sometimes coming in disguise as direct String methods like String.split)
  4. Use a lexer generator like http://www.cs.princeton.edu/~appel/modern/java/JLex/ or http://jflex.de/
  5. Using a full parer generator like http://www.antlr.org/
  6. doing this by hand using low level String functions, e.g. indexOf and substring
  7. remember your C days and still do this by hand, but rather by iterating through the input character by character
What did I do?
  • Options (1) and (2) do not work as they are not powerful enough, especially when it comes to escaping. Besides they are slow
  • Option (3) might acutally work, but besides being slow, dealing with complex regular expressions and the Java API for it is something I can not recommend. Even after reading and groking this tutorial would you want to write and maintain regular expressions? Try it. I don't.
  • (4) and (5): Having the full burden of a generated lexer plus runtime libraries or even a full generated parser is hardly worth the effort considering the simplicity of the expressions, even though both approaches would solve the problem.
Which leaves me doing it by hand - which I wound up doing. First I persued option (6) which did the job, but resulted in code very hard to read and very hard to maintain.

I then turned to option (7) and things became both easy and fast. I even came up with a very simple utility class that not only handles the above case, but other similar inputs. This is a test case for that utility class

@Test
public void scanAndSplit() throws Exception {
String input = "function(param1, param2)";
List segments = MiniParser.defaultInstance().scan(input, "(", ")");
assertEquals(2, segments.size());

String functionName = segments.get(0);
String parameterString = segments.get(1);
assertEquals("function", functionName);
assertEquals("param1, param2", parameterString);
List parameters = MiniParser.trimmedInstance().split(parameterString, ',');
assertEquals(2, parameters.size());
assertEquals("param1", parameters.get(0));
assertEquals("param2", parameters.get(1));
}