Koala Planet

May 07, 2013

Arnaud Le Hors

Linked Data Platform Update

Since the launch of the W3C Linked Data Platform (LDP) WG in June last year, the WG has made a lot of progress.

It took a while for WG members to get to understand each other and sometimes it still feels like we don’t! But that’s what it takes to make a standard. You need to get people with very different backgrounds and expectations to come around and somehow find a happy medium that works for everyone.

One of the most difficult issues we had to deal with had to do with containers, their relationship to member resources and what to expect from the server when a container gets deleted. After investigating various possible paths the WG finally settled on a simple design that is probably not going to make everyone happy but that all WG members can live with. One reason for this is that it can possibly be grown into something more complex later on if we really want to. In some ways, we went full circle on that issue but in the process we have all gained a much greater understanding of what’s in the spec and why it is there so, this was by no means a useless exercise.

Per our charter, we’re to produce the Last Call specification this month. This is when the WG thinks it’s done – all issues are closed – and external parties are invited to comment on the spec (not to say that comments aren’t welcome all the time). I’m sorry to say that this isn’t going to happen this month. We just have too many issues still left open and the draft still has to incorporate some of the decisions that were made. This will need to be reviewed and may generate more issues. However, the WG is planning to meet face to face in June to tackle the remaining issues. If everything goes to plan this should allow us to produce our Last Call document by the end of June.

Anyone familiar with the standards development arena knows that one month behind is basically “on time”. :-)

In the meantime, next week I will be at the WWW2013 conference where I will be presenting on LDP. It’s a good opportunity for people to come and learn about what’s in the spec if you don’t know yet! If you can’t make it to Rio, you’ll have another chance at the SemTech conf in June where I will be presenting on LDP as well. Jennifer Zaino from SemanticWeb.com wrote a nice piece based on an interview I gave her.


Read post...

April 29, 2013

Guillaume Laurent

iTunes library tagging

A long while ago I looked into solutions to help me clean up and complete the mp3 tags of my iTunes music library. The problem is that many of my CDs were ripped on Linux, with a Ruby script I had written which used FreeDB (an alternative to CDDB) to fetch tags.

(Actually I’ve just dug out the sources of that script and it was more sophisticated than I remember – thanks to Ruby’s DRb (Distributed Ruby) module, it had a ripper client feeding the wavs to an encoder server using lame and freeDB – not bad)

Anyway, FreeDB didn’t really have the quality of CDDB, so many of my tags are lacking data such as genre or year. Having migrated now to OS X, I started searching for a convenient way of fixing this.

About the only solution I could find is Song Genie by Equinux (which name awfully sounds like a Linux shop :) ). It looked like a good solution but I quickly ran into serious limitations. One is that, in the case of tags with multiple choices, it’s very tedious to undo the choice you’ve picked. But the main one is precisely that many songs will yield several possible tags. Song Genie treats your library as a list of tracks, not a list of albums. Therefore each track is seen independently of any other, and if a given song has been featured on an album and a compilation for instance, SongGenie will show both possibilities and ask you to you decide. It gets worse for jazz or classical music tracks, where the “packaging” scheme of songs into albums is much looser than in rock/pop. So, forget about using this for an automatic solution : you have to make sure you pick the right choice for each track, and it also occasionally gives only one choice which is still wrong. One particularly annoying detail : this applies to album titles, and also to track numbering.

To sum up, I’d often start with an album lacking genre and year, but otherwise properly named and numbered, and Song Genie would turn it to a bunch of tracks apparently coming from several different albums, each with their own numbering order. So much for a hassle-free solution.

When iTunes Match was introduced, I hoped it could provide a solution since the iTunes Store obviously has properly tagged files. I thought there would be a “update tags” feature in iTunes but no. I also tried matchtag which does pretty much that, fetching tags from iTunes Store (only on tracks which have been redownloaded via iTunes Match), but the problem of track vs. album dichotomy remains. Also, matchTag often fails to find info (I just tried with Pink Floyd’s Dark Side of the Moon).

I also tried MusicBrain’s Picard but the UI is very cumbersome, and while it does seem to be build around the concept of albums rather than tracks, I couldn’t get it to work reliably and simply.

Finally I found iTunes Script, in particular this one which copies track info to CD tracks (for when you need to re-rip a CD). I simply reversed the source and destination, and now I can insert a CD, and copy its CDDB info on the tracks. The main problem is that it’s so very tedious (I have to manually select the corresponding tracks in iTunes), but it’s simple and does the job.

A remaining lead would be to use GraceNote’s SDK to try and see if I can do without inserting a CD, or having to manually select the tracks in iTunes.

Read post...

March 30, 2013

Cedric Beust

The time that never was

I spent some time tracking down a funny bug yesterday, which suddenly starting clogging our logs with the following error message:

org.joda.time.IllegalFieldValueException: Value 22 for hourOfDay is not supported: Illegal instant due to time zone offset transition

If there are two things I have learned about Joda-Time these past years, it’s that 1) it hardly ever fails and 2) when it does, it’s for a good reason. So I took a look at the code causing the exception and I found this:

max = eventLocalTime.withTime(22, 0, 0, 0);

I see the “22″ value but this code has been working flawlessly for weeks, what is suddenly causing it to fail? I fired the debugger, reproduced the problem and inspected the eventLocalTime variable. Something felt a bit unusual about its value:

2013-03-30T22:32:00.000 (America/Godthab)

I won’t claim that I know all the different time zones in existence in North America, but “America/Gothab” is certainly new to me. A quick Google search reveals that this time zone is in Greenland. Alright, so we have users in Greenland, but why would this cause a problem?

Reading this page again, something strikes me:

Next Scheduled DST Transition
DST will begin on Sat 30-Mar-2013 at 10:00:00 P.M. when local clocks are set forward 1 hour

and then everything falls into place.

The variable eventLocalTime is perfectly legitimate but today is March 29th, and adding 22 hours to it puts it into a nonexistent time, which happens whenever a time zone transitions to or from Daylight Savings Time. By adding twenty-two hours to the variable, we were trying to create a date “March 30th, 10pm”, which doesn’t exist because the clock in this time zone skips to 11pm. In the US, this nonexistent time period is usually between 2am and 3am, but for some reason, Greenland does this switch at 10pm.

The fix ended up looking as follows (happy to hear if there is a better solution):

try {
    max = eventLocalTime.withTime(22, 0, 0, 0);
} catch (IllegalFieldValueException e) {
    max = eventLocalTime.withTime(23, 0, 0, 0);
}

I am so happy that Joda will finally become standard with Java 8, and I have to tip my hat to Stephen, again, for his dedication to the terribly hard problem of date management.

If you have any funny bug to share, please go ahead and do so in the comments!

Read post...

March 10, 2013

Cedric Beust

A small step for Jebediah, a giant step for Kerbinkind

This is Kerbal Space Program, a sandbox space simulator created by a small team of passionate space programmers. I never really thought that designing rocket ships an aligning orbits could be fun, but I already spent more than thirty hours trying to launch my Kerbals into space (and killing most of them in the process). This turned out to be much more entertaining than I thought.

The game takes place on an imaginary planet called Kerbin. Kerbin looks like the earth and the planetary system it’s located in it has a lot of similarities with our own. As of the current version (0.18, $23, Windows, Mac and Linux), the game allows you to design either rocket ships or airplanes (you can send these to planets as well). Then you launch them and try to follow the plan you decided on.

The screen shot above is Jebediah Kerman, proudly taking his first steps on Mün. It’s the very first successful landing I ever did and it took me about fifty attempts (and countless fiery explosions) to reach this goal. I won’t deny that it was a lot of fun to get there, though, and I learned tons about space travel and ballistics.

The process of mastering the game follows a pretty clear path and while it doesn’t look that there is a big learning distance between your first orbit and your first successful landing, you will soon realize that you need to perfect a lot of intermediary steps in-between. And along the way, you will learn about ship design, the pros and cons of liquid and solid fuel, the compromises of taking a lot of fuel with you, how to launch a ship on a circular orbit, perfecting that orbit, learning how to use and interpret the navball, learning the maneuvers, when and how to perform gravity turns, fuel efficiency, choosing the optimal transfer path between planets, gravity slingshots, controlling your speed to land without exploding, etc…

The game is still in the very early stages and it’s hard not to draw a parallel with the early Minecraft days, where even with so few features, the game has such a strong appeal on imagination that it’s already attracting a very strong and devout following. Take a look at the Kerbal Space Program’s subreddit to get a feel for what people are doing with the game even at such an early stage. I can’t wait to see what it will be like once it reaches 1.0. The developers have managed to take what appears to be a very dry and challenging topic and turn it into a fun and challenging game which remains very approachable. And while you can take a very hard science approach to it, you can also decide to enjoy what it has to offer by simply learning what periapsis and apoapsis are, stopping there and focusing on the flying after that.

As for myself, I still have a lot to do. First, I need to work on fuel efficiency, because even if the Mün landing above was successful, my spaceship is now completely out of fuel (don’t tell Jebediah, he looks so happy). After this, the next step will be to try to land on the more distant planets.

Ad astra!

Read post...

February 25, 2013

Coralie Mercier

mv My\ Opera WordPress

I moved my blog to coraliemercier.wordpress.com. Read post...

February 17, 2013

Cedric Beust

Answer to the “School” challenge

I’m happy to see mostly correct answers to the School coding challenge.

To make things more interesting, let’s start by looking at a naïve (and wrong) solution:

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    result = prime * result + ((nickname == null) ? 0 : nickname.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    // ... details omitted
    return other.nickname.equals(nickname) || other.name.equals(name);
  }

Let’s create two School objects, make sure they are equal, add them to a set and then display this set:

    School school1 = new School("University of Pennsylvania", "upenn");
    School school2 = new School("University of Pennsylvania", "Penn State");
    System.out.println("Equals: " + school1.equals(school2));
    Set<School> schools = Sets.newHashSet();
    schools.add(school1);
    schools.add(school2);
    System.out.println("Set: " + schools);

The output:

Equals: true
Set: [com.beust.School@d8e612c6, com.beust.School@7086780a]

This is obviously wrong and caused by the fact that this implementation breaks several laws, among which: “if two objects are equal, their hashcode should be equal as well”. However, this is clearly not the case here since the two objects instantiated in the main method are equal but their hash code are different, since it’s calculated from both the name and nickname. The consequences of such an implementation are disastrous in more ways than one, starting with the fact that your objects cannot reliably be stored in nor retrieved from identity-based collections (e.g. sets and maps).

The only way out of this would be to return a variable hashcode, but this doesn’t make sense since we wouldn’t know what field to base that hash code on.

Most commenters came up with the idea of always returning the same value for hashCode(), regardless of the name and nickname values. This approach is actually correct but it comes at the cost of losing all running time benefits offered by sets and maps, such as constant time retrievals. Instead, Hashmap#get and Set#contains are now linear operations. That’s a pretty bad prank to pull on your coworkers when their collections can contain millions of objects.

So, what’s the best way to solve this problem?

I’m not quite sure. There are several approaches, all with their pros and cons.

The first idea would be to not override equals and hashCode, using their default implementation defined on Object. This implementation (simple reference equality test) is guaranteed to be wrong in most cases, but since you can’t write a correct one, maybe the best approach is to do nothing.

Another approach would be to throw an OperationNotSupportedException in equals/hashCode. The implementation is still wrong but at least, your program will crash loudly if someone attempts to put these objects in an identity-based collection.

Ultimately, you really want to get rid of the fuzzy matching performed in the equals method, so the best approach is probably to perform a first pass on all your School objects and unify all those that are equal under the same id. After this, you can implement equals/hashCode based on this id field.

Read post...

February 14, 2013

Cedric Beust

Coding challenge (“light” edition)

This coding challenge is a bit different from the previous one ([1] [2]) because it is shorter and also a bit more closely tied to Java.

A School has either a name (“Stanford”) or a nickname (“UCSD”) or both.

Your task is to write equals() and hashCode() methods for the School class that satisfy the following requirement: two Schools are identical if they either have the same name or the same nickname.

Read post...

January 31, 2013

Coralie Mercier

I used to be thick in #semanticweb


I used to be thick in #semanticweb. But that was before.

That was before Alexandre (@bertails) started to explain, and Amy (@amyvdh) translated.

What's a triple? Easy. It's three URLs: subject (sky), predicate (has color), object (blue).
Now, what's a quad? It's a 4th URL that names the context.

I was kidding; I'm still obtuse to Semantic Web. But I've learned something!

Thanks, wonderful colleagues.
Read post...

January 26, 2013

Coralie Mercier

So, my dad has an iPhone

I gave my former iPhone to my father. This morning, after watching for a while his 5 year-old grand-son play Angry Birds, he recounted his experience setting up the iPhone.

First, he didn't know how to insert the SIM card. The leaflet only said to look some page up on the Web. Eventually, he searched and found a good video on YouTube, and watched it 15 times to get the hang of it.

Then he wondered how to open the damn thing and where the heck was the tool he had seen in the video. Well, it was where it had to, nicely tucked on the side of the white cardboard. He found it eventually, which saved him from having to look for a paper clip. Then he cut his SIM card. No sweat, here.

His next step was to install iTunes on his PC. It took a while to download but the hard part was to install the program. It failed near the end with an obscure error. He tried ten times. He decided to discard what he had downloaded and start again. It took another while but this time he managed to install iTunes properly.

What next? Well he needed to activate the iPhone. It didn't work; he said the servers were probably loaded too much when he tried and that he'd try the next day.

So he took back the SIM card, reconstructed the card to its previous bigger shape, using tape and put it back in his previous cell phone. The next day, he was able to activate his phone.

Et voilà!

Read post...

January 22, 2013

Coralie Mercier

Recette : Filets de poisson en papillote, au curry et lait de coco

Filets de poisson curry et coco en papillotes, pour 4.
Préparation : 15 minutes.
Cuisson : 20 minutes.



Ingrédients :
4 filets de poisson (merlu, cabillaud, etc.)
160 g de riz basmati
4 poignées de haricots verts extra-fins
2 carottes
200 ml de lait de coco
Curry, sel, ail moulu

Préparation :
1. Cuire 5 minutes le riz, et séparément les haricots et les carottes en lamelles.
2. Dans chaque papillote d'aluminium, déposer un fond de riz, disposer deux lamelles de carottes, une couche de haricots. Verser un fond de lait de coco. Saler, saupoudrer de curry.
3. Déposer les filets de poisson, saupoudrer de curry, de sel et d'ail. Disposer deux lamelles de carottes.
4. Garnir le riz restant autour des filets et recouvrir le riz du reste de haricots. Verser le reste du lait de coco sur les filets et autour.
5. Fermer les papillotes et enfourner 12 minutes à 180ºC, et 8 minutes à 210ºC.

Et voilà !
Read post...

January 12, 2013

Cedric Beust

A humble suggestion to protect your important information

When you create a new account on a web site, it’s pretty much the norm to be asked to enter an email address. Why aren’t there more (any?) web sites that ask me for an additional email address that will be used exclusively to send me password resets?

With such a simple extra step, my account has become impossibly hard to crack. Not just because my “safe email address” will, obviously, be protected by two-step authentication or other similar mechanism, but more importantly because the hackers have no idea what that email address is: it’s not used to send any email, it only receives emails sporadically, and the only way to find out what it is is to hack into the bank’s servers (I’m pretty sure that hackers able to do that will find far more interesting accounts to empty than mine).

Another benefit is that I don’t need to burden my regular email address with two-step authentication, which would be a hassle since I log into that account so often from so different places.

So… What am I missing? Why isn’t this practice more widespread?

Read post...

January 03, 2013

Cedric Beust

No silver bullet: reloaded

I had to read the recent article “Functional Programming Basics”, by Robert Martin, several times to make sure that I wasn’t missing any deeper point, but every time, I just became more and more concerned by the sloppiness of the arguments presented.

Here are a few thoughts.

First, it’s almost certainly true that functional programming is the next big thing.

We’ll see about that. This has been predicted for several decades and it still hasn’t happened. Some say that it will never happen, others say it’s already happened and more moderate people just observe that quite a few core concepts of functional programming have been leaking into mainstream languages for a while, so in some way, functional programming is slowly percolating through the industry.

Functional programming is programming without assignment statements.

This is a pretty silly statement since functional programming languages have assignments. Maybe the emphasis should be more on referential transparency or perhaps “variables can never be assigned more than once” would be a more accurate description of one of the important tenets of functional programming.

Let’s look at a functional program for the squares of integers. We’ll use the language Clojure for this, though the concepts we’re going to explore work the same in any functional language.

(take 25 (squares-of (integers)))

I find the use of Clojure (or more generally, Lisp) to illustrate his points a bit puzzling because while the question of whether functional programming will play a big part in the software industry’s future is still up for debate, it seems pretty clear to me that 1) object orientation and 2) static typing are two concepts that have clearly established themselves as powerhouse ideas that have an established track record and a bright future ahead of them. Scala or Kotlin would have been a better choice, especially they are not that much more verbose on such a trivial example:

// Kotlin
ints.map { it * it }.take(25)

Read that sentence again; because I did something important there. I took the three separate definitions of the functions that I gave you in the preceding paragraph and combined them into a single sentence. That’s called: (are you ready for the buzzword?) Referential Transparency. [cue: Fanfare, glitter, ticker tape, cheering crowds]

This is where I start being a bit confused by Robert’s point, because if anything, the code he just showed is illustrating a lot more composition than referential transparency.

If you are trying to sell functional programming as a big thing in order to prop up your consultant business, you should probably skip the trivial stuff and start with the hard problems right away, such as preserving referential transparency and immutability, demonstrating the power of composition while accessing a database, returning JSON data from a servlet and have another servlet modify that same database. Do this with a functional programming language and with snippets of code that show clear advantages over today’s Java and C# based solutions and you have yourself a market.

Honestly, we programmers can barely get two Java threads to cooperate.

Not really. Hundreds of thousands of Java programmers write multithreaded code every day and they are doing just fine, because the intricacies of parallelism are abstracted away from them by the frameworks they rely on to get their job done. I’m not talking just about complex Java EE or Spring-based containers but even the simple Tomcat or Jetty servers. More advanced programmers dabble with the amazing java.util.concurrent classes but even those never really have to think much about the hard problems that heavy paralellism involve, because domain gurus such as Brian Goetz and Doug Lea have already done all the hard work for them.

I continue to be wholly unconvinced by the claim that “the new era of multi cores is going to wreak havoc on our code bases unless we adopt a functional programming language”. This claim has two sides, both equally bogus.

