The Limber Lambda

Eric Smith’s technical musings

Doing a Good Job

with 2 comments

I’m going to say something shocking …

Your degree that you worked for for years doesn’t mean a whole lot.

I can say that, because I was living proof.  I studied for six years and ended up with a masters in electrical engineering.  At the end of it all though, there’s only one pertinent question:

Can you do a good job, consistently?

And, I’m ashamed to say that at that time, as a fresh start in my first job, I could not reply “yes” to that question, at least according to my present-day definition.

So, what does “good” mean? you may ask.  Good point.

It can be argued that it’s in the eye of the beholder, but “good” can be characterised by a range of things and it’s pretty much universally recognisable:

  • It’s complete.  The proverbial i’s have been dotted, and t’s crossed.  It’s been checked, and cross-checked.  Complete has an “aroma” to it—you actually want someone to look at it—you’re proud of it.
  • It’s timely.  Part of “good” is sticking to your word—you said it would be finished by the end of the week?  Make it so, by hook … or by crook.
  • It’s succinct.  There’s been an effort to ruthlessly focus on what’s important.  Just because the annual budget is important, it doesn’t have to be voluminous.
  • It’s correct.  That means you’ve proof-read it, and possibly even got someone else to proof read it.  If it’s code you’re writing, you’ve written automated tests to confirm that it behaves the way it’s intended to.
  • It has built-in continuity.  Someone needs to extend it or enhance it?  No problem, there’s a Readme that bootstraps you … and the code is “literal” (not necessarily Knuth’s definition, but aspiring to be).  The way to nail this one is to regularly put yourself in the next persons shoes.
  • It’s transparent.  It’s built to be absorbed by other human beings—there are no gotcha’s.  If it’s code, it isn’t too “clever”.
  • It fails fast.  When you build something, you need to be in the place where you know it’s going to fail.  Good is not perfect.  So when it fails, even when the condition seems innocuous, fail fast and fail hard.  That’s because too much energy is expended on hiding and fretting than failing and fixing.

The thing to notice about all the points above is that they’re not actually taught at school, not explicitly at least.  For me, that’s ironic—because knowing what I know now, I would take someone who’s got those things down pat any day over someone who has a PhD but who can’t deliver.

So, it’s worth ruminating on today: “Am I doing a good job?”.

Written by Eric Smith

December 2, 2009 at 5:38 AM

Posted in Opinion

Mort Revisited

leave a comment »

Today I attended an interview for a prospective VB6 candidate.  Are there serious developers out there who actually want to develop in VB6 going forward, without a prospect of perhaps moving onto a newer platform?  Apparently there are.

Asks I: Can you tell me what polymorphism is?

Says prospect: [paraphrased] It’s when you have a method that takes two parameters, say x and y and another method with the same name that takes three parameters, x, y and z.

Asks I: Say for instance you have an array of strings … a bunch of names of people … but they’re all jumbled up, how would you get them into alphabetical order?

Says prospect: I would do an “order by”.

Asks I: Can you tell me what COM is all about?

Says prospect: It has to do with objects and DLL’s (waves hands in air for effect).

Asks I: Can you tell me what a hash table is?

Says prospect: No [pause] … [a "go-on-give-it-a-go" nod from me]

Says ex-prospect: Aren’t you going to tell me?

Evidently Mort and his cohorts are alive and well and being paid real shekels for propping up those critical business systems.  Afterwards a colleague called me out for asking irrelevant questions like … well, who in the world is expected to know what polymorphism is?  Especially in the VB world (puh!).

This just re-affirms my (reluctant) assertion that it doesn’t really take rocket scientists to keep critical business systems running.  It doesn’t even take people who are mildly interested in furthering their career of choice.  When the proverbial hits the fan, folks may end up running around screaming blue murder for a while, but the problem will be fixed, and more than likely it’ll be fixed with a little duct tape.  Until of course the tape peels off, and a patch over a patch is required.

Let’s say that again–the system will be fixed.  It might be expensive, it might be inelegant, it might take a couple of days off someones life, but things will carry on, and in a year or two the cross will be borne by a new eager victim, one who may even have been lucky enough to have had a mere brush with a computer science text book (we can only hope).

Sadly I have no wise rebuttal right now, because the numbers just aren’t there.  And that is, simply put, why some people can play pied piper to the development masses and lead them into dubious territory.  Our industry is a young one, too young still for the toll of poor practice to be quantified.  My most effective contribution right now then is to continue playing disciple to the way of Uncle Bob and hope that one day, all will be converted.

