Anything Else

Tuesday, February 12, 2008

How Microsoft Checkmated Facebook

Forbes:

So what is Facebook's destiny?

Microsoft's investment in October 2007 was based on an estimated valuation of $15 billion. If we apply a 15X revenue multiple (higher than that of Google's 11), and let's assume for a moment due to its extraordinarily high monetizing potential (See: " Facebook's Monetization Strategy") to its estimated revenue of $350 million, its optimistic valuation turns out to be $5.25 billion. Based on that, we get an EBITDA multiple of 105, which is much higher than Google's 29. Moreover, we may see Facebook's valuation get a cold shower, given that even Google just missed its earnings because it is finding it difficult to monetize its social networking sites. Even News Corp.'s MySpace, which Google has pledged to support to the tune of $900 million over three years, is having trouble figuring out how to monetize its popularity.

No investment banker in his or her right mind would be willing to take Facebook public at a $15 billion valuation. Facebook could try the same kind of auction-based initial public offering that Google popularized. But investors have to be really stupid to pay this astronomical value for a company that is still in its adolescence with an unproven road map for sustainable revenue and profitability (at that scale).

Would anyone buy the company? Most certainly not at that valuation.

Looks to me like Facebook has been frozen--frozen by Microsoft's brilliant business acumen, and by Zuckerberg's adolescent ego.

...

Microsoft must have reasoned like this: "Google must not acquire Facebook. Neither should Yahoo!. Let's play to this kid's ego, and by sprinkling $250 million on the exercise, we can establish an artificially high valuation that would bring their options of exit down to zero."

On the receiving end, 23-year-old Mark Zuckerberg must have been thinking, "I must be a real stud. I've got Microsoft eating out of my hands!" If some adult at the investor table tried to mumble that this valuation may cause problems, he was appropriately silenced by the euphoria of the $15 billion.

Smart indeed.

Labels: Google Tips n Tricks


Wednesday, November 21, 2007

RSI Tip: Swap Control And Capslock Keys

Stop bending your left thumb in funny ways, after all its opposable thumbs that gives us all the superiority. Here is a reg file to do it on windows[remember to reboot after applying it], other platforms should not be that difficult.

And mix both hands in all the key combos, Right Alt with Tab on left, Right Ctrl with C to copy etc. 

Labels: Programming Life Happens Tips n Tricks


Thursday, July 26, 2007

Vim: Python Code Folding And My VIMRC

If you were curios about the "# {{{" and "# }}}" in my previous post about extending django user model, they are code folding markers. Getting code folding right in vim took me some time and learning, so here I am documenting the takeaways. Code folding, hiding parts of code that you are not working on, is really cool and helpful, and once you start using it, you can not live without it. Here is how to do it in vim.

Pick The Fold Method 

First of all, you have to decide the method for code folding. Vim offers many methods. First is manual, which is basic, you can fold any piece of text at your whim. This might be good for one off or free form texts. Then comes markers. This is my preferred approach for folding as it can be fairly arbitrary, and it can be preserved in version control and gets shared with multiple developers. Then there is folding by indentation, and language syntax. Both these will let you quickly fold things if you have not manually handpicked folding markers. 

Learn The Keys 

Once the method has been decided, then comes the commands, here is a short list:

  • zf create the fold, useful for manual and marker methods. Select any piece of text, [press v or shift-v, then use arrow keys], and then press zf. It will place the markers around the fold for you in marker mode; in case of manual, it will store fold location in memory. Remember f by saying this command "forms" the fold, or just remember fold :-)
  • zc close the fold at the cursor.
  • zo open the fold at the cursor.
  • zr  increment the fold level by one, so if all classes are folded, they will opened, but function definitions will be kept folded.
  • zm reverse of the above, if one or more function folds are open, they will be closed, but classes will be kept open.
  • zR open all folds.
  • zM close all folds.
  • zj and zk can be used to jump from one fold to another. 

Thats it, that is all you need to know about folding in vim, all commands start with z so they are easy to remember. Z represents a piece of folded paper. From my experience you will be only using zf, zo, zc, zj and zk, and these key combinations have been selected quite wisely to make it easy to remember. 

Configure Things

Here is my complete vimrc file, optimized for python source editing:

" enter spaces when tab is pressed:
set expandtab
" do not break lines when line lenght increases
set textwidth=0
" user 4 spaces to represent a tab
set tabstop=4
set softtabstop=4
" number of space to use for auto indent
" you can use >> or << keys to indent current line or selection
" in normal mode.
set shiftwidth=4
" Copy indent from current line when starting a new line.
set autoindent
" makes backspace key more powerful.
set backspace=indent,eol,start
" shows the match while typing
set incsearch
" case insensitive search
set ignorecase
" show line and column number
set ruler
" show some autocomplete options in status bar
set wildmenu

" automatically save and restore folds
au BufWinLeave * mkview
au BufWinEnter * silent loadview

" this lets us put the marker in the file so that
" it can be shared across and stored in version control.
set foldmethod=marker
" this is for python, put
" # name for the folded text # {{{
" to begin marker and
" # }}}
" close to end it.
set commentstring=\ #\ %s
" default fold level, all open, set it 200 or something
" to make it all closed.
set foldlevel=0

" share clipboard with windows clipboard
set clipboard+=unnamed

" set viminfo='100,f1
" minibufexplorer settings:j
let g:miniBufExplMapWindowNavArrows = 1
let g:miniBufExplMapCTabSwitchWindows = 1

syntax on

Enjoy! 

Labels: Python Programming Invented Here Tips n Tricks


Django Master Class

If I have to call a piece of documentation: "mind blowing", this has to be it. You do any kind of web programming, you must read this. If you do django, you will know what all you can do, if not you will know what all can be done in a thought-out framework, and start considering switching or implementing part of it in your own. Read it now.

Labels: Python Programming Django Tips n Tricks


Thursday, July 5, 2007

JQuery Plugin: Masked Input

I love jquery. And I love innovation. Check their demo. Really cool.

Labels: Programming Tips n Tricks


Friday, June 22, 2007

Online HTTP Page Load Analyzer

Came across this handy tool to analyze page load times online. It gives you nice colored display of all the components of a page, and the time it took to load them. So far I used to rely on a firefox extension for the same, which is probably more accurate, but this sure is convenient.

Labels: Programming Tips n Tricks


M4: Getting Started

According to m4's official online documentation:

m4 is a macro processor, in the sense that it copies its input to the output, expanding macros as it goes. Macros are either builtin or user-defined, and can take any number of arguments. Besides just doing macro expansion, m4 has builtin functions for including named files, running shell commands, doing integer arithmetic, manipulating text in various ways, performing recursion, etc.... m4 can be used either as a front-end to a compiler, or as a macro processor in its own right.

Linux would have it installed by default, windows binaries can be obtained here.

So seriously what is it?

Command Prompt: > m4
define(NAME, Amit)

NAME
Amit
define(AGE, 24 years)

My age is AGE.
My age is 24 years.
format('result is %d', eval(2*10))
'result is 20'
define(full_name, NAME upadhyay)

full_name
amit upadhyay
syscmd(dir *dbg)
 Volume in drive C has no label.
 Volume Serial Number is 7C69-CA73

 Directory of C:\Documents and Settings\amitu

06/22/2007  03:29 PM    <DIR>          bin-dbg
               0 File(s)              0 bytes
               1 Dir(s)   1,825,427,456 bytes free

