Entries Tagged 'Technology' ↓

iPad vs Kindle vs Wood pulp

This passage I came across recently in Yeats Is Dead, struck a chord:

“I think books are wonderful”, the woman said, evidently bent on conversation. “If they had never been invented and somebody thought of them now, they would be the greatest thing ever. I can’t think of anything that has given so much happiness to humanity. Or could do, except maybe a pill to make us live longer. Books are so simple. No batteries, no wires, no earphones. Absolutely silent, don’t interfere with anything else, you can take them anywhere with you, into bed, into the bath. And they can’t be broken. You can lie on them, sit on them, prop the door or the window sash open with them and you still can’t damage them.”

Add the ability to buy them second hand, and this is precisely why I think books will win. Nothing comes remotely close to the simplicity of a book.

Two Worlds

The media’s portrayal of the iPhone App Store in the US has been all about the triumph of the individual developer: how your regular Joe moonlighted on an iPhone app and found himself richer by a few thousand dollars. For example, see this Wired article.

I saw a similar attempt in India by Mint recently, and here it is all about how software outsourcing companies keep a steady trickle of revenue alive amidst the downturn – thanks to the iPhone App Store. The focus is not the individual but the organization. It’s about software factories. It makes me sick.

The article is here. Don’t miss a certain Mr. Palak Biswas posing with his prized possession.

The problem of unreadable CAPTCHAs

A CAPTCHA is usually a severely contorted image of random characters that you are supposed to key in correctly to be able to get into a website. The idea is to thwart automated scripts/programs – the sort of stuff that spammers (among other bad guys) use to create hundreds of fake accounts for spamming. Now as optical character recognition (OCR) becomes sophisticated a simple image or one that is not significantly distorted, does not present a sufficient challenge to an OCR program. As a result we are seeing increasingly more distorted/noisy CAPTCHAs that are beginning to push the limits of even human readability – like the one below from Yahoo India’s e-mail sign-up page:

Yahoo Captcha

And then there are CAPTCHAs that just want to mock you, like the one blogger so affectionately threw at me this morning:

Blogger Captcha aka 'Visual Verification'

Since CAPTCHAs cannot be read by screen readers, a lot of sites also include an audio version of the CAPTCHA. I hadn’t heard one till recently (I happened to click on the accessibility icon accidentally), but what I heard was stuff of nightmares! Turn down your speakers a bit this stuff is not pleasant:

Obviously, the intent here is to stop sound recognition programs in their tracks by introducing a lot of background noise. The overall effect however brings images of prisons, misery and torture to one’s mind. (Or may be I watched one war movie too many this year!)

And then there is this minor matter of spammers with an army of CAPTCHA cracking humans at their disposal. Or may be that explains why CAPTCHAs are becoming increasingly painful even for legitimate users.

Programming For The Mac: Learning To Crawl

It’s been close to 9 months since I picked my 24″ iMac. Despite the initial scare (yes it was bizarre!), things have turned out to be great. Being a dyed-in-the-wool Windows user, I did tinker with Windows Vista inside Bootcamp but there was something alluring about Leopard (aka Mac OS 10.5) which kept pulling me back. Having mastered the OS for daily tasks, and having overcome the muscle memory of 8+12+ (I am older than I thought) years of Windows usage (from Windows 3.11 all the way to Windows Vista), I decided to tackle the next frontier – developing for the Mac.

After several attempts at using cross-platform frameworks (wxWidgets, Mono, GTK) with unsatisfactory results, I started exploring the native Mac development platform. The biggest hurdle here was Objective C. For someone who is coming from a C#/VB.NET/C++ background (with good exposure to PERL/Javascript thrown in), the syntax stumped me. Then I came across Aaron Hillegass’s brilliant Cocoa Programming book some 3 weeks ago, and it has been a smooth sailing ever since. It reminds me so much of my days in college spent learning Win32 and MFC programming.

Today I came up with a small app which I thought I’d share. This builds on the SpeakLine example presented in Aaron’s book. Instead of using a Text Field to take a string from the user, it uses the sample text which comes with each voice profile on the Mac, and says it when you click the Speak button:

My first native Mac app!

The sample text for a lot of voices is hilarious (just like the voices themselves). It is one of the many small things that add up towards making Macs a fun, playful platform.

p.s. The app, the complete XCode 3.1 project.

Moonlight On Ubuntu 7.04