Written by Eric Smith

November 3, 2009 at 5:00 PM

Posted in Opinion

PubSubHubbub Hullabaloo

with 2 comments

Anil Dash recently wrote an article on what he calls the Pushbutton Web, a catch-all term not dissimilar to AJAX that describes the popular concept of technology initiatives related to the real-time web.  The assertion is that open protocols like PubSubHubbub are the future means by which we’ll get real-time updates, that is, the real-time web will no longer be the exclusive domain of semi-proprietary protocols like those used with Twitter and Friendfeed.

PubSubHubbub sets out a way for subscribers to be directly notified when there’s an update to a providers RSS or Atom feed.  Here’s how it works:

pshb

  • Firstly, the content provider (Any RSS source such as FeedBurner) requests a selected hub to respond to future notification pings about updated content (1);
  • When a subscriber (choose your RSS reader) asks for content (2), the response (3) contains not only the newest articles but also some metadata informing the client that there is one or more hub that can be used for notifications;
  • Subscribers subscribe to content updates by asking the designated hub for updates (4);
  • As updates come in (5), they’re broadcast to interested subscribers (6).

Something key that I haven’t mentioned about the diagram above is that the lines represent HTTP requests and responses (blue are requests, green are responses).  The dotted lines represent the “push” part of the protocol.  Something that’s noticeable to anyone who’s ever had to do any networking or administration of a firewall is a rather naive assumption about the connectivity between the hub and the Subscriber.  Now, if by “Subscriber” we’re talking about your typical Internet-connected workstation, then there’s something missing in this picture.  That’s because the vast majority of Internet connected workstations connect via a firewall or a NAT device.

In practice, this translates to:

 pshb2

And trying to hunt down a response by the designers to this little snag reveals:

"I’m behind a NAT. Can I subscribe to a Hub? The hub can’t connect to me."
Anonymous
 

No, PSHB is a server-to-server protocol. If you’re behind NAT, you’re not really a server. While we’ve kicked around ideas for optional PSHB extensions to do hanging gets ("long polling") and/or messagebox polling for such clients, it’s not in the core spec. The core spec is server-to-server only.
Brad Fitzpatrick, San Francisco, CA
 

Looks like the final word on the matter. PSHB is not intended to be used by Internet connected workstation subscribers.  How then does PSHB help us get closer to an open-standard Twitter or Friendfeed?  In the short term, at least, it doesn’t.

So, to conclude, for all practical purposes, our “real-time-web” world is going to be one of piggy-backing the HTTP response, in it’s various incarnations.  To the purist, this spells “hack” and PSHB clearly hasn’t compromised on this one.  Hopefully firewall vendors out there will build in the ability to respect and forward incoming PSHB notifications at some point.  Until then though, the Internet will use what’s simple, available and works—that one I will agree with Anil on.

Written by Eric Smith

August 10, 2009 at 8:01 AM

Posted in Opinion

Fun at TechEd 2009

with 3 comments

Today is the penultimate day of my three day stint at Africa’s premiere Microsoft event.  Things have improved significantly from the dull-and-wet environs that I stepped out of the plane into two days ago, to a very pleasant, warm and cloudless tropical playground.  Too bad I haven’t had a chance to do any “fun in the sun”.

The event itself has been very well organised thus far, starting with a cool, hip and happening keynote and intro party on Sunday evening.  Being the staid geek that I am though, and despite the extremely enticing party hats and masks, I left early.image

Monday was a mad-rush to make very efficient use of my time, and not a moment was wasted on anything but sessions … one after another with on average, less than 20 minutes between each one.  From sunrise to sunset, no time for lunch (lunch packs were provided for those whose information appetite overshadowed their gastric cravings).  Sadly, my eagerness has since waned.

Let’s do a walk-through to date:

Monday, August 3rd

Starting the day, Brian Noyes told us about new tools and controls for WPF.  Brian is clearly very sussed when it comes to the relatively new “dub-effs”, namely WF, WCF and WPF (anyone know what happened to CardSpace?) and I’m quite sure it doesn’t stop there.  This demo-driven talk was thorough, and correct, and aimed just right re the audience.  Problem is … I found myself nodding off.  That may of course be an indication of my generally poor ability to focus—I’m going to give Brian the benefit of the doubt here.

