<?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>Wrong Side of Memphis</title>
	<atom:link href="http://wrongsideofmemphis.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://wrongsideofmemphis.wordpress.com</link>
	<description>Adventures of a Software Developer in a Strange Land</description>
	<lastBuildDate>Tue, 29 Nov 2011 10:49:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='wrongsideofmemphis.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Wrong Side of Memphis</title>
		<link>http://wrongsideofmemphis.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://wrongsideofmemphis.wordpress.com/osd.xml" title="Wrong Side of Memphis" />
	<atom:link rel='hub' href='http://wrongsideofmemphis.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Respect your production data</title>
		<link>http://wrongsideofmemphis.wordpress.com/2011/11/22/respect-your-production-data/</link>
		<comments>http://wrongsideofmemphis.wordpress.com/2011/11/22/respect-your-production-data/#comments</comments>
		<pubDate>Tue, 22 Nov 2011 06:00:25 +0000</pubDate>
		<dc:creator>Jaime Buelta</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[disaster]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[mongoengine]]></category>

		<guid isPermaLink="false">http://wrongsideofmemphis.wordpress.com/?p=463</guid>
		<description><![CDATA[I read yesterday this blog post: I Accidentally Deleted All Our Data by Taylor Fausak. Probably you&#8217;ll end with the same expression in your face that I did. An a palm covering it. Something in advance. It takes GREAT courage and openness to tell in your blog this story. I think is really a great attitude about [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=463&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I read yesterday this blog post: <a href="http://taylor.fausak.me/2011/11/18/i-accidentally-deleted-all-our-data/">I Accidentally Deleted All Our Data</a> by Taylor Fausak. Probably you&#8217;ll end with the same expression in your face that I did. An a palm covering it.</p>
<p>Something in advance. It takes <strong>GREAT courage</strong> and openness to tell in your blog this story. I think is really a great attitude about it.</p>
<p>Saying this, I must say that the whole story a recipe for disaster. Lots of steps make my spider-sense to tingle. <strong>Strongly</strong>.</p>
<p>Doing a script on the python interactive shell to update your production data, while in a convention, between presentations&#8230; Well, it&#8217;s not the right moment to do ANYTHING that could change your data. A quick look a monitoring tool, that&#8217;s grand. But anything more complex that that is highly risky. And specially using the interactive shell.</p>
<p>You have to <strong>RESPECT</strong> your production environment and data. Ideally, every change in production should be automated and tested before in advance. That means everything but the most extreme cases, like bugs that are blocking the whole application. Sometimes, in extraordinary cases, could necessary to take extraordinary measures. But it should always be treated with the proper caution.</p>
<p>You have to set <strong>all</strong> your attention each time you have to change anything on production and have a clear view in advance of what are you trying to do. Think really carefully what are you going to do. And double check everything you type. Every step that has not been previously tested on a staging environment is a possible disaster for your application.</p>
<p>Anyway, stories like that only make me remember how much attention should I put into changing production data and keep a healthy fear of what could happen. Treat your production environment with proper R-E-S-P-E-C-T or it can bite. Hard.</p>
<p>Bonus: Really, <em>really</em>, <strong>REALLY</strong> the best way of testing that something works is <strong>SAVING everything AGAIN</strong>????????</p>
<p>This code give me nightmares&#8230;</p>
<p><pre class="brush: python;">
from mongoengine import connect
from models import Family
connect('the-production-database')
for family in Family.objects:
   family.save()
</pre></p>
<br /> Tagged: <a href='http://wrongsideofmemphis.wordpress.com/tag/disaster/'>disaster</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/english/'>english</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/mongoengine/'>mongoengine</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/python/'>python</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wrongsideofmemphis.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wrongsideofmemphis.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wrongsideofmemphis.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wrongsideofmemphis.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wrongsideofmemphis.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wrongsideofmemphis.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wrongsideofmemphis.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wrongsideofmemphis.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wrongsideofmemphis.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wrongsideofmemphis.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wrongsideofmemphis.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wrongsideofmemphis.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wrongsideofmemphis.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wrongsideofmemphis.wordpress.com/463/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=463&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wrongsideofmemphis.wordpress.com/2011/11/22/respect-your-production-data/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b9658a734adea071829d31278bb242d8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">khelben</media:title>
		</media:content>
	</item>
		<item>
		<title>Utopia Kingdoms scaling case. From 4 users to 90k+</title>
		<link>http://wrongsideofmemphis.wordpress.com/2011/10/23/utopia-kingdoms-scaling-case-from-4-users-to-90k/</link>
		<comments>http://wrongsideofmemphis.wordpress.com/2011/10/23/utopia-kingdoms-scaling-case-from-4-users-to-90k/#comments</comments>
		<pubDate>Sun, 23 Oct 2011 06:44:16 +0000</pubDate>
		<dc:creator>Jaime Buelta</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://wrongsideofmemphis.wordpress.com/?p=458</guid>
		<description><![CDATA[I almost forget to put this presentation I gave in PyCon Ireland 2011 this month. It&#8217;s about some problems and solutions working on Utopia Kingdoms game regarding scalability. So, here are the slides UPDATE: In case anyone is interested, here is the talk, courtesy of PyCon Ireland &#160; Tagged: english, mongodb, python, scalability<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=458&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I almost forget to put this presentation I gave in <a href="http://python.ie/pycon/2011/">PyCon Ireland 2011</a> this month. It&#8217;s about some problems and solutions working on <a href="https://apps.facebook.com/utopiakingdoms">Utopia Kingdoms game</a> regarding scalability.</p>
<p>So, here are the slides</p>
<iframe src='http://www.slideshare.net/slideshow/embed_code/9839863' width='700' height='574'></iframe>
<p>UPDATE: In case anyone is interested, here is the talk, courtesy of PyCon Ireland <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<div class='embed-vimeo' style='text-align:center;'><iframe src='http://player.vimeo.com/video/32656480' width='400' height='222' frameborder='0'></iframe></div>
<p>&nbsp;</p>
<br /> Tagged: <a href='http://wrongsideofmemphis.wordpress.com/tag/english/'>english</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/mongodb/'>mongodb</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/python/'>python</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/scalability/'>scalability</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wrongsideofmemphis.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wrongsideofmemphis.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wrongsideofmemphis.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wrongsideofmemphis.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wrongsideofmemphis.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wrongsideofmemphis.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wrongsideofmemphis.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wrongsideofmemphis.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wrongsideofmemphis.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wrongsideofmemphis.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wrongsideofmemphis.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wrongsideofmemphis.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wrongsideofmemphis.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wrongsideofmemphis.wordpress.com/458/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=458&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wrongsideofmemphis.wordpress.com/2011/10/23/utopia-kingdoms-scaling-case-from-4-users-to-90k/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b9658a734adea071829d31278bb242d8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">khelben</media:title>
		</media:content>
	</item>
		<item>
		<title>Jolt Online Gaming is hiring</title>
		<link>http://wrongsideofmemphis.wordpress.com/2011/05/23/jolt-online-gaming-is-hiring/</link>
		<comments>http://wrongsideofmemphis.wordpress.com/2011/05/23/jolt-online-gaming-is-hiring/#comments</comments>
		<pubDate>Mon, 23 May 2011 10:11:11 +0000</pubDate>
		<dc:creator>Jaime Buelta</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[cassandra]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[pylons]]></category>

		<guid isPermaLink="false">http://wrongsideofmemphis.wordpress.com/?p=439</guid>
		<description><![CDATA[I don&#8217;t usually use my blog for these kind of things, but right now is proving quite hard to find good developers, and, as I am really happy with my job in Jolt (my current employer), I feel obligated to lend a hand and try to spread the word as much as possible. There are currently two [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=439&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t usually use my blog for these kind of things, but right now is proving quite hard to find good developers, and, as I am really happy with my job in Jolt (my current employer), I feel obligated to lend a hand and try to spread the word as much as possible.</p>
<p>There are currently two available positions in the development team, <a href="http://joltonline.com/aboutus/jobs/Senior_Developer_JD.pdf">a lead Flash developer</a> and <a href="http://joltonline.com/aboutus/jobs/Senior_Developer_JD.pdf">a senior Python developer</a>. The links are the official job descriptions, but I would like to tell a bit more about the tools we use everyday and the company, and about my experience working here.</p>
<p>First of all, basic info about the company. <strong>Jolt Online Gaming</strong> is a games company based in Dublin, Ireland. Specifically, online free-to-play games, with social elements on them. Our latest releases are <a href="http://apps.facebook.com/playboyparty">Playboy Party (in Facebook) </a>and Utopia Kingdoms (available in <a href="http://apps.facebook.com/utopiakingdoms/">Facebook</a> and <a href="http://www.kongregate.com/games/JoltOnline/utopia-kingdoms">Kongregate</a>). We are just about to release a new football management game, Championship Manager on Facebook.</p>
<p>On the technical side of things, we try to find the right tool for each problem, so a lot of innovation is not only expected, but encouraged. We build our systems thinking of millions of players, which is always challenging. Scalability and performance are always important when making choices. Learning new things and being up-to-date is important.</p>
<p>Some of the cool technologies and tools that we currently are using are:</p>
<ul>
<li><em>Languages</em>: Recently, the focus is mainly <strong>Python</strong> for backend and Flash (<strong>ActionScript</strong>) for frontend, but there are also develops in Ruby, JavaScript and other languages.</li>
<li><em>Frameworks</em>: Several Python ones, including <strong>Pylons, CherryPy, Django</strong> and <strong>web.py</strong>. In the past we have used also Ruby on Rails.</li>
<li><em>Databases</em>: <strong>NoSQL databases</strong> like MongoDB and Cassandra are being more and more important, but we also make good use of <strong>MySQL</strong> when fits.</li>
<li><em>Amazon services</em>: Our infrastructure is based on <strong>Linux</strong> servers living in Amazon cloud services, making extensive use of <strong>Ec2</strong>, <strong>S3</strong> and others.</li>
<li><em>DVCS</em>: We use <strong>git</strong> in all our projects.</li>
</ul>
<div>Another important detail about my work here, is that I am able to see almost immediately that a change on the code is reflected in the gameplay of thousands. It&#8217;s good (and sometimes a little scary) to know that lots of people are using the software you&#8217;re developing, and they are having fun with it.</div>
<div>About the experience working here, I have to say that is absolutely fantastic. Not only do we work making games, but, of course, we love to play them. We often play boardgames and console games in the office, and we have a great time together. It&#8217;s hard to imagine a nicer and friendlier place to work. I also learn something new everyday from my coworkers. A great environment of cooperation, with lots of freedom to do the things your way.</div>
<div>The developers work closely with game designers and artists, which is also rewarding and leads to better understanding of the needs of the final game.</div>
<div>If any of this sounds interesting, you can send an email directly to <a href="mailto:jobs@joltonline.com">jobs@joltonline.com</a> or you can contact me if you prefer on the <a href="http://wrongsideofmemphis.wordpress.com/contact/">Contact page</a>.</div>
<br /> Tagged: <a href='http://wrongsideofmemphis.wordpress.com/tag/cassandra/'>cassandra</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/django/'>django</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/flash/'>flash</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/git/'>git</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/mongodb/'>mongodb</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/pylons/'>pylons</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/python/'>python</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wrongsideofmemphis.wordpress.com/439/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wrongsideofmemphis.wordpress.com/439/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wrongsideofmemphis.wordpress.com/439/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wrongsideofmemphis.wordpress.com/439/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wrongsideofmemphis.wordpress.com/439/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wrongsideofmemphis.wordpress.com/439/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wrongsideofmemphis.wordpress.com/439/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wrongsideofmemphis.wordpress.com/439/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wrongsideofmemphis.wordpress.com/439/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wrongsideofmemphis.wordpress.com/439/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wrongsideofmemphis.wordpress.com/439/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wrongsideofmemphis.wordpress.com/439/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wrongsideofmemphis.wordpress.com/439/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wrongsideofmemphis.wordpress.com/439/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=439&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wrongsideofmemphis.wordpress.com/2011/05/23/jolt-online-gaming-is-hiring/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b9658a734adea071829d31278bb242d8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">khelben</media:title>
		</media:content>
	</item>
		<item>
		<title>Think a little about the readers of your web site</title>
		<link>http://wrongsideofmemphis.wordpress.com/2011/01/12/think-a-little-about-the-readers-of-your-web-site/</link>
		<comments>http://wrongsideofmemphis.wordpress.com/2011/01/12/think-a-little-about-the-readers-of-your-web-site/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 09:56:08 +0000</pubDate>
		<dc:creator>Jaime Buelta</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://wrongsideofmemphis.wordpress.com/?p=389</guid>
		<description><![CDATA[This is a translation of a post by Ricardo Galli about some of the lessons he has learned on Menéame, a social news website in Spanish similar to Digg. I wanted to share some of the concepts with my co-workers, but I thought that it could be interesting to translate the complete work and share it with the whole world [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=389&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<blockquote><p>This is a translation of <a href="http://gallir.wordpress.com/2010/08/27/piensa-un-poco-en-los-lectores-de-tu-sitio-web-optimiza-lo-fundamental-intercala-y-elimina/" target="_blank">a post</a> by <a href="http://gallir.wordpress.com/" target="_blank">Ricardo Galli</a> about some of the lessons he has learned on <a href="http://www.meneame.net/" target="_blank">Menéame</a>, a social news website in Spanish similar to <a href="http://digg.com/" target="_blank">Digg</a>. I wanted to share some of the concepts with my co-workers, but I thought that it could be interesting to translate the complete work and share it with the whole world <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  Any English errors are my own. I will also like to thank David Brodigan for help me reviewing the English version.</p></blockquote>
</div>
<p>Bored of having to wait more than 5 seconds to display a blog&#8217;s page? Annoyed with those sites with dozens of <em>widgets, gadgets, AJAX effects</em> and<em> mashups</em> that take hours to load? Troubled because you have developed a very efficient program for the last hot framework and<em> &#8220;it&#8217;s slow&#8221;</em>? Me too, and that worries me a lot, These sites are incredibly crap pieces of work that don&#8217;t take into account the basics about usability and human interface: Response time perceived by the user.</p>
<p>You can criticize everything else about Menéame, except its speed or that we have not taken into account this very important aspect, that&#8217;s why I&#8217;m sharing the few rules we have been following very strictly. We already knew some, but we have also learnt many more during these past five years of development .</p>
<div>
<p>There are a lot of parameters to take into account to develop <em>&#8220;fast&#8221;</em> websites. Not only the server speeds, or the time it takes the server to generate dynamic HTML, there are other parameters that directly affect the browser and user&#8217;s perception.</p>
</div>
<p>In July 2001 I <a href="http://bulma.net/body.phtml?nIdNoticia=734" target="_blank">wrote an article at Bulma</a> [in Spanish] where I explained, according to measurements made during the development of the first sites of <a href="http://dbalears.cat/" target="_blank">Diari de Balears</a> and <a href="http://ultimahora.es/" target="_blank">Última Hora</a> (during the years 1997-1998), the fundamental technical parameters to measure and take into account: response time, return time, download time and <em>&#8220;display time&#8221;. </em>That last parameter, display, is the one that has the most impact for the user. The user expects a quick response, and that&#8217;s mostly perceived as the time that takes for the page to start to display on the browser.</p>
<p>In that article I commented, giving examples, of how to achieve a shorter display time that the total time needed to render and download the whole HTML using optimized generation. So, a rendered page without taking those parameters in mind, takes about six seconds to display.</p>
<div>
<p>T<sub>dis</sub> = T<sub>download</sub> = 0.5 sec + 40 KB/7.5KBsec = 0.5 sec + 5.33 sec =~ <strong>6 seconds</strong></p>
<p>On the other hand, the same page, but properly formated, can reduce the display time to just one second.</p>
<p>T<sub>dis</sub> = 0.5 sec + 4 KB/7.5KBsec = 0.5 sec + 0.53 sec =<strong>~ <strong>1 second</strong></strong></p>
</div>
<p>Those benchmarks were made during the reign of HTML tables, when CSS and JavaScript where not even used yet. Now the situation has gotten worse, even with the spectacular increase in bandwidth (the best available in 2001 was RDSI at 64 kbps and a few 128 or 256 kbps connections)*, better browsers and increased processor power. Today, there are a lot of popular sites that take more than six seconds to display.</p>
<p>* [of course, he is talking about the situation in Spain at the time, in other countries maybe the connection was better at the time]</p>
<div>
<p>The basic problems are still the same, just increased in complexity by the presence of CSS, JavaScript, advertisement, libraries, effects, and so on. It could be difficult to make a recipe for all situations, but here are some rules we strictly follow on Menéame:</p>
<h2>1. Minimize the inclusion of CSS and JavaScript</h2>
</div>
<p>CSS and the majority of JavaScript files are included at the top of HTML and they are <em>blocking</em>, meaning they make the browser to stop the rendering process until the downloading is completed. Including a lot of CSS and JavaScript files on a website should be carefully planned. Most of the time, it&#8217;s just annoying the users. A good rule of thumb is to keep the number of those files down to a minimum, don&#8217;t include unused libraries and reduce the number of images inside CSS, as they generate additional connections.</p>
<p>It&#8217;s very common for blogs and websites to include every kind of external JavaScript (<em>widgets</em>) without taking into account the penalty on display time. Those scripts usually block the render, especially if they weren&#8217;t carefully developed to avoid it. A good script usually is just a few lines of code that defines a fixed-sized iframe and then afterwards loads the rest of the code (using the proper requests). An example of good code in this respect are the Google AdSense scripts.</p>
<p>So, if external JavaScript code has to be included, a closer look at how it works should be taken, and those that block the rendering while making their queries to external servers should be discarded. If there is no choice but to use those kind of slow, blocking scripts, some strategies can be used to circumvent the problem. It&#8217;s what Menéame does on the two advertising blocks it has.</p>
<p>That advertising is generated from JavaScript libraries from Social Media S.L. server. That server first verifies if there are any specific advertising for the site from their own and third party databases. If not, it redirects to load AdSense. This process is slow and the server API is not optimized. The solution that Menéame uses can be adapted for use on any site with similar problems.</p>
<p>The JavaScript is not loaded directly. Instead, a fixed-size iframe is defined which loads an independent HTML. That code is the one loading the advertising scripts. The load of the iframe content does not block the rendering of the page and has a lower priority. That is the reason that, when arriving at Menéame, advertising is the last to be displayed, after rendering of the complete page.</p>
<p>So, if dealing with those slow widgets is required, the users will appreciate if they can be loading, avoiding those annoying waiting times. But even more important, when developing widgets or plugins the same techniques can be applied. Here you have an example of how we do it for the Menéame &#8220;votes counter&#8221; <a href="http://websvn.meneame.net/filedetails.php?repname=meneame&amp;path=/branches/version4/www/api/check_url.js" target="_blank">check_url.js</a> or this similar but <a href="http://websvn.meneame.net/filedetails.php?repname=meneame&amp;path=/branches/version4/www/api/check_url.js.php" target="_blank">more elaborate example</a>.</p>
<div>
<p>Note: You can also use the <a href="http://www.w3.org/TR/html4/interact/scripts.html#h-18.2.1" target="_blank">defer attribute from the script tag</a>, but be careful, we had lots of problems when trying to use it.</p>
<h2>2. Delay the load of JavaScript files when it&#8217;s not needed to display the page</h2>
</div>
<p>As mentioned previously, the number of script files included at the top of the page should be reduced to a minimum. When additional files are loaded, the best approach is to include them at the end of HTML, just before the &lt;/body&gt; tag.</p>
<p>That sometimes is not easy, as the code can be needed to render or display content on the same page. That can be solved, like in the <a href="http://www.meneame.net/story/mujeres-piden-legalice-topless-playa-california" target="_blank">Menéame case</a> of news with geolocation, when the Google Maps map is displayed on the side bar. The main idea is to delay as much as possible the load of the additional JavaScript.</p>
<p>The code can be seen at the end of the html, just before the &lt;/body&gt; tag (the first script includes Google API, <a href="http://websvn.meneame.net/filedetails.php?repname=meneame&amp;path=/branches/version4/www/js/geo.js" target="_blank">the second Menéame&#8217;s own</a><a href="http://websvn.meneame.net/filedetails.php?repname=meneame&amp;path=/branches/version4/www/js/geo.js" target="_blank"> </a>functions):</p>
<div>
<div><pre class="brush: xml;">
&lt;script src=&quot;&lt;a href=&quot;&gt;&lt;!--mce:0--&gt;&lt;/script&gt;
</pre></p>
</div>
</div>
<p>The moment the browser interprets the CSS of those three <em>divs, </em>it can calculate the needed sizes to quickly render: the width of the visible part, the height of the top header, the height of the left menu and the width of the right column (as well as the width of the central main column) The part that takes most of the CPU time in Menéame page is the link or comments requests. To reduce the display time even more, the first block sent to the browser is the content of the right column (the #sidebar). As the width is already specified, it can be rendered even when the browser hasn&#8217;t received the HTML of the main column. That&#8217;s why on slow connections (or slow computers), the first element to be displayed is the right column.</p>
<div>
<h2>4. Use different domains for the static content</h2>
</div>
<p>Browsers (at least most of them) parallelise downloads from different sites, so it is better to download static files from a different domain.</p>
<div><pre class="brush: xml;">

...

...
&lt;script src=&quot;&lt;a href=&quot;&gt;&lt;!--mce:1--&gt;&lt;/script&gt;
...

...
&lt;img src=&quot;&lt;a href=&quot; alt=&quot;&quot; /&gt;http://aws.mnmstatic.net/img/common/search-left-04.png&quot; alt=&quot;&quot; width=&quot;6&quot; height=&quot;22&quot; /&gt;
...
&lt;img src=&quot;&lt;a href=&quot; alt=&quot;&quot; /&gt;http://aws.mnmstatic.net/cache/00/01/1-1280021590-20.jpg&quot; alt=&quot;gallir&quot; width=&quot;20&quot; height=&quot;20&quot; /&gt;
</pre></p>
<div>
<div>
<div>Line 3 needs some comment. There are some libraries, like jQuery that are used in lots of places. Even when it&#8217;s the same code, each site includes its own copy, which means the browser will download the same file over and over.  To avoid this situation, Google created the Google Apis servers, when a copy of those libraries is mantained to be used on any place. If every important site used them, the users will save a lot of time (also, Google servers are distributed and optimized, so the download is quite fast) .</div>
</div>
</div>
<h2>5. Use different domains, not subdomains, for static content</h2>
</div>
<p>This point could have been included as part of the previous one, but it has been stated as a different one,  as it is a nice trick for complex sites (with use of cookies) and a lot of static files or images.  As seen in the previous point, a subdomain <a href="http://meneame.net/" target="_blank">meneame.net</a> (i.e. <a href="http://static.meneame.net/" target="_blank">static.meneame.net</a>) is not used to serve static content. Instead, a completely different one is used instead. The objective is to avoid the generation of aditional traffic due the use of cookies. Each defined cookie implies sending the cookie each connection for that domain. This happens even when downloading small images of just a few bytes. Also, upload bandwidth is usually smaller than download bandwith. This situation is even worse with cookies defined by statistical tools like Google Analytics, which tend to be big. The way of avoiding all that useless traffic is to use a completely different domain. According to some benchmarks after implementing this solution on Menéame, about 14 KB was saved on each request for a browser with an empty cache.</p>
<div>
<h2>6. Define timeout for the static content</h2>
</div>
<p>To avoid the browser connecting each time to verify that a static file was modified, define a timeout. That way the browser won&#8217;t come back to check the file until that time has expired. In Menéame the timeout is set to 10 days, in nginx:</p>
<div><pre class="brush: plain;">
location ~* \.(gif|jpg|png|js|css|html|ico)$ {
  expires   10d;
  ...
}
</pre></p>
<div>
<div>
<div>For example, for an image it will generate the following HTTP headers:</div>
<div><pre class="brush: plain;">
Cache-Control: max-age=864000
Expires: Mon, 06 Sep 2010 16:12:01 GMT
</pre></p>
</div>
</div>
</div>
<h2>7. Compress the text content</h2>
<p>If a site is reasonably well programmed, it will spend most of its time sending HTML over the net , so the browsers can accept a compressed version. With current processors, it&#8217;s best to compress the data before sending it. Web servers can do it on-the-fly if the browser is able to. For example, nginx configuration for Menéame to compress in gzip:</p>
<p><pre class="brush: plain;">
gzip  on;
gzip_comp_level 4;
gzip_proxied any;
gzip_min_length 512;
gzip_disable &quot;MSIE [1-6]\.(?!.*SV1)&quot;;
gzip_http_version 1.0;
gzip_vary on;
gzip_types text/css text/xml application/x-javascript application/atom+xml text/plain application/json application/xml+rss text/javascript;
</pre></p>
</div>
<p>There are more rules and tricks to minimize times, like set all the CSS images in just one file and treat them as sprites [*], but using just these seven rules, the speed improvement in any site will be noticeable.</p>
<p>[*] I don&#8217;t particularly like this option for sites where the design is dynamic like Menéame. Each time an icon is changed or one icon is added a new image should be generated, which has to be coordinate-compatible with the previous one, or it has to be redefined on the CSS. It&#8217;s a lot of &#8220;admin&#8221; work and quite error prone. But I think it&#8217;s a good strategy for plugins of widgets that include icons and are going to be used in lots of places (so stability is greater). I  hold the same opinion about minimizing the JavaScript code.</p>
<div>
<h2>You don&#8217;t need faster servers! You must intercalate</h2>
</div>
<p>This section is <em>geekier</em> and is the one that motivates me to write the whole article. But for different reasons it goes last and is smaller that I would like. The trend in web programming is to use more and more complex and sophisticated templates. Some typical examples are to generate all the queries to the DB and then generate the HTML results inside a FOR loop inside a template. More sophisticated examples are to include a template inside other templates or use inheritance (blocks). Something similar happens in simpler cases, like using the PHP output buffer. <em>Informatics Mythology</em> says that the better way to use TCP/IP is to lessen the number of sent packages. Probably it is better for simple sites which can be generated very fast. But the truth is that current sites generate pages of several tenths of a KB (the main HTML in Menéame has an average of 50-60KB and some news with lots of comments can easily reach 200KB) Some weeks ago we released <a href="http://gallir.wordpress.com/2010/08/11/haanga-plantillas-django-para-php-uber-eficiente/" target="_blank">the code of Haanga</a>, the Menéame template system. Even though it allows inheritance we don&#8217;t use that feature. Nor the PHP output buffer. We also don&#8217;t use big FOR loops, but the content is progressively generated for each <a href="http://websvn.meneame.net/filedetails.php?repname=meneame&amp;path=/branches/version4/www/templates/link_summary.html" target="_blank">news</a>,  <a href="http://websvn.meneame.net/filedetails.php?repname=meneame&amp;path=/branches/version4/www/templates/comment_summary.html" target="_blank">comment</a> or <a href="http://websvn.meneame.net/filedetails.php?repname=meneame&amp;path=/branches/version4/www/templates/post_summary.html" target="_blank">note</a>. This progressive generation of HTML is used for all the parts of the page, <a href="http://websvn.meneame.net/filedetails.php?repname=meneame&amp;path=/branches/version4/www/templates/header.html" target="_blank">header</a>, <a href="http://websvn.meneame.net/filedetails.php?repname=meneame&amp;path=/branches/version4/www/templates/footer.html" target="_blank">footer</a>, etc. That way, the response and return time is lower.</p>
<div>
<p>A web application has several different parts: database queries, logic, HTML generation, network transmission. To simplify, they can be named as:</p>
<ul>
<li>Q: Database queries and logic</li>
<li>H: HTML generation</li>
<li>N: Network transmission</li>
<li>A: Additional files (CSS, JavaScript)</li>
</ul>
<p>So, a typical pattern when PHP buffer is used, or when an HTML template is sent at the end of the logic (in blue and as reference, the moment when the browser begins to display content to the user)</p>
<p><pre class="brush: plain;">
QQQQQQQQQQHHHHHNNAAANNNNNNNNNNNNNNNNNN
</pre></p>
<p>In this example:</p>
<ul>
<li>Ten time units (let&#8217;s call them &#8220;ticks&#8221;) for the logic and database queries.</li>
<li>Five ticks for HTML template rendering</li>
<li>Twenty ticks for compression (if enabled) and net download</li>
<li>Three ticks to download additional files</li>
</ul>
</div>
<p>Of course, that&#8217;s only an approximation, if more complex templates are used, the HTML render could take more time than the logic and queries, or the opposite if the HTML is simple but queries are complex. In the example, the total time is 38 ticks, and the user can start to see something after 20 ticks. If the web is very slow, most programmers will decide that the best approach is to upgrade the database server or web server to a faster one, lowering the CPU load, and reducing query and HTML generation time. But that is not easy, specially because the access to the DB server involves (at least on big websites) network connections. Even if the processor speed is increased, the latency of the network is the same.</p>
<p>Even so, let&#8217;s assume that is possible to change the servers and network for faster ones and reduce to the half the time[*] for querying and rendering the HTML</p>
<p><pre class="brush: plain;">
QQQQQHHHHHNNAAANNNNNNNNNNNNNNNNNN
</pre></p>
<p>After that investment to achieve such an inprovement, plus all the extra work in the migration to the new infrastructure, the time will be reduced to 31 ticks (improvement of 18%) and the display time to 13 ticks(improvement of 35%) [*] Usually web programming is single threaded, so getting more CPUs or cores doesn&#8217;t speed up the process. The core clock can also be increased,  but doubling the MHz is not going to double the speed (not at all) and the monetary cost can be very high. But the programmer is forgetting something important that he learned over his studies and that is fundamental in IT, operating systems and multiprogramming in general: <strong>intercalation</strong>.</p>
<div>
<p>So, taking that into account, the strategy is to get to the HTML generation as fast as possible to make it progressive, so the compression and transmission can start while the rest of queries are made. So, taking that strategy on the original schema, with the original servers:</p>
<p><pre class="brush: plain;">
NNQQQQQQQQQQHHHHH
  AAANNNNNNNNNNNNNNNNNN
</pre></p>
</div>
<div>So, immediately the static (or the one needing very few queries) content, is sent so the browser can start to display it. With those numbers, the total time is 23 ticks (an improvement of 40%) and 5 ticks before starting the display (improvement of 75%). The results are much better without having to change any equipment, just putting up front some template evaluation. Of course, this spectacular improvement depends highly on the particular application. Menéame is an extreme case with regard to its times, logic and DB queries are very optimized and consume a small amount of relative time. Next are the resulting times of 100 measurements about the production servers on a peak hour (friday between 12:00 and 13:00)</div>
<div>
<ol>
<li>Queries times, plus logic (Q) average 0.03348 sec (standard deviation 0.02155)</li>
<li>Queries + logic (Q) + HTML rendering (H): 0.04663 sec (standard deviation  0.02903)</li>
<li>From #1 and #2 we get that average H is 0.01315 sec</li>
</ol>
</div>
<p>As it would be a lot of work to redo programs and templates, I made some benchmark enabling and disabling buffering and compression. The next table shows the total average time (in seconds, taking into account the time to create a new TCP/IP connection) that takes to load portrait HTML (about 14KB compressed, 57KB uncompressed):</p>
<div>
<table border="0" cellspacing="0" rules="NONE">
<col width="95"></col>
<col width="86"></col>
<col width="86"></col>
<col width="86"></col>
<col width="86"></col>
<tbody>
<tr>
<td width="95" height="17" align="LEFT"></td>
<td colspan="2" width="171" align="CENTER" valign="MIDDLE"><strong>Uncompressed</strong></td>
<td colspan="2" width="171" align="CENTER" valign="MIDDLE"><strong>Compressed</strong></td>
</tr>
<tr>
<td height="17" align="LEFT"></td>
<td align="CENTER"><strong>Unbuffered</strong></td>
<td align="CENTER"><strong>Buffered</strong></td>
<td align="CENTER"><strong>Unbuffered</strong></td>
<td align="CENTER"><strong>Buffered</strong></td>
</tr>
<tr>
<td height="17" align="RIGHT"><strong>ONO 12 Mbps</strong></td>
<td align="CENTER">0.52</td>
<td align="CENTER">0.61</td>
<td align="CENTER"><strong>0.32</strong></td>
<td align="CENTER">0.34</td>
</tr>
<tr>
<td height="17" align="RIGHT"><strong>3G Vodafone</strong></td>
<td align="CENTER">1.09</td>
<td align="CENTER">1.12</td>
<td align="CENTER"><strong>0.86</strong></td>
<td align="CENTER">0.89</td>
</tr>
</tbody>
</table>
</div>
<div><strong>Without buffering it is a little faster, but the difference is very small. Compression is more noticeable, it can reduce the time up to 38%</strong></div>
<h2>Conclusions</h2>
<p>Output buffer shouldn&#8217;t be used unless you&#8217;re not absolutely sure about what you&#8217;re doing and/or have measured the impact. In general it will be better without and will consume less server resources (basically RAM memory). If an application with templates is complex and the time of processing and querying is relatively big, generating a big, final template should be avoided. That will save RAM and CPU time.</p>
<p>If serializing the generation of each object can&#8217;t be achieved, at least an independent template with the HTML header can be generated and sent as fast as possible, so the browser can download in parallel the CSS and JavaScript files.</p>
<div>
<p>Final comment about mobile devices and iPads</p>
</div>
<p>A lot of access comes from cell phones and iPads. The users should be happy to access with their gadgets when they browse through your site, that&#8217;s why they spend a lot of money on them! There are some easy tricks, like not showing secondary content, not loading heavy API and use the @media selector on CSS to adjust sizes, margins and not display complex sections.</p>
<p>Menéame has had its own <a href="http://m.meneame.net/" target="_blank">optimized mobile site</a> for a long time. Very few users knew this, so an automatic redirection was implemented to the mobile version if it detected a mobile browser (we had over 10,000 daily visits). A lot of people complained about it, so the access was restricted to direct access from external sites, or if a short link like <a href="http://m.menea.me/m5za" target="_blank">http://m.menea.me/m5za</a> is used (for example, it&#8217;s used on <a href="http://twitter.com/#!/meneame_net" target="_blank">automated tweets</a>)</p>
<p>To make the browsing on the main site more lightweight for those users, some differences with the non-mobile version have been implemented</p>
<div>
<ul>
<li>The right side bar and the top advertising are not generated.</li>
<li>Font size and some margins are changed, and some content is hidden (<em>display: none</em>) using the @media selector on CSS files:</li>
</ul>
<p><pre class="brush: css;">
/* Definitions for mobile, iPad and TVs */
@media print,tv,handheld,all and (max-device-width: 780px) {
body {
font-size: medium;
}

.sneaker {
font-size: small;
}

#wrap {
min-width: 320px;
}

#sidebar {
display:none;
}

#singlewrap, #newswrap {
margin: 5px 5px 0px 5px;
}

#footwrap {
margin: 5em 5px 0 5px;
clear: both;
}

.banner-top {
width: 470px;
}
}
</pre></p>
<ul>
<li>The maps and API from Google Maps are not loaded.</li>
<li>The megabanner is replaced for a smaller AdSense ad.</li>
</ul>
</div>
<br /> Tagged: <a href='http://wrongsideofmemphis.wordpress.com/tag/english/'>english</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/software-engineering/'>software engineering</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wrongsideofmemphis.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wrongsideofmemphis.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wrongsideofmemphis.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wrongsideofmemphis.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wrongsideofmemphis.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wrongsideofmemphis.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wrongsideofmemphis.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wrongsideofmemphis.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wrongsideofmemphis.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wrongsideofmemphis.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wrongsideofmemphis.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wrongsideofmemphis.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wrongsideofmemphis.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wrongsideofmemphis.wordpress.com/389/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=389&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wrongsideofmemphis.wordpress.com/2011/01/12/think-a-little-about-the-readers-of-your-web-site/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b9658a734adea071829d31278bb242d8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">khelben</media:title>
		</media:content>
	</item>
		<item>
		<title>Django and Rails and Grails, Oh my!</title>
		<link>http://wrongsideofmemphis.wordpress.com/2010/10/20/django-and-rails-and-grails-oh-my/</link>
		<comments>http://wrongsideofmemphis.wordpress.com/2010/10/20/django-and-rails-and-grails-oh-my/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 00:59:39 +0000</pubDate>
		<dc:creator>Jaime Buelta</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[pycon]]></category>
		<category><![CDATA[python ireland]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://wrongsideofmemphis.wordpress.com/?p=364</guid>
		<description><![CDATA[On the PyCon Ireland I give a talk comparing between Django, Ruby on Rails and Grails framework&#8230; I just forget to put a link on this blog! The presentation can be found at Prezi, and there is even a video, if someone wants to make funny comments on my exotic accent A problem with the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=364&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>On the PyCon Ireland I give a talk comparing between Django, Ruby on Rails and Grails framework&#8230; I just forget to put a link on this blog!</p>
<p>The presentation can be found at <a href="http://prezi.com/">Prezi</a>, and there is even a video, if someone wants to make funny comments on my exotic accent <img src='http://s2.wp.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  A problem with the projector doesn&#8217;t allow me to display the slides, so I felt a little weird taking the laptop and pointing at the screen, but the people making the video has make their homework and shows the proper slides on place. Nice!</p>
<p><a href="http://prezi.com/n9re7-x9guah/django-and-rails-and-grails-oh-my/">Presentation</a></p>
<p><a href="http://vimeo.com/groups/pyconireland/videos/14083682">Video</a></p>
<p>The original idea was to show the same simple application (a simple posting service) make with the three frameworks, but not being able to display on the projector really ruined it. Anyway, the code can be downloaded <a href="https://docs.google.com/leaf?id=0ByawkMkzunElNzc0MmEyZWQtMWZkYS00YjcwLWJiNmItNTk1N2Q3NmVkYWQ0&amp;sort=name&amp;layout=list&amp;pid=0ByawkMkzunElNDlkOGRiYmQtNjE5Zi00MmIyLTg5MWMtYTUwYWI3NDkyYzRj">here</a>, if you want to take a look.</p>
<p>Let me know what do you think!</p>
<br /> Tagged: <a href='http://wrongsideofmemphis.wordpress.com/tag/django/'>django</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/english/'>english</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/grails/'>grails</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/pycon/'>pycon</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/python/'>python</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/python-ireland/'>python ireland</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/rails/'>rails</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wrongsideofmemphis.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wrongsideofmemphis.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wrongsideofmemphis.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wrongsideofmemphis.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wrongsideofmemphis.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wrongsideofmemphis.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wrongsideofmemphis.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wrongsideofmemphis.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wrongsideofmemphis.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wrongsideofmemphis.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wrongsideofmemphis.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wrongsideofmemphis.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wrongsideofmemphis.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wrongsideofmemphis.wordpress.com/364/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=364&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wrongsideofmemphis.wordpress.com/2010/10/20/django-and-rails-and-grails-oh-my/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b9658a734adea071829d31278bb242d8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">khelben</media:title>
		</media:content>
	</item>
		<item>
		<title>Planes de desarrollo profesional</title>
		<link>http://wrongsideofmemphis.wordpress.com/2010/10/19/planes-de-desarrollo-profesional/</link>
		<comments>http://wrongsideofmemphis.wordpress.com/2010/10/19/planes-de-desarrollo-profesional/#comments</comments>
		<pubDate>Tue, 19 Oct 2010 07:00:24 +0000</pubDate>
		<dc:creator>Jaime Buelta</dc:creator>
				<category><![CDATA[Economía]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[plan]]></category>
		<category><![CDATA[trabajo]]></category>

		<guid isPermaLink="false">http://wrongsideofmemphis.wordpress.com/?p=219</guid>
		<description><![CDATA[Llevo un tiempo pensando en escribir sobre algunas de las posiciones que tengo al respecto de mi empleo y mi manera de abordar mi carrera profesional. Algo que se destaca constantemente en webs relacionadas con el empleo y la carrera profesional es la necesidad de tener un plan. Y un plan profesional es algo que [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=219&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">Llevo un tiempo pensando en escribir sobre algunas de las posiciones que tengo al respecto de mi empleo y mi manera de abordar mi carrera profesional.</p>
<p style="text-align:justify;"><img class="alignright size-full wp-image-372" style="margin:10px;" title="alwayshaveplan" src="http://wrongsideofmemphis.files.wordpress.com/2010/10/alwayshaveplan.png?w=280&#038;h=280" alt="" width="280" height="280" />Algo que se destaca constantemente en webs relacionadas con el empleo y la carrera profesional es la necesidad de tener <strong>un plan</strong>. Y un plan profesional es algo que casi siempre se pone en las oferta de trabajo (posibilidades de carrera), pero que, lamentablemente, tenemos que crear nosotros mismos. Es lo que <a href="http://www.marcapropia.net">Andrés Pérez</a> lleva mucho tiempo sintetizando en <em>&#8220;o eliges tú, o alguien va a elegir por tí&#8221;</em></p>
<p style="text-align:justify;">No es nada sencillo, porque lo primero que viene a la cabeza son  los típicos planes  detallados al milimetro, como si la vida de uno fuese &#8220;Ocean&#8217;s 11&#8243; y todo funciona como un reloj. Pero eso es imposible, porque la vida no es una película de Hollywood y hay que improvisar constantemente. Y proponerte objetivos imposibles sólo va a frustrarte.</p>
<p style="text-align:justify;">Lo más importante es tener claros tus objetivos estratégicos. No necesariamente tienen que ser objetivos muy concretos, sino sensaciones generales sobre los que un conocido llamaba <em>&#8220;qué quiero ser de mayor&#8221;</em>. Añadir algún tema concreto está bien, de todos modos, pero esas preguntas de &#8220;<em>¿dónde te ves dentro de 5 años?</em>&#8220;, al menos a mí, me resultan terriblemente complicadas de contestar. Cualquier cosa que hubiese podido decir hace 5 años no hubiese tenido nada que ver con lo que hago ahora, posiblemente&#8230;</p>
<p style="text-align:justify;">Para poder hacerlo, aunque parezca una perogrullada, necesitamos conocernos bien a nosotros mismos. Pero no lo es. Cuesta mucho realmente darse cuenta de lo que es importante en nuestra vida y no seguir lo que nos imponen los demás, bien sean nuestros padres, nuestros amigos, la sociedad en general, etc&#8230; Tenemos que tener claro qué deseos son nuestros y cuales son &#8220;lo que se supone que tiene que ser&#8221;. Eso supone pensar y meditar sobre uno mismo.</p>
<p style="text-align:justify;">Y, por supuesto, cada cierto tiempo hay que revisarlas y, ¿por qué no?, cambiarlas.</p>
<p style="text-align:justify;">Por ejemplo, algunas de mis ideas actuales:</p>
<ul style="text-align:justify;">
<li>En primer lugar, creo que el trabajo de cada uno debe ser algo que llene, que vaya más allá que el mero hecho de cobrar una nómina. Más que lo creo, es que QUIERO que mi trabajo sea algo <strong>gratificante</strong> y que me importe. Bastantes horas al día se tira uno trabajando como para que luego no merezca la pena más que en la cuenta corriente.</li>
</ul>
<ul style="text-align:justify;">A pesar de que muchas veces se plantea la dicotomía trabajar en lo que te gusta-ganar dinero, a partir de mi experiencia personal, creo que trabajar en lo que a uno le gusta funciona mucho mejor como medio de ganar dinero mas que &#8220;sacrificarse estoicamente&#8221;.</ul>
<ul style="text-align:justify;">
<li>Quiero también que mi carrera profesional sea <strong>interesante y variada</strong>. Me gusta mucho aprender cosas nuevas, aunque eso inevitablemente sea algo complicado y difícil. Require esfuerzo, y todos tendemos a ser vaguetes y a apalancarnos.</li>
</ul>
<ul style="text-align:justify;">A pesar de ser desarrollador de software, que es algo que implica reinventare casi casi cada día, me gusta también probar otras cosas, y trabajar en equipos interdisciplinares. También meto aquí lo interesante que creo que está siendo para mí la experiencia de estar trabajando en Irlanda y en una industria como la de los videojuegos, en las que cada semana parece un año de lo rápido que va.</ul>
<ul style="text-align:justify;">
<li>Creo que uno debe siempre aspirar a más. Ser <strong>ambicioso</strong>. Eso no quiere decir ambición desmedida, pero sí tener un cierto sentido de progreso, entendido de manera personal, y, aunque sea secundaria, por qué no en lo económico. También incluye el reconocimiento.</li>
</ul>
<ul style="text-align:justify;">
<li>Valoro mi <strong>independencia</strong> y no soporto el micromanagement. Quiero ser capaz de proponer objetivos y no hacer las cosas porque las diga el jefe, sino porque es necesario/mejora el proyecto. Quiero estar en un entorno cooperativo y no ordeno-mando. Es muy frustante tener que luchar contra imposiciones.</li>
</ul>
<ul style="text-align:justify;">
<li>Cada vez creo más en ser transparente, en <strong>comunicar</strong> lo que haces y menos en guardarse secretos. Eso incluye hablar de lo que hago de manera pública (como en este blog), pero también aceptar errores, admitir inseguidades y ser sincero. Y mira que cuesta horrores.</li>
</ul>
<p style="text-align:justify;">Con estas coas, ya puedes ir sacando diferentes &#8220;derivadas&#8221;, Por ejemplo, muchas cosas que son importantes para mí (y, destaco, lo mismo no lo son para nadie más) son mucho mas factibles en pequeñas empresas o startups que en grandes empresas (y esa es una buena manera de clasificar qué buscar), o, incluso, llegado el caso, con autoempleo.</p>
<p style="text-align:justify;">Eso implica que, probablemente, tenga que vivir con más riesgo implícito que estando 10 años seguidos en la misma compañía. Bueno, por el momento lo asumo (aunque cada día piense más que trabajar en una gran empresa es muy arriesgado, en cualquier momento prescinden de tí en las &#8220;altas esferas&#8221; y no hay manera de librarse). Pero creo que es importante entender que no hay nada gratis, para todo se paga un precio y es cuestión de prioridades.  Es parte del plan, decidir si es más importante esto o lo otro e ir a por ello.</p>
<p style="text-align:justify;">Así que, de tanto en tanto, me planteo, ¿lo que estoy haciendo sirve para mis objetivos estratégicos? ¿Hay otro camino para cumplirlos mejor? Y, si lo hay, pues uno se puede poner manos a la obra con un objetivo en la cabeza&#8230;</p>
<br /> Tagged: <a href='http://wrongsideofmemphis.wordpress.com/tag/personal/'>Personal</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/plan/'>plan</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/trabajo/'>trabajo</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wrongsideofmemphis.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wrongsideofmemphis.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wrongsideofmemphis.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wrongsideofmemphis.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wrongsideofmemphis.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wrongsideofmemphis.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wrongsideofmemphis.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wrongsideofmemphis.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wrongsideofmemphis.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wrongsideofmemphis.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wrongsideofmemphis.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wrongsideofmemphis.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wrongsideofmemphis.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wrongsideofmemphis.wordpress.com/219/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=219&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wrongsideofmemphis.wordpress.com/2010/10/19/planes-de-desarrollo-profesional/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b9658a734adea071829d31278bb242d8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">khelben</media:title>
		</media:content>

		<media:content url="http://wrongsideofmemphis.files.wordpress.com/2010/10/alwayshaveplan.png" medium="image">
			<media:title type="html">alwayshaveplan</media:title>
		</media:content>
	</item>
		<item>
		<title>Database madness with mongoengine and SQLAchemy</title>
		<link>http://wrongsideofmemphis.wordpress.com/2010/10/14/database-madness-with-mongoengine-and-sqlachemy/</link>
		<comments>http://wrongsideofmemphis.wordpress.com/2010/10/14/database-madness-with-mongoengine-and-sqlachemy/#comments</comments>
		<pubDate>Thu, 14 Oct 2010 17:20:08 +0000</pubDate>
		<dc:creator>Jaime Buelta</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[mongoengine]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[python ireland]]></category>
		<category><![CDATA[SQLAlchemy]]></category>

		<guid isPermaLink="false">http://wrongsideofmemphis.wordpress.com/?p=340</guid>
		<description><![CDATA[Yesterday I gave a presentation in the Python Ireland October meeting about some work we are doing with mongoengine and SQLAchemy and how we are managing three databases (MS SQL server, MySQL and MongoDB) on an online football management game we are working on. So, here are the slides, so feel free to make comments, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=340&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Yesterday I gave a presentation in the <a href="http://www.python.ie/">Python Ireland</a> October meeting about some work we are doing with <strong>mongoengine</strong> and <strong>SQLAchemy</strong> and how we are managing three databases (<strong>MS SQL server</strong>, <strong>MySQL</strong> and <strong>MongoDB</strong>) on an online football management game we are working on.</p>
<p>So, here are the slides, so feel free to make comments, ask questions and even criticize them!</p>
<iframe src='http://www.slideshare.net/slideshow/embed_code/5441121' width='700' height='574'></iframe>
<p>You can also download the presentation on PDF <a href="http://wrongsideofmemphis.files.wordpress.com/2010/10/database_madness_with_mongoengine_and_sqlalchemy.pdf">here</a>.</p>
<p>PD: When I talk about football game, I&#8217;m referring to <strong>soccer. </strong></p>
<br /> Tagged: <a href='http://wrongsideofmemphis.wordpress.com/tag/english/'>english</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/mongoengine/'>mongoengine</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/orm/'>orm</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/python/'>python</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/python-ireland/'>python ireland</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/sqlalchemy/'>SQLAlchemy</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wrongsideofmemphis.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wrongsideofmemphis.wordpress.com/340/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wrongsideofmemphis.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wrongsideofmemphis.wordpress.com/340/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wrongsideofmemphis.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wrongsideofmemphis.wordpress.com/340/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wrongsideofmemphis.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wrongsideofmemphis.wordpress.com/340/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wrongsideofmemphis.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wrongsideofmemphis.wordpress.com/340/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wrongsideofmemphis.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wrongsideofmemphis.wordpress.com/340/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wrongsideofmemphis.wordpress.com/340/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wrongsideofmemphis.wordpress.com/340/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=340&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wrongsideofmemphis.wordpress.com/2010/10/14/database-madness-with-mongoengine-and-sqlachemy/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b9658a734adea071829d31278bb242d8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">khelben</media:title>
		</media:content>
	</item>
		<item>
		<title>Commenting the code</title>
		<link>http://wrongsideofmemphis.wordpress.com/2010/09/15/commenting-the-code/</link>
		<comments>http://wrongsideofmemphis.wordpress.com/2010/09/15/commenting-the-code/#comments</comments>
		<pubDate>Wed, 15 Sep 2010 00:42:14 +0000</pubDate>
		<dc:creator>Jaime Buelta</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://wrongsideofmemphis.wordpress.com/?p=321</guid>
		<description><![CDATA[I always find surprising to find out comments like that regarding code comment. I can understand that someone argues about that writing comments on the code is boring, or that you forget about it or whatever. But to say that the code shouldn&#8217;t be commented at all looks a little dangerous to me. That doesn&#8217;t mean that [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=321&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I always find surprising to find out comments like <a href="http://programmers.stackexchange.com/questions/1/comments-are-a-code-smell/3339#3339">that</a> regarding code comment. I can understand that someone argues about that writing comments on the code is boring, or that you forget about it or whatever. But to say that the code shouldn&#8217;t be commented <strong>at all</strong> looks a little dangerous to me.</p>
<p>That doesn&#8217;t mean that you&#8217;ll have to comment <strong>everything</strong>. Or that adding a comment it&#8217;s an excuse to not be clear directly on the code, or the comment should be repeat what is on the code. You&#8217;ll have to keep a balance, and I agree that it&#8217;s something difficult and everyone can have their opinion about when to comment and when not.</p>
<p>Also, each language has it&#8217;s own &#8220;comment flow&#8221;, and definitively you&#8217;ll make more comments on low level languages like C than in a higher level language like Python, as the language it&#8217;s more descriptive and readable. Ohhh, <strong>you have to comment</strong> so many things in C if you want to be able to understand what a function does it in less that a couple of days&#8230; (the declaration of variables, for example) <a href="#note">#</a></p>
<p>As everyone has their own style when it comes to commenting, I&#8217;m going to describe some of my personal habits commenting the code to open the discussion and compare with your opinions (and some example Python code):</p>
<ul>
<li>I put comments summarizing code blocks. That way, when I have to localize a specific section of the code, I can go faster reading the comments and ignoring the code until getting to the relevant part. I also tend to mark those blocks with newlines.</li>
<p><pre class="brush: python;">
# Obtain the list of elements from the DB
.... [some lines of code]

# Filter and aggregate the list to obtain the statistics
...  [some lines of code]
</pre></ul>
<ul>
<p>UPDATED: Some clarification here, as I think that probably I have choose the wrong example. Of course, if blocks of code gets more than a few lines and/or are used in more than one place, will need a function (and a function should ALWAYS get a docstring/comment/whatever) . But some times, I think that a function is not needed, but a clarification is good to know quickly what that code is about. The original example will remain to show my disgrace, but maybe this other example (I have copy-paste some code I am working right now and change a couple of things)<br />
It&#8217;s probably not the most clean code in the world, and that&#8217;s why I have to comment it. Latter on, maybe I will refactor it (or not, depending on the time).</p>
<p><pre class="brush: python;">
               # Some code obtaining elements from a web request ....

                # Delete existing layers and requisites
                update = Update.all().filter(Update.item == update).one()
                UpdateLayer.all().filter(UpdateLayer.update_id == update.item_id).delete()
                ItemRequisite.all().filter(ItemRequisite.item == update).delete()

                # Create the new ones
                for key, value in request.params.items():
                    if key == 'layers':
                        slayer = Layer.all().filter(Layer.layer_number == int(value)).one()
                        new_up_lay = UpdateLayer(update=update, layer=slayer)
                        new_up_lay.save()
                    if key == 'requisites':
                        req = ShopItem.all().filter(ShopItem.internal_name == value).one()
                        new_req = ShopItemRequisite(item=update, requisite=req)
                        new_req.save()
</pre></ul>
<li>I describe briefly every non-trivial operation, specially mathematical properties or &#8220;clever tricks&#8221;. Optimization features usually needs some extra description telling why a particular technique is used (and how it&#8217;s used).</li>
<p><pre class="brush: python;">
# Store found primes to increase performance through memoization
# Also, store first primes
found_primes = [2,3]

def prime(number):
    ''' Find recursively if the number is a prime. Returns True or False'''

    # Check on memoized results
    if number in found_primes:
        return True

    # By definition, 1 is not prime
    if number == 1:
        return False

    # Any even number is not prime (except 2, checked before)
    if number % 2 == 0:
        return False

    # Divide the number between all their lower prime numbers (excluding 2)
    # Use this function recursively
    lower_primes = (i for i in xrange(3,number,2) if prime(i))
    if any(p for p in lower_primes if number % p == 0) :
        return False

    # The number is not divisible, it's a prime number
    # Store to memoize
    found_primes.append(number)
    return True
</pre></p>
<p>(Dealing with prime numbers is something that deserves lots of comments!) EDIT: As stated by Álvaro, <a href="http://en.wikipedia.org/wiki/Prime_number#Primality_of_one">1 is not prime</a>. Code updated.</p>
<li>I put TODOs, caveats and any indication of further work, planned or possible.</li>
<p><pre class="brush: python;">
# TODO: Change the hardcoded IP with a dynamic import from the config file on production.
...
# TODO: The decision about which one to use is based only on getting the shorter one. Maybe a more complex algorithm has to be implemented?
...
# Careful here! We are assuming that the DB is MySQL. If not, this code will probably not work.
...
</pre></p>
<ul>
<p>UPDATE: That is probably also related to the tools I use. S.Lott talks about Sphinx notations, which is even better. I use Eclipse to evelop, which takes automatically any &#8220;TODO&#8221; on the code and make a list with them. I find myself more and more using &#8220;ack-grep&#8221; for that, curiously&#8230;&nbsp;</p>
<li>I try to comment structures as soon as they have more than a couple of elements. For example, in Python I make extensive use of lists/dictionaries to initialize static parameters in table-like format, so use a comment as header to describe the elements.</li>
<p><pre class="brush: python;">
# Init params in format: param_name, value
init_params = (('origin_ip','123.123.123.123'),
               ('destiny_ip','456.456.456.456'),
               ('timeout',5000),
              )
for param_name, value in init_params:
    store_param(param_name, value)
</pre></ul>
<ul>
<li>Size of the comment is important, it should be short, but clearness goes first. So, I try to avoid shorting words or using acronyms (unless widely used). Multiline comments are welcome, but I try to avoid them as much as possible.</li>
<li>Finally, when in doubt, <strong>comment</strong>. If at any point I have the slightest suspicious that I&#8217;m going to spend more than 30 seconds understanding a piece of code, I put a comment. I can always remove it later the next time I read that code and see that is clear enough (which I do a lot of times). Being both bad, I prefer one non-necessary comment than lacking one necessary one.</li>
<li>I think I tend to comment sightly <strong>more</strong> than other fellow programmers. That&#8217;s just a particular, completely unmeasured impression.</li>
</ul>
<p>What are your ideas about the use of comments?</p>
<p>UPDATE: Wow, I have a reference on<a href="http://slott-softwarearchitect.blogspot.com/2010/09/comments-assertions-and-unit-tests.html"> S.Lott blog</a>, a <strong>REALLY good blog</strong> that every developer should follow. That&#8217;s an honor, even if he disagrees with me on half the post <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><a name="note"></a> On one of my first projects on C, we follow a quality standard that requires us that 30% of the code lines (not blank ones) should be comments.</p>
<br /> Tagged: <a href='http://wrongsideofmemphis.wordpress.com/tag/c/'>C</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/english/'>english</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/python/'>python</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/software-engineering/'>software engineering</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wrongsideofmemphis.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wrongsideofmemphis.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wrongsideofmemphis.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wrongsideofmemphis.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wrongsideofmemphis.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wrongsideofmemphis.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wrongsideofmemphis.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wrongsideofmemphis.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wrongsideofmemphis.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wrongsideofmemphis.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wrongsideofmemphis.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wrongsideofmemphis.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wrongsideofmemphis.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wrongsideofmemphis.wordpress.com/321/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=321&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wrongsideofmemphis.wordpress.com/2010/09/15/commenting-the-code/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b9658a734adea071829d31278bb242d8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">khelben</media:title>
		</media:content>
	</item>
		<item>
		<title>ORMs and threads</title>
		<link>http://wrongsideofmemphis.wordpress.com/2010/09/07/orms-and-threads/</link>
		<comments>http://wrongsideofmemphis.wordpress.com/2010/09/07/orms-and-threads/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 22:21:17 +0000</pubDate>
		<dc:creator>Jaime Buelta</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[mongoengine]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[threads]]></category>

		<guid isPermaLink="false">http://wrongsideofmemphis.wordpress.com/?p=305</guid>
		<description><![CDATA[Do you remember the post from Joel Spolsky about leaking abstractions? It&#8217;s the kind of idea that, the first time I read, about it, was intrigued, but after some time, I began to see it on every place. There are from time to time some problems on my Python code (as well as in other high-level [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=305&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Do you remember <a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html">the post from Joel Spolsky</a> about leaking abstractions? It&#8217;s the kind of idea that, the first time I read, about it, was intrigued, but after some time, I began to see it on every place. There are from time to time some problems on my Python code (as well as in other high-level languages) that I am really glad to be able to have an idea of the underlaying low level C, or I will be struggling with some very weird, confusing problems. I have enough confusing and weird problems of my own to add more&#8230;</p>
<p>One of my recent leaking abstractions has come using a ORM, in particular <a href="http://mongoengine.org/">mongoengine</a>, but I think it will happen probably on every ORM. On a web application I am developing at the moment, we need to launch a thread to perform some operations, in a timed manner. A request comes to the server, launches a thread, and then that thread stores its status on the database. Then the user can check the status from the database (and do more operations, like pause, etc, but that I will leave that). While performing some tests on the application, I made the following code:</p>
<p><pre class="brush: python;">
def testing():
    user = User.objects.get(TEST_USER)
    user.launch_thread()
    time.sleep(TIME)
    assert user.status == END
</pre></p>
<p>Inside the thread, the code looks similar to this</p>
<p><pre class="brush: python;">
def thread(user_id):
    thread_user = User.objects.get(user_id)
    # Do things that take a while, but less than TIME
    thread_user.status = END
    thread_user.save()
</pre></p>
<p>Ok, so we&#8217;re getting an object from the database, the object launches a thread that changes its state to END and saves it after a while. Well, not really&#8230; Obviously it&#8217;s not working (or I wouldn&#8217;t be writing this). But we all already know that threads are the root of all evil, and always have nasty hidden surprises.</p>
<p>The error I was making was assuming (and that&#8217;s the abstraction in my mind) that the ORM maps the database into memory, and that <strong>the copy is unique</strong>. After all, that&#8217;s why you have a database. But it&#8217;s not true. What it&#8217;s happening here it&#8217;s that we are creating two different objects in memory. I have (now) used two different names, <em>user</em> and <em>thread_user</em>. In my code I used the same name (<em>user</em>) which probably adds to the confusion. Each one reflects the status of the database <strong>when you read the database</strong>, but after that, you are not updating the object with the real information on the DB. So, the <em>user</em> object has still the starting status, the first one, as we haven&#8217;t refreshed it with the new and changed information that another, rogue thread, has changed while we naively thought that was under our control.</p>
<p>Usually, on a web application (at least the ones developed with high-level tools) the usual situation is having a request, read the data from the DB using a ORM, change something, and then save. We don&#8217;t have rogue threads interrupting that operations and requests can be processed fast enough. And even user data is different so two users probably don&#8217;t need to write any related information. BUT definitively another request (faster one) could interrupt the process and make the data to not be coherent. It&#8217;s going to be (extremely) rare in most applications, but in case of long, threaded operations, could be important to be aware of this and try not to relay on the ORM as a virtual copy of the DB, but to read and write in short operations. Or lock the database.</p>
<p>Just one more thing. It&#8217;s possible to use only one object in memory, and pass it to the thread, and avoiding this problems. But that could generate others, like not storing (and loading) any intermediate steps of the process. So, in case the thread is stopped (for example, a server restart), the process is totally lost. Any operation that takes time to execute will ideally have some &#8220;resume&#8221; process, so that will include storing the partial state, as well as a resume, which will need to read from the DB. Also, in this particular case, there are more than one thread working the same process, communicating through the DB. </p>
<p>But wait! There is still a little more unexpected and funny behavior!</p>
<p>To reload the user object, my first idea was to generate a refresh method, this way:</p>
<p><pre class="brush: python;">
class User(mongoengine.Document):
     ...

     def refresh(self):
          ''' Refresh the object '''
          self = User.objects.get(self.id)
</pre></p>
<p>And again, it&#8217;s not working&#8230; <img src='http://s0.wp.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /><br />
Again, the problem is an abstraction. <em>self</em> it&#8217;s not always the object, not outside the method. It&#8217;s just a label (or pointer, if you know C) to the object. Yes, we have created a new object called <em>self</em>which has the new (and correct) object. BUT the label <em>user</em> is still pointing to the not-updated object we have since the beginning.</p>
<p>So&#8230; no shortcuts, we will have to reload the object after the sleep to check that the object on the DB it&#8217;s behaving properly</p>
<p><pre class="brush: python;">
def testing():
    user = User.objects.get(TEST_USER)
    user.launch_thread()
    time.sleep(TIME)
    user = User.objects.get(TEST_USER)
    assert user.status == END
</pre></p>
<br /> Tagged: <a href='http://wrongsideofmemphis.wordpress.com/tag/english/'>english</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/mongoengine/'>mongoengine</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/orm/'>orm</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/python/'>python</a>, <a href='http://wrongsideofmemphis.wordpress.com/tag/threads/'>threads</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wrongsideofmemphis.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wrongsideofmemphis.wordpress.com/305/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wrongsideofmemphis.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wrongsideofmemphis.wordpress.com/305/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wrongsideofmemphis.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wrongsideofmemphis.wordpress.com/305/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wrongsideofmemphis.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wrongsideofmemphis.wordpress.com/305/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wrongsideofmemphis.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wrongsideofmemphis.wordpress.com/305/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wrongsideofmemphis.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wrongsideofmemphis.wordpress.com/305/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wrongsideofmemphis.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wrongsideofmemphis.wordpress.com/305/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=305&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wrongsideofmemphis.wordpress.com/2010/09/07/orms-and-threads/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b9658a734adea071829d31278bb242d8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">khelben</media:title>
		</media:content>
	</item>
		<item>
		<title>Cambio de aspecto en el blog</title>
		<link>http://wrongsideofmemphis.wordpress.com/2010/05/21/cambio-de-aspecto-en-el-blog/</link>
		<comments>http://wrongsideofmemphis.wordpress.com/2010/05/21/cambio-de-aspecto-en-el-blog/#comments</comments>
		<pubDate>Fri, 21 May 2010 09:51:42 +0000</pubDate>
		<dc:creator>Jaime Buelta</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://wrongsideofmemphis.wordpress.com/?p=300</guid>
		<description><![CDATA[El anterior no me terminaba de convencer, sobre todo porque en WordPress.com no tienes muchas opciones de configurar el aspecto, tienes que atenerte a uno de los temas que te proponen. Eso sí, los hay estupendos. A pesar de que me gustaba mucho la idea de ese mapa entre Memphis y Nashville, que creo que [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=300&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>El anterior no me terminaba de convencer, sobre todo porque en WordPress.com no tienes muchas opciones de configurar el aspecto, tienes que atenerte a uno de los temas que te proponen. Eso sí, los hay estupendos.</p>
<p>A pesar de que me gustaba mucho la idea de ese mapa entre Memphis y Nashville, que creo que daba mucho juego, este estilo es mucho más limpito, claro, y creo que &#8220;pega&#8221; también muy bien con la idea de tener un blog más orientado a temas técnicos. Además, he cambiado el idioma por defecto para que los enlaces, etc aparezcan en inglés&#8230;</p>
<p>De todas formas, estoy abierto a sugerencias si alguien quiere proponerme otros temas, o si este le parece horrible y propone volver al tema anterior&#8230;</p>
<br /> Tagged: <a href='http://wrongsideofmemphis.wordpress.com/tag/blog/'>Blog</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wrongsideofmemphis.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wrongsideofmemphis.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wrongsideofmemphis.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wrongsideofmemphis.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wrongsideofmemphis.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wrongsideofmemphis.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wrongsideofmemphis.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wrongsideofmemphis.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wrongsideofmemphis.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wrongsideofmemphis.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wrongsideofmemphis.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wrongsideofmemphis.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wrongsideofmemphis.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wrongsideofmemphis.wordpress.com/300/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wrongsideofmemphis.wordpress.com&amp;blog=6419543&amp;post=300&amp;subd=wrongsideofmemphis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wrongsideofmemphis.wordpress.com/2010/05/21/cambio-de-aspecto-en-el-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b9658a734adea071829d31278bb242d8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">khelben</media:title>
		</media:content>
	</item>
	</channel>
</rss>