I recently had to install Moonlight (Silverlight on Linux) on Ubuntu 7.04. The Moonlight plug-in for Firefox is not available as a binary package and needs to be compiled from source. Moonlight has dependencies on Mono. The instructions on the Moonlight project page are not sufficient for a casual Linux user like me. Fortunately, this thread at the mono-olive group came to my rescue (thanks Chris!). I am reproducing its contents with minor changes and slightly more detailed instructions:

The instructions assume that you have a clean installation of Ubuntu 7.04 up and running on your machine. Fire up Terminal. First we’ll update the Ubuntu package list and install Subversion on our machine. The commands to accomplish this require admin privileges and we’ll be using sudo to execute them. Unlike a lot of other Linux distributions, Ubuntu doesn’t prompt you to create a root account during installation. When sudo prompts you for a password, just key-in the password of the account that you’ve used for logging into your current session.

sudo apt-get update
sudo apt-get install subversion

If you are attempting this at work, chances are you are behind a proxy. In which case apt-get will give you errors. Use the following command to indicate your proxy server and type the above commands again.

export http_proxy=http://YourProxyName:Port
sudo apt-get update
sudo apt-get install subversion

We’ll now create a folder for Mono source and pull down the required bits.

mkdir mono
cd mono
svn co svn://anonsvn.mono-project.com/source/trunk/mcs
svn co svn://anonsvn.mono-project.com/source/trunk/mono
svn co svn://anonsvn.mono-project.com/source/trunk/gtk-sharp
svn co svn://anonsvn.mono-project.com/source/trunk/gnome-sharp
svn co svn://anonsvn.mono-project.com/source/trunk/olive
svn co svn://anonsvn.mono-project.com/source/trunk/moon
svn co svn://anonsvn.mono-project.com/source/trunk/monodoc

Again, if you are behind a proxy, things will need to be done a little differently. The above commands would have given you errors. Go to the .subversion folder under your home directory open the file called “servers”.

cd ~/.subversion
vi servers

If you are from the Windows world and don’t know how to use vi, use gedit:

gedit servers

Scroll down to the end of the file, and add the following lines. Save and exit your text editor.

http-proxy-host  = sinproxy
http-proxy-port =  80

We’ll also need to re-run the svn commands. Notice that this time we’ll use the http:// prefix instead of svn://.

svn co http://anonsvn.mono-project.com/source/trunk/mcs
svn co http://anonsvn.mono-project.com/source/trunk/mono
svn co http://anonsvn.mono-project.com/source/trunk/gtk-sharp
svn co http://anonsvn.mono-project.com/source/trunk/gnome-sharp
svn co http://anonsvn.mono-project.com/source/trunk/olive
svn co http://anonsvn.mono-project.com/source/trunk/moon
svn co http://anonsvn.mono-project.com/source/trunk/monodoc

We’ll use apt-get again to install dependencies and tools required to build Mono and Moonlight.

sudo apt-get install libavcodec0d libavformat0d libgtk2.0-dev libnspr-dev firefox-dev libavcodec-dev libavformat-dev libasound2-dev librsvg2-dev
sudo apt-get install autoconf automake libtool build-essential bison

One of the dependencies required for Moonlight to build (libswscale-dev), is not available for Ubuntu 7.04 but is available from the upcoming 7.10 release. We’ll use a tool called prevu to backport the package’s 7.10 version to our present 7.04 installaiton. First, we’ll need to install prevu itself.

sudo apt-get install prevu

Next we setup the prevu environment. This step requires a few hundred megs of space under /var, and takes a while to finish.

sudo prevu-init

We now need to instruct prevu to pick the libswscale-dev package from the 7.10 repositories. Go to /etc/apt and edit the sources.list file.

cd /etc/apt
sudo vi sources.list

Add the following line right at the end of this file and save it.

deb-src http://us.archive.ubuntu.com/ubuntu gutsy main universe restricted multiverse

Next, we retrieve and build libswscale-dev.

sudo apt-get update
prevu libswscale-dev

The step above will again take a while to finish. If all goes well, you’ll have a bunch of .deb packages under /var/cache/prevu/feisty-debs that can be installed. Ignore any errors/warnings about being unable to install ffmpeg.

cd /var/cache/prevu/feisty-debs
sudo dpkg -i *.deb

We are a step or two short of being able to build Mono and Moonlight. To build Mono we need a working copy of the Mono runtime and the Mono C# compiler (mcs).

cd ~
sudo apt-get install mono-mcs