Next up was Bart de Smet, with a talk on how to deal with the inevitable paradigm shift from Hertz to cores.  I subscribe to Barts blog, but I have to admit that I usually set aside half a day to read any new entries, since it’s not exactly light reading.  This guy is super-bright;  we’re talking a young Richard Feynman with a sense of humour to match.  In any case, a very technical subject was dealt with deftly, and we got to hear about all the various incarnations of Microsoft’s attempt to give us a developers a way of “spreading out” to multiple cores.  The principle message here being that there’s no silver bullet (meh).

Ahmed Salijee then gave us a fairly comprehensive overview of what’s new in .NET 4.0.  Apart from the new WF stuff, there wasn’t anything that I hadn’t already gleaned from a rather old PDC Anders intro that I’d watched quite some time ago.  Ahmed was our first South African presenter, and held the flag high.  I would say though that the pre-arranged code snippets made things a little difficult to follow, but given the huge amount he got through in the relatively short amount of time, it was a noble effort.  At least everything worked!

Now jQuery is just so super-cool that I couldn’t resist the session by Hilton Giesenow on the same.  Hilton is made for speaking and there wasn’t a moment where I found myself distracted.  Everything was demo’d using the awesome Firebug to such an extent that at one point I was wondering if jQuery’s glory hadn’t been stolen by Firebug.  Of course, all the demos happened in Firefox which made the presentation all the more satisfying.  Hilton has awesome potential, but wow … things went pear-shaped.  The little bits of code that he demo’d were hand-written, and well … didn’t work.  There were regular appeals to the audience of “can someone see the problem here?”.  Just a little bit of prep can make a world of difference, Hilton.

Tuesday, 4th August

I was scheduled to attend Brian Noyes’ talk on developing service oriented workflows, but since I’d forgotten my caffeine tablets at the hotel, I opted to try out Jayesh Mowjee’s non-dev talk.  Jayesh endeavoured to inspire us with a Windows 7 security overview.  Jayesh is a seriously dynamic speaker and could probably do some stand-up moonlighting; he’s that confident.  He also knows his stuff.  Being a dev at heart, I can’t say I was inspired to preach his message from mountain-tops—let that be no reflection on his abilities though.  So what’s new in Windows 7 security?  Erm … lots of cool audit trails that’ll keep your annually visiting Delloitte and Touche droids happy as pigs in the proverbial.

Up next: John deVadoss on Windows Azure and the Cloud.  It’s funny how a small glitch in someone’s talk can ruin the whole thing—like not being able to connect to your box at Redmond so that you can do your key demo—the demo that makes or breaks your session.  Someone should have told John that we have a virtual telecoms monopoly in South Africa that on Monday just so happened to be the victim of a wage strike.  So do an rdesktop with 24-bit colour at high resolution over that thar Internet connection … at your peril.  The content?  I forget … still having flashes of embarrassment on Johns behalf, as his presentation went into an unrecoverable tail-spin.

After an extended break I attended Donald Farmers talk on a groundbreaking initiative, namely Gemini.  This presentation was stellar.  Donald went to great lengths to prepare a novel presentation for us—completely different from the somewhat tired bullet-point infested standard PowerPoint slide-set.  He used a great metaphor of the evolution of a bicycle for everyone’s workhorse … Excel.  Tandem bicycles represented Excel extended for workgroups, bicycles with shoe-spoked wheels talked to Excel being used as a square peg being pushed into a round hole, an envious kid looking on as friends ride their shiny new bikes past, communicated how everyone wants the latest-and-greatest incarnation of Excel.  All in a retro setting, for effect … a great, fresh, unexpected approach.

Oh, and the content was good too.  I got excited by this stuff because it promises to address a pervasive issue that’s close to home.  It’s the story of how in any organisation, the systems story doesn’t end at those systems that are looked after by us IT people.  There are a myriad systems out there that we don’t know about.  They may be mentioned idly in conversation—if we’re lucky.  They may be mentioned when they fail, and, unbeknownst to any IT staff, just happen to support a critical function in the business.  They live inside Excel, on a business-persons desktop.  Gemini promises to address this issue—make it maintainable, sustainable and monitor it.  Instead of chastising business for building un-maintainable spreadsheets, it supports this practice, but fills in the gaps, by providing an interactive OLAP-like experience, right inside Excel, and by tracking data that’s used by business through integration with Reporting Services.  An emphatic thumbs-up to Donald for what I’m sure we will see become the next killer app.  Excel hasn’t seen an enhancement this momentous to date.

