Developer Corner & API

 

Today we started with the local.ch developer network. That’s a space where we want to provide stuff for developers. As a starting point, there is a small API to get a list of Swiss cities. That’s ideal for auto completion of cities (like we do on our search form) and I will demonstrate a usage tomorrow at the Tweakfest in Zürich (in the Technopark). The examples will then follow online as well.

More will of course follow. For now visit developer.local.ch.

 
 

Help for stressed parents in search of a Kinderkrippe

 

As father of two small children, the last four years since the birth of our first has left us struggling to find information we never knew we needed. Just one of the “joys” of parenting, as anyone in our position knows, is finding a Kinderkrippe, especially in Zürich, where there’s endless demand.

The fun begins with finding suitable locations… on the way to work? Which bus or tram line? And when do they have an Open Day to visit? Thursday at 10am?!? Riiiiight. Then add your children to the waiting list. And wait. And call. And wait and so on. Of course much of this has to be packed into the peaceful 60 minutes after lunch, when the little darlings aren’t trying to crawl up your leg or eat the telephone.

Anyway, at least for the first step in this ritual, local.ch can make things a little easier. As Cédric already mentioned, we now have “near search” feature. When you find something you are searching for, you can search for something else in it’s vicinity.

Here’s how I could use it to help find potential locations of Kinderkrippen…

The first thing is to find the location that I want the Kinderkrippe to be near to, such as where I work at local.ch. So I head over to tel.local.ch and search for What: “local.ch” and Where: “Zürich”…

finding a starting point

Now I can see “local.ch ag” as the first result on the list, so I click on it’s title to go to it’s “detail view”, so that only the result for local.ch is displayed.

Next I click on “Search in Area”, on the left of the result, and enter What “kinderkrippe”, at a distance of “1″ km and click the “Search” button. Below the result for local.ch I can now see all the Kinderkrippen within a 1km radius of local.ch…

Kinderkrippen near local.ch

Moving the mouse of the names of each Krippe, a point appears on the map, showing me where it is. Meanwhile, at the bottom left of the map, there’s a link “Show map points selection” – clicking on it allows me to add “Public Transport” points, such as bus stops, to the map, helping me figure out which Krippe best suits my journey to work in the morning (and taking children to the Krippe during rush hour is another little “joy”)…

Adding the bus stops

Sadly this wasn’t around when we were searching for Krippen but, hopefully, it will make future parents a little less stressed…

 
 

Start searching on your Plazes.com location

 

Plazes.comFor once – something for Web 2.0 geeks. The Plazes site helps you to keep track where your friends are. Visit plazes.com to learn more about it.

As a lab experiment – we created a Firefox Extension that gets your current location from Plazes.com and modifies the local.ch home page to show the appropriate city page and the map zoomed to the place. Useful to directly start a search at your location.

We thought that might also interest some of our users. You can download the Firefox Extension here:

http://files.chregu.tv/whereami/whereami.xpi

local.ch integrates your location from plazes.com After installation – visit the Extension Preferences in Firefox: Tools > Add-ons > whereami > Preferences and provide your Plazes username and password. That is necessary to get your current location over the Plazes API. Once configured – visit www.local.ch – the homepage redirects to the city page and the map zooms. Of cause you need to have the Plazes client running during that time (to tell plazes.com where you are) and it’s only useful if you are in Switzerland ;-)

Many thanks to chregu from Liip for hacking the extension.

Update May 20th: Just added support to display your Plazes friends on the map. You might have to zoom-out if no friend is in close distance. Run the Add-ons “Find Updates” to update to the latest release.

 
 

Today’s changes – May 9, 2007

 

(Deutsch siehe unten)

A quick overview of the new features and changes we did this week:

  • Searching on the “All Section” now also shows results of the market and auto classifieds part
  • The search result visualization in “All Section” has been redesigned to resemble a summary. The result set adapts depending on the amount of results found. A single hit on a phone number does instantly shows the details page (try local.ch/yourphonenumber) – a hand full is shown as regular result set – if a lot result are found we show a summary based on top categories. Of course always with direct links to the full result set in the corresponding section.
  • The phone book details pages now an simple option to start a search in the area around the result. Use the “search in area” link in the left action list.
  • We added result set sorting in the classifieds and car market section – e.g. sort by price
  • The car market got a brand new Advanced Search – allowing you to query for specific car properties and subscribe to the query as RSS feed. Note: Give us some more weeks to tweak the search quality.
  • Due to unpopular demand we removed a few things – the map from homepages and the recent location drop-down on the where field.
  • And – you might have noticed – we have polished a lot of edges and introduced functional design elements to make the site generally easier to use.