You might get some errors in the step above about missing dependencies. The following command should install the dependencies.

sudo apt-get -f install
sudo apt-get install mono-mcs

We also need to patch the Mono source for Moonlight to work. Browse to: http://tirania.org/tmp/mono-delegate-appdomain-patch using Firefox, select everything and save it to a text file (call it mono-delegate-appdomain-patch) in the mono/mono/mono under your home directory. In case you are wondering about the three mono folders – the first one was created by you, the second one got created when you retrieved the mono branch using svn and the third one came along with the mono source. Let’s switch back to the terminal window and apply the patch that we just saved.

cd ~/mono/mono/mono
patch -p0 < mono-delegate-appdomain-patch
cd ..

We are now ready to build Mono and co.

./autogen.sh --prefix=/usr --with-moonlight=yes
make
sudo apt-get remove mono-mcs
sudo apt-get autoremove
sudo make install
cd ../olive
./configure --prefix=/usr
make
sudo make install
cd gtk-sharp
./boostrap-2.10 --prefix=/usr
make
sudo make install
cd ../monodoc
./autogen.sh --prefix=/usr
make
make install
cd ../gnome-sharp
./bootstrap-2.16 --prefix=/usr
make
sudo make install
cd ../moon
./autogen.sh --prefix=/usr
make
sudo make install

This builds Mono and the Moonlight Firefox plug-in. We install it as follows.

sudo cp *.so moonlight.exe /usr/lib/mozilla-firefox/plugins
sudo ln -s /usr/lib/mono /usr/lib/mono/3.0

Launch Firefox and type about:plugins into the address bar. The Moonlight plugin will be listed on top (on my build it was called Silverlight). Visit any of the samples at the Silverlight website to check your installation or take the Silverlight Airlines demo for a spin!

Cleaning Hard Disks

I’ve been exceptionally unlucky with hard disks over last few days – to the point that I was beginning to wonder if I was exuding some kind of magnetic force field. Fortunately, the latest replacement from Toshiba seems to be doing fine and looks like the hard-disk I had on loan from an old PC will have to go back.

I was looking for ways to wipe data off the old disk beyond just formatting it, when I stumbled upon DiskPart’s clean command. Here is how you’ll do it (assuming the disk you are trying to clean is #1).

C:\>DiskPart

DISKPART> select disk 1

Disk 1 is now the selected disk.

DISKPART> list partition

  Partition ###  Type              Size     Offset
  -------------  ----------------  -------  -------
* Partition 1    Primary            241 MB      0 B

DISKPART> clean all

DiskPart succeeded in cleaning the disk.

Firstly DiskPart always assumes you know what you are doing. It will not prompt you for confirmations. Unlike some of the other disk management tools (linux’s fdisk comes to mind), there is no “commit phase” where you write the changes you made to the disk. All changes are made live to the disk. Be extremely careful with this tool.

This technique works for external disks as well as for memory cards/sticks. In fact the output above is from an actual session with my 256 MB SD card connected via a USB card reader.

The list partition command has nothing to do with disk clean-up. It is merely a way to make sure that I have the correct disk selected.

The clean command simply zeros out the master boot record, while clean all zeros out every sector on the disk.

Surely a tool as powerful as this deserves a KB, and gets one too!.

If you need more rigorous cleaning than what DiskPart gives, you’ll need to look at external tools such as PDWipe.

Type Conversion And WPF Data Binding

In my last post we saw, that though it is possible to bind to a bound property, some implicit type conversions might occur. We can however create a custom type converter and bring a little more predictability into the way the type conversions happen.

We start by creating a class that implements the IValueConverter interface (found in System.Windows.Data). As part of the implementation we define two methods Convert – which is responsible for converting the source data type to destination data type and ConvertBack which is its antithesis. In the context of our example from the last post, Convert will take a SolidColorBrush and give us a String (the proper name of a color rather than its hex value). ConvertBack will do the reverse – the implementation being left as an exercise for the reader :-) .

Here is what the code looks like:

using System;
using System.Windows.Media;
using System.Windows.Data;
using System.Globalization;


namespace TypeConversion
{
  class ColorToStringConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      if (null != value)
      {
        System.Windows.Media.Color MColor;
        MColor = ((SolidColorBrush)value).Color;