As I mentioned above, the fact that we are now running our programs on multiple cores instead of multiple CPU’s brings very little practical difference for anyone writing multithreaded code. What processor/core/green thread/lightweight process your thread will be riding should have zero impact on how you structure your code. If your code was multithread safe on “n CPU’s / 1 core”, it will be equally multithread safe on “1 CPU / n cores” or even “n CPU’s / m cores”. The only major difference is that it now becomes possible to test for actual parallelism (not just concurrency) on inexpensive developer boxes.

The second part of the claim, that only functional programming languages can save us from the impending multicore apocalypse, is equally dubious but I’ll save this for another post, although I’ll point out that traditional OO and imperative programming has shown an amazing power of adaptation and versatility for several decades now, so whatever the next big paradigm will be, it will have to bring significant improvements to the table.

More importantly, if you could peer into the computer’s memory and look at the memory locations used by my program, you’d find that those locations would be initialized as the program first used them, but then they would retain their values, unchanged, throughout the rest of the execution of the program. In other words, no new values would be assigned to those locations.

This is a bizarre claim that shows that Bob only has a passing familiarity with the internals of how a compiler or a VM works. Just because the observable effects of a program are consistent with immutable structures does not mean that the underlying memory is not being shifted around by the OS or by the abstraction layer standing between the source code and the CPU.

Moreover, the claim that immutable structures automatically lead to easy concurrency is not just naïve but plain incorrect: there are a lot of algorithms (such as merge sort) that are inherently not parallelizable.

Overall, this is a fairly unconvincing article that seems to miss most of the well recognized benefits of functional programming (composability remains the aspect that has the highest impact on my code on a daily basis) while touting advantages that range from poorly understood concepts to plain incorrect claims.

Read post...

December 30, 2012

Cedric Beust

Migrating from Ember.js to AngularJS

I recently spent some time converting a medium-sized Javascript application using Ember.js to AngularJS, here are a few thoughts about the migration.

First of all, why migrate at all?

The Ember.js code is based on a 0.9x version and as Ember.js is approaching 1.0, I was growing increasingly nervous at the thought of porting the application to 1.0 considering the number of breaking changes that the new version contains (nothing wrong with that, it’s the risk you take when you use a pre-release version). Since there would be major work involved, I thought that taking another look at Angular wouldn’t hurt.

Overall, Angular is a much more extensive framework than Ember. On top of offering a binding/MVC framework, Angular supports:

  • Modules. You pick and choose which functionalities you want and you can create modules of your own code as well.
  • Injection and testability. This should come as no surprise since one of Angular’s main developers, Misko, is a regular poster on Google’s testing blog.
  • Support for partials and inclusion of templates. This is another thing I really missed with Ember.js, which offers no easy way to break down your HTML templates into smaller, more manageable files. Angular allows you to do this either through routes and partials or straight inclusion of files.
  • Documentation. While the Ember.js documentation is fairly large, I found it very unorganized and I often resorted to searching the page to find what I need. In contrast, Angular’s documentation follows a clean structure where each page contains a full example of the concept being explained (a trend I wish more documentations followed: with this kind of model, it doesn’t matter much if your documentation is well written as long as the code samples work. Also, I really like the way they present the code in these samples, with individual panels for the HTML, Javascript and any other file you might need).

There are a lot of fundamental differences in philosophy between Ember.js and Angular, and one of the most important ones is how they handle templates.

Ember.js follows the more classical way of making you write files that look like HTML but are not really since they are littered with directives that drive the template engine:

    {{#each people}}
  • Hello, {{name}}!
  • {{/each}}

In contrast, Angular template files use proprietary HTML attributes which will be processed by its compiler to modify the DOM:

  • Hello, {{person.name}}!

I have found that Angular’s approach makes it easier to debug your templates because the HTML that you are inspecting is exactly what it looks like after expansion. Reading Ember.js processed templates is made harder by the fact that they are littered with magic Ember identifiers (e.g. “id="metamorph-34-start"“).

Data binding is performed very differently between the two frameworks. Ember.js makes you wrap all the objects that are part of your model so that it can monitor them. Despite offering theoretical great power, updating Ember objects is still fraught with annoyances:

  • You need to remember to call the setter: object.set('foo', newValue). Assigning this field directly will not fail but will cause some data binding to not work.
  • Cascading updates are being executed right away. While this seems like a good idea in theory, the practice is very different since there are times where I want to do batch updates to my objects before telling my UI to update itself. I ended up adding boolean flags to manually prevent my listeners from automatically triggering until my model was ready, which seems to defeat the purpose of data binding.

Angular’s data binding is much more straightforward (you just update the objects of your model directly) and “most of the time”, it works. There are times where you will have to tell Angular to perform its updates, but these are rare. See this very interesting explanation from Misko on StackOverflow.

Ember’s data binding is also magic is a few more ways. You can bind values together (for example, defining that a “full name” is made of “first name” and “last name” by declaring dependencies between these fields) and you declare these by adding “Binding” to the end of the variable. This takes a little to get used to. Bindings at the template level are pretty awkward too, especially for attributes:

  
  <img {{bindAttr alt="altText"}} />

  
  <img alt="{{altText}}" />

I had a few other items to cover in this comparison but I’ll stop here, except for one last point: IDEA’s Javascript support is light years ahead of Eclipse and a joy to work with.

Overall, I have to say that I am enjoying working with Angular a lot more than I ever did with Ember, and between the credentials of both the company and the engineers driving Angular, the vibrant community (the mailing-list gets about fifty emails every day), the high quality documentation and support and the modern concepts it supports (modularity, testability, injection), it’s clear to me that Angular has a tremendous amount of momentum and is bound to become the defacto standard with which Javascript single page applications are written in the future.

Read post...

December 11, 2012

Coralie Mercier

Matin d'automne, le chaud et le froid

La cime des arbres, encore habillés de feuilles orange, semble s'embraser sous les rayons puissants du clair soleil de ce matin d'automne. Un beau contraste que cet orange cuivré sur le fond bleu du ciel. Alors que le jardin, dans l'ombre, est encore blanc et mat et que l'herbe est transie dans la rosée gelée. Quelques feuilles orange tombent, virevoltent dans l'air figé. Leur chute une tâche de lumière dansante et puis elles disparaissent tout à fait et se posent à l'ombre froide. Read post...

November 22, 2012

Coralie Mercier

Things for which I am grateful

Happy Thanksgiving to those who celebrate it! Happy regular day to the rest!

My laptop acted up last night and today and what a prank it was for it to assess the disk corrupt, claim it can't be fixed, and declare that reformatting and restoring from backup were in order. Turned out the disk got repaired and I tweeted I'm grateful for it:


This is the short-term gratefulness and there are other things I am deeply grateful for: I am healthy and literate in a country where life is good, I have a family of good people, I have a son whom I love from the bottom of my unfathomable heart, I live with his sweet father, I have a job I live for and colleagues who are kind, talented, dedicated, funny that I admire them. This is a fraction of the things I am grateful for. Today I thought about them, and I'm thankful.

Read post...

November 15, 2012

Coralie Mercier

Attribution links to pasted content? - Something is wrong on the Internet!

Some websites will transform, at the paste event, the content that you copy. This isn't recent, and it was a mild annoyance until it made its début in Opera, the browser I use the most (I installed 12.11 beta RC last last week).

What happens is that when you select text from some web pages, the site uses JavaScript to report what you’ve copied to an analytics server and append an attribution URL to the text that you paste.

What a terrible idea.

As John Gruber put it in a 2010 article on the subject:

It’s a bunch of user-hostile SEO bullshit.



I looked at the Tynt website, and soon found that users can opt out. \o/ http://www.tynt.com/opt_out.php


If you don't want Tynt tracking copy activity or adding attribution links, 
you can disable Tynt, by clicking the Opt Out button below. 
You will need to Opt Out for each browser you use, and have cookies enabled.


It appears that there aren't any other competitor. I hope it stays that way.

But what I wish even more, is that Websites would just NOT do this. It's not privacy that concerns me, it's the fact that in many cases, what I want to paste is lost.
In all cases, what I want to paste is what I select.

I don't want to need any work-around. Yes, I can view the source of a page and select from there. It's tedious. Yes, I can paste in a text editor, strip to what I need, copy again and paste what I want. It's also tedious.

Read post...

November 07, 2012

Coralie Mercier

Last week's scribing performance

One of the things I did a lot last week was minuting meetings, that is capturing a record of what people talk about. At W3C we typically do that via IRC and then a handful of bots and scripts generate HTML minutes.

So I scribed. Friday was particularly intense, being the second day of the Advisory Boad face-to-face meeting, the agenda for the day still being pretty full, and people's heads being quite full of long talking points on what I consider complex topics.

I cleaned up the minutes the same evening, as I usually do, while things were still fresh in my memory. And what surprised my was the small amount of typos and spelling mistakes I had to fix.

Thanks to grep and wc, I found that of the 949 lines in the IRC log of the Friday meeting, 687 were my scribings (amounting to 8835 words). And the number of typos and spelling mistakes I find so low is: 32. That is all. I performed significantly better on that day than I usually do.

Of course, the worst part is now; I need to synthesize 2350 lines (15K words) of minutes into a summary. And "again, the Advisory Board saved the Consortium" isn't enough (nor is it true just yet!).
Read post...

September 30, 2012

Guillaume Laurent

Miscellaneous bits

It’s been quite a while since my last post, and I missed a few news topics I felt like commenting on, so here goes, all in one block.

Canon 5D mark III

Boy has this one kept us waiting. The main hope was even better low-light performance than the mrkII, and the first samples were indeed astounding. But that’s because it applies heavy noise reduction on the jpegs. The raw files show only a much lesser improvement compared to the mrkII. What remains is a much improved auto-focus, something I could certainly do with given that all the focus spots on the mrkII except the central one can be pretty stubborn.

the Linux desktop is dead, and it finally knows it

When someone like Miguel de Icaza publishes a post titled What killed the Linux desktop, it’s safe to assume the idea has gotten wide recognition. It did get a serious backlash from no less than Alan Cox and Linus Torvalds, but neither claimed the premise was untrue, only the causes which Miguel invoked.

For one thing, Alan Cox’s response is spot on, Miguel helped creating the confusion he laments by launching Gnome (though he fails to recognize he was once an active member of Gnome, albeit not a very enthusiast one, as I remember). Gnome certainly helped killing any hope of Linux ever making a dent on the desktop because 3rd-party apps devs would be confronted by a choice no dev want to make : about which platform you’ll code for. The only worst thing to do would have been to offer a “choice” in different C libraries.

Moreover, I really can’t see how Linus Torvalds character or his stance toward Linux ABI compatibility can be seen as part of the problem. Linus certainly did not “invent” the “tough geek” persona, that existed long before him.

And the reason behind that was not that we have a culture of “engineering excellence” as Miguel stated in his original post (though we certainly liked to think we had that). Constantly breaking APIs is not a sign of good engineering, engineering is also about pragmatism, not just lofty ideals. We saw ourselves as programming prodigies able to code better and faster than the old grumpy suits-and-tie corporation engineers, but that was the arrogance of inexperience.

The reason is because everyone still wants to have things the way he likes and nobody is willing to give up his own preferences for the sake of common good. We had the moral caution to keep doing so from the old Cathedral and the Bazar manifesto, since we believed the Right Solution would always impose itself in the end. It never did.

iPhone 5 and iOS 6

It’s already a commercial success, while the press consensus is that it’s boring (“no vision”, “no creativity”, etc… with the recent addition of “you can see Steve Jobs is dead”). It was the same for the 4S, perhaps not so much for the 4 given the redesign, but it was also the case for the 3GS… Anyway, the best description I’ve read about this so far is from John Gruber : “this is (still) how Apple rolls”. No, we won’t ever again feel the same sense of wonder and history-in-the-making that the initial 2007 MacWorld keynote created. The iPhone is an established product, it will only have incremental improvements. Remember that even the iPad was met with collective yawns from the press : “It’s just a big iPhone”. It took a while to understand that it was yet another whole new market.

The only comment I have is, it may actually be too tall for me. The 3.5″ screen format fits my hand perfectly, I don’t have to reach too much with my thumb to activate any control, though the top ones are a bit hard to attain. I haven’t handled an iPhone 5 yet, but I doubt it will be as comfortable for me, and I actually hope Apple will keep maintaining models with both screen ratios, though I think that’s very unlikely.

About iOS 6, the big disappointment of Plans overshadowed almost everything else. Yes, Apple shouldn’t have bragged so much about it during the presentation. That said, the application itself is way better than Google Maps : it displays much faster, zooms and rotates much more smoothly. It’s just the data which sucks, though from what I’ve seen with the satellite tiles around here (south of France), which were updated twice already between now and the first iOS beta, Apple is pretty hard at work at improving it. It’s still remarkable that Tim Cook wrote an apology about it, that’s not a common thing in Apple’s history.

I joke, however, that Plans is actually a ploy to divert the attention from the real fiasco, namely Podcasts. The new app which is supposed to handle that very important functionality of iPhones (the term ‘podcast’ derives from ‘iPod’) may be pretty (if you like skeuomorphic UIs – I don’t, and I find it idiotic that a device like an iPhone should present the appearance of a 4 decades old reel-to-reel tape player) but it can’t handle playlists and, worse, does not properly sync the episodes status with iTunes. As many, I had a simple “unplayed podcasts” playlist (a smart-playlist, actually, giving me all unplayed podcasts from the French national radio France Inter), and the whole thing was maintenance free. Refresh daily on iTunes, sync the iPhone, then in the car, ask Siri to play the smart-list, and that was it. Now iOS 6 has broken this, because even after removing the Podcasts app and having them back in the Music app, iTunes still fails to sync the episodes status, I have to manually mark them as played. It’s hard to think of something more stupid than this. I hope the next release will fix that.

Read post...

September 25, 2012

Coralie Mercier

Quick, a computer exorcist!

The fact that I find this irrationally funny is worrisome. Don't worry; I already do.
Someone's computer (Rigo's) goes berserk and gives darobin concerns. So, this made me laugh out loud:
[...]
2012-09-25T10:59:04Z <rigo>  
2012-09-25T10:59:06Z <rigo>  
2012-09-25T10:59:10Z <rigo>     
2012-09-25T10:59:11Z <rigo>  
2012-09-25T10:59:15Z <rigo>   
2012-09-25T10:59:17Z <rigo>  
2012-09-25T10:59:19Z <rigo>  
2012-09-25T10:59:21Z <rigo>          
2012-09-25T10:59:24Z <rigo>  
2012-09-25T10:59:25Z <rigo>  
2012-09-25T10:59:27Z <rigo>  
2012-09-25T10:59:29Z <rigo>  
2012-09-25T10:59:31Z <rigo>  
2012-09-25T10:59:33Z <rigo>  
2012-09-25T10:59:35Z <rigo>  
2012-09-25T10:59:37Z <rigo>  
2012-09-25T10:59:40Z <rigo>  
2012-09-25T10:59:41Z <rigo>  
2012-09-25T10:59:43Z <rigo>  
2012-09-25T10:59:45Z <rigo>  
2012-09-25T10:59:47Z <rigo>   
2012-09-25T10:59:49Z <rigo>   
2012-09-25T10:59:52Z <rigo>  
2012-09-25T10:59:53Z <rigo>   
2012-09-25T10:59:55Z <rigo>  
2012-09-25T10:59:57Z <rigo>   
2012-09-25T10:59:59Z <rigo>  
2012-09-25T11:00:01Z <rigo>  
2012-09-25T11:00:03Z <rigo>  
2012-09-25T11:00:05Z <rigo>  
2012-09-25T11:00:07Z <rigo>   
2012-09-25T11:00:08Z <darobin> mmmmm WTF?
2012-09-25T11:00:09Z <rigo>  
2012-09-25T11:00:11Z <rigo>  
2012-09-25T11:00:13Z <rigo>  
2012-09-25T11:00:15Z <rigo>  
2012-09-25T11:00:17Z <rigo>  
2012-09-25T11:00:19Z <rigo>  
2012-09-25T11:00:20Z <darobin> rigo?
2012-09-25T11:00:21Z <rigo>  
2012-09-25T11:00:23Z <rigo>
[...] 
2012-09-25T11:58:24Z -!- rigo [rigo@128.30.52.169] has quit [Excess Flood]

Read post...

September 24, 2012

Coralie Mercier

The sound of things

Sound that things make and their levels, as analysed on my smart phone with Decibel Ultra:

Light rain under the porch: 60 - 70 dB
Heavy rain under the porch: 90 dB
Thunder striking a couple kilometers away: 100 dB
Downpour under the porch: 100 dB

This is usually when I give up staying out under the porch, because it means ricocheting water will soak me soon. And my computer too. [User relocates] Here, let me wipe a few drops from my screen and trackpad. Done. You should see the cat --having migrated indoor against her will, she sits under the table in front of the French window and looks dismally at the curtains of rain.

I like to measure the sound of things. Not all things, only things which sound level I find notable. Here are a few additional examples:

Loud snoring: 86 dB (peak)
MIT machine room: 83 dB? I haven't committed that one to memory, I was too busy being impressed.
Meadhall nearby Stata Center: 103 dB! I lasted throughout dinner once, kept only by the fine company of two people I like.









Read post...

September 11, 2012

Arnaud Le Hors

More on Linked Data and IBM

For those technically inclined, you can learn more about IBM’s interest in Linked Data as an application integration model and the kind of standard we’d like the W3C Linked Data Platform WG to develop by reading a paper I presented earlier this year at the WWW2012 Linked Data workshop titled: “Using read/write Linked Data for Application Integration — Towards a Linked Data Basic Profile”.

Here is the abstract:

Linked Data, as defined by Tim Berners-Lee’s 4 rules [1], has
enjoyed considerable well-publicized success as a technology for
publishing data in the World Wide Web [2]. The Rational group in
IBM has for several years been employing a read/write usage of
Linked Data as an architectural style for integrating a suite of
applications, and we have shipped commercial products using this
technology. We have found that this read/write usage of Linked
Data has helped us solve several perennial problems that we had
been unable to successfully solve with other application
integration architectural styles that we have explored in the past.
The applications we have integrated in IBM are primarily in the
domains of Application Lifecycle Management (ALM) and
Integration System Management (ISM), but we believe that our
experiences using read/write Linked Data to solve application
integration problems could be broadly relevant and applicable
within the IT industry.
This paper explains why Linked Data, which builds on the
existing World Wide Web infrastructure, presents some unique
characteristics, such as being distributed and scalable, that may
allow the industry to succeed where other application integration
approaches have failed. It discusses lessons we have learned along
the way and some of the challenges we have been facing in using
Linked Data to integrate enterprise applications.
Finally, we discuss several areas that could benefit from
additional standard work and discuss several commonly
applicable usage patterns along with proposals on how to address
them using the existing W3C standards in the form of a Linked
Data Basic Profile. This includes techniques applicable to clients
and servers that read and write linked data, a type of container
that allows new resources to be created using HTTP POST and
existing resources to be found using HTTP GET (analogous to
things like Atom Publishing Protocol (APP) [3]).

The full article can be found as a PDF file: Using read/write Linked Data for Application Integration — Towards a Linked Data Basic Profile


Read post...

Arnaud Le Hors

Linked Data

Several months ago I edited my “About” text on this blog to add that: “After several years focusing on strategic and policy issues related to open source and standards, including in the emerging markets, I am back to more technical work.”

One of the projects that I have been working on in this context is Linked Data.

It all started over a year ago when I learned from the IBM Rational team that Linked Data was the foundation of Open Services for Lifecycle Collaboration Lifecycle (OSLC) which Rational uses as their platform for application integration. The Rational team was very pleased with the direction they were on but reported challenges in using Linked Data. They were looking for help in addressing these.

Fundamentally, the crux of the challenges they faced came down to a lack of formal definition of Linked Data. There is plenty of documentation out there on Linked Data but not everyone has the same vision or definition. The W3C has a growing collection of standards related to the Semantic Web but not everyone agrees on how they should be used and combined, and which one applies to Linked Data.

The problem with how things stand isn’t so much that there isn’t a way to do something. The problem is rather that, more often than not, there are too many ways. This means users have to make choices all the time. This makes starting to use Linked Data difficult for beginners and it hinders interoperability because different users make different choices.

I organized a teleconference with the W3C Team in which we explained what IBM Rational was doing with Linked Data and the challenges they were facing. The W3C team was very receptive to what we had to say and offered to organize a workshop to discuss our issues and see who else would be interested.

The Linked Enterprise Data Patterns Workshop took place on December 6 and 7, 2011 and was well attended. After a day and a half of presentations and discussions the participants found themselves largely agreeing and unanimously concluded that: the W3C should create a Working Group to create a Recommendation that formally defines a “Linked Data Platform”.

The workshop was followed by a submission by IBM and others of the Linked Data Basic Profile and the launch by W3C of the Linked Data Platform (LDP) Working Group (WG) which I co-chair.

You can learn more about this effort and IBM’s position by reading the “IBM on the Linked Data Platform” interview the W3C posted on their website and reading the “IBM lends support for Linked Data standards through W3C group” article I published on the Rational blog.

On a personal level, I’ve known about the W3C Semantic Web activities since my days as a W3C Team Member but I had never had the opportunity to work in this space before so I’m very excited about this project. I’m also happy to be involved again with the W3C where I still count many friends. :-)

