A Java Puzzle

July 23rd, 2008

During the presentation by William Pugh at JavaOne, he mentioned this interesting puzzle

public class Puzzle {
   public static void main(String[] args) {
      Set s = new HashSet();
      for(short i = 0; i < 100; i++) {
         s.add(i);
         s.remove(i-1);
      }
      System.out.println("Size of set = " + s.size());
    }
}

Now the question is, what will the above program print out as size of set? Options are

  1. 1
  2. 100
  3. Throws Exception
  4. None of above

My answer at first was option (1) as we are adding and removing everything except 99. But as this is a puzzle the answer should be different. Here goes the explanation ….

The answer is option (2). The reason is that the statement s.remove(i-1) is operating on integer. This might look strange but in Java 1 is int and even if i is short (i-1) is int. And due to autoboxing (i-1) becomes Integer object. Even though set s takes Short as the type when declared, remove method on an object of Set class takes in an Object and not the generic type. So the result is we are removing an element which isn’t there in the set. So we are just keeping on adding all the 100 elements but removing none. Hence the answer (2).

So to correct the above program to get the expected result i.e., option (1), we need to cast (i-1) to short and then remove from the set.

But the interesting question is how to detect such kind of bugs. There comes the use of FindBugs a static code analyzer which is very slick.

java, programming ,

CapitalOne CreditInform Nightmare!!

July 12th, 2008

Today I decided to replace my CapitalOne credit card with my new Amazon.com Visa (Chase) card for all my day to day spendings due to various benefits. I did not cancel the CapitalOne credit card as it might bring down my credit score. So decided to just stop using and moving all my automatic bill payments to my new card. I decided to stop CreditInform service (a credit-theft protection service provided by CapitalOne) which I was wanting to discontinue long back. But I tell you, cancelling this was real harrasing.

I did some googling and found that lot of people have trouble discontinuing CreditInform.

So I called up CreditInform contact-us (1-866-226-3745) to discontinue the service. To my surprise I had to answer a lot more questions to verify my authenticity to cancel a CreditInform than to get a credit card. They asked me the following

  1. Complete SSN
  2. Date of Birth
  3. First and Last Name
  4. Current Mailing Address
  5. Current and Previous Phone number
  6. Account numbers of 2 accounts (other than CapitalOne) monitored by CreditInform

It was scary and I am not sure if it is required for me to answer all these stuff to an operator. With the above information I am sure there can be an Identity Theft. She was about to ask more questions but I thought this was enough and started asking her the reason why I was asked this much information just for canceling. She kept on pestering me that its for complete verification of my account. But I still cannot understand what other information is required for verification to just cancel a CreditInform service. I believe this is just to discourage and harass customers from canceling the account. Truely I was foolish in the first place to signup for that service when it was free for first 3 months and was billed $9 for this never used feature since 2 years. A classic trap of introductory offers. But I could never believe that it will be so tough to cancel a service especially when they mention that cancelling the service is very easy. Atlast I was able to hear from her after a lot of special offers that the service is discontinued for me. I still doubt that this is taken care of completely as other users in the forums mentioned that their cards are still charged for CreditInform and they had to cancel the credit card to stop it.

So if you are doing the same make sure to take a note of

  1. Confirmation Number
  2. Operator’s Name
  3. Date of cancellation

for your records and make sure that the service is actually cancelled and not charged in the next billing periods (which I still need to monitor)

I strongly discourage any others out there who are using CapitalOne credit card to not fall in this trap. This is just a rip-off and they constantly rob your account month after month and you will not notice. And when you notice and want to get rid off it you are hassled. CapitalOne is a bin NO NO for me in future.

money

Mobile Friendly Metro Bus Trip Planner

June 23rd, 2008

Lately I have been working on developing a metro bus trip planner website which is mobile friendly for Indian Cities. Main goal of this website was to make it mobile friendly.