        switch(MColor.ToString().ToLower())
        {
          case “#ffff0000″:
           return “Red”;
          case “#ff00ff00″:
           return “Lime”;
          case “#ff008000″:
           return “Green”;
          case “#ff0000ff”:
           return “Blue”;
          default:
           return MColor.ToString();
        }
      }
      else
      {
        return “bad color”;
      }
    }


    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
      throw new NotSupportedException();
    }
  }
}

The code for conversion is a little inelegant for my taste. I wish there was a better way of doing this. I tried converting System.Windows.Media.Color to System.Drawing.Color and then using System.Drawing.Color.ToKnownColor(). Sadly, that works only if System.Drawing.Color was initialized using a System.Drawing.KnownColor enumeration member in the first place. One could build a look-up table to find the English name of a color given its Hex value but I didn’t bother.

Now in order to use this class we need to make some modifications to our XAML code:

<Page xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
xmlns:local=”clr-namespace:TypeConversion”
HorizontalAlignment=”Center”
VerticalAlignment=”Center”>
    <Page.Resources>
        <Local.ColorToStringConverter x:Key=”TheConverter”>
    </Page.Resources>

    <StackPanel Width=”400″>
        <TextBox x:Name=”txtColor” BorderBrush=”Black” Text=”Type a color” Margin=”2,2,2,2″/>
        <Rectangle x:Name=”rectColor” Height=”100″ Fill=”{Binding ElementName=txtColor, Path=Text, Mode=OneWay}” Margin=”2,2,2,2″ Stroke=”Silver”/>
        <TextBox x:Name=”txtTextColor” BorderBrush=”Black” Text=”{Binding ElementName=rectColor, Path=Fill, Mode=OneWay, Converter={StaticResource TheConverter}}” Margin=”2,2,2,2″/>
    </StackPanel>
</Page>

Basically, we first instantiate our type converter class as a static resource and then refer to it as part of the binding expression. You’ll also need to compile this XAML and the converter class into either an XBAP or a windows application. I have uploaded the pre-built XBAP which you can run now (IE only) or download the Visual Studio project and play with it.

Binding To A Bound Property

During my WPF DataBinding sessions at TechMela, one of the attendees asked me if it was possible to have a property of a control bound to a property of another control which is already bound. It is indeed possible. Let us start with the following scenario:

<Page xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
HorizontalAlignment=”Center”
VerticalAlignment=”Center”>
    <StackPanel Width=”400″>
        <TextBox x:Name=”txtColor” BorderBrush=”Black” Text=”Type a color” Margin=”2,2,2,2″/>
        <Rectangle x:Name=”rectColor” Height=”100″ Fill=”{Binding ElementName=txtColor, Path=Text, Mode=OneWay}” Margin=”2,2,2,2″ Stroke=”Silver”/>

    </StackPanel>
</Page>

Our UI consists of a TextBox and a Rectangle. The Rectangle’s Fill property is bound to the TextBox’s Text property. Each time you type a valid color name in the TextBox, the color of the Rectangle changes to it. Typing Blue in the TextBox will get you a Blue Rectangle (it would work for any color defined in System.Windows.Media.Colors class). This is what you get when you paste the code above in XamlPad and type in Maroon into the TextBox:

TextBox + Rectangle in XamlPad

If you are running Windows Vista or have .NET Framework 3.0 installed on Windows XP/Windows Server 2003, you can directly run the XAML in your browser:

Stage I: Basic UI with a TextBox and a Rectangle

This works because behind the scenes the Text property (a string) is being automatically converted to a SolidColorBrush (which is what the Rectangle’s Fill property is). In fact, if you are debugging this in Visual Studio, you’ll see Exceptions in the Output window for every character you type that results in an invalid color. For instance, while you are typing Blue, you’ll get 3 exceptions (B, Bl, Blu are all invalid color names):

System.Windows.Data Error: 6 : ‘TargetDefaultValueConverter’ converter failed to convert value ‘B’ (type ‘String’); fallback value will be used, if available. BindingExpression:Path=Text; DataItem=’TextBox’ (Name=’txtColor’); target element is ‘Rectangle’ (Name=’rectColor’); target property is ‘Fill’ (type ‘Brush’) FormatException:’System.FormatException: Token is not valid.
at MS.Internal.Parsers.ParseBrush(String brush, IFormatProvider formatProvider, ITypeDescriptorContext context)



and so on for Bl and Blu…

It is this very type conversion infrastructure that supports XAML; allowing us to transparently assign the name of a color (a string) to the Rectangle tag’s Fill attribute.