Eine Übersicht an Verbesserungen und Änderungen die wir diese Woche veröffentlicht haben:

  • Suchen im “Alle Bereich” zeigen nun auch Treffer aus der Fundgrueb und Autobörse
  • Die Darstellung der Treffer im “Alle Bereich” wurde überarbeitet. Je nach Menge der Treffer wird eine andere Darstellungsart gewählt. Eindeutige Treffer auf der Telefonnummer werden direkt zum Detaileintrag weitergeleitet (einfach mal local.ch/meinetelefonnummer probieren). Bei einer Hand voll Treffer kommt die Liste – bei vielen Treffer kommt eine Zusammenfassung. Natürlich immer mit dem direkten Link zu allen Treffern im jeweiligen Bereich.
  • Auf der Telefonbuch Detailseite gibt es neu eine einfache Möglichkeit in der Umgebung des Treffers zu suchen. Einfach auf “Im Umkreis suchen” klicken – ausfüllen – radium bestimmen – und die neue Resultat werden auf der Karte zusätzliche angezeigt.
  • In der Fundgrueb und Autobörse lassen sich die Treffer sortieren – z.B. nach Preis
  • Die Autobörse biete eine neue Erweitere Suche. Damit lassen sich detailliere Suchen auf Autoeigenschaften zusammenstellen und per RSS Feed abonnieren. Beachte: Wir sind z.Z. noch dran die Suchqualität zu verbessern – mehr dazu zu einem späteren Zeitpunkt.
  • Entfernt wurden die Karten auf den Startseiten und die zuletzt besuchten Orte Auswahl beim Wo Feld.
  • Wir haben einige Design Umstellungen gemacht – um Funktionen besser zugänglich und local.ch generell einfach bedienbar zu machen.
 
 

Java: Finding Differences in Objects

 

Writing JUnitTests for code that writes data to the database has always proven to be not that easy.

Probably the most obvious way to do it is generating a bunch of test data, to write it to the database, to read the data back from db and to compare the read data to the one originally generated. This way the writers (insert/update/delete) and readers are all tested.

The problem I faced was comparing the originally created objects to the one resulting from the Data Access Objects (DAOs) reading from the db. In my case the test data wasn’t just stored in one object but instead a JavaBean containing collections of other JavaBeans, one-to-many relationship that is. That means comparing doesn’t just mean putting five equals statements into an if statement.

I came up with a helper class that lets you find the differences – recursively – of two arbitrary objects of the same class:

DifferenceFinder.getDifferences(myObject, myOtherObject)

the method returns a Map of differences:

{"addresses.name": ["differs"],
 "categories":     ["id 345 is missing in left object", "id 34 is missing in right object"]
}

you can also exclude some fields from being compared:

Collection<String> exclude = new LinkedList<String>();
exclude.add("categories.last_updated");
exclude.add("addresses.number_of_pets");
DifferenceFinder.getDifferences(myObject, myOtherObject);

comparing collections

In fact the “deep comparison” is already solved by the EqualsBuilder in the apache commons lang libraries. What their libabry doesn’t solve is the problem of comparing two collections: In order to know which objects in a collection should be compared to which objects in the other collection, it is inevitable to get an id for each object in the collection. Therefore I introduced a Diffable interface which all objects in a collection have to meet. The DifferenceFinder searches for the shortest get*Id method of the object in the collection and calls this method to get the id of the object. If you don’t like this magic you can implement the DiffablePrecise interface which urges you to add the method getDiffableId

In the end you can just use examples above and let DifferenceFinder eventually yell at you to add some implements Diffable or rather implements DiffablePrecise and you get your job done.

the code

Four java files served as differencefinder.jar or differencefinder_source jar.
DifferenceFinder depends on the apache commons lang libraries. We are using the DifferenceFinder for many tests now so the code seems stable. The code is public domain. That means do with it whatever you want.