I will try to post updates on this blog as the WG makes progress.


Read post...

September 03, 2012

Cedric Beust

Coding challenge: a sliding window map

A lot of sites offer programmatic access to their content via API’s. The main advantage for the producer of this content is to be able to control finely what they export and how they export it (and also avoid being scraped) while clients receive the data they need in a structured and documented way. These API’s are usually strictly monitored to make sure that clients can’t abuse them. For example, the producer will typically limit how often clients can call a certain API, how much data they can transfer every minute, etc…

Today’s coding challenge is based on these requirements.

We want to make multiple calls to a site that only allows to use a key 500 times every 10mn. You are given a collection of keys (strings), a max count (e.g. 500) and a time period (e.g. 10mn) and your task is to implement getNextKey() as follows:

public class SlidingWindowMap {
  public SlidingWindowMap(Set<String> keys, int maxCount, long periodMs) {
    // ...
  }

  /**
   * @return a key that has been used less than `maxCount` times during the
   * past `periodMs` milliseconds or null if no such key exists.
   */
  public String getNextKey() { 
    // Your brilliant solution goes here
  }

}

I’m keeping the statement of the problem as open as possible to encourage exploration, but feel free to ask for clarifications if something is not clear. Please post your solution on a pastebin/gist like site (or wherever your code will be easy to read) and link to it in your comment. All languages are welcome.

Read post...

August 21, 2012

Cedric Beust

Advanced dependency injection with Guice

The more I use dependency injection (DI) in my code, the more it alters the way I see both my design and implementation. Injection is so convenient and powerful that you end up wanting to make sure you use it as often as you can. And as it turns out, you can use it in many, many places.

Let’s cover briefly the most obvious scenarios where DI, and more specifically, Guice, are a good fit: objects created either at class loading time or very early in your application. These two aspects are covered by either direct injection or by providers, which allow you to start building some of your object graph before you can inject more objects. I won’t go too much in details about these two use cases since they are explained in pretty much any Guice tutorial you can find on the net.

Once the injector has created your graph of objects, you are pretty much back to normal and instantiating your “runtime objects” (the objects you create during the life time of your application) the normal way, most likely with “new” or factories. However, you will quickly start noticing that you need some runtime information to create these objects, other parts of them could be injected.

Let’s take the following example: we have a GeoService interface that provides various geolocation functions, such as telling you if two addresses are close to each other:

public interface GeoService {
  /**
   * @return true if the two addresses are within @param{miles}
   * miles of each other.
   */
  boolean isNear(Address address1, Address address2, int miles);
}

Then you have a Person class which uses this service and also needs a name and an address to be instantiated:

  public class Person {
    // Fields omitted

    public Person(String name, Address address, GeoService gs) {
      this.name = name;
      this.address = address;
      this.geoService = gs;
    }

    public boolean livesNear(Person otherPerson) {
      return geoService.isNear(address, otherPerson.getAddress(),
          2 /* miles */);
    }
  }

Something odd should jump at you right away with this class: while name and address are part of the identity of a Person object, the presence of the GeoService instance in it feels wrong. The service is a singleton that is created on start up, so a perfect candidate to be injected, but how can I achieve the creation of a Person object when some of its information is supplied by Guice and the other part by myself?

Guice gives you a very elegant and flexible way to implement this scenario with “assisted injection”.

The first step is to define a factory for our objects that represents exactly how we want to create them:

public interface PersonFactory {
  Person create(String name, Address address);
}

Since only name and address participate in the identity of our Person objects, these are the only parameters we need to construct our objects. The other parameters should be supplied by Guice so we modify our Person constructor to let Guice know:

  @Inject
  public Person(@Assisted String name, @Assisted Address address,
      GeoService geoService) {
    this.name = name;
    this.address = address;
    this.geoService = geoService;
  }

In this code, I have added an @Inject annotation on the constructor and an @Assisted annotation on each parameter that I will be providing. Guice will take care of injecting the rest.

Finally, we connect the factory to its objects when creating the module:

    Module module1 = new FactoryModuleBuilder()
        .build(PersonFactory.class);

The important part here is to realize that we will never instantiate PersonFactory: Guice will. From now on, all we need to do whenever we want to instantiate a Person object is to ask Guice to hand us a factory:

@Inject
private PersonFactory personFactory;

// ...

Person p = personFactory.create("Bob", new Address("1 Ocean st"));

If you want to find out more, take a look at the main documentation for assisted injection, which explains how to support overloaded constructors and also how to create different kinds of objects within the same factory.

Wrapping up

Let’s take a look at what we did. First, we started with a suspicious looking constructor:

public Person(String name, Address address, GeoService s) {

This constructor is suspicious because it accepts parameters that do not participate in the identity of the object (you won’t use the GeoService parameter when calculating the hash code of a Person object). Instead, we replaced this constructor with a factory that only accepts identity fields:

public interface PersonFactory {
  Person create(String name, Address address);
}

and we let Guice’s assisted injection take care of creating a fully formed object for us.

This observation leads us to the Identity Constructor rule:

If a constructor accepts parameters that are not used to define the identity of the objects, consider injecting these parameters.

Once you start looking at your objects with this rule in mind, you will be surprised to find out how many of them can benefit from assisted injection.

Read post...

August 19, 2012

Cedric Beust

A note on null pointers

It’s the second time in a few weeks that I have read something along the lines of:

In a year at foursquare, I’ve seen exactly one null pointer exception.

To me, this kind of statement is similar to

Ever since I switched to BASIC, I haven’t seen a single stack trace.

and it shows a fundamental misunderstanding of what a programming error is. Similarly, hearing Tony Hoare say that introducing null was a “one billion dollar mistake” makes me really question if he understands the fundamental idea behind crashes.

Null pointer exceptions, stack traces, core dumps, guru meditations, etc… are usually all the manifestation of a simple phenomenon: unexpected values. Somehow, your code expected a value but received another one. This is a programming error, also known as a bug.

If you are using a language that supports monadic Option/Maybe types, by definition, you will not be seeing any null pointer exceptions, but this doesn’t mean that you have solved the “unexpected value” problem.

In languages such as Java or C, null pointers translate into crashes that are hard to miss and usually easy to diagnose. What would be the equivalent of this in Scala?

The answer is easy: receiving a None when you expected a Some. Because of the way you thread monads through your functions, such a bug will not trigger any exceptions nor any crash: your None value will happily make its way through monadic transforms and will simply result in a no-op every time it’s being mapped. Of course, your program will yield an unexpected value that you will take notice of at some point, and then you will have to go through the painful process of retracing all the Options that your transformations have gone through to find out which one returned None when it should have returned a Some.

At this point, you should probably ask yourself: if this piece of code should never return a None, why return an Option at all? In such cases, you are better off unboxing your Option and returning its raw value. Of course, the downside of this is that you might have to lift your value again if the following computations happen in the Option monad as well.

As you can see, Options come with their own trade offs and hard design decisions as well. No such thing as a free lunch.

Which leads us to the next big misconception about this class: Option doesn’t solve null pointer exceptions nor unexpected values, it just saves you from having to test against null. And actually, doing so (e.g. pattern matching your option against Some/None) is usually considered bad practice, even though it’s sometimes necessary for Java interoperability reasons.

Personally, I favor the way Groovy, Fantom and Kotlin address the problem over having to lift all my values into Option. For example, here is how Kotlin lets you ignore null values encountered along a chain of invocations:

bob?.department?.head?.name

If either of these accesses returns null, the result of this expression will be null. No need to put your values into monadic boxes nor mapping through them, just use the standard composition operator you are familiar with if you are using a C family language.

By all means, do use Option whenever you can if you are programming in Scala (and you will probably realize that you can’t use it as much as you would like because Java libraries, and some Scala ones, are just not implemented to take Option parameters), but don’t listen to people who tell you that because you are no longer seeing any null pointer exceptions, your code is safer. It’s not. You still have to fix your bugs.

Read post...

July 30, 2012

Cedric Beust

Reinventing assertions

If you have ever written a test in Java, you are undoubtedly familiar with the Assert class:

  Assert.assertEquals(result, expected);

Java 5 introduced the assert keyword, but because it wasn’t enabled by default, the world of testing has continued to use the Assert class.

I’ve always been bothered by the fact that the methods on this class are static, which shouldn’t come as a surprise since getting rid of statics in my test code base was one of the motivating factors I had for creating TestNG.

Over the past years, I have received an increasing number of requests to make assertions more flexible in order to support various scenarios:

  • Logging all the assertions as they are happening, even if they succeed.
  • Accumulating the results of multiple assertions inside a test method but not failing until the end of the method.
  • Performing a certain operation whenever an assertion fails (for example, taking a screen shot of the browser, as is often required in Selenium).

I decided that the time had come to revisit assertions in order to make it more flexible so it can accomodate all these real world scenarios.

The first step is to create a new assertion class that supports exactly the same methods as Assert but without these methods being static. Here is a test that uses this new assertion class:

import org.testng.asserts.Assertion;

@Test
public class A {
  private Assertion m_assert = new Assertion();

  public void test1() {
    m_assert.assertTrue(true, "test1()");
  }
}

On top of having all its assertion methods being instance methods and not static ones, the class Assertion defines several life cycle methods that subclasses can override. Here is the list as it stands today:

  • onBeforeAssert()
  • executeAssert()
  • onAssertSuccess()
  • onAssertFailure()
  • onAfterAssert()

I’m not going to go into details right now, these names should be self-explanatory. All these methods receive an instance of IAssert in parameter which captures the assert that’s about to be run:

public interface IAssert {
  public String getMessage();
  public void doAssert();
}

For example, here is what a class that logs each assert would look like:

public class LoggingAssert extends Assertion {

  private List<String> m_messages = Lists.newArrayList();

  @Override
  public void onBeforeAssert(IAssert a) {
    m_messages.add("Test:" + a.getMessage());
  }

  public List<String> getMessages() {
    return m_messages;
  }
}

Here’s how to use this class in your test:

@Test
public class A {
  private LoggingAssert m_assert = new LoggingAssert();

  public void test1() {
    m_assert.assertTrue(true, "test1()");
  }

  public void test2() {
    m_assert.assertTrue(true, "test2()");
  }

  @AfterClass
  public void ac() {
    System.out.println("Tests run in this class:" + m_assert.getMessages());
  }
}

Now let’s take a look at the implementation of a “soft assert” class: we want each assert to just run but not throw an exception if it fails. Instead, we just want to record it and once we’ve reached the end of the class (or the suite), assert the whole result.

Here a simple implementation of such a class. The idea is simply to override the executeAssert() and if an exception occurs, catch it, store it and carry on:

public class SoftAssert extends Assertion {
  private Map<AssertionError, IAssert> m_errors = Maps.newHashMap();

  @Override
  public void executeAssert(IAssert a) {
    try {
      a.doAssert();
    } catch(AssertionError ex) {
      m_errors.put(ex, a);
    }
  }

  public void assertAll() {
    if (! m_errors.isEmpty()) {
      StringBuilder sb =
      		new StringBuilder("The following asserts failed:\n");
      boolean first = true;
      for (Map.Entry<AssertionError, IAssert> ae : m_errors.entrySet()) {
        if (first) {
          first = false;
        } else {
          sb.append(", ");
        }
        sb.append(ae.getValue().getMessage());
      }
      throw new AssertionError(sb.toString());
    }
  }
}

How to use it:

@Test
public class A {
  private SoftAssert m_assert = new SoftAssert();

  public void multiple() {
    m_assert.assertTrue(true, "Success 1");
    m_assert.assertTrue(true, "Success 2");
    m_assert.assertTrue(false, "Failure 1");
    m_assert.assertTrue(true, "Success 3");
    m_assert.assertTrue(false, "Failure 2");
    m_assert.assertAll();
  }
}

The result:

FAILED: multiple
java.lang.AssertionError: The following asserts failed:
Failure 2, Failure 1
	at org.testng.SoftAssert.assertAll(SoftAssert.java:32)

On top of the default new assertion classes that TestNG will ship with, I expect the following techniques to become fairly common:

  • Using different assertion instance fields to mix and match the type of assertions depending on which one you need
  • Extending the assertion classes to add new methods or override specific ones.

Of course, the older (static) Assert class will continue to work in TestNG, but starting with the next TestNG version, consider using Assertion in your test code to gain some additional flexibility. And as always, feel free to send me your feedback, especially now that this implementation hasn’t officially shipped yet.

Read post...

July 27, 2012

Coralie Mercier

Chatting with a bot

We use several IRC bots at work, and this is what happens when sometimes they interrupt a conversation, out of the blue (we, humans, usually invoke them with triggers, none of which I knew I typed). This bit has only my side of the conversation, and I chose to leave out all context as it entertains me better this way:
2012-07-27T15:02:23Z <koalie> so I'll do it by hand
2012-07-27T15:02:23Z  * Zakim koalie, you typed too many words without
commas; I suspect you forgot to start with 'to ...'
2012-07-27T15:02:40Z <koalie> ok, Zakim 
2012-07-27T15:02:57Z <koalie> to ... have it with both, so I'll do it by hand
2012-07-27T15:02:57Z  * Zakim sees koalie on the speaker queue
2012-07-27T15:03:05Z <koalie> silly bot
2012-07-27T15:03:10Z <koalie> ack me
2012-07-27T15:03:10Z <Zakim> koalie, you wanted to ... have it with both,
so I'll do it by 
Read post...

June 21, 2012

Coralie Mercier

Opera 12: new version, new esoteric bug

I'm taking the time to document the obscure bug that I often experience with Opera 12 (like every other day since I installed version 12 on the day it was released).

It is a surprising bug to say the least, not too annoying (as you'll understand, Opera quickly recovers from it), but still, I reported it (DSK-367824).

[Update 2012-06-26: This is a duplicate of DSK-365797]

For no good reason that I can see or that console logs can explain, Opera actions are suddenly mapped to others, regardless that I use their keyboard shortcuts or that I click commands in the menus. When this happen, I feel like Opera is in play mode (like it's a software thing to replace commands with other actions!).

For example, I want a new tab but get the window to "Open...". The first time that occurred, I thought "aha! so I need to press cmd-o if I want to get a new tab." Nope, all I got was the "Save As..." window. In play mode, it's "Save As...", or cmd-s, that will open a new tab. Consistently. Except that I don't know what triggers play mode.

I played as long as I could, it was entertaining. The play-mode key-combos I found are:
cmd-t (for new tab) = open file
cmd-n (for new window) =
save-as
cmd-s (to save) = new tab
cmd-c (to copy selection) =
fullscreen
cmd-v (to paste selection) = right click
cmd-w (to close tab) =
game over, it does cmd-q (to quit).

Read post...

June 12, 2012

Cedric Beust

Apple maps

I can see three consequences to Apple rolling their own maps in iOS 6:

  • iOS users get turn by turn navigation.
  • Google has to keep innovating in that area to stay ahead (not that they ever stopped, but the more competition, the better).
  • There are even less reasons to buy a Garmin or a Tom Tom GPS.
Read post...

June 10, 2012

Coralie Mercier

Odd encounter with an old woman

I had a strange encounter with a little old woman today. I stood outside a restaurant smoking and she stood nearby, observing me. At some point she said "You're pretty tall. You're 190 cm tall, aren't you?" I replied I'm 177 cm tall. She kept observing, looking sulky and then pointed a finger at me and seemed to count in a low voice, her finger moving up one notch at a time toward my head. I suppose she counted how many heads taller than her I was. She looked me in the eyes, I smiled, she started counting again! Then she added, almost to herself "young ones these days are way taller than us." I put out my cigarette and slipped away. Read post...

May 20, 2012

Guillaume Laurent

Objective C and C++ verbosities compared

In my previous post I mentioned Steve Job’s choice of Objective C over C++ for development, based on his assertion that he wanted “to eliminate 80% of the code you have to write for you app”. To which Chris commented that in this older post, a piece of C++ code that I had converted to Objective C was actually twice as long as the original.

I probably should have gone into a bit more details in that initial remark on Objective C vs. C++, but that would have been rather off topic. Chris’s comment calls for more discussion, though.

The quick reply :

the C++ code I converted uses a simple STL-based data structure. The Objective C version uses Core Data.

There’s no question that, for simple operations, Core Data is more verbose than the STL equivalent. In the latter case you’re iterating over a simple container, in the former you’re actually querying a DB (an SQLite db, btw – yet another example of a well-reused piece of technology).

So, even though both codes do the same thing conceptually, the underlying technology is completely different. Yes, the Objc version is much longer, however… in the C++ case, there’s the whole definition of the STL data structure which is not shown in the example, and that you have to write. In the case of Core Data, well, there isn’t. You simply design the data model with Xcode’s Core Data builder :-) . So the complete number of lines of code is actually smaller in the ObjC case.

The longer reply :

Core Data didn’t exist yet in at the time Jobs chose Objective C as the base language for NeXTStep, and Objective C does tend to be more verbose in its APIs than C++. The best way to demonstrate this is through a basic example of an array of ints :

C++

// declare an array of ints
std::vector arrayOfInts;

// add one element
arrayOfInts.push_back(1);

// get the element’s value
int i = arrayOfInts[0];

Objective C

// no array of ints, only arrays of NSObject* so :
NSMutableArray* arrayOfInts = [NSMutableArray array];

// add one element
[arrayOfInts addObject:[NSNumber numberWithInt:1]];

int i = [[arrayOfInts objectAtIndex:0] intValue];

If that reminds you of Java, you’re right. And thankfully, autoboxing is being added in Objective C (better late than never).

Edit Jan. 12th, 2013 : the above code would now be written as follows :

// no array of ints, only arrays of NSObject* so :
NSMutableArray* arrayOfInts = [NSMutableArray array];

// add one element
[arrayOfInts addObject:@1];

int i = arrayOfInts[0].intValue;

// or, even simpler :

NSArray* arrayOfInts = @[ @1 ];

int i = arrayOfInts[0].intValue;

end Edit

So why choose Objective C over C++ at the time ?

Because Objective C, as verbose are its basic APIs, is actually closer to Python than to C++. The object model is much more elaborate than in C++ (in which you have nothing else but virtual methods) : classes are first class objects, an object can be asked if it handles a method or not, you can add methods to a class at runtime and without having to derive it, and the language’s position toward type safety is much more relaxed – it’s essentially duck typing. You don’t have to declare a method in the interface to implement it, which is very convenient for internal methods. You do not have to declare a method that you override either, again simply implementing your classes’s own version is enough.

@interface MyClass : NSObject

// nothing

@end

@implementation MyClass

// this overrides NSObject:init
- (id)init
{
// some code
[self moreInit]; // moreInit not declared in interface
}

- (void)moreInit
{
// some more code
}

@end

In C++ that would be :

class MyClass : public Object
{
virtual void init();
virtual void moreInit();
}

void MyClass::init()
{
// some code
moreInit();
}

void MyClass::moreInit()
{
// some more code
}

All this makes of Objective C almost a scripted language in disguise. While in C++ you will spend a lot of time getting your types right, and any non-trivial refactoring will take a whole lot of time, Objective C lets you code much more freely.

Read post...

May 13, 2012

Coralie Mercier

Last day in Costa Rica

Saturday 5 May, 2012. We're touring one last time in Alajuela, and leaving Costa Rica in the afternoon. We'll be home Sunday evening.

We were drawn to the square near our hotel, that faces the Alajuela Cathedral.


We spotted a man who looked typical under his bright white hat.


And we crossed the square and there was a little girl with a pink polo shirt and her abuelo who were busy feeding pigeons. Hundreds of pigeons. People were gathering around them and watching. She was so happy and he was so proud. The grand-father poured a few crumbs on the little girl's head and soon both of them were assailed by birds.


Attracted by the commotion, squirrels crept down a tree nearby. I didn't think so many squirrels could populate a single tree. They wanted their fair share, of course. And children and adults were happy to deliver.


Vlad was close to one, extended his hand and the squirrel sniffed the empty hand before trying someone else.


Each squirrel would snatch the food and hop back on the tree trunk and climb someplace to eat, wary of other hungry squirrels.


Back to the little girl with the pink polo shirt. She decided the pigeons were more rewarding and got back to them. This is her, holding a plastic bag full or crumbs, proudly leading hundreds of pigeons. Such a happy face.


But we wanted to explore Alajuela again, since it had been raining the day before and there was sun on that fine morning. We walked for two hours and a half, not very fast, and spotted six churches and four soccer fields. And we explored only a fraction of the city!


We followed a man who was pushing his cart on the road. We had seen several of them already. He seemed to sell drinks and snacks. What we had also seen in other places through the country, are people at street lights selling bagged fruit or vegetables that they hold in both hands, and even shrimps in a bucket.


Another thing that striked me compared to where we live, was how prettier their advertising posters and paintings are. Except in San José and Cartago, cities have modest posters and advertising paintings that appeal to me far more than the industrial, gigantic printed ones. Here's the advertisement, painted on corrugated iron, for a car wash and parking, and much more, it appears.


We got back to our hotel, via a part of town that was more spacious and nearly deserted. Maybe it was that people were eating lunch. I had the feeling we had the streets all to ourselves. Here is a bright blue minivan parked in front of a house where people sold pineapple, 3 for 1000 colones ($2).


And here is the outside of the fruteria Las Delicias.


Soon after, we checked out and hopped in a taxi. The fare was supposed to be around $6, but when I asked the driver, at the airport, what he said in Spanish sounded like 13,000.00 colones. I realized, but too late, that he had probably said 3,000. Ahem... I gave him 11,000.00 and was looking for more when he gestured it was enough. Then he seemed to be looking in his wallet either for change or for a receipt, and we were getting our backpacks. Since he wasn't handing us anything we said good bye and left. He followed us with his eyes. This is when I realized he had let us give him nearly twice what he wanted. Oh well. He had been a decent and friendly driver.

And before 5 p.m., we left Costa Rica, relaxed although tired, and our heads full of extraordinary memories. We had wanted to visit that country for years and we were not disappointed at all. Vlad did a wonderful job organising the trip, choosing the route, selecting places and lodges. It was such a great vacation.


Read post...

May 12, 2012

Coralie Mercier

Costa Rica: Puerto Jiménez to Alajuela

Friday 4 May, 2012. We're leaving Lapa Rios lodge in the beautiful and preserved Osa Peninsula. José, who drove us there four days ago, drove us back, as well as two other people from the lodge who needed to be in Puerto Jiménez. José spotted a caiman on the way; we had told them how foolish we had felt the day before, standing only meters away from one and joking we had yet to see a caiman.

We were in Puerto Jiménez at 11 a.m. and had over an hour to spare till we needed to board our flight. It is a small city by the golfo dulce (because the ocean water is "sweetened" by much river water). We walked in streets, few of which were in asphalt concrete, circled towards the waterfront and back to the airfield.




The plane was even smaller than the small one we took four days prior, however, the flight was devoid of any air pocket and I enjoyed it even more. We flew to Golfito where a few passengers got off and a few others boarded, and then we took off for San José. It was all so very lovely from above.






We were going to spend a night, the last one, in Alajuela, which is the closest city next to the San José airport. It was raining but not a lot and we spent our time improvising a tour, taking pictures of what we found beautiful (and I took a lot of pictures).







After sunset, we found ourselves near the Alajuela Cathedral and went inside. It was very pretty. Vivid colours, some parts painted as fake marble, a narrow but long vaulted ceiling with several biblical scenes painted in bright colours, rows of white neon lights. We were intrigued that there was a band inside, tuning their instruments and rehearsing. And there was a steady flow of people, all dressed up, who were coming in. Was it going to be mass or was there going to be a wedding, we wondered. After more than an hour, mass hadn't started, more people kept coming in, and the band had rehearsed tunes and songs a couple of times. We felt sort of out of place, not dressed up and while we were respectful of the place and people, it had been mostly curiosity that made us stay. So we left. We found a bar and had a drink (Imperial bier for Vlad, tequila sunrise for me). We walked by the cathedral again an hour or so afterwards and mass was taking place. The big cathedral was filled up. I don't know if they were celebrating something particular of this is their regular Friday mass, but I was impressed. I suspect the former, as there was a crew filming, a master of ceremony with a microphone, one cleric dressed in golden-coloured clothes and a dozen others dressed in white.

Read post...

May 11, 2012

Guillaume Laurent

Focus

(yes, this is an old topic, but I’m a slow blogger. Anyway…)

Of all the material that came under the spotlight shortly after Steve Jobs’s death, the most interesting one I’ve seen by far was his WWDC keynote from 1997 :

Let’s recap the situation : Apple is months away from bankruptcy, Gil Amelio is the current CEO, they’ve just bought NeXT and Steve Jobs has returned as “advisor”.

At the WWDC (that’s the Mac developers worldwide conference), Steve Jobs walks on stage and instead of doing a presentation, offers to take questions from the audience. And his answers have made me realise why the guy really was completely different from the other tech CEOs that run other IT companies.

Here’s a breakdown of the most interesting moments (time indications are approximative) :

4:00 – explains how he thinks that there’s a market for great products. Not “fancy products with an apple logo on them” – great products. Products that stand above the others in term of quality. All other companies do market studies, try to offer a variety of products tailored to each market segment… He wants Apple to do differently.

5:00 – “I know some of you worked on stuff that we put a bullet in the head of” : the way he acknowledges that is rather uncommon in my experience. Most would try to weasel around the issue and soften the blow. The reason he doesn’t is not because of his usual callous approach, it’s because he’s able to justify it with what comes next : “Focus is saying no”. This will echo to any developers who’s been involved in a project that has fallen to feature bloat. Raise your hand if you’ve met many managers with this kind of mindset. I haven’t.

10:00 – at this point he acknowledges that Apple should no longer reinvent everything, as they had done in the past. Pick the right elements (i.e. the Unix core technologies), figure out what they need to turn them into a product that is really better than the competition. And they did just that.

13:00 – “using computers not for computation intensive tasks, but as a window into communication intensive tasks” – coming from NeXT, he describes what his experience was using an OS which had the network built in from the start. A familiar vision to any Unix user, something very remote to Mac users at the time. In more ways than one, he also describes what cloud computing is aiming to bring to everybody now.

He also mentions gigabit ethernet, which will only be deployed 3 years later.

16:00 “what is really exciting to me is to look at that personal computer, and take out every moving part except the keyboard and the mouse”. That’s the Macbook Air, right there, which would be released 11 years later, in 2008. There was also the failed Sun/Oracle Network computer in between, but Apple pulled it off.

19:00 “Apple is vertically integrated – makes the hardware, the software, the marketing experience”. To this day, nobody else than Apple has this, and few still understand how fundamental a strength this is for them. So he got that while the PC world has the advantage of economies of scale, they can’t match Apple’s reactivity and ability to provide a much more seamless experience.

22:00 let’s not forget this is a developer convention – here he explains how cool the NeXTStep development platform is. Nothing special in itself, except that I don’t know of too many CEOs of IT companies who can convincingly sell a development environment to an audience of experienced developers. The part about “managing complexity” (at 25:00) really hits home.

41:00 “the way you get programmer productivity is not by increasing the number of lines of code per programmer per day. That doesn’t work. The way you get programmer productivity is by eliminating the lines of code you have to write. [...] the goal here is to eliminate 80% of the code you have to write for your app”. Another thing that not too many tech managers get (although more do nowadays than back when this was recorded). That’s why he chose Objective C over C++.

01:01 About the Newton. “Most companies can be successful with 1 stack of system software. Rarely can they manage two and we are going to succeed at managing two during the next several years with MacOS and Rhapsody. I cannot imagine being successful at managing 3″. Let’s recap : this is still MacOS 9. Rhapsody, which will become Mac OS X, is in its infancy. So Apple will have to manage those two. The 3rd one is the Newton OS, therefore that will have to be shut down. Again, focus.

In a few years, once OS X is well established, they still will release the iPod, which did have its own (very simple) OS.

“Do you have a newton ?” asks a guy – He replies he bought one of the early ones, thought it was a piece of junk and threw it away, same with a Motorola Invoice. He grants that the new Newtons may be a lot better, the guy suggests he tries one, but he stops the argument with this : “the high-order bit is connectivity. It’s being in touch, connected to a network”. He then explains that using infrared to transfer data from your organizer to your computer when you get back is not what he wants. “If somebody would make a thing where you’re connected to the Net at all times… I’d love to buy one”.

Again, 1997. The Net is mostly accessed through modems. DSL is in its infancy. Wireless data access hardly exists at all. Yes, the concept itself is obvious, but at this point it’s clearly many years away… 10 years away, to be exact, when he took the stage at MacWorld and started with those words : “we’re gonna make some history today”. Others had implemented that concept before them (Treo, Blackberry), but they set the bar on how to do it.

Name one IT company which could see and plan 10 years ahead, and successfully achieve those plans. That’s focus.

Read post...

May 10, 2012

Coralie Mercier

Costa Rica: day tour in the Corcovado

Thursday 3 May, 2012. Third day at Lapa Rios in the Osa Peninsula. A day of adventure, like I wrote yesterday as a teaser. The helpful staff at Lapa Rios had asked whether they could help us make arrangements or provide information, so we told them we were keen on a day tour in the Corcovado and had heard there was a bus going to Carate and it would be helpful if they had more information. They said the bus in question was called "colectivo" (or camion) and wasn't a bus strictly speaking. It is a truck and behind the cab the passengers area is made of wooden planks as floor, two long benches and this is covered with a tarp. I think most of the lodge staff came to us over the two days prior to make sure this is how we really wanted to travel. One of them even said it could be a traumatic experience (sic). We thought we would live through it. We actually enjoyed it, being a one-time experiment.

We woke up at 5.45 a.m. to prepare ourselves, get an early breakfast (again, the staff was kind enough to accommodate us, as the kitchen normally opens at 7), and be by the country road before 7 a.m. with one of the staff members, Eli, who wanted to make sure we were on the right track and find out from the driver when and where we had to be to make it back to the lodge on the same day wink We paid the flat fare ($8 per person for a single ticket), climbed inside and waved Eli good bye. With us were four or five locals and four other young tourists.


It was a long trip, all in all, 1h30 for something like 20 km. It had been bumpy, some rough patches even hurt our back. The truck passed through water (either rivers, or puddles big as small ponds), climbed steep rocky hills at the speed of the sloth, but the driver was pretty good, I found. We arrived in Carate around 8:30 a.m.


It was already hot outside and the weather was gorgeous on that day, with sun and big white clouds. We needed to walk on the beach forever to reach La Leona, where the entrance of the Corcovado National Park was. The beach was splendid. We wondered why nobody was either sunbathing or swimming. We later heard there were rip currents. And sharks.


After an hour of walk along the beach we reached La Leona, gave our tickets to the guard and mumbled something about high-tide around noon, crossing the river, "walking two hours". We nodded and took off, it was nearly 10. We entered a forest by the beach but were walking on a trail in the woods. There was something peculiar about the light during the morning. I think it had to do with the very fine mist created by the breaking waves which crept inside the forest and was visible when met by the sun. I saw beautiful sunbeams through the trees. We soon saw capuchin monkeys, at eye level and only a few meters away from us. This appears to be a favourite position:


We found ourselves at the river the guard had mentioned. It wasn't noon already but the waves met the water of the river. We took off our walking shoes and socks, rolled up our trousers and waded in waters that weren't too deep (mid-sheen) but reached our knees when a wave was breaking. We met a couple of trekkers who tipped us that there was a Baird's tapir near the Cementerio Madrigal and they explained how to find the place, not far from where we were. We were looking for a smaller animal than it actually was (my idea of a tapir was that it was as big as a cat, and Vlad thought it was the size of a dog). Then I saw it. Huge. The height of a poney, the bulk of pot-bellied pig, the feet of an elephant and a dinosaur, the ears of a hippo and that snout which is so distinctive.


We came a little too close to the tapir who went away. We followed. Then Vlad spotted an anteater in a tree. This too, was larger, longer, and bigger than we thought. It was really beautiful. Alas, it was pretty active, moved a lot and at some point we couldn't keep up.


We were near the beach and walked to it. Perfect place to picnic. The Lapa Rios staff prepared sandwiches, crips and cakes.


At 1 p.m. we resolved to turn back and take our time. We had to be in Carate where the colectivo had dropped us by 4 p.m. (or spend the night and catch the next one on the next morning). The light has changed. Less over-exposed. But the mist and sunbeams were gone. We crossed the Rio Madrigal again.


The spider webs in the forest were beautiful, strong, small, tightly woven, and there were many of them. Some bare branches even looked like a whole dream catcher with the amount of spider webs they bore. We saw several golden orb spiders (they're the length of my index finger):


Vlad spotted a squirrel for the second time on that day. This one was reasonably close to us. It was busy munching wood (isn't there good acorn in Corcovado, I ask?), checking on us from a distance every now and then.


Then I spotted a black-throated male trogon on a low branch. It was splendid!


We resumed our walk but stopped almost immediately; I had spotted a black and green dart frog:


Again, we resumed walking but soon stopped under a group of capuchin monkeys with their young. One appeared to smile at me. And then I wondered, was it a smile or was it baring its teeth at me. The latter, most likely. I went from "awww, look, it's smiling at us!" to "wait, this isn't a pretty smile". So here's a non-threatening monkey, looking up at a young one (the baby isn't in the photo):


We exited the forest (and the boundary of the Corcovado) after 2 p.m. and braced for the long walk along the beach, under the sun. We stopped mid-way next to a pond to watch the Jesus Christ lizards run on the water. What a singular spectacle. The spot was lovely. With no wind, there were palm trees reflected in the water. We took a little break. Vlad joked that the one thing we hadn't seen was the caiman. The next instant, there was a swift movement and a splash --a caiman was there, not 3 meters away from us! We were so certain there wouldn't be one (we had inspected the pond edges on the way to the park in the morning), that we didn't think to check again. Oh, the idiots. On the photo I took of the spot, we can see a dark shape by the water, behind a log, it is the caiman (I have increased the contrast in post-processing to make it a little bit more obvious, but still it is a fraction of the photo, and this made me think of where is Waldo).


We laughed at ourselves for a while, and kept walking back to Carate. At the end of the beach, there was one last beautiful animal in plain view. A yellow-headed caracara was perched on a low bare branch not far from us:


We reached Carate at 3.40 p.m., with ample time for drinks and reflection. What a great day. It was as though every animal we had seen had been planted there for us to admire. The colectivo was a little late and we were back at the Lapa Rios lodge shortly after sunset, 5.45 p.m.


We were greeted, like a couple days prior, with wet hand towels and fruit cocktails. And then it made sense. Both were totally welcome and highly appropriate. The staff asked us how it was, they looked worried but not for long, we looked and were delighted.
Read post...

May 08, 2012

Coralie Mercier

Costa Rica: Second day at Lapa Rios, more beach and rainforest

Wednesday 2 May, 2012. The morning of the second day at Lapa Rios, I got to see the sun rise. It wasn't yet 5:30 a.m. and surfers were already in the water between the pan dulce playa and the backwash playa. Two of them. I sat on the deck and sipped coffee, took photographs of what was around me. In the tree above the roof, there was a big iguana which had been there already the day before. It had barely moved. It was partially hidden by foliage but in the morning sun its colours were splendid. There were hummingbirds in the little garden trees by the deck. And butterflies. Pelicans which crossed the sky between the forest and the beach. None of the photos are good enough to post, though. So here is our bungalow as seen from the deck:


It occurred to me that morning, and at other times during the trip, that while one is busy taking a photograph of something, there is often a sound that disrupts the whole process, because one knows this is something else worth photographing. I sipped more coffee with Vlad around 6:30 a.m. when he woke up (the slacker).

We had decided to go down to the beach again before breakfast and left at 7:30. Pan dulce playa and Backwash playa:



There were several surfers, by now. Here is one who was smiling (perhaps it isn't obvious on the small photo):


From the beach this is the view we had on the bungalows:


On our way and at the beach, we saw spider monkeys, crabs, scarlet macaws, a black vulture. We left in time to get breakfast up-hill at the lodge, and came back down. On our way, we finally spotted the sloth in one of the trees. A naturalist had told us the day prior that a sloth had been spotted in that tree and there was a good chance it was there. But the tree was quite tall and not exactly bare of leaves. Anyway, there it was, far up, and we saw its fur. For a good while we could not guess in which position it was. We were pretty sure its back was facing us and this is it. After some time, it moved slowly. One has to see it to reckon how slow the movements are. We distinguished an arm and guessed where his head was. We knew this was a male; we had heard from a guide in Manuel Antonio national park, that male sloth have a black strip along the neck. We were keen to wait to see more of him. I was thinking of my good friend Amy who is endeared by sloth. Eventually, he showed us his face:


We had spent so much time there that returning to the beach wasn't a plan anymore. We indulged in lazing around for a bit at the bungalow and went for lunch. Food was delicious there. I can't think of any good reason to miss a meal at Lapa Rios wink All the more reason that from the deck next to the tables we had seen many birds and animals. And there happened to be spider monkeys, albeit a bit far:


In the afternoon we went back down-hill along the edge of the rainforest. We meant to walk on the country road a good while and reach a flat area with fields and a river, where we expected to see herons, birds of prey and possibly a caiman. But we didn't since we spotted so many other animals after travelling only a short distance --a yellow-headed gecko with a blue body, the sloth again (which was apparently sleeping and had shifted position a bit, he was sitting and bundled and his arms were hugging a branch and his head seemed to be rested between his folded arms). We also saw an agouti which we sort of tracked as it progressed in the forest parallel to our trail. A little farther down, Vlad spotted a blue-crowned motmot, a lovely colourful bird with a long tail which tip resembles two rackets.




We went into the forest, instead of going to the plain. We were looking for a waterfall but had no idea where it was. We crossed a river but couldn't progress on the side of the river we thought we could find the waterfall. We saw more vegetation than wildlife, to the exception of ants with a big yellow abdomen that looked almost golden. Some of the trees had colours on the bark that made me think of camouflage. Here is Vlad next to one of them, a big one:


We found ourselves on the path we had taken the night before with the guide. We easily found the tarantula nest. Vlad couldn't resist; he grabbed a thin stick and did as the naturalist had done to coax the spider out. He lightly touched the mesh of thin web outside and around the edges of the nest --hairy brown legs darted out to attack the stick. Guillermo had described this as fishing. So Vlad fished the tarantula out. It took him a couple of minutes. Well done.


As the guide had said, it was too bad we didn't have a grasshopper for the spider, as it had really earned it. I wasn't going to find it myself, scared as I am of insects. Again, I was so eager to be out of the forest. It was going to be sunset soon and this part of the forest was already getting dark.

The sunset colours were pretty. I can't believe it took us two days to look for them.


The dinner time and evening were rich in emotions. During dinner a huge brown grasshopper decided to land on my back and stay there until Vlad carefully took it away. Already the night prior at dinner, a couple of lizards had landed on my hand from a beam in the ceiling and they scared me, but I didn't freak out about the lizards as much as I did about the grasshopper. Then we walked to the bungalow, where I went straight in while Vlad stayed outside and walked further down to look for tree frogs or poison dart frogs. As soon as I closed the door I noticed another big brown grasshopper which was on the door, inside the bungalow. I called Vlad and asked him to come save me again, which he did. Whew. But that wasn't all. A few minutes afterwards I spotted a big black cockroach inside one of the white mosquito nets that surround the beds. That wasn't all, there was another one, one of the kind that is wide, long, flat and brown. It was at eye level, on the mosquito net that served as separation between inside and outside the bungalow. Both of them were immobile. So I did that too, at a safe distance from each of them, and surveyed them till Vlad returned and was my hero again.

The week prior in the mountains, a huge green grasshopper flew straight to me cheek and landed next to me on the bench. There has to be a law that the insects will go to those who are scared of them. If Vlad had similar experiences during our stay, either I wasn't around when it happened, or he didn't make a big deal out of it and didn't tell me at all ;)

We're now back where insects are minuscule and I can tell that these don't scare me as much as they did pre-Costa Rica. Last night even, I ushered a spider outside. Yay, me. End of the insect phobia rant.

Closing statement of the entry at hand. Our next day in the Osa Peninsula was going to be quite an adventure and this is a story for next time.

Read post...

Coralie Mercier

Costa Rica: First day near Carbonera, day and night wildlife

Lovely morning. I was up early but not early enough to see the sun rise. Still, as the sun was rising to reach the layer of clouds that hung over us all day, the view at that time was really pretty:


This day was devoted to spotting wildlife, as was the early night since we had signed up for the lodge night walk with young naturalist Guillermo.

During breakfast one of the naturalists came in the main bungalow, holding a small coral snake on the back on his hand:


We thought this had to be the non-poisonous fake coral snake, which pattern of coloured rings differs from the venomous one. But it was the Costa Rica coral snake. It was just still too little to be able to bite. The naturalist let it go on the ground next to us, where it tried to hide under Vlad's flip flop, and then under a rock. A bit later, it was about to slither away:


We decided to walk down to the beach. On our way we saw a young green iguana:


And we saw a couple of coati mundi in a mango tree, hunting for fruit. Here is one:


We ventured away from the country road into what we thought was a short cut to the beach but was in fact a private property, and back-tracked. But I stole (snapped) a few photos, including a pineapple, a bungalow, and a beautiful red hibiscus flower that looks like a Christmas tree bauble:




At the beach our attention was drawn to a tree that was squawking. Several scarlet macaw were perched and as we drew closer we saw them through the foliage. Here is one holding in its beak what it was going to tear to pieces and eat (almond), and the same bird flying away later in a blur of red and blue feathers:



We also saw a mangrove black hawk perched on a palm tree and surveying the beach:


Back up the hill to the main bungalow. After lunch we observed a couple of Swainson toucans who were pretty close to where we were on the deck:



The sun sets around half past five and it gets dark shortly after 6 p.m. We were at the naturalists' station for a night walk around one of the trails in the reserve. There were two other people with us, and Guillermo, the guide. The walk lasted almost two hours and near the end, I was glad I was doing it, but so ready to be out of the woods, away from its insect diversity. Here is is impressive list of what the guide spotted to show us: giant brown grasshopper, gaudy leaf frogs, basilisks, Jesus Christ lizards, a weird-looking angular black insect from the same family of the scorpion, wolf spiders, jumping spiders, asleep blue-throated female trogon, baby scorpion, Fer-de-lance snake, and finally, a tarantula.




And since we're at the chapter of the night residents, here is a large moth (its width was about the length of my hand) that I photographed the day before:


After the emotion, we were ready for civilization, dinner and we rewarded ourselves with red wine from Chile.
Read post...

May 07, 2012

Coralie Mercier

Costa Rica: Going south to Osa Peninsula

I used all the data of my Kolbi SIM card pretty quickly, hence the interruption in the flow. We're back home since last night. I'm now catching up.

Monday 30 April 2012, we left Savegre Albergue de Montaña under the fog and drove to the city to return the rental car. The drive took almost three hours. After so many days away from cities, it was a bit of shock --all the animation and traffic. San José itself was crazy. Not only was there a lot of traffic at mid-day, but we drove past three accidents although people don't speed that much (none of the accidents seemed serious, fortunately). At this intersection, for example, a truck had collided into a car (not visible in the photo), and while policemen were taking measurements, the traffic was taking place around them, both on the road and on the sidewalk visible at the right of the truck:


The car rental guy agreed to drive us to Tobias Bolaños international airport, a very small airport. So small that it didn't have a bar or cafeteria, not even vending machines. We were starving. It occurred to me to try to catch one of the big birds or climb the giant mango tree and pick ripe fruit. But we just sat outside in the shade, enjoying the breeze, killing time. We were going to travel very soon in the blue plane:


The plane in question was a Twin Otter, and it wasn't the smallest of the airline (since we flew in a smaller plane on the way back). About 15 passengers boarded around 3 p.m. and soon we took off. It was really impressive, more impressive than the usual big airliner. It wasn't scary or anything (at least, not for me; I don't want to tell on him, but this isn't necessarily true for Vlad), the plane lift off quickly but not as high as big airliners do. So we had time to see the immense San José under us getting smaller and smaller, but it is such a large city that the entertainment lasted a while:


Then the city went away and came the hills and their curvy ochre country roads, and meandering rivers between hills, and then clouds. We flew through clouds and above them. At some point during the 50-minute flight the pilots couldn't avoid a series of air pockets. It lasted just long enough for my body to prepare to get sick (that is, five long minutes), and then to be glad it was over.

We landed in Puerto Jiménez, right behind the seafront and next to a cemetery very similar to those we saw in Guadeloupe last year, with white and black tiles decorating or protecting graves. We were going to be in the Osa Peninsula for 4 days, staying at the Lapa Rios Lodge, a luxurious ecolodge of 16 bungalows, for which we got a special offer. But first there was a short stay at the local office of the lodge, where we were greeted with a local drink --agua de pipa (coconut milk) and banana cake (very nice):


Then we set for a forty-minute ATV drive, as Lapa Rios is 18 km south of Puerto Jiménez. On the road, our driver showed us three big birds --crested caracaras, one young and two adults--, some monkeys in the trees, and a juvenile blue heron. When we reached the lodge there were two members of the lodge staff to greet us with wet hand towels and cocktails of fruit juice. How nice and unexpected.

We were then given a short tour and introduction, and were taken to our bungalow. It was dusk, there was still enough light to discover the view from the deck; long big waves in Cabo Matapalo, behind a thick forest:






Read post...

April 30, 2012

Coralie Mercier

Costa Rica: quetzal quest in the highlands


We're near San Gerardo de Dota, in the mountains, and it's quite cold except in the sun. We even lit the fire in the room at night.

The weather is splendid in the morning and we set on a walk yesterday, looking for quetzals. We were told about a couple nesting not far from the lodge, by the dirt track.

On the way, we saw tall trees covered in moss and epiphytes.


And some birds, too. Although we heard many more than we saw, a species of woodpecker was all over the place. Here's one at the entrance of a hole in a tree.


We kept walking toward the small church and soon enough we spotted a group of people with a guide by the fence of the dirt track. A binocular was aimed at the top of a beheaded tree, some twenty meters away. Two long green and blue quetzal feathers emerged of a hole in the trunk --the nest, and were flying in the breeze.


The group had been here for a while already and they had been lucky to see the male quetzal outside of the nest, ruffling its feathers in the sun. The guide said the female would be back shortly, as she goes away between 45 and 60 minutes and then the male can leave.

Our wait was interrupted by the thunderous and surprising sound of horses galloping. Seven or eight horses were coming at us at high speed. My 100-300 lens was fitted on the camera and I could photograph but details of them as there was a curve near us and they soon disappeared.


The wait continued. After an hour, the group left. The female should have been back a half hour prior and the people had other things to do. We waited some more. A little wile afterwards, we saw the head of the male quetzal emerging from the nest, looking in every directions. I took a few photos and suddenly it plunged and flew away behind foliage. We never saw him again and thus, couldn't get a picture of its full body.


The female had to be back sooner or later... A half hour later I spotted a bird landing in the distance, zoomed in and it was her. Green with a medium length tail that appeared spotted or striped. She ruffled her feather and I noticed some red below her chest, under her otherwise green feathers. She stayed on that high branch in the distance for 25 minutes before she flew to the nest at noon.


Soon after, she got into the hole, hidden from view. We didn't see the young. Her head and upper body emerged 45 minutes afterwards, she looked left, right, top, tilted her head a few times, and went back in. We waited some more. By now the weather had worsened. It was raining slightly. Woodpeckers were still flying from one tree to another, entertaining us. Here are three aligned on a bare branch.


We decided to wait till 1.30 p.m. and leave, weather we see the male again or not. And we didn't. Meh. The rain was coming down harder anyway.

The mountain had been pretty in the sun, but in the rain, with low hazy clouds visible, it was even prettier.



It was pouring rain by the time we reached the lodge. We rewarded ourselves with lunch; it was 2 p.m. Sheltered by the roof outside we looked at hummingbirds, mostly black ones with a straight long beak, but also green ones with a curvy beak.

Read post...

Coralie Mercier

Costa Rica: Playa Dominical to Dota Valley, or altitude 0 to 3360 m. in one day


We left Manuel Antonio under a pale sun and after a breakfast of gallo pinto (white rice and black beans) with ham and eggs. Here is a photo of the ocean above a red corrugated iron house roof and a hedge of red hibiscus:


We were driving on the CN34 between Matapalo and Barú when a flock of big birds in a dirt field caught Vlad's attention. We stopped on the side and saw dozens of black vultures. Some were perched on chopped wood, others on a fence, and the rest was in the field, packed. We approached slowly and they let us within five meters of them.


On the road again but not for long. Soon we reached Dominical. The view from the bridge that crosses the river Barú was astounding. We saw big water birds (a grey heron, an egret) and stopped, but soon we saw an aracari (a sort of toucan), and beyond the river there was the ocean and big waves.


We stayed two hours between the river and Playa Dominical, photographing leafcutter ants, cormorants, basilisks, a green heron, black vultures, crabs, brown pelicans. I leaned so close to the female basilisk that I can see the shape of my body reflected in her eye.


Then we drove on a track next to the river Barú, wondering if we'd see crocodiles, as there were signs warning against them. Also, openstreetmap didn't have that track. It was about 3 km long and when it stopped, it did at the river, steeply. We parked. Soon after, a pick-up truck crossed the river. It was impressive. We walked a bit along the river. Vlad saw a little crocodile but it dived immediately and we never saw it again. I photographed a tiny brown frog, flowers, etc. and Vlad, crossing a ford in the 4WD, of course.


Back on the road, more curves, more bumpy tracks, more rivers crossed, including the Rio Savegre. I was in awe in front of a tree next to a house by a bridge crossing the Rio Savegre. A tall tree bare of leaves but full of pink blossom. Here, see:


Before and after the big city of San Isidro the road kept winding and climbing, except that after San Isidro, it was called a highway. That is, one lane each, limited speed of 50 Kph, with many big trucks that drove well above the limit, in both directions. We passed through small villages, watched the very green pastures, forests, in the sun and above clouds.


Then we were in the clouds. Around 6 p.m. the clouds around us had a pink or orange glow. It was eerie.


We climbed some more, and soon were at the highest point, 3360 meters, and we understood the glow ealier. On our left there was the most amazing sunset we had ever seen. High as we were, there were mountains underneath, each valley filled with thick white clouds, the summits emerging, and above us there were several layers of clouds that the sun was colouring in deep pink, bright orange and red. Here, see:


We were late, but nevermind, really. Soon after the pass, we drove downward, took a left and drove, in the dark, on a bumpy track during 9 kilometers (how long? Between thirty and forty minutes) and we reached Savegre Hotel de Montańa.


Read post...

April 28, 2012

Coralie Mercier

Costa Rica: Catarata de Cortés, Tarcoles crocodiles, Manuel Antonio National Park


We left the Arenal area and set to drive for a good while under the sun, for a change.

We stopped by the side of the road as Vlad spotted monkeys in a tree, spider monkeys.



We made quite a detour to see the Catarata de Cortés, the prettiest waterfall I ever saw.


In its vicinity there was a little pool of water where no tourist was, that was populated by lizards, one of which was really big, grey, and crested from head to tail, possibly a basilisk.


We didn't stay long as there was driving to do, but Vlad took a dip. On the road again, we quickly saw the change of vegetation and scenery as we were driving south. Less forest, more plaines.



We were in Tarcoles, our next stop, around 4 p.m. This place is famous for its long bridge under which many crocodiles rest.




We even saw an iguana.


We had a little more than two hours of daylight and hit the road again to reach a place between Quepos and Manuel Antonio. We arrived a bit after dark which comes a half hour after sunset. And then there was thunder and rain.

Fast forward to next day, a rainy day, but the one day we could visit the Manuel Antonio National Park. In a tree right next to our room there was a howler monkey.


We were advised to take a guided tour as only a guide could show us animals on this rainy day, but we didn't feel like being with a guide and preferred being on our own, taking our time. We didn't regret that choice. We saw so many animals!

A deer, a toucan, woodpeckers, a bird big as a pigeon with a red chest and a striped tail, butterflies, dragonflies, an urubu (red-headed vulture), hermit crabs, crabs, spider monkeys, a bird of prey which was all black, a female capuchin carrying her baby and which let us follow her for a while in the forest --a most magical experience!-- and finally, a female sloth.



The Park also had lovely beaches. Vlad went in the water (I forgot my gear). As I was on the sand, I saw two raccoons.



The park closed at 4 p.m. It was still raining. We rewarded ourselves with drinks and a late lunch of snacks. I chose a mango rita, the most delicious cocktail I ever tasted.


Read post...

April 26, 2012

Cedric Beust

Dark Souls

I heard about Dark Souls when it came out because it was said to be incredibly difficult. I made a mental note of trying it out one day and then forgot about it. A few weeks ago, two good friends mentioned it to me again with high praises, so I decided to give it a shot. I dusted off my Playstation 3 (I’m pretty much exclusively a PC gamer), grabbed the game ($35 on Amazon, quite a bargain) and launched it with an open mind.

Nothing could have prepared me for what happened next.

Be prepared to die. And die again. And again. And again.

While the game starts with the standard tutorial on how to use the controller to move your character about and how to fight, I wasn’t exactly ready to face a boss five minutes into the tutorial and immediately die. Then try again, and die. And die, again and again. Ever time I fight it, I chip at his health a bit more but I realize that my sword hilt is barely damaging it at all, and at this pace, it would take me a very, very long time to kill it, assuming I manage to stay alive for that long.

I don’t want to spoil the game so I’ll just say that there is a way out, obviously, and once you figure it out, you realize that the game wasn’t being “stupidly” hard, it was just being “hard but fair”. It was giving you a small taste of what lies ahead. And that looked not just deliciously refreshing but quite enticing as well. You will die a lot in Dark Souls, but most of the time, it will be your fault and you will learn from it. And the next time you try, you’ll get a bit further.

Having said that, limiting the description of this game to this simple observation doesn’t come even remotely close to doing it justice.

Much, much deeper than it looks.

First of all, Dark Souls has the best combat system I have ever seen in more than thirty years of gaming. It’s not even close. Not only do you need to learn to hit, but also to dodge, to parry, to roll, to position yourself correctly, to backstab and to riposte. You also need to learn your opponent. Each of them (trash and boss) have cues that tell you what the next attack is going to be, and each of these attacks can be mitigated or completely avoided if you know what to do.


A bonfire, your best friend in the game.

Next, you have the enemy population. I’ve been constantly impressed with the level of attention that the developers have put in making the game challenging but manageable. There is only one level of difficulty on Dark Souls (with a small caveat, see below), so you don’t get to choose how hard or how numerous the enemies are. But they are planted along your way in very, very calculated ways that will make you want to be extremely mindful when you progress through new areas. This is not the game where you rush in a pack of enemies and mash your controller buttons until you are surrounded with carcasses. As a matter of fact, dealing with more than one enemy at a time will very often result in a quick death.

The leveling is also quite innovative. As opposed to most RPG/MMORPG’s, you are in complete control of how your character progresses. When you kill enemies, you earn “souls” which you can then use either to level, buy things or upgrade your existing gear. There is never a better path on what to do with all these souls, and the game is so well tuned that you can put all your souls into equipment upgrades and complete it at level 1.

When you die, all your souls drop on the ground and you need to run back there to retrieve them. However, if you die on your way to retrieve them, these souls are lost. This is a very simple mechanism (halfway between World of Warcraft and Everquest, which was very punishing) but one that creates a very palpable and constant tension. You don’t care too much about dying when you’re walking around with a small number of souls, but as you progress, that number grows and very soon, you start wondering if pressing ahead is not too risky and if you shouldn’t turn around, go back to a check point (bonfire) and spend these souls, which you can’t bank. Obviously, the fact that in new areas, the mobs are strategically positioned to kill you if you’re not careful makes for some very tense moments (“do not die, do not die!”). It’s not very often that playing a game raises my heart rate and hand clamminess, but Dark Souls definitely has this effect on me on a regular basis.

Who’s the boss?

The bosses are probably the least innovative aspect of Dark Souls. Don’t get me wrong, it’s nowhere near “Deus Ex Human Revolution bosses” bad: the Dark Souls bosses are still fairly challenging to the point where initial encounters usually result in a oneshot death within thirty seconds, but so far, I haven’t seen incredibly innovative mechanics. The bosses are still a lot of fun to figure out and I strongly recommend not reading any strategy beforehand, because killing bosses after figuring them out all by yourself alwas makes for an amazing feeling of elation. I do think the value of Dark Souls is more that the attention to combat details applies to all the mobs and not just the bosses.


The Hydra, one of the many, many bosses you will encounter.

Here is another innovative aspect of Dark Souls: when you reach a bonfire, all the enemies respawn (except bosses and a few special enemies). I was quite baffled when I discovered this, but I’m now realizing how important this aspect is to the Dark Souls atmosphere and philosophy. I won’t dig too deep in the details, but this aspect opens up the possibility of farming, which gives you an always available option to improve your character in case you think it’s not strong enough for the area you’re trying to explore.

Tools of the trade

Do you enjoy gearing up and tuning your weapons and armor? Dark Souls has plenty to offer in that area as well, with a mindbogglingly number of items to find and a lot of varied ways to enchant them the way you want them. Like many things, there is not a single true path there and it’s much more important to use and tune a weapon that fits your play style than picking up the one with the highest numbers.

Dark Souls is also very open in terms of character evolution. When the game starts, you get to choose the class that you want, but this class is not much more than a set of stats that are precalculated for you. When comes the time to level, you are free to put these souls into whatever stat you feel like, and if you started with a Knight but decided that you wanted it to cast a decent number of spells or wield daggers and move around very fast, just allocate the points in the correct categories (Faith and Dexterity) and you’ll create the character that represents your style of play. This flexibility of character build is what is prompting players to restart the game many times over and experiment with various builds. However, many choose to continue on with the same character, which is another intriguing aspect of Dark Souls.

Here is how it works.

Beyond the first play through

I haven’t completed the game yet, so I’m only repeating what I’ve read, but once you beat the final boss, you can reset the entire game and start from scratch. The new game (referred to as “NG+”: New Game Plus) features tougher enemies and bosses, and obviously, better rewards in gear and souls. Quite a few people seem to enjoy this aspect of the game as well since I’ve seen many say that they were on their third, fifth or tenth (NG+10!) play through.

Two is a crowd

One final noteworthy and innovative aspect of Dark Souls is multiplayer. First of all, you can play the entire game offline without any problems, but you will miss out on some very neat features of the game. If you choose to play while signed in, a few interesting multiplayer options open up.

On top of the traditional duels against human opponents, you can invade someone else’s game or be invaded. These invasions can be either co-operative or hostile.

For co-op play, you can leave a mark letting everyone know that you are willing to be summoned. If a player chooses to summon you, you will materialize in their world and, most likely, help them out with a boss that they’re having trouble with. Being summoned this way gives you a chance to observe that boss more carefully so you are more prepared to kill it on your own. Alternatively, you can ask for help, which can come either in the form of another player or from certain NPC’s, which are made available throughout the game for specific bosses.

Invasions can also be hostile, but you need to explicitly make yourself available to them in order for PvP to occur (like flagging yourself at WoW). In Dark Souls, you do that by “regaining” humanity. By default, you are not human (the game calls this state “hollow”). Regaining humanity will net you added rewards but it will also make you available for PvP, which means that other players can then invade you. When this happens, the current area becomes sealed and the PvP phase will only end when one of the two players dies (or the phantom withdraws). I’m not much of a PvP person myself, but I have to say that receiving the suddent notice that “Player xxx has invaded!” on your screen is always a bit stressful, and you start getting paranoid trying to locate that person before they find you.


In red, a phantom that has invaded your world.

A couple more interesting aspects of the online play: 1) players can leave messages for everyone else to see (“Chest ahead”, “Be wary of left”, etc…) and 2) you can see where and how other online players died by touching their bloodstain. In theory, this is supposed to give you an idea of the kind of trap or trash pull that lies ahead, but in practice, I can’t say I’ve found much value in bloodstains.

To the top with you!

I have played more than one hundred hours so far. I’m probably about 2/3rd through the game, and I’m still loving every minute of it. In more than thirty years of video games, I can only think of two games that I ever played more than one hundred hours: World of Warcraft and Civilization. Dark Souls has definitely earned the title “One of the best games I have ever played” with its mix of innovative features, amazing tuning, clever mechanics and engrossing world. Both WoW and Civilization have given me incredible amounts of satisfaction and fun, but Dark Souls goes beyond this by making me stressed, tense and incredibly elated when I finally overcome a difficult part.

It’s currently available on Playstation 3 and XBox 360, but a PC version is in the works and scheduled to ship this summer.

Read post...

Coralie Mercier

Costa Rica: Arenal volcano, Arenal Hanging Bridges


The Arenal volcano is supposed to be active, although not to the point that there is lava flowing or explosions. What we saw is a lot of cloud activity around it! But on two occasions, the summit was clear enough that we saw the shape of it, and we distinguished two sources of fumes, like thin streams of clouds, except they were going in opposite direction from the clouds.


We're staying at the Arenal Observatory Lodge. From the deck that faces the volcano, we tower above a lovely garden, that many animals inhabit. Mostly birds --including hummingbirds, toucans and oropendolas--, but also a coati or two and a couple of great curassows.


Yesterday we walked on a few of the trails around the lodge, reaching a river with old lava, a hanging bridge, a waterfall.


Today we went to the Arenal Hanging Bridges, a park of 600 acres of rainforest with 6 hanging bridges and numerous regular bridges, a trail of 3 kilometers (1.8 miles) that we "achieved" in slightly over 4 hours (possibly a world record of unspeed).


We saw a blue ara in the parking area. It flew noisily above us and landed close to us. Then it posed on top of a fence and even let us stand quite close.


Inside the park we saw lizards, ants, a few birds, two black squirrels, insects (not a lot, thankfully, there was one, somewhere between the ant and the wasp, that was as big as a little bird. Eek).

On the way back we stopped next to a field where cows were grazing. Or rather a breed of cows. They looked like zebus with ears like those of donkeys. Their head was very much like that of Jar-Jar Binks, in fact.

Read post...

April 24, 2012

Coralie Mercier

Costa Rica: La Paz waterfall

The visit to Volcan Poas almost happened. We drove on tracks and bumpy roads, passed through clouds and when we reached the entrance of the park, the cloud we were in was so thick that we made a U turn and went somewhere else instead. A wonderful place, La Paz waterfall gardens. In retrospect it's too bad we wasted time earlier.


Highlights of La Paz waterfall gardens: walking in a giant aviary --including walking where toucans fly, seeing many kinds of snakes --including some of the most dangerous ones of Costa Rica, I walked among a myriad of butterflies, and of course the waterfalls.




We continued on bumpy roads and pretty good roads, but also very shaky ones (Vlad got to push the 4WD button on the dashboard) for 2.5 hours to reach the Arenal Observatory Lodge.



We arrived a bit after sundown. The Arenal appeared enshrouded in clouds too, I see a pattern here. We'll see tomorrow if we see it. We're here three nights. There are numerous hikes. But now, there is sleep to be had.
Read post...

April 23, 2012

Coralie Mercier

We're in Costa Rica!

We are in Costa Rica and the place we are at tonight happens to have wifi, woohoo!
We landed in the afternoon, it was raining, but by the time we got outside it had stopped. We didn't see much yet, as the sun sets slightly before 6 p.m. But we hear a lot outside! Insects, presumably. Many of them.


The flight was long but OK. Entertainment wasn't so much provided by the in-flight TVs --there was one every five rows, attached from the ceiling, and while the list of films was impressive on paper, they showed only a couple. Instead, some of the entertainment was provided by a group of eleven Russian next to us, all males. The stewardess even took from them a big bottle of alcohol, and kept coming back, asking them to not stand in the aisle. There was this one massive guy, one as we see in movies, and he acted very much like he was either a body guard, or a handyman --or both. All of them looked Russian, to the exception of two old men, who looked British, and one teenager. The boy didn't look like any of them, except he had blue eyes. The rest of our entertainment came from eating tray food, playing Angry Birds, listening to music, and sleeping. Sleeping wasn't an issue. We went to bed real late the night before and woke up entirely too early.

Fast forward to the car rental place at a five-minute drive in shuttle from the San Jose airport. The people wanted us to rent a GPS and were amused that Vladimir refused because we're using the program he wrote. Amused and doubtful. One of them repeated that there is only one GPS program that works in Costa Rica, because they don't really have addresses there. Anyway. It took us where we wanted, all right.


Where we wanted is Tetual Norte, in Alajuela, not far from San Jose, and thirty kilometers away from Volcan Poas --where we'll go tomorrow. We arrived shortly after sunset. The colours were really pretty and the noises from trees and bushes were pleasant. We ate an early dinner of Indian cuisine.


Here is an overview of our holiday:
Volcan Poas tomorrow morning and then to the Arenal where we'll stay three days. Followed by two days near the Manuel Antonio Park, two days near the Parque Nacional Los Quetzales, three days in the Osa Peninsula near the Corcovado Park. We'll then spend one last day near San Jose before we fly back in two weeks.


Read post...

April 13, 2012

Philippe Kaplan

Maven pom tree

Here is a very nice trick I discovered almost by chance. Maven is an amazing tool to build software project. It scales...Complex and big projects follows the SCM (Source Control Management) structure, usually a tree. Maven's best weapon is indeed to structure the project in a tree, where each node contains a pom that follows more or less the following rules:module list is the list of children,it Read post...

March 31, 2012

Coralie Mercier

A couple tips, troubleshooting a bug in Opera menus

Before I forget and in case I need it later.
A bug in Opera 11.61 I submitted in February [DSK-357462] (that apparently others with similar configurations can not reproduce) still occurs in Opera 11.62. So I looked at other possible causes for that peculiar bug.

The bug is in any menu of Opera, any drop-down list and any right-click menu. When the menus appear, selecting through them is slow at best, and doesn't apparently work at worse. I can click several times and sometimes forever on an item in the list, it's as though the state doesn't change, or takes a while to actually select. I click outside of it to make it disappear and it just stays there until I click either outside of the Opera window, or sometimes (not always) until I hover the mouse over it and then click outside of it, inside the Opera window.

I needed to find when I last performed software updates. Karl gave me this tip:
cat /Library/Receipts/InstallHistory.plist

This is much more accurate than my intuition to search in the console (there is entirely too much info there, and this would take much longer) or looking in the Applications folder and find a common date for "Date Modified".

This allowed me to check that a few days prior to my noticing the bug, I had performed the "Mac OS X Update Combined" (10.7.3). This was later followed by a "Mac OS X 10.7.3 Supplemental Update".

Then I needed to assess whether my usage of Opera could be a factor. I typically run it several days or weeks without quitting it. I operate with 1 or more windows and the number of tabs I keep open is around 90. Opera is also my Mail User Agent, has been for years and as such its mail database indexes more than 133K messages (I archived once in 2004, but then I became lazy).

I performed two tests.
The first on my other computer which has the same OS as my work laptop and the same Opera version (the processors are different but I don't suppose the test is invalid). My opera session on that other computer has an empty mail database and I ran it with one tab. Menus were reactive as expected and selecting through them was smooth and gratifying. I opened several other tabs and I had the same positive experience.
I performed the second test on my work laptop and started a new Opera session with one tab and then a few. I was happy to experience smooth and reactive menu action. Happy and frustrated at the same time.

So maybe there is something in the early February Mac OS 10.7.3 update that impacts Opera to some extent. And if Opera couldn't reproduce the bug to fix it in 11.62, it may be useful to give them extra info on that bug.

Another good tip, via Dean, was to run in the Terminal:
sample Opera

And perform any menu action for it to dump an "Analysis of sampling Opera (pid xxxxx) every 1 millisecond" in a text file. The blitz sampling, which lasted a fraction of time, analysed me right-clicking on a link in a Web page and clicking on "copy link address", and wrote 21K lines, hardly any of them making sense to me. I sent it to Opera to accompany my February bug report.

Then I went back to my habitual session, bookmarked for good as many tabs as I could and tried with a 28-tab session. Same frustratingly slow menu actions. Oh well. I need them all (I need more of them in fact) to work, they're my work flow. I hope this is fixed some day.

Read post...

March 26, 2012

Cedric Beust

You’ve been implementing main() wrong all this time

Since the very early days of Java (and C-like languages overall), the canonical way to start your program has been something like this:

public class A {
  public static void main(String[] args) {
    new A().run(args);
  }

  public void run(String[] args) {
    // Your application starts here
  }
}

If you are still doing this, I’m here to tell you it’s time to stop.

Letting go of ‘new’

First, install Guice in your project:

        <dependency>
          <groupId>com.google.inject</groupId>
           <artifactId>guice</artifactId>
           <version>3.0</version>
        </dependency>

and then, modify your main method as follows:

public class A {
  public static void main(String[] args) {
    Injector.getInstance(A.class).run(args);
  }
}

So, what does this buy you exactly?

You will find a lot of articles explaining the various benefits of Guice, such as being able to substitute different environments on the fly, but I’m going to use a different angle in this article.

Let’s start by assuming the existence of a Config class that contains various configuration parameters. I’ll just hardcode them for now and use fields to make the class smaller:

public class Config {
  String host = "com.example.com";
  int port = 1234;
}

This class is a singleton, it is instantiated somewhere in your main class and not used anywhere else at the moment. One day, you realize you need this instance in another class which happens to be deep in your runtime hierarchy, which we will call Deep. For example, if you put a break point in the method where you need this config object, your debugger would show you stack frames similar to this:

com.example.A.main()
com.example.B.f(int, String)
com.example.C.g(String)
com.example.Deep.h(Foo, int)

The easy and wrong way to solve this problem is to make the Config instance static on some class (probably A) and access it directly from Deep. I’m hoping I don’t need to explain why this is a bad idea: not only do you want to avoid using statics, but you also want to make sure that each object is exposed only to objects that need them, and making the Config object static would make your instance visible to your entire code base. Not a good thing.

The second thought is to pass the object down the stack, so you modify all the signatures as follows:

com.example.A.main()
com.example.B.f(int, String, Config)
com.example.C.g(String, Config)
com.example.Deep.h(Foo, int, Config)

This is a bit better since you have severely restricted the exposure of the Config object, but note that you are still making it available to more methods than really need to: B#f and C#g have really nothing to do with this object, and a little sting of discomfort hits you when you start writing the Javadoc:

public class C {
  ...
  /**
   * @param config This method doesn't really use this parameter,
   * it just passes it down so Deep#h can use it.
   */
  public void g(String s, Config config) {

Unnecessary exposure is actually not the worst part of this approach, the problem is that it changes all these signatures along the way, which is certainly undesirable in a private API and absolutely devastating in a public API. And of course, it’s absolutely not scalable: if you keep adding a parameter to your method whenever you need access to a certain object, you will soon be dealing with methods that take ten parameters, most of which they just pass down the chain.

Here is how we solve this problem with dependency injection (performed by Guice in this example, but this is applicable to any library that implements JSR 330, obviously):

public class Deep {
  @Inject
  private Config config;

and we’re done. That’s it. You don’t need to modify the Config class in any way, nor do you need to make any change in any of the classes that separate Deep from your main class. With this, you have also minimized the exposure of the Config object to just the class that needs it.

Injecting right

There are various ways you can inject object into your class but I’ll just mention the two that, I think, are the most important. I just showed “field injection” in the previous paragraph, but be aware that you can also prefer to use “constructor injection”:

public class Deep {
  private final Config config;

  @Inject
  public Deep(Config config) {
    this.config = config;
  }

This time, you are adding a parameter to the constructor of your Deep class (which shouldn’t worry you too much since you will never invoke it directly, Guice will) and you assign the parameter to the field in the constructor. The benefit is that you can declare your field final. The downside, obviously, is that this approach is much more verbose.

Personally, I see little point in final fields since I have hardly ever encountered a bug that was due to accidentally reassigning a field, so I tend to use field injection whenever I can.

Taking it to the next level

Obviously, the kind of configuration object I used as an example if not very realistic. Typically, a configuration will not hardcode values like I did and will, instead, read them from some external source. Similarly, you will want to inject objects that can’t necessarily be instantiated so early in the lifecycle of your application, such as servlet contexts, database connections, or implementations of your own interfaces.

This topic itself would probably cover several chapters of a book dedicated to dependency injection, so I’ll just summarize it: not all objects can be injected this way, and one benefit of using a dependency injection framework in your code is that it will force you to think about what life cycle category your objects belong to. Having said that, if you want to find out how Guice can inject objects that get created at a later time in your application life cycle, look up the Javadoc for the Provider class.

Wrapping up

I hope this quick introduction to dependency injection piqued your interest and that you will consider using it in your project since it has so much more to offer than what I described in this post. If you want to learn more, I suggest starting with the excellent Guice documentation.

Read post...

March 10, 2012

Cedric Beust

Video game update

I haven’t talked about video games in a while, so I thought I’d put together a short summary of what I played this past year, in no particular order.

The original Deus Ex is considered to be one of the best PC games of all times (along with another one mentioned below), so developing a sequel more than ten years later is quite a tall order. From what I can see, DXHR manages to pull it off. I played about one third through the game and then put it away with the firm intention to go back to it (a pattern that seems to be recurring in my gaming habits).

I don’t think Portal needs any introduction, and nobody actually expected a sequel to the best PC game of all times (according to PC Gamer) to be able to measure up. This is why Portal 2 was such a delightful surprise to me, and in hindsight, I think it’s better than the first episode in all respects. On top of inventing new creative puzzles, Valve managed to actually imagine a very poignant and appealing story that I absolutely fell in love with. I replayed the game three times and I suspect that I will do so again on a regular basis in the years to come. The characters, their acting and voices are also incredibly well done and downright funny despite the tense scenario, and I don’t think anyone will be able to forget the Stephen Merchant / Ellen Mc Lain duo for a long time.

I have always been a Civilization fan, going back to the very first installment of the series and its insanely punishing difficulty. Civilization V doesn’t betray the series and streamline a lot of the rough edges that players complained about in the previous version. List most Civilization, I have the feeling I barely scratched the surface of this one and I’m looking forward to going back to explore it further. In my book, however, Civilization IV remains the best of the entire series.

Referring to this little gem as “Minecraft in 2D” is not doing it justice. It shares some crafting and discovery ideas with Minecraft, but the resemblance stops there. In this 2D platformer, you craft to create stronger weapons and armors so you can explore further away from your base. That’s about the extent that I know of it, I only spent an hour or so on it but I definitely want to see how far that rabbit hole goes. The developers recently announced that they were moving on, but there is already enough material in the current release to keep someone playing for a long, long time (some fans have clocked more than 100 hours on this game).

While I did buy Oblivion on the day it came out, I felt that I never really explored all that it had to give because I was extremely turned off by the clunky, obviously console targetted, UI. While I think that Skyrim is one of the best games I’ve played these past years, I’m sad to report that it suffers from the exact problem as Oblivion. However, the UI is not irreparably damaged that it makes playing it on a PC impossible, so after some tweaking, I was able to play the game in a reasonably satisfying manner. In one sentence, Skyrim is what World of Warcraft would be if it weren’t a multiplayer game.

I spent about thirty hours on it and reached level 20 while barely touching the main quest line (and I had a tremendous amount of fun doing so). And then my excitement and interest waned. Again, I really want to go back to it, if only to finish the main quest and visit some of the gorgeous locations I’ve heard of, such as Black Reach, so I really hope I’ll find enough resolve and time to do so.

Rift recently became free to play, so why not try it? I did but after an hour spent in the beginner zone, I can’t say I felt compelled to push further. Admittedly, this is no way to assess a MMO game, so I’m aware I might be missing out.

Another attempt at reusing some of World of Warcraft’s successful recipe without the MMO component. The main difference is that the fights are much more action oriented (this game also runs on consoles, after all), so you will find yourself sidestepping, dodging, rolling and also swinging, parrying and triggering various special combinations during your fights. The story line seems to be fairly expansive with a lot of content to go through. I have only spent five hours on this game and it feels like I have barely scratched its surface.

No, I didn’t get the screen shot wrong. I really mean the original X-Com game, released in 1993. I mentioned in the introduction that I would talk about another game ranked among the best of all times, and this is it.

I never really played the original when it came out but given the non stop rants and articles I have read about it during these past two decades, I have always wanted to give it a fair shot. What eventually motivated me was learning that Firaxis was going to create a sequel for it. There have been several sequels to the game but the one that the Firaxis (of Civilization fame) is working on is pretty much guaranteed to be true to the original. Here is one of the two interviews they gave on the subject. These guys mean business.

Back to the original game: it’s very simple to install and play on any OS (thanks to DOSBox) and while I expected some frustration from the punishing user interface, I ended up finding my way through it fairly easily. I only played a few hours and I managed to down my first UFO, so I can’t say that I have experienced what everyone has been raving about, but I think I now have a better idea. I’m hoping I’ll be able to push through a bit further before Firaxis’ version of the game comes out.

Yes, that Ultima 6. Inspired by the riveting reports of the “CRPG Addict” blog, I decided I wanted to replay an Ultima. Since he had just reviewed Ultima 5 and I still felt that Ultima 7 was fresh in my mind (I played it a couple of years ago), I decided to go for Ultima 6. I wasn’t holding much hope, but it didn’t take long for Lord British’s creation of 1990 to completely suck me in again. Next thing I know, I was taking tons of notes and slowly unraveling the mystery of the False Prophet. It was a blast from start to finish, but unfortunately, I didn’t keep track of how many hours I spent on it. I did save all my notes for posterity (the annotated map might come in handy and it doesn’t contain any major spoilers).

Maybe I’ll carry on with Ultima 7, which has several flavors available (I’ve only ever played the first one, so I have at least three to discover before moving on to Ultima 8, which I don’t have fond memories of).

Don’t try, you have probably never heard of this game. It was released in 1984 on the Apple ][ and even back then, it was a pretty obscure game. Yet, I remember vividly spending hours and hours on it during high school until I finally managed to beat it. For some reason, I thought about this game again recently and I decided to see how well it lived up to my memory.

Like most of the games that came out at the time, it’s pretty hard to describe and bizarre in its own way, but that’s also what makes it very interesting. You are controlling a ship in across a maze made of sixty-four rooms and your goal is to explore all of them. Part of the fun of the game is to uncover its mechanisms and how to unlock doors. Once you have solved the game, you can complete it in less than twenty minutes but to get there, you should expect to spend at most a couple of hours to unravel its mysteries. I have to say I enjoyed playing it this time around and I certainly wish we saw more of these creative and innovative games today.

I actually wrote an extensive review of this absolutely wonderful adventure game last year, so I’ll just refer you there if you are curious. Even if you’re not that much into adventure games, I strongly recommend giving this game a shot, it’s perfect in pretty much all respects and it sits up there with the likes of “Monkey Island”, “Indiana Jones and the Fate of Atlantis” and “Zak Mc Kracken and the Alien Mindbenders”.

Speaking of classics, I spent some time rediscovering the Monkey Island series and I play them whenever there is a bit of a lull in my video games activities. The Monkey Island Special Editions are fantastic, they talk about pirates, they are funny and the entire series is considered the best adventure game saga of all times. What’s not to like?

An indie game that took everyone by surprise last year. The soundtrack is beautiful and it’s hard not to start paying attention to the story as it slowly unfolds through the wonderful Chandler-like narration. Bastion also sits in a niche of its own in terms of game play, with the land assembling ahead of you as you make progress through the levels. It offers various weapons (melee, range and special ability) which can be boosted by elixirs (buffs) and other customizations that you can gain either through the game or by performing well on challenge levels (such as knocking out all the enemies with only fifteen shots of your scrap musket). I must be about one third through the game and while I’m starting to feel a little bit of repetition, I really want to reach the conclusion of this game to find out where it’s taking me.

“You can check out any time you want, but you can never leave”. This probably sums up my relationship with World of Warcraft since 2004. At least, I feel I made a major advance two years ago when I stopped raiding, and at that point, I thought I was pretty much done. Well, it turns out that the devils living in Blizzard’s halls know a thing or two on the multiple ways in which they can hook you to a game, and they certainly managed to pull that trick on me since I became a casual player.

The good news is that I’m no longer spending as many hours as I used to in Azeroth and also that my interest goes in bursts. The latest example is deciding to level a new character and take it to the very end of the game: killing Deathwing. I was curious to find out how long it would take, and while I thought most of it would be a grind, I actually enjoyed goign through the entire journey, probably since it was a good opportunity to find out exactly what changes had been made to the early areas of Cataclysm, but also because the new “Looking for Group” mechanism makes leveling very fast. You basically queue all the time and you then have the choice to either quest or accept the dungeon invitation.

As soon as I met the level 85 gear requirements to queue for the new “Looking for Raid” interface, I did so and one hour later, I had killed Deathwing. It took me about five days played (emphasis on “played”: that’s more than one hundred hours of game time and two-three months of real time) to take my character from level one to end game. And once I was done with this task, I… well, felt absolutely no urge to launch the game again. I’m probably done until the next expansion, the Mists of Pandaria, comes out, at which point I will probably fall for it again.

Conclusion

So this is my video game history of this past year. If there is one thing I’m taking away, it’s that I’m finding it increasingly hard to be interested in a game for extended periods of time, World of Warcraft being the striking and sole exception. I seem to hit a ceiling at twenty or thirty hours, and most of the games I play don’t even make it that far. This year, I’m looking forward to playing Mass Effect 3, Diablo 3 and maybe give Guild Wars 2 a try. Hopefully, I’ll come across a few other interesting games that are not sequels of well established franchises, something that seems all but impossible outside the Windows gaming arena.

Read post...

March 02, 2012

Cedric Beust

Solution to the “Power story” challenge

Here is the solution to the “Power story” non coding challenge:

When the power went out, Ann open the wireless settings of her laptop, scanned the area but couldn’t find a single wireless access point in the neighborhood.

This is actually based on a true story (mine, yesterday). I can usually see a dozen access points at any time, but they were all gone after the power went out yesterday, which gave me the idea for this challenge.

We had a few good answers, some that came close and a few more that answered without reading the problem carefully :-) .

I have approved all the moderated comments on the original challenge.

Read post...

Cedric Beust

Non coding challenge: a power story

Since the next coding challenge will be a bit brutal, I thought we all earned a little break so here is a short non coding challenge. I’m pretty sure you won’t find the answer on the net since I just made it up…

Ann was enjoying this Sunday morning in her San Francisco apartment by sipping a nice cup of coffee and browsing the web on her laptop and her home wifi connection when the entire apartment went dark. Her husband entered the room:

“I might have tripped a fuse with my computer, I’ll go check the breaker box.”

“Don’t bother, it’s a general outage, the neighbors lost power too.”

“Oh? How do you know? Did you talk to them?”

“No.”

“Did you make a phone call or receive one?”

“No.”

“Did you talk to anyone?”

“Only you.”

“Did you see something outside that tipped you off?”

“No.”

How did Ann know that the outage was general and not just their apartment?

Update 1: I will hold the comments in the moderation queue for a little while to avoid spoilers, but I’ll publish them all shortly.

Update 2: I posted the solution.

Read post...

February 20, 2012

Cedric Beust

Various ways to get randomness wrong


xkcd’s random generator

Here is the wrap up of the coding challenge I proposed a few days ago, and which gathered some interesting feedback, both in the comments and also on reddit.

Randomness

First of all, as many commenters pointed out, you can’t really test for randomness, so we’ll have to settle for a looser criterion, such as even distribution. Randomness usually implies even distribution but not the other way around. On the face of it, even distribution can seem like a very weak assertion (for example, the series “[1,2,3],[2,3,1],[3,1,2],[1,2,3],…” is evenly distributed but obviously not random) but if you can ascertain it with a data set that was generated from a fair random source, then you can probably make a good claim that your algorithm is reasonably unbiased.

Shuffling

Let’s get the first question out of the way. The Fisher-Yates shuffle is very simple to explain: start from the end and swap the element at that index with a random one. Then take the next to last and swap it with a random element between 0 and i -1. Here is the (simplified) Java library version, Collections.shuffle():

public static void shuffle(List<?> list, Random rnd) {
    int size = list.size();
    for (int i=size; i>1; i--)
        swap(list, i-1, rnd.nextInt(i));
    }
}


Note: this is actually not the Fisher-Yates algorithm, which runs in O(n^2) but an improved version, which runs in linear time. For some reason, most people still call it the Fisher-Yates algorithm, probably because of its resemblance to it.

Before I can show in how many ways you can actually get this wrong, we need to find out how can measure the distribution of these results, which was the heart of the second question.

Simple distribution measurements

Again, there are many ways to go about this and all of them have various compromises in time and space (mostly in space, actually). One of the most intuitive ways of reasoning about this is to maintain a matrix where each element [i,j] records how many times the digit i appeared at index j. If we call N the size of the array (for example 5) and RUNS the number of times we will invoke our function to get a representative sample (for example one million), we will generate one million arrays, so five million numbers. Since the matrix is NxN = 25, we would expect each element of the matrix to be approximately 5,000,000 / 25 = 200,000.

I will be using this approach in the rest of this article, but for the sake of completeness, let’s spend a short time considering other options.

You might be thinking that such a matrix doesn’t contain enough information. For example, while it will tell you that “2″ appeared 201,000 times in position “3″, it doesn’t tell you if there was any pattern to these appearances or whether these appearances were coupled with other numbers in the array. Whatever additional data you want to measure, you will probably end up having to extend your matrix with either constant space or maybe N (e.g. turn it into a 3D matrix).

Another thought might be that instead of counting the occurrences of these numbers, we could calculate the average of the number that each index has contained. And if you have some education in statistics, you know that once you start getting into the idea of computing averages, you can’t avoid looking at standard deviations as well.

Here is what we get for an evenly distributed algorithm:

Averages:[1.9988, 1.9992, 2.0023, 2.0011, 1.9983]
Stdev:   [1.4131, 1.4145, 1.4145, 1.4147, 1.4140]

The average is 2 since the elements range from 0 to 4 inclusive. The standard deviation is the square root of 2, which means that the numbers are evenly distributed around the average within a distance of 2.

Here are the results for the identity function, which doesn’t distribute at all:

Averages:[0.0, 1.0, 2.0, 3.0, 4.0]
Stdev:   [2.0, 1.0, 0.0, 1.0, 2.0]

Unsurprisingly, the average of numbers appearing in position 0 is 0 and 4 for the position 4. The elements in position 0 and 4 are 2 away from the average, etc…

So we can get some approximate information about how evenly distributed our function is with a simple average and standard deviation, but if we want to dig further, we need to go back to our count matrix.

The count matrix

Here is how the identity function spreads on the count matrix:

 1000000      0      0      0      0
      0 1000000      0      0      0
      0      0 1000000      0      0
      0      0      0 1000000      0
      0      0      0      0 1000000

And here is a typical run for Collections.shuffle():

2000455 2000514 2000895 1998349 1999787
2001463 1999130 1999621 1999253 2000533
1997862 2000217 2001450 2000810 1999661
1999117 1999870 1998689 2000809 2001515
2001103 2000269 1999345 2000779 1998504

This looks good but it’s a bit difficult to read, so instead, let’s count how many of these numbers differ from the expected value by, say, 1%:

for (int i = 0; i < N; i++) {
  for (int j = 0; j < N; j++) {
    float delta = Math.abs((RUNS / N) - mat[i][j]);
    float percent = delta * 100f / N / RUNS;
    if (percent > 0.01f) {
      failures++;
    }
  }
}

The outcome:

Failures: 0/25

We would expect the number of failures to increase as we reduce the number of runs:

Runs: 10000000, failures: 0/25
Runs: 1000000, failures: 0/25
Runs: 100000, failures: 15/25
Runs: 10000, failures: 24/25
Runs: 1000, failures: 24/25

Doing it wrong

Alright, so Collections.shuffle() seems to score well on this scale. Now let’s turn our attention to the many ways you can get this algorithm wrong. Let’s make a copy of it:

for (int i = N; i > 1; i--) {
  Collections.swap(result, i-1, rnd.nextInt(N));
}

Let’s reset RUNS to one million and try again:

Runs: 1000000, failures: 17/25

Oops. Running it again and again yields similar results. What happened?

Okay, I’ll admit it, I introduced a bug when copying the code, can you spot it?

  Collections.swap(result, i-1, rnd.nextInt(N));  // incorrect
  Collections.swap(result, i-1, rnd.nextInt(i));  // correct

It looks like selecting the random index to swap among the entire array totally wrecks the distribution, while selecting it from only these elements we haven’t reached in our loop makes everything right. I’ll leave the interpretation of this behavior as an exercise to the reader.

Here is another way to get this wrong.

When you look at the fundamentals of the algorithm, you may wonder if you really need to go through the entire array to perform the swaps. After all, once you reach the half point of the array, it’s very likely that the second half of the array has been swapped randomly already, so why not stop there? Well, let’s try (I am also increasing the size of the array to 10):

Runs: 1000000, failures: 25/100

Again, it looks like we messed up the algorithm. Let’s take a look at the distribution matrix:

    for (int i = N; i > N / 2; i--) {
      Collections.swap(result, i-1, rnd.nextInt(i));
    }
 499916      0      0      0      0  99893 100776  99757  99744  99914
      0 499489      0      0      0 100013 100040 100580  99643 100235
      0      0 499929      0      0  99719  99753 100135 100363 100101
      0      0      0 500268      0  99903 100346  99934 100079  99470
      0      0      0      0 500255  99669  99766 100426 100040  99844
 100364 100323  99846  99878  99909 100102  99518  99608  99934 100518
 100392  99868  99843 100204  99662 100333  99544  99582 100313 100259
  99946 100439 100138  99926 100406  99785 100144  99898  99773  99545
  99906  99622  99748 100211  99641 100624 100149 100188 100003  99908
  99476 100259 100496  99513 100127  99959  99964  99892 100108 100206

Our modified algorithm has introduced a strong bias in the first half of the array (the one we decided wasn’t worth selecting on): number 0 has a 50% chance of being found in position 0, same for 1-4. From 5 to 9, the probability drops to the expected 10% odds.

Let’s see what happens if we go a bit further than the half point, say 3/4 of the array:

    for (int i = N; i > N / 4; i--) {
      Collections.swap(result, i-1, rnd.nextInt(i));
    }
 199836      0 100150 100374 100292 100139  99861  99665  99861  99822
      0 200711 100183  99753 100317  99945  99761  99403  99879 100048
 100283  99860  99936  99915  99693 100480  99786 100128  99848 100071
 100057  99592 100152  99785 100017  99507  99550 100557 100564 100219
  99933 100225  99808 100193  99844 100017 100212  99573 100462  99733
  99776  99789  99895  99753  99953  99973 100124 100873  99518 100346
  99921 100068 100020 100316  99589  99728 100461 100206  99900  99791
 100169  99896  99941  99880  99922 100094 100168  99947  99754 100229
 100217  99964  99812 100066 100413 100209  99975  99593 100216  99535
  99808  99895 100103  99965  99960  99908 100102 100055  99998 100206
Runs: 1000000, failures: 4/100

Here is another way to mess it up. Let’s restore our loop to swap the entire array:

    for (int i = N; i > 1; i--) {
      Collections.swap(result, i-1, new Random().nextInt(i));
    }

Let’s run it:

 137244  44545  91552  87602 100969 122467 100299 125866 101490  87966
  71720 138821  92466 107337 103311 123042  99610  73350 103791  86552
 129376 113794 114303  98828 102760  55589 100312 102734  95621  86683
  71216 112960 111268 115538 102947  99968 100271  98012 100026  87794
  94519  94294  94709  94851  93888 103046  99956 100257 101460 123020
  95533  96387  95852  96858  96351  96101  99570  99488  96360 127500
  99901  99926  99890  99421  99929 100409  99989  99744 100489 100302
 100233  99852  99969  99940  99872  99922 100016 100154 100071  99971
  99725  99387  99817  99841 100002  99500 100061 100811 100863  99993
 100533 100034 100174  99784  99971  99956  99916  99584  99829 100219
Runs: 1000000, failures: 49/100

Wow, that’s another massive failure. What did I do wrong this time?

    private Random rnd = new Random();

// ...

    Collections.swap(result, i-1, rnd.nextInt(i));  // correct
    Collections.swap(result, i-1, new Random().nextInt(i)); // incorrect

Why would creating a new Random object trigger such a bug while reusing the same Random object through our loops provides a good distribution?

If you ever deal with random generation in Java (and probably other languages), you absolutely need to be aware of the way java.lang.Random is implemented. The problem here is that new objects are seeded with the current time, so creating objects within a loop pretty much guarantees that these objects will be created within a timeframe that’s smaller than the clock granularity, which means that a lof ot the random numbers generated in succession will be identical. You address this either by reusing the same Random object (consider warming it up, too) or, better, by using java.util.Math#random (or even better: java.security.SecureRandom).

I’ll show one more common mistake, which might actually not always be one:

    for (int i = N; i > 1; i--) {
      Collections.swap(result, i-1, rnd.nextInt(i - 1));  // was i
    }

The difference here is that the random index is picked between 0 and i-1, instead of between 0 and i. Here is the distribution:

      0 249684 250515 249406 250395
 250334      0 249828 249915 249923
 249569 249612      0 250188 250631
 249973 250505 250471      0 249051
 250124 250199 249186 250491      0
Runs: 1000000, failures: 25/25

We observe that no number i can ever be found in position i, which, while totally failing our even distribution test, possesses a few interesting qualities. This approach is actually known as the Sattolo algorithm, and it’s actually useful because it always generates cycles (look it up in a section of its own in the Fisher-Yates entry on Wikipedia).

This is getting much longer than I anticipated, so I’ll just leave you with a final thought in the form of a simple problem, which touches on a question that Lawrence Kesteloot mentioned on in his comment on the original entry: I’m giving you an unbiased random source that returns either 0 or 1 and I want you to use it to generate a random list of the letters ‘a’, ‘b’, ‘c’, ‘d’ and ‘e’. And then, extend the idea to shuffle a deck of 52 cards.

Update: discussion on reddit

Read post...

February 16, 2012

Cedric Beust

A new coding challenge

It’s been a while since I proposed a coding challenge, so I’ve been thinking about another one. Coming up with original problems that are not solved with a simple Google search is not easy, but I think this new one, while not especially hard, should produce some interesting and creative results.

This problem comes in two parts. The first part is more of a warm up since it’s very easy to look up, but the follow up question will, hopefully, be the source of innovative answers.

Here it is:

1) Write a function which, passed an int n, returns an array of size n containing all the numbers between 0 and n-1 in random order. For example, with n=5, valid answers are [0, 2, 3, 1, 4], [4, 1, 2, 0, 3], etc…

2) Prove that the function you wrote in 1) returns “really random” arrays.

I’m being intentionally vague on how to answer the second question in order not to lead the answers, but hopefully, the question is specific enough that no further clarifications is needed. Feel free to ask in the comments otherwise.

All languages welcome, and I suggest you use pastebin to submit your code.

Read post...

February 09, 2012

Cedric Beust

The only sure way to lose is not to play

Google’s recent letter to the IEEE about their position on the current lawsuits between Motorola Mobility and Apple seems to spark some outrage across the mobile land. And I’m puzzled.

First of all, I don’t think any specific company is innocent in this dance, starting with Apple themselves. In their letter to the ETSI, Apple stated (quoted):

Apple’s letter then moves on to propose a solution based on three specific principles: appropriate royalty rate; common royalty base; no injunction.

That’s a nice thought, but it’s making quick work of Apple’s recent attempts at obtaining various injunctions against its rivals in the recent past, most notably Samsung.

So what’s going on, here, now that the injunction course of action didn’t work for them, Apple thinks injunctions should be disallowed for everyone?

This whole patent war is ugly. Ugly, ugly, ugly. When Apple fired the first shot against Samsung in April 2011, the entire community seemed to be in wide agreement that this was a crazy move, one that could only lead to the mutually assured destructions of all the parties involved. Obviously, Apple had weighed these risks and they came to the conclusion that either they could afford the collateral or that this collateral would be very small anyway, since they thought that innovation was on their side.

As the events since April have shown, things are obviously not so clear cut and innovation seems to be spread quite evenly among all the parties involved. The result of Apple’s opening salvo has been a flurry of suits and counter suits which, frankly, have led nowhere. All the companies involved are poorer than before, their patent attorneys are much richer and the whole field is an intellectual property war zone.

In the letter mentioned above, Google is simply stating that they won’t change anything to the legal actions that Motorola Mobility had underway before Google acquired them. That’s it.

It makes as much sense getting upset about this as it is to be outraged at someone because they play chess viciously.

Now that the war is full on, I can’t find anything wrong with all the players trying to fight as much as they can and let the courts decide who’s right and who’s wrong. The only stupid move in this conflict would be not to play.

Read post...

February 04, 2012

Arnaud Le Hors

LibreOffice should declare victory and rejoin OpenOffice

When OpenOffice went to the Apache Software Foundation I started writing a post about this topic that I never got to finish and publish.

The post from my colleague Rob Weir on Ending the Symphony Fork prompted me to post this now though.

I should say that I no longer have anything to do with what IBM does with ODF and anything related. I’ve changed position within IBM in the Fall of 2010 and now focuses on other things such as Linked Data which I may talk about in some other post.

In fact, I’m now so out of touch with the folks involved with ODF that I only learned about OpenOffice going to the Apache Software Foundation when the news hit the wire. I had no knowledge of what was going on and have no insights as to what led to it. Similarly, I only learned after the fact about IBM deciding to merge Symphony with OpenOffice.

So, if anyone wants to blame me for speaking as a person on IBM payroll, I’m not even going to bother responding. This is entirely my personal opinion and I’ve not even talked about it to anyone within IBM.

But let me say quite bluntly what Rob is only hinting at: It’s time for LibreOffice to rejoin OpenOffice.

LibreOffice started from a sizable portion of the OpenOffice.org community being tired of Oracle’s control and apparent lack of interest in making it a more open community. I certainly understand that. But now that this problem is solved, what does anyone have to gain from keeping the fork alive?? Seriously.

While forks in the open source world can be a tremendous way of shaking things up, they can also be very damaging. In this case, I think it’s a waste of resources and energy to keep this going. Instead of competing with each other the LibreOffice and OpenOffice communities should get together to fight their common and real competitor.

I know a certain level of competition can be healthy but I’m tired of seeing open source communities fight with each other to their own loss.

I know the fork was painful and people still hold a lot of angst against one another but they need to get over that. They need to realize they would do themselves and everyone else a real service by putting all this behind them and uniting. LibreOffice should declare victory and join forces!


Read post...

January 26, 2012

Coralie Mercier

Opendirectoryd crashes

I was unlucky enough two months ago to start to experience loss of my (computer) identity, occasionally at wake froms sleep. My computer terminal would show "I have no name!" in the prompt instead of my user name, would claim that I am 501, when it should say I'm koalie. Of course, ssh would not want me, telling me to go away as I don't exist. So I rebooted a couple time and grumbled a lot.

Vlad suggested something was wrong with LDAP and my colleague Thomas diagnosed that opendirectoryd was crashing. All true.

It happened again tonight and Vlad found a way to restart opendirectoryd (in Terminal.app):
sudo launchctl
stop com.apple.opendirectoryd

Which restarts opendirectoryd.

I'm none the wiser on what triggers the opendirectoryd crash at wake from sleep. But I'm glad this works when the crash happens.

Update: The above doesn't always work. Actually, it may have worked just once. Since then, I've experienced silent opendirectoryd crash, and no sudo worked, neither some kill -9. Only a restart can fix it.
Read post...

January 02, 2012

Cedric Beust

Ushering TestNG into the new year

I took advantage of the holiday break to completely revamp TestNG’s HTML reports, something I’ve been meaning to do for a very long time but never found the time to put at the top of my TODO list. I wrote the original reports pretty much with the very first version of TestNG, around 2004, and I hardly touched them since then. My intention with this rewrite was not just to revamp them visually but also technically, so that I could give myself as much freedom as possible to improve them from this point on.

Here are some notes I took during this process.

Content and appearance

First of all, here are the new reports. They show all the suites on the same page with a banner at the top, a navigator pane on the left hand side (which always stays visible) and a main panel on the right hand side, which shows all the information you requested depending on which item you clicked in the navigator. Pretty straightforward.

If you take a look at the source, you will see that it hardly contains any HTML: it’s mostly made of <div> and <span>. I didn’t really set out to do this initially, it’s just that whenever I used HTML elements, I inherited undesirable CSS attributes (margins, paddings, etc…) which I ended up resetting manually, so after a while, it just seemed much easier to use divs and spans knowing that they start with a clean CSS slate.

Since there is so much generated text, I pondered using a templating library to make my life easier. The first question to settle was: client side or server side templates? In this case, there is not really a “server” side, so the question is more “Java” or “Javascript” templates. I quickly rejected the client side approach which, while well adapted to serve pages over a network, doesn’t seem to have much benefit in this particular case since the page is generated locally. As for the Java side, the two standard options for templates (Freemarker and Velocity) seemed quite overkill for what I was trying to do, so I ended up writing my own tiny implementation of mustache.js (which I’ve used in the past and liked quite a bit)..

Once I had the templating code working, I started converting the Java code over to it but… something felt wrong. I quickly gained the impression that this was actually a step backward compared to doing the generation 100% from Java, and the reason quickly became apparent to me: the Java compiler.

The problem with using templates is that you get very little help from the tools. Some template libraries allow you to include other templates, which can reduce the repetition, but it’s still very easy to make simple typos or being forced to copy/paste a lot. In contrast, my Java hierarchies makes it quite trivial to, say, add a new panel on the right hand side with a link to the left. Implement the right class, declare it and it will automatically work, with the right defaults (CSS selectors) and a lot of the logic validated by the compiler.

This comfort was too good to pass up so I scrapped my template idea (my mustache.js implementation is still around, though, and I might use it some time in the future) and I stuck to 100% Java generation.

Javascript and development tools

Picking jQuery was a no-brainer, it’s hard for me to imagine doing anything in Javascript that manipulates the DOM without using JQuery. The logic in the new reports is fairly simple and is just above one hundred lines of Javascript.

Chrome’s development environment is also quite superb (I’m sure other browsers’ is just as good). In a nutshell, you have access to pretty much the same range of support that Eclipse or IDEA provides in Java: breakpoints, inspection and modification of variables, and even CSS debugging, which I’ve found invaluable to track down unexpected CSS behaviors (I came across quite a few).

If you haven’t kept up with what you can do with Chrome/Javascript/JQuery these days, try the following:

  • Open http://testng.org/new in Chrome.
  • Right click anywhere on the page and select "Inspect element". This will open the document explorer at the bottom.
  • With the focus in the document explorer, type ESC, which will open the REPL.
  • Type $('.navigator-suite-content').hide().
  • This will collapse the content under both suites.

You can see how easy it is to debug this kind of code.

Other libraries

If you select the "Times" link of the first test suite in the Navigator pane, you will see the following table:




Click to enlarge

I am using Google’s Chart Tools to display this table and it was quite straightforward to add. The only tricky part was how to generate the data in Javascript form and make sure that the table gets drawn only after this data has been initialized, which required using a few Javascript tricks to make sure the initialization order is correct. The Google Chart Tools are very powerful and I will probably use more of their API to display additional graphs in the TestNG reports (pie charts, etc…).

Conclusions

Here are my main take away points:

  • CSS still feels like black magic to me. The theory is trivial on paper but in reality, I often come across results that just don’t make sense. With the help of modern CSS debuggers, it’s a little bit easier to find out what is happening and why (I especially like Chrome’s “Computed style” which gives you a list of all the attributes that were derived from .css files), but there are still times where I feel completely helpless trying to find out why something is not how it should be.
  • I’m a bit concerned with the size of the reports: I was quite surprised to find out that the reports you’re looking at is one meg in size. Admittedly, it shows over five hundred test methods, but the fact that it contains all the panels, even those the user might not be interested in, is a potential place for improvement. I might decide to put each individual pane in its own file.
  • Javascript’s rubbery type system is handy for this kind of task, but I’m still a bit unsure how well it scales to hundreds of thousands of lines of code. For example, I really enjoy being able to say if (v) regardless of what type v is and have Javascript’s truthiness values do the right thing. Similarly, it’s nice to be able to add a parameter to a function and not having to update one single call site (if you call a Javascript method with less parameters than it expects, the extra parameters simply receive the Undefined value. Obviously you need to test for this in said function).
  • JQuery is great and it’s probably making Javascript even more popular than it already is. I’m hoping the Dart team is taking notes and making sure that a similarly powerful and elegant framework will be available in Dart.

Finally, a call for help: I welcome any feedback on how to improve the CSS of these new reports, so if you are so inclined, feel free to improve the look of these new reports and share your improvements with me. I will be very grateful.

Happy new year!

Read post...

December 16, 2011

Coralie Mercier

lorem ipsum

"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..."
"There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain..."


Read post...

December 13, 2011

Cedric Beust

Ground control to major Tom


This could be you!

Who hasn’t dreamed of becoming an astronaut? Well, now you can. The NASA has an open position for an “Astronaut Candidate” for the International Space Station in Houston, TX. The requirements are pretty interesting.

The training will take two to three years and will require a lot of traveling, probably mostly to Russia, since they will be using Soyuz to travel to and from the ISS. The required education is fairly broad, and more interestingly, the list of degrees that are not applicable is fairly short (technology, psychology, nursing(!), etc…). It looks like a CS degree is good enough, and you can make up for the lack of flying experience with an MS or better, a PhD.

“Correctable” 20/20 eyesight is required, which means that contact lenses and Lasik are accepted (I wonder how hard it is to put contact lenses on in zero gravity…). The ad also takes the time to explain each jargon occurrence: “Extravehicular Activities (space walks)”, “the extravehicular activity mobility unit (space suit)”.

Although the ad will only be open for the next couple of months, the selection process takes a while since the selection will be announced in the spring of 2013.

I was fortunate to be able to experience a Zero-G flight a few years ago, I can’t say I’m not tempted to apply :-)

Read post...

December 11, 2011

Cedric Beust

Table of contents in Javascript

This is my week end project: a table of contents generator. Well, technically, it’s more like a two hour project interrupted four times over the course of a Saturday but I guess it still qualifies as a week end project.

I got tired of managing the table of contents of my documentations manually and in particular, of having to modify all the section numbers by hand whenever I moved things around. This short Javascript program now automatically takes care of it for me. Here is the quick documentation:

// A simple HTML "table of contents" generator.
//
// 1) Include toc.js in your HTML file:
//          <script type="text/javascript" src="http://planet.koalateam.com/koalas/output//toc.js"></script>
//
// 2) Call generateToc() in your onLoad() method:
//           <body onLoad="generateToc();">
//
// 3) Declare a div with the id "table-of-contents" where you want
// your table of contents:
//           <div id="table-of-contents"></div>
//
// 4) Put each of your sections in an <a> tag with class "section",
// specifying an "indent" representing the indentation of that section.
// Only the length of the indent matters, now its content. If no indent
// is found, a string of size 1 is the default.
//
// Example:
// <a class="section" name="Section 1">Section 1</a>
// <a class="section" indent=".." name="Section 1a">Section 1a</a>
// <a class="section" name="Section 2">Section 2</a>

This script now powers both testng.org and jcommander.org, go take a look there if you want to see what it looks like.

Ideas for potential improvements:

  • Make the numbering optional or configurable.
  • Have the script add CSS classes to the sections for easier styling (“section1″, “section2″, etc…), since the indenting is pretty crude right now.
Read post...

Aggregation of Blogs:
Feeds for this planet:

Open

 
Koalateam / KoalaPlanet

Navigate: Changes -  Index -  Map -  Search -  Print version -  RSS Feed
Advanced: Backlinks -  Children -  Raw View -  Email changes -  History
Admin: Admin -  Statistics -  Preferences -  Notifications -  Your Account
Edit: Edit -  Raw edit -  Attach -  Create New Topic -  More topic actions
Home.KoalaPlanet
Topic revision: r33 - 2009-02-05 - 22:29:17 - ColasNahaboo
Powered by This site is powered by the TWiki collaboration platformTWiki - Comments & feedback