Amazon needs smarter warnings

I had pre-ordered Call of Duty: Black Ops 2 from Amazon a few months ago.  Today, I get an email stating that my credit card that I used to place the order would be expired at the time that the order would be fulfilled.  

It was kind of disturbing, because my credit card that I used expired back in August, but Amazon knew that the Black Ops 2 is released on November 13 and knew when my credit card expires.  Couldn’t they at least notified me back in August?

One good thing that I can say about Amazon is that their customer service is pretty good. They do answer question in a timely manner. 

Bash: Detecting if Script is Sourced

Here is a quick way of detecting if your script is being source as part of a larger script or being executed directly:


#!/bin/sh

[ "$0" = "$(basename $SHELL)" ] && echo "Script is sourced"

And here are some tests:


ralph@goten:bin$ ./sourced.sh
ralph@goten:bin$ bash sourced.sh
ralph@goten:bin$ . sourced.sh
Script is sourced
ralph@goten:bin$ source sourced.sh
Script is sourced
ralph@goten:bin$

MySQL Query Browser in Ubuntu 12.04

I going to outright say it: MySQL Workbench completely sucks. It is a convoluted, complicated, steaming pile of bloated nonsense. It is hard to perform a simple query. Worse, the damn thing keeps crashing. I missed the simplicity of MySQL Query Browser. Yet, Oracle deprecated it a while back and Canonical removed the package in Ubuntu 12.04.

After some searching, I found that Tyler Wagner maintains an APT repository containing MySQL Query Browser ported from Oneiric.

I summarize the installation here:

sudo apt-add-repository 'deb http://www.tolaris.com/apt/ precise main'
wget -q http://www.tolaris.com/apt/tolaris-keyring.gpg -O- | sudo apt-key add -
sudo apt-get update
sudo apt-get install mysql-query-browser

So, a big shout out to Tyler for doing this work!

Edit: You do need to execute sudo apt-get update before install. Thanks, Steve!

libgmp.so missing in Ubuntu 10.04?

When programming Haskell, I usually hack in a GHCi interactive session.  So I was surprise when I tried to make a test executable the other day:

ralph@vegeta:~/src/haskell$ ghc --make Hello
[1 of 1] Compiling Main             ( Hello.hs, Hello.o )
Linking Hello ...
/usr/bin/ld: cannot find -lgmp
collect2: ld returned 1 exit status

libgmp is a library for arbitrary precision arithmetic, which is something Haskell does well. So, I was surprise that I was getting this message. The obvious solution is install the Ubuntu package for libgmp:

ralph@vegeta:~/src/haskell$ sudo apt-get install libgmp3c2
Reading package lists... Done
Building dependency tree       
Reading state information... Done
libgmp3c2 is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 44 not upgraded.

Well that was strange!  So, I searched for libgmp on my system:

ralph@vegeta:~/src/haskell$ find /usr/lib/ -name libgmp*
/usr/lib/ssl/engines/libgmp.so
/usr/lib/libgmp.so.3.5.2
/usr/lib/libgmp.so.3

There is no libgmp.so symlink, so I just created one:

ralph@vegeta:~/src/haskell$ cd /usr/lib 
ralph@vegeta:/usr/lib$ sudo ln -s libgmp.so.3 libgmp.so

Now everything compiles and links:

ralph@vegeta:~/src/haskell$ ghc --make Hello
[1 of 1] Compiling Main             ( Hello.hs, Hello.o )
Linking Hello ...

String Similarity Library

Today, I submitted a new open source project onto Google Code. It is a Java port of a string similarity library that I wrote years ago. The API is a service that calculates a distance or similarity score between two strings. A score of 0.0 means that the two strings are absolutely dissimilar, and 1.0 means that absolutely similar (or equal). Anything in between is a metric on how similar each the two strings are.

Here is a simple example, using the Jaro-Winkler algorithm strategy:


SimilarityStrategy strategy = new JaroWinklerStrategy();
String target = "McDonalds";
String source = "MacMahons";
StringSimilarityService service = new StringSimilarityServiceImpl(strategy);
double score = service.score(source, target); // Score is 0.90

The next step for this project will be documentation and figure out where to host binary releases.

Epic Design Fail

Apple tries very hard to do unique designs, but I think my iPod Shuffle 3rd Generation has a serious flaw. It has no control buttons on the unit itself. The controls are embedded inline with the earbuds. The control has a single button operations where a single-click starts and stops playback, a double-click moves you forward on your playlist, and a triple-click moves you backward on your playlist. While playing a song, a single click-and-hold initiates a Voice-Over feature where the name of your current song is spoken above your song. On a superficial level, it seems so simple and modern. So, why is this necessarily an epic design fail?

Let’s set aside the fact that this Shuffle model requires earbuds with remote functionality. If I lose my earbuds, I would have to buy either a new set of these “special” earbuds, or by an adapter that has the controls. I thought that I can accept this fact, so I was OK with the situation.

Alas, the situation has changed. This morning, I was doing a half-hour cardio program on a treadmill while listening some tunes. After a half-hour, I was working up a good sweat. All of the sudden, the Shuffle starts to tell me the name of my current song and keeps repeating it. Then, it goes into a mode where it starts announcing every song in my current playlist. I thought that the remote control was stuck or something, but it was not it. It got so annoying that I just shut the unit off.

Eventually, I was able to figure out what was going on. Because the control is near the earbuds, the control switch rests at the top of my chest. Since I was doing a lot of cardio, the top of my chest was covered in sweat. The control was swimming in a pool of my sweat and most likely started to short out. I tried different configurations but there is really no good fix. If there was buttons on the unit itself, this would not be an issue.

In most circumstances, we accept a certain level design failures. Our tolerances are very high, especially with electronic devices. The design fail becomes epic when you cannot use said device in normal, practical scenarios. It does not matter if the design looks good, if it is not functional, then its useless.

Lexical Illusion

Occasionally, I have an issue where my grammar is bad. I can’t count how many times this problem when I comment my code. I always thought it was a cut and paste issue or a typo, but how come I could never catch it when proofreading? Then, I realized that my problem may be in my proofreading.

For example, read the following text:

Many readers are not aware that the
the brain will automatically ignore
a second instance of the word “the”
when it starts a new line.

Now read the same text, with the line breaks in different position:

Many readers are not aware that the the
brain will automatically ignore a second
instance of the word “the” when it starts
a new line.

See the problem? This is called a lexical illusion. It is more prominent now than ever because of the use of IM, text messaging, and email. It appears in documents that are written in text editors rather than word processors, because most word processors have grammar correction. When proofreading, people often miss the errors because brains like to process information fast and lazily. When we read from one line to the next, our brain is willing to filter duplicate or redundant words at the beginning of a line. It takes extra concentration to catch the illusion.

Reflecting back, I noticed that it often happens when I shorten or lengthen existing code, rather than creating new comments. So, I have to make extra effort to find when this happens.

Installing clbuild

After frustration with using an older version of sbcl and using asdf-install, I decided to try clbuild.  clbuild is a shell script that allows me to keep my lisp environment updated.  It is a little different from asdf-install, because it does not download tarballs, it gets the source code directly from their respective source code repositories.

So, the first thing I did was to get clbuild itself.  For some reason, I did not have darcs installed, so I had to install that first on my Kubuntu laptop:

~$ sudo apt-get install darcs

After that, use darcs to get clbuild:

~$ darcs get http://common-lisp.net/project/clbuild/clbuild

Make clbuild executable:


~$ cd clbuild
~/clbuild$ chmod +x clbuild

As far as I can tell, you need to run clbuild from this directory. So, the next step is to do a system check:


~/clbuild$ ./clbulid check

Now, time to get an update to sbcl. With my system, sbcl is natively located in my bin directory:


~/clbuild$ which sbcl
/usr/bin/sbcl
~/clbuild$ sbcl --version
SBCL 1.0.18.debian

Now, using clbuild to download and compile the latest version of sbcl:


~/clbuild$ ./clbuild update sbcl
~/clbuild$ ./clbuild compile-implementation sbcl

After a long wait, an sbcl implementation was placed in ~/clbuild/target/bin. To run it, use clbuild again:


~/clbuild$ ./clbuild lisp
This is SBCL 1.0.38.5, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org&gt;.
*

So, clbuild is using the newest version, but my older implementation is still there. Next time, I will set up SLIME with Emacs to point to this new target.

Chromium Tricks for the Lazy Programmer

One of the cool time-saving features in Chromium (better known as Google Chrome) is the custom search engines. It’s not a new concept. Mozilla Firefox has similar capabilities, but it feels like a hassle sometimes. You have to physically select the custom search engine in a separate combo box, then enter your search terms. That takes up extra time with all that mouse action, especially for a lazy programmer like me. Chromium goes on step further. The address box has a secondary function as a search box. If you were to enter anything but a URL or a domain name in the box, Chromium treats it as a search term and uses the default search engine. Google is default on mine, but any search engine that uses HTTP GET query parameters can be used.

If I was not a programmer, I may use my default search engine to do general searching. But, when I want to search programming language documentation, I would normally have to add the programming language name as a search term.  Given that a lot of programming languages have fairly common words as their names (python, ruby, lisp), you may waste some brain cycles filtering.  Again, for a lazy programmer, I want my information correct as well as fast.

So Chromium allows me to create a custom search engine to query a specific web site. In my example, I will be using lispdoc to search Common Lisp documentation. First, you need to go to the site and examine how a query is done. For lispdoc, the query is very similar to Google. However, there is another time-saving feature in Chromium. If you performed a search on the target site, there is a good chance that Chromium has already added a custom search engine for you:

Manage Search Engines

Wicked awesome! For lispdoc, the Chromium recognized that I searched on that site and added an entry for me. I don’t think there was anything special the site did, but you can add a search engine on your own if Chromium did not detect it for some reason.  The only issue that I have with it is the keyword property that Chromium selected. It put the domain name as the keyword, but why is that important?

The keyword is how you tell Chromium that you want to use a custom search engine instead of the default. It’s almost like what you would do if you went to the search engine directly with one important difference. If I entered the keyword (currently “lispdoc.com”) in the address box, space bar, then tab key, Chromium selects the custom search engine matching that keyword:

Using custom search

Then, I can enter more search terms. Unlike Firefox, I do not need to stop typing to tell Chromium what I want. The mouse is not even involved. Perfect for the lazy programmer? Not just yet. Since the keyword defaulted to the domain name (“lispdoc.com”), it has two usability problems.  Since I visited lispdoc.com, the URL shows up in my browsing history and will probably be the first selection. So, a chance a mistake can occur.  The second problem is that the name is too long for a lazy programmer.

The solution to both problems is quite simple: change the keyword to something else.  For lispdoc.com entry, I would change the keyword to “cl” for “Common Lisp”, which makes it less characters, no ambiguity, and easy to remember. Now, I can search documentation very quickly now. I have specific searches for other popular sites and assign them to shorter keywords, also. Here are some examples:

Try it out and let me know what you think!

Trying Pylons

So, I was looking into trying some of the Python web frameworks this past weekend.  I originally started to look into Django and TurboGears, but after seeing nxsy’s comparison, I decided to try Pylons. My initial thought was that all three have similar goals, but have different approaches. A decent Pylons book by James Gardner is available online, too. You can also get the dead tree version at Amazon.

A second reason that I wanted to try Pylons is that there is a well-known, real-world application written using Pylons. I think its a good thing to see how someone else uses a framework that you are evaluating. I may not want to copy their style, but it gives me great insight.