Now, that’s not really everyone, it’s just everyone who made an impression on me.  I do get the impression though that TechEd Africa is seen as kind of a presenters sandbox.  This is because, in general, there was somewhat of a lackadaisical approach to presentation from the overseas presenters (that is, except for Donald and Bart)—almost as if it didn’t matter too much if there were screw-ups … it’s Africa after all.  The basics just weren’t covered—like doing a little research into the nature of Internet connectivity in South Africa (it’s nothing like what one gets in the States), and not hinging the better part of your presentation on an RDP session to some server at Redmond without testing it beforehand.  That’s just plain unprofessional.

In general there was also a disparity in quality of presentation between overseas presenters and local presenters—for that reason I tended to favour the Americans when choosing sessions.  Eben de Wit and his entourage could have geared up the pre-keynote prep before inflicting numerous demo failures on the audience.  I didn’t appreciate the anti-Linux gag when demo’ing the systems management stuff either, everything about Microsoft’s recent culture shift says that we’ve all moved on from juvenile sniping.

Is there anyone I haven’t managed to slag off yet?  Seriously though, all-in-all a pretty well organised affair, even though the general quality of presentations could be upped a notch.  Apart from Donald’s talk I can’t really say that I learned anything earth-shatteringly new … well … I did get to read about booting VHD’s from Windows 7 on Scott Hanselman’s blog during an inter-session break :).  In fairness, the jury isn’t out—perhaps today I’ll be completely blown away by some newfangled technology that allows you to remote to a Windows server over a flaky 54kbps connection using 10000:1 fractal compression whilst making things seem like you’re on the LAN … but I doubt it.

UPDATE: The ending keynote by Arthur Goldstuck was definitely worthwhile, otherwise Lynn Langits talk on migrating applications to Windows 7 was enlightening.  Morne Blakes “level 400″ talk “Case of the Unexplained 3″ (Mimicing Mark Russinovich’s notable series) left a whole lot to be desired and definitely wasn’t as advanced as it promised to be (pretty much everything he said I already knew).

Written by Eric Smith

August 5, 2009 at 5:05 AM

Posted in Uncategorized

On Exceptions

leave a comment »

A while ago, Justin Etheredge posted an article on best practices for when, when not, how and how not to program with exceptions in .NET.

For the most part, I agree with what he says in this article, but felt that I needed to blow my own horn on some of these issues since I get to see some fundamental misunderstandings (“misgrokkings”?) on the purpose of exceptions in code that is written by some of the guys here.

Part of me wants to start off with a tirade on the definition of the word exception, but I’ll spare you and skip that—suffice to say that exceptions really are that; they’re not supposed to be something we worry about or deal with during most of our programming—they’re … well … exceptional.  They’re supposed to be part of that whole managed thing that everyone keeps talking about.  Do you remember the good old days of C programming where everything returned an int to keep track of errors (even if that int being non-zero occurred only 1% of the time?).

In any case, a list of Smith’s rules around exceptions follow.

Rule 1: Relax, don’t Catch It

For the most part, really—carefully consider the reasons for catching exceptions.  The only times you should catch exceptions are:

  • When you need to do some kind of teardown or cleanup, regardless.  That’s why we have finally—so this isn’t really a reason for catching an exception after all;
  • when you need to align the exception with the context of what you were trying to do—a typical example of this is where an unexpected runtime exception such as NullReferenceException is thrown and you want to provide some more problem context, so wrap it in a more meaningful exception and throw;
  • When you absolutely have to recover gracefully from a condition that would normally terminate the application—be really careful here – continuing on in what will essentially be an errant state can lead to even more problems;
  • In order to log an error using a logging subsystem.  There should really only be one of these—just before the exception is about to fall through to the runtime.

Rule 2: Be Specific

When catching exceptions (and after some long, hard deliberation to reach this decision), try to be as specific as possible.  We’ll want to do:

catch (IOException ioException)
{
    // Stuff...
}

… and not:
catch
{
    // Stuff...
}

Rule 3: Don’t Throw Stuff Away

Ok, I couldn’t resist that small pun—by doing this sort of thing, we are throwing information away:

catch (NullReferenceException e)
{
    throw new InvalidOperationException(
        “The dooda can’t be used with a gidgimigadge: “ + e);
}

We would rather want to do:
catch (NullReferenceException e)
{
    throw new InvalidOperationException(
        “The dooda can’t be used with a gidgimigadge“, e);
}

The latter preserves all stack trace information, the former throws it away.

What you hide will bite you

Someone once said to me:

Ignore small problems, they’ll either go away or become big problems.