But soon realized that its pretty challenging especially because of lack of structured data like timetables, schedules, route information available readily as a service. I thought of scrapping the corresponding sites but was still lacking the useful data. However I stuck to my plan and wanted to make use of whatever data I could get. I am just finished with extracting data for Mumbai from here. The information I was able to extract was bus route numbers, station names, route information, fare information for a particular bus between any two stations and distance. There is no accurate way to get bus departure and arrival times from this information. And the data which can be scrapped is limited only to landmarks and does not have all the bus stops. So for now I just wanted to support time independent paths and change overs. I know that this might not be of much use but wanted to prove it instead of guessing it. Lets see whats the outcome is.

So from this project I wanted to see if I can extract some kind of framework for trip planning websites (public transport). I see a major need for this as many people are starting to opt for public transport.

In this process I refreshed some of the graph algorithms (Dijkstra’s, Floyd-Warshall, Strongly Connected, A*, etc). I also stumbled upon some of the research papers on Public Transportation and some existing solutions. So far no road blocks other than lack of data.

For now I am running O(n^3) Floyd-Warshall algorithm to determine All Pairs Shortest Paths. But I am sure I can make lot of optimizations because of the kind of structure. Will dig into this soon and post my findings.

Update: I finished generating all the shortest and cheapest routes between any two landmarks. This process need not be done in real-time based on user input as the routes are same every day and change less often. Now I am collecting data about local trains and need to run the above algorithm again to combine train routes with bus routes. Any suggestions on this are welcome.

rails ,

Migrating to Rails2.1

June 3rd, 2008

Hurrah! Rails-2.1 is out and is too tempting. Its time to jump start the migration. Though my team uses SVN, I use git and connect to svn using git-svn. This provides me an opportunity to try out rails-2.1 on our website fundu.mobi without disrupting the flow. Git makes it so easy to create my own branch on my system and test the latest stuff without fear. And anybody out there who wants to live on edge, must use GIT. This and a few posts after this will focus on my journey to Rails-2.1. To recap new features in Rails-2.1 are mentioned in great detail here. So now lets jump into the process.
Before I begin here are my system details

  • OS: Ubuntu (Hardy)
  • Ruby: 1.8.6
  • Git installed

Freeze Rails-2.0.2

I am still in my master branch. I unpacked Rails-2.0.2 into vendor/rails directory. I should have done it earlier, but better later than never. Luckily we are using VPS (slicehost) so we had control on which version of rails we wanted to run. However to try experimenting with Rails-2.1, I decided it would be better if I remove any dependency on system rails gem. Tested this change out and committed changes to master. To get 2.0.2 from git use the following steps
git clone git://github.com/rails/rails.git vendor/rails
cd vendor/rails
git checkout v2.0.2

Create Branch

Now I created a branch with name rails2.1
git checkout -b rails2.1

Freeze Rails-2.1

Checkout Rails-2.1 tagged version from github
cd vendor/rails
git checkout v2.1.0

Changes to Config

Before doing anything I had to run the following command to update the configuration files to work with 2.1
rake rails:update
I also had to remove the following line from environment/development.rb
config.action_view.cache_template_extensions = false
Now I verified the setup by running ./script/console and checked that there are no errors or warnings in the logs.
Umm lets try to run the server, and there comes my first hurdle! when I try to visit the home page of the app I get

Could not find RubyGem activerecord (&gt;= 1.10.1)
 
