Friday, August 28, 2009

I Love JavaScript (Sometimes)

News:

From Business Week Big Blue's Global Labs

Building a global chain of "collaboratories." Good luck, IBM. May I loan you my copy of Fumbling the Future?

JavaScript:

Something like this:


btn.onclick = click_func;
document.body.appendChild( btn )



That, obviously, will never work. This will:


document.body.appendChild( btn )
btn.onclick = click_func;



Did I say "obviously"? That, obviously, was sarcasm.

When coding you exhaust all the rational possibilities first. With code still failing, you move on to the semi-rational possibilities.

After exhausting the rational possibilities, I briefly considered DLing the source for Mozilla, to just take a look for myself at the troubled area. Briefly. Just long enough to learn that there are about 2.5 million lines of code there.

It was Saturday, the 15th, when my Ruby writing ground to a halt with The Bug from Hell. I believe I can proceed again, albeit with the simplicity of document.write() in the rear view mirror.

Started yesterday building tables the slow way. Create a table element and attach it to the body of the document. Create a row element and attach it to the table element. Create cell elements and attach them to the row element. Create contents and insert or attach (depending on type) content to the cells. On to the next row.

My UI includes a table with a table. It's very complex so that the user will think it simple. It took a half day to build it with document.write() . I'm thinking five times the code, and five times the time, doing it the slow way. That, of course, doesn't allow for additional "gotcha"s.

Anybody going to bet against more "gotcha"s?

Friday, August 21, 2009

The Bug from Hell

Executive Summary

One full week lost. Zero output units. It was the bug from hell. If you have any faith in your software schedules, read on.

I am writing a SketchUp Ruby. Stuff that worked Friday stopped working Saturday morning. I got to the bottom of the problem Thursday morning. In a lifetime of coding I've never been stopped for five days by one bug. It was subtle.

The trickiest bit about Rubies is that your UI runs in a browser. That means that the Ruby code that manipulates the model has to communicate with the JavaScript in the browser. (Note: this is another case where you have two languages to use and zero choices about which you use.)

JavaScript on the Front Line:

The general idea is that since the user is in charge, JavaScript notes what buttons are clicked or whatever. JS can then call a Ruby function that will dig up whatever data is needed or manipulate the model in the manner requested. If it needs to send data, Ruby prepares a bit of JavaScript, like this:


script = 'name_of_javascript_function( whatever, facts, are, required )'


Ruby hands this script to a webdialog object (prepared by the web dialog and passed to the Ruby callback). The webdialog executes the script, presumably calling JS functions that make use of the data. The whole communication thing is at best inelegant. This is NOT pythonic.

"No, no, Monty! I didn't mean you. You are totally pythonic."

Monty, my pet python, has been crabby since I turned him into a vegetarian. Sorry for the interruption.

Ruby in the Trenches

Saturday morning I moved the JavaScript out of the HTML file and into a separate JavaScript file so I could validate the HTML. I've got validated HTML, but the code no longer worked. It seems that JavaScript correctly calls Ruby. Ruby correctly gathers the data wanted and correctly forms the script needed. But Ruby is definitely not succeeding in getting back to JavaScript. The final step, executing the JavaScript script, is not happening. At one point the JavaScript function that I wanted called by the script was reduced to launching an alert box that said, "Hooray! Finally!". It never said "Hooray! Finally!".

Note that the tool set is completely primitive. There is no NetBeans, no Eclipse, no debugger. On Windows, we can choose any browser we like, provided we choose MSIE. At one point it reported that I had an error in my JavaScript at line 51 million and something. Ugh. The tiniest little bit of error checking and it's too buggy to be helpful.

For debugging, you stick print statements into the Ruby and pop up alert boxes in JavaScript. Before Saturday ended I knew that my JS was correctly calling Ruby, that Ruby was preparing a valid script passing correct data and was calling the correct method of the webdialog (the webdialog that JS had passed to Ruby). And that was the end of the road.