define(`foo', `Macro `foo'.')dnl things after dnl are comments.
foo
Macro foo.

Things in purple are input, rest is output.

Why not your fav programming language? For most simple cases, m4 is much easier to read and understand, and you don't have to write and store scripts everywhere. Think of it as a simple templating language.

A disclaimer:

Some people find m4 to be fairly addictive. They first use m4 for simple problems, then take bigger and bigger challenges, learning how to write complex sets of m4 macros along the way. Once really addicted, users pursue writing of sophisticated m4 applications even to solve simple problems, devoting more time debugging their m4 scripts than doing real work. Beware that m4 may be dangerous for the health of compulsive programmers.

:-)

Labels: Programming Tips n Tricks


Thursday, June 21, 2007

Firefox Tip: Open New Tabs In Background

A handy tip from lifehacker:

Google Reader seems pretty neat, but it's always bugged me that using the "v" key to view a link opens that link in a new tab. I usually like to browse all feed items, open interesting links in the background, and then view the opened links [all at once].

In order to force all links that open in a new window to load in a background tab, type about:config in the URL bar and change browser.tabs.loadDivertedInBackground to true. While you're at it, be sure to grab some other Firefox tweaks, too. Thanks, J! — Kyle Pott

First thing I needed after installing a fresh firefox. Firefox 3 Alpha seems stable enough for my purpose, and uses lesser RAM than Firefox 2.

Label: Tips n Tricks


Monday, June 11, 2007

Django Image Bundle

One of the most important factor in a users percieved performance of a website is the initial page load time. Initial load time depends on backend performance, time it took for the backend to generate the HTML page, and front end performance, the time it takes for the browser to download and render the HTML and all its dependencies. And it turns out that browsers typically take much longer to download dependencies than the original HTML page, due to browser pipelining. Look at the chart below:

As one can see, most of the time is spent in downloading the images, especially problematic for image heavy sites. Read Yahoo! UI Blog's entries on this topic for futher details.

Google recently released GWT 1.4, and one of the features introduced in this release is ImageBundle. The basic idea is to bundle all the images into one at the server side, and use CSS sprite technique to render them. Inspired by it, I just finished an implementation of "Image Bundling" for Django. Here is a demo of the same. The original template to generate the page is here. Look at the bundled image. And the image bundle template tag library can be downloaded from djangosnippets.com. As an added bonus the size of bundled image is about 70% of the total size of individual images, so one can save both total bandwidth, and number of http requests.

This is still the first cut solution. Both this and Google's ImageBundle face an issue when dealing with images with padding, google suggests to avoid padding, or put a wrapper div around the image and put the padding on it. Another issue is images in CSS. They are to be handled slightly differently, but to still keep the output image count to one, some kind of bundle naming is to be done. Google's approach here is creating bundles and using them as two separate steps, I have tried to combine the two together for greater flexibility.

Labels: Python Programming Google Invented Here Django Tips n Tricks


Saturday, July 8, 2006

Nicholson's Categories Solution

This fellow dropped by, telling about his solution to blogger's lack of category problem. Smart. Not as integrated as labelr, but definetly much easier to "install". We seem to think alike, dude, you ever visit India, I will buy you a drink. :-)


I have a few suggestions for you:
  • You use transparent images, which means your server will be hit by n+1 times for each page load, where n is the number of categories for that post page, you can change this to 1, by a "post ping", let javascript come, let it come with information about the categories assigned to this page, known by your server, and let the javascript find a discrepency between that and what the current page says, notify the server if there is difference.
  • Use <div class="category">Name of the Category</div> to assign categories to a post instead of <img src="">s, this way they can appear at the bottom of the post, which is more "traditional", and in you javascript find all instances of divs of class category, and convert it to links, which when clicked will do the same thing that you do in the sidebar.

Labels: labelr Tips n Tricks


Tuesday, May 9, 2006

ps | grep gem

While random readings I came across this gem:

The ps pipeline also contains a true grep gem, which was kindly sent to me by Hans Peter Verne. Notice that grep -v grep is no longer part of the pipeline; instead, it has been removed and grep "ssh-agent" has been changed to grep "[s]sh-agent". This single grep command ends up doing the same thing as grep ssh-agent | grep -v grep; can you figure out why?

Listing 10. Neat grep trick

mypids=`ps $psopts 2>/dev/null | grep "[s]sh-agent" | awk '{print $2}'` > /dev/null 2>&1
Stumped? If you've decided that a grep "ssh-agent" and grep "[s]sh-agent" should match the exact same lines of text, you are correct. So why do they generate different results when the output of ps is piped to them? Here's how it works: when you use grep "[s]sh-agent", you change how the grep command appears in the ps process list. By doing so, you prevent grep from matching itself, since the [s]sh-agent string doesn't match the [s]sh-agent regular expression. Isn't that brilliant? If you still don't get it, play around with grep a bit more and you'll get it soon enough.

Label: Tips n Tricks


Tuesday, May 2, 2006

svn: REPORT request failed

Symptom:

amitu@red:~/work$ svn co  http://code.djangoproject.com/svn/django/trunk/ django_mr
svn: REPORT request failed on '/svn/!svn/vcc/default'
svn: REPORT of '/svn/!svn/vcc/default': 400 Bad Request (http://code.djangoproject.com)
amitu@red:~/work$

Reason: Very likely you are behind a transparent proxy.

Solution: Something like this? Try your luck.

Label: Tips n Tricks


Next