I’ve tried to keep this article positive, but I just have to have a word on this one … as someone pointed out, everybody loves code they can hate, and this is my personal sleeping blanket:

try
{
    // Stuff...
}
catch { }

This is known as exception burying.  image

In my earlier days as a developer, tinkering with various obscure scripting languages (the more arcane, the better), I bumped into Perl.  When they say that you can do something in more than one way with Perl, that’s a gross understatement—this is why I said my goodbyes to the language some time ago.  Apart from not being able to remember all of the syntax due to it’s sheer size, because the syntax is so ambiguous, you can end up writing stuff that is perfectly legal but doesn’t do what you want it to.  My initial self-high-five after writing my first Perl program and having it run without any errors quickly turned to dismay and frustration when it didn’t appear to work.  That’s because unless you “use strict” in Perl (or the ‘-w’ command-line switch), it just works … in particular, things like referencing variables that you’ve neither declared nor assigned to is just hunky-dory.

My point is: warnings and errors are good, not bad, they provide visibility into your program and give you hints about what may turn out to be problems later on.  They allow you to avoid days of trying to track a bug down because an errant condition is being buried.  Don’t bury exceptions.

A word on the appropriateness of exceptions being thrown

The .NET base class library provides a range of generic exceptions that can be used to report errors (including ArgumentException, InvalidOperationException, NotImplementedException, ArgumentOutOfRangeException and various others), and these should be used if at all possible.  The important thing though it to distinguish between exceptions that have been built to be thrown by your code, and ones that haven’t.

I can’t really think of valid situations where NullReferenceException and OutOfMemoryException should be thrown in your own code—these are things that you would catch (once again, that decision needs to be made carefully) but not throw.

Written by Eric Smith

July 15, 2009 at 6:17 AM

Posted in Development

“Sharpen Up” Series: Episode 7

leave a comment »

Do you know what a pandigital number is?  Following is the definition from Wikipedia:

“In mathematics, a pandigital number is an integer that in a given base has among its significant digits each digit used in the base at least once, for example: 1223334444555567890.”

Project Euler problem number 32 modifies the definition a little for the sake of convenience:

“We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once”
Note the deviation from the official definition:
  1. 1 to 9 instead of 0 to 9
  2. Each digit occurs only once, instead of at least once.

Now if the definition is extended to a multiplicand/multiplier/product identity, that is, like this:

39 × 186 = 7254

Then the problem becomes:

“Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.”

A “hint” is provided, although I think that this is less of a hint and more of “additional instructions”. As it turns out, the set of answers has multiple identities that result in the same product (and these are not the obvious transpositions of multiplicand and multiplier as one might think), so where there are duplicates, only one instance of the product should be added to the total. As an example:

18 x 297 = 5346

27 x 198 = 5346

In this case, the second identity is ignored.

This isn’t a hugely challenging problem – I would say the only interesting bit is finding the possible 9 digit permutations. We know that the number of permutations is 9! = 9 x 8 x 7 x 6 x 5 x 4 x 2 = 36288o.  Given the sort of computing power we have these days, churning through that list should be an absolute doddle.

Finding Permutations

I generally try not to defer to “official algorithms” when trying to solve problems like these, and as a result end up implementing something that may work but probably is not the most efficient.  There are various algorithms for calculating permutations, but the one that I came up with is of the recursive variety (recursion is fun).  It goes something like this:

  1. mySwapper = { Given a set of n digits (numbered 1 … n), swap digit i with the remaining digits where i goes from 1 … n.  For each iteration of i, return mySwapper(<remaining digits>) }
  2. mySwapper(<all the digits>)

Note that we obviously don’t need to swap digit k with digit k, but to keep the algorithm neat (read: exception-free) we’ll sacrifice a little performance.

Producing the Sum

Once we have all the possible permutations of 9 digits, what remains is to split them up into multiplicand/multiplier/product parts and test that the product is correct.  Now, since we only have 9 digits, we can make use of some common sense rules re products, that is, a product will always have at least as many digits as the sum of multiplicand and multiplier digits minus 1. The only multiplicand/multiplier/product combinations that satisfy this condition are 2/3/4 and 1/4/4 (well … 3/2/4 and 4/1/4 as well, but these provide duplicate answers).

What remains is to check that we don’t add duplicate products (like the one shown above), and to calculate the sum.  I’ve included the source code in C# below–I’m not claiming that this is particularly efficient at all though, I’m quite sure there are much faster ways of doing this using System.Int32‘s only:

using System;
using System.Collections.Generic;

