Tatva-Artha

meaning of "it"

Setting up Motorola S9 Bluetooth headset with Trendnet TBW-105UB Bluetooth USB adapter on ubuntu

without comments

On our current ruby/rails project, we have a distributed team and remote pairing is a daily chore. I recently bought iPhone and Motorola S9 bluetooth headset to listen to music and radio. I decided to get wireless headset working with my ubuntu laptop to help with remote pairing. After looking up which USB adapter work with Ubuntu, I decided to buy Trendnet TBW-105UB.

As mentioned on wiki, the USB adapter installed out of the box, without installing any driver and apt-get packages on my Karmic Koala (Ubuntu version 9.04). The bluetooth icon showed in my taskbar and it offered option to add new device. The GUI wizard searched for other bluetooth devices but couldn’t locate my S9 headset. After a few trial, I realized that I was making a few mistakes.

  • The S9 is in pairing mode only for a few seconds when turned on. So, I couldn’t get it to pair if the headset is already on. I had to turn it off and then on while the Ubuntu bluetooth software is searching for device.
  • The other mistake I was making was having iPhone bluetooth ON. The headset was already configured to pair with iPhone so as soon as it found iPhone, it would stop and not pair with ubuntu box. I had to turn off the bluetooth on iPhone so that headset would not find anything else before ubuntu.

Once I did this, ubuntu was able to find headset. But then it failed to pair successfully, probably because the 4-digit pin didn’t apply properly. I tried again and this time, I selected the specific pairing digits of “0000″ for headset. That worked and it paired successfully.

Now, I started an audio stream on my ubuntu laptop and guess what. No, it would still use my laptop speaker phone. I was close but not there yet.

I opened up the “Sound” Preferences dialog from “System” menu. There I found option to switch from default microphone and speaker to motorola headset. Once I switched both, it all worked.

Happy pairing!

Written by Sharad

December 24th, 2009 at 8:20 pm

Posted in All

How to diff git changes

without comments

git diff [commit_old]..[commit_new]
# where commit_old and commit_new are first 6 characters of git commit SHA ID

If you need to diff with current head, its even easier:

git diff [commit_old]

Written by Sharad

December 11th, 2009 at 12:08 am

Posted in All

Upgrading Ubuntu: from 9.04 to 9.10

without comments

So, after ignoring the new upgrade in my update-manager for several months, I finally decided to upgrade today.

I don’t remember any major headaches when upgrading from v8.10 to 9.04 except for a few config files (mysql’s my.cnf) being changed. However, this time it wasn’t as smooth.

The total time it took to download and install upgrade was around 2.5-3 hours. On the upside, it did upgrade my netbeans version automatically from 6.5 to 6.7, which I meant to do one of these days. However, the default version of Netbeans didn’t have ruby plugin in it. So, I had to patch that manually and install other plugins that aren’t default in netbeans (e.g. haml).

Mysql upgrade wasn’t as smooth. The server didn’t install properly and won’t start. It was time to roll up sleeves and get to work (should’ve planned timing properly!)

# try starting daemon
$ sudo /etc/init.d/mysql start
# won't start, time to tail daemon log
$ tail -f /var/log/daemon.log
# found that /var/run/mysqld folder is missing

After some googling, found that this is an issue with v9.10 upgrade. References here and here. The workarounds mentioned in these bug-reports didn’t work for me. I had to uninstall and install mysql-server.

$ sudo apt-get remove mysql-server
$ sudo apt-get install mysql-server
# try restarting server
$ sudo /etc/init.d/mysql start

Lucky me, re-installing mysql-server doesn’t delete any existing databases and those database files work with new version of mysql-server.

Lesson Learnt: Upgrade only when you have 4-6 hours of spare time in hand.

Initial impression about the upgrade is mixed. I am happy that I am “current”, however not sure what else it out there broken waiting to eat a few more hours. Also, I do miss the old color theme over new one. I should get used to new theme with time though.

Written by Sharad

November 27th, 2009 at 10:04 am

