<?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/"
	>

<channel>
	<title>Pablo&#039;s site</title>
	<atom:link href="http://pupeno.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://pupeno.com</link>
	<description>A bit of this, a bit of that and a lot about computers</description>
	<lastBuildDate>Thu, 25 Feb 2010 16:00:20 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Science is cool</title>
		<link>http://pupeno.com/blog/science-is-cool/</link>
		<comments>http://pupeno.com/blog/science-is-cool/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 16:00:20 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[announcement]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[science]]></category>
		<category><![CDATA[science is cool]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1608</guid>
		<description><![CDATA[
			
				
			
		
I&#8217;ve created a blog called:
Science is cool
It is my first try at a blog with a subject. The subject is, of course, science and coolness. Well, cool science. I find things related to science, every day, that are cool and I want to share them. Videos of experiments, conferences that are funny or inspiring. This is my way to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fscience-is-cool%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fscience-is-cool%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve created a blog called:</p>
<h1 style="text-align: center;"><a href="http://science-is-cool.com">Science is cool</a></h1>
<p>It is my first try at a blog with a subject. The subject is, of course, science and coolness. Well, cool science. I find things related to science, every day, that are cool and I want to share them. Videos of experiments, conferences that are funny or inspiring. This is my way to share them with everybody.</p>
<p>It&#8217;s also a statement in an age where myth and legend are jumping at us everywhere, we have to remember that science and technology brought us where we are and that science is cool.</p>
<p>My web site was born around 1998 or 1999. Since then it has been many things, but for a while it has been a blog. My blog, my personal blog, where nothing I write is off-topic. <a href="http://science-is-cool.com">Science is cool</a> is my first try at a blog with a subject and that a blog that I intend to grow beyond a handful of friends.</p>
<p>Of course, linking, sharing, re-tweeting and so on is very welcome.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/is-it-science-fiction/' rel='bookmark' title='Permanent Link: Is it Science Fiction?'>Is it Science Fiction?</a></li>
<li><a href='http://pupeno.com/blog/computer-science-and-software-engineers/' rel='bookmark' title='Permanent Link: Computer Science and Software Engineers'>Computer Science and Software Engineers</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/science-is-cool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What I didn&#8217;t like about Avatar</title>
		<link>http://pupeno.com/blog/what-i-didnt-like-about-avatar/</link>
		<comments>http://pupeno.com/blog/what-i-didnt-like-about-avatar/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 23:16:18 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[rant]]></category>
		<category><![CDATA[Avatar]]></category>
		<category><![CDATA[legend]]></category>
		<category><![CDATA[myth]]></category>
		<category><![CDATA[Rama]]></category>
		<category><![CDATA[religion]]></category>
		<category><![CDATA[science]]></category>
		<category><![CDATA[science fiction]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1601</guid>
		<description><![CDATA[
			
				
			
		
I&#8217;ve just seen Avatar. I liked it, except for one thing.
In Avatar there are two societies, one is technologically advanced and believes in science; the other is religious. Of course they gave some consistency to the religion, but it remains a religion. The technological society, the humans, are warmongers; while the spiritual society is peaceful. They [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fwhat-i-didnt-like-about-avatar%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fwhat-i-didnt-like-about-avatar%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve just seen Avatar. I liked it, except for one thing.</p>
<p>In Avatar there are two societies, one is technologically advanced and believes in science; the other is religious. Of course they gave some consistency to the religion, but it remains a religion. The technological society, the humans, are warmongers; while the spiritual society is peaceful. They go to war and the religious society wins. I don&#8217;t think that&#8217;s the right message.</p>
<p>I&#8217;m a geek. I believe in reason. I believe in science. I believe in technology. I believe the human race will only survive if it stops taking myth and legend seriously and start seeking proof, learning, studying, researching, building. Look at medicine, people were dying of very simple deases a hundred years ago. Today we conquered a lot of them!</p>
<p>The life expentansy is growing at the rate of one year every two years. If today the life expectancy is 80 years old, by the time I&#8217;m 80, it&#8217;ll be 106 years old. And that&#8217;s consider the growth of the life expectancy linear, it&#8217;s actually accelerating.</p>
<p>The previous generation of science fiction authors dreamed of supercomputers in our pockets, being able to pick up a microphone and talk with anyone on the planet. We are living that and it&#8217;s great.</p>
<p>Back to Avatar, for me a story that is much more worthy of being told is the one of <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=https%3A%2F%2Fwww.amazon.com%2Fs%3Fie%3DUTF8%26x%3D0%26ref_%3Dnb%255Fsb%255Fss%255Fi%255F0%255F14%26y%3D0%26field-keywords%3Drama%2520arthur%2520c.%2520clarke%26url%3Dsearch-alias%253Dstripbooks%26sprefix%3Drama%2520arthur%2520c.&amp;tag=pupeno-20&amp;linkCode=ur2&amp;camp=1789&amp;creative=390957">Rama</a><img style="border: none !important; margin: 0px !important;" src="https://www.assoc-amazon.com/e/ir?t=pupeno-20&amp;l=ur2&amp;o=1" border="0" alt="" width="1" height="1" />. In Rama there&#8217;s an alien civilization, extremely advanced and technological, and at the same time very pacific. They inhabit part of a huge ship while the humans inhabit another part. One day the stupid humans decide they want the whole ship. Maybe they were procreating too much and were overpopulated, go figure!</p>
<p><em>Stop reading know if you intend to read Rama, spoilers ahead.</em></p>
<p>They start invading the technological civilization. A selected group of the technological civilization gathers to save their race, they develop a virus that would kill adult human males; the group that was actually attacking them. In a couple of hours, the war is over, every human adult male is dead and peace returns.</p>
<p>The individuals of the advanced civilization who participated in the extermination, all commit suicide. It&#8217;s part of their law: those that participate in war must kill themselves at the end, even the leaders. Nobody that causes the death of other beings is fit to return to the society.</p>
<p>How many soldiers would enlist if they knew that after returning from a tour, what awaits them is suicide? Very few. How many wars would we have in the world if those declaring them would have to blow their brains out at the end of it? None.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/science-is-cool/' rel='bookmark' title='Permanent Link: Science is cool'>Science is cool</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/what-i-didnt-like-about-avatar/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The iPad&#8217;s lack of Flash is a win-win situation</title>
		<link>http://pupeno.com/blog/the-ipad-lack-of-flash-is-a-win-win-situation/</link>
		<comments>http://pupeno.com/blog/the-ipad-lack-of-flash-is-a-win-win-situation/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 04:34:21 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[tablet]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1595</guid>
		<description><![CDATA[
			
				
			
		
It seems iPad lack of Flash support is the debate of the moment. On one camp: &#8220;You can&#8217;t use the web without Flash&#8221;, on the other camp: &#8220;We don&#8217;t need no stinking Flash&#8221;. Although I do realize how a technology like Flash is sometimes needed, I&#8217;m more on the second camp. The less flash, the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fthe-ipad-lack-of-flash-is-a-win-win-situation%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fthe-ipad-lack-of-flash-is-a-win-win-situation%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://pupeno.com/wp-content/uploads/2010/02/iPad-Flash.jpg"><img class="alignright size-medium wp-image-1596" title="iPad Flash" src="http://pupeno.com/wp-content/uploads/2010/02/iPad-Flash-300x198.jpg" alt="" width="300" height="198" /></a>It seems iPad lack of Flash support is the debate of the moment. On one camp: &#8220;You can&#8217;t use the web without Flash&#8221;, on the other camp: &#8220;We don&#8217;t need no stinking Flash&#8221;. Although I do realize how a technology like Flash is sometimes needed, I&#8217;m more on the second camp. The less flash, the better.</p>
<p>I think iPad&#8217;s lack of Flash cause two things to happen:</p>
<ul>
<li>Slow down the adoption of the iPad: surely someone will say &#8220;<a href="http://noflashnoipad.com/">No Flash, No iPad</a>&#8220;.</li>
<li>Speed up the adoption of HTML5: surely someone will consider using HTML5 to support the tablet.</li>
</ul>
<p>Giving that the iPad is a closed device, probably the closedest non-phone computer consumers <em>ever</em> had access to and that HTML5 is good progress for the web, I consider both results of the <strong>iPad not having Flash positive</strong>. If I have to say anything about it, it&#8217;d be: please, stop trying to wake Steve Jobs up regarding this, you&#8217;ll ruin it.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/ensuring-the-displaying-of-flash-messages-in-ruby-on-rails/' rel='bookmark' title='Permanent Link: Ensuring the displaying of flash messages in Ruby on Rails'>Ensuring the displaying of flash messages in Ruby on Rails</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/the-ipad-lack-of-flash-is-a-win-win-situation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I&#8217;m changing how I deal with spam</title>
		<link>http://pupeno.com/blog/im-changing-how-i-deal-with-spam/</link>
		<comments>http://pupeno.com/blog/im-changing-how-i-deal-with-spam/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 04:05:21 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[policy]]></category>
		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1587</guid>
		<description><![CDATA[
			
				
			
		
My email address, pupeno@pupeno.com, existed since around 1998 and was never obfuscated or protected in any way. Spam wasn&#8217;t such a huge problem in those days. Today my Spam folder has 3200 mails.
My spam filter is quite good, but I still like going through my spam in case some non-spam message was thrown in there. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fim-changing-how-i-deal-with-spam%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fim-changing-how-i-deal-with-spam%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><a title="&quot;wall of spam&quot; by chotda" rel="http://www.flickr.com/photos/santos/56256773/" href="http://www.flickr.com/photos/santos/56256773/" target="_blank"><img class="alignright size-full wp-image-1590" title="&quot;wall of spam&quot; by chotda" src="http://pupeno.com/wp-content/uploads/2010/01/spam.jpg" alt="Spam" width="225" height="300" /></a>My email address, pupeno@pupeno.com, existed since around 1998 and was never obfuscated or protected in any way. Spam wasn&#8217;t such a huge problem in those days. Today my Spam folder has 3200 mails.</p>
<p>My spam filter is quite good, but I still like going through my spam in case some non-spam message was thrown in there. I&#8217;ve tried cleaning it weekly, daily, whenever I have free time and even inbox zero. It&#8217;s a hassle and I&#8217;m tired of it.</p>
<p>My new way to deal with spam is ignoring it. Since my spam is deleted automatically whenever it is more than 30 days old, filling up my inbox won&#8217;t be my problem; and whenever I someone tells me &#8220;I&#8217;ve sent you an email, haven&#8217;t you receive it?&#8221; I&#8217;ll be able to search for it and find it if it was on the spam folder unless it&#8217;s more than 30 days old. The cases I won&#8217;t be able to spot are mails that just went there. Life is tough.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/from-broken-kmail-to-evolution-or-from-maildir-to-mailbox/' rel='bookmark' title='Permanent Link: From (broken) KMail to Evolution (or from maildir to mailbox)'>From (broken) KMail to Evolution (or from maildir to mailbox)</a></li>
<li><a href='http://pupeno.com/blog/increasing-views-without-changing-content/' rel='bookmark' title='Permanent Link: Increasing views without changing content'>Increasing views without changing content</a></li>
<li><a href='http://pupeno.com/blog/what-is-a-blog/' rel='bookmark' title='Permanent Link: What is a blog?'>What is a blog?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/im-changing-how-i-deal-with-spam/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Some comments on This Week in Android #1</title>
		<link>http://pupeno.com/blog/some-comments-on-this-week-in-android-1/</link>
		<comments>http://pupeno.com/blog/some-comments-on-this-week-in-android-1/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 17:33:50 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[rant]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[This Week in Android]]></category>
		<category><![CDATA[TWiA]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1577</guid>
		<description><![CDATA[
			
				
			
		
I&#8217;m catching up with my podcasts and right now listening (and watching) to This Week in Android #1. I have some comments to add.
First of all, I think it&#8217;s great they are making a show about it. I&#8217;ve been extremely excited about Android since day 1 (when I couldn&#8217;t tell anyone because it was confidential [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fsome-comments-on-this-week-in-android-1%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fsome-comments-on-this-week-in-android-1%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;m catching up with my podcasts and right now listening (and watching) to <a href="http://www.twiandroid.com/?p=5">This Week in Android #1</a>. I have some comments to add.</p>
<p>First of all, I think it&#8217;s great they are making a show about it. I&#8217;ve been extremely excited about Android since day 1 (when I couldn&#8217;t tell anyone because it was confidential information at Google) and I&#8217;m getting more excited all the time. I honestly believe the Nexus One is the best phone ever made. The show still has some rough edges, but that&#8217;s a huge compliment for episode #1 and looking forward to #2.</p>
<p>So, my comments&#8230;</p>
<p>Android was not a response to iPhone. Android was released latter but it was being developed before iPhone was publicly known, probably even before it was even a rumor. If you look at the early Android emulators, you can see it was targeted as a Blackberry competitor and I actually believe Android was delayed because they&#8217;ve had to get rid of the keyboard to compete with iPhone.</p>
<p>Android is not good old Java. It&#8217;s for sure not J2ME, it&#8217;s something totally different. The virtual machine doesn&#8217;t follow Sun&#8217;s specification so you need a separate VM, compiler and so on (provided in the SDK, of course). The language, in a sense, it&#8217;s not really Java. It&#8217;s so identical than developers won&#8217;t notice the difference.</p>
<p>Android is more open than they&#8217;ve mentioned on the show. In the show the mention the usual complaints about the draconian attitude for approving iPhone Apps while the Android Market is much more free and open. But then, pushing the argument forward, the Android Market doesn&#8217;t allow adult content. What they&#8217;ve failed to mention is that in Android you are not stuck with the Android Market (like you are with the App Store in an iPhone).</p>
<p>In Android you can install web apps directly from the web, without any kind of market. And some of those apps are actually markets themselves. There are alternative markets including some that will allow adult content. Another reason for these markets to exists is that they offered paid apps in countries before the Android Market did or you can envision they offering a bigger share to the developers or other benefits.</p>
<p>Google decided not to serve the porn industry with their Android Market but at no time they are forbidding you from getting adult content in your small wonderful portable tablet.</p>
<p>At some point in that episode they&#8217;ve show a graph where iPhone had only 1% of the market. Well, iPhone really doesn&#8217;t have the bast majority of the market. It&#8217;s really a small player in amount of phones. It&#8217;s the biggest player in apps and money moved in those apps and totally dominates some communities; but not the whole market.</p>
<p>Android is going to be the dominant player because it&#8217;s going to be in all those other phones. Android will be huge without ever causing one lose sales for the iPhone. It&#8217;s a huge market with space for both players. What Android is really grabbing is the market of Symbian and other operating systems like that.</p>
<p>My last comment for the show: stop talking about the iPhone. I think it would be good to have one person be the outside voice, defending iPhone, and I think Lon is that voice. He plays the part well. The rest should never mention iPhone and should never do a pros and cons with Android in a balanced way. It&#8217;s not interesting, it doesn&#8217;t make a show and I&#8217;m not watching This Week in <em>Android</em> to know what are the advantages of iPhone. Just say and keep repeating how Android is crushing it, get me excited about it.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/if-i-was-in-charge-of-audible/' rel='bookmark' title='Permanent Link: If I were in charge of Audible'>If I were in charge of Audible</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/some-comments-on-this-week-in-android-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A message to kids: what is your passion?</title>
		<link>http://pupeno.com/blog/a-message-to-kids-what-is-your-passion/</link>
		<comments>http://pupeno.com/blog/a-message-to-kids-what-is-your-passion/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 20:38:18 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[idea]]></category>
		<category><![CDATA[kid]]></category>
		<category><![CDATA[kids]]></category>
		<category><![CDATA[passion]]></category>
		<category><![CDATA[profession]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1542</guid>
		<description><![CDATA[
			
				
			
		
This message actually applies to everybody but I think it&#8217;s obvious how it applies to adults. What most kids don&#8217;t realize is that it applies to them too.
If I ask you &#8220;What is your passion?&#8221; and you don&#8217;t give me a straight, simple and quick answer, you are in trouble.
My passion is programming. When I [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fa-message-to-kids-what-is-your-passion%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fa-message-to-kids-what-is-your-passion%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>This message actually applies to everybody but I think it&#8217;s obvious how it applies to adults. What most kids don&#8217;t realize is that it applies to them too.</p>
<p><strong>If I ask you &#8220;What is your passion?&#8221; and you don&#8217;t give me a straight, simple and quick answer, you are in trouble.</strong></p>
<p><em>My passion is programming</em>. When I start programming the world around me fades away; I forget about time, I forget about people, I forget about sleeping. I don&#8217;t even feel sleepy. If I spend two days without programming I start to feel uneasy. Five days and I&#8217;m going crazy; I start writing algorithms in napkins. I think that&#8217;s how a passion feels like.</p>
<p>I believe it doesn&#8217;t matter what your passion is as long as you have one. I&#8217;m fortunate that my passion is an extremely profitable one. Work and play are the same for me. Even if you think your passion is not on that category, you may be able to force it into it. And enjoying one&#8217;s job is the best thing that could happen to anyone.</p>
<p>I think most adults recognize this. I would hope so. Most kids don&#8217;t even know what I&#8217;m talking about. They don&#8217;t know the feeling or that the feeling even exists. I was, again, very fortunate of finding my passion when I was 7 years old.</p>
<p>It&#8217;s very important to find your passion as soon as possible, so you can align your life to it. I loved to program and now I work as a programmer. I didn&#8217;t wait until the second year of Computer Science to find out. It would have been way too late then.</p>
<p>If you think your passion might be programming? <em>Pick a book, start writing code</em>. You think it&#8217;s helping animals? What animals have you helped so far? Go out, find an animal, and help it; go to a shelter and feed an injured dog at least. You think it&#8217;s money? You better had a spreadsheet with your income and expenses, even if your income is your weekly allowance.</p>
<p>Let&#8217;s see a couple of activities which seem hard to turn into a passion for a kid.</p>
<p>Medicine? Go and do a course in first aid, it doesn&#8217;t matter how old you are, they&#8217;ll probably let you do it. Read about about anatomy or any other aspect of medicine. You can start at the Wikipedia and read for as long as you want. If you get bored in 10 minutes, that&#8217;s probably not your passion. Get a microscope and play with it. There are experiments to extract DNA from some plants, do them. There are experiments to figure out the type of blood of a person, do them.</p>
<p>Watch Dr House, ER (does it still exist?), Grey&#8217;s Anatomy and whenever there&#8217;s an illness in them do your own research. Start a blog and for every episode explain how wrong they are. Watch documentaries about real emergencies, even about forensics and corroborate what they say, blog about it.</p>
<p>Talk to a medic, ask them how it is like to be a medic. Ask them what was the most interesting case they&#8217;ve had. Probably they&#8217;ll have some reserve in talking about them, but if you are interested, they&#8217;ll find something to tell you. People love talking about themselves.</p>
<p>And then find out the thousand experiments to do and things to learn about medicine that I don&#8217;t know about because it&#8217;s not my passion. I already gave you a lot of ideas for not knowing anything about the field, if it&#8217;s your passion you&#8217;ll have many more.</p>
<p>Law? Watch all the law-related TV shows, there are a lot. Are they right or wrong? Same as for medicine, go and do your own research, blog about it. If you are old enough, try to get a job as a clerk, or errand-boy in a law firm. You&#8217;ll learn how that world works.  Get yourself real cases to read an analyze. Are public trials conducted where you live? Can you get into one? Do it. Can you go to congress sessions? Do it.</p>
<p>Help someone with a contract. Contracts move around all the time. Work contracts, leasing contracts. Most people, me included, glance over them and sign them. Help someone understand a contract, by understanding it yourself first. I don&#8217;t have the time or the money to get a lawyer to review everything I sign, but if you were my neighbor and want to help me for free, sure! Go ahead! Do know about any potential liability problem, though.</p>
<p>Find a lawyer and ask them about their job. Ask them about cases. And then learn about the thousands of things you can do in relation to law without being a lawyer that I don&#8217;t know about because it&#8217;s not my passion.</p>
<p>You don&#8217;t have to wait until your are 17 or 18 to start doing all that. You can start today no matter what your age is.</p>
<p>Leave a comment: What is your passion and what are you doing about it?</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/a-message-to-kids-what-is-your-passion/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Distributed revision control was a breakthru</title>
		<link>http://pupeno.com/blog/distributed-revision-control-was-a-breakthru/</link>
		<comments>http://pupeno.com/blog/distributed-revision-control-was-a-breakthru/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 18:00:45 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[tutorial]]></category>
		<category><![CDATA[CVS]]></category>
		<category><![CDATA[Darcs]]></category>
		<category><![CDATA[distributed revision control]]></category>
		<category><![CDATA[dvcs]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[revision control]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1157</guid>
		<description><![CDATA[
			
				
			
		
I strongly believe in revision control. Back in the days when there wasn&#8217;t any other choice that CVS I spent countless hours setting up CVS servers and re-freshing my mind on its obscure commands and arguments, which were almost all of them. If you drop my copy of Professional Linux Programming it&#8217;ll open on the CVS [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fdistributed-revision-control-was-a-breakthru%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fdistributed-revision-control-was-a-breakthru%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I strongly believe in revision control. Back in the days when there wasn&#8217;t any other choice that <a href="http://www.nongnu.org/cvs/">CVS</a> I spent countless hours setting up CVS servers and re-freshing my mind on its obscure commands and arguments, which were almost all of them. If you drop my copy of <a href="http://www.amazon.com/gp/product/1861003013?ie=UTF8&amp;tag=pupeno-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1861003013">Professional Linux Programming</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=pupeno-20&amp;l=as2&amp;o=1&amp;a=1861003013" border="0" alt="" width="1" height="1" /> it&#8217;ll open on the CVS chapter by itself (much like my copy of <a href="http://www.amazon.com/gp/product/0131103628?ie=UTF8&amp;tag=pupeno-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0131103628">The C Programming Language</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=pupeno-20&amp;l=as2&amp;o=1&amp;a=0131103628" border="0" alt="" width="1" height="1" /> will open itself on the pointers chapter, somewhere on the pointers to pointers section).</p>
<p>Then came Subversion and it was somewhat better. After that we got the explosion of revision control systems with the introduction of distributed ones. We&#8217;ve got <a href="http://pupeno.com/tag/darcs/">Darcs</a>, <a href="http://pupeno.com/tag/git/">Git</a>, Mercurial, Arch, Bazaar, etc. My choice right now is Git. It used to be Darcs, but unfortunately it stagnated for a long time and I moved on to the next new thing. I&#8217;ve used Mercurial as well. From my perspective Mercurial and Git are almost equivalent.</p>
<p>For me distributed revision control was a breakthru. There&#8217;s one small feature that makes a huge difference for me. In the old days I used to set up CVS or Subversion servers/repositories (in those, a repository is essentially a server-side thing). I had to decide where that repository was going to reside, how it was going to be named, how it was going to be accessed (ssh, http, custom protocol?), by whom, etc.</p>
<p>Today with Git I just do this</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git init</pre></div></div>

<p>That&#8217;s it. I&#8217;m done. The directory where I am is now a repository. I can start committing, branching, rolling back, looking at the history, generating patches, stashing, etc. It&#8217;s that simple. The fact that it&#8217;s so simple goes from a quantitative advantage to a qualitative advantage. What I mean is that I not only revision-control things faster but that I revision-control things I wouldn&#8217;t have otherwise. For example the configuration directories on my servers.</p>
<p>I know many people will complain: &#8220;But with no centralized repository chaos will ensue&#8221;. The fact that it&#8217;s distributed doesn&#8217;t mean there can&#8217;t be a central repository. When I want to collaborate with someone using Git I create one repo somewhere, in my servers or GitHub and we both push and pull from there. The difference is that I commit a lot locally, and when the chances are ready I push them. That means that I can commit broken code, without worrying.</p>
<p>At work we don&#8217;t use a distributed revision control system, we use a centralized one and we have a very string peer reviewing policy. My current tasks involve touching code in many different files in many different systems never getting familiar to any of them. That means that it&#8217;s common for my peer reviews to say things like &#8220;all this methods don&#8217;t belong here, these two should go there, that one should be broken into three different ones going here, there and somewhere else&#8221;.</p>
<p>Now I have a problem. I can&#8217;t commit because my peers don&#8217;t consider my code ready. My code works but it has to be refactored in a very destructive way. What happens if during the refactoring it stops working. For example copying and pasting I loose a piece of code. I can&#8217;t roll back to my working state and start over. If we were using a distributed revision control system I could.</p>
<p>So, being able to commit non-finished code locally while colaborating with other people is one of my other crucial features in DVCS.</p>
<p>The third one is being able to branch locally. In a similar vein as the last example. When I find myself thinking about a very destructive refactoring that I&#8217;m not sure if it&#8217;s going to get me anywhere and worst than that is going to take me three days to do; I just create a local branch. I experiment in that branch. If at any time I get tired or I need to do anything else I go back to the main one. That is what branching is about.</p>
<p>Why is locally branching better than globally or centralized branching? Well, one reason is that a local branch doesn&#8217;t have to make sense to anyone else. I don&#8217;t have to pick a name that&#8217;s descriptive for anyone else than me. I don&#8217;t have to justify myself for creating a branch with anyone else. Let&#8217;s suppose I had an argument with a co-worker where I believe something is doable and (s)he believes is not. Do I want him/her to see that I created a branch to prove him/her wrong? I don&#8217;t. And if I prove myself wrong I want to quietly delete that branch and never ever talk about it.</p>
<p>But I am starting to go into the very hypothetical realm. In short, for me, DVCS is about this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git init</pre></div></div>

<p>and get to code.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/revisioning-etc-with-git/' rel='bookmark' title='Permanent Link: Revisioning /etc with Git'>Revisioning /etc with Git</a></li>
<li><a href='http://pupeno.com/blog/software-release-cycle/' rel='bookmark' title='Permanent Link: Software Release Cycle'>Software Release Cycle</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/distributed-revision-control-was-a-breakthru/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Erlang gen_server template</title>
		<link>http://pupeno.com/blog/erlang-gen_server-template/</link>
		<comments>http://pupeno.com/blog/erlang-gen_server-template/#comments</comments>
		<pubDate>Sun, 03 Jan 2010 21:53:31 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[gen_server]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1536</guid>
		<description><![CDATA[
			
				
			
		
I like Erlang and I like gen_servers, I end up coding a lot of stuff as gen_servers and I like behaviors in generally. I even wrote some myself. I haven&#8217;t used Erlang for a while. I&#8217;ve been playing with it in the last couple of days, hopefully I&#8217;ll announce something soon.
I ended up creating my [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Ferlang-gen_server-template%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Ferlang-gen_server-template%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I like Erlang and I like gen_servers, I end up coding a lot of stuff as gen_servers and I like behaviors in generally. I even wrote some myself. I haven&#8217;t used Erlang for a while. I&#8217;ve been playing with it in the last couple of days, hopefully I&#8217;ll announce something soon.</p>
<p>I ended up creating my own gen_servers template to get started. It&#8217;s a very verbose one and I&#8217;m putting it here more for me to know where it is that anything else; but, maybe it&#8217;s of use for someone else:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>module<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">compile</span><span style="color: #109ab8;">&#40;</span>export_all<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">behaviour</span><span style="color: #109ab8;">&#40;</span>gen_server<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>init<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span> handle_call<span style="color: #014ea4;">/</span><span style="color: #ff9600;">3</span><span style="color: #6bb810;">,</span> handle_cast<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> handle_info<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> terminate<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> code_change<span style="color: #014ea4;">/</span><span style="color: #ff9600;">3</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% Public API</span>
&nbsp;
<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff4e18;">gen_server</span>:<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#123;</span>local<span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">MODULE</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">MODULE</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">stop</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Module</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff4e18;">gen_server</span>:<span style="color: #ff3c00;">call</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Module</span><span style="color: #6bb810;">,</span> stop<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">stop</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">stop</span><span style="color: #109ab8;">&#40;</span>?<span style="color: #6941fd;">MODULE</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">state</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Module</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff4e18;">gen_server</span>:<span style="color: #ff3c00;">call</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Module</span><span style="color: #6bb810;">,</span> state<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">state</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">state</span><span style="color: #109ab8;">&#40;</span>?<span style="color: #6941fd;">MODULE</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% Server implementation, a.k.a.: callbacks</span>
&nbsp;
<span style="color: #ff3c00;">init</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;init&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
&nbsp;
<span style="color: #ff3c00;">handle_call</span><span style="color: #109ab8;">&#40;</span>stop<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_From</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;stopping by ~p, state was ~p.&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_From</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#123;</span>stop<span style="color: #6bb810;">,</span> normal<span style="color: #6bb810;">,</span> stopped<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
&nbsp;
<span style="color: #ff3c00;">handle_call</span><span style="color: #109ab8;">&#40;</span>state<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_From</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~p is asking for the state.&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_From</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#123;</span>reply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
&nbsp;
<span style="color: #ff3c00;">handle_call</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Request</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_From</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;call ~p, ~p, ~p.&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_Request</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_From</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#123;</span>reply<span style="color: #6bb810;">,</span> ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
&nbsp;
<span style="color: #ff3c00;">handle_cast</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Msg</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;cast ~p, ~p.&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_Msg</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#123;</span>noreply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
&nbsp;
<span style="color: #ff3c00;">handle_info</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Info</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;info ~p, ~p.&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_Info</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#123;</span>noreply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
&nbsp;
<span style="color: #ff3c00;">terminate</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Reason</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;terminate ~p, ~p&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_Reason</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_State</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  ok<span style="color: #6bb810;">.</span>
&nbsp;
&nbsp;
<span style="color: #ff3c00;">code_change</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_OldVsn</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Extra</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;code_change ~p, ~p, ~p&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_OldVsn</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Extra</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% Some helper methods.</span>
&nbsp;
<span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Format</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Format</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #ff3c00;">say</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Format</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~p:~p: ~s~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>?<span style="color: #6941fd;">MODULE</span><span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">self</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #ff4e18;">io_lib</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Format</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Update 2010-01-04: I keep changing the actual contents of the template as I&#8217;m coding a little Erlang app. I&#8217;ve recently added, among other things, a call to get the state of the process, useful for debugging.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/erlang-the-language-for-network-programming-issue-1-pattern-matching/' rel='bookmark' title='Permanent Link: Erlang, the language for network programming Issue 1: pattern matching'>Erlang, the language for network programming Issue 1: pattern matching</a></li>
<li><a href='http://pupeno.com/blog/erlang-the-language-for-network-programming-issue-2-binary-pattern-matching/' rel='bookmark' title='Permanent Link: Erlang, the language for network programming Issue 2: binary pattern matching'>Erlang, the language for network programming Issue 2: binary pattern matching</a></li>
<li><a href='http://pupeno.com/blog/unstable-packages-on-ubuntu/' rel='bookmark' title='Permanent Link: Unstable packages on Ubuntu'>Unstable packages on Ubuntu</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/erlang-gen_server-template/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Revisioning /etc with Git</title>
		<link>http://pupeno.com/blog/revisioning-etc-with-git/</link>
		<comments>http://pupeno.com/blog/revisioning-etc-with-git/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 18:00:30 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[tutorial]]></category>
		<category><![CDATA[/etc]]></category>
		<category><![CDATA[distributed revision control]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[revision control]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1165</guid>
		<description><![CDATA[
			
				
			
		
First and foremost I&#8217;m a coder, a coder who strongly believes in revision control. Second I am also a sysadmin; but only by accident. I have some servers and someone has to take care of them. I&#8217;m not a good sysadmin because I don&#8217;t have any interest on it so I learn as little as [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Frevisioning-etc-with-git%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Frevisioning-etc-with-git%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>First and foremost I&#8217;m a coder, a coder who strongly believes in revision control. Second I am also a sysadmin; but only by accident. I have some servers and someone has to take care of them. I&#8217;m not a good sysadmin because I don&#8217;t have any interest on it so I learn as little as possible and also because I don&#8217;t want to be good at it and get stuck doing that all the time. What I love is to code.</p>
<p>I&#8217;m always scare of touching a file in /etc. What if I break something? I decided to treat /etc the same way I treat my software (where I am generally not afraid of touching anything). I decided to use revision control. So far I&#8217;ve never had to roll back a change in /etc, but it gives me a big peace of mind knowing that I can.</p>
<p>In the days of CVS and Subversion I thought about it, but I&#8217;ve never done it. It was just too cumbersome. But DVCS changed that, it made it trivial. That&#8217;s why I believe DVCS is a breakthru. Essentially what you need to revision-control your /etc with <a href="http://pupeno.com/tag/git/">Git</a> is to go to /etc and turn it into a repository:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>etc
git init</pre></div></div>

<p>Done. It&#8217;s now a repo. Then, submit everything in there.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git add .
git commit <span style="color: #660033;">-am</span> <span style="color: #ff0000;">&quot;Initial commit. Before today it's prehistory, after today it's fun!&quot;</span></pre></div></div>

<p>From now on every time you modify a file you can do</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git add <span style="color: #000000; font-weight: bold;">&lt;</span>filename<span style="color: #000000; font-weight: bold;">&gt;</span>
git commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Description of the change to &lt;filename&gt;&quot;</span></pre></div></div>

<p>where &lt;filename&gt; is one or many files. Or if you are lazy you can also do:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git commit <span style="color: #660033;">-am</span> <span style="color: #ff0000;">&quot;Description to all the changes.&quot;</span></pre></div></div>

<p>which will commit all pending changes. To see your pending changes do:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git status</pre></div></div>

<p>and</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git <span style="color: #c20cb9; font-weight: bold;">diff</span></pre></div></div>

<p>When there are new files, you add them all with</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git add .</pre></div></div>

<p>and if some files were remove, you have to run</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git add <span style="color: #660033;">-u</span> .</pre></div></div>

<p>to be sure that they are remove in the repo as well (otherwise they&#8217;ll stay as pending changes forever).</p>
<p>That&#8217;s essentially all the commands I use when using git and doing sysadmin. If you ever have to do a rollback, merge, branch, etc, you&#8217;ll need to <a href="http://www.amazon.com/gp/product/1934356158?ie=UTF8&amp;tag=pupeno-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1934356158">learn git for real</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=pupeno-20&amp;l=as2&amp;o=1&amp;a=1934356158" border="0" alt="" width="1" height="1" />.</p>
<p>One last thing. I often forget to commit my changes in /etc, so I created this script:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/env sh</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>etc
git status <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-v</span> <span style="color: #ff0000;">&quot;On branch master&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-v</span> <span style="color: #ff0000;">&quot;nothing to commit&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">true</span> <span style="color: #666666; font-style: italic;"># Don't return 1, which is what git status does when there's nothing to do.</span></pre></div></div>

<p>on /etc/cron.daily/git-status which reminds me, daily, of my pending changes.</p>
<p>Hope it helps!</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/distributed-revision-control-was-a-breakthru/' rel='bookmark' title='Permanent Link: Distributed revision control was a breakthru'>Distributed revision control was a breakthru</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/revisioning-etc-with-git/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Please Select your Language</title>
		<link>http://pupeno.com/blog/please-select-your-language/</link>
		<comments>http://pupeno.com/blog/please-select-your-language/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 02:55:29 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[rant]]></category>
		<category><![CDATA[Active]]></category>
		<category><![CDATA[countries]]></category>
		<category><![CDATA[EA Sports]]></category>
		<category><![CDATA[EA Sports Active]]></category>
		<category><![CDATA[international]]></category>
		<category><![CDATA[multilingual]]></category>
		<category><![CDATA[multilingualism]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1512</guid>
		<description><![CDATA[
			
				
			
		

I apparently speak Spain, United States, United Kingdom and Canada.
I would also like to speak Germany because it might be useful in Switzerland, you see, in Switzerland they speak a version of Germany, something like Swiss Germany.
As seen on http://easportsactive.com. And by the way, the reason why I was at their site is to try [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fplease-select-your-language%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fplease-select-your-language%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://pupeno.com/wp-content/uploads/2009/12/select-your-language.png"><img class="aligncenter size-full wp-image-1513" title="Please Select your Language" src="http://pupeno.com/wp-content/uploads/2009/12/select-your-language.png" alt="" width="654" height="333" /></a></p>
<p>I apparently speak Spain, United States, United Kingdom and Canada.</p>
<p>I would also like to speak Germany because it might be useful in Switzerland, you see, in Switzerland they speak a version of Germany, something like Swiss Germany.</p>
<p>As seen on http://easportsactive.com. And by the way, the reason why I was at their site is to try to figure out whether EA Sports Active, here in Switzerland at least, comes multilingual or not. From the box it seems to be only in German (or should I say Germany?), searching on-line I&#8217;ve found conflicting results. It seems EA Sports doesn&#8217;t dig multilingualism, they should support <a href="/tag/esperanto">Esperanto</a> to not have to deal with that problem (of course I&#8217;ve had to drop some Esperanto propaganda!).</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/the-need-for-a-common-language/' rel='bookmark' title='Permanent Link: The need for a common language'>The need for a common language</a></li>
<li><a href='http://pupeno.com/blog/i-speak-esperanto-the-t-shirt/' rel='bookmark' title='Permanent Link: I speak Esperanto, the t-shirt'>I speak Esperanto, the t-shirt</a></li>
<li><a href='http://pupeno.com/blog/a-programmer%e2%80%99s-favourite-language/' rel='bookmark' title='Permanent Link: A programmer’s favourite language'>A programmer’s favourite language</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/please-select-your-language/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The sad truth about testing web applications</title>
		<link>http://pupeno.com/blog/the-sad-truth-about-testing-web-applications/</link>
		<comments>http://pupeno.com/blog/the-sad-truth-about-testing-web-applications/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 16:50:13 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[rant]]></category>
		<category><![CDATA[HtmlUnit]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[HttpUnit]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web applications]]></category>
		<category><![CDATA[Web Driver]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1449</guid>
		<description><![CDATA[
			
				
			
		
There are many ways to test a web application. In the lowest level, we have unit tests; in the highest levels we have HTTP test, those that use the HTTP protocol to talk to running instance of your application (maybe running it on demand, maybe expecting it to be running on a testing server).
There are [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fthe-sad-truth-about-testing-web-applications%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fthe-sad-truth-about-testing-web-applications%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>There are many ways to test a web application. In the lowest level, we have unit tests; in the highest levels we have <strong>HTTP test</strong>, those that use the HTTP protocol to talk to running instance of your application (maybe running it on demand, maybe expecting it to be running on a testing server).</p>
<p>There are several ways to write HTTP tests. Two big families: with and without a web browser. <a href="http://seleniumhq.org/">Selenium</a> is a popular way to write tests with a browser. A competing product is <a href="http://code.google.com/p/webdriver/">Web Driver</a> which I understand can use a browser or other methods. If you&#8217;ve never seen Selenium before is pretty impressive. You write a tests that says something like:</p>
<ol>
<li>go to http://&#8230;</li>
<li>click here</li>
<li>click there</li>
<li>fill field</li>
<li>fill field</li>
<li>submit form</li>
<li>assert response</li>
</ol>
<p>and when you run it you actually see a Firefox window pop up and perform that sequence amazingly fast. Well, it&#8217;s amazingly fast the first three runs, while you still have two tests or less. After that it&#8217;s amazingly slow, tedious, flaky and intrusive.</p>
<p>For the other family of tests, without a web browser, aside of Web Driver we have <a href="http://httpunit.sourceforge.net/">HttpUnit</a>, <a href="http://htmlunit.sourceforge.net/">HtmlUnit</a> and most of the Ruby on Rails testing frameworks. The headless solution tend to be faster and more solid, but the scenarios are not as realistic (only one JavaScript engine, if you are lucky, no rendering issues, like slowdowns, etc).</p>
<p>When you are testing, as soon as you touch the HTTP protocol everything becomes much harder and less useful. If you want to be totally confident a web application is working you need to test at the HTTP level, but the return-of-investment for those tests is very low: they are hard to write and not very useful.</p>
<h2>Hard to write</h2>
<p>They are hard to write because you are not calling methods with well-defined interfaces (list of arguments) but essentially calling one method HTTP-request, passing different parameters to get different results. You don&#8217;t have any code-completion, you don&#8217;t have any formal way to know which arguments to pass. Anything can be valid.</p>
<p>In a unit test you may have something like:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">add_user<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;john&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>when in a HTTP test you&#8217;ll have something like</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">http.<span style="color: #0000FF;">send_request</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;/user/create&quot;</span>, <span style="color: #666666;">&quot;username=john&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>When you are writing a unit test, figure out the name of the add_user function and its arguments is easy. Some IDEs would autocomplete the name and show you the argument list. And if the name of add_user changes, some refactoring tools will even fix your tests for you.</p>
<p>But &#8220;/user/create&#8221; and &#8220;username=john&#8221; are strings. To figure them out you&#8217;ll have to know how your application handles routing, and how the parameters are passed and parsed. If your application changes from &#8220;/user/create&#8221; to &#8220;/user/add&#8221; the test will just break, and most likely, with a not-very-useful error message. Which takes into the next issue&#8230;</p>
<h2>They are not very useful</h2>
<p>They are not very useful because their failures are cryptic. When you write a test that calls method <tt>blah</tt>, which calls method <tt>bleh</tt>, which calls method <tt>blih</tt>, and then <tt>bloh</tt> and <tt>bluh</tt> and <tt>bluh</tt> divides by zero, you get an exception and a stack trace. Something like:</p>
<pre>bluh:123: Division by zero! <a href="http://pupeno.com/blog/trying-to-find-exceptions-in-haskell/">I can't divide by zero (I'm not Haskell)</a>
bloh:234: bluh(...)
blih:452: bloh(...)
bleh:34: blih(...)
blah:94: bleh(...)
blah_test:754: blah(...)</pre>
<p>You know that the test <tt>blah_test</tt> failed on line 754 when calling <tt>blah</tt>, which called <tt>bleh</tt><tt> on line 94, which called </tt><tt>blih</tt> on line 34, which called <tt>bloh</tt> on line 452 which called <tt>bluh</tt> on line 234 which dived by zero on line 123. You jump to <tt>bluh</tt>, line 123, and you may find something like:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">a <span style="color: #008000;">=</span> i <span style="color: #008000;">/</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span></pre></div></div>

<p>where you replace the zero with something else; or most likely:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">a <span style="color: #008000;">=</span> i <span style="color: #008000;">/</span> j<span style="color: #008000;">;</span></pre></div></div>

<p>where you have to track where <tt>j</tt> came from. Either it was calculated there or generated from another method and passed as an argument. The stack-trace gives you all the information you need to find where <tt>j</tt> was generated or where it came from. That&#8217;s a very useful test.</p>
<p>When you have HTTP in the middle, tests become much less useful. The stack trace of a failure would look something like:</p>
<pre>http_request:123: Time out, server didn't respond.
blah_test:45: http_request(...)</pre>
<p>That means that <tt>blah_test</tt> failed on line 45 making an http request call which failed with a timeout. Did your application divide by 0 and crashed? Did it try to calculate pi and it&#8217;s still doing it? Did it failed to connect to the database? Where did it actually fail? You don&#8217;t know. The only thing you know is that something went wrong. Time to open the log files and figure it out.</p>
<p>You open the log file and you find there&#8217;s not enough information there. You make the application log much, much more. So much that you&#8217;ll fill a terabyte in an hour. You run the test again and this time it just passes, no errors.</p>
<p>When you are at the HTTP level there are many, many things that are flaky and can go wrong. Let&#8217;s invent one example here: the web server you were using for the tests wants to DNS resolve everything it can. Every host name is resolved to the ip, and every ip is reverse-resolved to a name. When you run the test there was a glitch and your name servers were down. Now they are working correctly and they&#8217;ll never fail for another year. Good luck figuring it out from a  time-out message.</p>
<p>The other way in which HTTP tests fail is something like this:</p>
<pre>blah_test:74: Index out of bound for this array</pre>
<p>You go to line 74 and it&#8217;s something like:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">assert_equal<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;username&quot;</span>, data<span style="color: #000000;">&#91;</span><span style="color: #FF0000;">0</span><span style="color: #000000;">&#93;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>If <tt>data[0]</tt> caused an out-of-bound error, then the array data is empty. How can it be empty? It contains the response from the server and you know the server is responding with something usable because you are using the app right now.</p>
<p>What happened was that the log in box used to have the id, in HTML, <tt>"login"</tt> and it is now <tt>"log-in"</tt>. That means the HTML parsing methods on <tt>blah_test</tt> don&#8217;t find the log in box and fail to properly fill the array data. Yet another case of tests exposing bugs, in the tests. And the real-life failures are much, much more complex like this.</p>
<h2>My recommendation</h2>
<p>All this makes the return of investment of writing HTTP tests quite low. They are very hard to write and they provide very little information when they fail. They do provide good information when they pass: if it works at the HTTP level, probably everything else works too.</p>
<p>I&#8217;d recommend any project not to write any HTTP test unless every other possible test, unit and integration, is already written.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/closing-tag-in-xml/' rel='bookmark' title='Permanent Link: Closing tag in XML'>Closing tag in XML</a></li>
<li><a href='http://pupeno.com/blog/quick-and-dirty-continuous-testing-with-ruby-on-rails/' rel='bookmark' title='Permanent Link: Quick and dirty continuous testing with Ruby on Rails'>Quick and dirty continuous testing with Ruby on Rails</a></li>
<li><a href='http://pupeno.com/blog/are-dynamic-languages-just-a-temporary-workaround/' rel='bookmark' title='Permanent Link: Are dynamic languages just a temporary workaround?'>Are dynamic languages just a temporary workaround?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/the-sad-truth-about-testing-web-applications/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Computer Science and Software Engineers</title>
		<link>http://pupeno.com/blog/computer-science-and-software-engineers/</link>
		<comments>http://pupeno.com/blog/computer-science-and-software-engineers/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 18:00:53 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[comment]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[cs]]></category>
		<category><![CDATA[Joel Spolsky]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[software engineers]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1142</guid>
		<description><![CDATA[
			
				
			
		
Joel Spolsky published yet another complaint about what they teach people to get a Computer Science degree. I think he is right in complaining that no university is producing the kind of programmers he wants, but he&#8217;s missing one point.
In Argentina there are two different careers related to programming: Computer Science, and Software Engineering. Computer [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fcomputer-science-and-software-engineers%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fcomputer-science-and-software-engineers%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Joel Spolsky published <a href="http://www.joelonsoftware.com/items/2009/10/26.html">yet another complaint about what they teach people to get a Computer Science degree</a>. I think he is right in complaining that no university is producing the kind of programmers he wants, but he&#8217;s missing one point.</p>
<p>In Argentina there are two different careers related to programming: Computer Science, and Software Engineering. Computer Science, like its counterpart in USA produces scientist. Scientist are people not very much concerned about what&#8217;s practical or useful, but by advancing knowledge.</p>
<p>You don&#8217;t expect physicists (scientists) to build a bridge. Although they may understand all the forces at play, they don&#8217;t have the practical training. You have civil engineers that know how to build a bridge. Civil engineers, on the other hands, don&#8217;t play with subatomic particles, the beginning of the universe and black holes. They generally don&#8217;t advance knowledge, they build practical things</p>
<p>In the same vein, one should expect nothing else of a Computer Scientist than to use Haskell, push the advance of  type inference, experiment with artificial intelligence, dream of computers with a teracores (that is 10<sup>12</sup> cores) and know nothing about deploying servers, Microsoft tools, etc. And you do expect a Software Engineering to know how to use Java, C#, Python or other current languages and never touch Haskell. They should also be able to organize themselves using agile or whatever to produce working practical products.</p>
<p>The Computer Science and Software Engineering careers in Argentina more or less reflect that. It&#8217;s not a clear cut but in CS you can find lessons in Artificial Intelligence while on Software Engineering you even find some lessons about laws. Not sure what they are about, but a Software Engineer does require some basic knowledge of licensing.</p>
<p>I thin Joel Spolsky and many others are right about complaining that universities don&#8217;t produce software engineers, but I think he is wrong about expecting them out of Computer Science departments. It would be very sad if Computer Science turns into Software Engineering and there&#8217;s nobody to dream of type inference and teracores.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/complexity-of-writing-software/' rel='bookmark' title='Permanent Link: Complexity of writing software'>Complexity of writing software</a></li>
<li><a href='http://pupeno.com/blog/science-is-cool/' rel='bookmark' title='Permanent Link: Science is cool'>Science is cool</a></li>
<li><a href='http://pupeno.com/blog/is-it-science-fiction/' rel='bookmark' title='Permanent Link: Is it Science Fiction?'>Is it Science Fiction?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/computer-science-and-software-engineers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>150 years ago</title>
		<link>http://pupeno.com/blog/150-years-ago/</link>
		<comments>http://pupeno.com/blog/150-years-ago/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 19:36:44 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[rant]]></category>
		<category><![CDATA[Esperanto]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1471</guid>
		<description><![CDATA[
			
				
			
		
150 years ago a great man was born. His name was Ludovic Lazarus Zamenhof and he was born to a world divided by language, a world of constant violence between polish, jews, russians, etc. All speaking different languages. He thought the problem of the world was that people could not understand each other and set [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2F150-years-ago%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2F150-years-ago%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>150 years ago a great man was born. His name was Ludovic Lazarus Zamenhof and he was born to a world divided by language, a world of constant violence between polish, jews, russians, etc. All speaking different languages. He thought the problem of the world was that people could not understand each other and set himself the task of fixing it.</p>
<p>He invented what latter on became know as Esperanto. You can go to the Wikipedia and check the article on <a href="http://en.wikipedia.org/wiki/Esperanto">Esperanto</a> and on <a href="http://wikipedia.org/wiki/L._L._Zamenhof">Zamenhof</a> to get a lot of encyclopedic information. If you want to actually taste or learn the language, my recommendation is to go to <a href="http://lernu.net">Lernu</a>. And with that you can learn your first Esperanto word (if you don&#8217;t know any yet): lernu means learn, as in &#8220;you learn&#8221;. Lerni means to learn.</p>
<p>In this post I will tell you some things I find interesting about Esperanto.</p>
<p>Let&#8217;s go on with lerni. School is lernejo. See the relationship? lern &#8211; ej &#8211; o is school. Ej means a &#8220;a place for&#8221;, so lernejo is literarily a place to learn. There are other places like laborejo, which is the place to work. Laboro means work (think of &#8216;labor unions&#8217;).</p>
<p>Zamenhof thought about the task of creating the Esperanto dictionary and the task was so big he thought it was the end. Until he came up with the idea of allowing people to build words. My English-Esperanto, Esperanto-English dictionary is 75% for English, 25% for Esperanto. There are less words to learn in Esperanto.</p>
<hr />
<p>Did you know the Wikipedia is available in Esperanto? If you go to wikipedia.org, you&#8217;ll see it <strong>among the languages with more than 100000 articles</strong>.</p>
<p><img class="aligncenter size-full wp-image-1472" title="Esperanto Wikipedia" src="http://pupeno.com/wp-content/uploads/2009/12/Esperanto-Wikipedia.png" alt="Esperanto Wikipedia" width="605" height="134" /></p>
<p>And if you go to the English wikipedia homepage, Esperanto is the only constructed language listed on the left column. Do you want to know something amazing? Vikipedio, the <strong>Esperanto Wikipedia</strong> is actually <strong>bigger than the Encyclopedia Britannica</strong>.</p>
<p>The legend goes that Zamenhof released his book about Esperanto, called La Unua Libro (the first book) and <strong>six months latter someone nocked at his door speaking Esperanto and asking to practice the language</strong>. Esperanto spread like wildfire, unlike any other constructed language.</p>
<hr />
<p><img class="alignright size-full wp-image-1473" title="Pasporta-servo" src="http://pupeno.com/wp-content/uploads/2009/12/Pasporta-servo.jpg" alt="Pasporta-servo" width="300" height="153" />Today it is estimated that <strong>there are 2 million Esperantists</strong> in the world. If you consider that 122 years ago there was only one Esperanto speaker, <strong>it&#8217;s growing quite fast</strong>. I would expect its growth is accelerating but it&#8217;s very hard to know. No census asks about Esperanto. I know someone that made a informal survey asking for people that spoke Esperanto on the streets of Zürich and then actually asking questions in Esperanto and he got <strong>3% positive response</strong>.</p>
<p>Those 2 million speakers are not concentrated in one location, they are spread through the world so you are very likely to <strong>find Esperanto-speakers everywhere</strong> if you know where to look.</p>
<p>There are even an estimate of <strong>1000 native Esperanto speakers</strong>. Basically that happens when a family is formed by a man and a woman who only share Esperanto as a common language. Even if they don&#8217;t actively teach their children Esperanto, they learn to be able to understand their parents. I know a couple of people that speak it natively.</p>
<hr />
<p>When talking about how many people speaks the language, it&#8217;s important to mention that <strong>Esperanto speakers were hunted</strong> by many totalitarian goverments. The <strong>Nazi government specially targeted them</strong> because Zamenhof was jewish and according to Hitler as expressed in his My Fight, Esperanto was the language to be used by the International Jewish Conspiracy to set a new world order.</p>
<p><strong>In the Soviet Union Esperanto was embraced</strong> at first. Most socialists parties saw the potential for international communication and understanding. <strong>Joseph Stalin</strong> saw it as a way to spread the ideals of communism until they realized that it was a two way street, new ideas would come from outside, including capitalism, and <strong>denounced Esperanto as the language of spies</strong>. Imperial Japan didn&#8217;t like the language either.</p>
<p>In all those cases of totalitarism, Esperanto was forbidden and Esperantists hunted, exiled or even executed.</p>
<hr />
<p>The <strong>first Esperanto congress</strong> was held in <strong>1905</strong>, bringing 600 people together from across the world. since then it was held every year except during the world wars with an average of <strong>2000 participants</strong>. When it was done in China it was the <strong>b</strong><strong>iggest gathering of foreign people ever to happen in China</strong>.</p>
<hr />
<p>There&#8217;s a very practical reason to adopt Esperanto. Currently we waste a lot of resources pretending English is an adequate medium of international communication and in translation. Let me give you one example. In 1975 the World Health Organization denied the following requests:</p>
<ul>
<li>$ 148,200 to improve the health service in Bangladesh</li>
<li>$ 83,000 to fight leprosy in Burma</li>
<li>50 cents per patient to cure trachoma, which causes blindness.</li>
<li>$ 26,000 to improve hygiene in the Dominican Republic</li>
</ul>
<p>All those requests denied. It seems the World Health Organization didn&#8217;t have much money. But that same year they a<strong>pproved Arabic and Chinese</strong> as working languages requiring lots of translations and increasing the expenses of the WHO by <strong>$ 5,000,000 per year</strong>. That&#8217;s right, 5 million dollars per year spent on translation when they couldn&#8217;t give 50 cents to cure trachoma.</p>
<hr />
<p>Esperanto is probably the easiest to learn usable language out there. The Institute of Cybernetic Pedagogy at Paderborn compared how long it would take French speaking people to learn different languages to reach the same level:</p>
<ul>
<li>2000 hours studying German</li>
<li>1500 hours studying English</li>
<li>1000 hours studying Italian</li>
<li>150 hours studying Esperanto</li>
</ul>
<p>Yes, a tenth of the time it takes to learn English and less than that when compared to German. And something very interesting happens here. The third language you learn takes less effort than the second one.</p>
<p>If you want to learn another language, let&#8217;s say, German, it&#8217;ll take you less time to learn Esperanto and then learn German than to just learn German. Yes, you&#8217;ve read right. Less time to learn two languages than one.</p>
<p>That experiment was done by teaching one year of Esperanto and four of French to some students while five of French to others. The amount of time studying was the same but those that spoke Esperanto first reached a better French level. So even if you never utter a single Esperanto word out there, it makes economical sense to learn it first, before you learn another language.</p>
<hr />
<p>Many said that Esperanto will never take off and they proceed to never learn it and accept a divided broken world. If you are among those, I&#8217;m sorry about your defeat. I&#8217;d rather hope and do my part and learn Esperanto. It&#8217;s not that hard.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/the-need-for-a-common-language/' rel='bookmark' title='Permanent Link: The need for a common language'>The need for a common language</a></li>
<li><a href='http://pupeno.com/blog/my-first-esperanto-experience/' rel='bookmark' title='Permanent Link: My first Esperanto experience'>My first Esperanto experience</a></li>
<li><a href='http://pupeno.com/blog/the-first-time-i-heard-about-esperanto/' rel='bookmark' title='Permanent Link: The first time I heard about Esperanto'>The first time I heard about Esperanto</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/150-years-ago/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Is it Science Fiction?</title>
		<link>http://pupeno.com/blog/is-it-science-fiction/</link>
		<comments>http://pupeno.com/blog/is-it-science-fiction/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 16:47:35 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[announcement]]></category>
		<category><![CDATA[sci fi]]></category>
		<category><![CDATA[science fiction]]></category>
		<category><![CDATA[scifi]]></category>
		<category><![CDATA[sf]]></category>
		<category><![CDATA[web app]]></category>
		<category><![CDATA[web site]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1444</guid>
		<description><![CDATA[
			
				
			
		
I go to a book store and after looking around I&#8217;m forced to ask.
- Excuse me, where&#8217;s the science fiction section?
The woman points to the back of the book store, to a poorly lit section, next to the book for kids sector full of toys and little chairs. Well, at least they have a section. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fis-it-science-fiction%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fis-it-science-fiction%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I go to a book store and after looking around I&#8217;m forced to ask.</p>
<p>- Excuse me, where&#8217;s the science fiction section?</p>
<p>The woman points to the back of the book store, to a poorly lit section, next to the book for kids sector full of toys and little chairs. Well, at least they have a section. From where I&#8217;m standing it look like a whole section, it probably has around 500 books. There must be something that I haven&#8217;t read.</p>
<p>When I arrive I notice that a whole shelf consist of Lord of the Rings books. I continue scanning and I see a lot of stuff about dragons and vampires. There&#8217;s even a copy of Harry Potter left over when it wasn&#8217;t popular enough and didn&#8217;t deserve the huge tower of books in the middle of the bookstore.</p>
<p>Where is the science in wizards, dragons and magic rings? You know, Science Fiction is called that way for a reason. If I wanted to read fantasy I would have gone to the fantasy section, thank you very much.</p>
<p>This is not the worst. I&#8217;ve seen countless top ten science fiction TV shows list that included <a href="http://isitsciencefiction.com/items/buffy-the-vampire-slayer">Buffy</a> and <a href="http://isitsciencefiction.com/items/angel">Angel</a>. &#8220;Science Fiction&#8221; is not a label for weird. I was throwing a huge tantrum about it and my wife, in her infinite understanding said:</p>
<p>- Maybe they don&#8217;t know it isn&#8217;t science fiction.</p>
<p>How could they not know? It says &#8220;science&#8221; in the name. But apparently people are not very logical and never think what a name means (and keep calling the United Kingdom England, The Netherlands Holland, and United States of America, well, America, which is a continent, not a country).</p>
<p>I&#8217;ve decided to solve this problem once and for all in the geek-programmer way, which is of course, a web site with voting. I created:</p>
<p style="text-align: center;"><a href="http://isitsciencefiction.com">Is it Science Fiction?</a></p>
<p>Of course, if everybody voted we would end up with a mess the world is today, but I hope only geeks will put up with my bad graphical design skills and actually vote and comment so we&#8217;ll end up with pretty good results. So far <a href="http://isitsciencefiction.com/items/star-wars">Star Wars</a> is 4th from the bottom, heavily on the not-sci-fi side of things, so I&#8217;m pretty sure it&#8217;s working. You have to be very hard core to believe <a href="http://isitsciencefiction.com/items/star-wars">Star Wars is not Science Fiction</a>.</p>
<p>My goal is to build the canonical place to point to when the discussion about whether something is or isn&#8217;t science fiction starts. You won&#8217;t have to explain it yet again why <a href="http://isitsciencefiction.com/items/the-lord-of-the-rings">Lord of The Rings is fantasy, not science fiction</a>, just point to <a href="http://isitsciencefiction.com/items/the-lord-of-the-rings">http://isitsciencefiction.com/items/the-lord-of-the-rings</a>. If <a href="http://isitsciencefiction.com/items/new">your favorite pet peeve is not there, feel free to add it</a>.</p>
<p>Of course we are only judging whether something is or isn&#8217;t science fiction, not whether something is good or bad. <a href="http://isitsciencefiction.com/items/batman">Batman is great, but it&#8217;s not Science Fiction</a>. <a href="http://isitsciencefiction.com/items/plan-9">Plan 9 From Outer Space sucks, but it is Science Fiction</a> (well, I don&#8217;t know, I haven&#8217;t seen it yet).</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/science-is-cool/' rel='bookmark' title='Permanent Link: Science is cool'>Science is cool</a></li>
<li><a href='http://pupeno.com/blog/fiction-blogging/' rel='bookmark' title='Permanent Link: Fiction blogging'>Fiction blogging</a></li>
<li><a href='http://pupeno.com/blog/computer-science-and-software-engineers/' rel='bookmark' title='Permanent Link: Computer Science and Software Engineers'>Computer Science and Software Engineers</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/is-it-science-fiction/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>An intelligent music player</title>
		<link>http://pupeno.com/blog/an-intelligent-music-player/</link>
		<comments>http://pupeno.com/blog/an-intelligent-music-player/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 18:00:12 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[idea]]></category>
		<category><![CDATA[Amarok]]></category>
		<category><![CDATA[intelligent]]></category>
		<category><![CDATA[iTunes]]></category>
		<category><![CDATA[machine learning]]></category>
		<category><![CDATA[MP3]]></category>
		<category><![CDATA[music]]></category>
		<category><![CDATA[Ogg]]></category>
		<category><![CDATA[player]]></category>

		<guid isPermaLink="false">16</guid>
		<description><![CDATA[
			
				
			
		
I still haven&#8217;t found a good music player, for my computer that is. The one that got the closest to it was Amarok, but still it was very far away. My problem is that I don&#8217;t know what to listen to, really! I&#8217;m only just finding out what music to use  for coding. There&#8217;s one thing [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fan-intelligent-music-player%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fan-intelligent-music-player%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><img class="alignright size-medium wp-image-976" title="einstein-violin" src="http://pupeno.com/wp-content/uploads/2009/08/einstein-violin-300x281.jpg" alt="einstein-violin" width="300" height="281" />I still haven&#8217;t found a good <a href="/tag/music/">music</a> player, for my computer that is. The one that got the closest to it was <a href="http://amarok.kde.org">Amarok</a>, but still it was very far away. My problem is that I don&#8217;t know what to listen to, really! <a href="/blog/music-for-coding/">I&#8217;m only just finding out what music to use  for coding</a>. There&#8217;s one thing I really want from a music player: for it learn what to play for me. It&#8217;s not the same as learning what I like. It&#8217;s much more complex. Amarok learns what I like, but not really what to play for me.</p>
<p>In Amarok, when you jump to the next song it checks how much of the song you listened and assigns a score based on that. For songs that you listen completely you get a high score and for songs you listen only for a couple of seconds a low score. Over time, as you listen, those you like most and listen most will get high scores while those you despise and jump immediately will get a lower score.</p>
<p>Amarok has a special playing list, or used to have in the 1.4 version, which is called &#8220;dynamic&#8221; and plays those songs with the highest score. That sounds excellent, but it&#8217;s not enough. This music player I&#8217;d like to have would not compute how much I like a song, like Amarok, but how probable it is that  I&#8217;ll like it when it plays that song.</p>
<p>Let&#8217;s call this player Pamup, <strong>Pa</strong>blo&#8217;s <strong>Mu</strong>sic <strong>P</strong>layer, and let&#8217;s see how it could provide such a magic feat as playing songs that you want to listen (even if you don&#8217;t know you want to listen to them).</p>
<p>Pamup would have a scoring for the songs but instead of being a linear score it&#8217;ll be multidimensional. Let&#8217;s start with two simple dimensions and the rest will be clear: percent of playing time and time of the day. Song A you play 100% and song B 50%. That means that you like song A better than B. That is what Amarok does. Pamup would instead record:</p>
<ul>
<li>Song A in the morning: 100%</li>
<li>Song B in the morning: 50%</li>
<li>Song A in the evening: 50%</li>
<li>Song B in the evening: 100%</li>
</ul>
<p>You like A as much as B, but you are more likely to want to listen to A in the morning, and B in the evening. Of course adding the time of the day will probably not improve the equation by much. The idea would be to add as many dimensions as possible. Some dimensions may be irrelevant and they should cancel themselves out, like in this case:</p>
<ul>
<li>Song A in the morning: 100%</li>
<li>Song B in the morning: 50%</li>
<li>Song A in the evening: 100%</li>
<li>Song B in the evening: 50%</li>
</ul>
<div>In that case, you like A better than B, in the evening and in the morning. The time of the day is irrelevant. Maybe it&#8217;s only irrelevant for some songs but not for other:</div>
<ul>
<li>Let it be, I like it at all times.</li>
<li><a href="http://en.wikipedia.org/wiki/File:Carl_Orff-Carmina_Burana-O_Fortuna.ogg">O Fortuna of Carmina Burana</a>, please, don&#8217;t wake me up with that (or maybe yes, please do, not sure).</li>
</ul>
<p>Maybe it&#8217;s irrelevant for some people, but not for others. I don&#8217;t know and we don&#8217;t need to know.</p>
<p>I can think of many other dimensions to add to the system and I&#8217;m sure many other people will think of more and as technology improves we&#8217;ll be able to have even more:</p>
<ul>
<li><strong>What program are you using?</strong> I want music that helps me concentrate when I&#8217;m using my text editor to write code while I don&#8217;t care much about what I&#8217;m listen to while web browsing.</li>
<li><strong>What are you browsing?</strong> Maybe I do care about the music while I&#8217;m web browsing. <a href="http://reddit.com">Reddit</a>ing and Facebooking can be done pretty much with any music, but if I&#8217;m at <a href="http://lambda-the-ultimate.org/">Lambda the Ultimate</a>, I need something to concentrate. Even some analysis of the web site could give some important hints: lot&#8217;s of dense text, no pictures, play Mozzart; a photo blog, play whatever.</li>
<li><strong>How are you controlling the player? </strong>Are you using the keyboard with global shortcuts? you are probably doing something else. Are you using the remote control? you are probably away from the computer. Are you using the mouse directly into the players window with the lyrics window open? Ok, let&#8217;s play something with lyrics because you probably feel like reading, maybe even signing.</li>
<li><strong>Are you singing?</strong> When can find that out using the computer&#8217;s microphone. Let&#8217;s play things that are in your vocal range, and mostly by the same gender as you are. Let&#8217;s also play things you liked singing before.</li>
<li><strong>Are you using only one app or switching between various apps?</strong></li>
<li><strong>Which apps are you switching with?</strong></li>
<li><strong>Is there any other sound coming out from the computer?</strong> If so, maybe soothing background music with not much volume is what the player should play.</li>
<li><strong>Are you dancing</strong>? Let&#8217;s disco! You think that&#8217;s a tough one? Most smart phones have accelerometers in them, if you have the smart phone on your pocket I&#8217;m sure I can find out if you are in the couch or dancing, or maybe moving but not dancing. Even the raw input of the accelerometer could be used as a signal, because it&#8217;ll be different depending how tired you are and how you are dancing.</li>
<li><strong>Are you alone?</strong> You think that&#8217;s a hard one as well? Many people are using wifi, so, what&#8217;s the strength signal received on other devices on the same network?. If another computer has a similar signal level as yours and it is being used, you probably are not alone. It could also be done using smart phones, although with a smart phone you don&#8217;t require to be in use, you require it not to be on the table. If it&#8217;s plugged into the computer, you can ignore it, if it&#8217;s flat and not moving (accelerometer again), you can ignore it.</li>
<li><strong>Who are you with?</strong> I hope by now you realize how much we can find out. Let&#8217;s make it social, let&#8217;s have the app in every device. Why would people install it? Well, when you visit me, if you have it on your device, you&#8217;ll device will tell my computer what you like, and my computer knows what I like, so it&#8217;ll try to find a common ground for us (and it won&#8217;t trust me that much when I skip a song, because maybe it&#8217;s you skipping it). We could make you use your own smart phone to skip it, and then Pumap knows who is skipping it.</li>
<li><strong>Who are you talking with?</strong> If you are talking with other people, using voice recognition you may identify that people, or at least how many there are. If there&#8217;s cutlery clater in the background, people are eating, let&#8217;s just play background music for a nice evening. If it&#8217;s only you speaking, maybe you are in an old land-line phone (if you were using your smart phone, Pumap would know), let&#8217;s cut the music altogether, probably it&#8217;s distracting.</li>
</ul>
<p>I believe this program should not work with special cases but have some very sofisticated machine learning system where we input all these signals and does the right thing. And as more signals become available, they are added and analyzed as well. I would like to have that music program! Because honestly, really, I&#8217;m not sure what music I want to listen to. I want my computer to figure it out for me.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/the-tracker-for-movies/' rel='bookmark' title='Permanent Link: The tracker for movies'>The tracker for movies</a></li>
<li><a href='http://pupeno.com/blog/music-for-coding/' rel='bookmark' title='Permanent Link: Music for coding'>Music for coding</a></li>
<li><a href='http://pupeno.com/blog/a-feature-we-need-for-the-post-pc-era/' rel='bookmark' title='Permanent Link: A feature we need for the post-PC era'>A feature we need for the post-PC era</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/an-intelligent-music-player/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Breaking the Monopoly-design monopoly</title>
		<link>http://pupeno.com/blog/breaking-the-monopoly-design-monopoly/</link>
		<comments>http://pupeno.com/blog/breaking-the-monopoly-design-monopoly/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 18:00:57 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[idea]]></category>
		<category><![CDATA[board]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[Hasbro]]></category>
		<category><![CDATA[Monopoly]]></category>
		<category><![CDATA[toy]]></category>

		<guid isPermaLink="false">66</guid>
		<description><![CDATA[
			
				
			
		
I am talking about the game, you know, Monopoly! There are so many versions of it but the other day I&#8217;ve seen the most interesting one. No, not the Esperanto one: Monopolo. A do it yourself Monopoly, or a Make it yourself-opoly.
From that I&#8217;m deriving the idea, why can&#8217;t you design your Monopoly in a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fbreaking-the-monopoly-design-monopoly%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fbreaking-the-monopoly-design-monopoly%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><img class="alignright size-full wp-image-67" title="monopoly" src="http://pupeno.com/wp-content/uploads/2009/07/monopoly.png" alt="monopoly" width="414" height="107" />I am talking about the game, you know, <a href="http://en.wikipedia.org/wiki/Monopoly_(game)">Monopoly</a>! There are so many versions of it but the other day I&#8217;ve seen the most interesting one. No, not the <a href="http://koplushia.tripod.com/Monopolo/index.html">Esperanto one: Monopolo</a>. <a href="http://www.amazon.com/gp/product/B00000K2IO?ie=UTF8&amp;tag=pupeno-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B00000K2IO">A do it yourself Monopoly, or a Make it yourself-opoly</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=pupeno-20&amp;l=as2&amp;o=1&amp;a=B00000K2IO" border="0" alt="" width="1" height="1" />.</p>
<p>From that I&#8217;m deriving the idea, why can&#8217;t you design your Monopoly in a web application, or even in a desktop one but that ultimately submits it to the web and you get the finished game delivered to your home. You add pictures, you pick themes, you pick the title, the language, the currency. It could make a perfect purchase or a magnificent gift.</p>
<p>Why can&#8217;t you sell it to other people? Like you do for stuff in CafePress. Hasbro would take some earnings but all the design is ultimately crowd-sourced, the designer also gets some money. I find one reason why that may not work and that&#8217;s because most stuff for which is worth it to make a monopoly are also copyrigthed. Average Joe wouldn&#8217;t be able to make a Monopoly of his favorite movie without striking a deal with the movie makers, which is not likely for average Joe.</p>
<p>But the movie makers could make them in a self-service way. That&#8217;s also unlikely to happen. But an <a href="http://xkcd.com">xkcd</a> Monopoly? That&#8217;s likely to happen and sell quite a few copies. Companies with a sense of humor or with a good PR would have some employee doing tha. Do you imagine Microsoft or Google Monopoly with each property being a product. Do you want to buy Office? Do you want to buy Chrome? Do you want to play as Bill Gates? Steve Ballmer? Larry Page? I know some geeks would stack them up and have one of each of those.</p>
<p>I thought about starting to make the web application for designing a Monopoly. It could generate PDFs that you download and print and paste in a normal board as an interim while not having any production. But there&#8217;s only one company that can legally do this: Hasbro, and <a href="http://www.joelonsoftware.com/items/2009/06/10c.html">having only one company as your potential exit is not a good idea</a>. So it was dropped from the ideas board into here, my blog.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/breaking-the-monopoly-design-monopoly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What Joel Spolsky doesn&#8217;t understand about Linux</title>
		<link>http://pupeno.com/blog/what-joel-spolsky-doesnt-understand-about-linux/</link>
		<comments>http://pupeno.com/blog/what-joel-spolsky-doesnt-understand-about-linux/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 21:51:06 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[FogBugz]]></category>
		<category><![CDATA[Joel Spolsky]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[operating system]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1433</guid>
		<description><![CDATA[
			
				
			
		
Once again I hear Joel Spolsky saying the same thing about Linux that I consider wrong. I&#8217;m sure I&#8217;m not the only one thinking that and I&#8217;m sure I&#8217;m not the only one writing about it, but I&#8217;m going to do it anyway. Joel&#8217;s position is that administrating Linux must be harder because something like [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fwhat-joel-spolsky-doesnt-understand-about-linux%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fwhat-joel-spolsky-doesnt-understand-about-linux%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Once again I hear Joel Spolsky saying the same thing about Linux that I consider wrong. I&#8217;m sure I&#8217;m not the only one thinking that and I&#8217;m sure I&#8217;m not the only one writing about it, but I&#8217;m going to do it anyway. Joel&#8217;s position is that administrating Linux must be harder because something like 70% of the support calls they handle for FogBugz come from Linux while it is less than 30% of its market.</p>
<p>I&#8217;d agree that for someone that doesn&#8217;t know anything about administrating, getting a Windows server running is easier than getting a Linux server running. I think that being an expert in both environments is equally hard. The sysadmin problems are hard and there are no shortcuts.</p>
<p>But Joel Spolsky point is wrong in one regard: <a href="/blog/linux-is-not-an-operating-system/">Linux is not an operating system</a>. I&#8217;ve said it before and I&#8217;ve got many negative comments, mails, messages about it but very few actually got my point. This is an instance where Linux being taken for an operating system is causing someone pain and thus causing that someone to say something that is not completely right.</p>
<p>Joel makes FogBugz for Windows and Linux. Does that mean that I can run it on my Windows CE phone? It is a Windows, isn&#8217;t it? It says Windows in the name! It has a start button! Well, of course I can&#8217;t run FogBugz on it. They ship it for Windows the PC operating system. Does it work on <a href="http://www.reactos.org">ReactOS</a> then? In a sense it is a Windows PC operating system; an alternative implementation of one with all the same interfaces and libraries. Well, of course not. It work only in the Windows PC operating system produced by Microsoft. For example, Windows 7 Starter Edition, yes, that one that allows you to run only three apps at the time. Well, no!</p>
<p>All those things I mentioned are in a sense Windowses as well, yet they are not supported and probably FogBugz doesn&#8217;t work on them. Yet, he says he supports Linux. Saying you support Linux is like saying that you supports computers that have RAM. It&#8217;s too broad. Trying to ship something that should run on almost everything won&#8217;t work. Be it Linux or anything else.</p>
<p>Linux is only a kernel. It&#8217;s a kernel used by many different operating systems. Some of them radically different (like Android or Chrome OS). If you are a company and make a product supporting it on Linux is crazy. What should Joel do then?</p>
<p>He should support operating systems, not kernels. What operating systems should Joel support? I don&#8217;t know, whatever is popular. I&#8217;d guess Red Hat&#8217;s RHEL, Ubuntu, Debian are probably popular operating systems. Once you start supporting operating systems instead of kernels the world looks differently. You don&#8217;t have to deliver a tar.gz (a compressed archive) that should compile and run everywhere. It&#8217;s insane to ship that and it&#8217;s insane to expect users to be able to install them. I administer various Debian and Ubuntu servers and workstations. Do you know how often I compile source code that I haven&#8217;t written myself? <strong>Never!</strong></p>
<p>When you support an operating system like Ubuntu or Debian you can <strong>ship binaries</strong>. You build binaries in the form of debs or rpms. And you don&#8217;t build only one of them, you probably need one deb for Ubuntu, one deb for Debian and maybe even one deb for each version of Ubuntu if they vary enough. If you think this is a lot of work, then look at how much work is building a Windows installer that can work in any Windows from XP pre-SP1 without .Net to Windows 7. If it was trivial there wouldn&#8217;t be companies like InstallShield making money.</p>
<p>I&#8217;ve heard FogBugz comes with its own copy of MySQL and Apache. How Windowish! That&#8217;s crazy and meant to break. You don&#8217;t copy code, programs or libraries in the world of Linux-based operating systems. You set dependencies. You make a fogbugz.deb that depends on Apache and depends on MySQL and when fogbugz.deb is installed it will automatically install Apache and MySQL. It will install an Apache built, optimized and customized for that version of Apache that follows the Ubuntu guidelines for storing caches, config files, etc.</p>
<p>There&#8217;s more, since there are some pretty straighfoward guidelines where everything is installed, fogbugz.deb could work out of the box. In an Ubuntu box I can run</p>

<div class="wp-terminal">pupeno@wopr:$ aptitude install phpmyadmin<br/></div>

<p>and it works out of the box. And phpMyAdmin depends on Apache and MySQL. Of course I could break those services so that nothing works, but most people don&#8217;t. What the phpmyadmin package does is drop files in certain locations where Apache is going to pick them up. Apache as many other programs don&#8217;t have just one configuration files but directories of them, so you can drop another configuration file and it&#8217;s picked up.</p>
<p>I am very certain that if FogBugz was packaged in this fashion, then it would not generate as many phone calls as it does now. It is packaged and distributed like software in 1995 for Linux-based operating systems, when almost everything was a mess and chaotic and there were very few people putting it in production.</p>
<p>To close this post let me tell you something else to convince you that Linux is not an operating system. You can write a program for Linux, but then it runs just fine in OpenBSD. And then you find out that it also runs just fine in Solaris. Well, but you wrote it on a Debian box, which is Linux. Did you know that there&#8217;s a Debian kFreeBSD (or something like that)? which is Debian running the FreeBSD kernel. Debian kFreeBSD is more similar to Debian than to FreeBSD. Nexenta is Ubuntu with the Solaris kernel, and it&#8217;s more similar to Ubuntu than to Solaris. Android is Linux, yet almost none of the software that runs on Debian, FreeBSD, Nexenta, Solaris runs on Android.</p>
<p>You see, Linux is just one component, and not even the biggest component, of an operating system. It is not the component users interact with when using a computer and it is not even the component programmers interact most of the time, when writing a program. It makes almost <strong>no sense to say &#8220;I make this program for Linux&#8221;</strong>.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/linux-is-not-an-operating-system/' rel='bookmark' title='Permanent Link: Linux is not an operating system'>Linux is not an operating system</a></li>
<li><a href='http://pupeno.com/blog/cleaning-up-a-debian-gnulinux-or-ubuntu-reprise/' rel='bookmark' title='Permanent Link: Cleaning up a Debian GNU/Linux (or Ubuntu), reprise'>Cleaning up a Debian GNU/Linux (or Ubuntu), reprise</a></li>
<li><a href='http://pupeno.com/blog/cleaning-up-a-debian-gnulinux/' rel='bookmark' title='Permanent Link: Cleaning up a Debian GNU/Linux'>Cleaning up a Debian GNU/Linux</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/what-joel-spolsky-doesnt-understand-about-linux/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fiction blogging</title>
		<link>http://pupeno.com/blog/fiction-blogging/</link>
		<comments>http://pupeno.com/blog/fiction-blogging/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 18:00:51 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[idea]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[entretainment]]></category>
		<category><![CDATA[fun]]></category>

		<guid isPermaLink="false">34</guid>
		<description><![CDATA[
			
				
			
		
As stories can be told in first person, or third person, in the form of a diary or a tale, as book or comic or movie; I was thinking that blogging could be a literarly style as well.
I can think of two sub-genres. Historic and fantastic blogging.
For historic imagine a blog written in the context [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Ffiction-blogging%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Ffiction-blogging%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>As stories can be told in first person, or third person, in the form of a diary or a tale, as book or comic or movie; I was thinking that blogging could be a literarly style as well.</p>
<p>I can think of two sub-genres. Historic and fantastic blogging.</p>
<p>For historic imagine a blog written in the context of -70 (minus 70) years. So that on October 19th 2009 you&#8217;d get a post for October 19th 1939. Who would be the blogger? It could be an important person, what would Churchil blog? Or it could be an unnamed person, an anti-nazi frenchman for example. They could also have a Twitter account! It would be an interesting way to learn history.</p>
<p>The other genre would be total fantasy. A blogger in the future, imagine if for some strange reason, blog posts of a guy surviving the singularity travel back in time? What if blog posts from a galaxy far away? I would certainly follow those blogs! But of course, it&#8217;s hard work that requires a very good writer.</p>
<p>Another thing that could be applied to any fictional blogging is having a network of blogs. Imagine reading the blogs of a frenchman in the resistance, a nazi soldier, a Russian red-army member. All blogging about the same, from different perspective! What about reading the Twitter feeds of Frodo, Sam, Gandalf, Aragorn, Saruman?</p>
<p>I think it would be very entertaining.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/being-a-prolific-blogger/' rel='bookmark' title='Permanent Link: Being a prolific blogger'>Being a prolific blogger</a></li>
<li><a href='http://pupeno.com/blog/reviewers-in-a-wordpress-blog/' rel='bookmark' title='Permanent Link: Reviewers in a WordPress blog'>Reviewers in a WordPress blog</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/fiction-blogging/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Blood pressure and conclusion</title>
		<link>http://pupeno.com/blog/blood-pressure-and-conclusion/</link>
		<comments>http://pupeno.com/blog/blood-pressure-and-conclusion/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 21:37:32 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[Building Sano]]></category>
		<category><![CDATA[Sano]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1414</guid>
		<description><![CDATA[
			
				
			
		
In less than an hour, I quickly added blood pressure:

It was really quick and dirty and it doesn&#8217;t have an in-line form, but it&#8217;s there and it&#8217;s working. I wasn&#8217;t able to achieve as much as I could but I think I got pretty far for one weekend. And it&#8217;s very clear that by the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fblood-pressure-and-conclusion%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fblood-pressure-and-conclusion%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>In less than an hour, I quickly added blood pressure:</p>
<p><img class="alignnone size-full wp-image-1415" title="sano-020" src="http://pupeno.com/wp-content/uploads/2009/11/sano-020.png" alt="sano-020" width="582" height="666" /></p>
<p>It was really quick and dirty and it doesn&#8217;t have an in-line form, but it&#8217;s there and it&#8217;s working. I wasn&#8217;t able to achieve as much as I could but I think I got pretty far for one weekend. And it&#8217;s very clear that by the end, my speed was much greater than at the beginning, just compare the difference in time it took to implement each of the trackers.</p>
<p>I think the bigger time sinks were new stuff that I didn&#8217;t know. At the moment I was starting those I knew they were going to waste some time, but I was thinking in long term. Getting Formtastic to work as I wanted took some time, but now I&#8217;m able to create forms pretty fast. Starting to use nifty_generators took some time to actually find what they were and the syntax, but now every time I generate code I&#8217;m one step closer to finish it than before; and the look of the page is not hideous.</p>
<p>Another waste of time was figuring out how Rails and gems interacted. Some gems I add them and work, others don&#8217;t. Previously I included those gems manually in my code, but now I know how it works. During a couple of hours I wanted to make a much more advanced graph that would properly display 4 values or 400 values until I realized that it doesn&#8217;t have to be dynamic. When you want to see the last week, you pick last week, when you want to see last month, you pick that (well, a graph like Google&#8217;s Finance would be better, but ok, I&#8217;m humble). There&#8217;s no way to pick bigger range for the graph now, but the code is very ready for it.</p>
<p>I believe the experiment was a success: I can and I am very productive in Rails, same as with ASP.NET MVC or more.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/super-exception-notifier/' rel='bookmark' title='Permanent Link: Super Exception Notifier'>Super Exception Notifier</a></li>
<li><a href='http://pupeno.com/blog/im-going-to-do-an-experiment-today/' rel='bookmark' title='Permanent Link: I&#8217;m going to do an experiment today'>I&#8217;m going to do an experiment today</a></li>
<li><a href='http://pupeno.com/blog/simplifying-the-weight-crud/' rel='bookmark' title='Permanent Link: Simplifying the weight CRUD'>Simplifying the weight CRUD</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/blood-pressure-and-conclusion/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>First graph</title>
		<link>http://pupeno.com/blog/first-graph/</link>
		<comments>http://pupeno.com/blog/first-graph/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 19:59:40 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[Building Sano]]></category>
		<category><![CDATA[Sano]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1409</guid>
		<description><![CDATA[
			
				
			
		
It&#8217;s not perfect, but it&#8217;s a start:



No related posts.]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Ffirst-graph%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Ffirst-graph%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>It&#8217;s not perfect, but it&#8217;s a start:<br />
<img class="alignnone size-full wp-image-1410" title="sano-019" src="http://pupeno.com/wp-content/uploads/2009/11/sano-019.png" alt="sano-019" width="560" height="340" /></p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/first-graph/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Profile page: a RESTful single resource using Formtastic</title>
		<link>http://pupeno.com/blog/my-profile-page-a-restful-single-resource-using-formtastic/</link>
		<comments>http://pupeno.com/blog/my-profile-page-a-restful-single-resource-using-formtastic/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 13:49:52 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[Building Sano]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Sano]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1392</guid>
		<description><![CDATA[
			
				
			
		
I&#8217;ve just implemented the My Profile tab for Sano:

Can I write 500 words about? Well, I can try.
I like using RESTful routes. In case you don&#8217;t know what they are let me try to explain it quick, at least the relevant part. You normally have a set of route rules that would point /movies to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fmy-profile-page-a-restful-single-resource-using-formtastic%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fmy-profile-page-a-restful-single-resource-using-formtastic%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve just implemented the My Profile tab for <a href="http://sano.pupeno.com">Sano</a>:</p>
<p><img class="alignnone size-full wp-image-1393" title="sano-018" src="http://pupeno.com/wp-content/uploads/2009/11/sano-018.png" alt="sano-018" width="582" height="354" /></p>
<p>Can I write 500 words about? Well, I can try.</p>
<p>I like using RESTful routes. In case you don&#8217;t know what they are let me try to explain it quick, at least the relevant part. You normally have a set of route rules that would point /movies to the movie listing, /movies/new to a form to add a new movie, /movies/123 to see the movie 123. With RESTful routes in Rails all that is done automatic in a single line:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">map.<span style="color:#9900CC;">resources</span> <span style="color:#ff3333; font-weight:bold;">:movies</span></pre></div></div>

<p>What you are doing is defining a resource. The resource has several actions that can be performed on them:</p>
<ul>
<li>index (a.k.a.: listing)</li>
<li>new</li>
<li>edit</li>
<li>create</li>
<li>update</li>
<li>destroy</li>
</ul>
<p>In Sano I have a weights resource that is a very fine example of it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">map.<span style="color:#9900CC;">resources</span> <span style="color:#ff3333; font-weight:bold;">:weights</span></pre></div></div>

<p>Running the rake routes command we can see all the routes it generate:</p>
<pre>    weights GET    /weights(.:format)          {:action=&gt;"index", :controller=&gt;"weights"}
            POST   /weights(.:format)          {:action=&gt;"create", :controller=&gt;"weights"}
 new_weight GET    /weights/new(.:format)      {:action=&gt;"new", :controller=&gt;"weights"}
edit_weight GET    /weights/:id/edit(.:format) {:action=&gt;"edit", :controller=&gt;"weights"}
     weight GET    /weights/:id(.:format)      {:action=&gt;"show", :controller=&gt;"weights"}
            PUT    /weights/:id(.:format)      {:action=&gt;"update", :controller=&gt;"weights"}
            DELETE /weights/:id(.:format)      {:action=&gt;"destroy", :controller=&gt;"weights"}</pre>
<p>You see the (.:format) in there? That means that every route is also accessible in alternative formats. For example: xml. Go and try it, add some weights and access <a href="http://sano.pupeno.com/weights.xml">http://sano.pupeno.com/weights.xml</a>.</p>
<p>If you are curious, the code for that is this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> index
  <span style="color:#0066ff; font-weight:bold;">@weights</span> = user.<span style="color:#9900CC;">weights</span>.<span style="color:#9900CC;">all</span>
&nbsp;
  respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span>
    <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@weights</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>I now want everything to be a resource. How can &#8220;my profile&#8221; be a resource? Well, it&#8217;s not hard. It&#8217;s not a collection resource, it&#8217;s a single resource. There&#8217;s no list of profiles, no creation of new profiles or destruction of profiles. There&#8217;s only editing and updating of a single profile (which is actually your user).</p>
<p>It turns out that in <a href="/tag/ruby-on-rails">Rails</a>, that&#8217;s very easy to define:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">map.<span style="color:#9900CC;">resource</span> <span style="color:#ff3333; font-weight:bold;">:profile</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:edit</span>, <span style="color:#ff3333; font-weight:bold;">:update</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>Notice how it says &#8220;resource&#8221; instead of &#8220;resources&#8221; and it only allows certain actions. Rails is really quite flexible here, logging in is also a resource. It&#8217;s called session and you can create them, by logging in, or destroy them, by logging out (no editing). There&#8217;s also an extra action needed by OpenID. This is the route definition:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">map.<span style="color:#9900CC;">resource</span> <span style="color:#ff3333; font-weight:bold;">:session</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:new</span>, <span style="color:#ff3333; font-weight:bold;">:create</span>, <span style="color:#ff3333; font-weight:bold;">:destroy</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:member</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:finish_creating</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:get</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>The &#8220;member&#8221; part specifies that action to be only for items, not for the whole collection. If it was a collection resource, you could have extra listings. The same way you have index, you could have sorted_index.</p>
<p>The form in the my-profile-page is an example of what Formtastic is good at. This is the whole form:</p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&lt;%</span> semantic_form_for <span style="color:#0066ff; font-weight:bold;">@user</span>, <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> profile_url <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span> f.<span style="color:#9900CC;">inputs</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#5A0A0A; font-weight:bold;">input</span> <span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#5A0A0A; font-weight:bold;">input</span> <span style="color:#ff3333; font-weight:bold;">:email</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#5A0A0A; font-weight:bold;">input</span> <span style="color:#ff3333; font-weight:bold;">:height</span>, <span style="color:#ff3333; font-weight:bold;">:hint</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;meters&quot;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#5A0A0A; font-weight:bold;">input</span> <span style="color:#ff3333; font-weight:bold;">:gender</span>, <span style="color:#ff3333; font-weight:bold;">:as</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:radio</span>, <span style="color:#ff3333; font-weight:bold;">:collection</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;Male&quot;</span>, <span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;Female&quot;</span>, <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#5A0A0A; font-weight:bold;">input</span> <span style="color:#ff3333; font-weight:bold;">:birthday</span>, <span style="color:#ff3333; font-weight:bold;">:start_year</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1900</span>, <span style="color:#ff3333; font-weight:bold;">:end_year</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">year</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span> f.<span style="color:#9900CC;">buttons</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
   <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">commit_button</span> <span style="color:#ff3333; font-weight:bold;">:label</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Update profile&quot;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></div></div>

<p>Special thanks to <a href="http://workingwithrails.com/person/6491-ryan-bates">Ryan Bates</a> who covered the gender case in <a href="http://railscasts.com/">Railscasts</a> <a href="http://railscasts.com/episodes/184-formtastic-part-1">episode 184</a> and <a href="http://asciicasts.com/about">Eifion Bedford</a> of <a href="http://asciicasts.com/">ASCIIcasts</a> for making it <a href="http://asciicasts.com/episodes/184-formtastic-part-1">easy to find</a>. It surely would have take me some time to figure it out.</p>
<p>Can you please <a href="http://sano.pupeno.com/profile/edit">update your profile on Sano</a>?</p>
<p>There you go 553 words!</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/creating-the-weight-model-and-scaffolding/' rel='bookmark' title='Permanent Link: Creating the weight model and scaffolding'>Creating the weight model and scaffolding</a></li>
<li><a href='http://pupeno.com/blog/making-the-weight-crud-work-per-user/' rel='bookmark' title='Permanent Link: Making the weight CRUD work per user'>Making the weight CRUD work per user</a></li>
<li><a href='http://pupeno.com/blog/profile-models/' rel='bookmark' title='Permanent Link: Profile models'>Profile models</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/my-profile-page-a-restful-single-resource-using-formtastic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrations that change the schema</title>
		<link>http://pupeno.com/blog/migrations-that-change-the-schema/</link>
		<comments>http://pupeno.com/blog/migrations-that-change-the-schema/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 12:43:14 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[Building Sano]]></category>
		<category><![CDATA[migrations]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Sano]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1384</guid>
		<description><![CDATA[
			
				
			
		
Up until today I did everything with a lot of planning and I let my OCD use migrations in a way they were not intended: I would go back and fix old migrations and destroy the database and re-run them.
With Sano, as I went through as fast as I could, two things happened: I made [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fmigrations-that-change-the-schema%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fmigrations-that-change-the-schema%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Up until today I did everything with a lot of planning and I let my OCD use migrations in a way they were not intended: I would go back and fix old migrations and destroy the database and re-run them.</p>
<p>With <a href="http://sano.pupeno.com">Sano</a>, as I went through as fast as I could, two things happened: I made mistakes in the schema and those mistakes are now deployed. Time to make migrations to fix them.</p>
<p>The original migration for the weight model was like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">create_table <span style="color:#ff3333; font-weight:bold;">:weights</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
  t.<span style="color:#CC0066; font-weight:bold;">integer</span> <span style="color:#ff3333; font-weight:bold;">:user_id</span>
  t.<span style="color:#CC0066; font-weight:bold;">float</span> <span style="color:#ff3333; font-weight:bold;">:weight</span>
  t.<span style="color:#9900CC;">datetime</span> <span style="color:#ff3333; font-weight:bold;">:measured_at</span>
  t.<span style="color:#9900CC;">timestamps</span>
  t.<span style="color:#9900CC;">foreign_key</span> <span style="color:#ff3333; font-weight:bold;">:users</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>and then I created two destructive migrations:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">change_column <span style="color:#ff3333; font-weight:bold;">:weights</span>, <span style="color:#ff3333; font-weight:bold;">:measured_at</span>, <span style="color:#ff3333; font-weight:bold;">:date</span>
rename_column <span style="color:#ff3333; font-weight:bold;">:weights</span>, <span style="color:#ff3333; font-weight:bold;">:measured_at</span>, <span style="color:#ff3333; font-weight:bold;">:measured_on</span></pre></div></div>

<p>and</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">add_index <span style="color:#ff3333; font-weight:bold;">:weights</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user_id</span>, <span style="color:#ff3333; font-weight:bold;">:measured_on</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:unique</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#0000FF; font-weight:bold;">true</span></pre></div></div>

<p>The first one converted the measured_at datetime column in a measured_on date column. It destroys data, but I believe there&#8217;s no way that one could fail.</p>
<p>The second one adds an index for uniqueness between measured_on and user_id. That means that users can have only one weight per day. That one doesn&#8217;t destruct any data but it has the potential to fail when run on the production server.</p>
<p>I was about to just give it a try and pray. It&#8217;s not like thousands of people are using Sano anyway. Well, I&#8217;ve just realized I didn&#8217;t have to pray. I could test the migration first. It was trivial:</p>
<ol>
<li>Open local phpMyAdmin and go to sano_devel</li>
<li>Delete all tables in local sano_devel</li>
<li>Open remote phpMyAdmin and go to sano (the production database)</li>
<li>Export everything</li>
<li>Run SQL in sano_devel with the exported text</li>
<li>Try migrations</li>
</ol>
<p>Well, they worked:</p>

<div class="wp-terminal">pupeno@wopr:$ $ rake db:migrate<br/>(in /Users/pupeno/Projects/sano)<br/>==  ChangeMeasuredAtTypeAndName: migrating ====================================<br/>-- change_column(:weights, :measured_at, :date)<br/>-> 0.3609s<br/>-- rename_column(:weights, :measured_at, :measured_on)<br/>-> 0.1440s<br/>==  ChangeMeasuredAtTypeAndName: migrated (0.5056s) ===========================<br/><br/>==  AddUniquennessIndexToWeightUserIdMeasuredOn: migrating ====================<br/>-- add_index(:weights, [:user_id, :measured_on], {:unique=>true})<br/>-> 0.1171s<br/>==  AddUniquennessIndexToWeightUserIdMeasuredOn: migrated (0.1173s) ===========<br/></div>

<p>and while I&#8217;m at it, let&#8217;s test the down-migrations, so I can be sure that if something goes wrong on production, I can rollback:</p>

<div class="wp-terminal">pupeno@wopr:$ $ rake db:migrate VERSION=20091121135320<br/>(in /Users/pupeno/Projects/sano)<br/>==  AddUniquennessIndexToWeightUserIdMeasuredOn: reverting ====================<br/>-- remove_index(:weights, {:column=>[:user_id, :measured_on]})<br/>-> 0.2745s<br/>==  AddUniquennessIndexToWeightUserIdMeasuredOn: reverted (0.2748s) ===========<br/><br/>==  ChangeMeasuredAtTypeAndName: reverting ====================================<br/>-- rename_column(:weights, :measured_on, :measured_at)<br/>-> 0.1381s<br/>-- change_column(:weights, :measured_at, :datetime)<br/>-> 0.1335s<br/>==  ChangeMeasuredAtTypeAndName: reverted (0.2719s) ===========================<br/></div>

<p>Note: actually, there was a typo in the down-migrations; I&#8217;ve fixed it and everything was all right.</p>
<p>The new version with the improved forms is now deployed (the one I showed in the previous post), you can now play with it: <a href="http://sano.pupeno.com">sano.pupeno.com</a>.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/making-the-weight-crud-work-per-user/' rel='bookmark' title='Permanent Link: Making the weight CRUD work per user'>Making the weight CRUD work per user</a></li>
<li><a href='http://pupeno.com/blog/merging-users/' rel='bookmark' title='Permanent Link: Merging users'>Merging users</a></li>
<li><a href='http://pupeno.com/blog/creating-the-weight-model-and-scaffolding/' rel='bookmark' title='Permanent Link: Creating the weight model and scaffolding'>Creating the weight model and scaffolding</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/migrations-that-change-the-schema/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I love to code</title>
		<link>http://pupeno.com/blog/i-love-to-code/</link>
		<comments>http://pupeno.com/blog/i-love-to-code/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 03:51:19 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[Bulding Sano]]></category>
		<category><![CDATA[Formtastic]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Sano]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1374</guid>
		<description><![CDATA[
			
				
			
		
I said I was done for the day more than 6 hours ago, but I love to code, I couldn&#8217;t stop. I wanted to implement a small feature: make the creation of new weights simpler for the common case and I did it:

Note: That change is not yet deployed. I don&#8217;t play with servers while [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fi-love-to-code%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fi-love-to-code%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I said I was done for the day more than 6 hours ago, but I love to code, I couldn&#8217;t stop. I wanted to implement a small feature: make the creation of new weights simpler for the common case and I did it:</p>
<p><img class="alignnone size-full wp-image-1376" title="sano-017" src="http://pupeno.com/wp-content/uploads/2009/11/sano-017.png" alt="sano-017" width="608" height="607" /></p>
<p>Note: That change is not yet deployed. I don&#8217;t play with servers while I&#8217;m half-asleep.</p>
<p>This took awfully long. The problem was that in the process I&#8217;ve found a bug in Formtastic, which made me realize I was running version 0.2.4 when the latest version was 0.9.2. That is because I was using justinfrench-formtastic:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">config.<span style="color:#9900CC;">gem</span> <span style="color:#996600;">'formtastic'</span>, <span style="color:#ff3333; font-weight:bold;">:lib</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'justinfrench-formtastic'</span></pre></div></div>

<p>when I should have been using formtastic from gemcutter:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">config.<span style="color:#9900CC;">gem</span> <span style="color:#996600;">'formtastic'</span></pre></div></div>

<p>When I moved to 0.9.2 I&#8217;ve found two bugs on it, one was temporary solved and then reverted (and <a href="http://github.com/pupeno/formtastic/commit/d85fedb1b3fdff3d31ab8de8e22eaaba45676d1f">I fixed it by reverting the revertion</a>) and the other is still there but I&#8217;m not 100% confident <a href="http://github.com/pupeno/formtastic/commit/c78e927c9e7e104de9b9b2016d1dc277a900b0ae">my solution</a> is the appropriate one. At any rate <a href="http://github.com/pupeno/formtastic">I forked Formtastic in GitHub</a>, fixed the bugs and made a merge request.</p>
<p>Conclusion: Git is great, GitHub is great, Formtastic is great, open source is great, Rails is great and yes, I am great ;)</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/super-exception-notifier/' rel='bookmark' title='Permanent Link: Super Exception Notifier'>Super Exception Notifier</a></li>
<li><a href='http://pupeno.com/blog/migrations-that-change-the-schema/' rel='bookmark' title='Permanent Link: Migrations that change the schema'>Migrations that change the schema</a></li>
<li><a href='http://pupeno.com/blog/sano-is-open-for-business/' rel='bookmark' title='Permanent Link: Sano is open for business'>Sano is open for business</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/i-love-to-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sano is open for business</title>
		<link>http://pupeno.com/blog/sano-is-open-for-business/</link>
		<comments>http://pupeno.com/blog/sano-is-open-for-business/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 21:04:58 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[Building Sano]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Sano]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1371</guid>
		<description><![CDATA[
			
				
			
		
I really wish I was able to get farther in one day, but I think it&#8217;s good enough that I went from idea to deployed app. On retrospective I wasted too much time figuring out formtastic. I don&#8217;t regret doing it because it was in my TODO list and in the long run it should [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fsano-is-open-for-business%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fsano-is-open-for-business%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I really wish I was able to get farther in one day, but I think it&#8217;s good enough that I went from idea to deployed app. On retrospective I wasted too much time figuring out formtastic. I don&#8217;t regret doing it because it was in my TODO list and in the long run it should make me more productive, but in the short run maybe I should have used the good old forms.</p>
<p>The other two big waste of times was CSS and tables and an issue with the Ruby OpenID gem. Both problems I encountered before and both times I gave up trying to solve them and moved on. I should have moved on again this time; but instead I figured them out.</p>
<p>The application is at <a href="http://sano.pupeno.com">http://sano.pupeno.com</a>. Please don&#8217;t break it ;) Remember to log in and if you add data I&#8217;ll be grateful as it&#8217;ll make my migrations more realistic:</p>
<p><img class="alignnone size-full wp-image-1372" title="sano-016" src="http://pupeno.com/wp-content/uploads/2009/11/sano-016.png" alt="sano-016" width="614" height="536" /></p>
<p>I&#8217;m done for today.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/rails-sano/' rel='bookmark' title='Permanent Link: rails sano'>rails sano</a></li>
<li><a href='http://pupeno.com/blog/migrations-that-change-the-schema/' rel='bookmark' title='Permanent Link: Migrations that change the schema'>Migrations that change the schema</a></li>
<li><a href='http://pupeno.com/blog/profile-models/' rel='bookmark' title='Permanent Link: Profile models'>Profile models</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/sano-is-open-for-business/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Super Exception Notifier</title>
		<link>http://pupeno.com/blog/super-exception-notifier/</link>
		<comments>http://pupeno.com/blog/super-exception-notifier/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 20:11:53 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[Building Sano]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Sano]]></category>

		<guid isPermaLink="false">http://pupeno.com/?p=1363</guid>
		<description><![CDATA[
			
				
			
		
I like knowing when something goes wrong with my web apps, so I&#8217;m using Super Exception Notifier to get by email a report should any exception be raised in the app. If you go to Super Exception Notifier&#8217;s site you&#8217;ll see some instructions on how to add it to your project. This is how I [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fsuper-exception-notifier%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpupeno.com%2Fblog%2Fsuper-exception-notifier%2F&amp;style=compact&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I like knowing when something goes wrong with my web apps, so I&#8217;m using <a href="http://github.com/pboling/exception_notification">Super Exception Notifier</a> to get by email a report should any exception be raised in the app. If you go to Super Exception Notifier&#8217;s site you&#8217;ll see some instructions on how to add it to your project. This is how I do it.</p>
<p>Add the gem requirement in environment.rb:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">config.<span style="color:#9900CC;">gem</span> <span style="color:#996600;">'super_exception_notifier'</span>, <span style="color:#ff3333; font-weight:bold;">:version</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'~&gt; 2.0.0'</span>, <span style="color:#ff3333; font-weight:bold;">:lib</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'exception_notifier'</span></pre></div></div>

<p>Then be sure to have gemcutter in your gem sources:</p>

<div class="wp-terminal">pupeno@wopr:$ gem sources<br/>*** CURRENT SOURCES ***<br/><br/>http://gemcutter.org<br/>http://gems.rubyforge.org/<br/>http://gems.github.com<br/><br/></div>

<p>If you don&#8217;t have it, you can add it this way:</p>

<div class="wp-terminal">pupeno@wopr:$ gem install gemcutter<br/></div>


<div class="wp-terminal">pupeno@wopr:$ gem tumble<br/></div>

<p>To install the gem, in your Rails project run:</p>

<div class="wp-terminal">pupeno@wopr:$ sudo rake gems:install<br/></div>

<p>Create a file in config/initializers, I&#8217;ve called it exception_notifier.rb and inside I&#8217;ve set up the only really needed value for the notifications, the email address:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Notification configuration</span>
ExceptionNotifier.<span style="color:#9900CC;">configure_exception_notifier</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>config<span style="color:#006600; font-weight:bold;">|</span>
  config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:exception_recipients</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#40;</span>pupeno@pupeno.<span style="color:#9900CC;">com</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The last task is to make your application controller noisy by adding one line to it (the second one of course):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ApplicationController <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActionController::Base</span>
  <span style="color:#9966CC; font-weight:bold;">include</span> ExceptionNotifiable
  <span style="color:#008000; font-style:italic;">#...</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>You also need to be sure that you have ActionMailer properly configured, otherwise no mail is going to get through.</p>


<p>Related posts:<ol><li><a href='http://pupeno.com/blog/i-love-to-code/' rel='bookmark' title='Permanent Link: I love to code'>I love to code</a></li>
<li><a href='http://pupeno.com/blog/installing-rails-2-on-ubuntu/' rel='bookmark' title='Permanent Link: Installing Rails 2 on Ubuntu'>Installing Rails 2 on Ubuntu</a></li>
<li><a href='http://pupeno.com/blog/playing-with-ruby/' rel='bookmark' title='Permanent Link: Playing with Ruby'>Playing with Ruby</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://pupeno.com/blog/super-exception-notifier/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