/usr/local/lib/site_ruby/1.8/rubygems.rb:523:in `report_activate_error'
/usr/local/lib/site_ruby/1.8/rubygems.rb:131:in `activate'
/usr/local/lib/site_ruby/1.8/rubygems.rb:155:in `activate'
/usr/local/lib/site_ruby/1.8/rubygems.rb:154:in `each'
/usr/local/lib/site_ruby/1.8/rubygems.rb:154:in `activate'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
vendor/rails/activesupport/lib/active_support/dependencies.rb:509:in `require'
vendor/rails/activesupport/lib/active_support/dependencies.rb:354:in `new_constants_in'
vendor/rails/activesupport/lib/active_support/dependencies.rb:509:in `require'
app/controllers/welcome_controller.rb:1
/usr/bin/thin:19:in `load'
/usr/bin/thin:19
 
This error occurred while loading the following files:
feed_tools

Seems like the above error was because of some strange dependency of AR in feed_tools. I unpacked feed_tools to vendor directory and somehow the error was no more. More investigation on this later, lets move on.

That’s about it, website is running as before.

rails

Case for E-Books on Programming Languages

May 28th, 2008

I am a big fan of books, blogs, screencasts and articles which are related to computer programming and software design. I spend almost 90% of my productive time with computers that are connected to internet.

I have noticed that buying e-books is the right way for me. This can be attributed to my way of living on the edge and the volatile nature of the latest programming languages. E-books provide an easy way to upgrade the book and not to mention greatly reduce the usage of paper (so eco friendly ;)). I know purists will hate to give up the paper book but I am not a purist.

I have recently bought couple of rails books, pickaxe (Ruby) book and Erlang book from The Pragmatic Programmers and have been very satisfied. I get regular email alerts whenever there is an update or new version of the above books and its very easy to get hold of the new copy for no extra charge. However, I am not sure whats the deal with other e-book sellers.

Other than the above there are plenty of other uses like, hyperlinked resources/references which are just a click away from the book, one can copy/paste the sample code instead of laboriously typing the same stuff, no need to context switch between computer and book, no need to switch between keyboard/mouse and pen/pencil, easy to take notes, easy to share snippets of books with friends and many more.

E-books are also advantageous to authors as they can bring the social networking aspect in editing of book. This is suitable in computer programming related books which would require lot of useful code snippets and examples. There are many people who want to contribute for this cause but are not ready to write a book! One of the recent experiences, where e-book might be the only way to go was Rails Recipes by Chad Fowler, this book as the title says is destined to constantly evolve and its not desirable for the reader to buy a copy of this book with each new recipe added or get a seperate addendum for each revision. With e-books its just a click away.

I am sure there are many out there who would want to adopt e-books. So a clear indication of when to buy an e-book (I would say always but …) is if you know or feel that a book will have more revisions in near future.

programming

Selenium RC with .Net 3.0

May 27th, 2008

Seems like a sidetrack from my work. I was helping out my wife in setting up Selenium-RC with C# client driver. However the documentation assumes everyone is using .Net 2.0. So I wanted to share what I have done to achieve the same with C# 3.0. Here are the steps,

Requirements

  1. JDK 1.5, to run selenium rc server
  2. Visual Studio 2008 (obviously)
  3. Selenium RC, and
  4. Nunit

Steps

  1. Create a sample C# class library, say SeleniumSample
  2. Change the build target framework to .Net 2.0. To do that go to Project > SeleniumSample Properties and select .Net Framework 2.0 under Target Framework drop down
  3. Remove the non .Net Framework 2.0 references, namely Linq etc.
  4. Clean and Rebuild the solution, fix the using errors
  5. Add the following class (GoogleTest) to test selenium
    using System;
    using NUnit.Framework;
    using Selenium;
     
    namespace SeleniumSample
    {
        [TestFixture]
    	public class GoogleTest
    	{
    		private ISelenium selenium;
     
    		[SetUp]
    		public void SetupTest()
    		{
    			selenium = new DefaultSelenium("localhost", 4444, "*iexplore", "http://www.google.com");
    			selenium.Start();
    		}
     
    		[TearDown]
    		public void TeardownTest()
    		{
    			selenium.Stop();
    		}
     
    		[Test]
    		public void GoogleSearch()
    		{
    			selenium.Open("http://www.google.com/webhp");
    			Assert.AreEqual("Google", selenium.GetTitle());
    			selenium.Type("q", "Selenium OpenQA");
    			Assert.AreEqual("Selenium OpenQA", selenium.GetValue("q"));
    			selenium.Click("btnG");
    			selenium.WaitForPageToLoad("5000");
    			Assert.IsTrue(selenium.IsTextPresent("www.openqa.org"));
    			Assert.AreEqual("Selenium OpenQA - Google Search", selenium.GetTitle());
    		}
    	}
    }
  6. Rebuild the solution
  7. Now open Nunit-Gui, Program Files > Nunit X.Y.Z > Nunit Gui (.Net 2.0)
  8. Do File > Open Project and select the SeleniumSample.dll which should be in projects bin directory
  9. Now you should see the test class GoogleTest with GoogleSearch test case under it.
  10. Open an command window and cd to directory where you downloaded and extracted selenium rc
  11. cd to selenium-server-1.0-beta-1
  12. run java -jar selenium-server.jar, check that the server is running and listening on port 4444
  13. Now back to Nunit-GUI, start the tests by clicking on run. This should launch internet explorer and run the steps/checks mentioned in the above code
  14. Feel free to add more test cases and then back in Nunit-gui do File > Reload Project and re-run the tests

Happy Testing

.net, testing

Serializing Objects in Ruby

May 24th, 2008

Simple object serialization in ruby can be done using two core ruby modules Marshal and Base64. Here is how its done

Marshalizer.rb


class Marshalizer
  def self.dump(obj)
    return Base64.encode64(Marshal.dump(obj))
  end

  def self.load(str)
    return Marshal.load(Base64.decode64(str))
  end
end

Sample Usage


class SampleObj
  attr_accessor :title, :description
end

class MarshalizerTest < Test::Unit::TestCase
  def test_serialization
    article = SampleObj.new
    article.description = "Test name"
    article.title = "Test title with 's"
    serialzied_article = Marshalizer.dump(article)
    assert_not_nil serialzied_article, "serialized article should not be nil"
    puts serialzied_article
    new_article = Marshalizer.load(serialzied_article)
    assert new_article
    puts new_article.inspect
    assert_not_nil new_article, "loaded article should not be nil"
    assert_instance_of SampleObj, new_article, "new_article should be of type article"
    assert_equal(article.title, new_article.title)
  end
end

ruby

Ruby Mobile Browser Detector (port of JMBD)

May 24th, 2008

I have successfully ported Java Mobile Browser Detector to ruby. I am sure there are other existing utilities to achieve this but I found this to more simpler to understand and use. It works well with my mobile site Fundu.mobi developed on rails. I though it would be useful for someone so here is the code rmbd.zip.

Here is how you can use it in any controller


class SampleController < ApplicationController
    def index
      device_config = DeviceConfigDetector.detect_capabilities_for_request(request);
      logger.debug("device config = #{device_config.inspect}")
    end
end

ruby ,

Emergent Design

May 23rd, 2008

Today I happened to attend a talk by Scott Bain, author of Emergent Design: The Evolutionary Nature of Professional Software Development . And incidentally today is my first day blogging. So I took the liberty of using the theme of book as concept of my blog.

Talk was mostly based on principles and practices which any sane developer would atleast try to follow. But the emphasis of the talk was to summarize the above book and give some concise examples on how to achieve the result in a much easier way. I felt the concepts a bit natural for me now because of my slow transition into ROR (a.k.a Ruby on Rails) which you would see my future posts will mostly focus on. ROR drives developers to follow the famous (or infamous with merb lurking around) Convention over Configuration. This means all the developers using rails follow similar practices making the process of sharing knowledge easier. And not to mention hacking around a code, expecting a particular behavior from the code and many more. Just to reiterate rails has done an excellent job in establishing concrete practices, thanks to DHH and rails core for this.

Coming back to the talk, the entire message was focussed on following Open-Closed Principle of design. This according to the author can be achieved by following,

  1. Pattern-Oriented software development: This does not mean complicating code by designing it exactly to the pattern but to understand why the pattern was created in first place.
  2. Test Driven Development (TDD): All folks should know about this by now. To learn more go here.

Though the talk sounded to me somewhat mundane, I am excited to know how deep the book goes and how it would change my perspective. But before I buy I would love some reviews ;). So the lesson I learn is follow patterns to the extent they need to be followed, follow TDD in a more disciplined way and constantly evolve code. As Scott mentioned this can be done by following some simple steps like,

  1. Refactoring code to fit good practices and not change existing behavior (am I defining Refactoring here?)
  2. Add documentation
  3. Change method/variable names to intended meaningful name

Software Design ,