Posted in All

Manipulating image using RMagick

without comments

An example of manipulating image using RMagick

require 'RMagick'
image = Magick::Image.read("original.jpeg").first
image.change_geometry("100x100") do |c,r,i|
  i.resize!(c,r)
  i.write 'out.jpeg'
end

Written by Sharad

November 14th, 2009 at 5:41 am

Posted in All

Installing rmagick on Ubuntu 9.04 – Jaunty Jackalope

without comments

Most help that turn up on google with installing rmagick on linux/ubuntu suggest installing following packages:

$ sudo apt-get install ruby rubygems irb ri rdoc ruby1.8-dev build-essential imagemagick libmagick9 libmagick9-dev
$

On my Ubuntu 9.04, it couldn’t find libmagick9-dev. I got following error:

$ sudo apt-get install libmagick9-dev
[sudo] password for sjain: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package libmagick9-dev is a virtual package provided by:
  libmagickwand-dev 7:6.4.5.4.dfsg1-1ubuntu3.1
You should explicitly select one to install.
E: Package libmagick9-dev has no installation candidate
$

Installing ‘libmagickwand-dev did the trick:

sudo apt-get install libmagickwand-dev

Then the following worked:

$ sudo gem install rmagick
Building native extensions.  This could take a while...
Successfully installed rmagick-2.12.2
1 gem installed
$

Written by Sharad

November 14th, 2009 at 5:16 am

Posted in All

Ruby Authlogic: lazy initialization based on defined?() call

without comments

What is the difference between following two versions of code?

  # Version: V1
  def current_user_session
    return @current_user_session if defined?(@current_user_session)
    @current_user_session = UserSession.find
  end

This is very similar to following code:

  # Version: V1
  def current_user_session
    unless @current_user_session
      @current_user_session = UserSession.find
    end
    @current_user_session
    # the above code could also be written as: @current_user_session ||= UserSession.find
  end

The difference is that V1 optimizes the code is by making that expense “UserSession.find” query only once per lifetime of enclosing class (which, if you’ve used authlogic, you recognize that it is the ApplicationController class). Then V2 version is a bit inefficient in that if the UserSession.find happens to be nil (when the user is not logged in), it continues to call UserSession.find each time this method is called. Fair enough.

However, this messes up your test if you aren’t writing your test with this fact (the first call to current_user_session method will fix the value of @current_user_session and cannot be changed for the entire test run) in mind.

Consider this test, which passes:

  # Test for when "logout" is invoked, the user-session is properly destroyed and user is redirected
  context "with a logged-in user" do
    setup do
      User.create(:username => "foo", :email => 'foo@company.com', :password => "secret", :password => "secret")
      UserSession.create(:username => "foo", :password => "secret")
      assert controller.logged_in?
    end
    should "destroy session and redirect to root page on logout" do
      post :destroy
      assert_nil(UserSession.find)
      assert_redirected_to root_url
    end
  end

Now, if you introduce a print statement to print the current_user_session after the user is logged in, it will mess up the test and your test will fail:

  # Test for when "logout" is invoked, the user-session is properly destroyed and user is redirected
  context "with a logged-in user" do
    setup do
      User.create(:username => "foo", :email => 'foo@company.com', :password => "secret", :password => "secret")
      # The following line is to make sure user is not logged in initially
      # However, this line will end up calling controller.current_user_session and will fixate @current_user_session to nil for the rest of the test !!!
      assert_nil controller.logged_in?
      UserSession.create(:username => "foo", :password => "secret")
      assert controller.logged_in?
    end
    should "destroy session and redirect to root page on logout" do
      post :destroy
      assert_nil(UserSession.find)
      assert_redirected_to root_url
    end
  end

I can see the reasoning for V1 but I still prefer V2, even though it is little ‘inefficient’.

Written by Sharad

November 12th, 2009 at 10:31 pm

Posted in All

Ruby ActiveRecord: How to implement has_few using has_one and belongs_to

without comments

