tag:blogger.com,1999:blog-77545252756468248332024-03-13T20:16:48.566+00:00Kutuma's RamblingsAbout technology, useful stuff or whatever I come across during my day.kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.comBlogger69125tag:blogger.com,1999:blog-7754525275646824833.post-15375852908808341822022-06-30T09:16:00.001+01:002022-07-01T13:01:36.970+01:00What can you see with a 60mm telescope?Like every other geek, I love astronomy and most things related to space. I never truly pursued this topic, apart from the odd article on <a href="http://www.nationalgeographic.com/">NGS</a>, but now I get to use a telescope on the weekends.
The telescope ain't that much, but it ain't that bad either. It's a <a href="http://www.telescopes.com/telescopes/refracting-telescopes/telescopes/refracting-telescopes/konustart900motorrefractorwithramotor.cfm?source=gbase&tid=KONU094&gbid=Konus_KonuStart_900_Motor_Refractor_Telescope_with_RA_Motor_and_Electronic_Focuser">60mm Konus</a>, with <a href="http://en.wikipedia.org/wiki/Equatorial_mount">equatorial mount</a> and a motor (which basically means I can point at an object, turn on the motor and the motor will make up for Earth's rotation).
One of the things I would like to know is what can you see with such a telescope. Oddly enough, I still wasn't able to find a comprehensive list on the net... so here's what I was able to see so far: (I've only used the telescope 3 times, so I hope the list will grow in the future!)
<ul><li><a href="http://en.wikipedia.org/wiki/Moon">Moon</a>: Excellent view, great contrast on the craters. I plan to look at it with a lot more detail.
</li><li><a href="http://en.wikipedia.org/wiki/Saturn">Saturn</a>: I was able to see the rings without a problem. I still wasn't able to see the <a href="http://en.wikipedia.org/wiki/Cassini_Division#Cassini_Division">Cassini Division</a>, but I'll keep trying. I was able to see a bit of the texture of the planet, but it's mostly a small white ball. I was also able to see one of the moons of Saturn (<a href="http://en.wikipedia.org/wiki/Dione_%28moon%29">Dione</a>, I believe).
</li><li><a href="http://en.wikipedia.org/wiki/Mars">Mars</a>: I've seen it without much detail, because right now it is way up in the sky and therefore a bit uncomfortable to watch. Still, it is rather small, and the only detail I was able to see was that it was only partly lit by the Sun.
</li><li><a href="http://en.wikipedia.org/wiki/Orion_Nebula">Orion Nebula</a>: You can see the <a href="http://en.wikipedia.org/wiki/Trapezium_%28astronomy%29">trapezium cluster</a> without a problem, as well as the nearer 3 stars. But the nebula itself is rather faint, and you can only see the brightest part. And even that is only a small blur.</li></ul>Next, I plan to see the <a href="http://en.wikipedia.org/wiki/Sun">Sun</a> (I'll need to buy a filter), <a href="http://en.wikipedia.org/wiki/Jupiter">Jupiter</a> and some other <a href="http://www.webcam-astrophotography.com/data/messier-objects-magnitude.html">Messier objects</a>. (I'd really like to see the <a href="http://en.wikipedia.org/wiki/Whirlpool_Galaxy">Whirlpool Galaxy</a>, but I still wasn't able to spot it... don't even know if it is visible with my telescope!)kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com2tag:blogger.com,1999:blog-7754525275646824833.post-63972850988875379232022-06-30T09:16:00.000+01:002022-07-01T13:01:17.357+01:00Beryl: Desktop FireworksIf you want to make your Ubuntu desktop really come to live, <a href="http://www.beryl-project.org/">Beryl</a> is the answer. It's an accelerated OpenGL desktop manager that gives you a lot of <strike>bells and whistles</strike> visual feedback on your window manager operations.
Installing is not as simple as you might wish, but it isn't too hard either. On the <a href="http://wiki.beryl-project.org/wiki/Main_Page">Beryl wiki</a> there's an entry on how to <a href="http://wiki.beryl-project.org/wiki/Install_Beryl_on_Ubuntu_Edgy_with_AIGLX">install Beryl on Ubuntu</a> and you can basically follow that.
The only notes I have on the installations steps are:
I had an error message while starting Beryl. As a consequence I had no window manager! The message was:
<pre>beryl: No GLXFBConfig for depth 32</pre>
After doing some searches on the web I found a <a href="http://www.ubuntuforums.org/showthread.php?p=2050655">post</a> that gave a solution to this problem. Just add the following to "Device" section on your <code>/etc/X11/xorg.conf</code> file:
<pre>Option "AddARGBGLXVisuals" "True"
Option "DisableGLXRootClipping" "True"</pre>
Also I skipped the entire "Configuring Beryl" section and just added <code>beryl-manager</code> to my <b>Startup Programs</b> in <b>System > Preferences > Sessions</b>
Next you have to configure Beryl. There's a ton of options, animations, keyboard shortcuts, themes, etc, etc that you can tweak with to make your desktop look exactly like you want it to! And if you have a bit of patience and 28Mb of spare memory to run Beryl, it's really worth the trouble.kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com0tag:blogger.com,1999:blog-7754525275646824833.post-49990198128622668442014-09-16T19:27:00.002+01:002015-02-06T09:28:05.291+00:00Building a mobile agenda for JSConf[Update: Sorry for the missing pics... Deleted by accident. Thank you google...]<br />
<br />
A couple of <a href="http://www.outsystems.com/">OutSystems</a>' engineering guys were going to a <a href="http://2014.jsconf.eu/">JSConf Europe</a> conference this weekend. While looking for the schedule, they found this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-NrYGwkJfpE8/VBh-0MKfN7I/AAAAAAAABG0/Sp-JD2LM-EM/s1600/jsconf_request.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-NrYGwkJfpE8/VBh-0MKfN7I/AAAAAAAABG0/Sp-JD2LM-EM/s1600/jsconf_request.png" height="296" width="400" /> </a></div>
<br />
We just couldn't let this opportunity go by, so <a href="https://twitter.com/joaomiguelneves">João Neves</a> used <a href="http://www.outsystems.com/platform/">Platform 9</a> (which is about to be released) to build an agenda for the event. <a href="http://labs.outsystems.net/jsconftimetable/">You can find the application here</a>. It gets the Agenda from google docs using the new REST capabilities, and it is a completely mobile ready!<br />
<br />
And, since on the week before I was playing with the source code of <a href="http://labs.outsystems.net/native/">OutSystems Now</a>, I built an <a href="https://play.google.com/store/apps/details?id=com.outsystems.jsconftimetable">application for Android</a> that would allow attendees to view the schedule of the conference on their devices, even if offline (<a href="https://github.com/RodrigoSC/JSConf2014">source code here</a>).<br />
<br />
The results were pretty cool! At the time of writing, 125 people had installed the Android App and we a bit over 7.500 pageviews! And we had some good reviews! :)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<img border="0" src="http://1.bp.blogspot.com/-QUVGFrijuzk/VBh_8F6fvrI/AAAAAAAABG8/3ape1QCAuD4/s1600/jsconf_views.png" /> <a href="http://4.bp.blogspot.com/-gLqXI1zGOTI/VBh-pWi7O3I/AAAAAAAABGw/hPXH1Gn0KXs/s1600/jsconf_request.png" imageanchor="1" style="clear: left; display: inline !important; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-gLqXI1zGOTI/VBh-pWi7O3I/AAAAAAAABGw/hPXH1Gn0KXs/s1600/jsconf_request.png" height="166" width="320" /></a></div>
<br />
<div>
<br /></div>
kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com1tag:blogger.com,1999:blog-7754525275646824833.post-26680380222561597502014-04-26T13:14:00.002+01:002014-04-26T13:14:57.288+01:00Star Wars stop motionSome fun with the kids, using discount animation software (the movie is in Portuguese...):<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="360" src="//www.youtube.com/embed/qtPkpepytRM" width="640"></iframe>
<br />
If you're curious, we used <a href="http://boinx.com/istopmotion/mac/">iStopMotion</a> to record the video using an iPad camera, <a href="https://www.toonboom.com/">ToonBoom</a> to add the lasers, QuickTime to record the sound, and <a href="https://www.apple.com/mac/imovie/">iMovie</a> to assemble everything. Extra videos and sounds downloaded from the internet.kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com1tag:blogger.com,1999:blog-7754525275646824833.post-36776747754662413762014-02-23T19:23:00.000+00:002014-02-23T19:46:20.798+00:00Displaying discrete data in RSuppose you have a restaurant, and you do a survey where your customers can grade from 1 to 5 several aspects of that restaurant. The 1st 5 lines on your data will look something like:<br />
<br />
<table border="1" cellpadding="5" cellspacing="0">
<tbody>
<tr> <th></th> <th>Food </th> <th>Drinks </th> <th>Location </th> <th>Service </th> </tr>
<tr> <td align="right">1 </td> <td align="right">4 </td> <td align="right">2 </td> <td align="right">5 </td> <td align="right">5 </td> </tr>
<tr> <td align="right">2 </td> <td align="right">4 </td> <td align="right">3 </td> <td align="right">5 </td> <td align="right">4 </td> </tr>
<tr> <td align="right">3 </td> <td align="right">5 </td> <td align="right">4 </td> <td align="right">5 </td> <td align="right">4 </td> </tr>
<tr> <td align="right">4 </td> <td align="right">3 </td> <td align="right">3 </td> <td align="right">5 </td> <td align="right">4 </td> </tr>
<tr> <td align="right">5 </td> <td align="right">4 </td> <td align="right">2 </td> <td align="right">5 </td> <td align="right">3 </td> </tr>
</tbody></table>
<br />
To analise this data, what I would usually do is check the mean, standard deviation, maybe do some histograms, and maybe do a boxplot of the data.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk1Svvs7HcX2MwXvL-IdeM402L7iCc2lO7pU3w7KwnS8Q5KJ3cnFFz2qV01Rjb_PhGG1SmLTExdQCvYZvV95741FzTHk8-rbP1SiwRbFku9Tr8FGfsMuCAaw7W7oSXsyQ0VUFztia3MEA/s1600/unnamed-chunk-31.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk1Svvs7HcX2MwXvL-IdeM402L7iCc2lO7pU3w7KwnS8Q5KJ3cnFFz2qV01Rjb_PhGG1SmLTExdQCvYZvV95741FzTHk8-rbP1SiwRbFku9Tr8FGfsMuCAaw7W7oSXsyQ0VUFztia3MEA/s1600/unnamed-chunk-31.png" height="320" style="background-color: white; background-position: initial initial; background-repeat: initial initial;" width="320" /></a></div>
<br />
But when you have small amounts of data, these approaches tend to hide the story. An alternative option is to use a beeswarm chart:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2-fllqVO3SemfHFdQ3w_UtGyzRHu73GpqYqLSUU-1llT2t4D2l4p7w2FyHFtZCffOM7SwNp2jlJ5emzTlZsZGrWP26fFO1CjhnNmFVbw1bmGjJ449r8N9EMZLbaDIluD7LnPUMi0F-7I/s1600/unnamed-chunk-32.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2-fllqVO3SemfHFdQ3w_UtGyzRHu73GpqYqLSUU-1llT2t4D2l4p7w2FyHFtZCffOM7SwNp2jlJ5emzTlZsZGrWP26fFO1CjhnNmFVbw1bmGjJ449r8N9EMZLbaDIluD7LnPUMi0F-7I/s1600/unnamed-chunk-32.png" height="320" style="background: #ffffff;" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
This type of chart shows the entire dataset, allowing you to see everything at a glance!<br />
<br />
If you're using <a href="http://www.r-project.org/">R</a>, you can create these charts using the <a href="http://www.cbs.dtu.dk/~eklund/beeswarm/">beeswarm</a> package. You can find the <a href="http://www.r-fiddle.org/#/fiddle?id=jx01TK9o">code that built this chart here</a> (it also uses the <a href="http://cran.r-project.org/web/packages/reshape/index.html">reshape</a> package).kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com0tag:blogger.com,1999:blog-7754525275646824833.post-42801195487914738592013-12-31T09:49:00.000+00:002013-12-31T09:50:01.040+00:00Circular Menu with D3.js<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRCoebpBrbjzEK0x2r-4LddYMIzOYLwmOIU_85FHZO2SCoA-8o2H7L78pP96jlMbR1aSH144g1cB8tkdciyqomPBmn1MYowuQDNkIEG9f6tFRqfef5v1Bj6NnvX78ug2-MaxGVfWu0HSg/s1600/wheelMenu.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRCoebpBrbjzEK0x2r-4LddYMIzOYLwmOIU_85FHZO2SCoA-8o2H7L78pP96jlMbR1aSH144g1cB8tkdciyqomPBmn1MYowuQDNkIEG9f6tFRqfef5v1Bj6NnvX78ug2-MaxGVfWu0HSg/s1600/wheelMenu.png" /></a></div>
<b>WheelMenu</b> is a circular menu aimed at mobile that allows you to quickly select from a small set of options quickly and with your thumb. You can see an example of the <b>WheelMenu</b> running in <a href="http://jsfiddle.net/RodrigoSC/8aHSf/embedded/result/">jsFiddle</a>.
<br />
Right now the menu only works for 6 slices, but <a href="https://github.com/RodrigoSC/WheelMenu/issues">let me know</a> if you need other number of slices.<br />
<br />
Check the <a href="https://github.com/RodrigoSC/WheelMenu">github page</a> for more details on how to use the <b>WheelMenu</b> and for access to the source code. If you're using the <a href="http://www.outsystems.com/platform/">OutSystems Platform</a>, head over to the community and <a href="http://www.outsystems.com/forge/component/487/wheelmenu/">download the component</a>.<br />
<br />
Credits to the <b>WheelMenu</b> original design go to <a href="https://plus.google.com/u/1/113199224625543479193/posts">Tiago Simões</a> and <a href="https://plus.google.com/116975587122912265118/posts">Daniel Nobre</a>.kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com0tag:blogger.com,1999:blog-7754525275646824833.post-5246551842295579762013-10-06T19:10:00.003+01:002013-10-06T19:11:33.311+01:00D3 drag and drop tree<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD2dlC5t0Isy2En9Y_8KFCXnaZM6-fQqFAm488FQBwTKOWSRRNRhjh44EJW8LOw2LLlK5wKYQN7ylngAk-a0DSsA2v9i9t4uNbcctthV5KbVah3Fgry4wlqR91dto1orAxIv_yGhUyH7I/s1600/fractal-tree1.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD2dlC5t0Isy2En9Y_8KFCXnaZM6-fQqFAm488FQBwTKOWSRRNRhjh44EJW8LOw2LLlK5wKYQN7ylngAk-a0DSsA2v9i9t4uNbcctthV5KbVah3Fgry4wlqR91dto1orAxIv_yGhUyH7I/s200/fractal-tree1.jpg" width="200" /></a></div>
I needed a heavily customizable drag and drop tree and I couldn't find one that really fit my needs, so I built one. It was also a great excuse to learn about <a href="http://d3js.org/">D3</a>, although most of the work was messing with the quirks of drag and drop.<br />
<br />
Anyway, although the code is far from decent and the tree is still work under progress, I decided to make it available to whomever wants to use. I hope it's useful for you, and be sure to <a href="https://github.com/RodrigoSC/dndTree/issues?state=open">let me know if you have any problems</a>.<br />
<br />
More <a href="https://github.com/RodrigoSC/dndTree">info and download at github</a>!kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com0tag:blogger.com,1999:blog-7754525275646824833.post-71164929911484822382013-08-17T13:06:00.000+01:002013-08-17T13:11:51.062+01:00Automatically building a cache manifest file<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiutZ6_lOqPEpvuVRWGdwQFypmXoiPSHG3AZmDxOcwWPOKWjeIJ87uW-xZvgBQIS46tiSe5Gy5daRMV_9y5rzTyYgFNlEaMzl5Mn6yku2ZCtmBOMzUpka39Yb8cH75FL4Mdf9iiIqXSclc/s1600/disconnected.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="95" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiutZ6_lOqPEpvuVRWGdwQFypmXoiPSHG3AZmDxOcwWPOKWjeIJ87uW-xZvgBQIS46tiSe5Gy5daRMV_9y5rzTyYgFNlEaMzl5Mn6yku2ZCtmBOMzUpka39Yb8cH75FL4Mdf9iiIqXSclc/s200/disconnected.jpg" width="200" /></a></div>
HTML5 has the capability to work <a href="http://www.html5rocks.com/en/features/offline">offline</a> and it allows you to cache files of your application on the browser by using a <a href="http://www.html5rocks.com/en/tutorials/appcache/beginner/">cache manifest</a>. The question is, which files to cache?<br />
<br />
Simple applications, with an HTML file, a couple of JS and CSS files are not a problem. But as soon as you move to more complex applications,<b> the number of files explodes</b> - think imported CSS files, background images, images within your page, etc. So here's a little help to build your cache file!<br />
<br />
<b>1.</b> Start by getting the <a href="https://github.com/RodrigoSC/HtmlOfflineHelpers"><span style="font-family: Courier New, Courier, monospace;">offlineHelpers.js</span></a> file and put it on your website. It's easier if you put it on the folder of the page you want to cache, but you can put it anywhere. If you don't have a site yet, download the whole project and play with the provided <span style="font-family: Courier New, Courier, monospace;">test.html</span> file.<br />
<br />
<b>2.</b> Be sure the page you want to cache includes <a href="http://jquery.com/">jQuery</a>. This is only needed to run the offlineHelpers script, you can remove it afterwards. You don't even need to download it, just <span style="font-family: Courier New, Courier, monospace;">src</span> the script from here: <span style="font-family: Courier New, Courier, monospace;">http://code.jquery.com/jquery-1.10.1.min.js</span><span style="font-family: 'Courier New', Courier, monospace;"><script src="http://code.jquery.com/jquery-1.10.1.min.js"></script></span><br />
<br />
<b>3.</b> Launch <a href="https://www.google.com/intl/en/chrome/browser/">chrome</a> (yes, for now it only works on chrome). Load the offllineHelpers script by opening the console (cmd+alt+j on the Mac) and typing <span style="font-family: Courier New, Courier, monospace;">$.getScript('offlineHelpers.js')</span>. Next, call <span style="font-family: Courier New, Courier, monospace;">offlineHelpers.getCacheFile()</span> on the console.<br />
<br />
<b>4.</b> Calling getCacheFile should result on a bunch of debug lines (in gray) followed by your cache manifest file. Something like:<br />
<br />
<span style="color: #cccccc; font-family: Courier New, Courier, monospace;">Getting stylesheets</span><br />
<span style="color: #cccccc; font-family: Courier New, Courier, monospace;">Found an import: jumbotron-responsive.css</span><br />
<span style="color: #cccccc; font-family: Courier New, Courier, monospace;">Getting JS files</span><br />
<span style="color: #cccccc; font-family: Courier New, Courier, monospace;">Getting Image files</span><br />
<span style="font-family: Courier New, Courier, monospace;">CACHE MANIFEST</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"># CSS Files</span><br />
<span style="font-family: Courier New, Courier, monospace;">css/bootstrap.css</span><br />
<span style="font-family: Courier New, Courier, monospace;">img/glyphicons-halflings.png</span><br />
<span style="font-family: Courier New, Courier, monospace;">img/glyphicons-halflings-white.png</span><br />
<span style="font-family: Courier New, Courier, monospace;">css/jumbotron-narrow.css</span><br />
<span style="font-family: Courier New, Courier, monospace;">css/jumbotron-responsive.css</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"># Javascript Files</span><br />
<span style="font-family: Courier New, Courier, monospace;">http://code.jquery.com/jquery-1.10.1.min.js</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"># Image Files</span><br />
<span style="font-family: Courier New, Courier, monospace;">img/creatures.jpg</span><br />
<br />
Next, tweak the result and copy to your <span style="font-family: Courier New, Courier, monospace;">cache.manifest</span> file.<br />
<br />
Let me know how this worked for you! If the script missed a file, let me know on the comments and I'll try to fix it!kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com0tag:blogger.com,1999:blog-7754525275646824833.post-12329184795048196872012-07-19T23:20:00.000+01:002012-07-19T23:21:25.097+01:00Command line script to batch convert imagesEver had a folder full of images that you needed to convert? Well, today I had a couple hundred 20Mb <a href="http://en.wikipedia.org/wiki/Raw_image_format">RAW</a> images that I wanted to convert to JPG, and I really didn't want to open them on an image editor.<br />
<br />
So I went hunting for a way to convert the images using the command line on the Mac. Here's what I found:<br />
<br />
<b>1. Converting an image via command line:</b> There's a tool called "<a href="http://www.ainotenshi.org/818/resizing-images-using-the-command-line">sips</a>" that does this (and much more) on the mac! To convert a file from RAW to JPG, you just need to call something like:<br />
<br />
<div class="p1">
<span style="font-family: 'Courier New', Courier, monospace;">sips -s format jpeg IMAGE.NEF --out IMAGE.jpg</span></div>
<div class="p1">
<br /></div>
<div class="p1">
<b>2. Getting the right name:</b> Iterating a list of files via command line is easy, getting just the filename in order to change the extension requires<span style="background-color: white;"> <a href="https://www.google.com/?q=bash+variable+string+operations">google</a>! Here's how to do it:</span></div>
<div class="p1">
<br /></div>
<div class="p1">
<span style="font-family: 'Courier New', Courier, monospace;">for i in *.NEF; do echo "${i%.*}.jpg"; done</span></div>
<div class="p1">
<br /></div>
<div class="p1">
(curious on how it works? Check <a href="http://tldp.org/LDP/abs/html/string-manipulation.html">this doc</a>)</div>
<div class="p1">
<br /></div>
<div class="p1">
<b>3. All together now: </b>To convert all the files in the current directory, do this:</div>
<div class="p1">
<br /></div>
<div class="p1">
<span style="font-family: 'Courier New', Courier, monospace;">for i in *.NEF; do sips -s format jpeg $i --out "${i%.*}.jpg"; done</span></div>
<div class="p1">
<br /></div>
<div class="p1">
Let me know how the script worked out for you!</div>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com0tag:blogger.com,1999:blog-7754525275646824833.post-18410835433271295982012-05-20T23:11:00.001+01:002012-05-20T23:12:45.078+01:00Moving from iPhoto to LightroomI've been using <a href="http://www.apple.com/ilife/iphoto/">iPhoto</a> since <a href="http://kutuma.blogspot.pt/2008/06/i-bought-mac.html">I bought my mac</a>, but lately it seems to be getting slower and buggier... Takes ages to launch, search doesn't work properly, and my library of about 25,000 photos seems too much for it. So I decided to try <a href="http://www.adobe.com/products/photoshop-lightroom.html">Lightroom</a>.<br />
<br />
Unfortunately, there's no easy way to get out of iPhoto, be it for Lightroom, <a href="http://picasa.google.com/">Picasa</a>, or whatever... There's no simple way to export all of your events into nice subfolders! So I built my own way out!<br />
<br />
I created a <a href="http://www.python.org/">python</a> script that reads the data from iPhoto, and uses it to create a tree structure with <span style="font-family: 'Courier New', Courier, monospace;">year/name_of_event</span> and all the photos inside. Here's a screenshot of the script running:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3Y6YB71ZHGqcrVQexiXqFAkiLVRF6QH02uCvsqqjWdt-5BtKZLRj87-_S2Bs8GXHHcDXBq_pg0vcQK7ew0jV9Ld9z2Fg82zns4PFtDyHR5NLP_muZzQoZDncgxitWY8uQbVV_x8oP-7c/s1600/Screen+Shot+2012-05-19+at+11.48.43+AM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3Y6YB71ZHGqcrVQexiXqFAkiLVRF6QH02uCvsqqjWdt-5BtKZLRj87-_S2Bs8GXHHcDXBq_pg0vcQK7ew0jV9Ld9z2Fg82zns4PFtDyHR5NLP_muZzQoZDncgxitWY8uQbVV_x8oP-7c/s640/Screen+Shot+2012-05-19+at+11.48.43+AM.PNG" width="640" /></a></div>
<br />
To use the script, <a href="http://iphoto-to-folders.googlecode.com/files/iphoto-to-folders.py">download it from here</a>, and execute it via the terminal using:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">python iphoto-to-folders.py [AlbumData.xml] [destinationDir]</span><br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">[AlbumData.xml]</span> is a file inside your iPhoto library, and can usually be located at <span style="font-family: 'Courier New', Courier, monospace;">~/Pictures/iPhoto\ Library/AlbumData.xml</span><br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">[destinationDir]</span> is the folder where you want your photos to be copied to.<br />
<br />
A couple of notes about the script:<br />
<br />
<ul>
<li>It only <b>copies the original versions</b> of the photos. Changes you made in iPhoto are not copied.</li>
<li>It copies all the files from your iPhoto library, so <b>it needs quite a bit of disk space</b>.</li>
<li>It <b>may take some time to run</b>. To copy my 25.000 photos it took 1.5 hours</li>
<li>It's not supposed to mess with your iPhoto library, but do <b>make backups</b>!</li>
<li>It has <b>no warranty</b> whatsoever!</li>
<li><b>It's supposed to be tweaked</b>! If you're comfortable with python, adapt the script to your needs.</li>
</ul>
<div>
If you have any questions or spot some problems, please <a href="http://code.google.com/p/iphoto-to-folders/issues/entry">submit them here</a>. And be sure to leave a comment telling me how the script worked for you!</div>
<br />
<span id="goog_145039479"></span><span id="goog_145039480"></span>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com6tag:blogger.com,1999:blog-7754525275646824833.post-20578954096031208572012-03-21T13:05:00.001+00:002012-03-21T13:52:52.680+00:00Delay your project, protect your future<br />
One of the dangers of Agile is that teams are so busy sprinting and delivering potentially shippable projects, that they <b>forget to invest in becoming more productive</b> in the future.<br />
<br />
Let's use some basic economics to illustrate this problem. Assume your team has a top productivity of X. It doesn't matter the unit you pick - story points per iteration, function points per month - but let's assume your team cannot produce more than X.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsi_kBz6gP8XlKIBMkIYEvXs1LhmY6GV3x3o22U1LGjonCNrp1JQzRVVfidcbu8SsgFUGttX-U14LLCHVqCD5riK4ASQvOwei4JKJ0c3ad1T1vA4ym9zlR-WiRRMTzrr2rIbwjbQrLqZU/s1600/Screen+Shot+2012-03-20+at+11.09.22+PM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="116" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsi_kBz6gP8XlKIBMkIYEvXs1LhmY6GV3x3o22U1LGjonCNrp1JQzRVVfidcbu8SsgFUGttX-U14LLCHVqCD5riK4ASQvOwei4JKJ0c3ad1T1vA4ym9zlR-WiRRMTzrr2rIbwjbQrLqZU/s320/Screen+Shot+2012-03-20+at+11.09.22+PM.PNG" width="320" /></a></div>
<br />
Now, one of the things you can do with productivity is move it around. For instance, <a href="http://www.google.com/">google</a> allows employees to invest part of their work week on pet projects. So if we put that on a vertical axis, we get something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn9vfrvZ2R8URxf-IAjHyLjJYxaZkSYHgoaLHQcHrM4C-gJ7JEVoHU_wXQ3fk9eTxjm8-9PRti_6XuA5fg3xqRSYr7dOehmKnDPwywRodCQjHELcU3Ja_7ODrmb5JOPueBlUX1sfoARcE/s1600/Screen+Shot+2012-03-20+at+11.09.32+PM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="273" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn9vfrvZ2R8URxf-IAjHyLjJYxaZkSYHgoaLHQcHrM4C-gJ7JEVoHU_wXQ3fk9eTxjm8-9PRti_6XuA5fg3xqRSYr7dOehmKnDPwywRodCQjHELcU3Ja_7ODrmb5JOPueBlUX1sfoARcE/s320/Screen+Shot+2012-03-20+at+11.09.32+PM.PNG" width="320" /></a></div>
<br />
This curve is called a <a href="http://en.wikipedia.org/wiki/Production%E2%80%93possibility_frontier">Production Possibility Frontier</a>, or PPF, and it represents your team's limit in terms of productivity. This means<b> the only way you'll make your team more productive is by moving the PPF</b>! And the way to achieve this is through investment.<br />
<br />
You may argue that google pet projects are an investment, but what I mean is direct investment in improving productivity. For instance, you could invest in improving your QA infrastructure, so that developers don't spend so much time building and fixing tests. Or you could invest in tools to improve your overall capacity to deliver, like the <a href="http://www.outsystems.com/agile-platform/">OutSystems' Agile Platform</a>. (disclaimer, I work for OutSystems! ;).<br />
<br />
When you do this type of investment, the end result is that you move the PPF to the right, therefore increasing your team's capacity to deliver.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXi6rDwq4b6XFPujEbv9t7x6_XEV8FkpozWckHOTgefa6TFPRVIgwguy_bWIn_M_nQXOq38ZW7vmLr52THfDB7kFUzEYtfkeNeoQKtUi2QuVD9BV4S82UQCQ19vXBbKCLpiL9c5Ls5atE/s1600/Screen+Shot+2012-03-21+at+1.51.27+PM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="263" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXi6rDwq4b6XFPujEbv9t7x6_XEV8FkpozWckHOTgefa6TFPRVIgwguy_bWIn_M_nQXOq38ZW7vmLr52THfDB7kFUzEYtfkeNeoQKtUi2QuVD9BV4S82UQCQ19vXBbKCLpiL9c5Ls5atE/s320/Screen+Shot+2012-03-21+at+1.51.27+PM.PNG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<b>Easy, right?</b> So why isn't everybody doing these investments and increasing their productivity? Why do we meet so many inefficient teams and R&D departments?<br />
<br />
Turns out there is a catch. <b>These improvements are not continuous</b>, and work in leaps. This means you need to go all the way to see the results of your investment. If you study a new tool for a couple of weeks and stop the investigation before something actionable comes out of the study, you're just throwing your time and money out the window...<br />
<br />
But guess what happens as soon as a the project stars to slip? We choose the short term solution, and increase the productivity of the team at the expense of our investment.<br />
<br />
<b>Standing up to your stakeholders and delaying a milestone to protect your future</b> is the hard part in making your team more productive. And I hope this short post gives you a bit of ammunition to go in the right direction! :)kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com1tag:blogger.com,1999:blog-7754525275646824833.post-42221312851501392882012-02-21T14:18:00.000+00:002012-02-26T14:19:00.786+00:00Why developers suck at UI design<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR6s1mnXjtGPCoblshHJMri2ieTBHj0P-B9VjiwUIkoESeROemlDbwdF6iAkYW-M76bqORqV8cQH-zbLvqgdA6jnrZAENZGazxS3Cw0GFA6wiuP7t6U-gEUbOkrUUbfClrfiizn0nfb6w/s1600/complexui.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR6s1mnXjtGPCoblshHJMri2ieTBHj0P-B9VjiwUIkoESeROemlDbwdF6iAkYW-M76bqORqV8cQH-zbLvqgdA6jnrZAENZGazxS3Cw0GFA6wiuP7t6U-gEUbOkrUUbfClrfiizn0nfb6w/s1600/complexui.png" /></a></div>
Yesterday I was listening to <a href="http://audioboo.fm/boos/669702-watch-out-for-what-if">this podcast</a> from <a href="http://boagworld.com/">Boagworld</a> dedicated to the dangers of "<i>what if</i>" design. The basic idea is that <b>you shouldn't let exceptions hinder the experience of the majority</b>. I.e. if something happens once in a blue moon, you shouldn't compromise your UI design because of it.<br />
<br />
At a certain point he alerts for the fact that developers tend to make this mistake because developers are worried about edge cases - "<i>what if the connection to the database is broken</i>", "<i>what if the user isn't logged in</i>". I agree with this, and I believe this is one of the reasons <b>developers tend to make interfaces that are overly complicated</b> for the common use case.<br />
<br />
The solution seems easy, right? <b>Developers need to take a step back from their work</b>, look at the user-stories they captured from their users, make the most used features really obvious, and hide the rest of the clutter.<br />
<br />
Well, nothing fundamentally wrong with this approach. I believe <b>developers must deliver the best possible interface they can</b>, and that requires effort and training. But I don't believe this is enough.<br />
<br />
The problem is, when you dive as deep as a developer does on the project, it's very hard to step back and take a look at the big picture. What developers really need to do is <b>get someone from the outside to spot the obvious errors</b> that are just too evident to be seen by someone buried in the nitty gritty details of a project.<br />
<br />
Again, this sounds like a simple enough solution. After all, getting someone to comment on your work isn't really hard, is it? Specially if it's about design! But the problem is that most <b>developers don't know how to listen or how to act on the feedback they receive</b>. It's the "<i>what if</i>" problem again... it's really easy to dismiss feedback based on edge conditions that happen 1% of the time. (This makes a great topic for another blog post, and I urge you to write it!)<br />
<br />
In the meantime, no time like the present to become better at UX design. Here's an interesting webinar with "<a href="http://www.outsystems.com/company/events/web/user-interfaces-webinar/">6 steps to engineering awesome user interfaces</a>". Have fun!<br />
<span class="Apple-style-span" style="color: #999999; font-family: Arial, Helvetica, sans-serif; font-size: x-small;">(disclaimer: this is a webinar recorded by me for <a href="http://www.outsystems.com/">OutSystems</a>, the company I work for)</span>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com7tag:blogger.com,1999:blog-7754525275646824833.post-91496448145354647662011-10-03T22:08:00.001+01:002011-10-03T22:09:27.772+01:00DIY tripod for the iPhoneDo you need to make a short video explaining how to do something with your hands? A drawing, assembling some <a href="http://www.lego.com/">lego</a>, playing with your <a href="http://www.nintendo.com/ds">Nintendo DS</a>? Well, I needed, and since the only video camera I have is my iPhone, I needed a tripod for it. So here it is, my homemade iPhone tripod!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgnLI6gkv7V786D6r3btvN9G2I3VcetNEtxpn0T10y-f3PK4ZJwEbAzJflnyQlXkLSTki1akKzudrTcYqVfCbGQdlTGqYlCovFeC5CjHoHntYeATX-oruV-rmUASkdimUgnRVsStj19Ew/s1600/tripod.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="425" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgnLI6gkv7V786D6r3btvN9G2I3VcetNEtxpn0T10y-f3PK4ZJwEbAzJflnyQlXkLSTki1akKzudrTcYqVfCbGQdlTGqYlCovFeC5CjHoHntYeATX-oruV-rmUASkdimUgnRVsStj19Ew/s640/tripod.JPG" width="640" /></a></div>
<br />kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com2tag:blogger.com,1999:blog-7754525275646824833.post-8899479139923293912011-09-26T09:05:00.001+01:002011-09-26T15:47:22.328+01:00Converting a list of IP addresses to countries<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5lSFc983brj3NxjHzK5mEOguaFK_ukLeicfPuPZlRaqEr2MUR-BJGtZpWLYiuVZzrLmLp9EQfcGVKZeUxEvQGXQd-hxTjnSev-0_CHgCewz3SE6FA43FpAqUJZKaJWEEQ3niuXO0Rv7E/s1600/globe.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5lSFc983brj3NxjHzK5mEOguaFK_ukLeicfPuPZlRaqEr2MUR-BJGtZpWLYiuVZzrLmLp9EQfcGVKZeUxEvQGXQd-hxTjnSev-0_CHgCewz3SE6FA43FpAqUJZKaJWEEQ3niuXO0Rv7E/s1600/globe.png" /></a></div>
If you have an Excel file with a column filled with IP addresses that need to be converted to countries, here's a way to do it. These instructions were tested on a Mac, but it should work fine in any environment with <a href="http://www.python.org/">Python</a>.<br />
<br />
Start by downloading the GeoIP City database from <a href="http://www.maxmind.com/">MaxMind</a>. They have a free version that you can download <a href="http://www.maxmind.com/app/geolitecity">here</a>. Download the one in binary format, and uncompress it.<br />
<br />
Next, you need the library to access this database format. There's a pure Python library called <a href="http://code.google.com/p/pygeoip/">pygeoip</a> that you can download from google code. To install it, just uncompress it and run the installer: <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">sudo python setup.py instal</span>l<br />
<br />
Next, you need to build a small script to convert the IP addresses to countries. Here's the script I used (note that the countries database should be in the same directory as the script).<br />
<br />
<pre>#!/usr/bin/env python
import pygeoip, sys
gi = pygeoip.GeoIP('GeoLiteCity.dat')
for line in sys.stdin:
rec = gi.record_by_addr(line)
print rec['country_name']
</pre>
<br />
I used this script (<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">geo.py</span>) by copying the IP list from excel to a plain text file (<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">ips.txt</span>), where you get one address per line. Then just run it with something like <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">python geo.py < ips.text</span> and you get a list of countries on your terminal window. Copy/paste to excel and you're done!<br />
<br />
If you want more than just the country, just play a bit with the print line. Here's a variation I did to get the state and the city. The output is tab separated so that you can copy it easily to excel:<br />
<br />
<pre>#!/usr/bin/env python
import pygeoip, sys
gi = pygeoip.GeoIP('GeoLiteCity.dat')
for line in sys.stdin:
rec = gi.record_by_addr(line)
print rec['country_name'] + '\t',
if rec['country_code'] == 'US' and 'region_name' in rec:
print rec['region_name'] + '\t' + rec['city']
else:
print '-' + '\t' + rec['city']
</pre>
<br />
As a side note, I tried another database from <a href="http://www.hostip.info/">hostip.info</a>, but it was only able to convert about half of the IPs I threw at it, so I recommend going with the one from MaxMind...kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com0tag:blogger.com,1999:blog-7754525275646824833.post-78445203928378258672011-08-10T17:27:00.001+01:002011-08-10T17:27:37.221+01:00Mobile Trends and Numbers - InfographicHere's an infographic that I designed for <a href="http://www.outsystems.com/">OutSystems</a>. It shows some of the impressive numbers around mobile adoption and mobile in the enterprise:<br />
<br />
<div align="center"><a href="http://www.outsystems.com/offer/mobile/mobile-trends-and-numbers-infographic/"><img alt="Mobile Trends and Numbers - Infographic" border="0" src="http://www.outsystems.com/CMS_BackOffice/ResourceLink.aspx?ResourceName=mobile-infographic" /></a><br />
Via: <a href="http://www.outsystems.com/">OutSystems</a></div>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com0tag:blogger.com,1999:blog-7754525275646824833.post-28363426083919739542011-01-19T00:16:00.000+00:002011-01-19T00:16:15.008+00:00What's wrong with ScrumBut?<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCuFG8mafBDW3Kuk_E-lDvQNj87NVge1Z4En3sq1o2Ur2ZehNOlxGzVP92LIBN-IEg00yvhWu2xZrAaIFr0n7XaA8_-Nsh0ZRQ3IqQ3aK4ciHWPU-DoTLTgLyywclKi1E-i4NjwDpWjLA/s1600/Screen+shot+2011-01-19+at+12.11.04+AM.PNG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCuFG8mafBDW3Kuk_E-lDvQNj87NVge1Z4En3sq1o2Ur2ZehNOlxGzVP92LIBN-IEg00yvhWu2xZrAaIFr0n7XaA8_-Nsh0ZRQ3IqQ3aK4ciHWPU-DoTLTgLyywclKi1E-i4NjwDpWjLA/s1600/Screen+shot+2011-01-19+at+12.11.04+AM.PNG" /></a></div>When I talk to other Agilists about <a href="http://en.wikipedia.org/wiki/Scrum_(development)">SCRUM</a>, I usually get two very extreme reactions to this methodology:<br />
<br />
On one side, I get people that say you've got to follow all the rules. That's what SCRUM is! There is no but!<br />
<br />
On the other side, I get people saying that there's no such thing as a one size fits all methodology, so you always need to adapt SCRUM for your particular scenario.<br />
<br />
Now, I don't agree that you need to blindly follow all the rules of SCRUM. That's not Agile at all... remember the 1st rule in the <a href="http://agilemanifesto.org/">Agile Manifesto</a>? <i>"Individuals and interactions over processes and tools"</i>. Seems clear to me that, if your team agrees that some part of SCRUM can be improved, the Agile Manifesto is there to back you up.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">But...</span></b><br />
<br />
Just because it is ok to change SCRUM, doesn't mean you should. <b>Failing to properly implement SCRUM is not a valid excuse</b> to change the process "to fit your organization". That's the the type of attitude that gives ScrumBut a bad name!<br />
<br />
Before adapting SCRUM to your organization, you need to implement and use original SCRUM for a while. It's only when you finally get SCRUM running smoothly on your organization (and that will take some time!) that you and your team can move to phase 2: Analyze the process, do retrospectives, and improve the process to better suite your needs.<br />
<br />
And that's when the real fun of Agile and SCRUM begins!kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com1tag:blogger.com,1999:blog-7754525275646824833.post-76812069663131094602010-06-26T19:24:00.005+01:002010-06-29T09:54:34.130+01:00Giving Gantt charts some Agile love!<a href="http://en.wikipedia.org/wiki/Gantt_chart">Gantt charts</a> have a really bad reputation these days. They're strongly associated with the <a href="http://en.wikipedia.org/wiki/Waterfall_model">waterfall methodology</a>, are considered an evil tool that managers use to micro-manage teams, and are usually classified as outdated delusions of certainty about projects that are subject to lots of change.<br />
<div><div><br />
</div><div>But still, <b>I love Gantt charts</b>! They're a great way to keep everybody in synch with the overall timeline of a project, team allocation, and how the project dates relate to other important dates.</div><div><br />
</div><div>My secret to make Gantt charts successful is easy: <b>Keep It Simple</b>!<br />
<br />
Here are a few tips on how to achieve Gantt Nirvana:</div></div><div><ul><li><b>You have to be able to produce the Gantt really quickly.</b> The problem with most Gantt charts is that creating them is a project in itself. And that means that by the time you publish them, they're already out-of-date.</li>
<li><b>It must be really easy to change the Gantt.</b> The Gantt's main purpose is communication. So when the project changes, the Gantt must also change. </li>
<li><b>Gantt's don't work well with lots of data.</b> Forget about the never-ending <a href="http://en.wikipedia.org/wiki/Work_breakdown_structure">WBS</a>s. It's too much detail and too much work. <a href="http://en.wikipedia.org/wiki/User_story">User stories</a> are more than enough detail.</li>
<li><b>Assign to teams, not individuals.</b> It's up to the team to organize how they solve problems. Besides, it means a lot less work for you!</li>
<li><b>Gantt's don't scale well vertically.</b> Don't make a stair case of user stories if they all belong to the same project. Show them one after the other, with the most important first, of course!</li>
<li><b>Be precise.</b> There's not much point communicating something that's wrong. Take into account the <a href="http://kutuma.blogspot.com/2009/07/reading-burndown-charts.html">team velocity</a>, vacations, national holidays, ...</li>
<li><b>Add milestones and releases.</b> Make it obvious when things will be made available. Just because a user story is completed next week, that doesn't mean it will be available in production.</li>
<li><b>Worry about the future.</b> Retrospectives are important learning tools, but usually it's more important to communicate were we are heading. Focus on that.</li>
</ul><div>At <a href="http://www.outsystems.com/">OutSystems</a>, we used our own <a href="http://www.outsystems.com/agile-platform">Agile Platform</a> to automate the entire process of creating the Gantt. All I have to do is click a button, and hey presto! Here's how they look:</div></div><div><br />
</div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6PKZwzB65HuE_IuwAHA6M9lzXDBW5cw74rKg6vC9FYRbxtmiVMb7ck_YwEZBZG-KCAnk48yR7-1VtgS8Rv111FUVfG8q64DTr6tTc6BMF61ik8UaxAP7pk4RCog-BsapjGf3qG-nS3iE/s1600/plan.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="332" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6PKZwzB65HuE_IuwAHA6M9lzXDBW5cw74rKg6vC9FYRbxtmiVMb7ck_YwEZBZG-KCAnk48yR7-1VtgS8Rv111FUVfG8q64DTr6tTc6BMF61ik8UaxAP7pk4RCog-BsapjGf3qG-nS3iE/s640/plan.png" width="640" /></a></div><br />
</div>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com1tag:blogger.com,1999:blog-7754525275646824833.post-57738607987598939982010-05-23T22:59:00.000+01:002010-05-23T22:59:35.758+01:00Beating the Delivery Deadline!<div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnNPuyafkpD86d7yKPc4nmq2EyyklbW3TjFDTzq3GawjTJDYQ8jlwET34JWRIv7s-pnEeXAIjXEJDs8XbjVwghBzU1XjaALr3WR94CfhqPClBejhBYmvxV4iDuQR14z1uxR7n9EpJxgNo/s1600/stopwatch.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnNPuyafkpD86d7yKPc4nmq2EyyklbW3TjFDTzq3GawjTJDYQ8jlwET34JWRIv7s-pnEeXAIjXEJDs8XbjVwghBzU1XjaALr3WR94CfhqPClBejhBYmvxV4iDuQR14z1uxR7n9EpJxgNo/s200/stopwatch.jpg" width="173" /></a></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">I'm a product delivery manager at <a href="http://www.outsystems.com/">OutSystems</a>. In a nutshell, my job is to make sure new versions of the <a href="http://www.outsystems.com/agile-platform">Agile Platform</a> are released on time, with quality, and with all the features agreed upon.</div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Last Friday we released version <b>5.1 beta</b> of the Agile Platform! And yes, it was <b>released on time</b>, with quality, and with everything the stakeholders were expecting! Cool, hum?</div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">And if you're wondering, <b>this wasn't a one time lucky shot</b>. This is the 4th version since I'm a delivery manager that we've pulled this off!</div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Actually, this shouldn't be anything to be amazed about... But the fact of the matter is that it is so unusual, that it surprises most people I know in the software industry. So I decided to share some principles I follow to make sure we ship on time:</div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div><ul><li><b>Embrace change:</b> One of the most anticipated features on 5.1 are the Wizards. Funny enough, the wizards weren't part of 5.1 when it started! This could've been a major stress factor, but it wasn't! From the moment we understood it was the right decision, we were more than thrilled to make it happen!</li>
<li><b>Don't add, swap:</b> It's really easy to add a bunch of features to a version, just so see its ship date delayed over and over. Swapping puts a price on features and forces everyone to prioritize. This keeps everyone focused on shipping the most important things first!</li>
<li><b>Say 'No':</b> It happens on every version. The end date gets near and everybody wants to add just one more thing. It's much easier to say "yes", but you'll regret it for much longer. I usually put it like this: Is it worth it to miss the ship date to add this last minute feature? It usually isn't...</li>
<li><b>Know your teams:</b> 5.1 got out on time because we were able to predict how long it would take to build! And the reason we were able to predict this (even with so much change!) is because we studied past versions to learn how long we take to do stuff. And not just the time software takes to build, we also consider interactions with other teams, user feedback, meetings, ...</li>
<li><b>Establish design rules:</b> It's really easy to derail when developing software. Establishing good design rules (visions, goals, guidelines, ...) is a great way to make sure everyone is on the same page. To be honest, I usually don't come up with these rules. The teams do! I just help teams stick to them.</li>
<li><b>Get out of the way:</b> I'm always available to give help and advice to my teams. But once I feel they're on track, I get out of the way. This is actually much harder to do than it seems, but once you have this level of trust with your teams, it's pure bliss - for both the manager and the team!</li>
<li><b>Ship:</b> There's always last minute bugs. There's always a reason to stop the presses and hold the version. Turns out most last minute bugs only occur when the planets are aligned and it's raining in the <a href="http://en.wikipedia.org/wiki/Kalahari_Desert">Kalahari</a>... so ship anyway! You can fix it tomorrow!</li>
</ul><div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">These might seem like easy enough tips, but to each of them there's a lot of preparation, trust, and discernment going on! Not only that, there's a huge requirement to make any of these tips work:</div></div><div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></div><div style="text-align: center;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b><span class="Apple-style-span" style="font-size: x-large;">You need amazing teams working with you!</span></b></div></div><div></div><div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></div><div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Lucky for me, <b>I work with the best teams on the planet!</b></div></div>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com3tag:blogger.com,1999:blog-7754525275646824833.post-5636516924357335902010-04-25T20:29:00.004+01:002010-04-25T22:29:44.794+01:00It's not about the numbers!<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_ESChb-kAcTZc9eoN5uJlGWS2-F-ndTmoiJtrOXUnvMX8UdDgASWK5IylAsRTD3xiqG-0TK5hIrH8pnVfh5OOgPARppWA96Dj5kdvzN2nYwVh0RvcRy5EZmCslpnaOp6v8qBybnwyHBU/s1600/numbers.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_ESChb-kAcTZc9eoN5uJlGWS2-F-ndTmoiJtrOXUnvMX8UdDgASWK5IylAsRTD3xiqG-0TK5hIrH8pnVfh5OOgPARppWA96Dj5kdvzN2nYwVh0RvcRy5EZmCslpnaOp6v8qBybnwyHBU/s320/numbers.png" /></a></div>When an organization is small, everyone knows what's going on. People have the full context, communication is easy, and so is evaluating performance. Everything is natural, very ad-hoc, and mostly <b>qualitative</b>.<br />
<br />
When the company grows, formalism starts to impose itself. Some evaluation forms (aka Excel files) appear, and <b>goals and metrics are agreed upon</b>. Still, when evaluation time arrives, everybody is very well aware that <b>things changed</b> since the day the goals were written, and a more qualitative approach is used once again.<br />
<br />
When the company gets big, people don't know each other so well, and they <b>don't have all the organization's context</b> at the top of their heads. To make sure everybody is aligned and working for the same grand objective, metrics are put in place. <b>Big mistake!</b><br />
<br />
Don't get me wrong.<b> Metrics are good</b>. The problem is turning metrics into goals and evaluations. Once you do that, people will try to make the number blindly, even if they have to <b>go against the organization's best interest</b>. To put it a single sentence:<br />
<br />
<div style="text-align: center;"><b><span class="Apple-style-span" style="font-size: x-large;">Metrics are tools, not goals!</span></b></div><br />
As with every tool, some care must be taken with metrics. Here's a few hints to make sure your metrics are helping you:<br />
<br />
<ol><li><b>Understand the metric:</b> Not only the formula to obtain the metric, but why are you getting the current values.</li>
<li><b>Question the values:</b> It's really easy to measure wrong. Check your numbers. <a href="http://punditkitchen.files.wordpress.com/2009/04/political-pictures-measure-twice.jpg">Measure twice, cut once</a>.</li>
<li><b>Question the metric:</b> Don't assume the current metric is adequate. Mistakes are made. Things change. More information is available. Be extra critical with metrics!</li>
<li><b>Study the derivative:</b> More important than the number, is the derivative. More important than knowing the current numbers, is knowing next month's.</li>
<li><b>Don't trust all stats:</b> You need a <a href="http://www.britannica.com/EBchecked/topic/330568/law-of-large-numbers">big sample of values</a> to trust statistics. Don't trust averages and the like if the sample is small.</li>
<li><b>Don't use metrics as a direction:</b> Use them as guidance.</li>
<li><b>Talk to people:</b> <a href="http://www.cafepress.com/pragmaticmarket.56372820">Don't trust yourself</a> to analyze the results. Talk to the people that measure. Talk to the people that affect the metric.</li>
</ol><br />
<div>I'm sure the list goes on and on. What is your advice for working with metrics? Do you have any stories of metrics gone wrong?</div>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com1tag:blogger.com,1999:blog-7754525275646824833.post-4419291242517202882009-11-01T22:19:00.006+00:002009-11-01T22:23:32.265+00:00Sprint review meeting: It's all about Marketing!<div>I attend a lot of <a href="http://www.mountaingoatsoftware.com/sprint-review-meeting">Sprint Review meetings</a>, and sometimes I leave those meetings a bit sad...<br />
<br />
</div><div></div><div>It's not that the team hasn't done a great job! Quite the opposite. The teams I work with do <b>miracles</b>! But, like most engineers, they <b>sell themselves short</b>.<br />
<br />
</div><div><b>Sprint Review Meetings are all about </b><a href="http://en.wikipedia.org/wiki/Marketing"><b>Marketing</b></a><b>!</b> Your team needs to sell the work done during the Sprint to the audience!<br />
<br />
</div><div>Here are a few tips to effectively market your work:<br />
</div><div><ul><li><b>Show the value of what you did:</b> Don't explain how you did it, and don't go into excruciating technical detail about what you implemented... explain the benefits of what you did!</li>
<ul><li><b>Do: </b>"By improving the reticulating splines performance, customers have a much smoother checkout process"</li>
<li><b>Don't:</b> "We improved reticulating splines speed by using a really smart b-tree structure"</li>
</ul>
<li><b>Make a big fuss about what you did:</b> Don't hide the great work you did in a bullet list with all the details of the Sprint. Pick 3 to 5 key points, and make a slide for each of them.</li>
<ul><li><b>Do:</b><br />
<img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ilWCbm-22eaGPbCnmpZKHgTT4ZSAgmnkqmiugy14cn1nuwqfpRZ3fhAs5QhbXwvENpoG3XhliREZ59VkBC5XfUe2WgqC8QNxapmnePpgmqXBiIdjIqKISbO2VSjCSihpSY0-JhnZ9eM/s200/sprint.002.png" /></li>
<li><b>Don't:</b><br />
<img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGnI_4GFmOkV38lEz8wE64LPvBCULiDxQp7pQ6i9mfpiAyeoRUe7lEO9EssRzkqKNWkSnGCJz34pkHrCEaNK1nqgyv3RLchhBauoccpXl99dZCyr-dqDdpwbxQsf0-clhJu5UO0r4TV6c/s320/sprint.001.png" /></li>
</ul>
<li><b>Make a real world demo:</b> Be smart with your seed data. Use real data whenever possible, or some really clever examples to make your demo more effective.</li>
<ul><li><b>Do:</b> "Peter Smith bought a Mega Chair and paid it with a Visa card"</li>
<li><b>Don't:</b> "Customer A bought Product 1 and paid with card X"</li>
</ul>
<li><b>Talk about the entire Use Case:</b> Even if you don't demo it all, explain how the user got to the point of the demo and what the user is trying to achieve. It will make understanding your demo much easier.</li>
<ul><li><b>Do:</b> "Peter Smith was navigating at our web site to buy a chair. He did a search for chairs, and clicked the 1st result on the list. What you see here is the page present to him at that stage."</li>
<li><b>Don't:</b> "Assume Customer 1 is at this page"</li>
</ul>
<li><b>Make a clean demo:</b> The demo should be as near to reality as possible. Avoid launching the command line, use batch files, or employ other kind of odd gizmos during your demo.</li>
<li><b>Don't dwell on what you didn't do:</b> If your team made a commitment to this sprint that it wasn't able to keep, mention it, give a one sentence justification, and move along. Be prepared to answer any questions that may arise, but don't spend the time you have to talk about what you did, speaking about what you didn't do.</li>
<ul></ul>
</ul></div><div>What other tips would you add to this list? How do you turn your Sprint Review meetings into huge successes?<br />
</div>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com3tag:blogger.com,1999:blog-7754525275646824833.post-2847022342197275882009-10-27T16:25:00.006+00:002009-10-26T20:58:35.077+00:00When is enough good enough?We all love perfect products! Those products that you actually feel pleasure just for using. And naturally, we all want to make our own products perfect!<br />
<br />
But <span style="font-weight: bold;">perfection comes at a price</span>. Generally speaking, the closer you want to get to perfection, the more it will cost you. And the cost increase isn't linear!<br />
<br />
<img alt="" border="0" id="BLOGGER_PHOTO_ID_5396166727666172754" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBDAiXQIJ2Pbe1JmkoPfm3SS2zlHe_71kQbjC_GZx7P0HfrE6P5beyNxsB_H-Xz3_2uSdsw1VChmxcTsT62OgMU0JPTway8NbeWcIypowRh3Yo5sykLIBEbc_O42ytDFkaP10hyphenhyphen15RDU0/s400/chart.001.png" style="cursor: pointer; display: block; height: 274px; margin: 0px auto 10px; text-align: center; width: 400px;" /><span style="color: #666666;"></span><br />
<div style="text-align: center;"><span style="color: #999999;">(the smiling faces represent the mood of your "average user")</span><br />
</div><br />
This means you have to be careful when investing on perfection. In most scenarios, there's simply <span style="font-weight: bold;">not enough time to make everything perfect</span>. Nothing new here, right? It's just the old quantity vs. quality dilemma. You either do 1 perfect thing, or you do 2 "good enough" things.<br />
<br />
If you take this into a software product scope, there are a few guidelines that can help deciding how perfect your feature needs to be:<br />
<ol><li><span style="font-weight: bold;">How many times will the feature be used?</span> Rarely used features can be a bit uncomfortable, and seldom used features can be good enough. Perfection should be saved for those features that are used all the time!<br />
</li>
<li><span style="font-weight: bold;">Who will be using the feature?</span> Features targeted at one particular user can get away with a hack. For features existing users are craving for, a quick "good enough" solution may be better than a delayed perfect solution. If you're aiming for first time users, you should go for perfection, to make sure they stick around for more.<br />
</li>
<li><span style="font-weight: bold;">How unique is the feature?</span> Is this something every other product does? Is it always done the same way? Unless this is really core to your product, you probably should stick to good enough and go with the crowd. But if this is something truly unique to your product, polish it up for perfection!</li>
<li><span style="font-weight: bold;">Is the feature demo-able?</span> If this is something you'll be wanting to show at a prospect demo or at a room with 400 people, going for perfection is a good investment.</li>
<li><span style="font-weight: bold;">Is the feature sell-able? </span>Is this one of those features that has the potential to enchant customers? Better yet, is this a feature customers will be talking about to your prospects? If so, by all means make it perfect!<br />
</li>
</ol>These are just a few things to consider. I bet there's lots more! What factors do you take into consideration when deciding how much effort you should invest on a feature?<br />
<br />
<span style="font-weight: bold;">PS: </span>The same principle can be applied to a bunch of other areas of a software product, like documentation and marketing. Anyone care to make a blog post about those? :-)kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com3tag:blogger.com,1999:blog-7754525275646824833.post-1178542885914186662009-09-06T20:52:00.003+01:002009-10-24T16:30:59.062+01:00The Secret of Agile SpeedHere's an introductory video on how Agile improves your projects' speed.<br />
<br />
<object height="344" width="425"><param name="movie" value="http://www.youtube.com/v/rhIu-hjvxc4&hl=en&fs=1&rel=0"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/rhIu-hjvxc4&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com6tag:blogger.com,1999:blog-7754525275646824833.post-38307349993284148492009-07-10T22:55:00.003+01:002009-07-11T15:40:15.154+01:00Reading burndown charts<div><a href="http://en.wikipedia.org/wiki/Burn_down_chart">Burndown charts</a> are a fairly common tool used in <a href="http://en.wikipedia.org/wiki/Agile_software_development">Agile projects</a> to measure the velocity of a team. It usually contains two sets of data, the actual missing effort and the expected missing effort. </div><div><br /></div><div>The thing is, <b>looking at a burndown chart is useless, unless you have a very good understanding of what’s going on with the project</b>. </div><div><br /></div><div>Here’s a sample of a burndown chart:</div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL0keB9iviTTC5GtBWfR65PGWfReae3lDr3r3_wSuyKOeCbfwZDhcOhbxPBAqLtSOz0ahBTf_JTw7GXRmBDXvhiZwkaTF80GshYchprh_gyVZNuCDKNH5gxL0bTgJkxFkMppyy9WOaE7U/s1600-h/burndown1.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 280px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL0keB9iviTTC5GtBWfR65PGWfReae3lDr3r3_wSuyKOeCbfwZDhcOhbxPBAqLtSOz0ahBTf_JTw7GXRmBDXvhiZwkaTF80GshYchprh_gyVZNuCDKNH5gxL0bTgJkxFkMppyy9WOaE7U/s400/burndown1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5356909015020470242" /></a><br /><div>At first glance, it seems things aren’t bad. Although there is a “saw” look to it, every couple of weeks things go back to normal. The drops seem to occur at the end of each iteration (assuming 2 week iterations). But the thing is, the chart doesn’t show us <b>why</b> the drops occur!</div><div><br /></div><div>One reason might be poor self management by the team. They only close the stories at the end of the iteration. This is a good scenario, because it means you can quickly coach the team to have more fine grained stories, so you can have better visibility on the project.</div><div><br /></div><div>Another reason for these drops might be that, at the end of each iteration, the team reviews the backlog and realizes it will miss the date. With that in mind, they remove the last items from the backlog, and the project gets back on track. This is way more problematic!</div><div><br /></div><div>The team is assuming the project is about 1/2 weeks late (marked by the dotted red line), so they cut 1/2 weeks worth of work from the backlog. But the reality is that <b>the project is 5 weeks late!</b> (marked by the dotted blue line).</div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGTV_RgINXJmi-N97qV2bsQ8JSLbx4qR5ZFGNJTVkWDjTlYGT6eony-Yi5fU9iht40OCLDHVop1iu0uczwECgwgX_vtClQd8rwzZ8r6JK58C5oY0w0_AYSIM_Bg5JTYrQEpbGudihYCy4/s1600-h/burndown2.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 280px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGTV_RgINXJmi-N97qV2bsQ8JSLbx4qR5ZFGNJTVkWDjTlYGT6eony-Yi5fU9iht40OCLDHVop1iu0uczwECgwgX_vtClQd8rwzZ8r6JK58C5oY0w0_AYSIM_Bg5JTYrQEpbGudihYCy4/s400/burndown2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5356909143806146994" /></a><br /><div>The consequence of this is that the team will have to cut about half of the backlog to finish the project on time! This can obviously have catastrophic implications for the project....</div><div><br /></div><div>There are several ways to deal this problem, but the important thing is that action is taken as soon as possible. And to be able to quickly understand what is going on, <b>you cannot trust on the burndown chart alone. You need a very good understanding of what is going on with the project</b>.</div>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com2tag:blogger.com,1999:blog-7754525275646824833.post-11721258090072979202009-05-09T12:09:00.009+01:002009-05-09T14:55:36.612+01:00Analyzing Movable Type search logsThe <a href="http://blog.outsystems.com/aboutagility/">OutSystems blog</a> uses <a href="http://www.movabletype.org/">Movable Type</a>. I was curious to see what type of searches were being made on the blog, so I downloaded the logs from MT's back-office and started thinking how I could analyze them.<br /><br />I wanted to generate <a href="http://en.wikipedia.org/wiki/Comma-separated_values">CSV</a> files, so I could open them in <a href="http://office.microsoft.com/en-us/excel/default.aspx">Excel</a> or <a href="http://www.apple.com/iwork/numbers/">Numbers</a>. At first I considered <a href="http://www.python.org/">Python</a>, because it has good CSV support. But most of the work would consist in parsing the MT log file, so then I considered <a href="http://www.perl.org/">Perl</a>. The problem with Perl is that I can never remember the syntax, so in the end I decided to just use the Unix command line.<br /><br />I started out by checking unique sentences in the file:<br /><br /><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size:small;">grep "Search: query for" logfile.csv | cut -d \' -f 2 | tr '[A-Z]' '[a-z]' | sort | uniq -c | sort -nr | sed 's/ *\([0-9]*\) \(.*\)/\2, \1/' > sentences.csv</span></span><br /><br />Here's what this does:<br /><ol><li><span class="Apple-style-span" style="font-family:'courier new';">grep "Search: query for" logfile.csv </span>- Get all the lines from the log that are searches</li><li><span class="Apple-style-span" style=" ;font-family:'courier new';">cut -d \' -f 2 </span>- Extract the content of the search. This might not work if the content has <span class="Apple-style-span" style="font-family:'courier new';">'</span> on it, so be advised.</li><li><span class="Apple-style-span" style=" ;font-family:'courier new';">tr '[A-Z]' '[a-z]' </span>- Turn everything to lowercase.</li><li><span class="Apple-style-span" style=" ;font-family:'courier new';">sort </span>- Group the sentences (for <span class="Apple-style-span" style="font-family:'courier new';">uniq -c</span> to work).</li><li><span class="Apple-style-span" style=" ;font-family:'courier new';">uniq -c </span>- Count the unique occurrences of each sentence.</li><li><span class="Apple-style-span" style=" ;font-family:'courier new';">sort -nr </span>- Sort by numbers, in reverse order.</li><li><span class="Apple-style-span" style=" ;font-family:'courier new';">sed 's/ *\([0-9]*\) \(.*\)/\2, \1/' </span>- Transform the result into a CSV file.</li><li><span class="Apple-style-span" style=" ;font-family:'courier new';">> sentences.csv </span>- Save to <span class="Apple-style-span" style="font-family:'courier new';">sentences.csv</span>.</li></ol><div>Turns out this wasn't very useful, because there are a lot of different sentences. One of them kind of stand out, but it accounted for about 5% of the searches. So I've added a bit of <a href="http://en.wikipedia.org/wiki/AWK">awk</a> to do the same for the words, instead of the sentences:</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size:small;">grep "Search: query for" logfile.csv | cut -d \' -f 2 | tr '[A-Z]' '[a-z]' | </span><b><span class="Apple-style-span" style="font-size:small;">awk '{for (i=1;i<=NF;i++) print $i}'</span></b><span class="Apple-style-span" style="font-size:small;"> | sort | uniq -c | sort -nr | sed 's/ *\([0-9]*\) \(.*\)/\2, \1/' > words.csv</span></span></div><div><br /></div><div>The awk script splits the sentences into words. This issue a more interesting result: 26% of the searches include the word "<b>Agile</b>"! Note that this counts words like "and" and "the", but it's easy enough to remove them.</div><div><br /></div><div>There's some more fun stuff you can do with this! Use <a href="http://www.wordle.net/">Wordle</a> to create a word cloud:</div><div><br /></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLSeAz-6NIpGIaNUZWEHnLKabeocLWqRIKkIBDyfcGyD9-hmxzH6lRL501Gr709Ape-3fOewjHKlbxgyQ2qx4Hd-PglDzdY49SXi8dMlF3kdAMY9Dif4HwSmKyR_taavnGGSNAZLsDIhQ/s1600-h/search_word_cloud.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 212px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLSeAz-6NIpGIaNUZWEHnLKabeocLWqRIKkIBDyfcGyD9-hmxzH6lRL501Gr709Ape-3fOewjHKlbxgyQ2qx4Hd-PglDzdY49SXi8dMlF3kdAMY9Dif4HwSmKyR_taavnGGSNAZLsDIhQ/s400/search_word_cloud.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5333809394660250226" /></a><br /><div>Or you can check where the accesses come from. If you have an <a href="http://www.iplocationtools.com/sql_database.php">IP geolocation DB</a>, you can try this:</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size:small;">grep "Search: query for" $1 | cut -d , -f 2 | sort | uniq | awk '{print "SELECT country_name FROM ip_group_country where ip_start <= INET_ATON(\""$1"\") order by ip_start desc limit 1;"}' | mysql --skip-column-names -B -uGeoDBUser -pGeoDBPwd GeoDB | sort | uniq -c | sort -nr | sed 's/ *\([0-9]*\) \(.*\)/\2, \1/' > geo.csv</span></span></div><div><br /></div><div>You can then open the file and make a nice chart! Have fun!</div><div><br /></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheoJEDtmE_vsncLwhrqUqDsLafUArsTqEWb1HWw7SXqwBNsBLeY-1r0Q2KCEmQNUxtgKoc_5G9SGR4dB6AQ2wCfRya7bovMRfKU1lSnq0bxhmqsRZGvB88BZ5mUKKZfBmc0XvPsY_qiLk/s1600-h/search_by_country.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 280px; height: 298px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheoJEDtmE_vsncLwhrqUqDsLafUArsTqEWb1HWw7SXqwBNsBLeY-1r0Q2KCEmQNUxtgKoc_5G9SGR4dB6AQ2wCfRya7bovMRfKU1lSnq0bxhmqsRZGvB88BZ5mUKKZfBmc0XvPsY_qiLk/s400/search_by_country.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5333822179516365714" /></a>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com1tag:blogger.com,1999:blog-7754525275646824833.post-6562174008723476302009-03-04T19:00:00.005+00:002009-03-04T21:14:33.443+00:00Great employee care!I had a baby boy a few days ago. Because of that, I'm on leave from work. And, to my surprise, today I got a gift delivered to my house.<div><br /></div><div>It was a gift from the company I work for, <a href="http://www.outsystems.com/">OutSystems</a>! It was a plant for my wife, a cigar for me, and a bunch of stuff for the baby, including some diapers, a blanket and some baby shoes.</div><div><br /></div><div>My company treats me pretty good on a regular basis, but for some reason this attention they had really hit a chord. It was a really thoughtful gesture, and I truly appreciate the gift!</div><div><br /></div><div>This is even more meaningful if you consider the tough times we're going through. To me, this sends a clear message that OutSystems is devoted to great employee care, even in the middle of the current crisis.</div><div><br /></div><div>Thank you <a href="http://www.outsystems.com/">OutSystems</a>!</div><div><br /></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBKBgkWNG1PSCQN3KlusCliDCvZAGXxj5jlwyUeFE5C5NajKqPKv8AwrpKw9zvlLkSjBWWtwz5yEGO1wCmcjEP7-4_L8UldNWh-blWrARUmGS6HgQXAE1uGifnVgC3FoO40C_if4bDU80/s1600-h/collage.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 325px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBKBgkWNG1PSCQN3KlusCliDCvZAGXxj5jlwyUeFE5C5NajKqPKv8AwrpKw9zvlLkSjBWWtwz5yEGO1wCmcjEP7-4_L8UldNWh-blWrARUmGS6HgQXAE1uGifnVgC3FoO40C_if4bDU80/s400/collage.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5309443896244504818" /></a>kutumahttp://www.blogger.com/profile/04576269769073593956noreply@blogger.com0