26 September 2017

Ten Years Since "Teach Yourself to Program in Ten Years"

Thank you Peter Norvig!

You guys! I just found this, which is (at the time of this writing) the single github repository maintained by Peter Norvig, director of research at Google. It contains several iPython/Jupyter notebooks (which github renders nicely). They explore all sorts of interesting problems and topics in computing. One of them is a journal of his participation in the "Advent of Code" and I've referred to it often as I've strived to understand the solutions to the many challenging problems therein. Check it out!

It was actually quite early on in my exploration of Software Development as a possible career that I stumbled upon the work of Peter Norvig, who I would call one of my first unofficial mentors. At the time I was at a "career crossroads" and read his blog post "Teach Yourself Programming in Ten Years".

That article gave me the confidence I needed to begin chipping away at the seemingly unsolvable problem that was (and still is) computer science. It settled my mind about which programming language I would tackle first (python, of course!) along with a good introductory text.

You see, according to him all I needed to do was get started coding and just keep going for about a decade, working on interesting projects, some as novice, others as a lead. If, at the end of that time I was still learning and enjoying the process, I might be onto something. (Yeah, a career!) By that time I might even approach expert-level status. Hmm, hard to say if that's actually true--probably not, but that's not the point. The point is, this programming stuff is fun!

Anyway, soon after discovering his "Teach Yourself Programming in Ten Years" article I stumbled on his write-up on "Solving Every Sudoku Puzzle". My mind was completely blown at the time. I had no concept for most of the the code, even though his explanations are very clear. Take the opening code block, for example:

def cross(A, B):
    "Cross product of elements in A and elements in B."
    return [a+b for a in A for b in B]

digits   = '123456789'
rows     = 'ABCDEFGHI'
cols     = digits
squares  = cross(rows, cols)
unitlist = ([cross(rows, c) for c in cols] +
            [cross(r, cols) for r in rows] +
            [cross(rs, cs) for rs in ('ABC','DEF','GHI') for cs in ('123','456','789')])
units = dict((s, [u for u in unitlist if s in u]) 
             for s in squares)
peers = dict((s, set(sum(units[s],[]))-set([s]))
             for s in squares)

The list comprehensions made my head spin ("What's with those backwards for-loops? Is that really valid python code?"). I had no concept for how those few lines of code could possibly represent an entire Sudoku grid in a way that was helpful for coding a generic solution to any valid input. You can imagine that if the initial calculations were beyond me, well, I was completely unprepared for his search algorithm implementation based on constraint propagation that put the finishing touches on the article. If only someone could have taken me through the code step-by step at the time...

Would I ever be able to 'grok' what he did in those few hundred lines of code? The good news: Yes, even though I still wouldn't call a perusal of his code 'casual reading'. The even better news: after almost 10 years learning to program I'm still loving it and I feel just as hungry to learn as I did when I first stumbled on Norvig's Sudoku solver. Rather than be discouraged about all the things I still don't know, I'm encouraged every day by all the things I can do by leveraging a computer.

Norvig has even teamed up with Udacity as an instructor on at least two of their courses:


For nearly ten years I've been looking forward to the time (now!) that I could look back on these early years of experience as a programmer and come to the conclusion that the difficult choice to leave other important things behind was, indeed, worth while. Thank you Mr. Norvig for your encouragement and for sharing your insights and knowledge with the world!