Codemuse.cohttps://codemuse.co/2018-05-01T00:00:00+02:00Removing Google Analytics, as well2018-05-01T00:00:00+02:002018-05-01T00:00:00+02:00Gertjan Zwartjestag:codemuse.co,2018-05-01:/2018/05/01/removing-google-analytics-as-well<p>Shortly after I received Google’s request for reviewing the new Google Analytics data processing terms for the <span class="caps">GDPR</span>, I read Jesse Squires’ post about <a class="reference external" href="https://www.jessesquires.com/blog/removing-google-analytics-too">him removing Google Analytics from his site</a>. This led me to ask the same questions as Jesse, and Ash Furrow who <a class="reference external" href="https://ashfurrow.com/blog/removing-google-analytics">also asked himself</a> whether …</p><p>Shortly after I received Google’s request for reviewing the new Google Analytics data processing terms for the <span class="caps">GDPR</span>, I read Jesse Squires’ post about <a class="reference external" href="https://www.jessesquires.com/blog/removing-google-analytics-too">him removing Google Analytics from his site</a>. This led me to ask the same questions as Jesse, and Ash Furrow who <a class="reference external" href="https://ashfurrow.com/blog/removing-google-analytics">also asked himself</a> whether he should be collecting data on visitors of his blog. I have no better answers to these questions then they have.</p>
<p>Instead of accepting the new <span class="caps">GDPR</span> data processing terms, I simply deleted my account — as of today <a class="reference external" href="http://codemuse.co">codemuse.co</a> is not using Google Analytics anymore.</p>
Remote Control for Kodi and XBMC 3.3.02017-02-12T00:00:00+01:002017-02-12T00:00:00+01:00Gertjan Zwartjestag:codemuse.co,2017-02-12:/2017/02/12/remote-control-for-kodi-and-xbmc-330<p><a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for Kodi and <span class="caps">XBMC</span></a> version 3.3.0 is available on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-kodi-xbmc/id416082141?l=en&mt=8">App Store</a>. This version brings support for the latest Kodi 17.x releases and contains some fixes to support iOS 9 and iOS 10. Also, you can now swipe left to mark any <span class="caps">TV</span> show, season …</p><p><a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for Kodi and <span class="caps">XBMC</span></a> version 3.3.0 is available on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-kodi-xbmc/id416082141?l=en&mt=8">App Store</a>. This version brings support for the latest Kodi 17.x releases and contains some fixes to support iOS 9 and iOS 10. Also, you can now swipe left to mark any <span class="caps">TV</span> show, season, episode and movie as watched or unwatched. For iPad long-press movies to mark them watched or unwatched.</p>
Replacing my Media PC2015-09-12T00:00:00+02:002015-09-12T00:00:00+02:00Gertjan Zwartjestag:codemuse.co,2015-09-12:/2015/09/12/replacing-my-media-pc<p>After five great years of service, <a class="reference external" href="https://codemuse.co/2010/07/24/building-a-mini-itx-ion-based-htpc">mbox</a>, my first <span class="caps">HTPC</span>, was starting to show signs of decay: a hard drive with bad sectors. A good time — ahem, excuse — to replace it. I wanted to go fanless five years ago, but the options were limited and expensive back then. However, with …</p><p>After five great years of service, <a class="reference external" href="https://codemuse.co/2010/07/24/building-a-mini-itx-ion-based-htpc">mbox</a>, my first <span class="caps">HTPC</span>, was starting to show signs of decay: a hard drive with bad sectors. A good time — ahem, excuse — to replace it. I wanted to go fanless five years ago, but the options were limited and expensive back then. However, with Intel’s latest Core M Broadwell series it is now possible to build a better performing, but also more power efficient media and server computer, without any fans.</p>
<p>Like I did for my original setup, I’ll document the process of setting up my new little box here as part of the <a class="reference external" href="https://codemuse.co/category/htpc">htpc</a> series.</p>
<div class="section" id="hardware">
<h2>Hardware</h2>
<p><a class="reference external" href="http://www.wouterbijlsma.net/blog/">A good friend</a> recommended watching out for the Zotac <span class="caps">ZBOX</span> nano series to be updated with Intel’s Broadwell CPUs. I took his advice and the moment it became availble, I ordered the following parts:</p>
<ol class="arabic simple">
<li><a class="reference external" href="http://www.zotac.com/products/mini-pcs/zbox-c-series/product/zbox-c-series/detail/zbox-ci521-nano-zbox-ci521nano.html">Zotac <span class="caps">ZBOX</span> <span class="caps">CI521</span> nano</a></li>
<li><a class="reference external" href="http://www.samsung.com/global/business/semiconductor/minisite/SSD/global/html/ssd850evo/overview.html">Samsung 850 <span class="caps">EVO</span> 500 <span class="caps">GB</span> 2.5” <span class="caps">SATA</span> <span class="caps">III</span> <span class="caps">SSD</span></a></li>
<li><a class="reference external" href="http://www.toshiba.com/us/accessories/Storage/Canvio-Desktop-Hard-Drives/5TB/HDWC250XK3J1">Toshiba 5 <span class="caps">TB</span> Canvio Desktop External Hard Drive</a></li>
</ol>
<p>At a grand total of € 716,49 it’s <cite>slightly</cite> more expensive than my <a class="reference external" href="https://codemuse.co/2010/07/24/building-a-mini-itx-ion-based-htpc">previous setup</a>, though that’s an unfair comparison, as my previous setup neither included 5 <span class="caps">TB</span> of external storage nor an <span class="caps">SSD</span>. After only two months of use I can confirm it has been worth every penny so far for me.</p>
</div>
<div class="section" id="installation">
<h2>Installation</h2>
<p>Installing Ubuntu server on this machine is as simple as <a class="reference external" href="http://www.ubuntu.com/download/server">downloading</a> the 64-bit install image, and “burning” it to a memory stick. I used my Mac to create the bootable memory stick as follows:</p>
<div class="highlight"><pre><span></span>hdiutil convert -format UDRW -o target.img ubuntu-14.04.2-server-amd64.iso
sudo dd <span class="k">if</span><span class="o">=</span>target.img.dmg <span class="nv">of</span><span class="o">=</span>/dev/rdisk<span class="nv">$N</span> <span class="nv">bs</span><span class="o">=</span>1m
</pre></div>
<p>Where for <tt class="docutils literal">$N</tt> you should use the device that holds the memory stick.</p>
<p>After I hooked up the Zotac <span class="caps">ZBOX</span> to an ethernet cable and my <span class="caps">TV</span> (I don’t have a spare monitor laying around, except for a display that requires Thunderbolt), I plugged in the memory stick and the system booted and installed smoothly. Working on a command prompt on a <span class="caps">TV</span> isn’t the most comfortable, so I instructed the installer to include OpenSSH. After just a few minutes I was remotely logged in to a freshly installed, fully working Linux system. Modern times.</p>
</div>
<div class="section" id="configuration">
<h2>Configuration</h2>
<p>At first boot, I ran a <tt class="docutils literal"><span class="pre">dist-upgrade</span></tt> to get the latest and greatest software and security patches. I adapted <tt class="docutils literal">.bashrc</tt> to my wishes (especially <tt class="docutils literal">$<span class="caps">PS1</span></tt>), and set locales to <a class="reference external" href="http://askubuntu.com/questions/162391/how-do-i-fix-my-locale-issue">squash certain Perl warnings</a>:</p>
<div class="highlight"><pre><span></span>sudo update-locale <span class="nv">LC_ALL</span><span class="o">=</span>en_US.UTF-8 <span class="nv">LANG</span><span class="o">=</span>en_US.UTF-8
sudo dpkg-reconfigure locales
</pre></div>
<p>I use byobu a lot for running tasks in the background, or as a screen multiplexer when I’m logged in remotely. It’s installed by default with Ubuntu, but I usually tweak a couple of things. I enabled it’s custom colored prompt:</p>
<div class="highlight"><pre><span></span>enable-byobu-prompt
</pre></div>
<p>Icconfigured the different status items, fixed monitoring the right ethernet adapter, set the network transfer units to bytes and set to monitor the right thermal device to show <span class="caps">CPU</span> temperature (of the first core). These settings can all be modified in <tt class="docutils literal"><span class="pre">~/.byobu/status</span></tt> and <tt class="docutils literal"><span class="pre">~/.byobu/statusrc</span></tt>. For the latter, these are the settings I use:</p>
<div class="highlight"><pre><span></span><span class="na">MONITORED_NETWORK</span><span class="o">=</span><span class="s">p4p1</span>
<span class="na">NETWORK_UNITS</span><span class="o">=</span><span class="s">bytes</span>
<span class="na">MONITORED_TEMP</span><span class="o">=</span><span class="s">/sys/class/hwmon/hwmon1/temp1_input</span>
</pre></div>
<p>I use <a class="reference external" href="http://www.multicastdns.org">mDNS</a> for easy reference to systems on my home network. With mDNS, machines in a network that support it can be resolved on the <tt class="docutils literal">.local</tt> domain. It’s part of <span class="caps">OS</span> X and Ubuntu Desktop by default, but with Ubuntu Server the <tt class="docutils literal"><span class="pre">avahi-daemon</span></tt> package needs to be installed manually:</p>
<div class="highlight"><pre><span></span>sudo apt-get install avahi-daemon
</pre></div>
<p>There we go, the new machine is now available using it’s hostname on the <tt class="docutils literal">.local</tt> domain directly. That’s pretty much the most important configuration changes that got me where I wanted, so let’s turn this thing into a real <cite>media</cite> <span class="caps">PC</span>.</p>
</div>
<div class="section" id="kodi">
<h2>Kodi</h2>
<p>I have been using <span class="caps">XBMC</span> — recently renamed to <a class="reference external" href="http://kodi.tv">Kodi</a> — from the moment I built my first media box in 2010. In my opinion it is the best open source media software. The installation instructions for Kodi for Ubuntu based distributions are as <a class="reference external" href="http://kodi.wiki/view/HOW-TO:Install_Kodi_for_Linux#Installing_Kodi_on_Ubuntu-based_distributions">simple</a> as:</p>
<div class="highlight"><pre><span></span>sudo add-apt-repository ppa:team-xbmc/ppa
sudo apt-get update
sudo apt-get install kodi
</pre></div>
<p>Kodi needs an X server, which for this specific Zotac <span class="caps">ZBOX</span> works right out of the box (no pun intended) with the Intel specific drivers:</p>
<div class="highlight"><pre><span></span>sudo apt-get install xserver-xorg xserver-xorg-video-intel
</pre></div>
<p>X11 needs to be configured in such a way that anyone is allowed to launch its own X server (I am going to create a specific <tt class="docutils literal">kodi</tt> user for automatic boot later on). This can be done as follows:</p>
<div class="highlight"><pre><span></span>sudo dpkg-reconfigure x11-common
</pre></div>
<p>I use <tt class="docutils literal">nodm</tt> to login automatically and start Kodi on boot:</p>
<div class="highlight"><pre><span></span>sudo apt-get install nodm
</pre></div>
<p>In <tt class="docutils literal">/etc/default/nodm</tt> change the following values to enable it and to use the <tt class="docutils literal">kodi</tt> user to login with:</p>
<div class="highlight"><pre><span></span><span class="na">NODM_ENABLED</span><span class="o">=</span><span class="s">true</span>
<span class="na">NODM_USER</span><span class="o">=</span><span class="s">kodi</span>
</pre></div>
<p>Unfortunately there is an issue between Plymouth and nodm grabbing terminals, which is why I had to apply the workaround described in <a class="reference external" href="https://bugs.launchpad.net/ubuntu/+source/nodm/+bug/714492">this</a> Ubuntu launchpad issue to get it working correctly.</p>
<p>With nodm set up, the <tt class="docutils literal">kodi</tt> user that will login automatically needs to be added still. I set it up without a password, just to be sure. The next step is very important, otherwise Kodi will be severely limited (no hardware acceleration, no audio, etc.). The new <tt class="docutils literal">kodi</tt> user needs to be in the right groups to grant it access to the resources it needs:</p>
<div class="highlight"><pre><span></span>sudo usermod -a -G cdrom,audio,video,plugdev kodi
</pre></div>
<p>The final step to get Kodi to boot automatically, is to create <tt class="docutils literal"><span class="pre">~kodi/.xsession</span></tt> with the following content:</p>
<div class="highlight"><pre><span></span><span class="ch">#!/bin/sh</span>
kodi
</pre></div>
<p>The new file needs to be executable:</p>
<div class="highlight"><pre><span></span>chmod +x ~kodi/.xsession
</pre></div>
<p>There’s one thing I also set up for audio, which is <tt class="docutils literal">alsamixer</tt>, because I still use an old stereo amplifier (which has served me well for more than 20 years already).</p>
<div class="highlight"><pre><span></span>sudo apt-get install alsa-utils
sudo alsamixer
</pre></div>
<p>I mute all other channels except for the <span class="caps">PCM</span> audio and the set the master volume. With <tt class="docutils literal"><span class="pre">alsa-utils</span></tt> installed the mixer levels are automatically saved and restored on a reboot.</p>
<p>That did the trick for me, after all these steps you should have a full blown media <span class="caps">PC</span>.</p>
</div>
<div class="section" id="backups">
<h2>Backups</h2>
<p>Last but not least, since this box is also my home server, I use a very simple crontab to backup my most important assets, namely my git repositories. The backups have daily, weekly and monthly copies and are synced daily to a remote Linode <span class="caps">VPS</span> instance I own and manage. This is what my <tt class="docutils literal">crontab</tt> looks like:</p>
<div class="highlight"><pre><span></span><span class="c1"># Daily, weekly and monthly repository backups.</span>
<span class="m">0</span> <span class="m">5</span> * * * rsync -a --delete <span class="nv">$DIRECTORY_WITH_GIT_REPOSITORIES</span> <span class="nv">$HOME</span>/backup/daily
<span class="m">30</span> <span class="m">5</span> * * <span class="m">5</span> rsync -a --delete <span class="nv">$HOME</span>/backup/daily/ <span class="nv">$HOME</span>/backup/weekly
<span class="m">0</span> <span class="m">6</span> <span class="m">1</span> * * <span class="nb">cd</span> <span class="nv">$HOME</span>/backup/daily <span class="o">&&</span> tar cjf <span class="nv">$HOME</span>/backup/monthly/<span class="sb">`</span>date +<span class="se">\%</span>Y<span class="se">\%</span>m<span class="se">\%</span>d<span class="sb">`</span>.tar.bz2 *
<span class="c1"># Sync everything daily to my Linode VPS.</span>
<span class="m">0</span> <span class="m">6</span> * * * rsync -a --delete <span class="nv">$HOME</span>/backup/*ly -e ssh <span class="nv">$REMOTE_BACKUP_HOST</span>:backup/
</pre></div>
<p>Replace <tt class="docutils literal">$DIRECTORY_WITH_GIT_REPOSITORIES</tt>, <tt class="docutils literal">$<span class="caps">HOME</span></tt> and <tt class="docutils literal">$REMOTE_BACKUP_HOST</tt> with whatever is applicable.</p>
<p>There’s one thing to configure to complete this setup, which is a simple mail server so cron can tell you when something is wrong. I have configured both Sendmail and Exim in the past, and I really don’t like to be remembered about that, so luckily there’s sSMTP:</p>
<div class="highlight"><pre><span></span>sudo apt-get install ssmtp
</pre></div>
<p>Then edit <tt class="docutils literal">/etc/ssmtp/ssmtp.conf</tt> and put in either your <span class="caps">ISP</span>’s <span class="caps">SMTP</span> host, or any other <span class="caps">SMTP</span> host you can send email from. The command line tool <tt class="docutils literal">ssmtp</tt> can be used to test if it works.</p>
</div>
<div class="section" id="data">
<h2>Data</h2>
<p>Besides the internal 500 <span class="caps">GB</span> <span class="caps">SSD</span>, I also bought a 5 <span class="caps">TB</span> Toshiba Canvio Desktop external 3.5” drive. Yep, 5 <span class="caps">TB</span>. Five. <em>Terra</em>. Bytes. For less than € 150,-. It replaces my 2 <span class="caps">TB</span> drive, which was chock-full, plus I wanted a <span class="caps">USB</span> 3.0 capable drive to connect to my new machine. So that’s going to be a whole lotta stuff to copy. More on that in a minute, first a word about partitioning.</p>
<p>I partitioned the drive using <tt class="docutils literal">cgdisk</tt> with a <span class="caps">GPT</span> partition table (tip: I always used <tt class="docutils literal">cfdisk</tt> so I like <tt class="docutils literal">cgdisk</tt> a lot better than <tt class="docutils literal">parted</tt>). I used a single partition with an ext4 filesystem covering the entire disk. However, I found ext4 reserved over 300 <span class="caps">GB</span> of space (for root, for system processes, and to avoid defragmentation) that is not counted towards free space. This external drive is for media only, so it’s definitely not needed to reserve space for system processes and certainly not 300 <span class="caps">GB</span>. As it turns out this can be tuned with <tt class="docutils literal">tune2fs</tt>:</p>
<div class="highlight"><pre><span></span>sudo tune2fs -m <span class="m">0</span> /dev/sd<span class="nv">$D$N</span>
</pre></div>
<p>Use your specific device <tt class="docutils literal">$D</tt> and partition number <tt class="docutils literal">$N</tt>. Before running <tt class="docutils literal">tune2fs</tt> the 4.6 <span class="caps">TB</span> sized drive, had 4.3 <span class="caps">TB</span> of free space. After running the above command, it shows 4.6 <span class="caps">TB</span> free. That’s better. Back to copying 2 <span class="caps">TB</span> of data.</p>
<p>The quickest way I know — and like — to copy large amounts of data from one system to another is using netcat. I normally use <tt class="docutils literal">scp</tt> for most of my day-to-day data transfers, but for many gigabytes of data it does not make sense to encrypt everything, especially if you control the wire between the two ends. Here’s how I do it. On the one system move into the directory that you want to copy, and run the following command:</p>
<div class="highlight"><pre><span></span>tar -cv . <span class="p">|</span> nc -q <span class="m">10</span> -l <span class="m">45454</span>
</pre></div>
<p>Go to the other system and fire up the following command:</p>
<div class="highlight"><pre><span></span>nc -w <span class="m">10</span> <span class="nv">$REMOTE_HOST</span> <span class="m">45454</span> <span class="p">|</span> tar -xv
</pre></div>
<p>Where for <tt class="docutils literal">$REMOTE_HOST</tt> you need to use the hostname (thank you, mDNS) or <span class="caps">IP</span> address of the host you are copying from. Using netcat I got between 35 and 45 <span class="caps">MB</span>/s data transfer, from the eSATA connected 2 <span class="caps">TB</span> drive to the <span class="caps">USB</span> 3.0 connected 5 <span class="caps">TB</span> drive, using a Gigabit Ethernet connection.</p>
<p>With all the data present on the new disk, I added it to <tt class="docutils literal">/etc/fstab</tt> to be automatically mounted. I like to put drives in <tt class="docutils literal">/etc/fstab</tt> by <span class="caps">UUID</span> (to find the <span class="caps">UUID</span> of a partition, check <tt class="docutils literal"><span class="pre">/dev/disk/by-uuid/</span></tt>). As a result, I could re-use the external drive <span class="caps">UUID</span> entries from my old machine directly on the new machine’s <tt class="docutils literal">/etc/fstab</tt>.</p>
</div>
<div class="section" id="silent-cool-and-low-power">
<h2>Silent, Cool and Low-Power</h2>
<p>To conclude, some statistics. On the old system, the <span class="caps">CPU</span> temperature usually stayed close to around 76°C. Only on hot summer days or when in heavy use, the readings sometimes went above 80°C. The temperature would never go below 70°C, even on cold winter days with a room temperature of only 15°C. As for power use, the old machine used between 22 and 23 W when in use and approximately 20 W when idle. The old 2 <span class="caps">TB</span> external hard drive used 10 W when spinning, adding up to a total of 33 W when in full use.</p>
<p>The <span class="caps">CPU</span> temperature on the new system stays around just 54°C, the influence of room temperature seems to be pretty much gone, though I do not have readings on very cold winter days yet. The new machine is definitely much more power efficient; it uses only 9 W when idle. That includes 1 W of idle power the external drive draws when in standby mode. That’s only 8W for the <span class="caps">PC</span> itself, which is less than half of the idle power that the old system used. Playing music from the <span class="caps">SSD</span> with Kodi uses between 10 to 14 W. Watching a video from the external drive consumes between 17 and 22W.</p>
<p>So the new system is silent, cool and uses less than half the power when idle and about two-thirds of the power when in use. Not bad. Not bad at all.</p>
</div>
Remote Control for Kodi and XBMC 3.2.02015-02-28T00:00:00+01:002015-02-28T00:00:00+01:00Gertjan Zwartjestag:codemuse.co,2015-02-28:/2015/02/28/remote-control-for-kodi-and-xbmc-320<p><a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for Kodi and <span class="caps">XBMC</span></a> version 3.2.0 is available on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-kodi-xbmc/id416082141?l=en&mt=8">App Store</a>. The new version fully supports Kodi 14.x, iOS 8, and iPhone 6 and iPhone 6 Plus. Also, support for pull to refresh is added to the library sections.</p>
<p>I am still looking for …</p><p><a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for Kodi and <span class="caps">XBMC</span></a> version 3.2.0 is available on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-kodi-xbmc/id416082141?l=en&mt=8">App Store</a>. The new version fully supports Kodi 14.x, iOS 8, and iPhone 6 and iPhone 6 Plus. Also, support for pull to refresh is added to the library sections.</p>
<p>I am still looking for more beta testers for future versions, email <tt class="docutils literal">remote@codemuse.co</tt> if you are interested. But for now, enjoy this new version!</p>
Looking for Beta Testers2015-02-14T00:00:00+01:002015-02-14T00:00:00+01:00Gertjan Zwartjestag:codemuse.co,2015-02-14:/2015/02/14/looking-for-beta-testers<p>It has been more than a year since the last release of Remote Control for <span class="caps">XBMC</span>. The release of iOS 8 happened, iPhone 6 and 6 Plus were announced, and shipped. <span class="caps">XBMC</span> got renamed to Kodi and Kodi 14 was released. I worked on supporting iOS 8. I tried out …</p><p>It has been more than a year since the last release of Remote Control for <span class="caps">XBMC</span>. The release of iOS 8 happened, iPhone 6 and 6 Plus were announced, and shipped. <span class="caps">XBMC</span> got renamed to Kodi and Kodi 14 was released. I worked on supporting iOS 8. I tried out Kodi. I got my own iPhone 6. I worked on supporting both the new 4.7” and 5.5” iPhones. But I also added support for pull to refresh and many other minor fixes and improvements.</p>
<p>On top of it all there was also this little guy that happened and changed my life last year. Needless to say, I like programming, but I absolutely love spending time with my kid. Development on my app is limited by that, but I am still motivated to continue on a good pace.</p>
<p>Back to the upcoming release. To support iOS 8, I completely modernized the networking backend, for iPhones 6 support I adopted auto layout in several parts of the <span class="caps">UI</span>. How things change in just several years, from the time of my initial commit, to where I am now. Back then, I started development on <span class="caps">XBMC</span> Remote Control for iPad targeting iOS 3.2. Today, by adopting all the latest iOS technologies, I was able to shrink the number of lines of code, even though I added the significant functionality and features. That’s what I call progress.</p>
<p>So a lot has happened the past year, and I am preparing for a new release of what will be Remote Control for Kodi and <span class="caps">XBMC</span> soon. But before the new version will be available I would love to get it into the hands of more beta testers. With Apple’s new TestFlight program, this has never been easier. All you need to do is install Apple’s TestFlight app, and all I need is your email address.</p>
<p>Interested? Send me an email at <tt class="docutils literal">remote@codemuse.co</tt>.</p>
Featured in Apple TV Concept2014-05-12T00:00:00+02:002014-05-12T00:00:00+02:00Gertjan Zwartjestag:codemuse.co,2014-05-12:/2014/05/12/featured-in-apple-tv-concept<p>About a month ago I was skimming through the <a class="reference external" href="http://www.macrumors.com/roundup/wwdc/">MacRumors <span class="caps">WWDC</span> 2014 roundup</a>, where I first saw the <a class="reference external" href="https://curved.de/news/apple-tv-touch-so-koennte-die-4-generation-aussehen-29810">Apple <span class="caps">TV</span> concept</a>, originally published by German technology magazine <a class="reference external" href="http://curved.de">Curved</a>. An interesting concept, especially the remote controls <span class="caps">UI</span>, which obviously is inspired, if not based directly on my <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC …</span></a></p><p>About a month ago I was skimming through the <a class="reference external" href="http://www.macrumors.com/roundup/wwdc/">MacRumors <span class="caps">WWDC</span> 2014 roundup</a>, where I first saw the <a class="reference external" href="https://curved.de/news/apple-tv-touch-so-koennte-die-4-generation-aussehen-29810">Apple <span class="caps">TV</span> concept</a>, originally published by German technology magazine <a class="reference external" href="http://curved.de">Curved</a>. An interesting concept, especially the remote controls <span class="caps">UI</span>, which obviously is inspired, if not based directly on my <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a> app. I reached out to <a class="reference external" href="https://twitter.com/curved_de">@curved_de</a> and quickly got a reply from Martin <a class="reference external" href="https://twitter.com/deplaatjesmaker">@deplaatjesmaker</a> Hajek who is the original designer of the 3D concept.</p>
<img alt="Apple TV concept" src="https://codemuse.co/images/xbmc-remote/apple-tv-concept/apple-tv-concept.jpg" style="width: 650px;" />
<p>He actually thought he found an image of the <span class="caps">UI</span> of Apple’s own remote app through a Google image search, but in fact it was a screenshot of my app. That may well be the best compliment to get as an iOS app developer!</p>
<p>After my reaching out, Martin immediately updated both <a class="reference external" href="http://www.martinhajek.com/apple-tv-the-next-generation/">his Apple <span class="caps">TV</span> piece</a> on his website as well as the article on Curved with a link attributing the <span class="caps">UI</span> design to <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a>. For that I’d like to publicly thank him. So thanks <a class="reference external" href="https://twitter.com/deplaatjesmaker">@deplaatjesmaker</a>!</p>
<p>Also, don’t forget to check out his latest iPhone 6 concepts on <a class="reference external" href="http://www.martinhajek.com">http://www.martinhajek.com</a>.</p>
Remote Control for XBMC 3.1.02014-02-02T00:00:00+01:002014-02-02T00:00:00+01:00Gertjan Zwartjestag:codemuse.co,2014-02-02:/2014/02/02/remote-control-for-xbmc-310<p><a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a> version 3.1.0 is available for download on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. This version contains several <span class="caps">UI</span> and stability improvements. I also implemented some significant improvements in downloading <span class="caps">TV</span> show information. With larger <span class="caps">TV</span> show libraries or when using slower hardware to run <span class="caps">XBMC</span> (a Raspberry …</p><p><a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a> version 3.1.0 is available for download on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. This version contains several <span class="caps">UI</span> and stability improvements. I also implemented some significant improvements in downloading <span class="caps">TV</span> show information. With larger <span class="caps">TV</span> show libraries or when using slower hardware to run <span class="caps">XBMC</span> (a Raspberry Pi for example), this new version will improve responsiveness and should fix possible timeouts.</p>
Remote Control for XBMC 3.0.02013-11-26T00:00:00+01:002013-11-26T00:00:00+01:00Gertjan Zwartjestag:codemuse.co,2013-11-26:/2013/11/26/remote-control-for-xbmc-300<p>I am pleased to announce that the redesigned version of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a> is now available for download on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>.</p>
<p>I am pleased to announce that the redesigned version of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a> is now available for download on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>.</p>
Remote Control for XBMC on iOS 72013-11-23T00:00:00+01:002013-11-23T00:00:00+01:00Gertjan Zwartjestag:codemuse.co,2013-11-23:/2013/11/23/remote-control-for-xbmc-on-ios-7<p>This morning I submitted a new version of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a> for iOS 7. Finally. It’s completely redesigned from the ground up, which took me more than four months.</p>
<p>Why did it take that long? I wanted to bring consistency in the design of the app on iPhone …</p><p>This morning I submitted a new version of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a> for iOS 7. Finally. It’s completely redesigned from the ground up, which took me more than four months.</p>
<p>Why did it take that long? I wanted to bring consistency in the design of the app on iPhone and iPad and I tried to work out the best experience for iOS 7 on both devices. No pixel of the app has been left untouched by this update. It was a lot of work, but I am very happy with the result.</p>
<p>I started with the overall design and remote controls. I liked the connection panel I introduced for the iPhone version, so I decided to keep it in and bring it to iPad as well. The remote and library icons as well as the remote control buttons needed a more iOS 7 design aesthetic, so I redesigned these from scratch. Likewise, the player and volume controls buttons are also redesigned to fit the overall iOS 7 look. <a class="footnote-reference" href="#id2" id="id1">[1]</a></p>
<p>Launching the app into the remote controls view immediately shows the difference between the new design for iOS 7 and it’s original counterpart.</p>
<img alt="Remote controls on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/remote-iphone-ios6.png" style="width: 320px;" />
<img alt="Remote controls on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/remote-iphone-ios7.png" style="width: 320px;" />
<img alt="Remote controls on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/remote-ipad-ios6.png" style="width: 650px;" />
<img alt="Remote controls on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/remote-ipad-ios7.png" style="width: 650px;" />
<p>The player and volume controls are part of the root view on iPad, on iPhone they are on the now playing view, which got its own redesign. With iOS 7, there’s a nice depth-blur effect when the artwork slides in from the bottom of the screen. On iPad the artwork slides in underneath the toolbar and on iPhone it slides in underneath the player and volume controls.</p>
<img alt="Now playing on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/now-playing-iphone-ios6.png" style="width: 320px;" />
<img alt="Now playing on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/now-playing-iphone-ios7.png" style="width: 320px;" />
<p>The original interface design for iPhone had a lot of custom designed interface chrome, but stock iOS 7 actually looks very good already. As a result I could remove a lot of images from the application bundle (shrinking from almost 15Mb down to only 2.9Mb). Also many custom <span class="caps">UI</span> tweaks could be removed from the source code. I loved that part. Nothing feels better than cleaning up and removing things while actually making the app better. Hopefully the iOS 7 stock <span class="caps">UI</span> elements look and feel don’t wear too quickly. The music library browsing views are pretty much the same with fresh coat of paint:</p>
<img alt="Albums on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/albums-iphone-ios6.png" style="width: 320px;" />
<img alt="Albums on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/albums-iphone-ios7.png" style="width: 320px;" />
<img alt="Artists on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/artists-ipad-ios6.png" style="width: 650px;" />
<img alt="Artists on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/artists-ipad-ios7.png" style="width: 650px;" />
<img alt="Album on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/album-iphone-ios6.png" style="width: 320px;" />
<img alt="Album on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/album-iphone-ios7.png" style="width: 320px;" />
<img alt="Artist on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/artist-ipad-ios6.png" style="width: 650px;" />
<img alt="Artist on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/artist-ipad-ios7.png" style="width: 650px;" />
<p>The <span class="caps">TV</span> shows section on iPad got a full make over, to make it more consistent with it’s iPhone counterpart. On iPhone, the <span class="caps">TV</span> shows view only got a cleaner look, except for the number of unwatched episodes badges. I have tried to make these more consistent with the way Apple’s iOS apps shows unread, unwatched and unlistened items. The screenshots show the banner style lists (which I personally like more), however <span class="caps">TV</span> show posters are still supported as well.</p>
<img alt="TV Shows on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/tvshows-ipad-ios6.png" style="width: 650px;" />
<img alt="TV Shows on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/tvshows-ipad-ios7.png" style="width: 650px;" />
<img alt="TV Shows on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/tvshows-iphone-ios6.png" style="width: 320px;" />
<img alt="TV Shows on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/tvshows-iphone-ios7.png" style="width: 320px;" />
<p>The detailed <span class="caps">TV</span> show view is mostly a design make-over on both iPhone and iPad, again except for the unwatched episode indicator.</p>
<img alt="TV Show on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/tvshow-iphone-ios6.png" style="width: 320px;" />
<img alt="TV Show on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/tvshow-iphone-ios7.png" style="width: 320px;" />
<img alt="TV Show on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/tvshow-ipad-ios6.png" style="width: 650px;" />
<img alt="TV Show on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/tvshow-ipad-ios7.png" style="width: 650px;" />
<p>Finally the movies view also got the new style of flagging unwatched ones. On iPad the movies browser got a more significant redesign to make it more consistent with iPhone, similar to the <span class="caps">TV</span> shows redesign:</p>
<img alt="Movies on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/movies-ipad-ios6.png" style="width: 650px;" />
<img alt="Movies on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/movies-ipad-ios7.png" style="width: 650px;" />
<img alt="Movies on iOS 6" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/movies-iphone-ios6.png" style="width: 320px;" />
<img alt="Movies on iOS 7" src="https://codemuse.co/images/xbmc-remote/ios7-redesign/movies-iphone-ios7.png" style="width: 320px;" />
<p>The new version will be a free update, available on all devices that support iOS 7. As I mentioned before, I’m very content with the new looks and I enjoy using my own app almost daily. I hope everyone out there who is using or who will be using Remote Control for <span class="caps">XBMC</span> will enjoy it as much as I do.</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>I originally did my design work in <a class="reference external" href="http://inkscape.org">Inkscape</a>, but since I’ve bought <a class="reference external" href="http://www.bohemiancoding.com/sketch">Sketch</a>, I’ve recently done all design work with it. It’s really the best <span class="caps">UI</span> design tool I know and well worth the purchase. With this full app redesign I’ve moved over all pixel based <span class="caps">UI</span> design work for Remote Control for <span class="caps">XBMC</span> to Sketch.</td></tr>
</tbody>
</table>
Boost.Foreach and Compiler Bugs2013-08-06T00:00:00+02:002013-08-06T00:00:00+02:00Gertjan Zwartjestag:codemuse.co,2013-08-06:/2013/08/06/boostforeach-and-compiler-bugs<p>Boost is a library that definitively <a class="reference external" href="https://codemuse.co/2008/03/12/boosting-productivity">boosts your productivity</a> writing C++ code. For instance, <tt class="docutils literal">for</tt> loops can be made a lot more readable if you use <a class="reference external" href="http://www.boost.org/doc/libs/1_54_0/doc/html/foreach.html">Boost.Foreach</a>. It’s almost as if you are writing Python, Objective-C or even Java, which support a <tt class="docutils literal">foreach</tt> construct natively.</p>
<p>However, like always …</p><p>Boost is a library that definitively <a class="reference external" href="https://codemuse.co/2008/03/12/boosting-productivity">boosts your productivity</a> writing C++ code. For instance, <tt class="docutils literal">for</tt> loops can be made a lot more readable if you use <a class="reference external" href="http://www.boost.org/doc/libs/1_54_0/doc/html/foreach.html">Boost.Foreach</a>. It’s almost as if you are writing Python, Objective-C or even Java, which support a <tt class="docutils literal">foreach</tt> construct natively.</p>
<p>However, like always, hiding things behind an abstraction <a class="reference external" href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html">can be a problem</a>. Especially when the abstraction <a class="reference external" href="http://lists.boost.org/boost-users/2011/07/69773.php">depends on a compiler bug</a>. That’s the case with <tt class="docutils literal">BOOST_FOREACH</tt> in Boost versions prior to Boost 1.47, which relies on a compiler bug for rvalue detection. And it so happens that is compiler bug is fixed in <span class="caps">GCC</span> 4.6, which breaks older Boost versions.</p>
<p>Ubuntu 12.04 actually ships with Boost 1.46.1 and <span class="caps">GCC</span> 4.6.3. A deadly combination as it seems. Just try to run this little C++ program:</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf"><boost/shared_ptr.hpp></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><boost/foreach.hpp></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><vector></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><iostream></span><span class="cp"></span>
<span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">boost</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o"><</span><span class="kt">int</span><span class="o">></span> <span class="o">></span> <span class="n">f</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">boost</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o"><</span><span class="kt">int</span><span class="o">></span> <span class="o">></span><span class="p">(</span><span class="mi">4</span><span class="p">,</span>
<span class="n">boost</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o"><</span><span class="kt">int</span><span class="o">></span><span class="p">(</span><span class="k">new</span> <span class="kt">int</span><span class="p">(</span><span class="mi">12</span><span class="p">)));</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">argv</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">BOOST_FOREACH</span><span class="p">(</span><span class="k">const</span> <span class="n">boost</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o"><</span><span class="kt">int</span><span class="o">></span> <span class="o">&</span><span class="n">pi</span><span class="p">,</span> <span class="n">f</span><span class="p">())</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="o">*</span><span class="n">pi</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>You would expect to see 4 lines printed with the number 12. Instead you will get this:</p>
<pre class="literal-block">
$ g++ test.cpp -o test
$ ./test
test: /usr/include/boost/smart_ptr/shared_ptr.hpp:412:
boost::shared_ptr<T>::reference boost::shared_ptr<T>::operator*() const
[with T = int, boost::shared_ptr<T>::reference = int&]:
Assertion `px != 0' failed.
Aborted (core dumped)
</pre>
<p>So what’s actually happening here? Internally Boost.Foreach will try to detect whether the container expression is an lvalue or an rvalue. In the example above the result from <tt class="docutils literal">f()</tt> is such rvalue: a temporary object that will be gone as soon as it goes out of scope. Boost.Foreach takes precautions for that by copying the rvalue internally such that it will live as long as the scope of the for loop.</p>
<p>Now what happens if rvalue detection fails in above example? It means that the vector returned by <tt class="docutils literal">f()</tt> will be gone before the statements in the loop get executed. The destruction of the vector means the smart pointers are destructed too. As a result, trying to access them in the <tt class="docutils literal"><span class="pre">std::cout</span></tt> statement will trigger the <tt class="docutils literal">px != 0</tt> assertion.</p>
<p>Fortunately this problem is fixed in Boost 1.47 and up. For more information on how Boost.Foreach works, see <a class="reference external" href="http://www.artima.com/cppsource/foreach.html">Conditional Love: <span class="caps">FOREACH</span> Redux</a>.</p>
Redesign and iPhone XBMC Remote2013-07-30T00:00:00+02:002013-07-30T00:00:00+02:00Gertjan Zwartjestag:codemuse.co,2013-07-30:/2013/07/30/redesign-and-iphone-xbmc-remote<p>After I finished iPhone support in Remote Control for <span class="caps">XBMC</span> I decided that its <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">landing page</a> was definitely overdue for an update. That lead me to decide to also <a class="reference external" href="https://codemuse.co/2013/03/13/now-using-pelican">overhaul the technology I’m using for this site</a>. A new engine and a new design, should be four weeks I …</p><p>After I finished iPhone support in Remote Control for <span class="caps">XBMC</span> I decided that its <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">landing page</a> was definitely overdue for an update. That lead me to decide to also <a class="reference external" href="https://codemuse.co/2013/03/13/now-using-pelican">overhaul the technology I’m using for this site</a>. A new engine and a new design, should be four weeks I thought, and a nice moment to launch iPhone support with a new dedicate page. Those four weeks turned into four months, because while I was redesigning my site we also redesigned and refurbished our bathroom in our house. Although there are many similarities in the design process, I can tell you redesigning a website definitively doesn’t result in the amount of dust you get from redesigning a bathroom.</p>
<p>So even though the Remote Control for <span class="caps">XBMC</span> 2.0.0 update with iPhone and iPod touch support is already available on the App Store for four months (to be precise, it was accepted by Apple on March 12), today, I’m officially launching my new design and a beautifully redesigned Remote Control for <span class="caps">XBMC</span> <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">landing page</a>.</p>
<p>In the meantime I’ve also released a 2.0.1 update with a few fixes which is currently the latest version available for download in the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. Besides support for iPhone and iPod touch, here’s a summary of the changes in 2.0.0 and 2.0.1:</p>
<ul class="simple">
<li>Added rewind/fast-forward buttons for small skips (tap) and seeking (tap-and-hold).</li>
<li>Previous/next buttons act as big skips when video is playing.</li>
<li>Better time formatting for <span class="caps">TV</span> show episodes and songs.</li>
<li>Odd rows in iPad are now colored differently.</li>
<li>Redesigned missing album, <span class="caps">TV</span> show, movie, audio and video art.</li>
<li>Add setting to prefer posters over banners (only supported for Frodo).</li>
<li>Fix vertical alignment of down button on retina displays.</li>
<li>Fix bugs with processing (large) library updates.</li>
<li>Fix crash with Frodo when loading <span class="caps">TV</span> shows that have no associated banner or poster art.</li>
<li>Fix issue with illegal unicode characters in thumbnail paths when <span class="caps">XBMC</span> runs on Mac <span class="caps">OS</span>.</li>
<li>Many other minor bug fixes and improvements.</li>
</ul>
<p>Lastly, with the release of <span class="caps">XBMC</span> 12.0 (Frodo), Remote Control for <span class="caps">XBMC</span> does not support <span class="caps">XBMC</span> 10.0 (Dharma) anymore. Please upgrade your <span class="caps">XBMC</span> installation if you are still using <span class="caps">XBMC</span> 10.0.</p>
Migrated to Pelican2013-03-13T00:00:00+01:002013-03-13T00:00:00+01:00Gertjan Zwartjestag:codemuse.co,2013-03-13:/2013/03/13/now-using-pelican<p>When I started this site, all I wanted was a place to pin down my thoughts. Back in <a class="reference external" href="https://codemuse.co/2007/04/05/hello-world">2007</a>, I chose WordPress to be the backend of Code-muse.com. It’s been almost 6 years, my requirements for this site have changed and there’s been some interesting changes in …</p><p>When I started this site, all I wanted was a place to pin down my thoughts. Back in <a class="reference external" href="https://codemuse.co/2007/04/05/hello-world">2007</a>, I chose WordPress to be the backend of Code-muse.com. It’s been almost 6 years, my requirements for this site have changed and there’s been some interesting changes in the technology landscape with respect to web development and blogging in these years.</p>
<p>Besides writing down an occasional blog post, Code-muse.com has become the home of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a> as well. I was getting tired of having to use WPs web backend to edit the posts and pages, and most of the time was copy/pasting text to/from Vim. So I was actually wondering why I didn’t choose to use a static website generator in the first place. Maybe they weren’t as popular in 2006 as they are now.</p>
<p>I’ve took some time to check out several popular static blog/site generators and finally settled with <a class="reference external" href="http://getpelican.com">Pelican</a>, a Python based static site generator. I’m not really into Ruby, which is why I didn’t go for Jeckyll or Octopress. I checked Hyde, which looks promising, but there’s almost no documentation for Hyde, whereas Pelican’s documentation is excellent. As far as I can tell at this moment, I am quite content with Pelican.</p>
<p>So here it is; a statically served all new Code-muse.com.</p>
Remote Control for XBMC 1.8.0 — New Name!2012-12-14T13:36:00+01:002012-12-14T13:36:00+01:00Gertjan Zwartjestag:codemuse.co,2012-12-14:/2012/12/14/remote-control-for-xbmc-180-new-name<p><span class="caps">XBMC</span> Remote Control for iPad has a new name, it will now live on as <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a>. The latest release (1.8.0) has many internal improvements using new iOS 5.x features, preparing for iPhone/iPod touch support. Yep, you read that correctly: support for iPhone and …</p><p><span class="caps">XBMC</span> Remote Control for iPad has a new name, it will now live on as <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">Remote Control for <span class="caps">XBMC</span></a>. The latest release (1.8.0) has many internal improvements using new iOS 5.x features, preparing for iPhone/iPod touch support. Yep, you read that correctly: support for iPhone and iPod touch devices is coming! But before that’s finished, this release pushes some improvements made in the process so far and fixes compatibility with the upcoming <span class="caps">XBMC</span> Frodo (12.0) release.</p>
<p>For the full list of changes and to get the latest version, visit the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>.</p>
XBMC Remote Control for iPad 1.7.02012-09-22T19:02:00+02:002012-09-22T19:02:00+02:00Gertjan Zwartjestag:codemuse.co,2012-09-22:/2012/09/22/xbmc-remote-control-for-ipad-170<p>A new update to <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a>, which adds additional eye-candy when you browse your music and <span class="caps">TV</span> show library and brings some minor bug fixes including updates to support the latest Frodo builds, is now is now available as version 1.7.0 on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store …</a></p><p>A new update to <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a>, which adds additional eye-candy when you browse your music and <span class="caps">TV</span> show library and brings some minor bug fixes including updates to support the latest Frodo builds, is now is now available as version 1.7.0 on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>.</p>
XBMC Remote Control for iPad 1.6.02012-08-14T21:39:00+02:002012-08-14T21:39:00+02:00Gertjan Zwartjestag:codemuse.co,2012-08-14:/2012/08/14/xbmc-remote-control-for-ipad-160<p>A few weeks ago I released a minor update bringing button tap-and-hold repeat functionality for navigation controls as well as the volume decrease and increase buttons. With that I was also preparing new seek functionality which is available in the latest update.</p>
<p>You can now tap-and-hold the next and previous …</p><p>A few weeks ago I released a minor update bringing button tap-and-hold repeat functionality for navigation controls as well as the volume decrease and increase buttons. With that I was also preparing new seek functionality which is available in the latest update.</p>
<p>You can now tap-and-hold the next and previous buttons to rewind and fast-forward. Also the progress bar is now a slider, that can be dragged to seek as well. Furthermore, some minor improvements: I improved the volume slider graphic design; added suspend and reboot options to the power button; added early Frodo nightly build support ((Tested with 7/27 build, but no guarantees it’ll keep working with newer builds)); internal network robustness improvements and some minor bugfixes.</p>
<p><a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a> 1.6.0 is now available on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>.</p>
XBMC Remote Control for iPad 1.5.0 — Movie Library Support2012-05-04T22:44:00+02:002012-05-04T22:44:00+02:00Gertjan Zwartjestag:codemuse.co,2012-05-04:/2012/05/04/xbmc-remote-control-for-ipad-150-movie-library-support<p>I’m very excited to announce that finally <span class="caps">XBMC</span> Remote Control for iPad now supports movie library browsing too! Version 1.5.0 is now available for download on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>.</p>
<p>I’ve spent a lot of time optimizing the new movie thumbnail view for all iPad models, including …</p><p>I’m very excited to announce that finally <span class="caps">XBMC</span> Remote Control for iPad now supports movie library browsing too! Version 1.5.0 is now available for download on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>.</p>
<p>I’ve spent a lot of time optimizing the new movie thumbnail view for all iPad models, including the original iPad 1, to work smoothly even with large libraries. The browser works in both portrait as well as landscape mode, just like the music and <span class="caps">TV</span> shows browsers. For large enough libraries a section index is included automatically for jumping quickly through different sections of your library. I’ve also updated the <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">dedicated</a> page here on my blog too with fresh screenshots. Enjoy!</p>
XBMC Remote Control for iPad 1.4.4 — iPad Retina Display Support2012-03-17T23:08:00+01:002012-03-17T23:08:00+01:00Gertjan Zwartjestag:codemuse.co,2012-03-17:/2012/03/17/xbmc-remote-control-for-ipad-144-ipad-retina-display-support<p>Unfortunately I haven’t (yet) laid my hands on a new iPad, but I hope to do so soon. I’m really interested to see Apple’s Retina display on a 9.7” device, and of course I’d love to see my own <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a> on …</p><p>Unfortunately I haven’t (yet) laid my hands on a new iPad, but I hope to do so soon. I’m really interested to see Apple’s Retina display on a 9.7” device, and of course I’d love to see my own <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a> on it! I immediately updated it with Retina display support after Apple’s latest update of Xcode with a Retina iPad simulator and I’m happy to announce that this update has landed on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. For everyone that can already try it on a new iPad: enjoy!</p>
XBMC Eden RC12012-03-01T08:56:00+01:002012-03-01T08:56:00+01:00Gertjan Zwartjestag:codemuse.co,2012-03-01:/2012/03/01/xbmc-eden-rc1<p>A few days ago the <span class="caps">XBMC</span> team released <span class="caps">XBMC</span> Eden release candidate 1. In there, the <span class="caps">JSON</span>-<span class="caps">RPC</span> protocol version has been updated to version 4, which causes problems with <span class="caps">XBMC</span> Remote Control for iPad. That’s my bad; I thought the version number would only be increased at the …</p><p>A few days ago the <span class="caps">XBMC</span> team released <span class="caps">XBMC</span> Eden release candidate 1. In there, the <span class="caps">JSON</span>-<span class="caps">RPC</span> protocol version has been updated to version 4, which causes problems with <span class="caps">XBMC</span> Remote Control for iPad. That’s my bad; I thought the version number would only be increased at the official release, but it seems that I should have accounted for the new version number in the <span class="caps">RC</span> cycles already. For everyone that updated to <span class="caps">RC1</span> and having problems connecting, this morning I submitted <span class="caps">XBMC</span> Remote Control for iPad 1.4.3 for review by Apple, which fixes the problem. I hope it will be available in the App Store in a few days.</p>
<p>By the way, movie support is going forward, my goal is to release it around the time that <span class="caps">XBMC</span> Eden is officially released as well.</p>
<p><strong>Update:</strong> 1.4.3 which fixes this problem has been approved by Apple and is available as of March 2.</p>
XBMC Remote Control for iPad 1.4.2 — XBMC 11.0 (Eden) Support2012-01-06T16:06:00+01:002012-01-06T16:06:00+01:00Gertjan Zwartjestag:codemuse.co,2012-01-06:/2012/01/06/xbmc-remote-control-for-ipad-142-xbmc-110-eden-support<p>A minor update of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a> is now available on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>, which adds support for the upcoming <span class="caps">XBMC</span> 11.0 (Eden). If you are still using nightly builds, please make sure it is from October 19 or later. Upcoming Eden beta’s and <span class="caps">RC</span> builds …</p><p>A minor update of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a> is now available on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>, which adds support for the upcoming <span class="caps">XBMC</span> 11.0 (Eden). If you are still using nightly builds, please make sure it is from October 19 or later. Upcoming Eden beta’s and <span class="caps">RC</span> builds should be fully supported, because the <span class="caps">XBMC</span> development team has frozen the <span class="caps">JSON</span>-<span class="caps">RPC</span> interface, that <span class="caps">XBMC</span> Remote Control for iPad uses to communicate with <span class="caps">XBMC</span>.</p>
<p>In the meantime I’m continuing my work on movie library browsing support.</p>
Education (R)evolution2011-12-23T20:52:00+01:002011-12-23T20:52:00+01:00Gertjan Zwartjestag:codemuse.co,2011-12-23:/2011/12/23/education-revolution<p>The past two months I have gone back to being a student again. Well, at least in the evening hours. Following <a class="reference external" href="http://ai-class.com">ai-class.com</a> took a significant part of the time I would have otherwise spent on other personal endeavors such as reading, blogging or writing <span class="caps">XBMC</span> remotes, but it was …</p><p>The past two months I have gone back to being a student again. Well, at least in the evening hours. Following <a class="reference external" href="http://ai-class.com">ai-class.com</a> took a significant part of the time I would have otherwise spent on other personal endeavors such as reading, blogging or writing <span class="caps">XBMC</span> remotes, but it was worth every minute. Although the future might prove me wrong, I have the feeling that the internet — after affecting or re-inventing many other fields — is now starting to redefine education as well. Not that the internet itself reinvents something; its of course humans themselves that redefine things <em>using</em> the internet as a new medium. That’s what Peter Norvig and Sebastian Thrun did with their “Introduction to Artificial Intelligence” class.</p>
<p>Salman Kahn’s <a class="reference external" href="http://kahnacademy.org">Kahn Academy</a> was the first pioneer that I heard of that was trying to combine education and the internet in a very useful way, and he’s ever-expanding the number of online lessons you can watch. With 2,700 videos you can learn something new everyday for the next 7 years. Amazing.</p>
<p>Back in August I read on Hacker News the announcement that Stanford is opening up an <span class="caps">AI</span> class via the web. For free. I was really excited about this idea and I enrolled that same day. During my <span class="caps">CS</span> program at the Eindhoven University of Technology I didn’t really took any of the <span class="caps">AI</span> or machine learning tracks, so it would also be a very interesting topic for me to learn more about. How would that be, to enroll and follow a full class through the internet? Would I be able to do a Stanford-level class in my spare time, next to my day-time job? Is this the future of education?</p>
<p>After going through the full class I can only say I liked it very much. The material was interesting, the format was very well thought out, and both professor Norvig and professor Thrun are apt and enthusiastic teachers. To get a feeling of the format, just follow one or two units, do some quizzes or take a look at the homework or exam questions. There were teething problems of course, and obviously an actual live lecture with a teacher and peers is in many ways incomparable to following an online class by yourself. However I believe this is a really good start and gets very close; after finishing the final exam and receiving my final rating, the accomplishment feels the same as it felt when I was attending university.</p>
<p>Summarized, I’ve learned a lot about a field that I had left unexplored up to now, and while doing that I might have also seen a glimpse of the future.</p>
XBMC Remote Control for iPad 1.4.0 — TV Show Library Support2011-09-18T21:09:00+02:002011-09-18T21:09:00+02:00Gertjan Zwartjestag:codemuse.co,2011-09-18:/2011/09/18/xbmc-remote-control-for-ipad-140-tv-show-library-support<p>The latest update of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a> adds long-awaited support for browsing your <span class="caps">TV</span> shows library and directly starting an episode from inside the browser; you can get the latest version from the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. I’ve re-used the concept for browsing an artist’s albums for browsing …</p><p>The latest update of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a> adds long-awaited support for browsing your <span class="caps">TV</span> shows library and directly starting an episode from inside the browser; you can get the latest version from the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. I’ve re-used the concept for browsing an artist’s albums for browsing a <span class="caps">TV</span> show’s seasons and episodes and I think the result works very well. For screenshots check out <span class="caps">XBMC</span> Remote Control for iPad’s <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">dedicated page</a>.</p>
<p>Besides some minor improvements and bug fixes I also implemented the support for the changes in the nightly builds made on September 5. I tested with the build from September 10 (caab280), which worked for me. Builds from before September 6 are *not* supported anymore, so please make sure to update <span class="caps">XBMC</span> if you encounter problems with nightly builds. Again, I’ll do my best to keep up with the <span class="caps">JSON</span>-<span class="caps">RPC</span> developments, but I cannot guarantee anything until <span class="caps">RC</span> cycles start.</p>
<p>I know this is only half of full video library support, but I’m working hard on movie support though. So more features to come soon.</p>
XBMC Remote Control for iPad 1.3.02011-08-19T13:31:00+02:002011-08-19T13:31:00+02:00Gertjan Zwartjestag:codemuse.co,2011-08-19:/2011/08/19/xbmc-remote-control-for-ipad-130<p>Another update of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a> has hit the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. This time it is a maintenance update with some minor bug fixes.
Besides that, I added Quartz2D <tt class="docutils literal">UIImage</tt> resizing code for album art thumbnails in the music browser and for thumbnails shown in the now playing view …</p><p>Another update of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a> has hit the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. This time it is a maintenance update with some minor bug fixes.
Besides that, I added Quartz2D <tt class="docutils literal">UIImage</tt> resizing code for album art thumbnails in the music browser and for thumbnails shown in the now playing view, which improves the interpolation quality of the downscaled images. Also, the connectivity indicator will also show when larger items are being downloaded from <span class="caps">XBMC</span>, such as music library updates, thumbnails, etc.</p>
<p>Last, but certainly not least, I added preliminary support for <span class="caps">XBMC</span>’s nightly builds. I used the build from August 8 (a1c2947) to implement the changes for the upcoming Eden release. I’ll do my best to keep up with the nightly builds, but I will only be able to start guaranteeing Eden compatibility when the <span class="caps">RC</span> releases start. For now, any change developers might make to the <span class="caps">JSON</span>-<span class="caps">RPC</span> interface in <span class="caps">XBMC</span> might break compatibility.</p>
<p>For more information on <span class="caps">XBMC</span> Remote Control for iPad, you can also take a look at the (updated) <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">dedicated page</a>.</p>
XBMC Remote Control for iPad 1.2.0 —- Music Library Support2011-07-14T22:03:00+02:002011-07-14T22:03:00+02:00Gertjan Zwartjestag:codemuse.co,2011-07-14:/2011/07/14/xbmc-remote-control-for-ipad-120-music-library-support<p>As of today, version 1.2.0 of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a>, is available for download on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. I have spent much of my free time on implementing music library support and I am very happy with the result. Being able to browse and play music from …</p><p>As of today, version 1.2.0 of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a>, is available for download on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. I have spent much of my free time on implementing music library support and I am very happy with the result. Being able to browse and play music from my <span class="caps">XBMC</span> library using my iPad as a remote control is for me —- apart from basic remote control —- the most important feature. That’s why I spent a lot of time polishing this feature. A short screencast demoing the new interface:</p>
<center><iframe width="480" height="360" src="http://www.youtube.com/embed/VgMiFPSfPdI" frameborder="0" allowfullscreen></iframe></center><p>The artist, album and song information is cached locally on your iPad. The same for album thumbnails (which are downloaded and cached the first time you browse the album). This is mainly done for speed and <span class="caps">UI</span> responsiveness, but it enables browsing your music library without being connected to <span class="caps">XBMC</span> as well. Various artists are supported, as well as unknown albums (holding songs that are not associated with an album). You can play an album starting with a specific song, shuffle an album, and play or shuffle all albums by a single artist.</p>
<p>I will be updating the page <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">dedicated</a> to <span class="caps">XBMC</span> Remote Control for iPad with new screenshots and description of the new
features very soon.</p>
Conway’s Law: A Thought Experiment2011-06-18T15:30:00+02:002011-06-18T15:30:00+02:00Gertjan Zwartjestag:codemuse.co,2011-06-18:/2011/06/18/conways-law-a-thought-experiment<p>Almost two years ago, I <a class="reference external" href="https://codemuse.co/2009/09/28/software-centered-organisation">wrote</a> something about Conway’s law — “Any organization that designs a system […] will inevitably produce a design whose structure is a copy of the organization’s communication structure”. I concluded:</p>
<blockquote>
As a corollary to Conway’s Law I would say: don’t hold on to …</blockquote><p>Almost two years ago, I <a class="reference external" href="https://codemuse.co/2009/09/28/software-centered-organisation">wrote</a> something about Conway’s law — “Any organization that designs a system […] will inevitably produce a design whose structure is a copy of the organization’s communication structure”. I concluded:</p>
<blockquote>
As a corollary to Conway’s Law I would say: don’t hold on to existing organization structures, if they are in the way. In a software company, it’s the product that sells. So if you want to improve the product and go forward, you will need to be flexible and willing to change: the company and its product should evolve together.</blockquote>
<p>I have been contemplating recently about this statement pushed towards the other far end: how would Conway’s law apply to (mostly large) corporations that shuffle around developers, ahem, “resources” from project to project? What software architecture would you get in that case? A Big Ball of Mud. Yep, that’s what I would say. <a class="reference external" href="http://http://www.laputan.org/mud/">Big Ball of Mud</a>.</p>
XBMC Remote Control for iPad 1.1.02011-04-29T09:45:00+02:002011-04-29T09:45:00+02:00Gertjan Zwartjestag:codemuse.co,2011-04-29:/2011/04/29/xbmc-remote-control-for-ipad-110<p>Earlier this week Apple approved a minor update to <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a>, so version 1.1.0 is now available for download on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. This update brings support for setting username and password to connect with <span class="caps">XBMC</span>. It also fixes some minor issues: sending return key …</p><p>Earlier this week Apple approved a minor update to <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a>, so version 1.1.0 is now available for download on the <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">App Store</a>. This update brings support for setting username and password to connect with <span class="caps">XBMC</span>. It also fixes some minor issues: sending return key code from iPad keyboard when <span class="caps">XBMC</span> virtual keyboard is active and improved keyboard handling for windows with edit controls. If you’re wondering what’s this <span class="caps">XBMC</span> Remote Control for iPad is all about, here’s a little demo video to see it in action:</p>
<center><iframe width="480" height="360" src="http://www.youtube.com/embed/EIv9DEU_BBY" frameborder="0" allowfullscreen></iframe></center><p>I originally built <span class="caps">XBMC</span> setup to replace my <a class="reference external" href="https://codemuse.co/2010/07/24/building-a-mini-itx-ion-based-htpc">iPod that was struck by lightning</a>, but besides music, I’m using <span class="caps">XBMC</span> very often too now to watch <span class="caps">TV</span> shows, movies, etc. To watch a <span class="caps">TV</span> show episode or movie you’re gonna have to have your <span class="caps">TV</span> turned on, so I mostly use <span class="caps">XBMC</span>’s on-screen menu to select the item to watch. That’s why I focused first on remote control in version 1.x. However, to turn on some music, it would be very nice if I wouldn’t have to turn on my <span class="caps">TV</span> to use my app for that purpose. So I’m now spending the time on my app working on support for browsing <span class="caps">XBMC</span>’s music library and being able to play artists, albums and individual songs from the music library. I’m planning that to be the next major update.</p>
iPad as XBMC Remote2011-03-30T21:37:00+02:002011-03-30T21:37:00+02:00Gertjan Zwartjestag:codemuse.co,2011-03-30:/2011/03/30/ipad-as-xbmc-remote<p>In the course of the last ~9 months <a class="reference external" href="/category/htpc.html">I have been writing</a> about this little <span class="caps">HTPC</span> I built, how I set up <span class="caps">XBMC</span> on a Ubuntu server install, using my iPhone as a remote control for it. Until I bought an iPad last year on one of my trips to …</p><p>In the course of the last ~9 months <a class="reference external" href="/category/htpc.html">I have been writing</a> about this little <span class="caps">HTPC</span> I built, how I set up <span class="caps">XBMC</span> on a Ubuntu server install, using my iPhone as a remote control for it. Until I bought an iPad last year on one of my trips to California. How cool would it be to have a <span class="caps">XBMC</span> remote app for the iPad? Back then, there were only a few apps for remote controlling <span class="caps">XBMC</span> through your iPad, they were expensive and I didn’t like their interfaces. That’s when I knew it was time for me to learn a new platform, a new language some new tools and a couple of new frameworks.</p>
<p>So yes, it’s been a bit quiet around here, since I have been spending a fair bit of my spare time on this little project… It was, and still is, a lot of fun learning and spending my time in a new environment. I already loved the Mac <span class="caps">OS</span> and iOS experience as end-user, but Apple has really done a magnificent job on the software development side as well. While I have been coding away on my own application, several new <span class="caps">XBMC</span> remote control applications emerged on the App Store. Some better than others, some even pretty good ones. However, I was having too much fun working on my own thing to stop me from finishing and adding another one to the list.</p>
<p>So here I am, proud to announce that as of today my first iPad App is available for <a class="reference external" href="https://itunes.apple.com/us/app/remote-control-for-xbmc/id416082141?l=en&mt=8">download</a> in Apple’s App Store! Last week I submitted version 1.0.0 of <a class="reference external" href="https://codemuse.co/remote-control-for-kodi"><span class="caps">XBMC</span> Remote Control for iPad</a> for review, and after a week of refreshing my mailbox way too often, it got accepted. I’ve added a <a class="reference external" href="https://codemuse.co/remote-control-for-kodi">dedicated page</a> for it on Code-muse.com, which currently contains basically the same information as in the App Store, however I’m planning to add more about configuring and using it there.</p>
<p>I’ve not stopped working on it, in contrary, I’ve still got a whole lot of features and ideas that I’d like to add in the coming weeks, months. First off, I want to be able to start me some music using my iPad and after that, besides music, it would be very nice to be able to also browse video items from your <span class="caps">XBMC</span> library.</p>
<p>I’m off testing my App by firing up another episode of The Wire. In the meantime, for everyone who’s willing to give it a try too, I’m open for bug reports, ideas, suggestions, and all other comments.</p>
Code Ownership2011-02-10T21:34:00+01:002011-02-10T21:34:00+01:00Gertjan Zwartjestag:codemuse.co,2011-02-10:/2011/02/10/code-ownership<p>I’m a big fan of having a coding style guide when working on a piece of software with a team. To be honest, I actually believe it’s an absolute must for a team to have a unified code writing style to be able to function optimally. Many software …</p><p>I’m a big fan of having a coding style guide when working on a piece of software with a team. To be honest, I actually believe it’s an absolute must for a team to have a unified code writing style to be able to function optimally. Many software developers will agree with me, but also many will disagree, either way, it can be a pretty hot topic for a nice discussion during lunch, coffee, or maybe even while having a beer, if you’re really hardcore.</p>
<p>Although being very important, uniform coding style is merely a tool to ‘implement’ an underlying, more important aspect of collaborative software development, namely code ownership. That’s what I want to discuss today.</p>
<p>In ye olde days, I would always defend team coding style with the argument of achieving the higher goal of collective code ownership. Everybody owns all code. Everybody is allowed to change whatever part of the source base they think is necessary. Refactoring is key to keep the code base maintainable. I still believe in all of that, except for the very first thing, namely the fact that everybody should own all code. That’s just plain impossible. With a code base of say, more than 100k lines of code, you must be the smartest guy on earth to own it all. In that case, when you’re the best programmer in the world, you don’t even need a team, so you can stop reading here. However, were talking about real life here, and in real life, we cannot all be the best coders in the world. In real life, you will have a team, and you will have Bob who knows all about the network layer, Joe who is all into the <span class="caps">GUI</span> stuff, and then there is Collin who you need for the build and test system, and of course don’t forget about Jane, she knows a bit about everything, especially how all components are tied together.</p>
<p>So there you are with your utopian dream that everybody needs to own all code. Let’s take another spin at it. Is there another way to look at this issue of code ownership? Actually there is: Thanks to reading <a class="reference external" href="http://codersatwork.com/">Coders at Work</a> I’m now looking at this slightly different. Namely, we can turn it turn around: Instead of everybody owning all code we want nobody to own any code.</p>
<p>Nobody owning any code? So what does that mean? Well, each and every team member should be “allowed” to touch any part they want. That means that everybody has access to the whole code base, and should be able to read and understand every part. There’s where the coding style comes in to play: as a tool to facilitate team members to be able to more quickly read and understand a part of the code base that he didn’t write himself originally and is thus not yet familiar with. Another super valuable tool here is an <span class="caps">API</span> documentation generator. Especially together with a set of guides that prescribe how you should document your classes, methods, functions, and all other public interfaces. Next to a coding style guide, an <span class="caps">API</span> documentation system (such as Javadoc, Doxygen, Sphinx, etc.) is something I’d always implement in a team setting.</p>
<p>An important question that remains still is, if nobody owns the code, who’s responsible then? Simple: the whole team is responsible for all code. If something’s wrong anywhere, it’s the team’s responsibility to figure out who would be the best suited for solving the particular issue. Could be anyone, since everybody should be able to at least figure out what’s going on. Of course there will probably this particular person in the team that knows most about this specific part of the software where the problem occurs. Now I’m not saying he shouldn’t be the one to attack the issue, he might as well be the best person to solve it, he’ll probably be the quickest at least, I guess. However this guy could be Super Busy with some other Highly Important Things, or on vacation or whatever. With the team being responsible, the problem should be solvable by any team member.</p>
<p>Summarized, I’m advocating the tools to build a real team, a team that feels collectively responsible for what they are building. I believe that, in achieving this goal, the form of collective code ownership where nobody owns any part, but where you have team responsibility (but not ownership) for all code, together with tools like coding style guides and <span class="caps">API</span> documentation tools can be a big leap forward.</p>
Opening a Root Terminal with gksu2010-12-02T09:03:00+01:002010-12-02T09:03:00+01:00Gertjan Zwartjestag:codemuse.co,2010-12-02:/2010/12/02/opening-a-root-terminal-with-gksu<p>On my Gentoo box, I’ve got this key-combination which is linked to a command to open a root terminal which I use very heavily. The command behind it is simply a call to gksu as follows: <tt class="docutils literal">gksu <span class="pre">-uroot</span> <span class="pre">/usr/bin/gnome-terminal</span></tt>. This same kind of command used to be …</p><p>On my Gentoo box, I’ve got this key-combination which is linked to a command to open a root terminal which I use very heavily. The command behind it is simply a call to gksu as follows: <tt class="docutils literal">gksu <span class="pre">-uroot</span> <span class="pre">/usr/bin/gnome-terminal</span></tt>. This same kind of command used to be a menu item, both in Gentoo, but also the Ubuntu distribution had a menu item like that by default.</p>
<p>Unfortunately however, already a while ago after a Gnome update, my key-combination stopped working. The menu item was gone. Not only on my Gentoo box, but I noticed that on a certain version of Ubuntu this menu item seemed to have disappeared too. After a search, I found I was not the only person suffering from this problem. There’s actually a <a class="reference external" href="https://bugzilla.gnome.org/show_bug.cgi?id=564649">bug report</a> in Gnome’s Bugzilla for this particular issue. Unsolved at the time I found it, unfortunately. However, the suggested work-around was perfect for me. I changed the command behind my root-terminal-short-cut-key-combination to the following script:</p>
<div class="highlight"><pre><span></span><span class="ch">#!/bin/sh</span>
<span class="nb">eval</span> <span class="sb">`</span>dbus-launch --sh-syntax --exit-with-session<span class="sb">`</span>
/usr/libexec/gconfd-2 <span class="p">&</span>
/usr/bin/gnome-terminal --geometry 112x38
</pre></div>
<p>While working on my Gentoo box today, my eye fell on a “Root Terminal” menu item in the “Accessories” menu. Interesting. It’s actually calling gksu with a Gnome terminal as root again. And it works! It seems that someone has <a class="reference external" href="http://git.gnome.org/browse/gnome-terminal/commit/?id=f41c3d14bdfd533109d7d75bdbb2e2a0ab59b60c">fixed</a> the problem. Thanks Christian Persch!</p>
<p>That’s one less work-around-convenience-script for me.</p>
Fix Static on XBMC Sound Signal2010-10-27T15:02:00+02:002010-10-27T15:02:00+02:00Gertjan Zwartjestag:codemuse.co,2010-10-27:/2010/10/27/fix-static-on-xbmc-sound-signal<p><a class="reference external" href="https://codemuse.co/2010/10/08/setting-up-xbmc-and-iphone-as-remote">After having set up <span class="caps">XBMC</span></a>, I loaded in all my music and video (where music actually was the most important, because <a class="reference external" href="https://codemuse.co/2010/07/24/building-a-mini-itx-ion-based-htpc">my iPod was blasted by lightning</a>). I already listened to several of my albums for a couple of days using my new and shiny mbox, after I started noticing …</p><p><a class="reference external" href="https://codemuse.co/2010/10/08/setting-up-xbmc-and-iphone-as-remote">After having set up <span class="caps">XBMC</span></a>, I loaded in all my music and video (where music actually was the most important, because <a class="reference external" href="https://codemuse.co/2010/07/24/building-a-mini-itx-ion-based-htpc">my iPod was blasted by lightning</a>). I already listened to several of my albums for a couple of days using my new and shiny mbox, after I started noticing a bit of static, especially during silences in a song, or in between albums when no music is playing.</p>
<p>I tried some things, fiddling with the cables that connect mbox to my amp, but that didn’t help, I did however find out that turning up the volume on the amplifier while no music is playing made it worse. So it must be something in the system I guessed.</p>
<p>I was a bit afraid that the static might be caused by a component, maybe the fan, or whatever. But fortunately when I fired up alsamixer I found the problem. Simply all and every channel was turned up to its loudest value. Even the input channels! After muting those input channels, the static was gone. Although it returned when I rebooted the system.</p>
<p>Turns out that the <tt class="docutils literal"><span class="pre">xbmc-live</span></tt> package installs an init script that contains some code that’s apparently the problem: on boot in turns each and every channel’s volume to it’s max, including the input levels.</p>
<p>Luckily this can be fixed quite easily. Edit <tt class="docutils literal">/etc/default/grub</tt>, and from the variable <tt class="docutils literal">GRUB_CMDLINE_LINUX_DEFAULT</tt> remove the <tt class="docutils literal">setvolume</tt> constant from <tt class="docutils literal">[list]</tt> in the <tt class="docutils literal"><span class="pre">xbmc=[list]</span></tt> argument. This will prevent the <span class="caps">XBMC</span> init script to screw up the volume levels.</p>
<p>Still it’s nice to store a decent mixer configuration and have that load up on boot. We can do that with <span class="caps">ALSA</span> as follows: first use alsamixer to set up the levels the way you want them, then to store the levels as the default configuration for next bootup, run:</p>
<pre class="literal-block">
sudo alsactl store 0
</pre>
<p>And that’s that, another problem fixed.</p>
Setting up XBMC and iPhone as Remote2010-10-08T14:31:00+02:002010-10-08T14:31:00+02:00Gertjan Zwartjestag:codemuse.co,2010-10-08:/2010/10/08/setting-up-xbmc-and-iphone-as-remote<p>After getting mbox up and running, it was finally time to put the <em>m</em> in mbox. This is going to be a very short post, because the guys over at <span class="caps">XBMC</span> have an excellent tutorial on their Wiki on how to get <span class="caps">XBMC</span> running on a minimal Ubuntu install. All …</p><p>After getting mbox up and running, it was finally time to put the <em>m</em> in mbox. This is going to be a very short post, because the guys over at <span class="caps">XBMC</span> have an excellent tutorial on their Wiki on how to get <span class="caps">XBMC</span> running on a minimal Ubuntu install. All I did was follow (a subset of) the steps over <a class="reference external" href="http://wiki.xbmc.org/?title=XBMCbuntu">here</a>. The walkthrough is pretty extensive, and like me, you might not need or want to follow each and every step, but the basic part to get everything up and running is in there and described in good detail.</p>
<p>The second most important thing for me was to be able to control <span class="caps">XBMC</span> remotely with my iPhone. Even before buying the components, I checked whether that’d be possible, otherwise I wouldn’t have been building mbox in the first place. But luckily some guys in Australia, under the name of collect3, have built a really nice iPhone app called <a class="reference external" href="http://remote.collect3.com.au"><span class="caps">XBMC</span> Remote</a> that does exactly what I want.</p>
<p>There were some problems with <tt class="docutils literal"><span class="pre"><record></record></span></tt> showing up in album names with the latest <span class="caps">XBMC</span> release, however this has been fixed in version 1.7.7 of the iPhone app. So, again lucky me, because I don’t have to write all about the work around I used to use to fix that particular problem…</p>
<p>To conclude, I was pretty amazed of the power of both <span class="caps">XBMC</span> and the remote iPhone app. It just works! I’m already happily using this setup for over a month now, and I still have nothing really to complain about.</p>
Coretemp and Byobu2010-09-17T08:44:00+02:002010-09-17T08:44:00+02:00Gertjan Zwartjestag:codemuse.co,2010-09-17:/2010/09/17/coretemp-and-byobu<p>Being at the point to leave mbox turned on 24/7, I wanted a way to monitor it’s temperature. I installed a so called fan mate, with which I can manually adjust the <span class="caps">CPU</span>’s fan speed. So here’s what I did. First you need to install the …</p><p>Being at the point to leave mbox turned on 24/7, I wanted a way to monitor it’s temperature. I installed a so called fan mate, with which I can manually adjust the <span class="caps">CPU</span>’s fan speed. So here’s what I did. First you need to install the Ubuntu package called <tt class="docutils literal"><span class="pre">lm-sensors</span></tt> to enable querying <span class="caps">CPU</span> temperature on the Zotac <span class="caps">ION</span>-<span class="caps">ITX</span> boards. Next make sure the <tt class="docutils literal">coretemp</tt> module is loaded, either <tt class="docutils literal">modprobe</tt>‘ing it manually or by adding it to <tt class="docutils literal">/etc/modules</tt> to have it load automatically.</p>
<p>After doing that, type <tt class="docutils literal">sensors</tt> to see the temperature of the <span class="caps">CPU</span>(s). Now that’s nice, but wouldn’t it be even much cooler to add a temperature display to <a class="reference external" href="https://launchpad.net/byobu">byobu</a>? That’s what I’d think. So create a file <tt class="docutils literal">5_sensors</tt> in <tt class="docutils literal"><span class="pre">~/.byobu/bin</span></tt>, make it executable and fire up your favorite editor to add the following content to it:</p>
<div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
<span class="nv">t</span><span class="o">=</span><span class="sb">`</span>sensors <span class="p">|</span> grep <span class="s2">"Core 0:"</span> <span class="se">\</span>
<span class="p">|</span> sed -e <span class="s1">'s/Core 0: \++//'</span> <span class="se">\</span>
<span class="p">|</span> sed -s <span class="s1">'s/\.0°C \+(crit.*).*$//'</span><span class="sb">`</span>
<span class="k">if</span> <span class="o">[</span> <span class="nv">$t</span> -gt <span class="m">49</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
<span class="nv">color</span><span class="o">=</span><span class="s2">"kR"</span>
<span class="k">else</span>
<span class="nv">color</span><span class="o">=</span><span class="s2">"kB"</span>
<span class="k">fi</span>
<span class="nb">printf</span> <span class="s2">"\005{= %s}%s\005{-}\005{= kw}\260%s\005{-}"</span> <span class="s2">"</span><span class="nv">$color</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$t</span><span class="s2">"</span> <span class="s2">"C"</span>
</pre></div>
<p>There you go, fire up byobu and you’ll see a new field appear (make sure to enable the “custom” status notifications, by pressing F9 for the byobu menu, go into “Toggle status notifications” and check “custom”). I use color red for a temperature above 49 degrees, which is encoded in the if statement. Feel free to change it however you like!</p>
Building a mini-ITX ION Based HTPC (2)2010-09-12T20:27:00+02:002010-09-12T20:27:00+02:00Gertjan Zwartjestag:codemuse.co,2010-09-12:/2010/09/12/building-a-mini-itx-ion-based-htpc-2<p>Already a few Saturdays ago the last package of items arrived, so the unboxing could start. I thought to include some images of the unpacking and assembly process.</p>
<div class="figure">
<img alt="Hardware" src="https://codemuse.co/images/mbox/mbox1.jpg" />
<p class="caption">The total set of hardware I ordered</p>
</div>
<p>Actually the first time ever in my life to lay hands on a mini-<span class="caps">ITX …</span></p><p>Already a few Saturdays ago the last package of items arrived, so the unboxing could start. I thought to include some images of the unpacking and assembly process.</p>
<div class="figure">
<img alt="Hardware" src="https://codemuse.co/images/mbox/mbox1.jpg" />
<p class="caption">The total set of hardware I ordered</p>
</div>
<p>Actually the first time ever in my life to lay hands on a mini-<span class="caps">ITX</span> mainboard. I’d only seen them as images on the web (honestly). Some images of the assembly in progress:</p>
<div class="figure">
<img alt="Zotac ION ITX A-E package" src="https://codemuse.co/images/mbox/mbox2.jpg" />
<p class="caption">Contents of the Zotac <span class="caps">ION</span> <span class="caps">ITX</span> A-E package</p>
</div>
<div class="figure">
<img alt="Mainboard installed into M350" src="https://codemuse.co/images/mbox/mbox3.jpg" />
<p class="caption">Mainboard installed into M350 (1)</p>
</div>
<div class="figure">
<img alt="Mainboard installed into M350" src="https://codemuse.co/images/mbox/mbox4.jpg" />
<p class="caption">Mainboard installed into M350 (2)</p>
</div>
<p>After finishing the assembly process, it was time to start setting up the software. I decided to go for a Ubuntu server install and without a <span class="caps">CD</span> or <span class="caps">DVD</span> drive I had to resort to an <span class="caps">USB</span> install. I first tried putting a full server <span class="caps">CD</span> install image onto an <span class="caps">USB</span> drive using <a class="reference external" href="http://unetbootin.sourceforge.net/">UNetbootin</a> and boot and install from that. Booting and everything went fine, but then I ran into problems installing from the <span class="caps">USB</span> drive, because of missing symlinks and truncated filenames. These problems probably were related to the fact that the <span class="caps">USB</span> drive needs to be a <span class="caps">FAT</span> filesystem (to boot). A quick search on Google showed me that I’m not the only one suffering from these issues.</p>
<p>The next try was to boot from <span class="caps">USB</span> but install from network. Again booting went fine, but setting up a wireless connection from the <span class="caps">USB</span> boot environment seemed to be impossible. Maybe it is possible, but I didn’t want to spend yet more time. So I was almost moving my new little media computer down to the living room next to the internet modem to connect it directly through a cable, when I had a new hunch. Maybe I can easily share my wireless internet connection from my MacBook to another <span class="caps">PC</span> using a cable… Connect cable, click, click. Open system preferences on my MacBook, click, click, click. Reconfigure network from installer. Woa, it works! Thanks Steve <span class="amp">&</span> co!</p>
<p>There we have it: mbox is alive. Up and running Ubuntu Server 10.04. But it’s not a real media box yet, still some more things to configure. Therefore, I’ve made a separate blog category named “mbox”. I’ll be writing more posts including how I configured a lot of things, and will all file them in there.</p>
Qt and Fontconfig2010-09-04T01:24:00+02:002010-09-04T01:24:00+02:00Gertjan Zwartjestag:codemuse.co,2010-09-04:/2010/09/04/qt-and-fontconfig<p>After upgrading to Lucid Lynx I found that all Qt based applications would not have anti-aliased fonts anymore. For example Skype would look awful with these pixelated fonts. Unfortunately Google didn’t help me out, so I started a little research of my own into this issue. I was previously …</p><p>After upgrading to Lucid Lynx I found that all Qt based applications would not have anti-aliased fonts anymore. For example Skype would look awful with these pixelated fonts. Unfortunately Google didn’t help me out, so I started a little research of my own into this issue. I was previously able to <a class="reference external" href="https://codemuse.co/2009/11/04/ubuntus-small-arial">tweak font settings</a> using <tt class="docutils literal"><span class="pre">~/.fonts.conf</span></tt> so I thought to start there.</p>
<p>To make a very long story a whole lot shorter; assigning pixelsize turns off font hinting for Qt apps. I wasn’t able to figure out why, but I did find a solution for my particular setup, resulting in the following <tt class="docutils literal"><span class="pre">~/.fonts.conf</span></tt>:</p>
<div class="highlight"><pre><span></span><span class="cp"><?xml version='1.0'?></span>
<span class="cp"><!DOCTYPE fontconfig SYSTEM 'fonts.dtd'></span>
<span class="nt"><fontconfig></span>
<span class="nt"><match</span> <span class="na">target=</span><span class="s">"font"</span><span class="nt">></span>
<span class="nt"><test</span> <span class="na">qual=</span><span class="s">"all"</span> <span class="na">name=</span><span class="s">"family"</span> <span class="na">compare=</span><span class="s">"eq"</span><span class="nt">><string></span>Arial<span class="nt"></string></test></span>
<span class="nt"><test</span> <span class="na">qual=</span><span class="s">"all"</span> <span class="na">name=</span><span class="s">"pixelsize"</span> <span class="na">compare=</span><span class="s">"eq"</span><span class="nt">><double></span>12<span class="nt"></double></test></span>
<span class="nt"><edit</span> <span class="na">name=</span><span class="s">"pixelsize"</span> <span class="na">mode=</span><span class="s">"assign"</span><span class="nt">><double></span>13<span class="nt"></double></edit></span>
<span class="nt"></match></span>
<span class="nt"></fontconfig></span>
</pre></div>
<p>You really have to look carefully to notice the difference with the <a class="reference external" href="https://codemuse.co/2009/11/04/ubuntus-small-arial">original</a>: it’s the <tt class="docutils literal"><span class="pre">qual="all"</span></tt> attribute in both <tt class="docutils literal">test</tt> nodes. That did the trick for me.</p>
The Future Is Now2010-09-01T17:21:00+02:002010-09-01T17:21:00+02:00Gertjan Zwartjestag:codemuse.co,2010-09-01:/2010/09/01/the-future-is-now<a class="reference external image-reference" href="http://www.amazon.com/Design-Everyday-Things-Donald-Norman/dp/0465067107/ref=sr_1_1?ie=UTF8&s=books&qid=1283316654&sr=8-1"><img alt="Design of Everyday Things by Donald Norman" class="align-right" src="https://codemuse.co/images/design-of-everyday-things-cover.png" /></a>
<p>Been on an Amsterdam-San Francisco flight again, so more time to read. An excerpt from “The Design of Everyday Things”:</p>
<blockquote>
Would you like a pocket-size device that reminded you of each appointment and daily event? I would. I am waiting for the day when portable computers become small enough that …</blockquote><a class="reference external image-reference" href="http://www.amazon.com/Design-Everyday-Things-Donald-Norman/dp/0465067107/ref=sr_1_1?ie=UTF8&s=books&qid=1283316654&sr=8-1"><img alt="Design of Everyday Things by Donald Norman" class="align-right" src="https://codemuse.co/images/design-of-everyday-things-cover.png" /></a>
<p>Been on an Amsterdam-San Francisco flight again, so more time to read. An excerpt from “The Design of Everyday Things”:</p>
<blockquote>
Would you like a pocket-size device that reminded you of each appointment and daily event? I would. I am waiting for the day when portable computers become small enough that I can keep one with me at all times. I will definitely put all my reminding burdens upon it. It has to be small. It has to be convenient to use. And it has to be relatively powerful, at least by today’s standards. It has to have a full, standard typewriter keyboard and a reasonably large display. It needs good graphics, because that makes a tremendous difference in usability, and a lot of memory —- a huge amount, actually. And it should be easy to hook up to the telephone; I need to connect it to my home and laboratory computers. Of course, it should be relatively inexpensive. What I ask for is not unreasonable. The technology I need is available today. It’s just that the full package has never been put together, partly because the cost in today’s world would be prohibitive. But it will exist in imperfect form in five e years, possibly in perfect form in ten.</blockquote>
<p>Do you think what I think? I reckon that Donald A. Norman must be the owner of an iPhone. At least the quote above is a perfect description of today’s smartphones, in particular the iPhone which in my opinion is one of a kind both in design and usability. Now this book is first published in 1988, so Norman was ~10 years off, still funny to bump into, in the already quite interesting book.</p>
Setting up WPA2 Wireless2010-08-31T06:52:00+02:002010-08-31T06:52:00+02:00Gertjan Zwartjestag:codemuse.co,2010-08-31:/2010/08/31/setting-up-wpa2-wireless<p>After first <a class="reference external" href="https://codemuse.co/2010/09/12/building-a-mini-itx-ion-based-htpc-2">setting up Ubuntu Server on mbox</a>, apart from ethernet I wanted to set up WiFi too, so whenever I move it somewhere in the house where there’s no wired connections it can still connect to the network and the internet. From earlier experience I know setting up …</p><p>After first <a class="reference external" href="https://codemuse.co/2010/09/12/building-a-mini-itx-ion-based-htpc-2">setting up Ubuntu Server on mbox</a>, apart from ethernet I wanted to set up WiFi too, so whenever I move it somewhere in the house where there’s no wired connections it can still connect to the network and the internet. From earlier experience I know setting up <span class="caps">WPA2</span> can surely be a bit of a <span class="caps">PITA</span>. It took me a whole-lot-o-time to figure this all out, so at least for myself to remember, here’s how I did it.</p>
<p>For the Zotac board’s Atheros chip to work in Linux, you will need <a class="reference external" href="http://wireless.kernel.org/en/users/Download">compat-wireless</a>. After installing that, reboot, and automatically the <tt class="docutils literal">ath9k</tt> module will be loaded by the Ubuntu kernel. Next install <tt class="docutils literal"><span class="pre">wpa-supplicant</span></tt>. Then edit <tt class="docutils literal">/etc/network/interfaces</tt> and add:</p>
<pre class="literal-block">
auto wlan0
iface wlan0
inet dhcp
wpa-ssid <your-network-ssid-goes-here>
wpa-key-mgmt WPA-PSK
wpa-psk <your-plain-text-key-goes-here>
</pre>
<p>For added security you can make this file readable for root only, since your <span class="caps">WPA2</span> password is in there unencrypted. There’s also ways to put it in there in an encrypted version, but I don’t really care since I’m the only user of the little box.</p>
<p>That’s it. If I’d knew all this beforehand, it would’ve saved me a whole-lot-o-time for sure.</p>
SCons, SWIG & Python2010-08-27T16:19:00+02:002010-08-27T16:19:00+02:00Gertjan Zwartjestag:codemuse.co,2010-08-27:/2010/08/27/scons-swig-python<p>There are some problems that you can only really solve, let alone understand, by diving into code. Lucky enough the Open Source movement has spread like wildfire these days, also for developer tools. So besides that it’s fun and very educating to read someone else’s source code, in …</p><p>There are some problems that you can only really solve, let alone understand, by diving into code. Lucky enough the Open Source movement has spread like wildfire these days, also for developer tools. So besides that it’s fun and very educating to read someone else’s source code, in come cases it’s also really, really helpful to find out how a program is doing its tricks internally to really understand how to best use it. In particular this problem case that I’ve been investigating including a combination of <a class="reference external" href="http://www.scons.org">SCons</a>, <a class="reference external" href="http://www.swig.org"><span class="caps">SWIG</span></a> and Python.</p>
<p>It’s a pretty straightforward setup. You’ve got this C++ library which you want to export to Python. You’ve already setup an interface to Lua, using <span class="caps">SWIG</span>. Now the cool thing about <span class="caps">SWIG</span> <a class="footnote-reference" href="#id2" id="id1">[1]</a> is, that it’s really easy to export the same interface to different scripting languages, so you want to use <span class="caps">SWIG</span>’s power to use your existing setup and extend that from Lua to Python as well. You take your existing <tt class="docutils literal">.i</tt> file, divide it up into two separate files, a general one and a Lua specific one. Say <tt class="docutils literal">common.i</tt> and <tt class="docutils literal">lua.i</tt> where you include <tt class="docutils literal">common.i</tt> in <tt class="docutils literal">lua.i</tt>. Then you can create your new <tt class="docutils literal">python.i</tt> with the Python specific instructions for <span class="caps">SWIG</span>, again including <tt class="docutils literal">common.i</tt>. Problem solved.</p>
<p>Well, not if you’re using SCons as your build tool and you put the <tt class="docutils literal">%module</tt> statement in <tt class="docutils literal">common.i</tt>. That does work for Lua, but for Python strange things will happen with SCons’ build dependencies on the <tt class="docutils literal">.py</tt> wrapper file generated by <span class="caps">SWIG</span>. I had to go all the way into SCons’ <tt class="docutils literal">Tool/swig.py</tt> to find out what the problem was. While SCons scans for <tt class="docutils literal">%module</tt> statements, which, if found SCons uses to define the <tt class="docutils literal">.py</tt> file build dependencies for Python extensions, <tt class="docutils literal">%include</tt> statements aren’t honored as such. That’s when I undestood that the problem was my Python specific <tt class="docutils literal">python.i</tt> which didn’t have a <tt class="docutils literal">%module</tt> statement! I put that into <tt class="docutils literal">common.i</tt>, reusing it for Lua and Python, thinking that would be ok. However, that setup will mislead SCons to thinking that there are no <tt class="docutils literal">%module</tt> statements at all. So build dependencies will be incorrect, leading to build errors.</p>
<p>Lesson learned: when using SCons, always put the <tt class="docutils literal">%module</tt> statements for <span class="caps">SWIG</span> in the <tt class="docutils literal">.i</tt> file that is used to directly generate the scripting language extension from.</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>Yes I am a fan.</td></tr>
</tbody>
</table>
Building a mini-ITX ION Based HTPC2010-07-24T13:49:00+02:002010-07-24T13:49:00+02:00Gertjan Zwartjestag:codemuse.co,2010-07-24:/2010/07/24/building-a-mini-itx-ion-based-htpc<p>Motivated by a heavy summer storm, where lightning struck a tree in the front garden of one of my neighbors, killing my iPod, I’m building my very own <span class="caps">HTPC</span>. Besides my broken iPod, also the fact that the cost of compact sized hardware has dropped, was another reason to …</p><p>Motivated by a heavy summer storm, where lightning struck a tree in the front garden of one of my neighbors, killing my iPod, I’m building my very own <span class="caps">HTPC</span>. Besides my broken iPod, also the fact that the cost of compact sized hardware has dropped, was another reason to start looking into the option of building a little media box. Last but not least, having an iPhone that fits my entire iTunes library, I don’t need another portable music player anymore.</p>
<p>I’ve got several purposes planned for my media box, namely: to host my music library using Squeezebox Server, connect it to my amplifier and play music with it, connect it to my <span class="caps">TV</span> to be able to play videos with it — most likely using <span class="caps">XBMC</span>, and to use it as a little web server and source control server. With that in my mind, I pointed Safari to a couple of hardware web shops, and ordered the following hardware to start with:</p>
<ul class="simple">
<li><strong>Mini-Box M350</strong> — Currently one of the smallest (if not smallest) mini-<span class="caps">ITX</span> enclosures, very suitable for fanless operation because of its design for natural air convection. I’m not planning on installing an internal <span class="caps">DVD</span> or Blu-ray drive, which would require a different case.</li>
<li><strong>Zotac <span class="caps">ION</span> <span class="caps">ITX</span> A-E</strong> — A low power dual-core Intel Atom N330 @ 1.6Ghz operated mainboard, with nVidia <span class="caps">ION</span> graphics processor capable of 1080p video playback. Perfectly fits my needs. Should even be possible to operate fanless, but we’ll see how hot it will get when I finally put the pieces together. One of the nice things about this mainboard is that it comes with an integrated <span class="caps">PSU</span>, which saves you some money and installation hassle. Goes well with the M350 too.</li>
<li><strong>Zalman Fan Mate 2</strong>— Just to be sure, when things get too hot, I can still install the optional fan that comes with the main board. With this handy tool it’s possible to reduce the fan’s speed to reduce the produced noise, because usually the fan doesn’t need to be running full speed.</li>
<li><strong><span class="caps">WD5000BUDT</span></strong> — A 2.5” 500Gb Western Digital hard drive design for systems that are running 24/7. Low power, cooler operation and 32Mb cache.</li>
<li><strong>Kingston 2Gb <span class="caps">DDR2</span></strong> — Running at 800Mhz, the highest speed supported by the Zotac board, I’ve only ordered one piece of 2Gb. I might consider upgrading to 2x2Gb to take advantage of the Dual Channel feature. But for now, I’m sticking with only one piece of 2Gb <span class="caps">DDR2</span> memory.</li>
</ul>
<p>The grand total of these 5 items was € 335.56. If I’d had to buy a new iPod Classic and docking station (which were both dead), that would’ve cost me € 278. So for an additional € 57.56 I now have a full-blown little media pc. Not bad. Not bad at all.</p>
Ubuntu, setuptools and install-layout=deb2010-07-23T14:09:00+02:002010-07-23T14:09:00+02:00Gertjan Zwartjestag:codemuse.co,2010-07-23:/2010/07/23/ubuntu-setuptools-and-install-layoutdeb<p>I wanted to start out with some wxPython <span class="caps">GUI</span> testing and was trying to get <a class="reference external" href="https://fedorahosted.org/dogtail/">dogtail</a> installed on my Ubuntu 10.04 system. The current dogtail version that you can install with Synaptic is 0.6.1, while I want to try out 0.7.0. So I grabbed the …</p><p>I wanted to start out with some wxPython <span class="caps">GUI</span> testing and was trying to get <a class="reference external" href="https://fedorahosted.org/dogtail/">dogtail</a> installed on my Ubuntu 10.04 system. The current dogtail version that you can install with Synaptic is 0.6.1, while I want to try out 0.7.0. So I grabbed the source from dogtail’s website, unpacked it into <tt class="docutils literal">/usr/local/src</tt> and ran:</p>
<pre class="literal-block">
$ cd /usr/local/src/dogtail-0.7.0$ sudo setup.py install
</pre>
<p>However, when I tried to run <tt class="docutils literal">sniff</tt> for example, it can’t find it’s image files, because it’s looking explicitly in <tt class="docutils literal">/usr/share</tt> instead of <tt class="docutils literal">/usr/local/share</tt>. Ok, so let’s try again:</p>
<pre class="literal-block">
$ sudo setup.py install --prefix=/usr
</pre>
<p>This time, <tt class="docutils literal">sniff</tt> starts complaining that there’s no module named <tt class="docutils literal">dogtail.config</tt>. The problem seems to be that instead of installing into <tt class="docutils literal"><span class="pre">dist-packages</span></tt>, with a prefix other than <tt class="docutils literal">/usr/local</tt>, the package files will be installed in <tt class="docutils literal"><span class="pre">site-packages</span></tt>. A bit of Googling tells me that Ubuntu doesn’t have <tt class="docutils literal"><span class="pre">/usr/lib/pythonx.y/site-packages</span></tt> in its path by default. Only <tt class="docutils literal"><span class="pre">dist-packages</span></tt> inside <tt class="docutils literal">/usr/local/lib/pythonx.y</tt> and in <tt class="docutils literal">/usr/lib/pythonx.y</tt> are added to Python’s system path by default (see <a class="reference external" href="https://bugs.launchpad.net/ubuntu/+source/python2.6/+bug/362570">this launchpad bug</a> for more information).</p>
<p>Now luckily enough there’s a special argument for distutils if you want to install a “distribution” package manually, namely <tt class="docutils literal"><span class="pre">--install-layout=deb</span></tt>. Passing this argument will put the package using <tt class="docutils literal">/usr</tt> as prefix and using dist-packages instead of <tt class="docutils literal"><span class="pre">site-packages</span></tt>, as if you were installing a deb package. So:</p>
<pre class="literal-block">
$ sudo setup.py install --install-layout=deb
</pre>
<p>That did the trick for me. Now back to what I was originally wanting to figure out: wxPython <span class="caps">GUI</span> scripting and testing with dogtail.</p>
<p><strong>Edit:</strong> an anonymous user pointed out to me that no <tt class="docutils literal"><span class="pre">site-packages</span></tt> directory is in Python’s system path by default; he’s right, I revisited the issue and my post, and it is the <tt class="docutils literal"><span class="pre">--prefix=/usr</span></tt> which is the problem. Ubuntu’s distutils will put custom installed packages in <tt class="docutils literal"><span class="pre">/usr/local/lib/pythonx.y/dist-packages</span></tt> automatically, but when you use a different prefix, the default behavior is to use <tt class="docutils literal"><span class="pre">site-packages</span></tt>. That’s why you shouldn’t use <tt class="docutils literal"><span class="pre">--prefix=/usr</span></tt>, but <tt class="docutils literal"><span class="pre">--install-layout=deb</span></tt> instead.</p>
Gnome Keyring Password Problem Fixed in Ubuntu 10.042010-07-15T09:13:00+02:002010-07-15T09:13:00+02:00Gertjan Zwartjestag:codemuse.co,2010-07-15:/2010/07/15/gnome-keyring-password-problem-fixed-in-ubuntu-1004<p>After I wrote up <a class="reference external" href="https://codemuse.co/2009/07/15/ubuntu-jaunty-how-to-change-gnome-keyring-password">my post</a> about problems changing my Ubuntu’s user account password, which didn’t automatically updated Gnome’s keyring, I found that I was not the only one suffering from this problem.</p>
<p>A while ago I upgraded to 10.04, and not long after that I …</p><p>After I wrote up <a class="reference external" href="https://codemuse.co/2009/07/15/ubuntu-jaunty-how-to-change-gnome-keyring-password">my post</a> about problems changing my Ubuntu’s user account password, which didn’t automatically updated Gnome’s keyring, I found that I was not the only one suffering from this problem.</p>
<p>A while ago I upgraded to 10.04, and not long after that I had to change my password again (the half-yearly password-will-expire-soon emails started coming in on the account I use on that system). So I did. With that I can also confirm that the keyring password problems have been fixed by the Ubuntu team in 10.04.</p>
<p>Thanks Ubuntu!</p>
Some Random Quotes2010-06-13T11:54:00+02:002010-06-13T11:54:00+02:00Gertjan Zwartjestag:codemuse.co,2010-06-13:/2010/06/13/some-random-quotes<p>Last month I visited Silicon Valley again. Always nice to be there. Not only for the weather and the surroundings, but also always really good to catch up and work together with my overseas colleagues face to face again. Only the flight from Amsterdam to San Francisco is not a …</p><p>Last month I visited Silicon Valley again. Always nice to be there. Not only for the weather and the surroundings, but also always really good to catch up and work together with my overseas colleagues face to face again. Only the flight from Amsterdam to San Francisco is not a short one, though that leaves you a lot of time for reading. So I took my chance and took with me some various writings, most notably <a class="reference external" href="http://www.amazon.com/Coders-at-Work-Peter-Seibel/dp/1430219483/ref=sr_1_1?ie=UTF8&s=books&qid=1276251543&sr=8-1">Coders at Work</a>, which I can definitely recommend.</p>
<p>Anyways, all that reading got me to pen down some random but interesting quotes I encountered:</p>
<blockquote>
<p>There are two ways to design a system: “One way is to make it so simple that there are obviously no deficiencies and the other ways is to make it so complicated that there are no obvious deficiencies” —- <span class="caps">C.A.R.</span> Hoare.</p>
<p><span class="dquo">“</span>When documents are mostly to enable handoffs, they are evil. When they capture a record that is best not forgotten, they are valuable” —- Tom Poppendieck.</p>
<p><span class="dquo">“</span>Its easier to optimize correct code than to correct optimized code”—- Joshua Bloch.</p>
<p><span class="dquo">“</span>There’s a grand myth about requirements: If you write them down, users will get exactly what they want. That’s not true. At best, users will get exactly what was written down, which may or may not be anything like what they really want.” —- Mike Cohn</p>
</blockquote>
<p>It’s interesting that only such a small number of words can express such a great deal of experience.</p>
New Title Image2010-06-03T10:06:00+02:002010-06-03T10:06:00+02:00Gertjan Zwartjestag:codemuse.co,2010-06-03:/2010/06/03/new-title-image<p>I’ve already been living in <a class="reference external" href="http://maps.google.com/?q='s-Hertogenbosch">‘s-Hertogenbosch</a> for one and a half years now, so it’s about time to update my blog’s header image, because it was still depicting Utrecht, which is the city I <em>used</em> to live. So this time I chose a photo that’s not …</p><p>I’ve already been living in <a class="reference external" href="http://maps.google.com/?q='s-Hertogenbosch">‘s-Hertogenbosch</a> for one and a half years now, so it’s about time to update my blog’s header image, because it was still depicting Utrecht, which is the city I <em>used</em> to live. So this time I chose a photo that’s not related to where I live, so I can safely move without having to update my blog’s design. I took this one on my last trip to California; it’s seaweed on one of the beaches along the <a class="reference external" href="http://en.wikipedia.org/wiki/17-Mile_Drive">17-Mile Drive</a>.</p>
Google Nexus One: YAAP2010-03-16T16:09:00+01:002010-03-16T16:09:00+01:00Gertjan Zwartjestag:codemuse.co,2010-03-16:/2010/03/16/google-nexus-one-yaap<p>In the past six months I could not put up and resist my tech-innards wanting a smartphone anymore. I had almost bought an iPhone last year, after which I impatiently was awaiting Google’s launch of the Nexus One, only to find out it would only be available in the …</p><p>In the past six months I could not put up and resist my tech-innards wanting a smartphone anymore. I had almost bought an iPhone last year, after which I impatiently was awaiting Google’s launch of the Nexus One, only to find out it would only be available in the <span class="caps">US</span> the first months after its initial release. I was seriously considering importing one, so this month it was time to finally make up my mind: iPhone or Android.</p>
<p>After reading and viewing many technical comparisons (I especially liked <a class="reference external" href="http://www.technobuffalo.com/blog/iphone/nexus-one-vs-iphone-3gs">TechnoBuffalo’s review video</a>), I was still in doubt. Although the Nexus One is technically a very capable phone and Android is certainly a promising platform, Apple’s iPhone kind of still kept “feeling” better. Then I found <a class="reference external" href="http://www.boygeniusreport.com/2010/01/09/google-android-personal-thoughts/">Boy Genius’ Personal Thoughts</a> about Android, which pushed me all the way over to the iPhone camp again. I too am missing the soul in Andriod. The little robot logo is cute, but it seems to me that that is almost the only thing that’s consistent.</p>
<p>So I wasn’t surprised by today’s Gizmodo article stating that <a class="reference external" href="http://gizmodo.com/5494406/the-nexus-one-is-a-total-flop">The Nexus One is a Total Flop</a>. Well, to me, the Nexus One is simply Yet Another Andriod Phone <a class="footnote-reference" href="#id2" id="id1">[1]</a>.</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>But hey, I might have become a little biased, after using an iPhone for the past 11 days.</td></tr>
</tbody>
</table>
Help, NUMLOCK is Broken!2010-01-28T15:51:00+01:002010-01-28T15:51:00+01:00Gertjan Zwartjestag:codemuse.co,2010-01-28:/2010/01/28/help-numlock-is-broken<p>I can’t remember after which update (of Gnome/Ubuntu) this happened, but each time when I fire up the Gnome Calculator and start hitting the numbers on my keyboard’s keypad, nothing appears in the calculator’s display! Aha, of course, <span class="caps">NUMLOCK</span> turned off. So I hit the <span class="caps">NUMLOCK …</span></p><p>I can’t remember after which update (of Gnome/Ubuntu) this happened, but each time when I fire up the Gnome Calculator and start hitting the numbers on my keyboard’s keypad, nothing appears in the calculator’s display! Aha, of course, <span class="caps">NUMLOCK</span> turned off. So I hit the <span class="caps">NUMLOCK</span> key and start banging on the keypad again. Still no numbers appear, but… What the heck, the mouse is moving?</p>
<p>After consulting the all-knowing Google, I found the cause of this rather interesting behavior. Open <tt class="docutils literal">System → Preferences → Keyboard</tt>. Then go to the <tt class="docutils literal">Mouse Keys</tt> tab. Now here’s the million dollar question. Why would somebody <em>ever</em> want to move its mouse pointer with the keypad? Maybe because you broke your mouse slamming it on your desk because you we’re so irritated that you couldn’t use your keypad? I don’t know. I’ve never had the urge to control my mouse pointer using the keyboard. Maybe they’d called it <em>keypad-pointer</em> if it was meant to be controlled by the keypad.</p>
<p>Well, they didn’t, so press <tt class="docutils literal">Shift + <span class="caps">NUMLOCK</span></tt>. This will uncheck the “Pointer can be controlled using the keypad” checkbox. Why was this box checked in the first place? Maybe its the default. Or maybe I once accidentally held down the shift key when I pressed <tt class="docutils literal"><span class="caps">NUMLOCK</span></tt>.</p>
<p>That must be it.</p>
Coding Standards, But Why?2009-12-21T17:01:00+01:002009-12-21T17:01:00+01:00Gertjan Zwartjestag:codemuse.co,2009-12-21:/2009/12/21/coding-standards-but-why<p>I already had a long standing draft to write something up about coding standards. To be more specific, coding standards about coding <em>style</em>. I’ve had many, no, too many (heated) discussions about coding standards and coding style, so I was — and am — reluctant to say something publicly about the …</p><p>I already had a long standing draft to write something up about coding standards. To be more specific, coding standards about coding <em>style</em>. I’ve had many, no, too many (heated) discussions about coding standards and coding style, so I was — and am — reluctant to say something publicly about the topic. However, sometimes the momentum is just right, and you can’t resist.</p>
<p>As a developer, source code is your deliverable, it is <em>the</em> thing you produce, and you should try to make it look good. But what is good? <em>How</em> should it look? To debate this and find a compromise, you could as well host your own <span class="caps">COP15</span>. The results will be as disappointing. There is no such thing as the Best Looking Coding Style.</p>
<p>However, I do firmly believe in <em>uniform coding style</em>. In an independent team, all produced code style should be consistent. At all times. No exceptions. And I mean it: No Exceptions!Use iron fist if needed.</p>
<p>Well that’s what <em>I</em> believe. Do I need arguments? I think not; consistent coding style is intuitively a Good Thing. Unfortunately when talking to other developers, they want arguments. Of course — who doesn’t want arguments when somebody asks you to change habits?</p>
<p>So, to get back to the momentum I started with, while me and a colleague were in an email discussion with a certain module’s author about adapting his code into our team’s code base, the perfect opportunity revealed itself for me to get back to the dust-collecting coding standards post again.</p>
<p>My colleague wrote:</p>
<blockquote>
<p>Just let me emphasize that we think style and code readability and consistency <em>really</em> is important, which is different from what a lot of people who write code think: if it works and the design is good, the code is good. This only holds when you’re the only one working on it, as soon as multiple people get involved it’s a very good thing to make all the code look uniformly, and keep the code readable and properly commented.</p>
<p>The main argument is that it helps shared ownership of the code (i.e. other people don’t feel reluctant editing your code to fix bugs, and won’t assume it is crap because it looks messy, to play the broken-window theory: it’s already crap so why should I care fixing it). Having all the code look the same also helps spotting inconsistencies, like parameters or functions that should be private but are public, debug code that is actually not debug code, comments that are misplaced and confusing etc.</p>
<p>It’s all a combination of minor nitpicking, but taking all of it together it definitely adds substantial value to a shared codebase.</p>
</blockquote>
<p>Need I say more?</p>
Ubuntu’s Small Arial2009-11-04T15:27:00+01:002009-11-04T15:27:00+01:00Gertjan Zwartjestag:codemuse.co,2009-11-04:/2009/11/04/ubuntus-small-arial<p>Being spoiled with the near perfect font rendering of Mac <span class="caps">OS</span> X on my MacBook, I always found Linux’ font appearance to be a bit behind. Especially in ye old days before libXft and FreeType2, font rendering in X11 applications was just plain ugly. However, with the introduction of font …</p><p>Being spoiled with the near perfect font rendering of Mac <span class="caps">OS</span> X on my MacBook, I always found Linux’ font appearance to be a bit behind. Especially in ye old days before libXft and FreeType2, font rendering in X11 applications was just plain ugly. However, with the introduction of font hinting, things have been improved a lot. Especially slight hinting looks very good.</p>
<p>As of Jaunty Jackalope, slight hinting (or “Subpixel Smooting” in Ubuntu terms) became the default in Ubuntu. But actually I kept reverting back to “Best Contrast” simply because of <em>one</em> annoying adverse effect of “Subpixel Smoothing”: Arial becomes too small on certain web pages. That is, on my 22” 1920x1200 <span class="caps">LCD</span> screen at work. Too bad. No subpixel smoothing at work for me.</p>
<p>Last week, with the release of Karmic Koala, I decided to revisit my subpixel smoothing choice again. I like it, so I found it was time to resolve my Arial 12px issue once and for all, so I could have my subpixel smoothing at work. So after the install finished, I switched to “Subpixel Smoothing” using the <tt class="docutils literal">System → Preferences → Appearance → Fonts</tt> tab. Ahh, very nice… Except for Arial when I start browsing. Actually its even only Arial at a size of 12px.</p>
<p>So here’s what I need to solve: I don’t want any other font to change, it’s really only Arial 12px that’s bugging me. Yes, I’m being a nitpicker here, but hey, there are just too many websites that use Arial 12px, starting with my iGoogle start page already. The easiest workaround option is to remove Microsoft’s TrueType core fonts package, so Arial isn’t used, but a replacement. However, most websites do look a lot better with Microsoft’s core web fonts, and besides that, I hate workarounds. I like real solutions. So that’s when I decided to dive into <a class="reference external" href="http://www.fontconfig.org/wiki/">fontconfig</a> to see if that could fix my problem.</p>
<p>I couldn’t imagine it being so simple as putting a <tt class="docutils literal">.fonts.conf</tt> in your home dir containing:</p>
<div class="highlight"><pre><span></span><span class="cp"><?xml version='1.0'?></span>
<span class="cp"><!DOCTYPE fontconfig SYSTEM 'fonts.dtd'></span>
<span class="nt"><fontconfig></span>
<span class="nt"><match</span> <span class="na">target=</span><span class="s">"font"</span><span class="nt">></span>
<span class="nt"><test</span> <span class="na">name=</span><span class="s">"family"</span> <span class="na">compare=</span><span class="s">"eq"</span><span class="nt">><string></span>Arial<span class="nt"></string></test></span>
<span class="nt"><test</span> <span class="na">name=</span><span class="s">"pixelsize"</span> <span class="na">compare=</span><span class="s">"eq"</span><span class="nt">><double></span>12<span class="nt"></double></test></span>
<span class="nt"><edit</span> <span class="na">name=</span><span class="s">"pixelsize"</span> <span class="na">mode=</span><span class="s">"assign"</span><span class="nt">><double></span>13<span class="nt"></double></edit></span>
<span class="nt"></match></span>
<span class="nt"></fontconfig></span>
</pre></div>
<p>But it really is as simple as that. In human language, the <span class="caps">XML</span> file tells fontconfig to set the pixelsize of Arial to 13 when any program requests Arial with pixelsize 12. How beautiful.</p>
Software Centered Organisation2009-09-28T11:04:00+02:002009-09-28T11:04:00+02:00Gertjan Zwartjestag:codemuse.co,2009-09-28:/2009/09/28/software-centered-organisation<p>I have always been fascinated with the link between software architecture and a company’s organizational structure. For the companies I have worked for so far, I found that the company’s structure can conflict with the software architecture that would work best. For example, a software development department might …</p><p>I have always been fascinated with the link between software architecture and a company’s organizational structure. For the companies I have worked for so far, I found that the company’s structure can conflict with the software architecture that would work best. For example, a software development department might be organized into separate teams, where each team is working on a separate part of the software. Usually, the software architecture clearly reflects the team structure: the software interfaces have grown to represent the borders between the parts where each team is working on. Suppose the product has evolved over the years, while the teams remained the same. At some point, the existing interfaces might become a major burden to implement new features. This seems to be a common problem, where the software design reflects the initial team structure, while the product is screaming for a new and more appropriate architecture reflecting the evolved product’s structure. As a result, team organization becomes detrimental for product progression.</p>
<p>This concept is known as <a class="reference external" href="http://www.melconway.com/law/index.html">Conway’s Law</a>, named after <a class="reference external" href="http://www.melconway.com">Mel Conway</a>, who published a paper called “How Do Committees Invent?”. Fred Brooks cited Conway’s paper in his classic “The Mythical Man Month”, and invented the name “Conway’s Law”. Here’s the definition from Conway’s own website (which also has the original paper in <a class="reference external" href="http://www.melconway.com/research/committees.html">full</a>):</p>
<blockquote>
Any organization that designs a system (defined more broadly here than just information systems) will inevitably produce a design whose structure is a copy of the organization’s communication structure.</blockquote>
<p>As Conway himself writes, “Brooks recognized that the law has important corollaries in management theory”. Here is one stated in the paper:</p>
<blockquote>
Because the design that occurs first is almost never the best possible, the prevailing system concept may need to change. Therefore, flexibility of organization is important to effective design.”</blockquote>
<p>For example, there are many cases, where you want to improve a product and there’s no other way than to redesign its architecture. According to Conway’s Law, that means you will need to start reconsidering your development team organization: it might have to become more software (product) centered.</p>
<p>As a corollary to Conway’s Law I would say: don’t hold on to existing organization structures, if they are in the way. In a software company, it’s the product that sells. So if you want to improve the product and go forward, you will need to be flexible and willing to change: the company and its product should evolve together.</p>
Exceptional Exception Handling2009-08-21T09:46:00+02:002009-08-21T09:46:00+02:00Gertjan Zwartjestag:codemuse.co,2009-08-21:/2009/08/21/exceptional-exception-handling<p><strong>Warning:</strong> this post is going to be technical; I’ll be using terms like C++, Python, <span class="caps">SWIG</span>, static and dynamic linking, shared objects, position independent code, and linux loader, so you can still bail out if all that sounds like gobbledygook to you. If not, well, I’ve been digging …</p><p><strong>Warning:</strong> this post is going to be technical; I’ll be using terms like C++, Python, <span class="caps">SWIG</span>, static and dynamic linking, shared objects, position independent code, and linux loader, so you can still bail out if all that sounds like gobbledygook to you. If not, well, I’ve been digging into a problem caused by a combination of all the previously mentioned terms. I’ll explain by example, so you can safely try this at home.</p>
<div class="section" id="simple-start">
<h2>Simple Start</h2>
<p>We’ll start by creating a C++ library. A very simple one; one function, throwing an exception derived from a generic library exception class. As follows:</p>
<div class="highlight"><pre><span></span><span class="c1">// lib.cpp</span>
<span class="cp">#include</span> <span class="cpf">"lib.h"</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">"exceptions.h"</span><span class="cp"></span>
<span class="kt">void</span> <span class="nf">throwDerivedException</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">throw</span> <span class="n">DerivedException</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
<p>Its header file is a one-liner:</p>
<div class="highlight"><pre><span></span><span class="c1">// lib.h</span>
<span class="k">extern</span> <span class="kt">void</span> <span class="nf">throwDerivedException</span><span class="p">();</span>
</pre></div>
<p>And the exception definitions are inside a single header file:</p>
<div class="highlight"><pre><span></span><span class="c1">// exceptions.h</span>
<span class="k">class</span> <span class="nc">LibraryException</span><span class="o">:</span> <span class="k">public</span> <span class="n">std</span><span class="o">::</span><span class="n">exception</span> <span class="p">{};</span>
<span class="k">class</span> <span class="nc">DerivedException</span><span class="o">:</span> <span class="k">public</span> <span class="n">LibraryException</span> <span class="p">{};</span>
</pre></div>
<p>So that’s that. As I’m a big fan of testing, I’ll create a unit test for my newly created library. We’re focusing on a single problem here, so I’ll just create the necessary tests to trigger the problem I’m investigating. The problem is in the exception <em>handling</em> part, so I’ll create a simple test to make sure that exceptions thrown by <tt class="docutils literal">throwDerivedException()</tt> can actually be caught. More specific, I want to check if my library generic <tt class="docutils literal">LibraryException</tt> can be used to catch unforeseen errors inside my library functions. This obviously is trivial:</p>
<div class="highlight"><pre><span></span><span class="c1">// test.cpp</span>
<span class="cp">#include</span> <span class="cpf">"lib.h"</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">"exceptions.h"</span><span class="cp"></span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="c1">// Exception handling check with statically compiled in symbols.</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"Testing exceptions, statically linked: "</span><span class="p">;</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">throwDerivedException</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">catch</span> <span class="p">(</span><span class="n">LibraryException</span> <span class="o">&</span><span class="n">e</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"ok</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>Compiling and running the above code will give results as expected:</p>
<pre class="literal-block">
$ g++ -c lib.cpp
$ g++ -c test.cpp
$ g++ -o test test.o lib.cpp
$ ./testTesting
exceptions, statically linked: ok
</pre>
<p>So far for C++ and statical linking, that leaves us still with a lot of remaining terms: Python, <span class="caps">SWIG</span>, dynamic linking, shared objects, position independent code, and linux loader. I’ll start using more of them very soon, so let’s continue.</p>
</div>
<div class="section" id="adding-complexity">
<h2>Adding Complexity</h2>
<p>A common way of supplying access to a library’s interface, besides its native (in our case C++) interface, is providing extensions for script languages. One of the best tools I’ve ever used to do that generically is <a class="reference external" href="http://www.swig.org"><span class="caps">SWIG</span></a>. With <span class="caps">SWIG</span> you can generate wrapper code to create an interface that you can compile, together with your C++ code, as a shared library that can be dynamically loaded by a script language. In today’s example I’m going to connect my library interface from <tt class="docutils literal">lib.h</tt> to Python. One particular interesting feature of <span class="caps">SWIG</span> is its language independent exception handling functionality. I’m going to use that to catch all exceptions that can be thrown by my library interface, identified by <tt class="docutils literal">LibraryException</tt>.</p>
<p>I won’t go into all of <span class="caps">SWIG</span>’s details here, you can browse through its excellent online documentation that can be found on <a class="reference external" href="http://www.swig.org">http://www.swig.org</a>. I’ll just list the contents of my interface file here:</p>
<div class="highlight"><pre><span></span><span class="nf">%module</span> <span class="n">lib</span>
<span class="o">%</span><span class="p">{</span>
<span class="cp">#include</span> <span class="cpf">"lib.h"</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">"exceptions.h"</span><span class="cp"></span>
<span class="o">%</span><span class="p">}</span>
<span class="cm">/* Generic language independent exception handler. */</span>
<span class="nf">%include</span> <span class="s">"exception.i"</span>
<span class="nf">%exception</span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">$action</span>
<span class="p">}</span>
<span class="k">catch</span> <span class="p">(</span><span class="n">LibraryException</span> <span class="o">&</span><span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="n">SWIG_exception</span><span class="p">(</span><span class="n">SWIG_RuntimeError</span><span class="p">,</span> <span class="n">e</span><span class="p">.</span><span class="n">what</span><span class="p">());</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nf">%include</span> <span class="s">"lib.h"</span>
</pre></div>
<p>Running <span class="caps">SWIG</span> on this interface file will generate a so called interface wrapper file, that contains the actual wrapper code to bind the C++ interface to a Python callable interface. In there the <tt class="docutils literal">$action</tt> placeholder will be translated to a call to <tt class="docutils literal">throwDerivedException()</tt> function for the respective Python wrapper function. In turn, a Python understandable <tt class="docutils literal">RuntimeError</tt> will be raised.</p>
<p>All this is best illustrated with a simple Python test script to test the exception functionality, like we did for the C++ interface above:</p>
<div class="highlight"><pre><span></span><span class="c1"># test.py</span>
<span class="k">print</span> <span class="s2">"Testing exceptions, dynamically loaded with Python:"</span><span class="p">,</span>
<span class="c1"># Import SWIG created library.</span>
<span class="kn">import</span> <span class="nn">lib</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">lib</span><span class="o">.</span><span class="n">throwDerivedException</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">RuntimeError</span><span class="p">:</span>
<span class="k">print</span> <span class="s2">"ok"</span>
</pre></div>
<p>Compiling and running the above test gives results as expected:</p>
<pre class="literal-block">
$ swig -c++ -python -o lib_wrap.cpp lib.i
$ g++ -fPIC -c lib.cpp
$ g++ -fPIC -c -I/usr/include/python2.5 lib_wrap.cpp
$ g++ -fPIC -shared -o _lib.so lib_wrap.o lib.o
$ python test.py
Testing exceptions, dynamically loaded with Python: ok
</pre>
<p>Note that I now pass the <tt class="docutils literal"><span class="pre">-fPIC</span></tt> flag to gcc to emit position-independent code, suitable for dynamic linking.</p>
</div>
<div class="section" id="so-where-s-the-problem">
<h2>So Where’s the Problem?</h2>
<p>Everything fine so far, however, I’d like to combine both tests into one test executable, since running multiple tests manually is too cumbersome for me. Luckily there’s a function in the Python/C <span class="caps">API</span> called <tt class="docutils literal">PyRun_SimpleFile</tt> to execute a Python script from within a C or C++ program. Including <tt class="docutils literal">Python.h</tt>, linking with <tt class="docutils literal">libpython</tt>, and calling <tt class="docutils literal">Py_Initialize()</tt> is all there is to it. Let’s extend the C++ test program:</p>
<div class="highlight"><pre><span></span><span class="c1">// test.cpp</span>
<span class="cp">#include</span> <span class="cpf">"lib.h"</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">"exceptions.h"</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">"Python.h"</span><span class="cp"></span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="c1">// Exception handling check with statically compiled in symbols.</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"Testing exceptions, statically linked: "</span><span class="p">;</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">throwDerivedException</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">catch</span> <span class="p">(</span><span class="n">LibraryException</span> <span class="o">&</span><span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"ok</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Embedded Python interpreter exception handling check -- this</span>
<span class="c1">// will fail if test executable is statically linked.</span>
<span class="n">Py_Initialize</span><span class="p">();</span>
<span class="kt">int</span> <span class="n">result</span> <span class="o">=</span> <span class="n">PyRun_SimpleFile</span><span class="p">(</span><span class="n">fopen</span><span class="p">(</span><span class="s">"test.py"</span><span class="p">,</span> <span class="s">"r"</span><span class="p">),</span> <span class="s">"test.py"</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>For the test to run successfully, we need to add three lines before importing the generated library in the test script, otherwise it won’t be found:</p>
<div class="highlight"><pre><span></span><span class="o">...</span>
<span class="c1"># Add current dir to system path, that's where our lib is.</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"."</span><span class="p">)</span>
<span class="c1"># Import SWIG created library.</span>
<span class="kn">import</span> <span class="nn">lib</span>
<span class="o">...</span>
</pre></div>
<p>So let’s compile this and run the test again:</p>
<pre class="literal-block">
$ swig -c++ -python -o lib_wrap.cpp lib.i
$ g++ -c -fPIC lib.cpp$ g++ -c -fPIC -I/usr/include/python2.5 test.cpp
$ g++ -c -fPIC -I/usr/include/python2.5 lib_wrap.cpp
$ g++ -fPIC -shared -o _lib.so lib_wrap.o lib.o
$ g++ -fPIC -o test test.o lib.o -lpython2.5
$ ./test
Testing exceptions, statically linked: ok
Testing exceptions, dynamically loaded with dlopen with Python:
terminate called after throwing an instance of 'DerivedException'
what(): std::exception
Aborted
</pre>
<p>That’s not what we’d expected. The exception thrown inside the library is not caught by the exception handler code installed by <span class="caps">SWIG</span>. How could that happen?</p>
</div>
<div class="section" id="the-problem-explained">
<h2>The Problem Explained</h2>
<p>After stripping down the actual problem into the simple test example as described, spending a few intense hours in a Googling-reading-Googling-reading loop, and interrogating a compiler guru colleague <a class="footnote-reference" href="#id2" id="id1">[1]</a>, I could conclude that I found an incarnation of the problem of <span class="caps">RTTI</span> crossing shared library boundaries. It’s actually a combination of how gcc does comparisons on the type of C++ objects and how symbols in dynamically shared libraries are resolved.</p>
<p>The entry “dynamic_cast, throw, typeid don’t work with shared libraries” in the <a class="reference external" href="http://gcc.gnu.org/faq.html#dso"><span class="caps">GNU</span> <span class="caps">GCC</span> <span class="caps">FAQ</span></a> explains the first half of the problem:</p>
<blockquote>
The new C++ <span class="caps">ABI</span> in the <span class="caps">GCC</span> 3.0 series uses address comparisons, rather than string compares, to determine type equality.</blockquote>
<p>But also it describes the root cause of the other half of the problem:</p>
<blockquote>
Like other objects that have to be present in the final executable, these <tt class="docutils literal"><span class="pre">std::type_info</span></tt> objects have what is called vague linkage because they are not tightly bound to any one particular translation unit (object file). The compiler has to emit them in any translation unit that requires their presence, and then rely on the linking and loading process to make sure that only one of them is active in the final executable. With static linking all of these symbols are resolved at link time, but with dynamic linking, further resolution occurs at load time. You have to ensure that objects within a shared library are resolved against objects in the executable and other shared libraries.</blockquote>
<p>So what happens in our example? First, the executable is read by the loader, including the exception symbols <tt class="docutils literal">LibraryException</tt> and <tt class="docutils literal">DerivedException</tt>. The C++ interface test is executed, giving the expected results. The Python test will be run, with the embedded Python interpreter. While interpreting the Python test script, the <tt class="docutils literal">_lib.so</tt> library will be loaded. At load time of the library the types inside catch statements are resolved using <em>the symbols in memory of the test
executable</em>. In the execution path the <tt class="docutils literal">throwDerivedException()</tt> function will be called. At that moment, at run time, the exception instance types will be resolved, using <em>the local symbols of the library</em>. The exception object that is thrown will have a pointer pointing to the address of the LibraryException type inside the library memory space, while the catch statement inside the wrapper code will check using the address of the LibraryException type from inside the test executable memory space: <em>they won’t match</em>. Hence the exception won’t be caught; program execution aborts.</p>
<p>If you don’t believe me, you can see for yourself. Here’s a <a class="reference external" href="https://codemuse.co/public/cross_library_rtti.tar.gz">link</a> to an archive containing the sample code as discussed. It contains a Makefile too, so just type:</p>
<pre class="literal-block">
$ make
$ ./test
</pre>
<p>And there you go. By means of the included Makefile, the archive also contains the three different solutions which I’ll discuss next.</p>
</div>
<div class="section" id="it-s-all-in-the-options">
<h2>It’s All in the Options</h2>
<p>Sometimes a problem that seems to be very complicated in the first place — taking a significant investigation to get to the bottom of it — can have a relatively simple solution. In this particular situation we even have three trivial solutions. As if we have won the lottery.</p>
<p>What we need to do is somehow to instruct the compiler, the linker, or the loader to use the right symbols to resolve the exception types. In other words, we need to make sure that resolving the exception types is not being messed up by either the linker or the loader. We can accomplish that by:</p>
<ol class="arabic simple">
<li>Using shared libraries — if we compile <tt class="docutils literal">lib.cpp</tt> as a shared library say <tt class="docutils literal">liblib.so</tt>, the test executable will not contain exception type symbols. The exception symbols inside <tt class="docutils literal">liblib.so</tt> will remain local and while <tt class="docutils literal">_lib.so</tt> is loaded by Python the exception symbols in there will be resolved locally too.</li>
<li>Exporting symbols to the dynamic symbol table — by exporting all symbols from the test executable to the dynamic symbol table, not only the type of the exception in the catch statement, but also the type of the exception in the throw statement will be resolved inside the executable memory space. The <span class="caps">GNU</span> linker has a special option for this purpose: <tt class="docutils literal"><span class="pre">-E</span></tt>, which, according to the <a class="reference external" href="http://sourceware.org/binutils/docs/ld/Options.html#Options"><span class="caps">GNU</span> ld manual</a>, “when creating a dynamically linked executable, add[s] all symbols to the dynamic symbol table. The dynamic symbol table is the set of symbols which are visible from dynamic objects at run time. If you do not use this option, the dynamic symbol table will normally contain only those symbols which are referenced by some dynamic object mentioned in the link. If you use dlopen to load a dynamic object which needs to refer back to the symbols defined by the program, rather than some other dynamic object, then you will probably need to use this option when linking the program itself.”</li>
<li>Binding references to global symbols to the definition within the shared library — using the <tt class="docutils literal"><span class="pre">-Bsymbolic</span></tt> option from the <span class="caps">GNU</span> linker. If we link the <tt class="docutils literal">_lib.so</tt> Python extension with this option, the exception type inside the catch statement will be resolved already to the local symbols inside the library by the linker at link time. When the library is loaded dynamically by Python in the test run, no symbols will be overridden with symbols from the test executable. I chose this third solution as my solution of choice, because it solves the problem inside the Python extension library. As a result, the Python extension becomes fully self contained, which in the particular case I was working on was exactly what I wanted.</li>
</ol>
<p>These solutions can be tried out using the archive as <a class="reference external" href="https://codemuse.co/public/cross_library_rtti.tar.gz">linked</a> before. The <tt class="docutils literal">Makefile</tt> has, besides the test target, three additional targets:</p>
<pre class="literal-block">
$ make test_shared
$ make test_export
$ make test_symbolic
</pre>
<p>that build a differently linked test executable, according to the above described solutions.</p>
<p>Enough compiler-and-linker-fun for me for this week…</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>A colleague who worked on the Watcom and Microsoft C++ compilers.</td></tr>
</tbody>
</table>
</div>
Multi-Monitor Window Lists2009-07-27T12:53:00+02:002009-07-27T12:53:00+02:00Gertjan Zwartjestag:codemuse.co,2009-07-27:/2009/07/27/multi-monitor-window-lists<p>If you are spoiled with a multiple monitor setup, and using Ubuntu, like me, you might be wondering whether it is possible to not have all your windows from your different monitors in one taskbar. The solution is easy: create a new panel by right clicking on an existing panel …</p><p>If you are spoiled with a multiple monitor setup, and using Ubuntu, like me, you might be wondering whether it is possible to not have all your windows from your different monitors in one taskbar. The solution is easy: create a new panel by right clicking on an existing panel and choosing <tt class="docutils literal">New Panel</tt>. Drag this panel to (one of) your additional monitor(s) — use the alt key to start dragging. Finally right click your new panel and choose <tt class="docutils literal">Add to <span class="pre">Panel...</span></tt>, and select the <tt class="docutils literal">Window
List</tt> item. That’s it; the newly added window list will only have buttons for those windows on that monitor where its parent panel is on.</p>
<p>Multi-monitor window lists are a feature of Gnome, so the steps mentioned earlier are not limited to Ubuntu.</p>
Breakthrough?2009-07-20T11:10:00+02:002009-07-20T11:10:00+02:00Gertjan Zwartjestag:codemuse.co,2009-07-20:/2009/07/20/breakthrough<p>A very interesting contemporary (yet also for many a controversial) viewpoint about software engineering from an acknowledged software industry expert: <a class="reference external" href="http://www2.computer.org/cms/Computer.org/ComputingNow/homepage/2009/0709/rW_SO_Viewpoints.pdf">Software Engineering: An Idea Whose Time Has Come and Gone</a>.</p>
<p>A very interesting contemporary (yet also for many a controversial) viewpoint about software engineering from an acknowledged software industry expert: <a class="reference external" href="http://www2.computer.org/cms/Computer.org/ComputingNow/homepage/2009/0709/rW_SO_Viewpoints.pdf">Software Engineering: An Idea Whose Time Has Come and Gone</a>.</p>
Ubuntu Jaunty: How to Change Gnome Keyring Password2009-07-15T09:24:00+02:002009-07-15T09:24:00+02:00Gertjan Zwartjestag:codemuse.co,2009-07-15:/2009/07/15/ubuntu-jaunty-how-to-change-gnome-keyring-password<p>After I’d changed the password of my user account on my laptop’s Ubuntu install, Evolution kept on bothering me asking the password to unlock the keyring:</p>
<img alt="Gnome unlock keyring dialog" src="https://codemuse.co/images/ubuntu/screenshot-unlock-keyring.png" />
<p>To unlock it, it required me to input my old password. Funny enough, if you change your user password, Ubuntu doesn’t …</p><p>After I’d changed the password of my user account on my laptop’s Ubuntu install, Evolution kept on bothering me asking the password to unlock the keyring:</p>
<img alt="Gnome unlock keyring dialog" src="https://codemuse.co/images/ubuntu/screenshot-unlock-keyring.png" />
<p>To unlock it, it required me to input my old password. Funny enough, if you change your user password, Ubuntu doesn’t change the keyring master password. After Googling around a bit, there are several blog and forum posts that point to ways of changing the keyring’s master password using seahorse, for example <a class="reference external" href="http://mexpolk.blogspot.com/2008/02/ubuntu-change-default-keyring-password.html">this one</a>. However, all information and screenshots I found seem to be outdated; I was unable to find the “Gnome Keyring” tab everyone is talking about. After playing around with my version of seahorse, I was able to find out where this option has been moved. I don’t know in which version of seahorse this has changed, but what I do know is that that version of seahorse with its new password change interface is included in Jaunty Jackalope.</p>
<p>So for those of you who are reading this to figure out how to change your keyring password with Ubuntu 9.04, here goes: open seahorse via <tt class="docutils literal">Applications → Accessories → Passwords and Encryption Keys</tt>. Click on the <tt class="docutils literal">Passwords</tt> tab, and now you need the secret trick: <em>right</em>-click on the <tt class="docutils literal">Passwords: login</tt> item and choose <tt class="docutils literal">Change Password</tt>:</p>
<img alt="Seahorse passwords and encryption keys interface" src="https://codemuse.co/images/ubuntu/screenshot-passwords-and-encryption-keys.png" />
<p>If you change the password for the login passwords set to the same password as your user account, Gnome will automatically unlock your keyring during login. Yay!</p>
Floating Point Trickyness (2) —- select Is’t Broken, Is It?2009-05-14T08:47:00+02:002009-05-14T08:47:00+02:00Gertjan Zwartjestag:codemuse.co,2009-05-14:/2009/05/14/floating-point-trickyness-2-select-ist-broken-is-it<p>In my <a class="reference external" href="https://codemuse.co/2009/03/11/floating-point-trickyness">previous post</a> I talked about rounding errors with floating point numbers. If you work with real numbers and computers, sooner or later, just like others before you, you will conclude that <a class="reference external" href="http://www.codinghorror.com/blog/archives/001266.html">computers suck at math</a>.</p>
<p>But what if you have a compiler that sucks at math? I recently …</p><p>In my <a class="reference external" href="https://codemuse.co/2009/03/11/floating-point-trickyness">previous post</a> I talked about rounding errors with floating point numbers. If you work with real numbers and computers, sooner or later, just like others before you, you will conclude that <a class="reference external" href="http://www.codinghorror.com/blog/archives/001266.html">computers suck at math</a>.</p>
<p>But what if you have a compiler that sucks at math? I recently experienced that that can give you severe headaches. Consider the following code snipplet:</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf"><cmath></span><span class="cp"></span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">argv</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">double</span> <span class="n">x</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">sqrt</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">-</span> <span class="n">std</span><span class="o">::</span><span class="n">pow</span><span class="p">(</span><span class="mf">2.0</span><span class="p">,</span> <span class="mi">2</span><span class="p">));</span>
<span class="p">}</span>
</pre></div>
<p>Taking the square root from -3, should be NaN, and if you try this with a recent version of g++, you will get NaN. Everything fine. However, if you try this with g++ 3.4.3 on Sparc, with <tt class="docutils literal"><span class="pre">-O2</span></tt> turned on, the answer is, well, actually, there is no answer. At least not after 12 hours; our test that includes the same formula as in the above code snipplet ran for more than 12 hours without terminating. That’s how I found this problem. From an infinitely looping test.</p>
<p>It took a while to figure out what was going on since the original problem line was of course bigger including several more mathematical expressions. After breaking it down I could isolate the problem to the simplified expression as shown above.</p>
<p>Even in the strangest cases, usually still <em>“select Isn’t Broken”</em> <a class="footnote-reference" href="#id2" id="id1">[1]</a>. But in this (very rare) case it is.</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>“It is rare to find a bug in the <span class="caps">OS</span> or the compiler, or even a third-party product or library. The bug is most likely in the application.” —- From the <a class="reference external" href="http://www.pragprog.com/the-pragmatic-programmer">Pragmatic Programmer</a>, one of the most influential programming books I read.</td></tr>
</tbody>
</table>
Floating Point Trickyness2009-03-11T09:50:00+01:002009-03-11T09:50:00+01:00Gertjan Zwartjestag:codemuse.co,2009-03-11:/2009/03/11/floating-point-trickyness<p>Interesting: say you have a 100x100 matrix of doubles. Then you put values in each row from -1 to 1, equally spaced, such that all 100 rows for each column i contain the value:</p>
<blockquote>
-1 + i * ((1 - -1) / (100 - 1)) == -1 + i * 2/99</blockquote>
<p>Where the columns are numbered from …</p><p>Interesting: say you have a 100x100 matrix of doubles. Then you put values in each row from -1 to 1, equally spaced, such that all 100 rows for each column i contain the value:</p>
<blockquote>
-1 + i * ((1 - -1) / (100 - 1)) == -1 + i * 2/99</blockquote>
<p>Where the columns are numbered from 0 to 99. By definition, the sum of all elements in this matrix should be 0. For integer numbers, this is true. For floating point numbers, this is tricky.</p>
<p>As a natural born hax0r, you should know that there is something called floating point errors. As the entropy of these values isn’t particularly high, operations on them might result in an error that will be large. But I never thought it could be <em>that</em> different. Watch this <a class="footnote-reference" href="#id2" id="id1">[1]</a>:</p>
<ul class="simple">
<li>Summing all elements individually gives a result of: 3.108624468950438e-15. A large error, this is what we would expect.</li>
</ul>
<p>However:</p>
<ul class="simple">
<li>Taking the sum of an individual row (doesn’t matter which one, of course) results in: 3.108624468950438e-15. The same number as summing all elements individually!</li>
<li>Taking the sum of these rows gives: 3.108624468950438e-13. This is what we would expect, 100 times the sum of a row. The funny thing of course, is the fact that this number is a 100 times different from the sum of all elements.</li>
<li>Taking the sum of the columns gives: -2.415845301584341e-13. A completely different number than in the previous cases.</li>
</ul>
<p>This issue surfaced in a debugging session where we were comparing the result of an algorithm written in Matlab and the same algorithm converted to C++. Although I have a copy of <a class="reference external" href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.102.244">“What Every Computer Scientist Should Know About Floating Point Arithmetic”</a>, which tells you that the addition operator + is not necessarily associative for floating point values, I still had to blink a couple of times when I saw the above results for the first time.</p>
<p>Lesson learned: be careful when you take the sum of (a matrix of) floating point numbers as a comparison measure —- or maybe even more general: beware: floating point number calculations ahead.</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>You can try this at home either with Matlab or C++, also probably other languages or tools will give similar amazingly unexpected results))</td></tr>
</tbody>
</table>
Background Pictures2009-02-27T09:21:00+01:002009-02-27T09:21:00+01:00Gertjan Zwartjestag:codemuse.co,2009-02-27:/2009/02/27/background-pictures<p>Now for something completely different…</p>
<p>As many other programmers, so it seems, I like photography too. A few months ago I had a dinner with an bunch of ex-colleagues and friends, from which one of them, Rick van Bijnen, is a brilliant photographer, you can check out his best pictures …</p><p>Now for something completely different…</p>
<p>As many other programmers, so it seems, I like photography too. A few months ago I had a dinner with an bunch of ex-colleagues and friends, from which one of them, Rick van Bijnen, is a brilliant photographer, you can check out his best pictures on his <a class="reference external" href="http://www.rickvanbijnen.nl">website</a>. I promised him to put up some pictures of my own on the net as well — better late than never — so here goes.</p>
<p>Sometimes in between all of the pictures I take, a desktop background jumps out. So that’s my selection for today (click on an image to download the full size 3008x2000 original): <a class="footnote-reference" href="#id2" id="id1">[1]</a></p>
<a class="reference external image-reference" href="https://codemuse.co/images/backgrounds/flower1.jpg"><img alt="Flower" src="https://codemuse.co/images/backgrounds/flower1-thumb.jpg" /></a>
<a class="reference external image-reference" href="https://codemuse.co/images/backgrounds/flower2.jpg"><img alt="Flower" src="https://codemuse.co/images/backgrounds/flower2-thumb.jpg" /></a>
<a class="reference external image-reference" href="https://codemuse.co/images/backgrounds/flower3.jpg"><img alt="Flower" src="https://codemuse.co/images/backgrounds/flower3-thumb.jpg" /></a>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>Images licensed under a <a class="reference external" href="http://creativecommons.org/licenses/by-nc/3.0/deed.en_US">Creative Commons Attribution-NonCommercial 3.0 Unported License</a>.</td></tr>
</tbody>
</table>
Coders Unite2009-01-26T16:39:00+01:002009-01-26T16:39:00+01:00Gertjan Zwartjestag:codemuse.co,2009-01-26:/2009/01/26/coders-unite<p>Reading Jeff Atwoods <a class="reference external" href="http://www.codinghorror.com/blog/archives/001216.html">latest blog entry</a>, inspired me to kick of again <a class="footnote-reference" href="#id2" id="id1">[1]</a> with a rant. I usually agree with Jeff’s statements, and this time I too do agree that scripting languages are a positive development in language evolution. They opened up many opportunities and make life a whole …</p><p>Reading Jeff Atwoods <a class="reference external" href="http://www.codinghorror.com/blog/archives/001216.html">latest blog entry</a>, inspired me to kick of again <a class="footnote-reference" href="#id2" id="id1">[1]</a> with a rant. I usually agree with Jeff’s statements, and this time I too do agree that scripting languages are a positive development in language evolution. They opened up many opportunities and make life a whole lot simpler with respect to mundane aspects of “real programming” like memory management, edit and compile cycles, and so on. But I cannot disagree more with the rest of what he is saying.</p>
<p>To summarize, he basically says that you have “real programmers” and scripters:</p>
<blockquote>
<p>I remember that evening only vaguely […] Tonight, <em>I become a real programmer</em>. And so I began.</p>
<p>What happened next was <em>the eight unhappiest hours of my computing life</em>. Between the painfully slow compile cycles and the torturous, unforgiving dance of pointers and memory allocation, I was almost ready to give up programming altogether. C wasn’t for me, certainly. But I couldn’t shake the nagging feeling that there was something altogether <em>wrong</em> with this type of programming. How could C suck all the carefree joy out of my stupid little AmigaBASIC adventures? This language took what I had known as programming and contorted it beyond recognition, into something stark and cruel.</p>
<p>I didn’t know it then, but I sure do now. <em>I hadn’t been programming at all. I had been scripting.</em></p>
<p>I don’t think my revulsion for C is something I need to apologize for. In fact, I think it’s the other way around. I’ve just been waiting for the rest of the world to catch up to what I always knew.</p>
</blockquote>
<p>Yes, scripting languages are certainly different from the conventional compiled languages. But that does not say anything about the person writing the code: <em>scripters are real programmers too.</em> They are, and can be much lazier than “real programmers”. Which is a compliment: programmers <a class="reference external" href="http://www.codinghorror.com/blog/archives/000373.html">should be lazy</a>:</p>
<blockquote>
Only a lazy programmer will avoid writing monotonous, repetitive code. The tools and processes inspired by laziness speed up production.</blockquote>
<p>Scripting langauges are such tools. But also for writing great programs in scripting languages you will need to have “real programming” knowledge.</p>
<p>You’ll write shit-script-code if you don’t know about data encapsulation: you won’t make use of powerful things like object oriented features of language like Perl or Python. Not only in C, but in scripting languages too you can introduce deadlocks and race-conditions when you are running your code in multiple threads or processes. You will face the same problems maintaining hundreds of thousands lines of script language code as with the same amounts of “real programming” language code.</p>
<p><strong>I believe it is wrong and harmful to divide coders into two camps</strong>: the scripters and the real programmers. Whether you are programming C, C++, Python, <span class="caps">PHP</span>, Java, C#, Visual Basic, Javascript, Erlang, <span class="caps">ADA</span>, D, x86 Assembly, Tangram, Delphi, or whatever programming language of your choice: <strong>we all face the same challenges, so let’s face them together</strong>.</p>
<p>Near the end of <em>A Scripter at Heart</em>, Jeff concludes:</p>
<blockquote>
Every language has its place, and every programmer should choose the language that best fits their skillset and the task at hand.</blockquote>
<p>I agree partly: every programmer should choose the language that best fits the task at hand. If there are multiple options that are equally well fitted for the task, then choose the one that best fits your skillset. None of these languages in your skillset? Then learn a new one, or pass on the task.</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>After changing houses; I’m (practically) done moving from Utrecht to ‘s-Hertogenbosch. Yes, I will need to update the background title picture, since that one was taken in Utrecht.</td></tr>
</tbody>
</table>
Software Nightmares2008-11-10T09:00:00+01:002008-11-10T09:00:00+01:00Gertjan Zwartjestag:codemuse.co,2008-11-10:/2008/11/10/software-nightmares<p>I <a class="reference external" href="https://codemuse.co/2008/11/04/a-means-to-an-end-festschrift">promised</a> to write about the analogy between running a restaurant and running a software project, which is my conclusion in my contribution to Derrick G. Kourie’s festschrift. So here goes.</p>
<p>I am a frequent watcher of the show called “Ramsay’s Kitchen Nightmares”, where Gordon Ramsay helps failing …</p><p>I <a class="reference external" href="https://codemuse.co/2008/11/04/a-means-to-an-end-festschrift">promised</a> to write about the analogy between running a restaurant and running a software project, which is my conclusion in my contribution to Derrick G. Kourie’s festschrift. So here goes.</p>
<p>I am a frequent watcher of the show called “Ramsay’s Kitchen Nightmares”, where Gordon Ramsay helps failing restaurants to get back on the map. You either love him or hate him, but I must admit that I’m a big a fan.</p>
<p>In each episode of Kitchen Nightmares, Ramsay takes kind of the same approach. He enters a restaurant and starts with an investigation to see what’s wrong. As you would expect, the first thing he does is to order a few dishes from the menu to check out the quality of the food — and thus the chef. After that he will inspect the kitchen and he checks out the staff. He then tries to turn those things around that seem to be the bottlenecks for the restaurant to be successful — in his own style: unabashed to tell the truth, wearing his heart on his sleeve, and using the f-word multiple times in almost every sentence.</p>
<p>If you listen carefully, you will notice that in between all the swearing, he actually knows what he is doing and that he is genuinely committed to help improve an establishment. His power lies in three things: 1) He is an outsider, he can take a step back and investigate things from a distance. 2) He wears his heart on his sleeve and he has the courage to tell the truth even if it might hurt somebody. 3) He keeps things simple — this way he can achieve higher quality and customers will be happier. On top of that, he employs his strengths to achieve but one crystal clear goal: getting clientèle and give them the best possible evening that will make them return or bring in more guests.</p>
<p>Back to the software world, where we’ve got our own “Software Nightmares” so to say. Unfortunately software development isn’t sexy enough for television, however, I believe a passionate person like Gordon Ramsay, with that kind of drive, could be successful in the software world too. I know nobody will watch “Software Nightmares” for fun, but I do hope we have enough of our own Gordon Ramsay’s in our field out there to turn around failing software projects.</p>
A Means to an End (Festschrift)2008-11-04T11:49:00+01:002008-11-04T11:49:00+01:00Gertjan Zwartjestag:codemuse.co,2008-11-04:/2008/11/04/a-means-to-an-end-festschrift<p>This summer I was very honored to be asked to write an article for a so called <a class="reference external" href="http://en.wikipedia.org/wiki/Festschrift">festschrift</a>, dedicated to the 60th Birthday of Derrick G. Kourie. Unfortunately, I couldn’t attend the celebration of his birthday in person, but it was a big pleasure for me to be able …</p><p>This summer I was very honored to be asked to write an article for a so called <a class="reference external" href="http://en.wikipedia.org/wiki/Festschrift">festschrift</a>, dedicated to the 60th Birthday of Derrick G. Kourie. Unfortunately, I couldn’t attend the celebration of his birthday in person, but it was a big pleasure for me to be able to congratulate him in this original manner. We got acquainted during my graduation project, and ever since it has been a pleasure exchanging thoughts and interesting ideas about software engineering.</p>
<p>A special <a class="reference external" href="http://www.cs.up.ac.za/cs/sgruner/Festschrift/">website</a> has been set up that contains each of the articles that make up the complete festschrift, including <a class="reference external" href="http://www.cs.up.ac.za/cs/sgruner/Festschrift/paper03.pdf">the one I wrote</a>. After I held a presentation at a workshop, we had a discussion about advances in software engineering, and that these improvements can have a downside too. In the festschrift article I elaborate on the hypothesis that the worst thing that can happen is that <em>a means is being promoted to an end</em>.</p>
<p>I won’t copy the whole article in verbatim as a blog post, just <a class="reference external" href="http://www.cs.up.ac.za/cs/sgruner/Festschrift/paper03.pdf">download</a> the article to read the entire text. Except for the analogy I make between running a restaurant and running a software project, which deserves a post on its own. To be continued…</p>
The One Thing Every Software Development Manager Should Know2008-10-30T09:20:00+01:002008-10-30T09:20:00+01:00Gertjan Zwartjestag:codemuse.co,2008-10-30:/2008/10/30/the-one-thing-every-software-development-manager-should-know<p>In light of Jeff Atwood’s <a class="reference external" href="http://www.codinghorror.com/blog/archives/001177.html">recent post</a> on the one thing every software developer should know, I immediately had to think about the one thing I believe every manager involved in software development project should now. Namely the law of the <em>Four Variables in Software Development</em>.</p>
<p>Now before I …</p><p>In light of Jeff Atwood’s <a class="reference external" href="http://www.codinghorror.com/blog/archives/001177.html">recent post</a> on the one thing every software developer should know, I immediately had to think about the one thing I believe every manager involved in software development project should now. Namely the law of the <em>Four Variables in Software Development</em>.</p>
<p>Now before I’m going into the details, first I will shortly break one of the <a class="reference external" href="http://www.codinghorror.com/blog/archives/000834.html">cliches of blogging</a>: “don’t apologize for not writing for a certain time”. Well, actually, I won’t apologize, but I do have my reasons for not posting in the last couple of months. I did write about my job change before code-muse went black for a while. Almost all my time got sucked up by working for my new employer. I traveled to California for training sessions and getting to meet my colleagues overseas, and besides that, my daily commute time increased significantly compared to my previous job. For that same reason, I’ll be moving this December. You can already guess that finding a new house took a bigger part of my free time as well. Fortunately, everything is slowly rolling into the right direction now, and I finally had some time to not only start reading my favorite blogs again, but also start writing again.</p>
<p>Back to that one thing that every manager that is controlling something software development related should be aware of. Namely, there are four important variables in software development: Functionality, Quality, Time and Resources. Now here’s what you should stick in your head forever: you cannot control all of these variables simultaneously. So whenever you hear yourself saying: “I want this functionality with these resources, at this level of quality, and I want it done by the end of…”, stop at that instant and write down “I cannot control all the four variables functionality, quality, resources and time at the same time!” a 100 times. And the next time your punishment will be bumped to a 1000. When you end up writing that same sentence for over a million times, maybe you should start thinking about a career move.</p>
<p>A clear, concise and detailed description of the four variables I found in a <a class="reference external" href="http://richardblouin.com/fourvariables.pdf">paper</a> written by Richard Blouin. The article cleanly describes the aspects of fixed and free variables in different circumstances. In practice, I believe almost all programmers who have participated in a smaller or bigger (business) software development project know that however being fixed, in the end, one of the four variables will always end up being a <em>free</em> variable. In my past experience I have seen that quality is sacrificed in many cases. But also time is a popular variable to end up being free. The worst cases are those where the release date is fixed — and one is supposed to believe that time is thus fixed — while time remains a free variable, in the sense of the amount of time spent on development. This usually has the side effect of quality dropping at the same rate as time is increasing.</p>
<p>More than once I have come across the following quote, which I think is the most earthy way to describe this concept: ((I do not know the source, and to be honest, I am too lazy to research who said or wrote it for the first time.))</p>
<blockquote>
<p>You can either have it <a class="footnote-reference" href="#id2" id="id1">[1]</a>:</p>
<ol class="arabic simple">
<li>Good</li>
<li>Fast</li>
<li>Cheap</li>
</ol>
<p>Pick two.</p>
</blockquote>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>Note that this particular quote assumes that functionality is fixed.</td></tr>
</tbody>
</table>
Optimization Quote of the Day2008-07-25T09:22:00+02:002008-07-25T09:22:00+02:00Gertjan Zwartjestag:codemuse.co,2008-07-25:/2008/07/25/optimization-quote-of-the-day<p>Optimization gone awry: “optimizing to save one or two clock cycles on a quadratic implementation of an algorithm that is known to have a linear solution.” Coined in a discussion about optimization freaks, by my respected colleague Wouter Bijlsma.</p>
<p>Optimization gone awry: “optimizing to save one or two clock cycles on a quadratic implementation of an algorithm that is known to have a linear solution.” Coined in a discussion about optimization freaks, by my respected colleague Wouter Bijlsma.</p>
Scaling Challenges2008-07-23T09:48:00+02:002008-07-23T09:48:00+02:00Gertjan Zwartjestag:codemuse.co,2008-07-23:/2008/07/23/scaling-challenges<p>After working at two smaller companies, I’ve moved on. This week I have started working for <a class="reference external" href="http://www.asml.com"><span class="caps">ASML</span></a>, and, as a result, the total number of colleagues I now have has bumped up from around 50 to more than 6000. Yes, that means my professional working environment has radically changed …</p><p>After working at two smaller companies, I’ve moved on. This week I have started working for <a class="reference external" href="http://www.asml.com"><span class="caps">ASML</span></a>, and, as a result, the total number of colleagues I now have has bumped up from around 50 to more than 6000. Yes, that means my professional working environment has radically changed, well, at least if you look at the numbers.</p>
<p>On Monday, my first day in Veldhoven, and yesterday we started with a lot of introduction and education about the company’s core business. We haven’t even touched the surface of the actual software engineering that’s going on, but I know we will get there soon. However, I couldn’t keep myself from wondering about the challenges I will be facing.</p>
<p>Most of all, what is intriguing me is the question whether the challenges and problems, but also the things that do go smoothly scale or not. What I mean by <em>scale</em> is whether some problem will have a much bigger impact in a large company than that same problem in a smaller company. The same for smoothing something out; does that have a bigger impact in a bigger company too? On the other hand, maybe larger companies are simply facing completely different challenges than smaller ones. I can’t say from experience, because I never worked at large high-tech businesses (with 1000+ employees). But I do have the feeling that it is not much different: possibly challenges don’t scale. And size doesn’t matter</p>
<p>I might be able to answer these questions in the coming weeks, months or years, but one thing is for sure, I’m up for interesting times.</p>
Performance: Perception or Deception2008-05-26T13:20:00+02:002008-05-26T13:20:00+02:00Gertjan Zwartjestag:codemuse.co,2008-05-26:/2008/05/26/performance-perception-or-deception<p>A while ago, Jeff Atwood talked about <a class="reference external" href="http://www.codinghorror.com/blog/archives/001058.html">actual performance and perceived performance</a>, and funny enough, just after reading his post, I stumbled upon a similar deception of a performance indicator. It is really unbelievable how deceiving performance numbers can be, which seems to be a result of the bad sense …</p><p>A while ago, Jeff Atwood talked about <a class="reference external" href="http://www.codinghorror.com/blog/archives/001058.html">actual performance and perceived performance</a>, and funny enough, just after reading his post, I stumbled upon a similar deception of a performance indicator. It is really unbelievable how deceiving performance numbers can be, which seems to be a result of the bad sense of time of human beings. I believe that not only <a class="reference external" href="http://www.codinghorror.com/blog/archives/000981.html">most of us suck estimating</a> how much time a certain task will take, but we also suck at estimating how long a task actually took. It actually happened to me the same time I read Jeff Atwood’s post.</p>
<p>It all started with a new parallel version of a certain algorithm we were working on. Actually, a very important part of my daily work is optimization, and to improve the speed of our software, we use different forms of concurrency, and lately, we were parallelizing a certain algorithm using multithreading. To test out the performance difference using a single thread or multiple threads, we used an already existing test application. This test executes the algorithm on a given input and reports the time it spent running the algorithm. As soon as we had a preliminary version of the new multithreaded algorithm working, we started testing whether we could improve performance using both cores on a dual core machine.</p>
<p>We ran the test on a large sized input, using only a single thread on a dual core machine. Reported time 16:38. We ran the test on the same input, using two threads on the same machine. Reported time: 16:41. Using two threads taking more time than using one thread. Okay, a bit strange, but it is possible, considering there might be more overhead as a result of locking. We introduced some mutexes where necessary, and also the <span class="caps">OS</span> does its own locking too, for example for memory management. Anyway, nothing seemed to be executed in parallel, otherwise we would have to see an increase in time.</p>
<p>We reconsidered the mutexes, and reran the test. Reported times were again in the 16 minutes, where the multithreaded version was slower. We used a different input; same result with times around 20 minutes. It was only when we started investigating the multithreaded algorithm’s performance on smaller inputs, where the actual problem started surfacing.</p>
<p>It was in those cases where the test reported around 2 minutes for the dual threaded run where my co-worker started distrusting the reported time. “Hey, that didn’t feel like already two minutes passed!”, he cried. “What is this test reporting, <span class="caps">CPU</span> time or wall clock time?” Rerunning the test and using a good-old stopwatch gave us the final answer: the test application reported <span class="caps">CPU</span> time. That means we already almost <em>doubled</em> the performance by using two threads with the new algorithm, compared to the single threaded version. We were simply deceived by the reported times; the very first test reported 16:41, but it actually took only 8:20. We couldn’t believe our eyes, so we actually ran it again and confirmed it was true with our stopwatch approach.</p>
<p>So yes, I too believe that “performance is determined largely by the user’s perception rather than actual wall-clock time.”</p>
Software Specification —- A Blessing In Disguise?2008-04-15T20:17:00+02:002008-04-15T20:17:00+02:00Gertjan Zwartjestag:codemuse.co,2008-04-15:/2008/04/15/software-specification-a-blessing-in-disguise<p>The first time I got in touch with a software engineering process was at university. I am amazed, but very happy that that experience did not diminish my interest in software engineering processes. As you can guess, we were obliged to follow a very heavyweight process (probably one of the …</p><p>The first time I got in touch with a software engineering process was at university. I am amazed, but very happy that that experience did not diminish my interest in software engineering processes. As you can guess, we were obliged to follow a very heavyweight process (probably one of the most extreme), that the university lend from the European Space Agency (<span class="caps">ESA</span>). In retrospect, it might have been one of the most educational of the practical experiences I went through in my years at the university. But while we were undergoing the project, it certainly didn’t feel that way. We tried to deliver quality software, stuck with that malicious standard that did more harm than good. In the end we spent 80% of our time on writing a pile of specification documents stretching many centimeters in height, which we ‘archived’ in a drawer somewhere, leaving us with only 20% of our time left to actually deliver a product.</p>
<p>I kept on thinking that there <em>must</em> be another way, where you <em>do</em> write specifications, that actually <em>help</em> you in the process of writing software, instead of simply following process. In the years that followed from my very first experience with a software engineering process, slowly I formed —- what I currently think is —- a reasonable statement how to address software specification. In other words, I have found the means to express, what I think are the important aspects of software specification to address in a software engineering process or project <a class="footnote-reference" href="#id4" id="id1">[1]</a>.</p>
<p>Let’s start with a little bit of history that influenced how my ideas got to their present form. As I said, I started out with the conservative <span class="caps">ESA</span> software engineering standard at university. I wanted to know about more lightweight standards, so I toyed a bit with the <em><span class="caps">ESA</span> lite</em> standard which was introduced during classes as well. Still it felt it had too much overhead, especially in smaller projects (approximately 5 to 10 people, 20 to 200 <span class="caps">KSLOC</span>) that I was working on at the time, in which we wanted to apply the standard. What we actually did then, was stripping the <span class="caps">ESA</span> lite standard, leaving only the useful things for our projects, stripping everything that did not help us delivering the project. You could say we created our personal <span class="caps">ESA</span> <em>ultra</em> lite, tailored to the wishes we had based on the projects we were doing.</p>
<p>Finally I got to my last year where at the <a class="reference external" href="http://w3.tue.nl/en/"><span class="caps">TU</span>/e</a> you have to go through a graduation or master’s project, where you write a dissertation, that is based on a (practical) research topic you work on for a minimum of 9 months. I was very lucky that, right at the same time, I got the opportunity to set up a new department for the company I worked for that time, together with a close friend, Joost, who I knew from university. We had already been working for a couple of years for that company in our spare time while we were studying computer science, so they had gained faith in our knowledge and abilities. The idea was to create a separate development group that would be responsible for researching and implementing robust generic building blocks that could help speed up the work and improve the quality of the company’s main software product. We were convinced that we could not just start this ad hoc, but that we would need some kind of process or standard, supported by a bunch of tools. Both Joost and me still needed a topic for our master’s project, and yes, as you can guess, we went lobbying.</p>
<p>Our best chance was the department called <em>Software Construction</em>, headed by Prof. Dr. Bruce Watson. We already knew him from the course of the same name (Software Construction), and we already talked to him that we were interested to graduate on a topic from the field of software development. He also thought setting up the proposed department would be an interesting project, and agreed to be our supervisor for our graduation project. We discussed our ideas with him, including our ultralite standard, and he pointed us into two directions, that heavily influenced me (up to this day, which holds for Joost as well I guess):</p>
<ol class="arabic simple">
<li>he gave me his copy of <a class="reference external" href="http://www.pragprog.com/the-pragmatic-programmer">the Pragmatic Programmer</a>, and</li>
<li>he talked about a new revolution in software engineering processes:
<a class="reference external" href="http://www.agilealliance.com/">the Agile movement</a>.</li>
</ol>
<p>As a result, our dissertation most importantly became research into the current available literature about software engineering processes, including setting up a process for the new department. Besides that, we investigated tool support for software engineering processes and ran a few projects in practice, with our new setup.</p>
<p>The process became a combination of a new subset of what we already took from the <span class="caps">ESA</span> lite standard, including new influences from the different Agile standards we dived into (e.g. <span class="caps">XP</span>, Scrum). Of course the process focused heavily on the main deliverable: the code, which makes the product, including the tests to guarantee product quality. But besides code, we invented another deliverable, which we called the <em>Software Specification Document</em>. In every project we included such document describing two things:</p>
<ol class="arabic simple">
<li>The functional goal of the project <a class="footnote-reference" href="#id6" id="id2">[3]</a>.</li>
<li>The architectural design of the project.</li>
</ol>
<p>If you came here before, you might recognize these as two of <a class="reference external" href="https://codemuse.co/2007/10/08/the-three-pillars">my three pillars of abstraction</a>. Which finally brings me to the point where I can tell what, in my opinion, are the important aspects of software specification to address in a software engineering process or project, namely: describing the software project at the functional level and at the architectural level of abstraction.</p>
<p>Why cover the functional level and architectural level of abstraction in a specification document for a software project? Let’s suppose we would not write any additional specification. That leaves us with the source code as only ‘specification’ of the project.</p>
<p>With that assumption, what functional information do we have? From source code alone, you can only guess what the program on a functional level implements. Even if you can compile the code, or have a working version of the program, you will know the basic functionality, but still it will be hard to understand what the exact intent is of every function of the program. It’s like running an application without consulting any manual, tutorial or help information. We’ve all been there; when you finally use the information at hand, you become noticeably more effective and productive with the application. Here’s where specification of the function of a program can help: if you know what the program should do at functional level, it will be easier to understand what is happening on the implementational level. In other words, you will better understand the source code if you know what it is supposed to do <a class="footnote-reference" href="#id5" id="id3">[2]</a>.</p>
<p>The same holds for architectural design. More than once, I have heard the statement that “the time it takes to really understand how a large piece of code works, is the same as the time it takes to write the code from scratch by yourself”. Personally I don’t think that it is that black and white. Reading source code can give you many hints, especially if the code is of rather high quality. However, I do believe that, in general, it is very hard to reverse engineer the intended architecture from source code alone. In this case too, I think software specification can help here: with the knowledge of the overall underlying architectural design decisions, it is easier to comprehend and thus maintain or extend the source code. That’s why I would recommend to document a software product’s architecture too (if you are interested in what I think are the important aspects of software architecture to put down, read my previous post about <a class="reference external" href="https://codemuse.co/2007/06/12/the-five-princes">my five principles of software design</a>).</p>
<p>To conclude, the three levels of abstraction —- function, architecture, implementation —- that I think are so important in software development can be used directly in software specification too. On top of the source code, the important information lies in functional and architectural specification.</p>
<p>We chose to write a <em>Software Specification Document</em> that was meant to end up as a hard copy, but obviously it does not have to be a paper document; you can capture the important functional and architectural information in a <span class="caps">HTML</span> page, or in a Wiki just as well. To be honest, currently I am a great fan of using a Wiki system for software specification.</p>
<p>I don’t know what came first; the idea of the software specification document or the idea of the functional and architectural levels of reasoning. I do know that for me software specification is putting down the most important information of a software project that cannot be captured in source code alone: function and architecture.</p>
<table class="docutils footnote" frame="void" id="id4" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>Note that I will not talk about the reason for software specification; there are many reasons to put down more about a piece of software besides its source code alone. This is a separate discussion, and for now I’ll just assume the case that the idea of software specification can be useful.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id5" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id3">[2]</a></td><td>Besides that, a functional description of a software product is <em>the</em> base for end-user documentation.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id6" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2">[3]</a></td><td>Also known as user requirements, but I dislike that term because it reminds me of <span class="caps">ESA</span> too much.</td></tr>
</tbody>
</table>
Boosting Productivity2008-03-12T22:02:00+01:002008-03-12T22:02:00+01:00Gertjan Zwartjestag:codemuse.co,2008-03-12:/2008/03/12/boosting-productivity<p>Lately I have been busy implementing several things using the libraries available under name of <a class="reference external" href="http://boost.org">Boost</a>. Boost is a free and open source effort, and has a commercial support branch called <a class="reference external" href="http://www.boost-consulting.com">Boost Consulting</a> that is dedicated to delivering services, training and what they call <em>enterprise</em> releases. I mention Boost Consulting …</p><p>Lately I have been busy implementing several things using the libraries available under name of <a class="reference external" href="http://boost.org">Boost</a>. Boost is a free and open source effort, and has a commercial support branch called <a class="reference external" href="http://www.boost-consulting.com">Boost Consulting</a> that is dedicated to delivering services, training and what they call <em>enterprise</em> releases. I mention Boost Consulting, firstly because that might help to convince your bosses to use Boost at your company, and secondly so I can quote from <a class="reference external" href="http://www.boost-consulting.com/boost-libraries">their site</a> to introduce Boost:</p>
<blockquote>
<a class="reference external" href="http://boost.org">Boost</a> is a development group creating free software libraries suitable for inclusion in the C++ standard. […] Boost libraries cover a wide range of domains, from concurrency to numerics to language interoperability. <a class="reference external" href="http://www.boost.org/libs/libraries.htm">The Boost libraries</a>, many of which have passed through the C++ standardization process, have become widely known as an industry standard for design and implementation quality, robustness, and reusability.</blockquote>
<p>The reason for us to start using the Boost libraries is the same as why the Boost libraries were initially started. Again, I quote from <a class="reference external" href="http://www.boost-consulting.com">boost-consulting.com</a>:</p>
<blockquote>
[…] Beman Dawes, then chairman of the C++ committee’s library working group, recognized that languages such as Java and Python were growing in popularity precisely because of the ready availability of library components. Some jobs, he argued, were just too hard in C++ — not because of any inherent limitation, but because the right libraries were not available.</blockquote>
<p>Obviously the Boost consultants eat, and also promote their own dogfood, so they conclude:</p>
<blockquote>
[…] Boost is much more than a collection of individual experts: a cultural emphasis on collaboration and inquiry creates an environment where synergies evolve and new insights are discovered. I don’t think any of us expected to become quite so reliant on the Boost libraries in our professional development work, but the Boost libraries have proven themselves to be remarkably useful, versatile, and well-designed. Ten Boost libraries have already been accepted into the next version of the C++ standard.</blockquote>
<p>It is about six months ago that I installed Boost and started testing it in a prototype project, and it is true, once you start using it, there is no way back anymore. Boost <em>is</em> remarkably useful, versatile and well-designed; all three at the same time.</p>
FM Tracker in Dosbox2008-02-26T15:50:00+01:002008-02-26T15:50:00+01:00Gertjan Zwartjestag:codemuse.co,2008-02-26:/2008/02/26/fm-tracker-in-dosbox<p>In a <a class="reference external" href="https://codemuse.co/2008/02/11/a-decade-of-programming">previous post</a> I became all nostalgic and talked about my very first programming project called <span class="caps">FM</span> Tracker. I dug it up from my backup archives to see if I could bring it back to life again. I tried to revive my baby using the magical powers of <a class="reference external" href="http://www.dosbox.com/">DOSBox …</a></p><p>In a <a class="reference external" href="https://codemuse.co/2008/02/11/a-decade-of-programming">previous post</a> I became all nostalgic and talked about my very first programming project called <span class="caps">FM</span> Tracker. I dug it up from my backup archives to see if I could bring it back to life again. I tried to revive my baby using the magical powers of <a class="reference external" href="http://www.dosbox.com/">DOSBox</a>, and amazingly I succeeded!</p>
<p>I tried DOSBox already three or four years ago, just for fun, by just running some good old <span class="caps">DOS</span> programs that I downloaded here and there. Already back then it seemed to work quite nicely. I wanted to try <span class="caps">FM</span> Tracker too, but didn’t get to it that time. But while I was writing about my assembly coding time, I remembered I wanted to try to get it running using DOSBox. So I downloaded the <span class="caps">PPC</span> version for my PowerBook (with a good old G4 processor in it), that brought my precious back to life. Unfortunately, DOSBox performs way too slow on my PowerBook for <span class="caps">FM</span> Tracker to play a song, probably because of the overhead of converting x86 to <span class="caps">PPC</span> instructions I guess.</p>
<p>Again it took a while before I found the time to start playing with DOSBox on my desktop <span class="caps">PC</span> at home. Being an <span class="caps">AMD</span> Athlon 1400+, it is not a youngster anymore, but as it has a x86 architecture I thought it would be worth trying DOSBox on that machine too. I’m running <a class="reference external" href="http://www.gentoo.org">Gentoo</a> on that box, and after issuing <em>emerge dosbox</em> I was ready to go. The result was what I hoped for, in one word: stunning. I mean, I know the code I wrote for <span class="caps">FM</span> Tracker; 100% assembly, accessing the <span class="caps">BIOS</span> directly, hooking into interrupts, continuously throwing bits and bytes at the <span class="caps">OPL</span>’s input/output ports (<tt class="docutils literal">0x388</tt> and <tt class="docutils literal">0x389</tt> if I remember correctly) while playing a song, it all works perfectly. Right there on my Gnome desktop in a window, without the physical presence of an <span class="caps">OPL</span> chip in that machine.</p>
<p>Now I know it is possible to see my initial project’s results in its original fully functioning state, and because I think it deserves its own place on the internet, I’m making it <a class="reference external" href="https://codemuse.co/public/fmt.zip">public</a> here today. Everybody that wants to try <span class="caps">FM</span> Tracker is welcome to do so.</p>
<p>To conclude, by looking at the long <a class="reference external" href="http://www.dosbox.com/comp_list.php">list of supported games</a> or the <a class="reference external" href="http://pain.scene.org/service_dosbox.php">list of supported demos</a>, and my <span class="caps">FM</span> Tracker experiment, I can only say that DOSBox is surely a great a piece of work.</p>
New Looks2008-02-13T19:30:00+01:002008-02-13T19:30:00+01:00Gertjan Zwartjestag:codemuse.co,2008-02-13:/2008/02/13/new-looks<p>I finally found the time to implement a new look for code-muse.com. Many thanks to the guys who created the <a class="reference external" href="http://getk2.com">K2</a> style for Wordpress, which made my life so much easier to freshen up my blog’s design. For the header, I used the picture that I took while …</p><p>I finally found the time to implement a new look for code-muse.com. Many thanks to the guys who created the <a class="reference external" href="http://getk2.com">K2</a> style for Wordpress, which made my life so much easier to freshen up my blog’s design. For the header, I used the picture that I took while I was on top of the <a class="reference external" href="http://en.wikipedia.org/wiki/Dom_Tower_of_Utrecht">Dom tower</a> in my beloved hometown <a class="reference external" href="http://en.wikipedia.org/wiki/Utrecht_(city)">Utrecht</a>.</p>
A Decade of Programming2008-02-11T10:55:00+01:002008-02-11T10:55:00+01:00Gertjan Zwartjestag:codemuse.co,2008-02-11:/2008/02/11/a-decade-of-programming<p>Thinking of my early years of programming, I almost cannot believe that I have already been writing computer programs for so long. My first decade of software development slowly went by. I’m even well into the next decade, considering I wrote my first statements on an 8086 in 1994 …</p><p>Thinking of my early years of programming, I almost cannot believe that I have already been writing computer programs for so long. My first decade of software development slowly went by. I’m even well into the next decade, considering I wrote my first statements on an 8086 in 1994 (while I should have been playing football with the guys of course, the nerd I was, ahem, am). Back then, my very first project, at least the project which I consider a real substantial undertaking, was “<span class="caps">FM</span> Tracker”.</p>
<p>I need to start with a short intermezzo to introduce <span class="caps">FM</span> Tracker. Do you remember the <a class="reference external" href="http://en.wikipedia.org/wiki/Demo_scene">demo scene</a>? No? Then this might all sound a bit alien for you. In the case the answer is “yeah, of course, I was a l33t h4x0r too!”, you’ll remember, say, the <a class="reference external" href="http://en.wikipedia.org/wiki/Future_Crew">Future Crew</a> just to name a then famous group. If you had h4x0rs, then these demo guys really were the 3l1t3. They could do things with the 386 and 486 <span class="caps">PC</span>’s with <span class="caps">VGA</span> cards nobody couldn’t ever imagine.</p>
<p>For those that do not know about the demo scene, there were, for example, 4 kilobyte contests: create an executable that takes no more than four-thousand-ninety-six bytes of disk space and squeeze in as much stunning graphics and music effects as possible. At <em>demo parties</em> these 4K exes are run and the attendants choose a winner, which usually is the one that could do the most amazing things with no more than 32.768 bits at their disposal. Besides, there was no such thing as a powerful <span class="caps">GPU</span> or OpenGL that time. Those were the days the Gb’s were still the future utopia for memory, as well as harddrives. I remember my dad bought a new <span class="caps">PC</span> with 105 <span class="caps">MEGA</span>-bytes of disk space. How on earth will we get that thing full?! Obviously it took less than a year until it was chockfull. Anyways, these guys in the demo scene could bring to live such mind-blowing graphical effects, usually including background music, which was really amazing taking into account the memory and <span class="caps">CPU</span> limitations of the 1990’s.</p>
<p>I was talking about my <span class="caps">FM</span> Tracker project. The reason to start being nostalgic about the 1990s demo scene is that so called <a class="reference external" href="http://en.wikipedia.org/wiki/Trackers">trackers</a> were a very popular tool to create computer music that time, and as you can guess, <span class="caps">FM</span> Tracker is a tracker too. The infamous ScreamTracker is a well known example, besides of course the widely used FastTracker. A combination of music and computers, that was pretty cool of course. I fell in love and immediately became a huge FastTracker fan.</p>
<p>The same time, I got fascinated by <a class="reference external" href="http://www.shipbrook.com/jeff/sb.html">programming the AdLib soundcard</a> (bearing an <span class="caps">OPL</span> chip). I don’t know what it was, but I was intrigued by the magic how you could send numbers and compose music with that. All of the trackers I had were <a class="reference external" href="http://en.wikipedia.org/wiki/PCM"><span class="caps">PCM</span></a> based, or in other words, worked with pre-recorded samples (actually ScreamTracker 3 came with an <span class="caps">OPL</span> synthesizer mode as well, but I think it was not yet released the time I started with <span class="caps">FM</span> Tracker, and if it was, I didn’t know of it). So I decided to build <span class="caps">FM</span> Tracker (<span class="caps">FM</span> —- meaning Frequency Modulation; the main method of synthesis of the <span class="caps">OPL</span> family of chips).</p>
<p>I finished it in 1997. I learned a lot. About hardware architecture, hardcore chip/signal programming. Optimizing for speed and memory. Programming via the <span class="caps">BIOS</span> and <span class="caps">MS</span>-<span class="caps">DOS</span>, all that sort of low-level stuff. I went through different programming languages. Starting out with Basic, which was not powerful enough and the overhead of the generated code was way too high. Then Turbo Pascal, which generated code that was faster, but was still too slow to put into a high resolution timer interrupt. For a brief moment I tried C, but in the end I really needed Assembly for the performance critical parts, which is why I finally chose to write <span class="caps">FM</span> Tracker fully in 386 assembler.</p>
<p>In retrospect, I actually learned myself programming in that period of time. However, looking back, I can say that learning to program is something else than becoming a software engineer or software developer. There was still much to learn for me to become a <em>real</em> software developer, being able to work in a <em>team</em> on a large scale product. Besides that, I didn’t know about any (mathematical) fundamentals, so I reinvented the wheel multiple times, but that fortunately made the years at university all the more valuable.</p>
<p>So here I am, more than 10 years from my first finished product. Those ten years, the previous decade, went by very fast. I finished computer science at the <a class="reference external" href="http://w3.tue.nl/en/">Eindhoven University of Technology</a>, and I worked on many more software projects, mostly commercial, currently developing software to enable the next generation chips to be manufactured.</p>
<p>We have come a long way in software development, and even though we now have a ginormous amount of memory and astronomically more computing power than 10 years ago, one thing certainly has not changed: developing software still requires <em>hard work</em>.</p>
Pillars vs. Dennet2008-01-22T10:28:00+01:002008-01-22T10:28:00+01:00Gertjan Zwartjestag:codemuse.co,2008-01-22:/2008/01/22/pillars-vs-dennet<p>I finally finished Daniel C. Dennet’s <a class="reference external" href="http://www.amazon.com/Darwins-Dangerous-Idea-Evolution-Meanings/dp/068482471X/ref=pd_bbs_sr_1/103-0734124-3625458?ie=UTF8&s=books&qid=1176755391&sr=8-1">book</a> “Darwin’s Dangerous Idea”. I wrote about already it in one of my first posts, <a class="reference external" href="https://codemuse.co/2007/04/18/simplify-to-understand">Simplify to Understand</a>, where I found an analogy between a claim in his book and my own ideas about software. I cited the book and explained my …</p><p>I finally finished Daniel C. Dennet’s <a class="reference external" href="http://www.amazon.com/Darwins-Dangerous-Idea-Evolution-Meanings/dp/068482471X/ref=pd_bbs_sr_1/103-0734124-3625458?ie=UTF8&s=books&qid=1176755391&sr=8-1">book</a> “Darwin’s Dangerous Idea”. I wrote about already it in one of my first posts, <a class="reference external" href="https://codemuse.co/2007/04/18/simplify-to-understand">Simplify to Understand</a>, where I found an analogy between a claim in his book and my own ideas about software. I cited the book and explained my own idea using Dennet’s view.</p>
<p>Interestingly, in the process of finishing the book in the last couple of weeks, I found another analogy. Namely, I found a passage in which he explains a remarkably similar idea as I set forth in my post “The Three Pillars”:</p>
<blockquote>
If you know something about the design of an artifact, you can predict its behavior without worrying yourself about the underlying physics of it parts. Even small children can readily learn to manipulate such complicated objects as VCRs without having a clue as to how they work; they know just what will happen when they press a sequence of buttons, because they know what is designed to happen. They are operating from what I call the <em>design stance</em>. The <span class="caps">VCR</span> repairer knows a great deal more about the design of the <span class="caps">VCR</span>, and knows, roughly, how all the interior parts interact to produce both proper functioning and pathological functioning, but may also be quite oblivious of the underlying physics of the process; they are the ones who must descend to what I call the <em>physical stance</em> in order to figure out what sorts of design revisions might enhance picture quality, or diminish wear and tear on the tape, or reduce the electricity consumption of the product. But when they engage in <em>reverse</em> engineering —- of some other manufacturer’s <span class="caps">VCR</span>, for instance —- they avail themselves not only of the physical stance, but also of what I call the <em>intentional stance</em> —- they try to figure out what the designers <em>had in mind</em>. They treat the artifact under examination as a product of a process of <em>reasoned</em> design development, a series of <em>choices</em> among alternatives, in which the <em>decisions</em> reached were those <em>deemed best</em> by the designers. Thinking about the postulated functions of the parts is making assumptions about the <em>reasons</em> for their presence, and this often permits one to make giant leaps of inference that finesse one’s ignorance of the underlying physics, or the lower-level design elements of the object.</blockquote>
<p>What Dennet means by <em>design stance</em>, is what I think the first pillar, namely the <em>functional</em> level of looking at a designed artifact. The <em>physical stance</em> maps onto the third pillar, namely the <em>implementational</em> level, and the <em>intentional stance</em> is what I describe as the <em>architectural</em> level, as the second pillar.</p>
<p>What is especially interesting is that, examining a designed artifact with knowledge only from the design stance and physical stance (in pillar terms having only the knowledge on the functional and implementational level) it is very difficult to make statements from the intentional stance (or on the architectural level). In other words, when you know about the function of a program, and you have its source code, devising its architecture with only that is hard. That’s why, for maintainability purposes, it is wise to some way or another document the architecture, or <em>design intent</em>, for software. Obviously this can be an separate document, but it might even suffice to add the right comment in the code. As long as the <em>intent</em> of code is clear, it will be much easier for somebody else (and also for yourself) to use, change or extend it, using the original ideas you had in mind when you first wrote those lines.</p>
<p>At least, if you have considered the architecture of your code, which I believe you always should.</p>
Herding Cats2007-11-26T11:37:00+01:002007-11-26T11:37:00+01:00Gertjan Zwartjestag:codemuse.co,2007-11-26:/2007/11/26/herding-cats<p>I could not resist to take Andrew Boake’s choice of cartoon from the presentation he gave at Schanskop, and put it here. By it, I will be able to remember the nice discussion we had —- at the Braai of course —- about managing software developers. It is a “Doctor Fun …</p><p>I could not resist to take Andrew Boake’s choice of cartoon from the presentation he gave at Schanskop, and put it here. By it, I will be able to remember the nice discussion we had —- at the Braai of course —- about managing software developers. It is a “Doctor Fun” episode (October 2002), by <a class="reference external" href="http://www.ibiblio.org/Dave/">David Farley</a>.</p>
<img alt="The cat herder's daydream" src="https://codemuse.co/images/herding_cats.jpg" />
Espresso Follow Up2007-11-22T10:53:00+01:002007-11-22T10:53:00+01:00Gertjan Zwartjestag:codemuse.co,2007-11-22:/2007/11/22/espresso-follow-up<p>I’ve returned from my South Africa trip two weeks ago already, that gave me enough time to get used to the Dutch cold again. While it is still quite fresh in my memory I would like to take the opportunity to write a bit about my experiences at the …</p><p>I’ve returned from my South Africa trip two weeks ago already, that gave me enough time to get used to the Dutch cold again. While it is still quite fresh in my memory I would like to take the opportunity to write a bit about my experiences at the Espresso workshop. First of all, I would like to thank the <a class="reference external" href="http://espresso.cs.up.ac.za">Espresso group</a>, and especially Derrick Kourie, to be so kind to organize the workshop and invite me. I had a very warm welcome; it was great being back in Pretoria for a short one-and-a-half day.</p>
<p>I got many reactions on my (short) presentation about abstraction and design foundations, and to hear from students that they enjoyed the talk, finding it interesting to hear from someone out there in the field was very nice. Especially the fact that I didn’t use, and I quote, “mathematical hieroglyphs that academics tend to use so much”, was an entertaining remark I was told at the evening <a class="reference external" href="http://http://en.wikipedia.org/wiki/Braai">Braai</a>. Besides that, several very interesting points were brought up in the discussion, and I will follow up on one of them in this post.</p>
<p>The most intriguing remark came from Stephan Gruner. He asked me the following question: “Everything you talked about today can be found in abundant resources on Software Engineering. So what’s new in what you presented?” Clearly I did not illustrate the context of my talk well enough that day. Undoubtedly, the three pillars of abstraction and the five principles of software design are not something new. They’re just fancy names that I invented for some of the very basics of software engineering. And yes, already back in the 70s while they were struggling with the waterfall model, these concepts have been in there. Nowadays we’ve got so many software engineering methodologies around, that it becomes impossible to know the details about them all (just to name a few famous ones: <span class="caps">XP</span>, <span class="caps">RUP</span>, Scrum, Crystal Clear). And that is exactly the point I wanted to make.</p>
<p>In practice —- at least that is what I have experienced —- there are now so many software engineering approaches that they have become a goal in themselves instead of a means for improving software development. That’s why I tried to find foundations, at the meta-process level, that are shared among those different processes. Searching for the foundations that I have found to be useful and thus important for me. I have worked with several different processes (such as the code-as-you-go-with-no-process-at-all method, the heavyweight <span class="caps">ESA</span> Software Engineering standard, <span class="caps">XP</span>, but also company customized standards), and two things have helped me in all of them. Different levels of reasoning and architectural design; my pillars and princes.</p>
<p>Instead of just working according to process simply for the sake of the process, I think you should always think about why you are following the rules dictated by the process, and more specifically what the goal is that you want to achieve by doing that. And although this sounds just like common sense —- and common sense it is —- I have unfortunately seen this mistake made too often.</p>
Talking of Which2007-10-16T20:22:00+02:002007-10-16T20:22:00+02:00Gertjan Zwartjestag:codemuse.co,2007-10-16:/2007/10/16/talking-of-which<img alt="Schanskop venue" class="align-left" src="https://codemuse.co/images/schanskop.jpg" />
<p>I am honored to give a presentation at the yearly <a class="reference external" href="http://fastar.org">Fastar</a>/<a class="reference external" href="http://espresso.cs.up.ac.za">Espresso</a> workshop on Monday the 22<sup>nd</sup> of October at the conference centre at Schanskop Fort on the hills overlooking Pretoria, South Africa (see picture). I will be talking about two of my blog posts, the three Pillars of …</p><img alt="Schanskop venue" class="align-left" src="https://codemuse.co/images/schanskop.jpg" />
<p>I am honored to give a presentation at the yearly <a class="reference external" href="http://fastar.org">Fastar</a>/<a class="reference external" href="http://espresso.cs.up.ac.za">Espresso</a> workshop on Monday the 22<sup>nd</sup> of October at the conference centre at Schanskop Fort on the hills overlooking Pretoria, South Africa (see picture). I will be talking about two of my blog posts, the three Pillars of Abstraction and the Five Principles of Software Design.</p>
The Three Pillars2007-10-08T22:26:00+02:002007-10-08T22:26:00+02:00Gertjan Zwartjestag:codemuse.co,2007-10-08:/2007/10/08/the-three-pillars<p>Generally, the base for a sturdy construction is a robust foundation. Take, for example, the good old Romans who built a stable Europe (for a short while). As builders, they were very inventive. Their structures have lasted for many years up to this day. Among other interesting architectural highlights, Roman …</p><p>Generally, the base for a sturdy construction is a robust foundation. Take, for example, the good old Romans who built a stable Europe (for a short while). As builders, they were very inventive. Their structures have lasted for many years up to this day. Among other interesting architectural highlights, Roman builders commonly used pillars to support their imposing structures. The reason to refer to the Roman pillars is because I will use them as a metaphor to propose my own <em>three pillars of abstraction</em>. Just as the pillars in the Roman time supported their grand constructions, the three pillars of abstraction are my foundation for a well built software system.</p>
<p>I already introduced my <a class="reference external" href="https://codemuse.co/2007/06/12/the-five-princes">five principles of software design</a>, but then I purely focused on architecture. However, the scope of software engineering obviously is broader, and consists of more than only architecture and design. With this post I want to address a broader the scope, instead of focusing on architecture.</p>
<p>Let me start by defining software engineering. For normal human beings, the essence could be summarized as “delivering a software solution for a problem”. With that being the goal and since software engineering is my job, I would like to investigate what I usually do to get from problem to solution, from my experience. I have been developing software for more than 10 years, in different teams, and on different scales. I have used many programming languages, and I have used many tools. I have been confronted with different software engineering processes and I have developed a customized software engineering process. But each and every time, one thing was the same for me: I relied on three <em>levels of reasoning</em> about the original problem and its software solution. Three levels of <em>abstraction</em>.</p>
<p>Before going straight into the details of each of the three levels, first a word about abstractions in general. There’s a definition of <a class="reference external" href="http://en.wikipedia.org/wiki/Abstraction_%28computer_science%29">abstraction on Wikipedia</a>, that says it all: “a mechanism and practice to reduce and factor out details so that one can focus on a few concepts at a time”. The main goal for abstraction in software engineering is to be better able building and understanding a complex system. Besides focus, abstractions also allow to spread people’s expertise, because a different concept might require different expertise. Furthermore, estimations can be more precise per concept and it might as well be easier to determine the amount of risk per concept. As a result, overall estimations and risk determination can become much more reliable.</p>
<p>Alright, let’s go back to the basics. As I said, I always rely on three levels of abstraction. Namely, the three pillars of abstraction:</p>
<ol class="arabic simple">
<li>Function</li>
<li>Architecture</li>
<li>Implementation</li>
</ol>
<p>Each of them focuses on a different level of detail. More specific, a higher level of detail leaves out as much as detail as possible from the lower levels.</p>
<p>There is a chance that you got scared looking at the list, because it might look an awful lot like the Waterfall model, or it might look like it promotes <a class="reference external" href="http://en.wikipedia.org/wiki/BDUF"><span class="caps">BDUF</span></a>. But no, no, no, it has nothing to do with neither of them. The Waterfall model has similar concepts, but imposes a strict order on them. For example, the Waterfall model says that you cannot start designing before you have put down all requirements. The same holds for <span class="caps">BDUF</span>, which tells that the implementation cannot start once the design is not finished. However, the pillars of abstraction do not impose any order; you can be reasoning on the level of architecture —- and even implementation —- while you are busy nailing down the requirements. Likewise, you can be reasoning about architecture while you are already coding (which is not such a bad idea anyway). The other way around, the different levels of abstractions can be perfectly used too in the Waterfall or <span class="caps">BDUF</span> way of working (not that you’d want to be working that way). In general, the pillars of abstraction are valid independent from the software engineering process that is used, whether it is an iterative or Agile process, such as <span class="caps">XP</span>, or the conservative Waterfall model. They can be best seen that they implement a way of “separation of concerns” as <a class="reference external" href="http://www.cs.utexas.edu/users/EWD/">Edsger W. Dijkstra</a> put it so eloquently <a class="reference external" href="http://www.cs.utexas.edu/users/EWD/transcriptions/EWD04xx/EWD447.html">already in 1974</a>.</p>
<p>Starting at the first level of abstraction, the functional level, the focus is on the problem. The details of the solution are factored out. Though at this level things are also comprehensible for the customer or end-user, it is the toughest and most tiresome pillar to be reasoning about for the average software developer. This is not strange, considering the fact that defining the functionality is, as Brookes explained it, the <a class="reference external" href="?p=20">inherently difficult part</a>. Consequently, this pillar is usually not that strong. My experience is that the capabilities to reason about the use of a system, and why it is being built are generally very meager among project members. That gives us a thin functional pillar.</p>
<p>On the architectural level, the next pillar, the focus is on the solution. How is the desired functionality converted to a software system? Which algorithms are used? What is the blueprint of the system? This is the context wherein the five principles of software design can become of use. Without the exact details of a particular implementation, on this abstraction level the machinery of the system can be communicated. This is the level where programmers start to have a little bit of fun. Still, they find it usually very hard to separate the implementation level from the architectural level of abstraction.</p>
<p>Last, and certainly not least, we have the implementation level. For programmers this is the level at where they can enthusiastically debate with each other for hours. This is their most comfortable domain. This level is about the technical details of the solution.</p>
<p>An example.</p>
<p>Suppose somebody wanted me to make a <span class="caps">PDF</span> viewer, by way of an example, with only the limited functionality to browse through the pages in a <span class="caps">PDF</span> document. The functional abstraction level leaves out everything that has to do with the architecture and code. That means that on functional level we could be talking about how a user might select a file to view. Which buttons he or she would use to go to the next page, and if the scroll wheel of the mouse will work too. If the program will work on Mac <span class="caps">OS</span> X or Windows. All terms that an end-user will more or less understand.</p>
<p>On architectural level, I’ll be thinking of a <span class="caps">PDF</span> parser, a <span class="caps">PDF</span> renderer, and some building block that will read user input. Whether to separate reading keyboard and mouse input, is a relevant question on architectural level. Maybe support for different types of documents, gives rise to an intermediate data structure in the design. The <span class="caps">PDF</span> parser fills that data structure, and the renderer will render the custom data. Making the renderer independent from <span class="caps">PDF</span>. For a simple <span class="caps">PDF</span> parser that architecture might be overkill, but for a more generic document viewer it might be a good idea.</p>
<p>At the level of the lines of code, we might be discussing whether to use the Qt or the wxWidgets library. Whether this or that function should have a reference as argument or a pointer. What the size of the blocks will be in memory when we are parsing the input <span class="caps">PDF</span>. And so on.</p>
<p>Another example: the elevator test.</p>
<p>In the process of writing this post, Jeff Atwood wrote about <a class="reference external" href="http://www.codinghorror.com/blog/archives/000962.html">the elevator test</a>. This test is closely related to the level of abstraction, I think, and gives a nice practical example of use too. The test is about the fact that very few developers can explain <em>why</em> they are coding. Usually when you ask a developer what he is doing, you will get the implementation level answer. If you are lucky, you will immediately get the answer in terms of design. Then you start asking why. Slowly you will move towards the functional level. You pass the elevator test if you can give a functional level answer about what you are doing within 60 seconds.</p>
<p>Whether or not you can go from implementation level to function level in 60 seconds, for me, all the different levels count. I think it is a good thing to know the separation between each level. I already noted that commonly the functional pillar is underdeveloped and that separating the architecture from the implementation is difficult for developers, and, as a result, we have a skewed foundation. A thin wooden pillar for function, a bit thicker architectural pillar, that is partly blended together with a firm pillar for implementation.</p>
<p>For the best result, of course, the pillars should be balanced.</p>
Why You Want Talented Artists2007-08-14T09:37:00+02:002007-08-14T09:37:00+02:00Gertjan Zwartjestag:codemuse.co,2007-08-14:/2007/08/14/why-you-want-talented-artists<p>After publishing about the art of software development yesterday, a friend pointed me at Frank Wiles’ <a class="reference external" href="http://blog.revsys.com/2007/08/a-guide-to-hiri.html">“Guide to Hiring Programmers: The High Cost of Low Quality”</a>. Assuming software development is an art, Frank Wiles very aptly outlines the reasons that in a company you should aim for talented artists only …</p><p>After publishing about the art of software development yesterday, a friend pointed me at Frank Wiles’ <a class="reference external" href="http://blog.revsys.com/2007/08/a-guide-to-hiri.html">“Guide to Hiring Programmers: The High Cost of Low Quality”</a>. Assuming software development is an art, Frank Wiles very aptly outlines the reasons that in a company you should aim for talented artists only.</p>
<p>Maybe the best summary that describes the people you’d want to hire is Joel Spolsky’s “Smart, and Get things done.” How do you find them? Read his <a class="reference external" href="http://www.joelonsoftware.com/articles/GuerrillaInterviewing3.html">“Guerrilla Guide to Interviewing (version 3.0)”</a></p>
Gurus Respond — Are We Artists?2007-08-13T10:43:00+02:002007-08-13T10:43:00+02:00Gertjan Zwartjestag:codemuse.co,2007-08-13:/2007/08/13/gurus-respond-are-we-artists<p>I have always had the feeling that developing software is an art. It requires creativity, vision, devotion, and, especially <em>Hard Work</em>. The first time I found material supporting my theory was when I read Frederick P. Brooks’ <a class="reference external" href="http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959">Mythical Man Month</a>, that contains his excellent article “No Silver Bullet”. The article …</p><p>I have always had the feeling that developing software is an art. It requires creativity, vision, devotion, and, especially <em>Hard Work</em>. The first time I found material supporting my theory was when I read Frederick P. Brooks’ <a class="reference external" href="http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959">Mythical Man Month</a>, that contains his excellent article “No Silver Bullet”. The article argues that developing software is inherently complicated; like an art, you must be talented, or at least skilled to do it.</p>
<p>I was triggered to write this post, because recently I received an email via the <a class="reference external" href="http://espresso-soft.org">Espresso</a> mailing list (Espresso is a software engineering research group I’m an associated member of), from Addey De Roubaix, who is completing his masters degree (at the university of Pretoria) related to Brooks’ “No Silver Bullet”. Addey took the initiative to write to a few gurus to get their views and — surprisingly — he received pleasant and courteous answers from all of them. They are, namely, Robert Glass, Dan Berry, Scott Ambler, and Fred Brooks himself. His supervising professor, Derrick Kourie, forwarded Addey’s communiques to the Espresso mailing list under the title “Brooks and other gurus respond”.</p>
<p>The question was:</p>
<blockquote>
Do you have an opinion on whether, over the last two decades, with all of the trends, tools and innovations —- such as <span class="caps">UML</span>, Process Maturity, Agile Methods, Object Orientation, etc. —- we are effectively tackling the essential difficulties asserted by Dr. Brooks in 1986?</blockquote>
<p>One of the responders, Daniel Berry, wrote about the subject in his “The Inevitable Pain of Software Development: Why There Is No Silver Bullet”. He has devoted <a class="reference external" href="http://se.uwaterloo.ca/~dberry/inevitable.pain.html">a separate page on his internet site</a> to this topic. The article sounded quite interesting to me, so I printed it, and read it in my daily train-commute. I found in it a good explanation about essences and accidents of software development. I like to quote it here to put the guru question in context:</p>
<blockquote>
<p>[Brooks] classifies software issues in essences and accidents. The essence is what the software does. The accidents are the technology by which the software does the essence or by which the software is developed. “The hardest single part of building a software system is deciding precisely what to build… No other part of the work so cripples the resulting system if it is done wrong. No other part is more difficult to rectify later.” This quotation captures the essential difficulty with software that must be addressed by any method that purports to alter fundamentally the way we program, that purports to make programming an order of magnitude easier, that purports to be the silver programming bullet we have all been looking for. Heretofore, no single method has put a dent into this essential problem, although all the discovered methods have combined to improve programming by at least an order of magnitude since 1968, the year the term “software engineering” was invented.</p>
<p>Moreover, Brooks, based on his experience, predicted that “There is no single development, in either technology nor management technique, which by itself promises even one order-of-magnitude improvement within a decade in productivity, in reliability, in simplicity.” He made this prediction in 1986 when he first published “No Silver Bullet” in Information Processing ‘86. Since we are now well past a decade after 1986, and no such single technology or management technique has appeared, he has been proven correct. He added a slightly stronger, but still conditional, prediction with which I agree. <em>“I believe the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it and testing the fidelity of the representation.</em> We still make syntax errors, to be sure; but they are fuzz compared to conceptual errors in most systems. If this is true, building software will always be hard. There is inherently no silver bullet.” Because we will always be building systems at the new frontiers opened by the latest advances in the accidents, I believe that the antecedent of this conditional statement, that conceptual errors are the hardest kind to find, will always be true. Therefore, <em>I</em> believe that the conclusion will always be true and that there is inherently no silver bullet.</p>
</blockquote>
<p>Mister Berry is very clear about it. Developing software is inherently complicated and not only does it require Hard Work once, no, it will <em>always</em> need Hard Work.</p>
<p>I’m reluctant to copy the other responses verbatim into my post, since it was a conversation between De Roubaix and each individual guru, so I probably should ask permission before quoting their responses fully. Summarizing, they all respond that Brooks’ article is still very relevant. Not one of them thinks we have found a silver bullet (neither have I met nor read from anyone who thinks we have).</p>
<p>Robert Glass, for example, points out that most new technologies (like <span class="caps">OOP</span>, Agile, <span class="caps">UML</span>, Process Maturity) are much less used than academics think they are. The last 5 years of experience I myself had with software development companies confirm his point, and I think many software developers at companies can confirm this. After all, these technologies only help, and not abolish the difficulties with software development.</p>
<p>The following from Frederick P. Brooks himself, I could not resist to cite:</p>
<blockquote>
Notice that most of the people claiming higher productivity (1) are tool builders with products to hype, (2) seem to be given to future tense pronouncements, (3) are expressing unsupported opinions, without data.</blockquote>
<p>Yes, as sharp as a chef’s knife. He is positive as well:</p>
<blockquote>
I think object-oriented programming in fact lifts design thinking to a higher level and thus addresses the essence of the problem.</blockquote>
<p>An abstraction of a problem into objects and relations between objects, <a class="reference external" href="https://codemuse.co/2007/06/12/the-five-princes">I also think</a> helps tackling the problem.</p>
<p>So it seems, in general we are still fighting accidents only. Maybe software engineering isn’t <em>engineering</em> after all. As Daniel Berry, I believe too there is no secret potion. There is no one way to do it. Now suppose for a second we are artists. Even painting has its basics. Handling a pencil for example. Choosing the right paint. Choosing the right materials. It certainly will affect an artist’s paintings. I could have never expressed it as clear as Daniel Berry does in his “Inevitable Pain of Software Engineering”:</p>
<blockquote>
<p>Software engineering is an art, no less than painting. Indeed, the first part of the titles of Donald Knuth’s books in his series on algorithms for computer programming is <a class="reference external" href="http://www.amazon.com/Art-Computer-Programming-Volumes-Boxed/dp/0201485419">The Art of Computer Programming</a>. The fact that software engineering is an art does not minimize its technical roots. A programmer must know the languages, the hardware platforms, the domain areas of his or her software, etc. However, what he or she does with them is very much a matter of art.</p>
<p>Even traditional arts, e.g., painting, have technical aspects. No matter how talented a painter is, if he or she does not know how to work with paints, his or her paintings will not be good. Furthermore, as has been demonstrated by mediocre artists, knowledge of the techniques does not insure good quality art.</p>
<p>Actually software engineering is an art just like mathematics. Both creativity and knowledge are required. Would mathematicians get upset if they were told that it was impossible to turn mathematics into a systematic engineering discipline? Would mathematicians even try?</p>
<p>If we know a domain well enough that architecture-changing requirement surprises are significantly tamed, as for compiler production these days, we can go the engineering route for that domain, to make building software for it as systematic as building a bridge or a building. However, for any new problem, where the excitement of major innovation is, there is no hope of avoiding relentless change as we learn about the domain, the need for artistry, and the pain.</p>
</blockquote>
<p>Suppose programming needs talent. Take talented sportsmen, they have their favorite gear too. They are certainly far better than average with the most rudimentary gear, but to outperform other talents they will need the best gear money can buy. They fight their accidental difficulties (effectively) using the right gear.</p>
<p>That’s why I think addressing the accidents is important too. You need the right team, the right people. But you can make them perform much better by tackling the right accidents. For me the most important accidents are the process and the set of tools. Amongst others:</p>
<ul class="simple">
<li><a class="reference external" href="https://codemuse.co/2007/06/12/the-five-princes">Communicating design</a></li>
<li><a class="reference external" href="https://codemuse.co/2007/04/18/simplify-to-understand">Simplicity</a></li>
<li>Source code control</li>
<li>Automated builds</li>
<li>Automated testing</li>
<li><span class="caps">API</span> documentation</li>
<li>And so on…</li>
</ul>
<p>I can make the list as long as I want. If you think of it, we all have our personal list of accidents that we think are most important and should be handled. For each team and even for each project, the list probably differs every time. Actually, I’m addressing most of my own list here on this blog, but I too obviously do not have the recipe for the Silver Bullet.</p>
<p>Back to the initial question. Are we artists? Maybe. Either way, it is just a metaphor. But one thing I know for sure after a decade of developing software, either alone, or in a team: for software to be good, it requires <em>Hard Work</em>. That’s the inevitable pain of our job.</p>
<p>Either accept this fact, or find a different job.</p>
The Five Princes2007-06-12T09:01:00+02:002007-06-12T09:01:00+02:00Gertjan Zwartjestag:codemuse.co,2007-06-12:/2007/06/12/the-five-princes<p>When asked to describe the architecture of a software system, the first thing developers usually do is picking a graphical tool to begin with. Maybe Visio, <a class="reference external" href="http://www.xfig.org">Xfig</a>, <a class="reference external" href="http://www.omnigroup.com">OmniGraffle</a>, or some other fancy <span class="caps">UML</span> tool. Maybe even Knuth’s <a class="reference external" href="http://www.tug.org/metapost.html">MetaPost</a>. These tools are all chock full of <em>drawing</em> features, and they …</p><p>When asked to describe the architecture of a software system, the first thing developers usually do is picking a graphical tool to begin with. Maybe Visio, <a class="reference external" href="http://www.xfig.org">Xfig</a>, <a class="reference external" href="http://www.omnigroup.com">OmniGraffle</a>, or some other fancy <span class="caps">UML</span> tool. Maybe even Knuth’s <a class="reference external" href="http://www.tug.org/metapost.html">MetaPost</a>. These tools are all chock full of <em>drawing</em> features, and they keep you all too busy playing with the looks of a system’s design.</p>
<p>Aren’t we primarily interested in <em>describing</em> and thereby <em>explaining</em> the design of a system? More strongly, isn’t the actual goal <em>communicating</em> a design? For instance, in order for a development team to agree on a design, commonly a design is documented in a design specification: the document communicates the design to all team members. Personally, I am regularly communicating (new) design idea’s to my development team too. For that purpose, I’d generally use a whiteboard or a couple of sheets of paper, before the design ends up in a full-blown document. Even while I am in the process of writing a large (undocumented) chunk of code on my own, I typically take some paper lying around to outline the design I’m working on.</p>
<p>So before grabbing another fancy tool, I want to try to explore what I’d actually need while I am describing an architecture. Not only when I am using a (graphical) software tool, but also while I am drawing on a whiteboard or a piece of paper, talking to colleagues, and so on.</p>
<p>Remains the question whether there are basic elements — or <em>principles</em> — for software design to be defined. I believe there are. That’s what this article is about. I even want to go as far as to say that I’m able to define my personal <em>five</em> most important principles for software design. The ones I use, I would say <em>almost daily</em>. Not exaggerating, let’s say I use them <em>a lot</em>, taking into account those days I’m having a Hoegaarden in the April sun at Queen’s day <a class="footnote-reference" href="#id2" id="id1">[1]</a>.</p>
<p>Back to software design.</p>
<p>The question was: “Are there basic principles for software design?” My answer is: “Yes, and I’ve got five here to present to you.”</p>
<p>Let me start at the beginning. First of all, to get grip of a system, I would want to divide it into parts. Starting with big chunks. Dividing those into smaller chunks. Going on until I decide it is time to stop. The whole system itself is a part too; the largest one. These chunks, or parts of the system are usually called entities, the system itself being the largest entity. Voila, here we have my first principle of software design: <strong>entities</strong>.</p>
<p>Entities divide a system into parts, the parts into sub-parts, these sub-parts again into sub-sub-parts, and so on. To structure this ever growing set of parts, I introduce my second principle of software design: <strong>hierarchy</strong>. The whole system itself is the entity at the top of the hierarchy. From there we can zoom in to the system’s different parts, representing the next level of hierarchy. These parts again can have subparts defined in another level deeper in hierarchy. And so on. The bottom level of hierarchy has the highest level of detail. It depends on the level of detail you want, how much levels of hierarchy you will have.</p>
<p>Using entities and hierarchy, a system can be divided into parts with the parts being divided into different levels of hierarchy, describing a system’s modular structure. But that does not tell us anything about the interrelations between entities, besides that they are ordered into different hierarchical levels. My third and fourth principles of software design, <strong>inheritance relations</strong> and <strong>instance relations</strong>, are the concepts to describe relations between entities. Modern programming languages actually have these two very important concepts for re-use — <em>specialization</em> and <em>instantiation</em> — usually built in.</p>
<p>An inheritance relation — or specialization — in terms of entities, is the concept that one entity <a class="reference external" href="http://en.wikipedia.org/wiki/Inheritance_%28computer_science%29">inherits</a> from, or specializes another entity. I believe this is such an important and truly valuable concept, that you should be able to reason about it on the level of a system’s design. To comprehend an existing system, you will really want to understand its inheritance relations.</p>
<p>Instance relations are the relation between an entity with one or more other (instances of) entities. We all know this elementary form of re-use (commonly termed <a class="reference external" href="http://en.wikipedia.org/wiki/Object_composition">composition</a>) and put it to use everyday. Except on those sunny Hoegaarden days of course. Undeniably, instantiation relations determine a large part of a system’s structure.</p>
<p>To conclude, on the same level in the hierarchy I will always want to describe the inheritance and instance relations, as they are two important concepts that determine the structure of a system for a great deal.</p>
<p>Now, at first, this might be trivial, but besides the first four principles, the remaining one is: <strong>explanation</strong>. “Hmm,” you’ll say, “you are leaving out all the other fancy schmancy stuff, and put it all under the name of explanation?!” I’ll answer: “Yes. That is precisely what I am doing. I am trying to <a class="reference external" href="https://codemuse.co/2007/04/18/simplify-to-understand">keep it simple</a>.”</p>
<p>To explain why, let’s shortly get back to the first four principles. They all describe static properties. They define what I’d rather call the blueprint of a system: its static structure. Shouldn’t a design contain the dynamics of a system too? In other words, a design should tell you, on top of the static structure, how the software will behave when it is in operation:</p>
<pre class="literal-block">
design = blueprint + behavior = static + dynamic structure
</pre>
<p><span class="dquo">“</span>Aaah!” You should say now. “That’s what you mean by explanation.” Yes. That is what I mean with explanation. I know of no model that can really capture dynamic elements. But words can! Maybe you need more than a couple of them, or a whole paragraph. Maybe even a few paragraphs. In all cases, those words can bring your static structure description to life.</p>
<p>Yes, there are modeling languages to capture the flow of a system. However, I generally think trying to model a flow in a diagram, still makes it static in the end. I have seen diagrams including attempts to depict the dynamics of a system, that obfuscated instead of clarified a design description. You just forcibly try to capture dynamics in a static graphic. Even if you do try to add dynamics in a picture, most of the time you will still need words to explain the diagram.</p>
<p>So why not just use words?</p>
<p>A picture might say more than a thousand words. On the other hand, it might also be impossible to capture a well written piece of text in a single graphic. It simply depends on what you are trying to communicate. And in our case, this means that the static structure description can be captured neatly in diagrams. Little clarifying text will be necessary. The dynamics of a system, however, I believe, can be explained best with text.</p>
<p>Summarizing, the first four principles I introduced can be used to describe the static structure. Then the fifth comes in and brings the design to life by explaining the dynamic behavior, and, of course, an explanation for all other aspects of the design not captured by the static structure. Here they are, all five:</p>
<ol class="arabic simple">
<li>Entities</li>
<li>Hierarchy</li>
<li>Inheritance relations</li>
<li>Instance relations</li>
<li>Explanation</li>
</ol>
<p>When I’m trying to discover, describe, communicate, or daydream about a software system’s architecture, I’ll generally stick to my own five principles of system design, as pillars for my mind.</p>
<p>Would you?</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>I started writing this article on the <a class="reference external" href="http://en.wikipedia.org/wiki/Koninginnedag">30th of April</a> already, but lost an almost finished version of the text a couple of days ago. The only thing that remained was “The Five Princ”, a part of the original title “The Five Principles for Software Design”. My gut feeling tells me this has something to do with upgrading, or otherwise fiddling with Wordpress, grrrrr! Evidently, it took me a while reconstructing the text to an acceptable version again. I decided to keep the title inspired on the event.</td></tr>
</tbody>
</table>
Internal Errors2007-05-24T09:10:00+02:002007-05-24T09:10:00+02:00Gertjan Zwartjestag:codemuse.co,2007-05-24:/2007/05/24/internal-errors<p>Almost every piece of software has it’s own way of handling <em>internal errors</em>. Usually such error is reported, and the software aborts. Take, as an example, the infamous <a class="reference external" href="http://en.wikipedia.org/wiki/Blue_Screen_of_Death">blue screen of death</a>. Is it possible to define the important concepts for internal errors, so as to not confuse an …</p><p>Almost every piece of software has it’s own way of handling <em>internal errors</em>. Usually such error is reported, and the software aborts. Take, as an example, the infamous <a class="reference external" href="http://en.wikipedia.org/wiki/Blue_Screen_of_Death">blue screen of death</a>. Is it possible to define the important concepts for internal errors, so as to not confuse an end-user? Let’s give it a try:</p>
<ul class="simple">
<li>First of all, if an internal error is detected, this should mean the software has found a potential bug. Something in the flow of execution went awfully wrong, with devastating effects such that the program cannot continue running. Which is actually what internal errors are for; detecting a wrong execution path <em>before</em> devastating events will take place.</li>
<li>Therefore, the program should <em>abort</em> after detecting and reporting the internal error.</li>
<li>The user should be notified how to report the error as a bug. Ideally, the program might provide a way to automatically report the previously occurred error. Via the internet, for example, see Joel Spolsky’s excellent article on <a class="reference external" href="http://discuss.joelonsoftware.com/help/Articles/GetCrashReportsFromUsersA.html">automatic crash reporting</a> in the context of his FogBugz product. Unfortunately, this might be out of the question in software for businesses depending highy on intellectual property rights.</li>
<li>Every internal error should be uniquely identified, for example, using an error code, to ease communication between clients, the helpdesk and development. They can all talk about, say, error 146. The developers should even be able to immediately identify the line in the code where error 146 is trapped.</li>
<li>A hint might be given about what is wrong, although that could confuse the user in believing to be able to solve the error. However, since an internal error detects a potential bug, most probably the source code is wrong, which a user usually cannot fix. Moreover, you don’t want the user to try working around the error, it is a software problem that you should want to know of. This is a tough call: give the user some information to be able to try to work around the problem, or leave out those details in the message reported by the software, to raise the chance of being notified of the problem (in particular when automatic reporting is not an option). In the second case, your helpdesk could be instructed with hints to work around specific internal errors.</li>
</ul>
<p>Some examples: a segmentation fault can actually be classified as an internal error, however not detected by the program itself, but the <span class="caps">OS</span>. Running Linux, an application will print “Segmentation fault” and is terminated by the kernel. Seems reasonable — there is no information how to contact the helpdesk, since there is no centralized Linux helpdesk to contact. I also see no reason to use error codes. The Windows 9x blue screen gives you a choice: terminate the program an continue or restart the <span class="caps">OS</span>. This is confusing for the user; in almost all cases, a restart is required to really recover from the problem. On the other hand, the <a class="reference external" href="http://en.wikipedia.org/wiki/Image:Xbox360_bsod_02.jpg">Xbox 360 error screen</a> shows a distinct example of a non-confusing internal error.</p>
Tell Them You’re Still Alive2007-05-09T11:36:00+02:002007-05-09T11:36:00+02:00Gertjan Zwartjestag:codemuse.co,2007-05-09:/2007/05/09/tell-them-youre-still-alive<p>Every now and then, I am running an application, and I cannot tell whether it is still doing something useful, or simply deadlocked. I check my <span class="caps">CPU</span> stats, showing 100% load, which indicates the program might be in a deadlock state; to be more precise it might be <a class="reference external" href="http://en.wikipedia.org/wiki/Livelock#Livelock">livelocked</a>. It …</p><p>Every now and then, I am running an application, and I cannot tell whether it is still doing something useful, or simply deadlocked. I check my <span class="caps">CPU</span> stats, showing 100% load, which indicates the program might be in a deadlock state; to be more precise it might be <a class="reference external" href="http://en.wikipedia.org/wiki/Livelock#Livelock">livelocked</a>. It might be <em>really</em> dead if my <span class="caps">CPU</span> is showing 0%. Should I kill it? Or should I leave it running for a while?</p>
<p>I think a good piece of software should always show a user it is still progressing.</p>
<p>So how, as a developer, do you decide for which cases you should show progress and in what way?</p>
<p>In general, I would say, running an application, it should never be executing a task for more than one minute without showing it is still progressing. That way you can easily tell when something <em>might</em> be wrong with the application: if it is running for more than one minute without showing progress.</p>
<p>The obvious way to show progress is by displaying the percentage of work done so far. However, you will need to know beforehand the size of the task. Progress bars can, and are generally used to visualize progress in this case. If a task’s size is unknown beforehand, it is all the more important to show progress; generally a moving element — like an hourglass, or the good old <span class="caps">ASCII</span> spinner — should do the trick.</p>
The Empirical Method2007-05-07T22:11:00+02:002007-05-07T22:11:00+02:00Gertjan Zwartjestag:codemuse.co,2007-05-07:/2007/05/07/the-empirical-method<p><span class="dquo">“</span>How the in the name can this piece of code do what it is supposed to do?! What if I change this line, that must be related to this $#!&^* bug I’m solving…” We all have been in that situation. You are just changing, no, fiddling with the details of …</p><p><span class="dquo">“</span>How the in the name can this piece of code do what it is supposed to do?! What if I change this line, that must be related to this $#!&^* bug I’m solving…” We all have been in that situation. You are just changing, no, fiddling with the details of several obscure lines of code, that magically seem to work. Just to find that segmentation fault that occurs when you press enter twice, put your mouse in the upper left corner of the screen, scratch your nose, get coffee and then try to open a new file. It happens only in those rare circumstances. You can’t make sense of a thing that is happening, you can do no more than moving around code. Adding printf or std::cout statements until you find that one magic change. You can’t even remember what you at all did, but suddenly, after an arbitrary number of mindless changes the crash disappeared. Wow! You must have fixed it! Phew. Quickly check in those changes, close the issue, get another cup of coffee, and do some <em>real</em> work.</p>
<p>Wrong!</p>
<p>It started out quite right. You were debugging to find that crash occurring only in rare circumstances. You are able to reproduce it, and (although sick of all the coffee) you managed to locate those lines of code responsible for the crash.</p>
<p>As obscure as these lines are, you can’t even understand they would work in normal circumstances. There you are, needing a fix for one of the least common situations. “Maybe it is in there,” you think. You change that line. No result. “Let’s try this.” No result. “Hmmm, what will happen if I move…” More crashes. After an hour or so, you think you comprehend at least some of it, because some changes give the results you’d expect.</p>
<p>After a few more hours (and a lot more coffee), you try yet another change, and whew, finally, the crash is gone. That last change didn’t even affect the normal circumstances. “Huh? How could that last change make the crash disappear?”.</p>
<p>Right!</p>
<p>The difference is in the last question you asked yourself. Using trial and error to find a solution for an issue in a system is not a bad thing at all, as long as you find out <em>why</em> and <em>how</em> the solution works, before committing to it. Otherwise, you will leave behind yet a worse mess than the developer(s) before you. Sad to say, I have encountered countless examples.</p>
<p>Every so often, you simply need the solution first, to decipher a fragment of code, and to figure out every inch of what is going wrong. And to get to that, trial and error is a proven method. The moment you know the trick that solves your problem, nine times out of ten it is relatively easy to continue experimenting to truly find out why the trick works. Perhaps you’ll even unravel how the code functioned in the first place, being able to replace those lines with an elegant and consistent solution.</p>
<p>After all, programming isn’t magic.</p>
Brilliance2007-04-23T20:11:00+02:002007-04-23T20:11:00+02:00Gertjan Zwartjestag:codemuse.co,2007-04-23:/2007/04/23/brilliance<p><a class="reference external" href="http://www.amazon.com/exec/obidos/ISBN=0201877120">Michael Jackson</a> magnificently points out a truth about the human factor in software development, entitled “Brilliance.”</p>
<blockquote>
<p>Some years ago I spent a week giving an in-house program design course at a manufacturing company in the mid-west of the United States. On the Friday afternoon it was all over. The <span class="caps">DP …</span></p></blockquote><p><a class="reference external" href="http://www.amazon.com/exec/obidos/ISBN=0201877120">Michael Jackson</a> magnificently points out a truth about the human factor in software development, entitled “Brilliance.”</p>
<blockquote>
<p>Some years ago I spent a week giving an in-house program design course at a manufacturing company in the mid-west of the United States. On the Friday afternoon it was all over. The <span class="caps">DP</span> Manager, who had arranged the course and was paying for it out of his budget, asked me into his office.</p>
<p><span class="dquo">“</span>What do you think?” he asked. He was asking me to tell him my impressions of his operation and his staff. “Pretty good,” I said. “You’ve got some good people there.” Program design courses are hard work; I was very tired; and staff evaluation consultancy is charged extra. Anyway, I knew he really wanted to tell me his own thoughts.</p>
<p><span class="dquo">“</span>What did you think of Fred?” he asked. “We all think Fred’s brilliant.” “He’s very clever,” I said. “He’s not very enthusiastic about methods, but he knows a lot about programming.” “Yes,” said the <span class="caps">DP</span> Manager. He swiveled round in his chair to face a huge flowchart stuck to the wall: about five large sheets of line printer paper, maybe two hundred symbols, hundreds of connecting lines. “Fred did that. It’s the build-up of gross pay for our weekly payroll. No one else except Fred understands it.” His voice dropped to a reverent hush. “Fred tells me that he’s not sure he understands it himself.”</p>
<p><span class="dquo">“</span>Terrific,” I mumbled respectfully. I got the picture clearly. Fred as Frankenstein, Fred the brilliant creator of the uncontrollable monster flowchart. That matched my own impression of Fred very well. “But what about Jane?” I said. “I thought Jane was very good. She picked up the program design ideas very fast.”</p>
<p><span class="dquo">“</span>Yes,” said the <span class="caps">DP</span> Manager. “Jane came to us with a great reputation. We thought she was going to be as brilliant as Fred. But she hasn’t really proved herself yet. We’ve given her a few problems that we thought were going to be really tough, but when she finished it turned out they weren’t really difficult at all. Most of them turned out pretty simple. She hasn’t really proved herself yet — if you see what I mean?”</p>
<p>I saw what he meant.</p>
</blockquote>
<p>I encountered the quote from Jackson’s book (which I unfortunately haven’t read yet) already a while ago. It was around the time I was busy writing my master’s thesis. Funnily I came across the quotation, laying around in a hallway at the <a class="reference external" href="http://www.tue.nl"><span class="caps">TU</span>/e</a>, waiting for my supervisor Prof to arrive.</p>
<p>In my <a class="reference external" href="https://codemuse.co/2007/04/18/simplify-to-understand">previous post</a> I talked about simplicity. That’s why I remembered this little story, and I couldn’t resist to cite it. What I have been describing in “Simplify to Understand” and what Jackson describes in “Brilliance”, is also known as <a class="reference external" href="http://en.wikipedia.org/wiki/KISS_principle"><span class="caps">KISS</span></a>. We should <em>always</em> remember the <span class="caps">KISS</span> principle during software design and development.</p>
<p>And so does Fred: Keep it Simple, Stupid!</p>
Simplify to Understand2007-04-18T21:58:00+02:002007-04-18T21:58:00+02:00Gertjan Zwartjestag:codemuse.co,2007-04-18:/2007/04/18/simplify-to-understand<p>I was reading <a class="reference external" href="http://nl.wikipedia.org/wiki/Daniel_Dennett">Daniel C. Dennet’s</a> excellent <a class="reference external" href="http://www.amazon.com/Darwins-Dangerous-Idea-Evolution-Meanings/dp/068482471X/ref=pd_bbs_sr_1/103-0734124-3625458?ie=UTF8&s=books&qid=1176755391&sr=8-1">book</a> “Darwin’s Dangerous Idea”, when I encountered the following excerpt:</p>
<blockquote>
I think the case is strong that not only do ‘over’-simplified models often actually <em>explain</em> just what needs explaining, but no more complicated model could do the job. When what …</blockquote><p>I was reading <a class="reference external" href="http://nl.wikipedia.org/wiki/Daniel_Dennett">Daniel C. Dennet’s</a> excellent <a class="reference external" href="http://www.amazon.com/Darwins-Dangerous-Idea-Evolution-Meanings/dp/068482471X/ref=pd_bbs_sr_1/103-0734124-3625458?ie=UTF8&s=books&qid=1176755391&sr=8-1">book</a> “Darwin’s Dangerous Idea”, when I encountered the following excerpt:</p>
<blockquote>
I think the case is strong that not only do ‘over’-simplified models often actually <em>explain</em> just what needs explaining, but no more complicated model could do the job. When what provokes our curiosity are the <em>large patterns</em> in phenomena, we need an explanation at the right level.</blockquote>
<p>Before reading Dennet’s statement, I had just finished a bit of text about software architecture. I immediately linked them together; software design is, no, <em>should</em> be such an “over”-simplified model. Precisely doing one thing: explaining the large patterns in a software system.</p>
<p>The source code of a system, in case of software development, is the complicated model. As developers, we all know that source code does not always explain a system that well. When we are coding, we are actually in the trenches. Which is where we usually only think in low-level terms. Variables. Statements. Type-conversions. Compiler-errors. Maybe classes or packages, at best. At that level, it is hard to overview the complete system. As Dennet puts it: “[T]he Key is often discovered when climbing out of the trenches and going for the panoramic view.”</p>
<p>A problem I have seen more than once: developers who are afraid to get out of the trenches. It is the fear of simplification that keeps those developers down there. Besides that, they cannot resist the urge to keep thinking in details. Unimportant details, on the wrong level. Dennet continues:</p>
<blockquote>
If you want to know why traffic jams tend too happen at a certain hour every day, you will still be baffled after you have painstakingly reconstructed the steering, braking, and accelerating processes of the thousands of drivers whose various trajectories have summed to create those traffic jams.</blockquote>
<p>My point here is that the panoramic view, the “over”-simplified model in terms of software development is a system’s design, its architecture. This model should be able to help you understand a system. Without the need to reason about the gritty details of implementation. With all the details of the problem you are solving. However, the panoramic view itself must be kept simple and minimalistic too; we are not <a class="reference external" href="http://www.codinghorror.com/blog/archives/000113.html">Designing the Space Shuttle</a>. That’s the whole other side of the spectrum were you can go wrong: too much design.</p>
<p>Concluding, to really understand a complex system, you need to simplify to get the right level of problem description. You can either dig into the minute details too deeply, or end up with an “over”-complex design. In both cases the <em>real</em> working of the system will be concealed by the wrong details.</p>
<p>Dennet concludes with a calculator as an example, aptly explaining why you need the right level of problem description. Have you ever encountered a piece of software, whereby inspecting the source code you cannot believe how it works? The example shows how the wrong level of problem description miraculously changes the matter of comprehensibility:</p>
<blockquote>
[I]magine tracing all the electrons through a hand calculator as it multiplies two numbers together and gets the correct answer. You could be 100 percent sure you understood each of the millions causal microsteps in the process and yet still be utterly baffled about <em>why</em> or even <em>how</em> it always got the <em>right</em> answer to the questions you posed it. If this is not obvious, imagine that somebody made — as a sort of expensive prank — a hand calculator that usually gave the wrong answers! It would obey exactly the same physical laws as the good calculator, and would cycle through the same sort of microprocesses. You could have <em>perfect</em> explanations of how both calculators worked at the electronic level, and still be utterly unable to explain the intensely interesting fact that one of them got the answers right and the other got them wrong. […] <em>of course</em> you can’t explain all the patters that interest us at the level of physics (or chemistry, or any one low level). This is undeniably true of such mundane and unperplexing phenomena as traffic jams and pocket calculators; we should expect it to be true of biological phenomena as well.</blockquote>
<p>It certainly <em>is</em> true for software systems.</p>
And Yet Another Blog…2007-04-05T22:30:00+02:002007-04-05T22:30:00+02:00Gertjan Zwartjestag:codemuse.co,2007-04-05:/2007/04/05/hello-world<p>As if there aren’t enough blogs already out there on the internet. Still, here is my first post to my own weblog at Code-muse.com. To start, I’ll try to explain why I am starting my new blog.</p>
<p>While I am working, traveling, and sometimes even when I …</p><p>As if there aren’t enough blogs already out there on the internet. Still, here is my first post to my own weblog at Code-muse.com. To start, I’ll try to explain why I am starting my new blog.</p>
<p>While I am working, traveling, and sometimes even when I am sleeping, I can have interesting, clarifying thoughts — at least, for me they are. The last couple of years I have been carrying small notebooks, wrinkled sheets of paper, large notebooks, and more kinds of paper in some or other form, to write down these thoughts as they crossed my mind.</p>
<p>So I decided, why not go digital with these notes? All those notebooks finally get lost anyway. Besides that, they are a real <span class="caps">PITA</span> to search through. Especially for that one topic you are so eager to re-read. That’s when I started evaluating the different options to start making my notes digitally accessible. That would make searching much easier. Moreover, using my notes as a base for a (digital) document would become possible. After several options (considering a Wiki as a viable option too), I ended up looking at blogs. Although being over-popular, I still liked the idea of having a blog. I investigated one piece of blog software further: Wordpress.</p>
<p>Wordpress was mighty easy to install and configure. I had it running in about 10 minutes. Even on my G4 Powerbook, running Mac <span class="caps">OS</span> X. While my Apache, <span class="caps">PHP</span> and MySQL experience was Linux only. I played around with it for a couple of hours. I was fully convinced. The next day I went and bought Code-muse.com, and here you are: my first blog post. Ever.</p>
<p>Diving into the technical details already, even on my first post, haha. Yes, this is supposed to be(come) a technical blog, but I intended to explain why I am starting this blog…</p>
<p>That is, I want to write down my thoughts - mostly thoughts on software design and development related matters. And a good piece of blog software is, after a bit of research I think, <em>the</em> kind software to digitally order your thoughts. As a free bonus, you can share your writings easily. You can even let people comment on them.</p>
<p>Accepting these bonuses, Code-muse.com is my shiny new notebook.</p>