Swapping Code

By Tuesday I knew that the same code that worked also failed. I started with a successful, small test package and the unsuccessful, larger actual package. I began removing parts of the larger package deleting bits one a a time until I could find the guilty party. I ended with a still-failing package no larger than the test package.

Wednesday found me copying Ruby source functions from the test to the failing routine. Still fails. Copy from the failing to the test? Still succeeds. So repeat this with the JavaScript functions. Same result.

Early Thursday I am convinced that it is a timing issue. How else could two copies of the exact same code fail and succeed?

"Martin, what are you talking about? It's single-user, single-threaded code! Timing issue?"

"OK, Monty. You explain it."

That got me back to Saturday morning. I had taken the JavaScript out of the HTML, where it had been at the end of the body of the page, and put it into a JavaScript file. I linked to the JavaScript file from the <head> section of the HTML, a common practice that I will never again practice.

Moving the "load the JavaScript file" command from the <head> of the HTML to the end of the <body> of the HTML turned the failing code to successful code. Bug in the SketchUp linkage: if your HTML is not completely processed, the webdialog that it passes to Ruby cannot execute the JavaScript script.

Moral?

(In Ruby convention, getters for booleans are suffixed with a "?". This section should return a boolean.) Moral? Maybe.

I let my ego get in the way. Hot shot programmers fix their own bugs, right? Instead of punching ahead on my own, I should have recruited an associate. Wise old programmers get help when they need it. I'll try to remember that.

Monday, August 17, 2009

Scroll Down! Blogger's to Blame.

In the previous (following this one if you are reading chronologically) there is a giant bunch of empty space above the table. Scroll down, the table's there.

I don't know why. The HTML doesn't have any problem if you view it in a browser. This is a Blogger issue. And so it goes.

Broadband for Everyone

Broadband in America:

From Business Week, stimulus package broadband expansion funds are not going to cities.

Broadband Stimulus and the Underserved

I was curious about the situation around the world, so I asked Google. He showed me Internet World Stats. They showed me a table of broadband penetration, but, unfortunately, it was ranked by total broadband subscribers. U.S. has the most. China is second. That is pointless.

How do we compare, penetration per capita. U.S.: 21.9%. China: 3.7%.

Open Office:

Internet World Stats does not, unfortunately, provide a spreadsheet version of its data for download. I needed their data sorted by penetration. Briefly considered retyping into a spreadsheet, but decided to try for an easy alternative.

I swept my mouse over Internet World Stats whole table. Pressed ^C. Went to my text editor and pressed ^V. Scrambled data eggs.

I opened an OO spreadsheet. Pressed ^V in cell A1. Absolutely amazing! A very nice spreadsheet appeared. Even the report and column headers were sensibly laid out.

I selected column D and asked for a descending sort. Ooops. That sorted column D. Selected all the data and asked for a sort. It asked, "What column(s) and up or down, please?" Click, click, done. Just what I wanted to know. U.S. is seventh in the world behind some countries you might have guessed (Sweden) and some you might not (France).

I'd show you the whole table, but that might be hard. I'll try, anyway.

Whole Table:

Back to OO. Save as HTML. Open HTML in text editor, copy the parts from "<TABLE>" through "</TABLE>" tags. (Sorry to see that OO still uses capital letters.)

Pasted the HTML into the Blogger "Edit HTML" tab. Here's the result:













































































































































































































