<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>@abahgat&#039;s blog</title>
	<atom:link href="http://blog.abahgat.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.abahgat.com</link>
	<description>Thoughts and experiences about software, the web and design</description>
	<lastBuildDate>Tue, 21 May 2013 21:44:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.abahgat.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/5b5f843cae442df056658c82264adec5?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>@abahgat&#039;s blog</title>
		<link>http://blog.abahgat.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.abahgat.com/osd.xml" title="@abahgat&#039;s blog" />
	<atom:link rel='hub' href='http://blog.abahgat.com/?pushpress=hub'/>
		<item>
		<title>What Van Gogh can teach us about persistence</title>
		<link>http://blog.abahgat.com/2013/03/04/what-van-gogh-can-teach-us-about-persistence/</link>
		<comments>http://blog.abahgat.com/2013/03/04/what-van-gogh-can-teach-us-about-persistence/#comments</comments>
		<pubDate>Mon, 04 Mar 2013 13:33:43 +0000</pubDate>
		<dc:creator>Alessandro Bahgat</dc:creator>
				<category><![CDATA[people]]></category>
		<category><![CDATA[Amsterdam]]></category>
		<category><![CDATA[Art]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[Van Gogh]]></category>
		<category><![CDATA[Van Gogh museum]]></category>

		<guid isPermaLink="false">http://blog.abahgat.com/?p=1122</guid>
		<description><![CDATA[I visited the Van Gogh museum in Amsterdam recently and, to my surprise, I left the exposition having learned something that matters beyond art. According to his biography, Van Gogh began to draw as a child, and he continued to &#8230; <a href="http://blog.abahgat.com/2013/03/04/what-van-gogh-can-teach-us-about-persistence/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=1122&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/File:Starry_Night_Over_the_Rhone.jpg"><img class="aligncenter size-large wp-image-1125" alt="Starry night over the Rhône" src="http://abahgat.files.wordpress.com/2013/03/starry_night_over_the_rhone.jpg?w=584&#038;h=389" width="584" height="389" /></a><span style="font-style:inherit;line-height:1.625;">I visited the Van Gogh museum in Amsterdam recently and, to my surprise, I left the exposition having learned something that matters beyond art.</span></p>
<p><span id="more-1122"></span></p>
<p>According to his <a href="http://en.wikipedia.org/wiki/Van_Gogh">biography</a>,</p>
<blockquote><p>Van Gogh began to draw as a child, and he continued to draw throughout the years that led up to his decision to become an artist. He did not begin painting until his late twenties, completing many of his best-known works during the last two years of his life. In just over a decade, he produced more than 2,100 artworks, consisting of <a title="List of works by Vincent van Gogh" href="http://en.wikipedia.org/wiki/List_of_works_by_Vincent_van_Gogh">860 oil paintings</a> and more than <a title="Drawings, water-colours and prints by Vincent van Gogh" href="http://en.wikipedia.org/wiki/Drawings,_water-colours_and_prints_by_Vincent_van_Gogh">1,300 watercolors, drawings, sketches and prints</a>. [...]</p></blockquote>
<p>Before focusing on painting, he worked as an art dealer, teacher and missionary. It wasn&#8217;t until he was 32 that he painted his first major work.</p>
<p>He did not have the fortune of being recognized as a talented artist in his young age like Michelangelo and others and yet still he did not let go of his desire of becoming a painter. The thing that strikes most of the museum is the quantity of studies and sketches Van Gogh made throughout his live in order to improve his skills. <span style="font-style:inherit;line-height:1.625;">He wanted to paint so much that </span><strong style="font-style:inherit;line-height:1.625;">he kept practicing</strong><span style="font-style:inherit;line-height:1.625;"> and put so much effort in improving that it eventually paid off: he is now remembered as the author of </span><span style="font-style:inherit;line-height:1.625;">dozens of the most renown paintings of the history of art.</span></p>
<p>In an age where the reference point to define an accomplishment is starting a company at 16 and become a billionaire at 22, we risk underestimating the value of persistence. Sure, he did not reach fame and success while he was alive, and his life was not what you would define &#8220;happy&#8221;. But if he had quit because he was not an accomplished painter in his young age, art now would certainly be very different from what we know.</p>
<p>The works of V<span style="font-style:inherit;line-height:1.625;">an Gogh are a proof that there is no such thing as </span><strong style="font-style:inherit;line-height:1.625;">being too late to accomplish something remarkable</strong><span style="font-style:inherit;line-height:1.625;">.</span></p>
<br />Filed under: <a href='http://blog.abahgat.com/category/people/'>people</a> Tagged: <a href='http://blog.abahgat.com/tag/amsterdam/'>Amsterdam</a>, <a href='http://blog.abahgat.com/tag/art/'>Art</a>, <a href='http://blog.abahgat.com/tag/persistence/'>persistence</a>, <a href='http://blog.abahgat.com/tag/van-gogh/'>Van Gogh</a>, <a href='http://blog.abahgat.com/tag/van-gogh-museum/'>Van Gogh museum</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/abahgat.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/abahgat.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/abahgat.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/abahgat.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/abahgat.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/abahgat.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/abahgat.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/abahgat.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/abahgat.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/abahgat.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/abahgat.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/abahgat.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/abahgat.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/abahgat.wordpress.com/1122/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=1122&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.abahgat.com/2013/03/04/what-van-gogh-can-teach-us-about-persistence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>52.365264 4.902523</georss:point>
		<geo:lat>52.365264</geo:lat>
		<geo:long>4.902523</geo:long>
		<media:content url="http://1.gravatar.com/avatar/7f3c642af40363040510685c7cc1334e?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">abahgat</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2013/03/starry_night_over_the_rhone.jpg?w=584" medium="image">
			<media:title type="html">Starry night over the Rhône</media:title>
		</media:content>
	</item>
		<item>
		<title>Prettier source code on WordPress.com</title>
		<link>http://blog.abahgat.com/2013/01/21/prettier-source-code-on-wordpress-com/</link>
		<comments>http://blog.abahgat.com/2013/01/21/prettier-source-code-on-wordpress-com/#comments</comments>
		<pubDate>Mon, 21 Jan 2013 10:34:50 +0000</pubDate>
		<dc:creator>Alessandro Bahgat</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[SyntaxHighlighter]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://blog.abahgat.com/?p=1085</guid>
		<description><![CDATA[Posting source code on WordPress.com is quite simple: the platform already provides an extremely easy to use shortcode called sourcecode, based on a fairly flexible syntax highlighter plugin. By looking at the examples in the documentation page, however, it is evident &#8230; <a href="http://blog.abahgat.com/2013/01/21/prettier-source-code-on-wordpress-com/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=1085&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-1091" alt="Formatted source code" src="http://abahgat.files.wordpress.com/2013/01/screen-shot-2013-01-16-at-10-44-59-pm.png?w=584&#038;h=73" width="584" height="73" /></p>
<p>Posting source code on WordPress.com is quite simple: the platform already provides an extremely easy to use shortcode called <code><a href="http://en.support.wordpress.com/code/posting-source-code/">sourcecode</a></code>, based on a fairly flexible syntax highlighter plugin. By looking at the examples in the <a href="http://en.support.wordpress.com/code/posting-source-code/">documentation page</a>, however, it is evident that the default styling used to render sources is quite old-fashioned and does not fit most modern themes.</p>
<p>While the shortcode offers options to allow users to control many options of the rendering, it does not allow us to configure colors, fonts and size (the default size is so tiny that it is barely readable on high-resolution screens).</p>
<p>When I was writing the previous technical post, I did some investigations to figure out what options are available to post more readable sources if your blog is hosted on WordPress.com and I found out there are basically two alternatives.</p>
<p><span id="more-1085"></span></p>
<h1>Embedding Gists</h1>
<p>The easiest option is to rely on <a href="https://gist.github.com/">Gist</a> - GitHub&#8217;s tool for sharing snippets of code &#8211; which offers an extremely easy way to embed code in your blog. Just create a new snippet (gist) there and <a href="http://en.support.wordpress.com/gist/">follow the instructions</a>.<br />
Unfortunately, the gist embed shortcode available on WordPress.com is less flexible than what you would get if you installed it as a <a href="http://wordpress.org/extend/plugins/embed-github-gist/">plugin</a> on your own instance of WordPress, but it will be enough for most cases.</p>
<table>
<tbody>
<tr>
<th>Pros</th>
<th>Cons</th>
</tr>
<tr>
<td>Easy to embed source</td>
<td>Suitable for posts with a few (long) code snippets</td>
</tr>
<tr>
<td>Code looks good and is readable</td>
<td>Does not always work perfectly with search engines</td>
</tr>
<tr>
<td>Easy for readers to access raw code</td>
<td>Does not work with RSS and posts over email</td>
</tr>
</tbody>
</table>
<h1>Styling source code by customizing your CSS</h1>
<p>While Gists work great most of the time, they are a pain to create and maintain if you are working on a post that should include multiple short snippets of code. In that case, the amount of bookkeeping you have to do is significant (you will have to create and link many small chunks of code) and you may want to be able to manage your code right within the post.</p>
<p>In that case, it may be more practical to fix the CSS theme used by the syntax highlight plugin to make it look post-2010. If you set your own custom CSS on WordPress.com, it will be supposed to be included as the last one to allow you to redefine the styles specified by the theme you are using.<br />
Unfortunately, the CSS used by the syntax highlight module was clearly not written with extensibility in mind, but quite the opposite:</p>
<ul>
<li>all the style declarations it includes make use of <code>!important</code>,</li>
<li>the plugin will dynamically include its own CSS as the last item in the <code>head</code> node, meaning that it will have preference on the custom one you define.</li>
</ul>
<p>This makes sense in the original context – the original syntax highlighter offered several themes you could choose from by including different stylesheets, but that feature is not available on WordPress.com – but will make your life more difficult. You will need to add <code>!important</code> to <strong>all the CSS declarations you redefine</strong> and you will need to use CSS selectors that are <strong>more specific</strong> than the ones used by the plugin. You will be able to see the final result at the end of this post.</p>
<p>WordPress&#8217;s syntax highlight is not perfect, and some things are still quite annoying (e.g. line numbers get in the way if you try selecting and copying source code). Most issues could be addressed by upgrading the plugin to use version 3 of <a href="http://alexgorbatchev.com/SyntaxHighlighter/">SyntaxHighlighter</a> instead of the outdated version that is in use now, but it is something you will not be able to control unless the folks at Automattic decide to update it.</p>
<table>
<tbody>
<tr>
<th>Pros</th>
<th>Cons</th>
</tr>
<tr>
<td>It is necessary to have access to Custom CSS (which is a paid feature)</td>
<td>Hard to copy sources without including line numbers (unless you disable them)</td>
</tr>
<tr>
<td>Access to advanced features (highlight lines, toggle line number display)</td>
<td>Search engines index sources with the post content</td>
</tr>
<tr>
<td>Source can be styled according to preference</td>
<td>Getting your CSS applied correctly can be difficult (but you can start from <a href="https://gist.github.com/4464280">here</a>)</td>
</tr>
</tbody>
</table>
<h1>What did I choose?</h1>
<p>Here is the <a href="https://gist.github.com/4464280">stylesheet</a> (embedded as a Gist) I am currently using  on this blog, based on the pygments theme used to style code at <a title="docs.python.org" href="http://docs.python.org/">docs.python.org</a>.</p>
<p><script src="https://gist.github.com/4464280.js"></script></p>
<p>You can can see what the final result looks like in this post about <a title="User authentication with webapp2 on Google App Engine" href="/2013/01/07/user-authentication-with-webapp2-on-google-app-engine/">User authentication with webapp2 on Google App Engine</a> and in the image at the beginning of this post.</p>
<br />Filed under: <a href='http://blog.abahgat.com/category/web/'>web</a> Tagged: <a href='http://blog.abahgat.com/tag/css/'>CSS</a>, <a href='http://blog.abahgat.com/tag/github/'>GitHub</a>, <a href='http://blog.abahgat.com/tag/source-code/'>Source code</a>, <a href='http://blog.abahgat.com/tag/syntaxhighlighter/'>SyntaxHighlighter</a>, <a href='http://blog.abahgat.com/tag/wordpress/'>Wordpress</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/abahgat.wordpress.com/1085/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/abahgat.wordpress.com/1085/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/abahgat.wordpress.com/1085/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/abahgat.wordpress.com/1085/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/abahgat.wordpress.com/1085/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/abahgat.wordpress.com/1085/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/abahgat.wordpress.com/1085/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/abahgat.wordpress.com/1085/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/abahgat.wordpress.com/1085/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/abahgat.wordpress.com/1085/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/abahgat.wordpress.com/1085/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/abahgat.wordpress.com/1085/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/abahgat.wordpress.com/1085/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/abahgat.wordpress.com/1085/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=1085&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.abahgat.com/2013/01/21/prettier-source-code-on-wordpress-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>45.463681 9.188171</georss:point>
		<geo:lat>45.463681</geo:lat>
		<geo:long>9.188171</geo:long>
		<media:content url="http://1.gravatar.com/avatar/7f3c642af40363040510685c7cc1334e?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">abahgat</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2013/01/screen-shot-2013-01-16-at-10-44-59-pm.png" medium="image">
			<media:title type="html">Formatted source code</media:title>
		</media:content>
	</item>
		<item>
		<title>User authentication with webapp2 on Google App Engine</title>
		<link>http://blog.abahgat.com/2013/01/07/user-authentication-with-webapp2-on-google-app-engine/</link>
		<comments>http://blog.abahgat.com/2013/01/07/user-authentication-with-webapp2-on-google-app-engine/#comments</comments>
		<pubDate>Mon, 07 Jan 2013 07:57:26 +0000</pubDate>
		<dc:creator>Alessandro Bahgat</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[Appengine]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[Google App Engine]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.abahgat.com/?p=808</guid>
		<description><![CDATA[Google App Engine for Python ships with the capability to manage user accounts without the need of any additional library. This functionality is, however, insufficiently documented. This post will be structured as a step-by-step tutorial addressing user registration, login, password &#8230; <a href="http://blog.abahgat.com/2013/01/07/user-authentication-with-webapp2-on-google-app-engine/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=808&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p style="color:#999;width:90%;margin-left:auto;margin-right:auto;font-size:smaller;">Google App Engine for Python ships with the capability to manage user accounts without the need of any additional library. This functionality is, however, insufficiently documented. This post will be structured as a step-by-step tutorial addressing user registration, login, password reset and a few other details.</p>
<p>The <a href="http://webapp-improved.appspot.com/"><em>webapp2</em></a> framework on Google App Engine for Python 2.7 is definitely a step forward from the original <em>webapp</em>.<br />
Despite the increase in flexibility and functionality, however, there are a few items that are still more laborious than in other frameworks. The most notable aspect is <strong>user account management</strong>.</p>
<p>Unsurprisingly, since it is meant to run on Google&#8217;s App Engine, using Google Accounts with webapp2 takes one line of code. OpenID authentication, while still defined <em>experimental</em>, is almost trivial to implement as well. There are some open source projects like <a href="https://github.com/crhym3/simpleauth">SimpleAuth</a> that attempt to offer a standard and unified API to handle signing in with Google, OAuth and OpenID accounts.</p>
<p>While it generally makes sense to offer support for authentication through popular services – it decreases friction for new users to try a service – in some cases users may prefer having a special login to access your application.</p>
<p>As experience teaches us, managing passwords securely is not a trivial task, and users legitimately expect application developers to take all the necessary measures to <a title="Are our passwords safe?" href="http://blog.abahgat.com/2009/10/19/are-our-passwords-safe/">protect their passwords</a>.</p>
<p>Since this is a use case that has to be considered countless time, there is significant value in using library functions to handle user accounts.</p>
<p>Here is how to do that using the functionalities embedded in the <em>webapp2_extras</em> package that is distributed with all standard installations of App Engine for Python 2.7.</p>
<p><span id="more-808"></span></p>
<h1>Basics and prerequisites</h1>
<p>Our main interface when dealing with authentication is <a href="http://webapp-improved.appspot.com/api/webapp2_extras/auth.html#module-webapp2_extras.auth"><code>webapp2_extras.auth</code></a>. This module leverages the rest of webapp2&#8242;s infrastructure to offer us a simpler way to manage user authentication.</p>
<p>In particular, it relies on</p>
<ul>
<li><a href="http://webapp-improved.appspot.com/api/webapp2_extras/security.html#module-webapp2_extras.security"><code>webapp2_extras.security</code></a> to handle password hashing (so that passwords are never stored in clear text) and random string generation;</li>
<li><a href="http://webapp-improved.appspot.com/api/webapp2_extras/sessions.html#module-webapp2_extras.sessions"><code>webapp2_extras.sessions</code></a> to identify requests coming from the same user as part of a client-server conversation.</li>
</ul>
<p>Since we are implementing our own user database, we will need to define a custom model class to represent users in our application. The auth framework described here works under the assumption that this model class defines the following instance method:</p>
<ul>
<li><code>get_id(self)</code></li>
</ul>
<p>and the following class methods:</p>
<ul>
<li><code>get_by_auth_token(cls, user_id, token)</code></li>
<li><code>get_by_auth_password(cls, auth_id, password)</code></li>
<li><code>create_auth_token(cls, user_id)</code></li>
<li><code>delete_auth_token(cls, user_id, token)</code></li>
</ul>
<p>The specific role of each of those methods is described <a href="http://webapp-improved.appspot.com/tutorials/auth.html">here</a>.</p>
<p>In addition to that, if you are interested in using the code for password reset provided as part of this tutorial, you will also need to implement the following class method:</p>
<pre>get_by_auth_token(cls, user_id, token, subject='auth')</pre>
<p>For each request, our application will then be able to do the following:</p>
<ol>
<li>read a cookie to figure out whether the current belongs to an existing session,</li>
<li>if a cookie is found, read an authentication from it and load the corresponding session (if present) from the session store backend,</li>
<li>loads some cached user information from the session.</li>
</ol>
<p>We will be able to tune some details of the process via configuration options.</p>
<h1>Extending the default User model</h1>
<p><em> webapp2</em> already contains a reference <a href="http://webapp-improved.appspot.com/api/webapp2_extras/appengine/auth/models.html#webapp2_extras.appengine.auth.models.User">User</a> model for Google App Engine that uses <a href="https://developers.google.com/appengine/docs/python/ndb/overview">NDB</a> for storage. If you are willing to use that, you will find it good enough for most of the needs you may have.<br />
In particular,</p>
<ul>
<li>it is an <a href="https://developers.google.com/appengine/docs/python/datastore/expandoclass"><strong>Expando</strong></a> model – it can include properties that were not specified as part of the class definition but are added at run-time, so it will not be a problem if your application needs to store some specific user information. New properties are indexed by default, so queries should still be fast.</li>
<li>it allows you to set uniqueness constraints – while NDB does not support unique properties by default, webapp2&#8242;s User model uses a custom mechanism to allow to allow that.</li>
</ul>
<p>Oddly enough – since the User class is clearly well designed – the reference implementation does not offer any method to update the password for a given user once it has been set. Because of that, it is a good idea to extend the User model to add a<br />
<code>set_password</code> method that will have the responsibility to securely hash passwords using the <em>security</em> module.<br />
You can find an example User model implementation below: it will contain the password setter and the <code>get_by_auth_token</code> class method (modeled after the one already provided by webapp2) that has been introduced in the previous section.</p>
<pre class="brush: python; title: ; toolbar: false; notranslate">
import time
import webapp2_extras.appengine.auth.models

from google.appengine.ext import ndb

from webapp2_extras import security

class User(webapp2_extras.appengine.auth.models.User):
  def set_password(self, raw_password):
    &quot;&quot;&quot;Sets the password for the current user

    :param raw_password:
        The raw password which will be hashed and stored
    &quot;&quot;&quot;
    self.password = security.generate_password_hash(raw_password, length=12)

  @classmethod
  def get_by_auth_token(cls, user_id, token, subject='auth'):
    &quot;&quot;&quot;Returns a user object based on a user ID and token.

    :param user_id:
        The user_id of the requesting user.
    :param token:
        The token string to be verified.
    :returns:
        A tuple ``(User, timestamp)``, with a user object and
        the token timestamp, or ``(None, None)`` if both were not found.
    &quot;&quot;&quot;
    token_key = cls.token_model.get_key(user_id, subject, token)
    user_key = ndb.Key(cls, user_id)
    # Use get_multi() to save a RPC call.
    valid_token, user = ndb.get_multi([token_key, user_key])
    if valid_token and user:
        timestamp = int(time.mktime(valid_token.created.timetuple()))
        return user, timestamp

    return None, None
</pre>
<h1>Setting up the configuration</h1>
<p>With what we have seen so far, we are now able to configure our application. We will need to set some properties as follows:</p>
<pre class="brush: python; title: ; toolbar: false; notranslate">
config = {
  'webapp2_extras.auth': {
    'user_model': 'models.User',
    'user_attributes': ['name']
  },
  'webapp2_extras.sessions': {
    'secret_key': 'YOUR_SECRET_KEY'
  }
}
</pre>
<p>In particular,</p>
<ul>
<li><code>user_model</code> is the name of the custom User model class we described earlier,</li>
<li><code>user_attributes</code> is a list of attributes in the User model that will be cached in the session. Ideally, frequently accessed properties should be stored here. The full User model will be accessible by querying the datastore.</li>
<li><code>secret_key</code> is the key used to secure the hash signature calculation for session cookies.</li>
</ul>
<h1>Creating a base handler class</h1>
<p>Before writing the actual handlers that will implement the business logic to sign up and authenticate users we will group some utility functions in a base handler class, which will be extended by all the following handler classes.</p>
<p>This will ensure that all handlers will inherit a set of useful utility functions and properties to access user data and infrastructure classes, but also ensures that all session data is properly saved on each request (see <code>dispatch</code>).</p>
<pre class="brush: python; title: ; toolbar: false; notranslate">
class BaseHandler(webapp2.RequestHandler):
  @webapp2.cached_property
  def auth(self):
    &quot;&quot;&quot;Shortcut to access the auth instance as a property.&quot;&quot;&quot;
    return auth.get_auth()

  @webapp2.cached_property
  def user_info(self):
    &quot;&quot;&quot;Shortcut to access a subset of the user attributes that are stored
    in the session.

    The list of attributes to store in the session is specified in
      config['webapp2_extras.auth']['user_attributes'].
    :returns
      A dictionary with most user information
    &quot;&quot;&quot;
    return self.auth.get_user_by_session()

  @webapp2.cached_property
  def user(self):
    &quot;&quot;&quot;Shortcut to access the current logged in user.

    Unlike user_info, it fetches information from the persistence layer and
    returns an instance of the underlying model.

    :returns
      The instance of the user model associated to the logged in user.
    &quot;&quot;&quot;
    u = self.user_info
    return self.user_model.get_by_id(u['user_id']) if u else None

  @webapp2.cached_property
  def user_model(self):
    &quot;&quot;&quot;Returns the implementation of the user model.

    It is consistent with config['webapp2_extras.auth']['user_model'], if set.
    &quot;&quot;&quot;    
    return self.auth.store.user_model

  @webapp2.cached_property
  def session(self):
      &quot;&quot;&quot;Shortcut to access the current session.&quot;&quot;&quot;
      return self.session_store.get_session(backend=&quot;datastore&quot;)

  def render_template(self, view_filename, params={}):
    user = self.user_info
    params['user'] = user
    path = os.path.join(os.path.dirname(__file__), 'views', view_filename)
    self.response.out.write(template.render(path, params))

  def display_message(self, message):
    &quot;&quot;&quot;Utility function to display a template with a simple message.&quot;&quot;&quot;
    params = {
      'message': message
    }
    self.render_template('message.html', params)

  # this is needed for webapp2 sessions to work
  def dispatch(self):
      # Get a session store for this request.
      self.session_store = sessions.get_store(request=self.request)

      try:
          # Dispatch the request.
          webapp2.RequestHandler.dispatch(self)
      finally:
          # Save all sessions.
          self.session_store.save_sessions(self.response)
</pre>
<p><b>Note</b> &ndash; You may want redefine the view-related methods to something different if you use a different templating engine.</p>
<h1>Registration: create new users</h1>
<p>If we are using the model class discussed in the previous sections, in order to create a new User we just need to call the <code>create_user</code> method.</p>
<pre class="brush: python; highlight: [12,13,14,15,16,25]; title: ; toolbar: false; notranslate">
class SignupHandler(BaseHandler):
  def get(self):
    self.render_template('signup.html')

  def post(self):
    user_name = self.request.get('username')
    email = self.request.get('email')
    name = self.request.get('name')
    password = self.request.get('password')
    last_name = self.request.get('lastname')

    unique_properties = ['email_address']
    user_data = self.user_model.create_user(user_name,
      unique_properties,
      email_address=email, name=name, password_raw=password,
      last_name=last_name, verified=False)
    if not user_data[0]: #user_data is a tuple
      self.display_message('Unable to create user for email %s because of \
        duplicate keys %s' % (user_name, user_data[1]))
      return

    user = user_data[1]
    user_id = user.get_id()

    token = self.user_model.create_signup_token(user_id)

    verification_url = self.uri_for('verification', type='v', user_id=user_id,
      signup_token=token, _full=True)

    msg = 'Send an email to user in order to verify their address. \
          They will be able to do so by visiting  &lt;a href=&quot;{url}&quot;&gt;{url}&lt;/a&gt;'

    self.display_message(msg.format(url=verification_url))</pre>
<p><code>create_user</code> will accept the following parameters:</p>
<ul>
<li>an <em>authentication id</em>: the token (such as a username or an email address) users will use to identify themselves when trying to access our application. While users can have multiple authentication ids, only one is allowed at creation.</li>
<li>a list of unique properties (in this case, <code>email_address</code>): if this is specified, webapp2 will not allow us to create new users if others share the same values for the properties in this list.</li>
<li>name/value pairs that are going to be set as properties of the resulting User model. If you want to add your own fields, this where to do it. If a parameter called <code>password_raw</code> is present, it will be assumed to be the user password that will be used for authentication; webapp2 will hash it and store the hash the password field: we do not want to store passwords in clear text, do we?</li>
</ul>
<p>We also create a <em>signup token</em> and associate it to the newly created account: we will use to confirm the email address that has been provided during registration.</p>
<p>Note that we are accessing the model as <code>self.user_model</code> rather than calling it directly, so that we are free to change which implementation to use by updating the application configuration.</p>
<h1>Login and logout</h1>
<p>If users are created as in the previous session, login is quite simple: the <code>get_user_by_password</code> method can be used to retrieve a user by their credentials. In addition to the user credentials, the method accepts some additional parameters. The one we care about (and the only one we use here) is <code>remember</code>: when set to <code>True</code>, the cookie used to identify the session is saved as persistent and the browser will keep it even after the user will close its window.</p>
<pre class="brush: python; highlight: [9,10]; title: ; toolbar: false; notranslate">
class LoginHandler(BaseHandler):
  def get(self):
    self._serve_page()

  def post(self):
    username = self.request.get('username')
    password = self.request.get('password')
    try:
      u = self.auth.get_user_by_password(username, password, remember=True)
      self.redirect(self.uri_for('home'))
    except (InvalidAuthIdError, InvalidPasswordError) as e:
      logging.info('Login failed for user %s because of %s', username, type(e))
      self._serve_page(True)

  def _serve_page(self, failed=False):
    username = self.request.get('username')
    params = {
      'username': username,
      'failed': failed
    }
    self.render_template('login.html', params)
</pre>
<p>The implementation above renders the login form when the request comes via GET and processes the credentials upon POST. When authentication fails it renders the login form and passes the username to the template so that the corresponding field can be pre-filled.</p>
<p>Implementing logout is even simpler: it is sufficient to get rid of the user session.</p>
<pre class="brush: python; title: ; toolbar: false; notranslate">
class LogoutHandler(BaseHandler):
  def get(self):
    self.auth.unset_session()
    self.redirect(self.uri_for('home'))
</pre>
<h1>Email confirmation and password reset</h1>
<p>Signup tokens are one of the undocumented features of webapp2 (and they may possibly subject to change), but they can be quite handy when implementing a flow to confirming email addresses or recover passwords.</p>
<p>As mentioned before, the webapp2 uses authentication tokens to identify users after they logged in: they are meant to be securely shared by a client and the server and exchanged when a client needs to prove its identity.</p>
<p>As you probably imagine, this mechanism can be generalized to handle email confirmations and password resets: when websites send us an activation link after a registration, the URL usually contain their equivalent of signup tokens.</p>
<p>webapp2 sets a <code>subject</code> property for each of the tokens it generates, so the only difference between auth token and signup token is the value for that property. So, why do we want to use signup tokens?</p>
<p>Setting a different value for that property allows us to partition tokens by their purpose: we can then implement useful features as <em>deleting all the password reset tokens that have not been used in 48 hours</em>.</p>
<p>Here is a sample verification handler that is able to process email verification links:</p>
<pre class="brush: python; title: ; toolbar: false; notranslate">
class VerificationHandler(BaseHandler):
  def get(self, *args, **kwargs):
    user = None
    user_id = kwargs['user_id']
    signup_token = kwargs['signup_token']
    verification_type = kwargs['type']

    # it should be something more concise like
    # self.auth.get_user_by_token(user_id, signup_token
    # unfortunately the auth interface does not (yet) allow to manipulate
    # signup tokens concisely
    user, ts = self.user_model.get_by_auth_token(int(user_id), signup_token,
      'signup')

    if not user:
      logging.info('Could not find any user with id &quot;%s&quot; signup token &quot;%s&quot;',
        user_id, signup_token)
      self.abort(404)

    # store user data in the session
    self.auth.set_session(self.auth.store.user_to_dict(user), remember=True)

    if verification_type == 'v':
      # remove signup token, we don't want users to come back with an old link
      self.user_model.delete_signup_token(user.get_id(), signup_token)

      if not user.verified:
        user.verified = True
        user.put()

      self.display_message('User email address has been verified.')
      return
    elif verification_type == 'p':
      # supply user to the page
      params = {
        'user': user,
        'token': signup_token
      }
      self.render_template('resetpassword.html', params)
    else:
      logging.info('verification type not supported')
      self.abort(404)
</pre>
<p>This handler is meant to be used with a route using a template that matches URLs like <code>/v/USERID-TOKEN</code>. You can configure it as follows (please refer to the sample code at the end of this article for the full routes configuration):</p>
<pre class="brush: python; title: ; toolbar: false; notranslate">
webapp2.Route('/&lt;type:v|p&gt;/&lt;user_id:\d+&gt;-&lt;signup_token:.+&gt;',
  handler=VerificationHandler, name='verification')
</pre>
<p>Two minor notes on this item:</p>
<ol>
<li>For increased security, we may require users to enter their password before authenticating them.</li>
<li>Ideally, we may want to use a different subject for email confirmation and password reset tokens.</li>
</ol>
<h1>Ensure users are logged in</h1>
<p>Now that everything else is in place, we can decide whether users are allowed to access certain resources depending on their logged in state.<br />
The following decorator can be used to annotate handler methods that require users to be logged in.</p>
<pre class="brush: python; title: ; toolbar: false; notranslate">
def user_required(handler):
  &quot;&quot;&quot;
    Decorator that checks if there's a user associated with the current session.
    Will also fail if there's no session present.
  &quot;&quot;&quot;
  def check_login(self, *args, **kwargs):
    auth = self.auth
    if not auth.get_user_by_session():
      self.redirect(self.uri_for('login'), abort=True)
    else:
      return handler(self, *args, **kwargs)

  return check_login
</pre>
<p>Just placing <code>@user_required</code>, as in the following example, before those methods will ensure that anonymous users will be directed to a login page when attempting to go through the annotated handler method.</p>
<pre class="brush: python; highlight: [2]; title: ; toolbar: false; notranslate">
class AuthenticatedHandler(BaseHandler):
  @user_required
  def get(self):
    self.render_template('authenticated.html')
</pre>
<h1>Finishing touches</h1>
<p>Before actually using this in code in production, there is at least one task we should take care of: calls that send passwords (like login, signup, password reset) should be using <code>https</code>.</p>
<p>This is quite easy to do and the documentation is quite straightforward: just follow the <a href="https://developers.google.com/appengine/docs/python/config/appconfig#Secure_URLs">instructions here</a> and you will be all set.</p>
<p>Your app.yaml file should include the following once you are done:</p>
<pre class="brush: plain; title: ; toolbar: false; notranslate">
handlers:
- url: .*
  script: main.app

- url: /signup
  script: main.app
  secure: always

- url: /login
  script: main.app
  secure: always

- url: /forgot
  script: main.app
  secure: always

libraries:
- name: webapp2
  version: &quot;2.5.1&quot;
</pre>
<p>Of course, we will also need some views to be able to use this application. While this is the typical task that is left as an exercise to the reader, the example implementation you will find in the following section will contain a fully working application you can play with.</p>
<h1>Reference code</h1>
<p>You can find a ready to use application skeleton <a href="https://github.com/abahgat/webapp2-user-accounts"><b>on GitHub</b></a>. Feel free to play with it to experiment the full flow described in this post, use it to bootstrap your project and to improve on it. Just post a comment if you have any question or suggestion.</p>
<hr />
If you found this post useful you should <a href="http://twitter.com/abahgat"><b>follow me on twitter</b></a>.</p>
<br />Filed under: <a href='http://blog.abahgat.com/category/software-engineering/coding/'>coding</a> Tagged: <a href='http://blog.abahgat.com/tag/appengine/'>Appengine</a>, <a href='http://blog.abahgat.com/tag/authentication/'>Authentication</a>, <a href='http://blog.abahgat.com/tag/google/'>google</a>, <a href='http://blog.abahgat.com/tag/google-app-engine/'>Google App Engine</a>, <a href='http://blog.abahgat.com/tag/programming/'>programming</a>, <a href='http://blog.abahgat.com/tag/python/'>Python</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/abahgat.wordpress.com/808/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/abahgat.wordpress.com/808/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/abahgat.wordpress.com/808/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/abahgat.wordpress.com/808/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/abahgat.wordpress.com/808/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/abahgat.wordpress.com/808/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/abahgat.wordpress.com/808/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/abahgat.wordpress.com/808/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/abahgat.wordpress.com/808/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/abahgat.wordpress.com/808/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/abahgat.wordpress.com/808/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/abahgat.wordpress.com/808/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/abahgat.wordpress.com/808/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/abahgat.wordpress.com/808/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=808&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.abahgat.com/2013/01/07/user-authentication-with-webapp2-on-google-app-engine/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		<georss:point>52.369540 4.849414</georss:point>
		<geo:lat>52.369540</geo:lat>
		<geo:long>4.849414</geo:long>
		<media:content url="http://1.gravatar.com/avatar/7f3c642af40363040510685c7cc1334e?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">abahgat</media:title>
		</media:content>
	</item>
		<item>
		<title>Beyond keyboard shortcuts</title>
		<link>http://blog.abahgat.com/2012/12/19/beyond-keyboard-shortcuts/</link>
		<comments>http://blog.abahgat.com/2012/12/19/beyond-keyboard-shortcuts/#comments</comments>
		<pubDate>Wed, 19 Dec 2012 08:13:57 +0000</pubDate>
		<dc:creator>Alessandro Bahgat</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[Alfred]]></category>
		<category><![CDATA[command search]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[interaction]]></category>
		<category><![CDATA[keyboard]]></category>
		<category><![CDATA[keyboard shortcuts]]></category>
		<category><![CDATA[shortcuts]]></category>
		<category><![CDATA[Sublime Text]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.abahgat.com/?p=923</guid>
		<description><![CDATA[In the age of touch devices, some days it seems like a day will come when we will not have to use a keyboard to interact with computers. A significant part of our relationship with technology passes through interfaces that &#8230; <a href="http://blog.abahgat.com/2012/12/19/beyond-keyboard-shortcuts/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=923&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In the age of touch devices, some days it seems like a day will come when we will not have to use a keyboard to interact with computers. A significant part of our relationship with technology passes through interfaces that were not common a decade ago: touch screens, accelerometers, cameras and microphones.</p>
<p><img class="alignright zemanta-img-inserted zemanta-img-configured" style="margin:5px;" title="English: QWERTY keyboard, on 2007 Sony Vaio la..." alt="English: QWERTY keyboard, on 2007 Sony Vaio la..." src="http://upload.wikimedia.org/wikipedia/commons/thumb/0/0a/QWERTY_keyboard.jpg/300px-QWERTY_keyboard.jpg" width="200" height="133" />Keyboards, however, are still the most efficient way to interact with a computer, and not only for typing email. From code editors like Emacs to advanced image manipulation tools like Photoshop, it is no wonder that most advanced programs can be controlled more efficiently by means of keyboard shortcuts.<br />
The learning curve for shortcuts is generally quite steep: while some of them are standard across programs and can be easily guessed, most shortcuts are complex abstract key combinations (as <code>Command-Control-Shift-3</code> on Mac, that takes a screenshot to the clipboard) and therefore not easy to remember.</p>
<p>Some applications, however, are introducing smarter ways to control our computers using a keyboard.<br />
<span id="more-923"></span></p>
<h1>Alfred: Mac at your fingertips</h1>
<p>Mac OS has a long tradition of exposing keyboard shortcuts that allow power users to perform common tasks more efficiently. Introducing <a href="http://en.wikipedia.org/wiki/Spotlight_(software)">Spotlight</a> was one more step towards keyboard driven interaction, as it allows to access applications, files and many other items by typing in a text box. <a href="http://www.alfredapp.com/">Alfred</a>, takes this approach to a new level: just like with Spotlight, pressing a combination of keys brings up a text box where you can enter anything from file names to simple commands (like <em>empty trash</em>, <em>shutdown</em>, and many more).</p>
<p><img class="aligncenter size-full wp-image-930" alt="Alfred in action" src="http://abahgat.files.wordpress.com/2012/12/a8ebd466-0c44-4365-b359-51a1c62611d6.png?w=584&#038;h=260" width="584" height="260" /></p>
<p>The advantage over the built-in solution is that those commands allow you to control many functionalities that traditionally would have required you to click through several items and menus. Alfred will even adjust its behavior depending on the way you use it: it will present you first the options you select the most.</p>
<h1>Sublime Text: controlling a text editor through text commands</h1>
<p>When working with a text editor, typing on a keyboard is &#8211; by definition &#8211; the main means of interaction and so these programs traditionally rely on keyboard shortcuts more than any other. The over 2000 keyboard shortcuts available in Emacs are the most significant evidence of the level of complexity shortcuts can reach: it is impossible to master all the key sequences, only the most common ones.</p>
<p><a href="http://www.sublimetext.com/">Sublime Text,</a> one of the best editors available today, takes an innovative approach to keyboard interaction: instead of requiring users to memorize arbitrary key sequences, it offers a mode called <em>Command Palette</em>, that allows users to type the name of any command to launch it.</p>
<p><img class="aligncenter size-full wp-image-931" alt="Sublime Text's command palette" src="http://abahgat.files.wordpress.com/2012/12/screen-shot-2012-12-18-at-20-44-47.png?w=584&#038;h=203" width="584" height="203" /></p>
<p>Compared to having to learn or remember keyboard shortcuts, this approach saves users also the need to sift through the application menus to find the feature they are looking for. As a side effect, it is also a much more effective way to discover application features than reading a manual.</p>
<h1>Ubuntu: using HUD to get past menus</h1>
<p>If the previous mode of interaction is still an exception on Windows and Mac, Ubuntu took some bold steps towards that: they designed a new system called <a href="http://www.markshuttleworth.com/archives/939">HUD</a> (as in <em>Head-Up Display</em>).</p>
<p>It immediately offers users the same benefit as Sublime Text&#8217;s command palette: faster interaction with menus items and easier discovery of features. In addition to that, however, it shares with Alfred its adaptive behavior and will learn by user behavior.</p>
<p>While HUD is ultimately designed with voice control in mind, keyboard commands are still extremely efficient and already effective today.</p>
<p>You can see it in action in the following video.</p>
<span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='584' height='359' src='http://www.youtube.com/embed/w_WW-DHqR3c?version=3&#038;rel=0&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0'></iframe></span>
<p>Embedding features like these in the operating system (or, more precisely, in the desktop shell) means that we will be able to control any application in a faster and more efficient way, regardless of whether its developers planned for that feature in advance or not.</p>
<h1>Conclusion: why should I care?</h1>
<p>Decades ago, keyboard shortcuts were born as a means to offer power users a more efficient way to perform their tasks. Nowadays, with fast access to command search (one or two keys) and smart algorithms to search through commands, anyone can become a power user in less time.</p>
<p>Not all applications will benefit dramatically from command search, but this pattern will become more and more common when web sites/applications start offering it: look at <a href="http://googledrive.blogspot.nl/2012/10/less-is-more.html">Google Docs menu search</a> and <a href="https://github.com/blog/1264-introducing-the-command-bar">GitHub&#8217;s command bar</a>.</p>
<br />Filed under: <a href='http://blog.abahgat.com/category/design/'>design</a> Tagged: <a href='http://blog.abahgat.com/tag/alfred/'>Alfred</a>, <a href='http://blog.abahgat.com/tag/command-search/'>command search</a>, <a href='http://blog.abahgat.com/tag/design/'>design</a>, <a href='http://blog.abahgat.com/tag/emacs/'>Emacs</a>, <a href='http://blog.abahgat.com/tag/github/'>GitHub</a>, <a href='http://blog.abahgat.com/tag/interaction/'>interaction</a>, <a href='http://blog.abahgat.com/tag/keyboard/'>keyboard</a>, <a href='http://blog.abahgat.com/tag/keyboard-shortcuts/'>keyboard shortcuts</a>, <a href='http://blog.abahgat.com/tag/shortcuts/'>shortcuts</a>, <a href='http://blog.abahgat.com/tag/sublime-text/'>Sublime Text</a>, <a href='http://blog.abahgat.com/tag/ubuntu/'>Ubuntu</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/abahgat.wordpress.com/923/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/abahgat.wordpress.com/923/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/abahgat.wordpress.com/923/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/abahgat.wordpress.com/923/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/abahgat.wordpress.com/923/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/abahgat.wordpress.com/923/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/abahgat.wordpress.com/923/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/abahgat.wordpress.com/923/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/abahgat.wordpress.com/923/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/abahgat.wordpress.com/923/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/abahgat.wordpress.com/923/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/abahgat.wordpress.com/923/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/abahgat.wordpress.com/923/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/abahgat.wordpress.com/923/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=923&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.abahgat.com/2012/12/19/beyond-keyboard-shortcuts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<georss:point>52.369530 4.849452</georss:point>
		<geo:lat>52.369530</geo:lat>
		<geo:long>4.849452</geo:long>
		<media:content url="http://1.gravatar.com/avatar/7f3c642af40363040510685c7cc1334e?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">abahgat</media:title>
		</media:content>

		<media:content url="http://upload.wikimedia.org/wikipedia/commons/thumb/0/0a/QWERTY_keyboard.jpg/300px-QWERTY_keyboard.jpg" medium="image">
			<media:title type="html">English: QWERTY keyboard, on 2007 Sony Vaio la...</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2012/12/a8ebd466-0c44-4365-b359-51a1c62611d6.png" medium="image">
			<media:title type="html">Alfred in action</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2012/12/screen-shot-2012-12-18-at-20-44-47.png" medium="image">
			<media:title type="html">Sublime Text&#039;s command palette</media:title>
		</media:content>
	</item>
		<item>
		<title>Story of a hack: Bring Your Own Music!</title>
		<link>http://blog.abahgat.com/2012/12/04/story-of-a-hack-bring-your-own-music/</link>
		<comments>http://blog.abahgat.com/2012/12/04/story-of-a-hack-bring-your-own-music/#comments</comments>
		<pubDate>Mon, 03 Dec 2012 23:19:00 +0000</pubDate>
		<dc:creator>Alessandro Bahgat</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[Amsterdam]]></category>
		<category><![CDATA[Apigee]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[hackathon]]></category>
		<category><![CDATA[nfc]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[Spotify]]></category>
		<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://blog.abahgat.com/?p=894</guid>
		<description><![CDATA[This post is a summary of the weekend we spent at the Kings of Code 2012 Hack Battle in Amsterdam. What started as an occasion to get to know smart people doing cool things in Amsterdam (something I look for since &#8230; <a href="http://blog.abahgat.com/2012/12/04/story-of-a-hack-bring-your-own-music/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=894&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This post is a summary of the weekend we spent at the <a href="http://kingsofcode.com/">Kings of Code 2012</a> Hack Battle in Amsterdam. What started as an occasion to get to know smart people doing cool things in Amsterdam (something I look for since <a title="What you should know before moving to Amsterdam" href="http://blog.abahgat.com/2012/11/20/what-you-should-know-before-moving-to-amsterdam/">I moved here</a>) turned out to be one of the funniest experiences I had in a while.</p>
<p>After a brief presentation of the services offered by the hackathon partners (<a href="http://apigee.com/">Apigee</a>, <a href="http://www.esri.com/">Esri</a>, <a href="http://www.spotify.com/">Spotify</a> and <a href="http://sendgrid.com/">Sendgrid</a>) <a href="http://about.me/diderik/">Diderik</a>, <a href="http://www.raibaz.com/">Mattia</a>, <a href="https://github.com/mikepage">Mike</a> and I teamed up to build the hack featured here. We started with the most obvious concept we could come up with: putting songs on a map and having people visualize them. We tried to elaborate the concept to include as many of the partners&#8217; APIs as we could, but then we decided for something simpler, something we could build over the weekend.</p>
<div id="attachment_895" class="wp-caption aligncenter" style="width: 594px"><img class=" wp-image-895" alt="Bring Your Own Music card reader" src="http://abahgat.files.wordpress.com/2012/12/2012-12-02-13-01-47.jpg?w=584&#038;h=438" width="584" height="438" /><p class="wp-caption-text">Bring Your Own Music!</p></div>
<p>It took us a couple of iterations to get to the final idea we developed: <strong>Bring Your Own Music</strong>, a toy application that allows users to control music playback through NFC-enabled objects by using an Arduino-powered NFC reader driving a Spotify app.</p>
<p><span id="more-894"></span></p>
<p>BYOM is based upon the idea of attaching Spotify playlists to physical objects, provided they contain an NFC tag, like many of the cards we have in our wallet. Once you have done that, you can then bring your card with you to a party, tap it on an NFC reader, and have a Jukebox Spotify app like the one we built start playing your songs automatically.</p>
<div id="attachment_896" class="wp-caption aligncenter" style="width: 594px"><a href="http://abahgat.files.wordpress.com/2012/12/byomscreenshot.png"><img class=" wp-image-896 " alt="A screenshot of the Spotify Jukebox app" src="http://abahgat.files.wordpress.com/2012/12/byomscreenshot.png?w=584&#038;h=361" width="584" height="361" /></a><p class="wp-caption-text">A screenshot of the Spotify Jukebox app we built during the hack battle</p></div>
<p>If multiple people tap their own cards, the main Spotify playlist adjusts itself according to the general preferences of the party attendees. We even kept playing with NFC-enabled objects and linked Spotify playlists to all sort of cards, like London&#8217;s Oyster cards, OV-Chipkaarts and even the disposable tram tickets you get here in Amsterdam.</p>
<p>As Mattia noted,</p>
<blockquote><p>wouldn&#8217;t it be great if passengers could listen to their favorite music when they check-in on trams?</p></blockquote>
<h1>How was BYOM built?</h1>
<p>We collected the identifiers of a bunch of NFC cards, OV-chipkaarts and tram tickets using Mike&#8217;s Arduino connected NFC reader. We then created a collection on <a href="http://apigee.com/docs/app_services">Apigee App Services</a> to store the card ids and URIs of the Spotify playlists we wanted to link to them.</p>
<p>We programmed Arduino to make a call to Apigee whenever a card is tapped on the reader, in order to store the card identifier into a <em>Swipes</em> collection.</p>
<div id="attachment_915" class="wp-caption aligncenter" style="width: 594px"><img class="size-full wp-image-915" alt="Hey, look, there is an Arduino in the box!" src="http://abahgat.files.wordpress.com/2012/12/2012-12-02-17-33-16.jpg?w=584&#038;h=438" width="584" height="438" /><p class="wp-caption-text">Hey, look, there is an Arduino in the box!</p></div>
<p>At the same time, we wrote a Spotify application that periodically queried Apigee for new swipes and, as soon as a new card was detected, fetched the songs associated to it and merged them into the main playlist (the one the Spotify Jukebox app would play).</p>
<h1>What have we learned by it?</h1>
<p>We (I, at least) walked away with some important teachings:</p>
<ul>
<li><span style="line-height:15px;"><strong>focus</strong> is more important than ever: there is no point in imagining lots of features if you are not going to finish them. Pick a small set of features and make them work (or almost work: we had the inevitable demo-time malfunctions despite having tried the full example multiple times before presenting),</span></li>
<li>build a <strong>story</strong>: having a story (in our case, the party) around your hack helps you focus and helps you when presenting it,</li>
<li>get some <strong>constraints</strong>: there are thousands of interesting APIs, devices and ideas out there, and even more ways those can be combined. Choose some constraints to ensure you don&#8217;t wander off too much (in our case, we wanted to do something with Mike&#8217;s NFC-reader)</li>
<li>have <strong>fun</strong>: while these sounds like rules, they are more of an advice. Do not let them distract you from your goal: <em>having fun</em>.</li>
</ul>
<h1>What about the technologies?</h1>
<p><strong>Arduino</strong> is indeed an extremely versatile tool and the amount of sample code and libraries available out there is surprising. While it can be a pain to debug at times, the fact that it allows you to add a physical dimension to your hacks is invaluable.</p>
<p><strong>Spotify</strong>&#8216;s wise choice to build their application framework on top of Chromium means that developers can leverage the tools they already got to know by developing web applications. The actual app SDK is a JavaScript library you an include and debug using the tools in Chromium. We were able to get started in minutes and, once <a href="https://twitter.com/mager">Andrew</a> put us on the right track (by pointing us at the experimental but more powerful 1.0 API), never hit a wall or get stuck at all.</p>
<p><strong>Apigee App Services</strong> is indeed a valuable tool: it saved us a lot of time by taking care of storing our data and, more important, exposing it over the internet with no hassle. (The fact that we were even able to interact with it through an Arduino is not trivial.) It also took away the need of building an admin interface for most basic needs. Quoting Diderik</p>
<blockquote><p>Apigee allowed us to get so much done on the first day of the hackathon that we could go home and get some sleep for the night.</p></blockquote>
<h1>How did it go?</h1>
<p>Not bad at all. We managed to win a couple of prizes: each of us won a 6 months premium subscription to Spotify (thanks <a href="https://twitter.com/mager">Andrew</a>!) and a gift certificate courtesy of Apigee (thanks <a href="https://twitter.com/timanglade">Tim</a>!). All in all, we did not build BYOM for the prizes, but we were glad to get them.<br />
The most important thing is that we had great fun coming out with a solution that worked and thinking about how to communicate what seemed so cool to us. We had even more fun seeing what the other teams had built (there were some really brilliant hacks indeed). Isn&#8217;t that what a hackathon should be about?</p>
<h1>Can I see it?</h1>
<p>Sure, you can check the <a href="https://github.com/abahgat/byom">source code</a>. Beware: it&#8217;s hackathon-grade code, so it probably does not look like the clean code you would normally want to write during the day. If you are curious, <a href="http://www.ustream.tv/recorded/27445421">here is a video</a> with Bring Your Own Music and all the other cool hacks built at Kings of Code 2012 Hack Battle. (It is a bit dark, but you get the idea.)</p>
<p>More from us: <a href='http://twitter.com/diderikvw' class='twitter-follow-button' data-show-count='false' data-text-color='#222222' data-link-color='#3783e6'>Follow @diderikvw</a> <a href='http://twitter.com/nldmike' class='twitter-follow-button' data-show-count='false' data-text-color='#222222' data-link-color='#3783e6'>Follow @nldmike</a> <a href='http://twitter.com/raibaz' class='twitter-follow-button' data-show-count='false' data-text-color='#222222' data-link-color='#3783e6'>Follow @raibaz</a> <a href='http://twitter.com/abahgat' class='twitter-follow-button' data-show-count='false' data-text-color='#222222' data-link-color='#3783e6'>Follow @abahgat</a></p>
<p>Thank you guys for the great weekend!</p>
<br />Filed under: <a href='http://blog.abahgat.com/category/software-engineering/coding/'>coding</a> Tagged: <a href='http://blog.abahgat.com/tag/amsterdam/'>Amsterdam</a>, <a href='http://blog.abahgat.com/tag/apigee/'>Apigee</a>, <a href='http://blog.abahgat.com/tag/arduino/'>Arduino</a>, <a href='http://blog.abahgat.com/tag/hack/'>hack</a>, <a href='http://blog.abahgat.com/tag/hackathon/'>hackathon</a>, <a href='http://blog.abahgat.com/tag/nfc/'>nfc</a>, <a href='http://blog.abahgat.com/tag/software/'>software</a>, <a href='http://blog.abahgat.com/tag/spotify/'>Spotify</a>, <a href='http://blog.abahgat.com/tag/technology/'>technology</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/abahgat.wordpress.com/894/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/abahgat.wordpress.com/894/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/abahgat.wordpress.com/894/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/abahgat.wordpress.com/894/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/abahgat.wordpress.com/894/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/abahgat.wordpress.com/894/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/abahgat.wordpress.com/894/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/abahgat.wordpress.com/894/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/abahgat.wordpress.com/894/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/abahgat.wordpress.com/894/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/abahgat.wordpress.com/894/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/abahgat.wordpress.com/894/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/abahgat.wordpress.com/894/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/abahgat.wordpress.com/894/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=894&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.abahgat.com/2012/12/04/story-of-a-hack-bring-your-own-music/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>45.463681 9.188171</georss:point>
		<geo:lat>45.463681</geo:lat>
		<geo:long>9.188171</geo:long>
		<media:content url="http://1.gravatar.com/avatar/7f3c642af40363040510685c7cc1334e?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">abahgat</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2012/12/2012-12-02-13-01-47.jpg" medium="image">
			<media:title type="html">Bring Your Own Music card reader</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2012/12/byomscreenshot.png" medium="image">
			<media:title type="html">A screenshot of the Spotify Jukebox app</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2012/12/2012-12-02-17-33-16.jpg" medium="image">
			<media:title type="html">Hey, look, there is an Arduino in the box!</media:title>
		</media:content>
	</item>
		<item>
		<title>What you should know before moving to Amsterdam</title>
		<link>http://blog.abahgat.com/2012/11/20/what-you-should-know-before-moving-to-amsterdam/</link>
		<comments>http://blog.abahgat.com/2012/11/20/what-you-should-know-before-moving-to-amsterdam/#comments</comments>
		<pubDate>Tue, 20 Nov 2012 12:05:19 +0000</pubDate>
		<dc:creator>Alessandro Bahgat</dc:creator>
				<category><![CDATA[personal]]></category>
		<category><![CDATA[Amsterdam]]></category>
		<category><![CDATA[expat]]></category>
		<category><![CDATA[Netherlands]]></category>
		<category><![CDATA[relocating]]></category>

		<guid isPermaLink="false">http://blog.abahgat.com/?p=848</guid>
		<description><![CDATA[This post is a bit unusual for this blog: a few months ago I moved from Milan to Amsterdam (curiously, four years after my first visit to the city) and gathered some advice from friends and websites in the process. That &#8230; <a href="http://blog.abahgat.com/2012/11/20/what-you-should-know-before-moving-to-amsterdam/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=848&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/bcnbits/327452460/"><img class="aligncenter size-full wp-image-857" title="Amsterdam - photo by MorBCN" alt="Amsterdam houses" src="http://abahgat.files.wordpress.com/2012/11/amsterdam.jpg?w=584&#038;h=390" width="584" height="390" /></a></p>
<p>This post is a bit unusual for this blog: a few months ago I moved from Milan to Amsterdam (curiously, four years after my <a title="How long will it take?" href="http://blog.abahgat.com/2008/11/18/how-long-will-it-take/">first visit to the city</a>) and gathered some advice from friends and websites in the process. That information helped a great deal during my first weeks here and ensured that my move was a smooth one. I believe others in the same situation may benefit from the notes I gathered, so I decided to post them here.</p>
<p>As an EU citizen with a job offer from a company that has an office in the Netherlands, my transition was quite easy, but there were still some aspects that took me a while to figure out: I will try to cover most of them within this post. For everything else, you may find a lot of useful information in the links at the end of this article.</p>
<p><span id="more-848"></span></p>
<h1>Finding an apartment</h1>
<p>I had started looking for apartments to rent a couple of weeks before flying in but soon realized it was an exercise in futility. The rental market is extremely dynamic here: properties that are up for rent one day may be gone the day after and new ones show up daily. Because of the high demand, both agents and landlords tend to ignore messages from anyone who is not already in the city. <strong>Start looking for apartments during the very last days before moving in</strong>: it will give you an idea about the market prices and you will have some chances of getting an appointment to see the places you want to see before they are rented out.</p>
<p>Here a few websites you can start from</p>
<ul>
<li><a href="http://www.funda.nl/">Funda</a> – a website affiliated with the national association of real estate agents, it is one of the most reliable sources as the postings are reviewed and usually backed by an agency. The downside is that it is only in Dutch (you&#8217;d better get used to that), but you can Google Translate it.</li>
<li><a href="http://www.pararius.com/">Pararius</a> – you will generally find almost the same postings you found on Funda, but Pararius is translated in several other languages (I mean the interface: the contents of the posting are likely to be in Dutch, clearly) but sometimes you can find posting by landlords that are not relying on an agency (yet).</li>
<li><a href="http://amsterdam.en.craigslist.org/">Craigslist</a> – less popular here than in the US, it is still possible to find a good number of listings for Amsterdam. Beware, however, that a good fraction of them are from scammers after your money or your personal details. If you are willing to invest some time to sift though the garbage, you may find some good deal without having to rely on an agency. You may use this <a href="https://ifttt.com/recipes/67028">IFTTT recipe</a> to get email notifications of new posts straight in your inbox.</li>
</ul>
<p>While there are other websites, they are likely to have the same information you can find on Funda and Pararius.</p>
<p>Once you are in Amsterdam you can visit agencies in the area(s) you are considering and tell them your requirements and your expectations. Do not overdo by contacting too many of them, though: most agencies have access to the same properties to rent, and they it is not unlikely that they will propose you the same properties you saw yourself on Funda.</p>
<p>Make sure you visit the areas where you are considering renting: while the city is small and commute is generally significantly shorter than in other European cities, each neighborhood has its own character and perks. Ideally, you will want to see what the place looks like during day and night.</p>
<p>Depending on where you live now, there are some details you may not pay attention to because they are not as relevant in the city you come from. A few examples</p>
<ul>
<li><strong>tram lines</strong> – check whether there is a tram line running right below your window and the area is popular with tourists. The combination of those two is that you will frequently hear the loud bell noise conductors use to <em>scare people away</em> (literally) of the tracks. Most houses are built with bedrooms away from the road so the noise may be less of a problem at night, but still you want to know what to expect.</li>
<li><strong>bike stands</strong> – some neighborhoods seem to have a chronic shortage of bike stands. While usually you may be able to chain your bike to a signpost or a tree, it may still be difficult to find a place to leave it if you come back late at night.</li>
<li><strong>parking</strong> – if you are planning on driving a car, bear in mind that finding a place to park in Amsterdam is generally challenging, and usually it is not free. You can apply for a parking permit for the neighborhood you live in, but there may be a wait list several months long.</li>
<li><strong>shops</strong> – since there aren&#8217;t many malls but plenty of smaller supermarkets, you will not be shopping for groceries once per week, but you will find it easier to make smaller purchases more frequently. Surprisingly, butcher shops, bakeries and greengrocers are cheaper (and the food you find there often tastes better) than supermarkets. Having shops close to your place will make your file easier in this sense.</li>
</ul>
<p>Once you find a place you like, it is time to look at how contracts work.</p>
<h1>Understanding the contract</h1>
<p>The laws regarding renting in the Netherlands are very protective of tenants. The market is strictly regulated and aspects like the conditions for breaking the contract, the maximum rent and standard contract conditions have to follow certain rules. I found <a href="http://www.expatica.com/nl/housing/renting/Fair-rent-for-all-in-the-Netherlands_15396.html">this article</a> to be a good source of information about how the whole system works.</p>
<p>Two important points about the regulations are that, under normal circumstances:</p>
<ul>
<li>only the tenant is allowed to break a contract,</li>
<li>&#8220;temporary&#8221; contracts are extremely uncommon.</li>
</ul>
<p>There is a points system according to which every apartment is given a score depending on many different factors (condition, location and many others), and that score determines the maximum price a landlord is allowed to charge. However, as soon as the score of an apartment exceeds the number points that correspond to about € 650, that apartment is considered to belong to &#8220;free market&#8221; and the score is not really important anymore. That explains why there is almost no apartment in the € 650 &#8211; 900 range: apartments that rent for less than € 650 are usually given to locals who have the patience to apply for rent and go through a wait list, and then there is a second market for expats, who don&#8217;t know the system or can&#8217;t afford to wait months in order to secure a fair rent. If you have a contract and you are not sure whether it is fair there is a non-profit organization, called <a href="http://www.wswonen.nl/">Wijksteunpunten Wonen</a>, that can help you: its members will review your contract and give you advice on how to proceed.</p>
<h1>Understanding rent costs</h1>
<p>Rent prices in the Netherlands can be <strong>exclusive or </strong><strong>inclusive of expenses</strong>. Exclusive prices work as you expect: you pay the landlord the base rent only, and you have to pay all the service costs yourself. With an inclusive rent, you pay an estimated amount in addition to the base rent as an advance payment for service costs (like energy and gas). In this case, the landlord is expected to keep an account of the actual costs and settle the bill at the end of the each year (refunding you the difference if you paid more or asking you to pay the difference if you paid less), so that you will not have to take care of setting up the contracts for energy, gas and the rest.</p>
<p>Regardless which option you choose, you will also need to consider that you will be expected to pay all the bills that are in registered in your name (like the taxes for water and for waste disposal). Fees often depend on where you live, you may spend about € 300 per year in addition to the rent. You will start getting those bills by the moment you register as a resident (see the following sections) in your apartment.</p>
<p>If you rely on an agency, be prepared to pay a commission of roughly one month&#8217;s rent at least (generally it is calculated on the base rent, excluding expenses, plus 19% tax). This will effectively mean that you will need to be able to pay roughly three times the rent upon entering the apartment (the commission, the first month, and one month&#8217;s rent as a deposit).</p>
<h1>Looking for shared accommodation</h1>
<p>I have been focusing since the beginning in finding an apartment, but there certainly are plenty of options if you want to share a place with someone else. The two options I have been (shortly) considering are <a href="http://amsterdam.en.craigslist.org/">Craigslist</a> (again, the same considerations in the previous section apply here) and <a href="http://kamernet.nl/">Kamernet</a>, a well-known website dedicated almost exclusively to rooms for rent. Even more than with apartments, being already in Amsterdam helps: you want to meet your possible flatmates in person and, more important, they want to meet you before making a decision. Do not make the mistake of underestimating the reach of your friends and acquaintances: they may know someone who is looking for a flatmate.</p>
<h1>Registering as a resident and obtaining a BSN</h1>
<p>Getting a BSN (<a title="National identification number" href="http://en.wikipedia.org/wiki/National_identification_number#Netherlands">Burgerservicenummer</a>, a sort of social security number) is a necessary step if you are going to live in the Netherlands: you will need it to get your health insurance, to open a bank account and your employer will need it before they can start paying your salary.</p>
<p><strong>You will get a BSN by registering as a resident in Amsterdam</strong> and you are supposed to do so within the fist five days of arrival if you are planning on staying more than four months. If you are a <a href="#high-skilled-migrants"><em>Highly Skilled Migrant</em></a> the process is extremely simple and you can take care of everything you need in one single day at the <a href="http://www.iamsterdam.com/en-GB/living/Expatcenter">Expatcenter</a>, provided that you asked for appointment <a href="http://www.iamsterdam.com/en-GB/living/Expatcenter/make-an-appointment/Online-appointment-form-EU-citizens">here</a> (applies only to EU citizens).</p>
<p>You will need to provide:</p>
<ul>
<li>your passport (an ID card may suffice, depending on your nationality)</li>
<li>a rental/tenancy contract or a home purchase agreement</li>
</ul>
<p>Note that, if you have not found permanent accommodation by the time you need to register you may still <strong>register at your employer&#8217;s address</strong>. Doing so, however, requires you company to provide a stamped registration form that explicitly authorizes you to do so. Note that this is considered by all means a contingency situation, and you <strong>will be required to register at your permanent address within three months</strong>. If you have a work contract already you can get a registration certificate (a sticker on your passport) as well: you will need it if you want to purchase an apartment or vote, for example. Note that to finalize registration you will have to present your birth (and marriage, if applicable) certificate in long form. You will not need this immediately as you can present it later, but if you have not left your country already, you can get one in advance.</p>
<p>Note that if you are not an EU citizen and/or not have a work contract yet the procedure may differ (even significantly), but luckily the IND (the Immigration and Naturalisation Service) has a <a href="http://english.ind.nl/residencewizard/">wizard</a> you can use to discover what you have to do to get a residence permit depending on your nationality and other conditions. The rules are quite complex but the wizard helps a lot: I suggest you to go through it.</p>
<p>Registering as a resident will kickstart a series of processes that usually end up in you having to pay some money: taxes on water and waste disposal are usually computed from the day you registered and bills will follow you a few days after you moved in.</p>
<p>Note that you may also want to register at you local embassy/consulate as a national living abroad. Specifics depend on your country, but the process is usually straightforward.</p>
<h1><a name="high-skilled-migrants"></a>Highly Skilled Migrants and the 30% ruling</h1>
<p>The Netherlands apply a particularly attractive policy to foreign workers that meet certain criteria: if you are recruited or transferred from abroad by a Dutch company and have a skill set that is rare or inexistant in the country you may be eligible to a tax reduction.</p>
<p>In practice, you can apply for the ruling if you earn more than a certain amount (at the time of writing it means € 50,000 if you are older than 30, € 38,000 otherwise) and your employer is willing to certify that you possess rare skills. Note that you can not present the application yourself: your employer has to do it.</p>
<p>If you present your application within 4 months of the start of employment the tax reduction is retroactive, otherwise it applies from the month after the one you filed your request. If your application is accepted, you will pay at most a bit more than 36% in taxes and will be eligible to a few benefits.  You can find more details on the ruling <a href="http://www.iamsterdam.com/en-GB/living/official-matters/thirty-percent-ruling">here</a>.</p>
<h1>Opening a bank account</h1>
<p>Opening a bank account is quite easy: there are less banks here in the Netherlands than there are in other countries and the difference in offering is not significant. If you do not know Dutch yet, you will be interested in banks that are able to deal with expats. The challenge is not in the staff (again, anyone is able to speak good English here) but in the correspondence: you will want to receive communications in a language you understand. <a href="http://abnamro.nl/expats">ABN Amro</a> is quite good in that respect (even though you will still struggle to find some documents in English) and I know that Rabobank has a special expat desk, but I am sure that you may the same with other banks as well. Just ask what they offer to expats and do not assume anything.</p>
<p>Once you made your choice, you will need:</p>
<ul>
<li>your BSN,</li>
<li>your passport,</li>
<li>(usually) a copy of your contract or a letter of employment.</li>
</ul>
<p>Note that if you don&#8217;t have a BSN but you still need to open a bank account, the ABN Amro branch at Schipol Airport may be able to open one for you if you commit to communicate them your BSN as soon as you obtain one. Unfortunately I did not know that at the time, otherwise things would have been much easier.</p>
<h1>Getting your health insurance</h1>
<p>Health insurance in the Netherlands is mandatory, even if you already have a one in your country of origin. You will need to get at least a basic insurance package (around € 100 per month) for your company of choice. The contents of a basic package are regulated by law, insurance companies are not allowed to charge different fees depending on demographics and are not allowed to refuse assistance, regardless of pre-existing conditions. Unlike what happens in other countries, you have to pay for your insurance but your employer may provide additional coverage as part of the compensation package. There are many different insurance companies in the Netherlands but, if you are going to get any additional coverage as part of your compensation, you will probably sign with the ones your employer has agreements with.</p>
<h1>Moving around</h1>
<p>Amsterdam is a small city, especially compared with Milan, where I used to live until a few months ago. Commute is shorter and there are many different options for moving around.</p>
<h2>Public transport</h2>
<p>Public transport in Amsterdam is excellent: the network of trams, buses and subway allows you to get to most destinations in a reasonable amount of time and with a limited number of changes. While the regular service stops a bit after midnight, night buses are still frequent enough to be a realistic option (for everything else, there are taxis). You can get public transport tickets at vending machines that you can find at in all the subway stations, but you can purchase them on board of trams and buses as well. If you do so, you are usually surprised by the costs: € 2.70 for a 1-hour ticket (you can use it as many times as you want) and € 7.50 for a day ticket.</p>
<p>It is indeed a lot, but there are ways to pay less. If you get an <a href="http://www.ov-chipkaart.nl/">OV-chipkaart</a> you will pay as you go: the amount will be charged will depend on the distance you travel (with an average of about € 1.50 for a trip across the city). You will have to <strong>check by tapping your card against an RFID reader once you board and check out once you get off</strong>.</p>
<p>The card itself costs € 7.50 and it can be topped up online, at vending machines at stations and supermarkets. You can get an anonymous card or a personal one which will have your name and photo on it. The advantage of the latter is that you will be able to use it for seasonal passes or have it top up itself automatically with credit from your bank account.</p>
<p>You can travel on trains across all the Netherlands using the same chipkaart you use for public transport in the city, you will only have to visit one of the <a href="http://www.ns.nl/">NS</a> vending machines (the yellow ones) and select your preference between 1st and 2nd class.<strong><br />
</strong></p>
<h2>Biking</h2>
<p>Bikes are a symbol for the Netherlands, and you will find Amsterdam to be perfectly designed for cyclists. Locals prefer biking to any other alternative, and you will find people driving their bike to work regardless of the weather. Once you will have spent more than a few days here you will be inclined to do the same: if you spend most of your time within the city, biking is faster than any alternative.</p>
<p>Get a sturdy bike, as it will need to withstand harsh weather conditions. Do not buy a fancy bike, as it will get more than a few scratches when placed on bike racks (even if you pay attention to avoid that, people placing their bike next to yours will not be as careful as you). Buy a good lock, even if it costs a lot compared to the value of the bike, especially if you leave your bike on the street at night: crime rate in Amsterdam is lower than in other cities, but <strong>bike theft is incredibly common</strong>.</p>
<p><span style="color:#000000;font-weight:bold;">Driving</span></p>
<p>Owning a car in Amsterdam is expensive: the road tax is quite high and parking is very limited (bear in mind that even if you have a permit to park in your neighborhood, you will likely need to pay if you drive to another). Given the way the canals affect the road plan, traversing the city by car is generally not the quickest option. Should you decide to bring your own car, you will have to follow a strict procedure: you can find more information <a href="http://www.expatica.com/nl/leisure/travel_tourism/a-guide-to-car-use-in-the-netherlands-8855_9070.html">here</a>. Depending on the country you come from, you may also have to <a href="http://www.iamsterdam.com/en-GB/living/official-matters/driving-licence">exchange your driving licence</a> with a Dutch one or get a new one.</p>
<h2>Useful resources</h2>
<p>I summarized all the information in my possession but I have not covered some topics that may still be of interest to you. The links in this section should provide you with all the information you need.</p>
<ul>
<li><a href="http://www.iamsterdam.com/en-GB/living">I amsterdam</a> – by far the most complete and accurate source of information about what you need to know about moving to Amsterdam</li>
<li><a href="http://english.ind.nl/">IND</a> – the official website of the Immigration and Naturalisation Service</li>
<li><a href="http://www.internations.org/amsterdam-expats/guide/moving-to-amsterdam-15398">Moving to Amsterdam</a> – a useful section on Internations that contains some more useful information (access is restricted to members, unfortunately)</li>
</ul>
<p>In addition to that, if you are already in the Netherlands or can plan a visit before moving, consider visiting the <a href="http://www.iamsterdam.com/en-GB/living/Expatcenter/contact-us">Expatcenter</a> in person: they will be able to help you and give a clear picture about what you need to do in order to move here.</p>
<div class="googlemaps"><iframe width="600" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=Strawinskylaan 1, 1077 XW Amsterdam, Netherlands (Expatcenter)&amp;aq=&amp;sll=52.340368,4.874112&amp;sspn=0.008692,0.015836&amp;gl=us&amp;doflg=ptk&amp;ie=UTF8&amp;hnear=Strawinskylaan 1, 1077 XW Zuideramstel, Amsterdam, Noord-Holland, The Netherlands&amp;t=m&amp;ll=52.345879,4.873381&amp;spn=0.018352,0.051498&amp;z=14&amp;iwloc=A&amp;output=embed"></iframe><br /><small><a href="https://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=Strawinskylaan 1, 1077 XW Amsterdam, Netherlands (Expatcenter)&amp;aq=&amp;sll=52.340368,4.874112&amp;sspn=0.008692,0.015836&amp;gl=us&amp;doflg=ptk&amp;ie=UTF8&amp;hnear=Strawinskylaan 1, 1077 XW Zuideramstel, Amsterdam, Noord-Holland, The Netherlands&amp;t=m&amp;ll=52.345879,4.873381&amp;spn=0.018352,0.051498&amp;z=14&amp;iwloc=A&amp;source=embed" style="text-align:left">View Larger Map</a></small></div>
<h1>Acknowledgements <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </h1>
<p>Most of the information in this article comes from personal research but, even more, by friends that have been through the experience of relocating to Amsterdam. Their precious advice helped me making my move here smooth and painless. <strong>Thank you Andrea, Angelo, Matias, Nicola.</strong></p>
<hr />
<p><span style="color:#999999;font-size:smaller;">Top photograph CC by <a href="http://www.flickr.com/photos/bcnbits/327452460/">MorBCN</a></span></p>
<br />Filed under: <a href='http://blog.abahgat.com/category/personal/'>personal</a> Tagged: <a href='http://blog.abahgat.com/tag/amsterdam/'>Amsterdam</a>, <a href='http://blog.abahgat.com/tag/expat/'>expat</a>, <a href='http://blog.abahgat.com/tag/netherlands/'>Netherlands</a>, <a href='http://blog.abahgat.com/tag/relocating/'>relocating</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/abahgat.wordpress.com/848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/abahgat.wordpress.com/848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/abahgat.wordpress.com/848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/abahgat.wordpress.com/848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/abahgat.wordpress.com/848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/abahgat.wordpress.com/848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/abahgat.wordpress.com/848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/abahgat.wordpress.com/848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/abahgat.wordpress.com/848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/abahgat.wordpress.com/848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/abahgat.wordpress.com/848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/abahgat.wordpress.com/848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/abahgat.wordpress.com/848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/abahgat.wordpress.com/848/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=848&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.abahgat.com/2012/11/20/what-you-should-know-before-moving-to-amsterdam/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<georss:point>52.369563 4.849441</georss:point>
		<geo:lat>52.369563</geo:lat>
		<geo:long>4.849441</geo:long>
		<media:thumbnail url="http://abahgat.files.wordpress.com/2012/11/amsterdam.jpg?w=150" />
		<media:content url="http://abahgat.files.wordpress.com/2012/11/amsterdam.jpg?w=150" medium="image">
			<media:title type="html">Amsterdam - photo by MorBCN</media:title>
		</media:content>

		<media:content url="http://1.gravatar.com/avatar/7f3c642af40363040510685c7cc1334e?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">abahgat</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2012/11/amsterdam.jpg" medium="image">
			<media:title type="html">Amsterdam - photo by MorBCN</media:title>
		</media:content>
	</item>
		<item>
		<title>On desire paths… and software</title>
		<link>http://blog.abahgat.com/2012/07/23/on-desire-paths-and-software/</link>
		<comments>http://blog.abahgat.com/2012/07/23/on-desire-paths-and-software/#comments</comments>
		<pubDate>Mon, 23 Jul 2012 13:10:00 +0000</pubDate>
		<dc:creator>Alessandro Bahgat</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[desire paths]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[shortcuts]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://blog.abahgat.com/?p=773</guid>
		<description><![CDATA[Desire paths are a common pattern in landscape design: born as simple footpaths when someone takes a more direct, shorter way to their destination, they often evolve to proper paths and roads after a while. While architects and garden planners &#8230; <a href="http://blog.abahgat.com/2012/07/23/on-desire-paths-and-software/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=773&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Desire_path"><strong>Desire paths</strong></a> are a common pattern in landscape design: born as simple footpaths when someone takes a more direct, shorter way to their destination, they often evolve to proper paths and roads after a while.</p>
<div id="attachment_821" class="wp-caption aligncenter" style="width: 594px"><a href="http://www.olifantenpaadjes.nl"><img class="size-full wp-image-821" title="Desire Path" src="http://abahgat.files.wordpress.com/2012/05/olifantenpaadje1.png?w=584&#038;h=466" alt="Desire Path" width="584" height="466" /></a><p class="wp-caption-text">A man walking through a <em>desire path</em>.<br />Photo: <a href="http://www.olifantenpaadjes.nl">Jan-Dirk van der Burg</a></p></div>
<p>While architects and garden planners often regard those paths as unesthetic and try to prevent them by using fences and the well known <em>keep off the grass</em> signs, desire paths tell a lot about the needs of people traversing a space. Some urban planners even use those paths to guide them when revising the original design by adding new roads or altering the original project.</p>
<p>Desire paths are important because they give insights about points where the original design is lacking from a functional point of view. Sure, they may not be as pleasant to the eye as a perfect, regular lawn, but they often show a more effective way to solve a problem: getting from one point in physical space to another.</p>
<p>I am posting about landscape design here because the same phenomenon can occur when observing the way users interact with software products. Users often compensate for missing features by and taking shortcuts and by adopting workarounds which, eventually, <strong>leave a persistent mark on the system they are using</strong>.</p>
<p><span id="more-773"></span>Here a couple of examples.</p>
<p>The first is a historical example. In 2007, allegedly following a convention proposed by Chris Messina, a group of Twitter users started using the <strong>#</strong> symbol to specify tags associated to their tweets.</p>
<blockquote class='twitter-tweet tw-align-center' lang='en'><p>how do you feel about using # (pound) for groups. As in <a href="http://twitter.com/search?q=%23barcamp" title="#barcamp">#barcamp</a> [msg]?</p>&mdash; <br />Chris Messina&#8482; (@chrismessina) <a href='http://twitter.com/#!/chrismessina/status/223115412' data-datetime='2007-08-23T19:25:10+00:00'>August 23, 2007</a></blockquote>
<p>The habit spread fast among the community, without any kind of central direction, and after a while Twitter integrated support for <a title="What Are Hashtags (&quot;#&quot; Symbols)?" href="https://support.twitter.com/articles/49309-what-are-hashtags-symbols">hashtags</a> as we know them today. This is one of the most significant examples of desire paths at work: users figured out a smart way to use a system that was eventually promoted to a full-fledged feature.</p>
<p><a href="http://abahgat.files.wordpress.com/2012/07/githubplusone.png"><img class="pull alignright  wp-image-831" title="+1s on GitHub" src="http://abahgat.files.wordpress.com/2012/07/githubplusone.png?w=82&#038;h=460" alt="A streak of +1 comments on GitHub" width="82" height="460" /></a>The second example is way more recent, and you may have noticed it if you spent some time navigating the open issues of some popular open source project hosted on GitHub.</p>
<p>The more popular the project, the more easy it is to find issues with never-ending threads of comments like the like the one on the right side of this page (click <a href="http://abahgat.files.wordpress.com/2012/07/githubplusone.png">here</a> to see it in full scale). At a first glance, those issues seem to be extremely severe or controversial to cause such discussions, but the truth is quite different.</p>
<p>On a closer look, all those comments do not carry much meaning: they often are just a long list of comments consisting in (verbatim) <em>&#8220;+1</em>&#8221; (and occasionally some variations on the same theme). Those types of comments have become a standard way for users to communicate to the development team that some issue is important to them.</p>
<p>While the intention is understandable, this is often perceived by some a &#8220;bad&#8221; way to use comments on issues. Regardless of what opinions we may have on that point, it is certain that this behavior is another clear example of desire paths at work. Users want a quick way to let developers know they care for issues: comments were not designed for this purpose, but people figured out that they can be used for that too.</p>
<p>And then who knows, GitHub may end up adding a &#8220;like&#8221; button equivalent on their issues.</p>
<p>Paying attention to patterns like these in software can give us important insights about features that would benefit our users if we were to implement them. They are like <strong>validated</strong> user needs, highlighting an area in which our product may be lacking.</p>
<br />Filed under: <a href='http://blog.abahgat.com/category/design/'>design</a> Tagged: <a href='http://blog.abahgat.com/tag/design/'>design</a>, <a href='http://blog.abahgat.com/tag/desire-paths/'>desire paths</a>, <a href='http://blog.abahgat.com/tag/github/'>GitHub</a>, <a href='http://blog.abahgat.com/tag/shortcuts/'>shortcuts</a>, <a href='http://blog.abahgat.com/tag/twitter/'>Twitter</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/abahgat.wordpress.com/773/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/abahgat.wordpress.com/773/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/abahgat.wordpress.com/773/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/abahgat.wordpress.com/773/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/abahgat.wordpress.com/773/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/abahgat.wordpress.com/773/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/abahgat.wordpress.com/773/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/abahgat.wordpress.com/773/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/abahgat.wordpress.com/773/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/abahgat.wordpress.com/773/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/abahgat.wordpress.com/773/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/abahgat.wordpress.com/773/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/abahgat.wordpress.com/773/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/abahgat.wordpress.com/773/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=773&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.abahgat.com/2012/07/23/on-desire-paths-and-software/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<georss:point>45.463681 9.188171</georss:point>
		<geo:lat>45.463681</geo:lat>
		<geo:long>9.188171</geo:long>
		<media:thumbnail url="http://abahgat.files.wordpress.com/2012/05/olifantenpaadje1.png?w=150" />
		<media:content url="http://abahgat.files.wordpress.com/2012/05/olifantenpaadje1.png?w=150" medium="image">
			<media:title type="html">Desire Path</media:title>
		</media:content>

		<media:content url="http://1.gravatar.com/avatar/7f3c642af40363040510685c7cc1334e?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">abahgat</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2012/05/olifantenpaadje1.png" medium="image">
			<media:title type="html">Desire Path</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2012/07/githubplusone.png?w=53" medium="image">
			<media:title type="html">+1s on GitHub</media:title>
		</media:content>
	</item>
		<item>
		<title>Can we get rid of unknown phone numbers?</title>
		<link>http://blog.abahgat.com/2012/04/30/can-we-get-rid-of-unknown-phone-numbers/</link>
		<comments>http://blog.abahgat.com/2012/04/30/can-we-get-rid-of-unknown-phone-numbers/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 15:58:08 +0000</pubDate>
		<dc:creator>Alessandro Bahgat</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[identity]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[phone numbers]]></category>

		<guid isPermaLink="false">http://blog.abahgat.com/?p=783</guid>
		<description><![CDATA[For most people of my generation, the phone system is broken. And it is not all about costs or devices: as Andreas Klinger once said, telephone numbers are a disgrace to our generation. His main point, one I agree with, &#8230; <a href="http://blog.abahgat.com/2012/04/30/can-we-get-rid-of-unknown-phone-numbers/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=783&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>For most people of my generation, the phone system is broken. And it is not all about costs or devices: as Andreas Klinger once said, <a href="http://klinger.io/post/17313437389/my-addressbook-keep-it-telephone-numbers-are-a">telephone numbers are a disgrace to our generation</a>.</p>
<p>His main point, one I agree with, is the disconnect between phone numbers and the identity of the people behind them. He says:</p>
<blockquote><p>I have friends that have three numbers in their signature. US, UK, local-european-country-no-one-knows. This whole system assumes I want to call their cellphones. Which is <strong>not</strong> true &#8211; I want to call them. The people behind that numbers, simcards and devices…</p></blockquote>
<p>Andreas stresses the need for a means to reach people regardless of where they are, what phone operator they are using or other details that are insignificant from the point of view of the caller.</p>
<p>In the era of email and, now, social networks, phone numbers are a legacy of the old days. Especially since the introduction of personal mobile phones, they often constitute an unnecessary level of abstraction between us and the person we are trying to reach.<br />
As Andreas points out, what modern phones would need is an identity system to abstract phone numbers out of the way, just like <a href="http://en.wikipedia.org/wiki/Domain_Name_System">DNS</a> does with IP addresses.</p>
<p>While this is a significant problem that needs solving, it would require some infrastructure to be in place, as you can see by looking at the scenarios explored in the <a href="http://klinger.io/post/17313437389/my-addressbook-keep-it-telephone-numbers-are-a">post</a>.</p>
<p>However, there is a smaller problem that can actually be addressed with resources that already are in place. And I am sure we all experienced it at least once.</p>
<p><span id="more-783"></span>Consider what happens when you get a phone call from a number you don&#8217;t know, and you are not able to answer it. Your phone will display an entry in its call log, and it will just list the number and the time of the call. You will likely not have enough information to decide whether or when to return the call.</p>
<p>Email is different, even just the format of an email address, the <strong>name@organization</strong> pair we are now used to, can be used to communicate something. Just seeing newsletter@somestore.com or orders@shop.com as a sender can give us an idea about what the message will be about.</p>
<p>Social networks are even better at this: whenever we get a message from someone, we see their name, their avatar picture and some profile information that may help in recognizing them if we already met them, or understand who they are in case we do not know them.</p>
<p>Compared to the previous scenarios, the impersonal string of numbers we see when we get a phone call from someone can be quite annoying, to the point that I know a significant number of people who are not at ease when they need to return a call and do not know who will be at the other end of the line.</p>
<h1>Can we fix this?</h1>
<p>Modern smartphones (iPhones and my Galaxy Nexus, for example) attempt to provide their users with a bit more information when they receive a call from a number that is not associated to any contact: they display the country or region of the caller under the phone number in the call log.</p>
<div id="attachment_786" class="wp-caption aligncenter" style="width: 375px"><a href="http://abahgat.files.wordpress.com/2012/04/callstate.png"><img class=" wp-image-786      " title="State of the caller on Android" src="http://abahgat.files.wordpress.com/2012/04/callstate.png?w=365&#038;h=158" alt="" width="365" height="158" /></a><p class="wp-caption-text">Ice Cream Sandwich displays the state of the caller when displaying unknown numbers in the call log</p></div>
<p>Seeing this behavior on my Android phone, I started to wonder whether that system could be generalized to provide an even better service.</p>
<p>In my case, the contacts on my phone are integrated with my GMail address book and Google+ circles: whenever I add a new friend, their name shows up among my phone contacts along with their phone number, if they chose to share it.</p>
<p>What I would love to have is a system where, whenever filling in their own Google+ profile, users could choose to <strong>allow the people they call to retrieve their profile given their phone number</strong>. Whenever the phone of the receiver is about to display their call entry in the log, the device could lookup the phone number on the Google+ directory and retrieve the user profile corresponding to that number. Verified<a style="font-size:xx-small;vertical-align:super;" href="#verification">1</a> owners of a phone number could choose whether they want to give the possibility to lookup their profile given their number to <strong>anyone</strong> or <strong>only to the people they tried to call recently</strong>.</p>
<p>I mentioned Android and Google+ because Google&#8217;s position in both mobile and social sectors gives them access to all the components needed to have such a system in place. Of course, a solution like this could be implemented virtually by anyone, but it would be a lot more complex to an outsider to build such a system, and the costs would probably exceed the benefits.</p>
<p>If a system like this were to be implemented by a significant number of parties and adopted by enough users, it would probably be another move towards a consistent and healthy approach towards proper identity management.</p>
<hr />
<p><a name="verification"></a><span style="color:#999999;">1. Verification of the phone numbers is important as it necessary to prevent scams and frauds.</span></p>
<br />Filed under: <a href='http://blog.abahgat.com/category/design/'>design</a> Tagged: <a href='http://blog.abahgat.com/tag/android/'>Android</a>, <a href='http://blog.abahgat.com/tag/identity/'>identity</a>, <a href='http://blog.abahgat.com/tag/iphone/'>iphone</a>, <a href='http://blog.abahgat.com/tag/mobile/'>mobile</a>, <a href='http://blog.abahgat.com/tag/phone-numbers/'>phone numbers</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/abahgat.wordpress.com/783/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/abahgat.wordpress.com/783/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/abahgat.wordpress.com/783/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/abahgat.wordpress.com/783/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/abahgat.wordpress.com/783/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/abahgat.wordpress.com/783/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/abahgat.wordpress.com/783/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/abahgat.wordpress.com/783/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/abahgat.wordpress.com/783/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/abahgat.wordpress.com/783/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/abahgat.wordpress.com/783/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/abahgat.wordpress.com/783/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/abahgat.wordpress.com/783/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/abahgat.wordpress.com/783/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=783&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.abahgat.com/2012/04/30/can-we-get-rid-of-unknown-phone-numbers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>45.463681 9.188171</georss:point>
		<geo:lat>45.463681</geo:lat>
		<geo:long>9.188171</geo:long>
		<media:content url="http://1.gravatar.com/avatar/7f3c642af40363040510685c7cc1334e?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">abahgat</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2012/04/callstate.png" medium="image">
			<media:title type="html">State of the caller on Android</media:title>
		</media:content>
	</item>
		<item>
		<title>Preventing (some) duplicate bug reports in Redmine</title>
		<link>http://blog.abahgat.com/2012/04/20/preventing-some-duplicate-bug-reports-in-redmine/</link>
		<comments>http://blog.abahgat.com/2012/04/20/preventing-some-duplicate-bug-reports-in-redmine/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 11:24:16 +0000</pubDate>
		<dc:creator>Alessandro Bahgat</dc:creator>
				<category><![CDATA[software engineering]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[code52]]></category>
		<category><![CDATA[issue trackers]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Redmine]]></category>

		<guid isPermaLink="false">http://blog.abahgat.com/?p=775</guid>
		<description><![CDATA[A while ago I wrote about a few problems we were having with the way our issue tracker was misused and concluded that the tools we use have a crucial role in directing our behavior towards good or bad behavior &#8230; <a href="http://blog.abahgat.com/2012/04/20/preventing-some-duplicate-bug-reports-in-redmine/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=775&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A while ago I wrote about a <a title="We need smarter issue trackers" href="http://blog.abahgat.com/2012/01/09/we-need-smarter-issue-trackers/">few problems</a> we were having with the way our issue tracker was misused and concluded that the tools we use have a crucial role in directing our behavior towards good or bad behavior patterns.</p>
<p>One of the major pain points I mentioned was linked to the many duplicate issues we were seeing and <a title="We need smarter issue trackers" href="http://blog.abahgat.com/2012/01/09/we-need-smarter-issue-trackers#duplicates">listed one possible solution</a> to reduce the number of duplicate issues that were being raised. After reading my post, my friend <a href="http://www.raibaz.com">Mattia</a> came to me saying &#8220;<em>Good point, why don&#8217;t we just build it?</em>&#8220;. Well, we did.</p>
<p><span id="more-775"></span>After a few weeks spent coding in our spare time, we released <a href="https://github.com/abahgat/redmine_didyoumean/wiki"><strong>Did you mean?</strong></a>, a Redmine plugin designed to warn users before they enter duplicate issues. It does so by performing a search among existing issues right before users submit new ones. The search is based on the issue subject and it is done in the background, in an attempt to make the process as effortless as possible to users. If you are familiar with StackOverflow, you will recognize it as the same strategy.</p>
<p style="text-align:center;"><a href="http://abahgat.files.wordpress.com/2012/04/dym.png"><img class="aligncenter  wp-image-776" style="border-style:initial;border-color:initial;border-image:initial;border-width:0;" title="Did you mean?" src="http://abahgat.files.wordpress.com/2012/04/dym.png?w=584&#038;h=319" alt="A screenshot of the Redmine plugin" width="584" height="319" /></a></p>
<p>A couple of months have passed since then, but Code52&#8242;s initiative <a href="http://code52.org/show-and-tell.html">Show and Tell</a> made me look in retrospective at what we accomplished.</p>
<p>We discovered that <strong>the problems we were facing in managing issues were more common than we imagined</strong>. We had great fun in developing the Redmine plugin, but we were surprised when other users started voluntarily contributing with localizations in their language and tips about how to make it better: we just released version <a title="Downloads for &quot;Did you mean?&quot;" href="https://github.com/abahgat/redmine_didyoumean/downloads">1.1.0</a>, which features English, Bulgarian, German, Spanish, Italian, and Chinese.<br />
The experience made us even more enthusiast about Open Source: the saying that you should start by &#8220;<em>scratching your own itch</em>&#8221; is true indeed.<strong> If you build something that really solves your problem, chances are it will be useful to someone else as well.</strong></p>
<p>You can find the plugin on <a href="https://github.com/abahgat/redmine_didyoumean">GitHub</a>, and if you want to help us, please do! We could use more localizations and some help in making the search work better.</p>
<br />Filed under: <a href='http://blog.abahgat.com/category/software-engineering/'>software engineering</a> Tagged: <a href='http://blog.abahgat.com/tag/bug/'>bug</a>, <a href='http://blog.abahgat.com/tag/code52/'>code52</a>, <a href='http://blog.abahgat.com/tag/issue-trackers/'>issue trackers</a>, <a href='http://blog.abahgat.com/tag/open-source/'>open source</a>, <a href='http://blog.abahgat.com/tag/redmine/'>Redmine</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/abahgat.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/abahgat.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/abahgat.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/abahgat.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/abahgat.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/abahgat.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/abahgat.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/abahgat.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/abahgat.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/abahgat.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/abahgat.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/abahgat.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/abahgat.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/abahgat.wordpress.com/775/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=775&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.abahgat.com/2012/04/20/preventing-some-duplicate-bug-reports-in-redmine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>45.463681 9.188171</georss:point>
		<geo:lat>45.463681</geo:lat>
		<geo:long>9.188171</geo:long>
		<media:thumbnail url="http://abahgat.files.wordpress.com/2012/04/dym.png?w=150" />
		<media:content url="http://abahgat.files.wordpress.com/2012/04/dym.png?w=150" medium="image">
			<media:title type="html">A screenshot of the Redmine plugin</media:title>
		</media:content>

		<media:content url="http://1.gravatar.com/avatar/7f3c642af40363040510685c7cc1334e?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">abahgat</media:title>
		</media:content>

		<media:content url="http://abahgat.files.wordpress.com/2012/04/dym.png" medium="image">
			<media:title type="html">Did you mean?</media:title>
		</media:content>
	</item>
		<item>
		<title>Do languages shape IDEs or IDEs shape languages?</title>
		<link>http://blog.abahgat.com/2012/03/26/do-languages-shape-ides-or-ides-shape-languages/</link>
		<comments>http://blog.abahgat.com/2012/03/26/do-languages-shape-ides-or-ides-shape-languages/#comments</comments>
		<pubDate>Mon, 26 Mar 2012 16:20:50 +0000</pubDate>
		<dc:creator>Alessandro Bahgat</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[ides]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[netbeans]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Sublime Text]]></category>
		<category><![CDATA[verbosity]]></category>

		<guid isPermaLink="false">http://blog.abahgat.com/?p=731</guid>
		<description><![CDATA[I spend most of my days at work on powerful IDEs like Eclipse or Netbeans, tools so advanced in functionalities that their feature lists span over several pages. Their power, however, has its own drawbacks: their memory consumption is measured &#8230; <a href="http://blog.abahgat.com/2012/03/26/do-languages-shape-ides-or-ides-shape-languages/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=731&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><img class="zemanta-img-inserted zemanta-img-configured alignleft" style="border-style:initial;border-color:initial;border-image:initial;border-width:0;margin:10px;" title="Duke, the Java Mascot, in the waving pose. Duk..." alt="Duke, the Java Mascot, in the waving pose. Duk..." src="http://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Wave.svg/226px-Wave.svg.png" width="75" height="135" />I spend most of my days at work on powerful IDEs like Eclipse or Netbeans, tools so advanced in functionalities that their feature lists span over several pages. Their power, however, has its own drawbacks: their memory consumption is measured in the gigabytes, and running them on underpowered computers is the most frustrating of experiences. Issues that any Java developer on Earth will have to face, sooner or later.</p>
<p>Having grown frustrated by Eclipse being too slow on my 4 years old work laptop (I will not comment on this), I decided to drop the IDE for a while, switching to an <a title="Sublime Text" href="http://www.sublimetext.com/">extremely powerful editor</a> that offered me the one thing that matters the most to me: blazing fast navigation between different source files.</p>
<p>Of course I knew I would miss some of Eclipse&#8217;s advanced features but I wanted to give it a try, especially since <a href="http://restreaming.wordpress.com/2012/03/02/primitive-tools-primitive-programmers/">Andraz&#8217;s post</a> left me with a bit of curiosity: how much the tools we use affect our abilities? And why IDEs are so used by desktop developers while they are not so popular with web frontend developers who generally use scripting languages?</p>
<p>A commonly accepted explanation is that it is easier to write IDEs for static languages, when lots of information is known at compile time. It is easier to extract information from the code and use it to build powerful and useful features.</p>
<p>However, after a few weeks of experimentation, I ended up with a slightly different point of view on the whole matter: the popularity of IDEs for Java encouraged coding conventions would not be so widely accepted if the majority of coders used a plain text editor to edit their source files. Those conventions grew so popular that that today <strong>Java appears to be designed to be used with an IDE</strong>. Let me give a few examples.</p>
<p><span id="more-731"></span></p>
<h1>Autocompletion harms API consistency</h1>
<p>If we want to know the length of a collection (as an abstract group of objects) in Java, the code we have to write will be quite different depending what object we are working on. It can be <code>length</code> if we are working on an array, <code>length()</code> if we are working on a String, <code>size()</code> if we are working on a Collection (from the Java Collections Framework).</p>
<p>Compared to Python, where the length is always retrieved by calling <code>len(_)</code>, or to Ruby, where each enumerable type offers a <code>length</code> method, Java APIs often look disorganized and inconsistent.</p>
<p>The cost of inconsistent APIs is mitigated by auto-completion: a quick glance at IDE suggestions helps us pick the right method by skimming a list of method signatures and, occasionally, reading the inline documentation.</p>
<p>Coders who are not used to this kind of support put a lot of value in predictability and consistency: if some popular library has a specific interface that resembles what their new library is going to do, they <strong>stick to the same interface</strong>, without reinventing the wheel every time. This means that switching from a library to another is almost effortless, and it is kind of fun to think that Ruby&#8217;s mixins achieved what Java&#8217;s interfaces could not, but that is another story.</p>
<p>Following the same pattern, iterating over an array, a String and a List was done quite differently in Java, although this has been mitigated by the introduction of the for each construct in Java 5. And yet again, dynamic languages tend to be very consistent and I believe that is not due to duck typing itself, but also to lack of an Intellisense-like autocompletion for scripting languages pushes coders to rely on habits, implicit knowledge and API conventions they learned by working with other tools and libraries.</p>
<h1>Packages and imports work great until we need to manage them</h1>
<p>A widely accepted convention among Java coders is to use fully qualified imports in source files, because this improves readability and makes dependencies on other classes explicit. This means that, even though there are a few notable exceptions of packages for which a general (*) import is considered acceptable, such as</p>
<p><code>import java.util.*;<br />
import java.io.*;</code></p>
<p>generally Java sources start with a long list of imports, with one line per each class outside the current package.</p>
<p>The rationale behind this convention totally makes sense, and it is effortless to coders as any decent IDE is able to do a great job in managing imports automatically. But guess what? Once you are using a text editor to work on your source files, all the burden of taking care of imports is on your shoulders.</p>
<p>Now, the choice to make Java packages correspond to the way classes are arranged on the filesystem is a strong one. Compared to C++ namespaces, Java packages tend to be more structured: a complex project is likely to contain several nested packages with several a few classes each. This means that, even if you contemplated the option of using the import * notation, you would still need to do some menial work to manage imports.</p>
<p>I would not say that packages are a bad idea, but being forced to manage them was probably one of the things that made me miss Eclipse the most.</p>
<h1>Code generation increases verbosity</h1>
<p>A lot has been written about Java being too verbose, and I tend to agree with that argument. The design of Java <a title="Languages, Verbosity, and Java" href="http://www.informit.com/articles/article.aspx?p=1824790">privileges readability and non-ambiguity over syntactical conciseness</a>, making it fairly easy to learn and use. Overloading operators, for example, is not allowed as it was one of the most common source of surprises in C++.</p>
<p>However, verbosity is not just about syntax: many of the common conventions in Java require developers to write lots of boilerplate code with little informative content. Take the example of accessor methods: for each property we add to a Java bean we have to write the corresponding getter and setter methods. The task is so repetitive and meaningless most IDEs offer the possibility to generate automatically the code for accessor methods.</p>
<p>The same thing in Ruby is extremely simpler: the <code>attr_accessor</code> method addresses the same problem in an incredibly concise way. It uses <a href="http://en.wikipedia.org/wiki/Metaprogramming">metaprogramming</a> (which itself is not achievable in Java) to accomplish its objective, but still it is an effective way to address the same issue.</p>
<p>The developer community influenced the evolution of the language before with (e.g. with the introduction of Generics), but the availability of code generation within IDEs has made Java developers much more tolerant towards verbose patterns. Would manually writing code for getters and setters be acceptable if we had no support from Eclipse? Personally, I do not think so.</p>
<h1>Conclusion</h1>
<p>Working with Sublime Text is great, it is incredibly fast and outperforms Eclipse in text manipulation. However, I unsurprisingly missed Eclipse when I had to debug, refactor existing code or inspect some complex call hierarchies in multiple projects, tasks for which an IDE is perfect.</p>
<p>What surprised me the most, however, was that I did not really miss Eclipse because of the benefits it gave me, but because it saved me a lot of nuisances that are caused by the way we write code in Java, by the conventions we chose ourselves.<strong> It is not by chance that Java does have plenty of IDEs and scripting languages do not; it is by design</strong>.</p>
<br />Filed under: <a href='http://blog.abahgat.com/category/software-engineering/coding/'>coding</a> Tagged: <a href='http://blog.abahgat.com/tag/api/'>api</a>, <a href='http://blog.abahgat.com/tag/eclipse/'>eclipse</a>, <a href='http://blog.abahgat.com/tag/ides/'>ides</a>, <a href='http://blog.abahgat.com/tag/java/'>java</a>, <a href='http://blog.abahgat.com/tag/netbeans/'>netbeans</a>, <a href='http://blog.abahgat.com/tag/programming/'>programming</a>, <a href='http://blog.abahgat.com/tag/python/'>Python</a>, <a href='http://blog.abahgat.com/tag/ruby/'>ruby</a>, <a href='http://blog.abahgat.com/tag/sublime-text/'>Sublime Text</a>, <a href='http://blog.abahgat.com/tag/verbosity/'>verbosity</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/abahgat.wordpress.com/731/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/abahgat.wordpress.com/731/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/abahgat.wordpress.com/731/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/abahgat.wordpress.com/731/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/abahgat.wordpress.com/731/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/abahgat.wordpress.com/731/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/abahgat.wordpress.com/731/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/abahgat.wordpress.com/731/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/abahgat.wordpress.com/731/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/abahgat.wordpress.com/731/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/abahgat.wordpress.com/731/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/abahgat.wordpress.com/731/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/abahgat.wordpress.com/731/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/abahgat.wordpress.com/731/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.abahgat.com&#038;blog=5154924&#038;post=731&#038;subd=abahgat&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.abahgat.com/2012/03/26/do-languages-shape-ides-or-ides-shape-languages/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>45.463681 9.188171</georss:point>
		<geo:lat>45.463681</geo:lat>
		<geo:long>9.188171</geo:long>
		<media:content url="http://1.gravatar.com/avatar/7f3c642af40363040510685c7cc1334e?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">abahgat</media:title>
		</media:content>

		<media:content url="http://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Wave.svg/226px-Wave.svg.png" medium="image">
			<media:title type="html">Duke, the Java Mascot, in the waving pose. Duk...</media:title>
		</media:content>
	</item>
	</channel>
</rss>