Google search for has_one vs. belongs_to reveals that the concept is a little confusing and it takes some practice for it to settle in. From Ruby Doc, it appears that in a one-to-one cardinality, we are free to choose which class holds “has_one” and which holds “belongs_to”, with belongs_to class’s database table schema holding the foreign key relationship.

Depending on your business case, one object comprises of other and hence the comprising object ends up having “has_one” side of it. For example, a mortgage application has a borrower_profile. And hence, one can say that borrower_profile belongs to a mortgage application. This is modelled as:

class MortgageApplication
  has_one :borrower_profile
end
class BorrowerProfile
  belongs_to :mortgage_application
end

So far, it’s good.

However, what happens when a mortgage application allows a co-borrower profile? Now we have one-to-TWO relationship that we need to model. One way to model this would be to think of it as one-to-many relationship and add custom validation to ensure that there are a maximum of 2 borrowers for a given mortgage application.

class MortgageApplication
  has_many :borrower_profiles, :order => "borrower_order ASC"
end
class BorrowerProfile
  belongs_to :mortgage_application
end

The :o rder option is needed to ensure that first item in list is the borrower and second item is the co-borrower.

That could work. But, strictly speaking a mortgage application has-one borrower and has-one co-borrower. So, can we model it using has-one/belongs-to? Let’s try.

class MortgageApplication
  has_one :borrower_profile # default: table = borrower_profiles, foreign_key = mortgage_application_id
  has_one :coborrower_profile, :class_name => "BorrowerProfile", :foreign_key => :mortgage_application_id
end
class BorrowerProfile
  belongs_to :mortgage_application
end

The above code won’t work since both borrower_profile and coborrower_profile are being looked up using same foreign key. The problem here is that MortgageApplication needs to foreign key to refer to each of the borrowers. The problem can be resolved by keeping the foreign keys in the mortgage_applications table instead of borrower_profiles table, effectively flipping the has-one/belongs-to relationship. Here we go:

class MortgageApplication
  belongs_to :borrower_profile # default: table = "BorrowerProfile", foreign_key = "borrower_profile_id"
  belongs_to :coborrower_profile, :class_name => "BorrowerProfile", :foreign_key => "coborrower_profile_id"
end
class BorrowerProfile
  has_one :mortgage_application
end
 
# Problem: coborrower.mortgage_application will always be null

The above will solve the problem with mortgage_application pointers to borrower_profile. However, bi-directional relationship from borrower to mortgage-application will only work for primary borrower and not for co-borrower. This is because the lookup for mortgage-application from borrower model will always be attempted using foreign-key: borrower_profile_id.

So, we do the following:

class MortgageApplication
  belongs_to :borrower_profile # default: table = "BorrowerProfile", foreign_key = "borrower_profile_id"
  belongs_to :coborrower_profile, :class_name => "BorrowerProfile", :foreign_key => "coborrower_profile_id"
end
class BorrowerProfile
  has_one :mortgage_application
  # coborrower will use following reference to mortgage-application
  has_one :comortgage_application, :class_name => "MortgageApplication", :foreign_key => "coborrower_profile_id"
end

The above code solves that problem of reverse reference from borrower-profile to mortgage-application for both borrower as well as co-borrower. The only wrinkle is that when looking up mortgage application for co-borrower, we have to use comortgage_application reference. This wrinkle could be wrapped inside the object by overriding “mortgage_application” method.

As we can see, it is possible to map has-few relationship using either has_many/belongs_to or has_one/belongs_to. Each approach has some wrinkles and we can use either depending on which fits our style of programming.

Written by Sharad

November 8th, 2009 at 11:16 pm

Posted in All

Ruby Interview Questions

without comments

I’ve been attending a few Ruby interviews recently. Here are a few questions that I liked being asked. The answers are all mine and may not be all correct.

# Question: Invert the following array
{:a => 1, :b => 2}
# Expected Result: 
{1=>:a, 2=>:b}
 
