Reading about all the news with the oil futures spike, peak oil theories and inflation makes me wonder if good old two hands will become more important in the future for a country.
Whenever I compare India (where I was born) and USA (where I live), I find that anything that requires human touch is a lot more expensive in the US than in India. The opposite is true for highly automated machines. Household help/caregiving, massages, drivers for hire, etc. are all less expensive to hire in India. Hiring people for cheap is usually the most common differentiator when people compare the quality of living in India with USA.
I even remember a speech at my college by the Human Resources Development minister (who is the ex-officio head of the IITs) highlighting this point. He was berating the computer science students for working on Robotics when we should be focusing on trying to better utilize India’s best resource - the abundance of human resource.
If automation (automobiles, manufacturing, et. al.) gets more expensive then in a hundred years we might be back to using human power to power everything! Not back to the dark ages, but to cycling and hammer and tongs…
digg
reddit
del.icio.us
June 8th, 2008
Once in a while I get the urge to do something with the few savings that we have sitting in the savings and retirement accounts. Something aggressive, creative or opportunistic. I always go back to sanity by reading a few bookmarks.
Here is an article in the San Francisco magazine that is the sanity check. I have that article saved locally so I would not have to worry about it disappearing from the web. The folks at Aperio Group who are mentioned in the article now have a website which is called Transparent Investing. They have a basic investing guide which is simple enough for do-it-yourself investing and detailed enough to appease the engineering minds (for example, it accounts for the fact that people have taxable accounts and retirement accounts).
I was reminded of these because of an anectode from Warren Buffett:
One shareholder asked a question along the lines of ‘how should I study investing in order to build wealth in my spare time?’
Buffett replied that, for most people, the bulk of their income is going to come from earning power in their chosen profession. Therefore, from the standpoint of building wealth, free time is better spent sharpening one’s professional skills rather than studying investing.
If you like your profession, and you enjoy doing what you do (like I enjoy what I do for a living), then read the articles and stop worrying about investing.
digg
reddit
del.icio.us
April 20th, 2008
Imagine Eli Manning and the NY Giants missing the points on their last drive. Many (if not all) news bulletins would have carried the photo of Randy Moss hauling in the pass from Tom Brady while Corey Webster was spread eagled even before the Ball was anywhere near Moss. It would have been painted as Tom Brady’s clinical effort and Randy Moss’ redemption for a poor post-season. However, more interestingly, Corey Webster would be forever the guy who was on his ass behind while NE scored. Instead Corey Webster is the guy who deflected the Hail Mary pass in the last 10 seconds and who (ahem!) inexplicably fell down on the previous drive.
Note: I am only a USC and OSU fan and not even a 49ers or Raiders fan.
digg
reddit
del.icio.us
February 5th, 2008
Microsoft and Yahoo potential merger is being billed as the largest tech merger. When such large software companies merge, it worries me.
There are many facets to the merger including markets, web presence, customers, communication tools, employees, work culture, among others. When financial companies that have money in their accounts merge they just become bigger institutions with larger capital to play with. When manufacturing companies (and others who make stuff) merge, they can optimize their making process and put together their product portfolio. However, when software companies merge it means they have figured out they are not able to complement their portfolio by building it themselves.
Most big software houses can afford to build a piece of software in terms of people and development cost. The harder part is stealing customers and mindshare away from products that already exist. You are effectively buying the other company to get the customers. Software companies do not really have any redundant operations to save on except the employees who work on duplicate efforts in both companies.
Everyone including Microsoft, Yahoo, Google, Facebook, Myspace are just fighting for the same crowd of people spending time on their pages for pretty much the same thing - mail, search, news, socializing - and hope to get the rest of the industry to pay for their eyeballs. Microsoft and Yahoo have a large pool of smart people in the house who have built many different technologies. But, they do not expect to put a few hundred people to a project on their own and create something that attracts and retains customers or eyeballs (to get the advertising money). There are not too many ways you can slice and dice and present those same features (at last that is what MSFT and YHOO think if they are merging).
You can hear them thinking: “We cannot really think of do anything else to create to get more customers, let us just put your customers and my customers together and see if we can hold on to all of them”
digg
reddit
del.icio.us
February 1st, 2008
I was LMAO ROFL (enjoying it immensely) when I saw the announcement of the Apple iPhone price cut to 399 all the way from 599 (or to 400 from 600 as your brain should really see it). Whatever be the reasons for the price cut, the joke is on those guys who stood in line less than two months ago to have the privilege of paying 50% higher price just for the sake of owning it a few days earlier than the rest of the crowd. I bet a whole bunch of them just bought it for the cool-factor than really needing to zoom in and out of their pictures with two fingers instead of pressing keys. I do not remember anything falling so much in price after so much hype like the iPhone. Some call it a ripoff of the early adopters! Snazzy interface with handicapped functionality only extracts so much from only so many lusers users wallets.
I know geeks take immense pleasure in staying at the cutting edge of technology by buying the latest gadgets. Phones are not the only such gadgets where early adopters pay the huge premiums. Computers, Blu-Ray/HDDVD players, Televisions and most other equipment charge a premium when they are the top-of-the-line. I remember someone at the recent Hotchips 2007 conference announcing at the mike that he regularly buys $8000 systems to play games. BTW, he looked more than 50 years old!
I said in a previous post of mine about shopping that I Forget the Features to avoid paying too much to future proof my purchases but focus on what I want in basics. However, I am deeply indebted to sheeple people who pay through their nose for bleeding edge technology since they partly contribute to keeping the technology industry (ergo my job) humming.
I did the whole bleeding edge thingy when I bought my first cellphone, a Sony CMD Z1. I bought it when I was a student (when a dollar is worth more than $1) for more than $200 and after just one year it was priced at $39. My last two cellphones were exactly the type of purchases that vampires vendors hate. I bought the Treo 300 (ugly beast of a phone) when the rebates dropped so low that I made $30 when I bought it on Amazon (and made $50 more when I sold it on craigslist a couple of years later). I realized I did not really need the keyboard as much when it made the phone so bulky. The next purchase was when I bought two Audiovox SMT 5600 Windows mobile phones for $20 each from cingular when it was being phased out.
I reckon I saved about 600 dollars in total by waiting an year from the prime-time of those phones. Dropping the price of an iPhone does not do much for me. My Audiovox plays mp3s very well through its speakerphone speaker. It also syncs very well over my vmware installation of windows to my corporate Exchange. Imagine saying that with iPhone in one sentence - sync, vmware, Exchange! The one I lust after is the HTC Vox (interestingly at the same $400 price point currently as iPhone) with a slick keyboard underneath a candybar form factor. I am still waiting for it to be released and become obsolete…
digg
reddit
del.icio.us
September 5th, 2007
When you are developing rails apps and you are hacking your way around, it is fine to get a bunch of errors and screen dump of what went wrong. However, when you start deploying it and want to convince users to accept the new system exceptions are like segfaults. You do not want them to see gobs of exception messages on their browser which will be an excuse for them to write it off even if they did not RTM and did something wrong. Another problem is that people will happily hit Back and not save what happened and only bitch about the instability of the system.
Exception Notifier is a great plugin to solve these issues. Basic installation of the plugin is pretty smooth and if you already have emails working from your app then exception notification works pretty easily. There are enough Google results for you to get it working.
One standard problem that almost everyone has is to get it working in your development environment. The following changes did it for me: update your application.rb and update your config/environment/development.rb.
application.rb
include ExceptionNotifiable
local_addresses.clear
development.rb
config.action_controller.consider_all_requests_local = false
More interesting changes are to do with picking specific errors out of all the errors and sending some to the browser and some via email. In my case, I had support for free-form SQL queries in our internal application which could give internal MySQL errors to user queries which I wanted to go to the browser. Here is what you add to application.rb:
# Try to get incorrect SQL errors and show them on screen
def rescue_action_in_public(exception)
case exception
when ActiveRecord::StatementInvalid
render :text => "You have errors in your SQL Syntax. Please try the Back button and fix them before trying again. #{exception.message.inspect}"
when ActiveRecord::MultiparameterAssignmentErrors
render :text => "You seem to have some inconsistent input. e.g. Date like Feb 30 2007. Please try the Back button and fix them before trying again. #{exception.message.inspect}"
else
super
end
end
The ActiveRecord::MultiparameterAssignmentErrors is a very interesting exception which you surely want to get to the user than via an email to the admin. I found out that when forms have incorrect date input (like Feb 31), MySQL generates this obscure exception. I could have borrowed some date validation code but why do extra work when you can rap the users knuckles instead.
digg
reddit
del.icio.us
July 28th, 2007
I was looking for a quick way to build a hierarchical navigation tool in Ruby on Rails. There are good examples to build your own tree in Ruby when you use acts_as_tree and Single Table Inheritance etc., but nothing very easy to do otherwise.
A little bit of searching led me to the railstree plugin (source). Unfortunately, the documentation and any notes I found were in Portuguese so I thought it will be useful to illustrate how to use it in English. You could just try the Google translation of the Portuguese page and get most of what I have below (and get a few laughs at the translation while doing it).
First download railstree plugin from one of the rubyforge mirrors and install the files into the appropriate directories. You might need to hack the RAILS_ROOT path in the install.rb to correctly install the files using the install.rb script. You could also just repeat what the script is doing by manually copying the files yourself. (The script/plugin method of installation mentioned in the homepage of railstree did not work for me).
Now you have to include the javascript standard files with the two additional lines at the bottom in your view.rhtml file:
(Note that I have not figured out how to show HTML tags inside my snippets so remember to add < and > to HTML tags in the snippets.)
< %= javascript_include_tag ‘prototype’ %>
< %= javascript_include_tag ‘effects’ %>
< %= javascript_include_tag ‘dragdrop’ %>
< %= javascript_include_tag ‘controls’ %>
< %= stylesheet_link_tag ‘tree’ %>
< %= javascript_include_tag ‘tree’ %>
You could always do a simpler version
< %= javascript_include_tag :defaults %>
< %= stylesheet_link_tag ‘tree’ %>
< %= javascript_include_tag ‘tree’ %>
Now you need to construct the tree in your controller. In my RoR project, the navigation tree is displayed in all controllers so I just put it in app/controllers/application.rb:
def create_tree_menu
if (@menutree)
return @menutree
end
@menutree = Tree.new("MyTree", "")
Parent.find(:all).each do |p|
pnode = Node.new
#(p.name, "/parents/show/#{p.id}")
pnode.link_to_remote p.name, {:base => self, :update => 'content',
:url =>{:controller => 'parents', :action => 'show', :id => "#{p.id}"}}
Child.find(:all, :conditions => "parent_id=#{p.id}").each do |c|
cnode = Node.new
#(c.name, "/children/show/#{c.id}")
cnode.link_to_remote c.name, {:base => self, :update => 'content',
:url =>{:controller => 'children', :action => 'show', :id => "#{c.id}"}}
pnode < < cnode
end
@menutree << pnode
end
@menutree
end
Now the explanation: The above code is constructing a navigation tree for a two-level hierarchy with a Parent Model and a Child Model. The Child Model has a parent_id attribute linking to the Parent table. The default action when someone clicks on any node on the tree is to call the show Action for that node. This is done by setting the pnode.link_to_remote and cnode.link_to_remote with the parameters as above. The update attribute points to the div of the view to be updated when the node is clicked in the tree. The base attribute is very important since that reference is used internally in the railstree plugin to callback so it better be not null.
I did not try modifying the images for the icons of the tree but you can do that by using the pnode.icon method. You can also set the open/close status of the node by calling the open method but we will come back to that later.
Now how do you show this in your view?
div id="dtree"
< % if (@menutree) %>
< %= @menutree.to_s %>
< % end %>
/div
div id=”content”
Your ERb code
/div
Viola! Now you have the tree just like it shows on the homepage of the project. For an additional tweak, I managed to figure out how to show/hide the tree by clicking on a link. Just add this at the top of the code snippet above (check to make sure the div ids are the same, dtree in the example here):
script type="text/javascript"
//< ![CDATA[
function hideTreeMenu(){
Element.toggle('dtree');
if (Element.visible('dtree')) {
Element.setStyle('content', {marginLeft: "210px"});
} else {
Element.setStyle('content', {marginLeft: "5px"});
};
};
//]]>
/script
a
href=”#” onclick=”hideTreeMenu();”>Show/Hide Tree
/a
The extra adjusting of the Element.setStyle is to just move my content into the space where I had my tree so hiding actually gives more space in the code for the content div. If you do not care about moving the content to reclaim space, you could just do a Element.toggle call. Note that I am a javascript noobie so others might have better ways of doing this.
Also, since I am a javascript and cookies noobie I could not figure out how to set a cookie to save/retrieve the state of the tree when someone actually clicks on a node in the tree. In the current form, when someone clicks on any node in the tree, it updates the content div and then curls up and shows a fully collapsed tree than the last state. I do not think I managed to even save/retrieve the Show/Hide state before and after a click on a node. Other than telling me to try cookies, let me know if you can explain how to do it.
digg
reddit
del.icio.us
July 14th, 2007
When we construct views of query results using ERb in rails, most of the time we know what we are displaying and how to format it. However, there are a few occasions when we run find_by_sql queries. Even rare are the occasions when we let users type free-form SQL queries into an input box and just take the query string as is and run it on the database (MySQL in my case).
The reason I did the free-form queries in our internal site was to let users crunch the data the way they wanted instead of trying to add more and more views as they kept requesting them. However, this presents a problem in the View portion (of the Model-View-Controller).
Since we do not know what columns the user has actually requested in the query, it is not easy to figure out how to write the ERb/HTML view code. Fortunately, the attribute_names method of the model helps here.
So you do this in your controller:
def sqlquery
if (!querystr.blank?)
@results = Model.find_by_sql(querystr)
@total = @results.size()
if (@total > 0)
@columns = @results.first.attribute_names
end
else
@total = 0
end
end
The attribute_names is very useful since it returns exactly the columns that are requested in the SELECT portion of the query (rather than every column in the Model model). Also, when the SELECT uses a AS clause (please refer to the MySQL SQL documentation), the attribute_names contains the string in the AS clause. e.g. If the query has SELECT name AS ‘UserName’ … then attribute_names returns UserName as one of the columns.
However, I still faced one gotcha that I could not figure out either by searching or by reading the rails source. The attribute_names method does not return columns in the order they were specified in the SELECT clause. It can return them sorted alphabetically, but that’s it! Now, users do not like see columns in random order showing up in the results table. I thought of parsing the query but then realized it was futile since the query could contain recursive SQL and table joins etc. The easiest hack that I found is to just try string matching which surprisingly works for all our SQL queries. I do not see a reason why it should not for all cases. So the new code looks like this:
def sqlquery
if (!querystr.blank?)
@results = Model.find_by_sql(querystr)
@total = @results.size()
if (@total > 0)
cols = @results.first.attribute_names
if (querystring.match(/s*SELECTs**s*FROM.*/i))
@columns = cols
else
pos = cols.inject({}) { |h, col| h[col] = querystr.index(col); h}
@columns = cols.sort { |x,y| pos[x] < => pos[y]}
end
else
@total = 0
end
end
So what does the code do? First, we check if the query was a SELECT * FROM which will not have any column names in the SELECT clause. Then we just rely on the random order of the columns returned by attribute_names. If not, we compute the position of the strings returned by the attribute_names in the original query (in the cols.inject line). They could be simple column names or even the AS clauses. We can now use the position(index) of the substring as a sorting criteria so that the earlier occurring column names in the SELECT clause is earlier in the @columns array. This seems like a hack but it seems to work everytime. If there is a more elegant way, I am all ears…
Now in the view, we can use the @columns array for our view (do not forget to change the code below from table to <table>, td to <td>, etc.):
table
thead
< % for col in @columns %>
td < %= col %> /td
< % end %>
/tr
/thead
< % for item in @results %>
tr
< % for col in @columns %>
td < %= item[col] %> /td
< % end %>
/tr
< % end %>
/table
digg
reddit
del.icio.us
June 19th, 2007
It did not have the slashdot effect but Marc Andreesen linked to the http://www.softwareinterview.com website in his post on recruiting and the traffic jumped a few hundred visitors the next couple of days. I guess the site showed up in some google search he tried (if he uses google).
See the post here: http://blog.pmarca.com/2007/06/how_to_hire_the.html
digg
reddit
del.icio.us
June 19th, 2007
I have been dabbling with Ruby on Rails a little more lately. I have hacked around and figured out solutions for issues that stumped me based on posts from others or from experiments. I will try to catalog some of those in my blog so it is useful for others. Pardon me if some of these seem trivial or violate Ruby idioms. I have been learning Ruby as I wrote an internal application in RoR. Recently, I ended up coding and checking in stuff in Verilog, C++, Ruby and Javascript in a single day so I have valid excuses to muck up all of them.
The first one is a hack I figured out to display find_by_sql results that I could not even get answers from rails mailing list. Stay tuned…
digg
reddit
del.icio.us
June 3rd, 2007
Previous Posts