class ProjectEuler32
{
    static void Main(string[] args)
    {
        var permutations = GetDigitPermutations();
        var alreadyHave = new HashSet<string>();
        Console.WriteLine(
            "Total: " +
            (GetMultiplicationComboSum(1, 4, permutations, alreadyHave) +
            GetMultiplicationComboSum(2, 3, permutations, alreadyHave)));
        Console.ReadLine();
    }

    static int GetMultiplicationComboSum(int multiplicandLen, int multiplierLen, char[][] permutationSet,
        HashSet<string> alreadyHave)
    {
        int sum = 0;
        for (int i = 0; i < permutationSet.Length; i++)
        {
			var productString = new String(permutationSet[i], multiplicandLen + multiplierLen,
				9 - multiplicandLen - multiplierLen);
			var multiplicandString = new String(permutationSet[i], 1, multiplicandLen);
			var multiplierString = new String(permutationSet[i], multiplicandLen, multiplierLen);
			var product = Convert.ToInt32(productString);
            if (Convert.ToInt32(multiplicandString) * Convert.ToInt32(multiplierString) == product)
            {
                if (alreadyHave.Contains(productString))
                {
                    Console.Write("Already have: ");
                }
                else
                {
                    alreadyHave.Add(productString);
                    sum += product;
                }
                Console.WriteLine(multiplicandString + " x " + multiplierString + " = " + productString);
            }
        }
        return sum;
    }