# Answer:
Hash[{:a => 1, :b => 2}.collect {|k,v| [v,k] }]
# OR
{:a => 1, :b => 2}.inject({}) { |r,e| r.merge({e[1] => e[0]}) }
# Question: What will following code return
{:a => 1, :b => 2}.to_a
# Answer:
[[:a, 1], [:b, 2]]
# Question: How to you quickly determine if a given hash is identity hash or not?
# (Identity Hash is where key == value. For example, {:a => :a, :b => :b})
hash.keys == hash.values
# (Note: hash.keys and hash.values will return the elements in matching order as long as hash is not modified between those 2 calls)
# Question: What is the difference between following to codes?
x = 'a'
x += 'b'
# and
x = 'a'
x << 'b'
# Answer: Nothing. They both return the same result
x = 'ab'
# Question: What will following code return
''.to_sym
# Answer: ArgumentError: interning empty string
# (in other words, an empty string cannot be symbolized/internalized)
# Question: What will the following code return
begin
  ''.to_sym
rescue => e
  5
ensure
  6
end
# Answer:
5
# Note: logic inside ensure does get executed but it still returns the final output of rescue block! This is different from Java, where anything returned from inside finally will override the original return value.
# Question: Given following classes, specify the parent-child inheritance relationship
Class
Object
Module
String
# Answer:

# Question: What will following code return?
x = 1
Array === x
# Answer:
false
# === is a equality operator used for case/when statement.
# Question: What will following code return?
x = []
Array === x
# Answer:
true

Written by Sharad

October 24th, 2009 at 5:18 am

Posted in All

COBRA and Insurance Shopping Tips

without comments

I blogged about some basic information when shopping of individual insurance and recently there was an article in Business Week about COBRA. I found a few more information that are worth keeping in mind when shopping for insurance.

Facts about COBRA:

  • Decide within 60 days of qualifying event whether to take cobra or not. Qualifying event is changing job (voluntary or involuntary).
  • More info about Cobra: dol.gov/ebsa/cobra.html
  • cobra is valid for 18 month. Obama govt. is subsidizing premium by paying 65% of the premium (for the first 9 months of the full 18month coverage)
  • This 65% subsidy is not available for somebody who has another group plan option available (like spouse’s employer insurance plan)
  • COBRA coverage is usually the same coverage that the employee had when on job. It has the same premium + 2% administrative fee. However, employee becomes responsible for full premium (unlike employer paying 2/3rd premium when employed).

When shopping for health insurance, look out for following things:

  • StateHealthFacts.org: information about consumer protection, plan features required by each state
  • Ask insurers for “Explanation of Benefits (EOBs), which are more detailed than summary. Insurers hesitate and sometimes provide EOBs only after you are signed up. Ask to see EOBs before signing up.
  • Avoid plans with annual benefit caps. Lifetime benefit maximum of 1.5 to 2 million are more common now.
  • If employer based group plans are not available, look for association based group plans. e.g. New York Freelancers Union. Each have qualifying rules.
  • There is a difference between insurance plans and “limited-benefit” plans. LB plans (usually touted on TV and offer doctor visit, prescription discounts) don’t cover surgery and hospital stays.

Written by Sharad

October 19th, 2009 at 12:13 am

Posted in All

Looking for Ruby/Rails Work

without comments

Job losses accelerate to 263,000 in September and yes, that number includes me.

After exciting, hard working, fun filled 2 and 1/2 years at Pathfinder Associates, we had to part ways. On the bright side, I worked with some of the finest programmers, agile practitioners and visionaries in Chicagoland area. I got to practice the goodness of agile, pair-programming, scrum, Test Driven Development, became a fan and devotee of Ruby/Rails. I got into serious habit of blogging. Thanks pathfinder!

Yes and it is time to move on. And I am actively looking for Ruby/Rails opportunities. If you are looking for senior level ruby developer or Java architects, please do not hesitate to contact me.

Wish you all a Happy Gandhi Anniversary.

Written by Sharad

October 2nd, 2009 at 4:37 pm

Posted in All