TOP COUNTRIES WITH THE HIGHEST NUMBER OF WORLD INTERNET BROADBAND SUBSCRIBERS IN 2007
# Country or Region Broadband Subscribers Broadband Penetration (%) Population ( 2007 Est. ) Source and Date of Usage Data
12 Netherlands 5388000 32.80% 16447682 ECTA - Mar./07
5 Korea, South 14042728 27.40% 51300989 OECD - Dec./06
20 Sweden 2478003 27.20% 9107795 ECTA - March/07
9 Canada 7675533 23.70% 32440970 OECD - Dec/06
6 United Kingdom 13957111 23.10% 60363602 ECTA - Mar./07
7 France 13677000 22.30% 61350009 Teleco - Mar/07
1 United States 66213257 21.90% 301967681 OECD - June/07
4 Germany 17472000 21.20% 82509367 OECD - June/07
3 Japan 27152349 21.10% 128646345 OEDC - June/07
13 Taiwan 4505800 19.60% 23001442 ITU - Sept/07
14 Australia 3939288 18.80% 20984595 OECD - Sept/06
10 Spain 7505456 16.70% 45003663 CMT - July/07
8 Italy 9427300 15.80% 59546696 ECTA - Mar/07
18 Poland 2640000 6.90% 38109499 OECD - Dec./06
16 Turkey 3632700 4.80% 75863600 ECTA - Mar/07
2 China 48500000 3.70% 1317431495 MII - Sept./06
15 Mexico 3728150 3.50% 106457446 OECD - Sept/06
11 Brazil 6417000 3.40% 186771161 Teleco - June/07
17 Russia 2900000 2.00% 143406042 ITU - Sept./07
19 India 2520000 0.20% 1129667528 TRAI - June/07






TOP 20 Countries 268150077 6.90% 3890377607 IWS - Nov.14/07
Rest of the World 36321302 1.40% 2684288810 IWS - Nov.14/07
Total World Subscribers 304471379 4.60% 6574666417 IWS - Nov.14/07

Saturday, August 15, 2009

JSON in Practice

Writing JSON:

I wrote a specific-purpose JSON writer, in Ruby, to encode the data I needed. It wasn't too tough:


# JSON to send to webdialog
def makeJson( layer_names, scene_names, vis )
ret = '{ '
ret += 'layers:' + makeJsonArr( layer_names )
ret += ', scenes:' + makeJsonArr( scene_names )
ret += ', vis:\"' + vis + '\"'
ret += ' }'
return ret
end

# convert array of names to JSON array
def makeJsonArr( names )
ret = '[ '
start = true
names.each do |n|
unless start
ret += ', '
else
start = false
end
ret += '\"' + n + '\"'
end
ret += ' ]'
return ret
end


Reading JSON:

Since JSON is syntactically correct JavaScript, this is the reader that decodes it in JavaScript:


function rubySays( data ) {
eval( 'obj = ' + data );


The rubySays() method then goes on to make use of the object it creates in its first line. I like code that weighs in at just tens of bytes.

Summary:

Writing JSON is easy. Reading JSON in JavaScript is effortless. Highly recommended!

Friday, August 14, 2009

Multiple Desktops

Today's Views:

Not news, views. AAPL Undervalued?

I know a couple things about stock prices. One is that rising EPS is a good thing. The other is that today's price of X is the price at which exactly half the people on Wall Street think X is overvalued while the other half believes X is undervalued. This is good to remember when you read an analyst who is in the undervalued camp. Half the people on Wall Street, and there are some very smart people on Wall Street, disagree.

Multiple Desktops:

I have a nice big desk and I keep it organized. This is good. Having several nice big desks would be better. Each project I am working on would have its own desk. Books, papers, 3D models, whatever would be on its own desk. Changing from project A to project B wouldn't require putting A's stuff away and opening B's stuff. I'd just move from desk A to desk B.

This is exactly what I have in Linux. I press Ctrl+F3 for this blog. Ctrl+F4 gets to my personal website. Ctrl+F11 gets to my Decaf language project. Almost all my desktops have a browser open, but none have the same tabs open. Most have a text editor, but each editor has different files open. I use 12 desktops (max: 20, but even 12 may be too many). Some have spreadsheets; some have pictures.

Multiple Desktops in Windows:

Windows sucks you back in like a black hole. Google SketchUp, for instance, runs in Windows and OS X, but not Linux. You want SketchUp Rubies? Any language you want, provided you want Ruby and any OS you want, provided you don't want Linux. Windows does not have multiple desktops.

Hold on. Windows has multiple users. Each user has a single desktop. Many users times one desktop each looks a lot like multiple desktops!

In Linux, Ctrl+Fx switches to desktop x. There's also a little display of an array of desktops where one mouse click switches. In Windows that's Start, Logoff, Switch User and then click on user. But if you hold down that special key with the windows logo and press L, you've got Start, Logoff, Switch User all at once. It's only a single click more difficult than Linux.

So go ahead and create a "User" for each of your projects. You will be very happily surprised at how nice it is to return to a browser with a handful of tabs open related to the project. And at how convenient it is to not have to put one project away to work on another.

You do have 2GB of RAM, don't you?

Thursday, August 13, 2009

Today's News:

Let's get to the really critical issue of the day: Will Windows 7 or Snow Leopard have better wallpaper? They're really on top of things at Fortune.


Snow Leopard vs. Windows 7: The War of the Wallpapers

The article's link to MSFT's wallpapers got you to its financial results, not its wallpaper. Use this one, instead.

I recommend that you get a camera and make some of your own. Here are a couple of mine: Catskills in Winter, Fall Scene from Kayak. (Big, fat files. Sorry.) The secret to good amateur photos? Take lots and lots. Then throw most of them, almost all of them, out.

Linux Desktops

Linux has two graphical front ends, GNOME and KDE. Free software champion Richard Stallman created a Unix workalike, naming it GNU (GNU is Not Unix). GNOME, (originally GNU Object Model Environment), and KDE (originally Kool Desktop Environment) are both excellent desktops. Both disavow their original acronyms.

I started with, and still use, KDE for the simple reason that it came preinstalled, as Windows typically comes. The computer was so cheap that I bought it just to satisfy my curiousity about Linux. Was it really as reliable as people said? Would the learning curve be steep?

Yes, it works for months at a time and no, there was almost no learning curve. I turned it on and started using it. A big button labelled "Launch" looked like it would be similar to MSFT's "Start" and it was. I was soon in familiar software: Firefox and Open Office. Then I found the Konqueror browser/explorer replacement. Firefox is maybe five years behind and Windows Explorer is utterly primitive by comparison.

I have learned to open a command window and use a handful of the original Unix commands, but this is no more necessary than using the DOS window in Windows.

What I have learned to love most, and even sort of simulate when I have to go back to Windows, is the multiple desktop feature. More on that, soon.

Open Office

Are you still paying Microsoft for its Office software? Why? It will not be long before you are asked this question by one of your directors whose own organization has switched successfully. The only acceptable answer is, "We're in transition right now. We'll be fully converted before the current licenses expire."

Wednesday, August 12, 2009

JSON: JavaScript Object Notation

Todays news:

Business Week tells us Why Apple Is More Valuable Than Google

Executive summary: Google makes money on search. Loses money elsewhere. Apple makes money on everything.

JSON: JavaScript Object Notation:

I'm working on Rubies, plug-ins for Google SketchUp written in Ruby. More exactly, since the UI takes place in a browser, written in JavaScript and Ruby. Google has provided a mechanism for Ruby to pass a string to JavaScript and for JavaScript to pass a string to Ruby. I need to share lists of strings and an array of booleans for my Ruby. Enter JSON.

Like XML, JSON stores stuff in human-readable strings. Specifically, it stores objects, arrays, strings, numbers, and constants 'true', 'false' and 'null'. Strings and numbers are very much like strings and numbers in C (and from C, C++, Java and many others).

Arrays are a comma-separated list of values enclosed in square brackets. Array values may be anything that JSON supports: objects, arrays, ... (list above). Arrays may be all of a single type, or any mix of types. Arrays are one dimensional, but as arrays may be members of arrays, this is not a restriction.

Objects are zero or more comma-separated name:value pairs, enclosed in curly braces.

Add whitespace between values, if you like.

And that's it! Very light but no less capable than XML. If you want to write a JSON reader/writer, the exact details (such as the short list of escaped characters) are at www.json.org. A JSON reader/writer is already written for all the languages I know.

Doug Crockford invented JSON, sort of. JSON copies the notation Brendan Eich invented for JavaScript. Crockford noticed that this notation made a simple but full-powered version of XML. Here's an example:


pet={type:python, diet:vegetarian, TimToady:opposed}
pets = [ python, kitten ]


Those are valid JavaScript statements. To the right of the "=" signs you see valid JSON. I love things like this. We backpackers say, "When in doubt, leave it out."

JSON can get just about anything talking to anything else. Highly recommended.

Tuesday, August 11, 2009

Regular Expressions and Perl

Today's News:


30 songs: $30? $4,000? $675,000?

Jury awards RIAA $675,000 from a grad student for DLing and sharing 30 songs. RIAA demanded $4k before trial. Grad student. Now he'll have to scrape up enough to pay a bankruptcy lawyer. RIAA won't get money, but it's got a hell of a legal precedent.

For the record, it took 42 seconds for me to find the file-sharing service my kids use.

Perl


First, Perl is a very kludgy language. The Perl programmer does a lot of work for the benefit of the interpreter. That is backwards. Scalar values' names must start with "$". Array names start with "@". If you have an array, @arr and want its first element you refer to $arr[0].

I assigned a task to myself: learn the three "P"s of the LAMP stack. That's Linux, the Apache server, the MySQL database and one of Perl, PHP or Python. I got far enough in Perl that I did not use it for CGI code. Too kludgy.

Consider this. Arguments are passed in the global variable @_. Suppose your second argument, $_[1], is a reference to a list. The reference is a scalar. The list is not. So you say:$ref = $_[1]; my @list = @$ref;. You now have a list variable, @list.

If that's not bad enough, consider this simpler substitute: my @list = @$_[1];. It looks identical, but it doesn't work. Ugh. I quit.

Regular Expressions

Perl did one thing well: regular expressions. It puts regular expression constants into the core syntax as most languages have string constants. You have "string constant" or /regular expression constant/.

A Perl statement has this format:

[optional statement part] [# optional comment part]

A regular expression to recognize this is /[~#]*#.*/. In English, that's any single character other than "#", repeated zero or more times, followed by "#" followed by zero or more characters of any kind. Add parentheses: /([~#]*)(#.*)/ and you can refer to the parts in your code.

For many text processing chores, regular expressions are so valuable that you forgive their unreadability. The programmer can partially solve this problem with extensive comments. Since Perl, most languages, including Python, feature regex constants delimited by forward slashes. Oddly, Ruby, designed to be a better Perl, does not. It features a regular expression class (JavaScript does this, also) which is somewhat less convenient.

Unfortunately, that sample regular expression won't handle itself as input. It would have /([~ as the statement part and #]*)(#.*)/ as the comment part.

The correct statement definition is:

Zero or more characters, including the "#" character if it is part of a string literal or a regex literal, optionally followed by a "#" character and zero or more comment characters.

There's a neat Perl program on my board that reads Perl source and emits html output. As the comments are output unprocessed, you can use HTML in the comments: lists, tables, images, ...

However, the processing that splits the Perl source into statement and comment does not use Perl's regex. It reads like a C program: got a quote character? Read forward until the matching close quote. Got a forward slash? Set the "in regex" flag. In regex, got a "["? Set the in character class flag. Got a "\"? The next char is escaped. And so it goes.

Challenge:

If you love your Perl and your Tim Toady, meet this challenge: write my "pl2html" program using Perl's regex. If you can get that done, I'll substantially revise this post.

Monday, August 10, 2009

The Big Gulp Method

Movie Review:

Julie and Julia

"Most strikingly, this is a Hollywood movie about women that is not about the desperate pursuit of men."

This blogger is NOT a moviegoer. For a movie about Julia Child, I make an exception. Mastering the Art of French Cooking was one of my bibles. Child's shows on PBS were my inspiration. Over the years my cooking has moved south: olive oil has replaced butter, seafood has replaced beef. Still, it all started with Julia.

The Big Gulp Method:

One of the Java-beginner articles on my website suggested that reading a file using Java's streamIO, as was universally suggested in every book I ever saw (my own excluded), was slow, foolish, and too much work for programmer and computer alike.

This was all that you needed:


RandomAccessFile raf = new RandomAccessFile
( "C:/mrwebsite/articles/raf.html", "r" );
bytes = new byte[ (int) raf.length() ];
raf.read( bytes );
raf.close();


In Python, that simplifies to:


file = open( pathname )
arr = file.read()
file.close()


In Python you can also use file.readlines() to populate an array with a text file, one line per array element. This feature is also available in Ruby with near-identical syntax and identical simplicity.

Of course, all of the above is simpler than file I/O in a finished application. Whatever the language, you have to try the file input (does the file exist?), catch errors and provide options for the user to recover from the errors.

Still, the big-gulp method of reading the file into a byte array (or line array, for text) is fast and easy.

Typical Tutorial:

So why do we still see this?


a = open("sample.txt", "r")
line = a.readline()
while line:
    print line
    line = a.readline()
a.close()


That bit happens to be from about.com, but it's typical of what is given to beginners. Beginners do as they are shown and we are doing file I/O in a way that made sense when RAM size was measured in kilobytes, not gigabytes. And so it goes.

Friday, August 7, 2009

JavaScript, Again

Opinion in Fortune:

"... most dismissive report ever produced by a Wall Street analyst" Fortune's Apple-watcher summary of an analysis of Microsoft's plan to launch stores to compete with Apple stores.

JavaScript, Encore:

The function concept and the basic syntax goes back to Fortran, c. 1960. (Born in 1956, Fortran, now structured and object-oriented, is still alive and well where scientists need to do serious number crunching.) In Fortran-descendant C you would write:


function add (num1, num2) {
    return num1 + num2;
}

(Actually, it's been a long time since someone wrote an "add" function, but you get the idea.)

That code will run, with only minor changes, through a wide range of compilers and interpreters, including Ruby and JavaScript. Unlike any of the others, here's JavaScript's functional programming alternative:


add = function( num1, num2 ) {
    return num1 + num2;
}


With the code in variable "add" you can use "add" like any other variable. For example, you can pass it to another method:


foo = function( bar ) {
    return bar(2, 2);

foo( add );
}

"foo" is a function with a parameter named "bar". "bar" is a method that foo will call with the arguments "2" and "2". This is certainly the hard way to get to four, but it has lots of powerful uses. Passing a comparison method to a sort routine, for instance.

This also means that in JavaScript, as in C, you can have an array of functions as easily as an array of strings (and without C's pointer mess). If you've ever needed an array of methods where you can't have one (Java comes to mind) you know how important this is.

Perhaps the best thing about this syntax is its pythonicness. Python itself has this capability but in a messy way with lambda functions. I do hope that the designers of future languages will learn from this innovation. (I doubt it, though. For functional programming you would study Lisp, as Python's designer Guido van Rossum did, and come up with lambda functions.)

Thursday, August 6, 2009

JavaScript

First, All the News that Fits

NY Times, yesterday: Google’s Android Jumps to the Living Room

Earlier this summer: Microsoft Wants Gadgets to Run Windows

JavaScript

You have people writing JavaScript right now. You did not choose this language. You did not invent the Internet. (Al Gore did, remember?) Brendan Eich, then at Netscape, invented this small scripting language for the then-dominant Netscape browser. If you want to run code within your visitor's browser (something as simple as rotating product pictures) you can do this in any language you choose, provided you choose JavaScript.

Yesterday I was writing JavaScript. SketchUp Rubies, written in Ruby, run their user interface in browser windows. Half or more of a Ruby may be JavaScript, not Ruby.

Actually, I don't write JavaScript. I write the subset that Doug Crockford (Yahoo's JavaScript guru) identifies in his book JavaScript: the Good Parts. JavaScript has other parts, but you can ignore them without losing any functionality. Stick to the good parts. Here's one:

python = {species:'python sebae', diet:'vegetarian'};

python.name = 'Monty';



I just created an object named "python". It had two characteristics (data members, if you prefer), "species" and "diet". (No, python sebae is not a vegetarian species. This is my pet python. I don't want him to eat the kitten.) After creating the object, I gave it another attribute, "name". No, there is no class from which this object was instantiated. As yet, python has no methods.

More exactly, python is an Object. Object is the superclass of all objects. As a practical matter, this is important if you are creating a JavaScript interpreter. You can ignore it if you are writing JavaScript.

This simple syntax (I'd call it pythonic!) is the basis for JSON, JavaScript Object Notation. JSON, invented by Doug Crockford, is a simpler alternative to XML for storing and retrieving objects. (For security reasons JavaScript cannot do disk I/O except for cookies. JavaScript plus X is needed for generalized disk I/O. For SketchUp Rubies, X is Ruby and the SketchUp API.)

Where JavaScript gets most pythonic is in its functional programming, which is a thing of beauty. I'll see what I can come up with for that topic tomorrow.

Wednesday, August 5, 2009

Not Well-Known for Marketing Prowess

In the News:

Business Week on Google Marketing Apps

Google apps (I've tried word processing and spreadsheet) are good and getting better. Now GOOG wants corporate America to buy premium versions at $50/seat/year. Enter a big billboard campaign backing a 400-person sales army.

Analysis:

8 persons per state. Let's blanket New York. We'll have 4 persons for the NYC metro area, one each in Albany, Binghamton, Buffalo, and Schenectady. We'll spread the metro folks one each in Westchester, Manhattan, the other boroughs and Long Island.

OK, that's not fair. New York will have twice the average, because it's a populous state. So in Manhattan we'll have one person covering finance, another covering advertising.

Stop! Too much sarcasm, Martin.

Reflection:

I've done marketing in Manhattan for a small time-sharing company. We had eight sales people backed by me and a half-dozen engineers.

Oracle, before the Sun acquisition, had just under 20,000 people in sales and marketing. That's an order of magnitude estimate of what you need to market to the world.

In the quarter ended June 30, 2009, MSFT spent 24% of revenue on sales and marketing. In the same quarter GOOG spent 9%. Clearly these are different business models. Let's ask Wall Street what it thinks of these two companies.

GOOG's revenue, latest quarter, was about one third of MSFT's revenue. GOOG's market cap was about two thirds of MSFT's market cap. Wall Street's opinion is that GOOG will grow its earnings a lot faster than MSFT will.

Summary:

So the question is this: should Google add a serious marketing effort to sell apps? If I were Google I would say no. I'd pick just one small target (e.g., drug companies) and look to convert that segment.

There's no real hurry about this. MS Office still dominates a market when the competition, Open Office, is free and superior in many ways.

Every fact in this post was extracted via Google searches. The spreadsheets (all .XLS) that I downloaded along the way were viewed and crunched with OO.

Tuesday, August 4, 2009

Python on Python

Yesterday my python slithered off, mad because I was writing Ruby. I feared he'd swallow the kitten. Since Python lets you create attributes on the fly, I solved the problem:


python.diet = 'vegetarian'


Actually, Python has nothing to do with snakes. The name comes from the British comedy troupe, Monty Python. My python is named Monty. Ruby gets its name from lists, such as wedding anniversaries, where Ruby follows Pearl.

When Python and Ruby engineers debate the merits of their respective languages, the discussion is generally learned and respectful. Monty, on the other hand, can really get going.

"Hey, Monty! Want to talk about Tim Toady?" (He never passes this one!)

"There you are. Tell me what you think of Tim."

"Martin, Tim's a fraud. There's maybe sixteen different ways to loop through an array in Ruby. You got some hotshot coder who never does it the same way twice. OK, boss. Who's going to maintain that crap? Some junior coder who just learned Ruby? I don't think so. You're stuck with hotshot. Hope you like paying his six-figure salary."

"Let's show a little real code." Monty dictates a little Ruby and Python.
Python



ids=[...] # array, listing division's employee ids

for id in ids
    # code processing
    # each id

Ruby


ids=[...] # array, listing division's employee ids

ids.each { |id|
    # code processing
    # each id
}


"You could write that loop other ways in Python, but no one would. That's the one, obvious way to do it. Ruby dudes will write every loop differently to show off their Tim Toadiness. And no, I did not forget curly braces in Python. You indent and you get code that looks like, and is, blocked."

"I could go on, Martin, but I just got this sudden urge for some broccoli. Broccoli? I never ate broccoli. What's going on?"

Monty slithers off. Actually, in Ruby looping by the "each" method is the preferred way, in most instances. The simplicity of the Python illustrates the quality that Pythonistas call "pythonicness."

Monday, August 3, 2009

Ruby, Python and Tim Toady

In the News:

Why Bing Is Gaining on Google

A triumph of creative headline writing. Bing soars from 7.2% to 8.2%. Google: 78%. Yo, Steve. When your competitor's name becomes a verb, they've solved the problem. If you don't want to take my word for it, google it.

Python v. Ruby:

Executive summary: two excellent modern, multi-paradigm languages with fiercely partisan fans who never tire of arguing for their personal choice. In the end, the one you prefer probably depends on where you stand on Tim Toady.

First, the basics. Both languages are interpreted, not compiled. Both are more than fast enough for business computing. Neither is strongly typed. Neither is more error prone than, for example, Java.

Both are object-oriented. Almost everything in Python is an object. Everything in Ruby is an object. (In Ruby, "2+2" is a notational convenience for "2.+(2)". That's an object "2" with a method "+" called with another "2" object as argument.)

Ruby's OO constructs are more Java-like. Python's object model struck me at first as chaos. You start with what in C++ or Java would be two instances of the "dog" class, "fido" and "rover" for example. If fido does tricks, you stick an array field to him: "fido.tricks = ["jump", "roll over", ...]. No need to extend any class, no problem that rover has no tricks.

Multi-paradigm means that unlike Java, you use OO coding when it works for you. You use other techniques and you don't force OO solutions on non-OO problems. For example, both support functional programming: the ability to pass code around and manipulate it as easily as other traditional languages handle strings.

Big difference: Rails. Ruby on Rails is the Ruby language with the Rails website framework. The Rails framework gets all the attention of the Ruby community. By contrast, Pythonistas are split among multiple frameworks, none enjoying the effort put into Rails. Rails JavaScript framework, Pythonistas argue, is based on Scriptaculous which is based on Prototype which has an enduring reputation for bad code.

Both languages work. Spectacular websites can be built successfully with either. Both will give you the same results as you could get with Java EE but with much less code, which will simplify maintenance. Would I recommend one or the other? For me, yes I would. For you? I would not. That's because I have a definite stand on Tim Toady.

Tim originated in Perl (which I recommend you avoid if at all possible). TMTOWTDI: There's More Than One Way To Do It. "Tim Toady" is the way it's pronounced. Ruby, which was designed as a better Perl, features Tim Toady. Pythonistas say, "There should be one, obvious way to do it."

I'd say more on this, but my Python just saw the Ruby code on my screen and slithered away looking very mad. I've got to find him before he swallows the kitten. (Why Ruby? SketchUp plugins can be written in the language of your choice, provided you choose Ruby. How can I explain that to my Python?)