    static char[][] GetDigitPermutations()
    {
        var toFill = new char[9 * 8 * 7 * 6 * 5 * 4 * 3 * 2][];
        var toFillIndex = 0;
        Action<char[], int> permutationFinder = null;
        permutationFinder =
            (ca, ix) =>
            {
                if (ix == 9)
                    toFill[toFillIndex++] = ca;
                else
                {
                    var myca = new char[9];
                    ca.CopyTo(myca, 0);
                    for (var i = ix; i < 9; i++)
                    {
                        var c1 = myca[ix]; myca[ix] = myca[i]; myca[i] = c1;
                        permutationFinder(myca, ix + 1);
                        c1 = myca[ix]; myca[ix] = myca[i]; myca[i] = c1;
                    }
                }
            };
        permutationFinder(new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9' }, 0);
        return toFill;
    }
}

And here’s the output:permutations

Written by Eric Smith

May 13, 2009 at 5:58 PM

Posted in Fun

“Sharpen Up” Series: Episode 6

leave a comment »

A colleague brought my attention to this brain-teaser, from Project Euler:

The series, 11 + 22 + 33 + 44 + … + 1010 = 10405071317.

Find the last ten digits of the series, 11 + 22 + 33 + 44 + … + 10001000

Having a Unix background, my first instinct was to fire up bc which I know can deal with integers of any size you like—such a calculator is known as an arbitrary precision calculator.

Here’s the one-liner, together with execution time:

image

Now, if you’re a Java programmer, you’ll know about java.math.BigInteger which is the implementation of an arbitrary precision integer.  Sadly, in the .NET world there is no built-in equivalent (soon to change in .NET 4.0).

What I did find interesting though was that the default (and only) implementation of integer in a lot of languages, including Python and Ruby is of the arbitrary precision variety (this also applies to Scheme and Lisp).  Since I have two implementations of python installed on my PC, namely cpython and IronPython, I could benchmark them from the command line.

First, cpython: image And … IronPython:

imageUnfortunately the initialisation of the python runtime puts a nasty skew on our comparison in the case of IronPython.

Somehow, that just feels like cheating though, and even though there aren’t any set rules on Project Euler about how you come to the answer, of course, you just feel like you should be doing it a clever way; read: no use of a big integer library, built-in or otherwise.

The solution is simple, but deceptively so—why would we need to keep track of all those “more significant digits” if we never need them?  As long as we keep our eight byte integer from overflowing, we should be fine.  Hence our BigInteger-free C# version:

class Program 
{
    static void Main(string[] args)
    { 
        var largest = 10L*10*10*10*10*10*10*10*10*10; 
        var tot = 0L; 
        for (int i = 1; i < 1001; i++)
        { 
            var exp = 1L; 
            for (int j = 0; j < i; j++)
                exp = (exp * i) % largest;
            tot = (tot + exp) % largest;
        }
        Console.WriteLine(tot);
    } 
}

And the result:

image

Written by Eric Smith

May 12, 2009 at 2:58 PM

Posted in Fun

The Great Microsoft Imposed Development Culture

with 3 comments

imageA while ago I followed up on investigating a popular metaphor amongst developers, namely, “Mort, Elvis, Einstein” (MEE).  I find it ironic that the origin of the MEE meme is Microsoft itself because there seems to be an undercurrent of bigotry surrounding it.  In short, it’s oft cited anywhere where there’s heated discussion about what I call “The Great Microsoft Imposed Development Culture”.

What constantly amazes me is the apparent lack of metrics and measures in development.  Perhaps I just haven’t done enough research, but everything I read (bar Steve Mcconnell’s writings) is full of opinion-laden anecdotal “evidence”.  There’s a whole lot of gut feel, but far too little accounting.  In fairness, that’s probably got a lot to do with how difficult it is to analyse development in that way.  Perhaps though, the most profitable software company in the world has got it right.  They may just have access to “the numbers”, and a neat little formula that takes as one of its inputs an enumerated type, namely, Mort, Elvis, Einstein, and spits out profit.

Wouldn’t such a scenario lead to an optimised developer culture—one that has been optimised for profit?  Of course, a chosen culture leads to a style in tooling as well.  Tools need to be optimised for use by the most cost-effective developer stereotype: you guessed it: Mort.

So, let’s follow this path a little further:

Q: How does Microsoft attract businesses to its platform?

A: Through the provision of a frictionless, feature-rich development platform; one that promotes visibly quick, effective solutions to business problems.

So, sure, IoC is neat and Context/Specification is da-bom, but do these things beat click-drag-and-F5 within Visual Studio backed up by a bit of copy-and-paste?  That question posed within the context of the answer above, as shocking as it may seem, has no objective answer.  Where are the numbers?

I’ve heard Bob Martin go on about the benefits of SOLID, and they all feel right to me, but if this really was as much a science as it should be (compared to say, civil engineering, for example), wouldn’t the sort of heated debate that was sparked by an episode of the StackOverflow podcast be moot?  Dead in the water.  Direct anyone who doubts the benefits of exhaustive unit testing to a neat, ratified theorem or an undeniably convincing set of statistical evidence.  If only we had such a thing.

I am a firm proponent of all things “good” (as opposed to evil, which is what many would label Mort and his cohorts), namely the SOLID principles, continuous integration, consistency of shared code, the DRY principle and various agile practices.  My gut just says it’s the right thing to do.  The question is, is it the most profitable?

Written by Eric Smith

April 30, 2009 at 12:18 PM

Posted in Methodology

The Key to Successful Software

leave a comment »

With a title like that, you’re probably expecting to hear about the elusive silver bullet–that one ingredient that makes projects finish on-time and within budget.  We all know that that’s a pipe dream … or is it?  If there were three things that were the most critical factors in determining if a software endeavour were to succeed, what would those be?  What would the most important of those three be? One word: People (capatilisation intentional).

Joel Spolsky runs a successful software company, and ‘casts to the masses on a regular basis; and guess what makes him excited?  Figuring out the best way to get the very best people on board.  He’s identified the proverbial Goose (that lays the golden egg) and things can only get better.  Developers have the latest toys at their disposal; enormous, luxurious displays, motorised desks and their own offices (with a view!).  Because Joel has realised that once you’ve bagged the alpha geek, the story is only beginning—a really productive “smart and gets things done” geek works best when surrounded by the most scintillatingly cool toys (multi-screen/big screen and really fast machine) and quiet … yes quiet (or put another way–”freedom from interruption/distraction”) makes an enourmous difference to productivity.  Justin Etheredge echoes some of these sentiments in this well-written whinge-fest.  Joel has spared no expense in clearing the path for his people because he groks it.  That being said though, not just anyone is hired at FogCreek and often good people are overlooked, but at the end of the day it’s all in aid of attracting the Best of the Best because once again … he groks it.

When the lone hero development model breaks down due to sheer project size, we need to move onto teams … or groups of co-working people.  It’s just an extension, so excellent people beget excellent teams and as Martin Fowler points out, it isn’t methodologies that succeed or fail, it’s teams that succeed or fail.  Excellent teams will always succeed.

Written by Eric Smith

January 30, 2009 at 6:54 AM

Posted in Methodology

Tagged with

“Sharpen Up” Series: Episode 5

leave a comment »

This one got me thinking for a long time, mostly because I subconsciously eliminated “cheat” solutions.  The problem is to calculate an estimate of π by working out the perimeter of an n-sided circle-inscribing polygon.  Let’s start with some pictures:

Now, the obvious solution (focus on Figure A) is to use a trigonmetric function to solve the problem.  Using a convenient r = 0.5 (implies that the perimeter of the circle is π) one side of our polygon (d) can be determined as follows:

d = 2rsin θ

And since the perimeter of the polygon = p = nd, and r = 0.5, and θ = 2π/2n, then:

p = nsin (π/n)

All too easy, and well … we’re using π to find an approximation of π.  Somehow that doesn’t sit well with me.  Which is the reason why I took two days to come up with a solution that didn’t involve trigonometric functions, or π.  Enter Figure B.

We apply a method of virtual construction–let’s assume a cartesian plane, our circle having centre (0,0), and radius r = 0.5.  The method is iterative, so we’ll need to start with a guess of the length of a side of the polygon, Rguess =Pguess / n, where Pguess is our “perimeter guess”.  Pguess can’t be any larger than π, so let’s make the upper bound = 3.2.  Rguess then forms the radius of a “construction circle”, with centre (x,y), starting at (x0,y0) in the diagram.  The intersection of said construction circle and our original circle will determine a polygon corner; of course, since there are two intersection points, we eliminate the one that has already been “visited” (or occurs where y is negative in the case of the first attempt).  We progressively “construct” our way around the circle n times, each time using the previously determined “corner” as the centre of the next construction circle, finally arriving at the final intersection point: (xn, yn).  If Rguess was correct, then (xn, yn) would equal (x0,y0).  Adjusting Rguess for the next iteration then becomes a case of increasing Pguess if yn turned out negative and decreasing Pguess if yn turned out positive.  A simple zero-by-halving (aka Bisection) technique is employed to get a value for the perimeter that satisfies the accuracy constraint (1e-9).

The source code for my π-less solution is below:


using System;

class Archimedes
{
    public double approximatePi(int numSides)
    {
        double upperPi = 3.5;
        double lowerPi = 0.0;
        while (Math.Abs(upperPi - lowerPi) > 1e-10)
        {
            bool first = true;
            double cx = 0.5;
            double cy = 0.0;
            double piGuess = (upperPi + lowerPi) / 2;
            double lastCx = 0.0, lastCy = 0.0;
            for (int i = 0; i < numSides; i++)
            {
                double[][] intersections = GetCirclesIntersection(cx, cy, piGuess, numSides);
                if (intersections[0][0] == Double.NaN ||
                    intersections[0][1] == Double.NaN ||
                    intersections[1][0] == Double.NaN ||
                    intersections[1][1] == Double.NaN)
                {
                    cy = 1;
                    break;
                }
                if (first)
                {
                    if (intersections[0][1] > 0)
                    {
                        lastCx = cx;
                        lastCy = cy;
                        cx = intersections[0][0];
                        cy = intersections[0][1];
                    }
                    else
                    {
                        lastCx = cx;
                        lastCy = cy;
                        cx = intersections[1][0];
                        cy = intersections[1][1];
                    }
                    first = false;
                }
                else
                {
                    if (Math.Abs(intersections[0][0] - lastCx) < 1e-10 &&
                        Math.Abs(intersections[0][1] - lastCy) < 1e-10)
                    {
                        lastCx = cx;
                        lastCy = cy;
                        cx = intersections[1][0];
                        cy = intersections[1][1];
                    }
                    else
                    {
                        lastCx = cx;
                        lastCy = cy;
                        cx = intersections[0][0];
                        cy = intersections[0][1];
                    }
                }
            }
            if (cy < 0.0)
            {
                lowerPi = piGuess;
            }
            else
            {
                upperPi = piGuess;
            }
        }
        return upperPi;
    }

    private double[][] GetCirclesIntersection(double xo, double yo, double piGuess, int n)
    {
        double e = xo;
        double f = yo;
        double p = Math.Sqrt(e*e + f*f);
        double k = (p * p + 0.25 - (piGuess / n) * (piGuess / n)) / (2 * p);
        return new double[2][] {
            new double[] {
                (e*k)/p + (f/p) * Math.Sqrt(0.25-k*k),
                (f*k)/p - (e/p) * Math.Sqrt(0.25-k*k) },
            new double[] {
                (e*k)/p - (f/p) * Math.Sqrt(0.25-k*k),
                (f*k)/p + (e/p) * Math.Sqrt(0.25-k*k)
            }
        };
    }
}

Written by Eric Smith

November 20, 2008 at 5:33 PM

Posted in Fun

Tagged with

Follow

Get every new post delivered to your Inbox.