We’ll now introduce another TextBox into our UI. The new TextBox’s Text property is going to be bound to the Rectangle’s Fill property (which we’ve already bound to another TextBox in the last example). Here is how the updated code will look like:

<Page xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
HorizontalAlignment=”Center”
VerticalAlignment=”Center”>
    <StackPanel Width=”400″>
        <TextBox x:Name=”txtColor” BorderBrush=”Black” Text=”Type a color” Margin=”2,2,2,2″/>
        <Rectangle x:Name=”rectColor” Height=”100″ Fill=”{Binding ElementName=txtColor, Path=Text, Mode=OneWay}” Margin=”2,2,2,2″ Stroke=”Silver”/>
        <TextBox x:Name=”txtTextColor” BorderBrush=”Black” Text=”{Binding ElementName=rectColor, Path=Fill, Mode=OneWay}” Margin=”2,2,2,2″/>
    </StackPanel>
</Page>

And this is how the things look like now in XamlPad:

TextBox + Rectangle in XamlPad

Again, if you have .NET Framework 3.0 installed, let us run the app first before moving on:

Stage II: TextBox with its Text property bound to the Rectangle’s Fill property

When you type the name of a color into the first TextBox (txtColor) now, you’ll see that the Text property of the TextBox we’ve just introduced (txtTextColor), updates automatically. However, you will not see it set to the same text that you’ve entered into txtColor. Instead you’ll see the color represented as hexadecimal. This is because txtTextColor’s property is bound to the Rectangle’s Fill property. The text entered into txtColor has been automatically converted to a SolidColorBrush in order to be able to bind to the Fill property. When you try to convert a SolidColorBrush back to a string to bind to txtTextColor’s Text property you don’t get the same “English” color name that you entered.

Moral of the story – by the time data cascades down to its final destination it might undergo type conversion(s). Of course the caveat is applicable only when a binding exists between incompatible types. In my next post, we’ll take this type conversion business into our own hand and try to restore the “fidelity” of a Text → SolidColorBrush → Text conversion using our custom IValueConverter class.

ASP.NET Stripping Accented Characters?

A friend who runs shortext.com pinged me with an interesting question one evening. People posting messages to his website via a Firefox plugin that he had written for twitter, were reporting that all accented characters in their posts (like éåüç), were being stripped out. For instance, each time someone posted café, all that came through was caf. I asked him for the problematic querystring/post data and here is what it looked like (server name changed to localhost):

http://localhost/default.aspx?message=caf%E9

Doing a Response.Write(Request.QueryString["message"]); got us:

caf

(Page’s encoding set to utf8, ASP.NET 2.0, IIS 6 on Windows Server 2003).

The result was consistent across all browsers.

Response.Write(Request.RawUrl);

got us:

/wwwroot/Default.aspx?message=caf%E9

Obviously, the browser was letting the querystring untouched. It was the ASP.NET infrastructure that was intervening while parsing the querystring.How about Server.UrlDecode, we thought. This is what we got:

Response.Write(Server.UrlDecode(Request.RawUrl));

/wwwroot/Default.aspx?message=caf

Time for some extreme measures. We added a reference to Microsoft.JScript and used

Response.Write(Microsoft.JScript.GlobalObject.unescape(Request.RawUrl)); which got us:

/wwwroot/Default.aspx?message=café

While this solved the problem, it meant that we would need to parse the QueryString by hand. And I had a nagging feeling that we were solving the wrong problem here. It then dawned on me that our URL was not encoded as utf8! Every character other than the first 128 ASCII characters takes up at least two bytes when encoded to utf8. Our é was encoded to E9, which is just one byte (or rather is 00E9 – Unicode but not utf8 encoded).

The next logical thing was to find out how we got this URL in the first place. It so happens, that we were using Javascript’s escape() method on the client to encode our URL. Changing that to encodeURIComponent gave us caf%C3%A9.

http://localhost/default.aspx?message=caf%C3%A9

Doing a Response.Write(Request.QueryString["message"]); now got us:

café

and all was well again with our world. Moral of the story, if you find that ASP.NET is stripping accented characters from your querystring, check that your data is encoded correctly as UTF8.

Server.XmlEncode?

While looking for Server.XmlEncode (there is none as of ASP.NET 2.0) , I came across the Microsoft Anti Cross-Site Scripting Library. The library also has two other interesting methods – JavaScriptEncode and VisualBasicScriptEncode, besides different implementations of UrlEncode and HtmlEncode. Now if only they would add a SqlEncode…