1. Git shortcuts

    Posted 2014-01-03 05:03 PM GMT

    Here are a few command line shortcuts I have created to use Git faster. Put these in your dot-files, and you will type much less when using Git.

    First, download .git-completion.bash and put it in your home directory.

    Next, put this line in .bash_profile

    source ~/.git-completion.bash
    

    Finally, put this stuff in ~/.bash_aliases

    #Git stuff

    # use .git-completion.bash to allow tab # completion of branch names when using gch __git_complete gch _git_checkout

    # gs to show git status alias gs='git status'

    # gd to show git diff of uncommitted changes alias gd='git diff'

    # gb to show the list of branches alias gb='git branch'

    # gmm to merge master into the current branch alias gmm='git merge master'

    # gch to checkout master or a given branch # example: # gch my-other-branch function gch { if [ -z "$1" ]; then git checkout master else git checkout $1 fi }

    # gco to check out a new branch based on master function gco { git checkout -b $1 master }

    # gc to commit, optionally with a message function gc { if [ -z "$1" ]; then git commit else git commit -m "$1" fi }

    Go forth, branch and merge with ease.

  2. How Dust Works

    Posted 2013-12-09 10:18 PM GMT

    How Dust Works

    When I started working at LinkedIn two years ago, I had never heard of Dust. Since then, I have had the opportunity to work on the LinkedIn team that develops and maintains the LinkedIn fork of Dust. When I started working on Dust, I decided to take some time digging through the code, to try to figure out how all the pieces work together. At the time, I was taking a Udacity course on programming languages, which proved to be very useful in my study of Dust. This is what I learned.

    Dust Grammar

    The Dust grammar is simple relative to many programming languages, which makes sense considering Dust is a (mostly) logic-less templating language. The grammar defines everything that is significant to Dust, including sections, bodies, references, filters, and helpers. Let's take a look at the grammar that defines a reference:

    /-------------------------------------------------------------------------------------------------------------------------------------
       reference is defined as matching a opening brace followed by an identifier plus one or more filters and a closing brace
    ---------------------------------------------------------------------------------------------------------------------------------------/
    reference "reference"
      = ld n:identifier f:filters rd
      { return ["reference", n, f].concat([['line', line], ['col', column]]) }
    
    In other places in the grammar ld (left delimiter) is defined as {, rd is defined as }, identifier is defined as being a key or a path, and key is defined as a series of characters starting with a-z, A-Z, _, or $, followed by zero or more of 0-9, a-z, A-Z, _, $, or - (and a path is a series of dot separated keys). We could follow the same procedure for every other piece of the Dust grammar.

    dust.parse

    Dust uses uses PEGjs to turn the grammar into a parser. The parser takes any valid Dust template and creates an AST. Let's look at an example. This Dust template:

    Hello {name}! I think you're a cool guy.
    
    creates this AST (by running dust.parse("Hello {name}! I think you're a cool guy.");)
    [
        "body",
        [
            "buffer",
            "Hello "
        ],
        [
            "reference",
            [
                "key",
                "name"
            ],
            [
                "filters"
            ]
        ],
        [
            "buffer",
            "! I think you're a cool guy."
        ]
    ]
    
    The highest level of every Dust template is a body, and that's what we see on the 2nd line of the AST. Inside the body we see a buffer, a reference, and another buffer. From the template we can see that a buffer is plain text, and a reference is { some text }. With an AST, each piece of the source code is clearly identified, ready for a compiler to transform into executable code.

    dust.compile

    Dust templates are compiled to JavaScript. The compiler takes a Dust template (and a template name), runs dust.parse to create an AST, optimizes the AST for compilation, then "walks" through each part of the AST to create the compiled JavaScript. To compile a Dust template:

    dust.compile("Hello {name}! I think you're a cool guy.", "home*")
    

    First the compiler creates the first part of an IIFE (immediately invoked function expression), and creates a call to register the template with the given name:

    The compiled template thus far:

    (function(){
        dust.register("home*",
    

    Then Dust compiles the template starting with the first node (body) of the AST. Each body is a function within the enclosing IIFE, and each of these functions is given a name of the form body_n starting with body_0.

    When a buffer is encountered in the AST, it is turned into something like .write("Hello "). When a reference is encountered, it becomes something like .reference(ctx.get("name"),ctx,"h") (note the "h" filter is applied by default to all references). How .write and .reference work will be discussed in the dust.render section below.

    The fully compiled template:

    (function(){
        dust.register("home*",body_0);
        function body_0(chk,ctx){
            return chk.write("Hello ").reference(ctx._get(false, ["name"]),ctx,"h").write("! I think you're a cool guy.");
        }
        return body_0;
    })();
    

    If you include the browser version of Dust and the above JavaScript on any web page, the template will register itself and be ready to be rendered.

    dust.render

    When you include a compiled Dust template on a web page, the IIFE is immediately executed and template is registered to the Dust cache with the call to dust.register. Now you can call dust.render to render your template. Here's an example:

    HTML before calling render:

    <div id="container"></div>
    
    JavaScript used to render:
    var container = document.getElementById('container');
    dust.render('home*', {name: 'Coach Z'}, function(err, out) {
        if (out) {
            container.innerHTML = out;
        }
    });
    
    HTML after calling render:
    <div id="container">Hello Coach Z! I think you're a cool guy.</div>
    

    How dust.render works

    When you call dust.render, Dust looks for a template with the given name in its cache. If such a template is found, the function related to the template is executed. When dust.register("home*", body_0); is executed, the body_0 function is tied to the home* template, so body_0 is executed. Here's that function again, with slightly nicer formatting.

    function body_0(chk, ctx){
        return chk.write("Hello ")
               .reference(ctx._get(false, ["name"]), ctx, "h")
               .write("! I think you're a cool guy.");
    }
    
    The function accepts two arguments: chk (pronounced "chunk"), and ctx (pronounced "context").

    chk is an object that holds data about the template currently being rendered (especially the rendered output), as well as a number of methods used to render the template (such as write, reference, and section).

    ctx is an object containing the data used to render the template. It is very similar to the data passed in to dust.render (in this exampled, {name: 'Coach Z'}), but it contains some extra metadata and is restructured to make the render process a bit easier. The example data ends up looking something like this:

    {
        "stack": {
            "isObject": true,
            "head": {
                "name": "Coach Z"
            }
        },
        "global": {
            "__templates__": [
                "home*"
            ]
        }
    }
    

    Looking back at body_0, we can see how our example template is executed by Dust. chk.write("Hello ") saves "Hello " to chk to be output when the template finishes execution. .reference(ctx._get(false, ["name"]), ctx, "h") first attempts to find the value of key name in the ctx, then applies filters to that value, then calls chk.write on the filtered value. When the execution is finished, Dust returns output that has been saved to chk. It is worth noting, however, that dust.render does return anything. Instead it takes a callback function which accepts the output as its second argument. This is because Dust is an asynchronous templating language.

    There are a number of other Dust features that make Dust a very valuable tool for building a web application. If you have questions about this post or Dust, you can send them to me or you can ask them on StackOverflow.

  3. How Programming Languages Work

    Posted 2013-12-04 04:48 PM GMT

    About a year ago I finished a Udacity course called "Programming Languages." This course opened my eyes to how modern programming languages work. I recommend it to anyone interested in becoming a better programmer. Here is a very brief summary of what I learned.

    Grammar

    Every programming language (and every human language) has a grammar. The grammar's of human languages evolve over time. Human lanaguages are so extensive, expressive, and ambiguous, that creating an exhaustive formal definition of the grammar is practically impossible. Programming languages, on the other hand, must be completely unambiguous (the computer is incapable of trying to figure out what you meant), and an exhaustive formal definitition of the grammar is a requirement.

    The grammar defines the different parts of the language. For instance, a variable might be defined as any characters a-z, A-Z, 0-9, -, _, or $, but the first character must be a-z or A-Z.

    Parser

    The grammar is used to make a parser. The parser takes code (in the form of a string), and turns it into an Abstract Syntax Tree (commonly referred to as an AST). Parse errors occur when something in your code breaks the grammar.

    Example parse error in English:

    I has good grammars.
    

    Example that will cause a parse error in JavaScript:

    for (var i=0; i<5; i++ {                     // Note the parentheses is not closed here.
      console.log('Why won't this work?!?!')
    }
    

    Abstract Syntax Tree

    The AST can be used by another computer program to compile the code, because an AST is a structured object that gives meaning to the different parts of the code.

    Below is an example of JavaScript code and its corresponding AST (built using Esprima):

    var myName = 'Steven';
    
    {
        "type": "Program",
        "body": [
            {
                "type": "VariableDeclaration",
                "declarations": [
                    {
                        "type": "VariableDeclarator",
                        "id": {
                            "type": "Identifier",
                            "name": "myName"
                        },
                        "init": {
                            "type": "Literal",
                            "value": "Steven",
                            "raw": "'Steven'"
                        }
                    }
                ],
                "kind": "var"
            }
        ]
    }
    

    Compiler

    The compiler "walks" the AST, and turns it into something that can be executed by the computer. Some compilers turn the code into binary, some turn the code into assembly, and some turn the code into some other high-level programming language. Compilation errors happen when the grammar is correct, but the code doesn't make any sense.

    Example compilation error in English:

    I have a goose, and the bus stop merry goes round.
    

    Example compilation error Python:

    def busStop():
        merry = goesRound   #goesRound was never defined.
        return merry
    

    Interpreter

    Some programming languages are not compiled at all. Instead they are interpreted. Instead of being compiled to machine code, the interpreter uses the AST to execute each instruction on the fly. Interpreted languages are slower than compiled languages, but they are generally easier and faster to develop because there is no compile step. Scripting languages like JavaScript, PHP, and Perl fall into this category.

    Next week I will write a post about how all of this applies to Dust.js

  4. Getting Closure(s)

    Posted 2013-10-11 05:48 PM GMT

    Understanding Closures in JavaScript

    When I was first learning about closures in JavaScript, I was very confused. First, I thought it was just Google's open source JavaScript library. I looked on StackOverflow and found a few discussions that were somewhat helpful, but I left more confused than when I started. Then I found a few blog posts, and they were more helpful, but I still wasn't sure if I understood.

    Since then, I have worked with closures quite a bit, and I have realized that they are far more simple than I had originally thought.

    A JavaScript function creates a new scope. Functions can be defined within functions. The inner functions are a part of the outer function's scope, and have access to the variables defined in the outer function. The implications of this make closures useful.

    Scope

    In this context, scope refers to the part of your code where a variable can be used.

    // This is the global scope. Variables declared in this scope // are available in all other scopes. var x = 1; function outer(y) {
    // This is the outer function's scope. Variables declared here are // available in the outer function and the inner function, but not // in any other scope, including the global scope. function inner(z) {
    // This is the inner function's scope. Variables declared here are // only available in the inner function. console.log('x is:' + x); // prints "x is: 1" console.log('y is:' + y); // prints "y is: 5" console.log('z is:' + z); // prints "z is: 6"
    } inner(x + y); // x=1, y=5
    } outer(5);

    The global scope is like the O Negative blood type—the universal donor. Every other scope can use variables defined in the global scope, but the global scope can only use its own variables.

    The inner function is like the AB Positive blood type—the universal recipient. The inner function can use variables defined in all parent scopes (in this case, the outer function scope and the global scope), but no other scope can use the variables defined in the inner function.

    How it's useful

    Sadly, every article I've read on closures stops with an example like the one above. You may have a vague idea about what a closure is, but you have no idea why it is useful. I think a real-world example helps clarify what a closure is and how it is useful.

    Avoiding global variables is widely regarded as a best practice in JavaScript. There are a few methods of doing this, and using a closure is one of them. In this example, I will allow a user to undo a "delete" action if they click the "undo" button within 5 seconds. I'm using jQuery to simplify a few things.

    function setupEventListeners() {
    
      // This variable is the reason we want to use a closure,
      // because it needs to be available in multiple functions,
      // like a global variable would be.
      var undoTimer;
    
      // Cache a reference to the item container and undo button.
      var $itemContainer = $('#item-container');
      var $undoButton = $('#item-container .undo');
    
      // Setup click event listeners
      $('#item-container').on('click', function(evt) {
        var $target = $(evt.target);
    
        if ($target.hasClass('delete')) {
    
          // IMPORTANT:
          // When the delete button is clicked, assign a setTimeout to
          // the closure variable `undoTimer`. Wait 5 seconds before actually
          // deleting the item.
    
          undoTimer = window.setTimeout(deleteItem, 5000);
    
          // Show the undo button so it can be clicked
          $undoButton.addClass('show');
    
        } else if ($target.hasClass('undo')) {
    
          // IMPORTANT:
          // If the undo button is clicked before the 5 seconds is up, clear the
          // timeout (using the closure variable `undoTimer`), so the item does not
          // get deleted
    
          window.clearTimeout(undoTimer);
    
          // Hide the undo button.
          $undoButton.removeClass('show');
        }
      });
    
      // Use this function to delete the item.
      function deleteItem() {
        $.ajax({ url: '/deleteItem' }).then(function() {
          $itemContainer.remove();
        });
      }
    }
    
    setupEventListers();
    

    The setupEventListeners function is only called one time, but the undoTimer, $itemContainer, and $undoButton variables are available each time the click listener's callback function is called, and each time the deleteItem function is called. The fact that these variables are "kept alive" after the original setupEventListeners function finishes execution is what is so powerful about closures. It's really that simple.

    PS This same power exists in any language with lexical scoping.

  5. How to rename hundreds of files in less than 30 seconds

    Posted 2013-09-20 10:48 PM GMT

    I think a solid knowledge of computers is useful for everyone, and not just professional software developers (I built a Chrome extension to track my hours while working as an auditor). In this post I will discuss how accountants (and others) can use the command line (or Windows command prompt) to save several hours of work.

    One of the first tasks I was given as an auditor at Ernst & Young was to copy all of the files from the previous year's audit into the current year's audit folder, then rename them with the correct year. So, accounts_payable_2010.xlsx would become accounts_payable_2011.xlsx, and inventory_walkthrough_2010.docx would become inventory_walkthrough_2011.docx. I thought the copying part would be easy, but then they told me not to copy any of the PDF's. So, I ended up copying everything, then deleting the copied PDF's.

    The renaming part was the hard part. There were literally hundreds of files to be renamed. So, I opened up Windows' file viewer (called Windows Explorer) and started the painfully mundane task. Click on the filename, wait for about half a second, then click again (the second click lets you rename the file), then hit the right arrow, hit backspace, and then type "1", and repeat. About 40% of the time I didn't wait long enough before the second click, and Excel or Word would (slowly) load the file I was trying to rename. I would wait for the file to load, close it, then finish renaming the file.

    After 15 minutes, I downloaded and installed Perl, spent 20 minutes writing a script to rename the files, ran my script, and I was done. I was pretty proud of myself, and my manager was shocked that I was already done.

    Perl was the first programming language I learned, and I think it's pretty great. However, I'm trying to show you that you can rename hundreds (or thousands) of files in less than 30 seconds, and it would take you a lot longer than that to write a Perl script to rename all the files (especially if you don't already know Perl). So, I'm going to show you how to do it using the command prompt (or command line if you're using Linux or Mac).

    1. Open the command prompt

    Windows: Use the keyboard shortcut Windows key + r to open the run menu, then type cmd in the prompt, and hit enter.

    Windows Run Dialog

    Mac: Use the keyboard shortcut + spacebar to open Spotlight, and type Terminal

    Mac Spotlight with Terminal as search term

    Linux: Use the keyboard shortcut ctrl + alt + t to open the Terminal.

    2. Navigate to the correct folder

    When you open the Command Prompt or termnial, you will be in your "home" directory. Use the cd command to move to the correct folder.

    Windows: Let's say the 2012 audit files are in C:\Users\sfoote\audit\2012, and I am currently in C:\Users\sfoote. I can use cd audit\2012 to move to the correct folder. Use the dir command if you're not sure what is in the current folder.

    Windows command prompt, using cd to navigate

    Linux/Mac: You use almost the same command, but use forward slashes instead of backslashes: cd audit/2012. Use the ls command to see what is in the current folder.

    Linux terminal, using cd to navigate

    3. Copy the correct files to 2013 folder

    Windows: I think there is a way to copy only the correct files using Windows, but I couldn't get it to work, so we are going to copy all the files, then delete the ones we don't need (this part may be just as easy to do using Windows Explorer). If you're in C:\Users\sfoote\audit\2012, and you need to copy the files into C:\Users\sfoote\audit\2013, use copy * ..\2013\* to copy the files. Then, if we want to delete all the PDF files, first move to the 2013 directory (cd ..\2013), then use del *.pdf.

    Windows command prompt, copy and del

    Linux/Mac: On Linux and Mac you have the option of only including certain file types as you copy. Let's say we only want to copy .xlsx and .docx files; we can use cp *.xlsx *.docx ../2013:

    Linux terminal, using cp to copy certain files

    4. Rename the files

    Windows: Use the ren or rename command (they both do the same thing) to rename a bunch of files at the same time: rename *_2012* *_2013*

    Windows command prompt, rename files

    Linux: Use the rename command: rename 2012 2013 *_2012*.

    Mac: Mac does not support rename, so we have to do a little bit of scripting.

    mac rename

    I admit, it will probably take more than 30 seconds your first time, but it's still way faster than the alternative.

  6. Faith and Bayes' Theorem

    Posted 2013-09-13 02:27 AM GMT

    Occasionally on this blog I will write about my beliefs and the things I learn about the world based on those beliefs. To learn more about what I believe, please visit mormon.org.

    Recently I learned about Bayes' Theorem, and I have found the implications to be overwhelming. This simple formula is used to:

    • Keep spam out of our email inboxes
    • Help us find our colleagues and friends
    • Help us find a movie to watch or a product to buy
    • Help self-driving cars know exactly where they are on the road

    Bayes' Theorem has also helped me increase my faith. Before I explain that, though, here is a quick intro to how Bayes' Theorem works.

    Bayes' Theorem

    The concept is pretty easy to understand, though the formula is a bit confusing:

    PX|Y= PY|XPX PY

    This formula gives you the probability of X (the unknown) given Y (the observation). A few examples should help clear things up a bit. The example on Wikipedia is great. We'll work through another example here.

    Let's say I'm going on a road trip from Las Vegas to Portland. The trip should take about 16 hours total, with 8 hours driving through Nevada. Let's say I fall asleep at the beginning of the trip, and wake up at a random time in the next 16 hours (we'll say the car is driving itself :). What is the probability that I am in Nevada? Given no additional information, it must be 0.5:

    PNevada= 8 hours in Nevada 16 hours total = 0.5

    P(California) and P(Oregon) are calculated the same way:

    Probability
    P(Nevada) 0.5
    P(California) 0.23
    P(Oregon) 0.27

    Now, I sit up and look out the window and I see sagebrush. I have a little bit more information. Does my probability of being in Nevada change? Is it higher or lower?

    First, we need the to know the probability of seeing sagebrush in the states we will pass through (I'm making this up based on a map from Wikipedia):

    Probability of sagebrush given location
    P(sagebrush|Nevada) 0.8
    P(sagebrush|California) 0.4
    P(sagebrush|Oregon) 0.5

    There is a lot of sagebrush in Nevada.

    Now our Bayes formula looks like this:

    PNevada|sagebrush= Psagebrush|NevadaPNevada Psagebrush

    We can fill in all the values on the right side of the equation, except P(sagebrush). We need to calculate the total probability of seeing sagebrush on the route, which is the sum of the probability of sagebrush in each state times the probability of being in that state:

    Psagebrush = Psagebrush|NevadaPNevada + Psagebrush|CaliforniaPCalifornia + Psagebrush|OregonPOregon = 0.80.5+0.40.23+0.50.27=0.63

    That means that sagebrush is visible during about 63% of our journey. Now, back to Bayes:

    PNevada|sagebrush= 0.80.5 0.63 =0.635

    When I woke up, the probability that I was in Nevada was just 0.5. But, when I sat up and saw sagebrush the probability increased to 0.635. A single observation, and my probability of being in Nevada increased by 27% ( (0.635 - 0.5)/0.5 = 0.27). If I also see a casino or an Elvis impersonator, the probability will keep going up. If I see a tree or rain, the probability will go down.

    Faith

    In the Book of Mormon, a prophet named Alma teaches about faith (Alma 32), and his explanation fits very well with Bayes' Theorem. Thinking of Bayes' Theorem in terms of faith helped me understand Bayes' Theorem. Then, thinking of faith in terms of Bayes' Theorem gave me a new perspective on faith.

    From our previous example, P(Nevada) is called a prior belief. It is our belief of the probability prior to any observations. P(Nevada|sagebrush) is a posterior belief. There are two important caveats to Bayes' Theorem:

    1. The prior belief must be greater than 0 and less than 1, else the posterior belief will always be the same as the prior belief.
    2. The unknown (Nevada) and the observation (sagebrush) must be in some way connected. If not, the observation will have no effect on the posterior belief.

    I first realized this while reading Nate Silver's book The Signal and the Noise, where he explains the concept using examples about politics and religion. These same caveats are critical to faith:

    1. Our prior belief has to be greater than 0 (we must at least have a desire to believe[1]), but less than 1 (if we already know something, there is no need for faith[2]).
    2. We have to be able to observe something that is correlated to the unknown, else our faith can't grow (this correlation and observation are promised by heavenly law[3]).

    With Bayes' Theorem P(X|Y) will never reach 1 (or 0). You cannot have a perfect knowledge of something that can be only indirectly observed. However, after each observation, the posterior belief becomes the prior belief of the next observation, and as we continue to make observations we can eventually have very high confidence that our belief is the truth.

    But, the posterior belief continues to approach the truth only if we are actively experimenting and making observations. In the context of faith, that means that we must act according to our faith, and consciously observe the result. The first time I fast and pray for something, and that thing happens, I may credit coincidence. After years of fasting and praying every month, if I carefully observe the result each time, I can see that coincidence has little to do with it. Faith comes from experimenting on the Word again and again, and always observing the result. Count your blessings, for it is mathematically proven to increase your faith!

  7. When Cars Drive Themselves

    Posted 2013-09-11 03:52 PM GMT

    A few years ago I watched a documentary about the DARPA Grand Challenge. The documentary really affected me, and I have since thought a great deal about the implications of self-driving cars. Since my first introduction to self-driving cars, I have had the opportunity to move to Silicon Valley, and I now work right down the street from where Google's self-driving cars are being developed. I see them almost every day (I saw two on my way home from work yesterday).

    Right now, automated automobiles may seem like science fiction, but they are already out there. Google's self-driving cars have logged hundreds of thousands of miles[1], and Nissan and Mercedes are planning on having self-driving cars hit the road by 2020[2, 3]. To put that into perspective, more time has passed since Cars hit the big screen than we will have to wait for self-driving cars to hit the road. What will the road be like when all cars drive themselves? This is what I think.

    No more traffic

    I never really cared about traffic until I moved to the Bay Area. Living in Las Vegas and Utah, getting stuck in traffic was very rare for me—not often enough for me to really give it much thought. Now, I spend close to an hour stuck in traffic every day I drive to work (I ride my bike about half the time). The cost of traffic in the US (measured as wasted fuel and lost productivity) was $120 billion in 2012[4]. I think about traffic a lot now, and I can see (and feel) that this is a major problem.

    Cars driven by computers can drive with machine precision, which means they can drive closer to each other, which means that we can add a few more lanes to every road without making the roads any wider. Computers don't cut off other computers, or drive distracted, or follow too closely, or brake harder than is necessary, or change lanes unnecessarily, or run into each other. The major causes of traffic would be eliminated. Additionally, cars could organize themselves into platoons to imporve efficiency by reducing air resistance and increasing road capacity and throughput.

    No more stop lights

    When all cars are automated, there will be no need for stoplights. As a car approaches an intersection, the intersection could take control of the car. If it is safe to go through without slowing, that's what will happen. If the car needs to slow to avoid collisions with other cars, or stop to let a pedestrian or cyclist pass, that's what will happen. For everyone who has sat alone for several minutes waiting at a red light, this is an amazing prospect.

    No more looking for parking

    Imagine this. Your car drives you to work, then drops you off at the front door. You hop out (no tip necessary), and the car drives away. Where does it go? Well, that depends. If you're just commuting, you don't really need to own the car, so the car might drive away and pick someone else up. If you do need to own the car (if you have kids, you probably need to own your car), the car finds available parking nearby. When you're ready to go, your car (or a nearby available car) comes to pick you up. No more parallel parking!

    Just to reiterate, in case you missed it, you probably don't need to own a car. You can have all of the benefits of owning a car (and then some), without all the hassle of ownership. It's like zipcar, but better.

    No more collisions with pedestrians and cyclists

    Two weeks ago I was riding my bike home from work and a car pulled out right in front of me, leaving me no time to stop. I broke my leg, and I won't be able to bike or drive for a long time. I am dependent on others for almost everything. I am very fortunate that all I broke was my leg. In 2011, 677 cyclists and 4,432 pedestrians were killed in collisions with motor vehicles[5, 6]. In my case, the driver just didn't look before he entered my lane. Self-driving cars may not prevent every collision with cyclists and pedestrians, but they would prevent most. They would have prevented mine.

    No more collisions with other cars

    Self-driving cars have sensors all over. There are no blind spots, and they see in all directions at the same time. I can't say that there would never be another collision between cars, but they would certainly be a rarity.

    What a self-driving car sees

    No more drunk driving (or distracted driving)

    When people aren't driving, they can't drive drunk, or distracted, or angry. No more DUI's, texting deaths, or road rage related shootings. In fact, no more speeding tickets or parking tickets, either.

    The idea of self-driving cars has interested me for years. My collision two weeks ago has significantly strengthened that interest. I won't stop riding my bike (I actually don't have a bike right now. The one I had broke in half), but I'm going to do what I can to make the road safer for everyone. I am starting by taking Udacity's Artificial Intelligence for Robotics course, taught by Sebastian Thrun, the man behind Stanford's winning DARPA Grand Challenge car, Stanley, and the Google Self-Driving cars. Self-driving cars will change the world for the better.

  8. Computer Hardware for programmers

    Posted 2013-09-10 02:11 AM GMT

    Some programmers know a lot about hardware. I am not one of those programmers. I do know a little, though its probably not even enough to be dangerous. Below I will discuss what I consider the three most important pieces of computer hardware for a software developer to understand. Please correct me where I'm wrong.

    CPU

    The Central Processing Unit (CPU) is the workhorse of the computer. The other pieces of hardware we will discuss are used to support the CPU in some way or another.

    Now is probably the best time to bring up a rather awkward subject. Computers are pretty stupid. They are also very obedient. They will do whatever we tell them to do, with two conditions:

    • They are capable of executing the instructions. For instance, just because you tell a computer to make you a sandwich doesn't mean you're going to get a sandwich (try using sudo and you may have more luck). Most computers just can't make sandwiches.
    • They can understand your instructions. This is where programming languages are useful.

    A computer's willingness to execute any and all instructions it receives is the reason we have bad software (both low quality and malicious). A computer will never receive an instruction and think "I'm not doing that!" Computers don't think; they just do. This is also the reason we have really good software. There are no limits to what can be created. It is truly amazing.

    The CPU is the part of the computer that actually executes the instructions. It is a small, seemingly insignificant chip that has created a multi-billion dollar industry. It has been featured on Formula One cars and Pro Cycling Jerseys. It has been the subject of several Super Bowl commercials. It's a big deal.

    RAM

    While the CPU executes the instructions, RAM (Random Access Memory) is the place where instructions wait to be executed. Think of it as short term memory. If I were to tell you how to build a paper airplane, my instructions couldn't be stored in your hands, even though your hands are actually executing my instructions. Instead, the instructions are kept in your short term memory, and executed by your hands one at a time. RAM also stores any data, such as variables, that is relevant to the program's execution.

    If you're like me, you can hold about 4 instructions in your head at once, and you probably ask for these instructions to be repeated several times. Fortunately, a computer's short term memory is much better than yours. Computers have unparalleled concentration, they don't forget until you tell them to forget, and they can hold millions of instructions at once in short term memory (which is one of the reasons more RAM means your computer tends to perform better. It doesn't have to keep going back and asking for more instructions). However, RAM does have a limited capacity, and everything stored in RAM is wiped out when your computer turns off.

    The CPU and RAM work very closely and quickly. They are positioned very close to each other inside the computer, so communication is fast. They have no moving parts, so performance is fast. They are a great team, but where do all the instructions come from?

    Hard drive

    The computer actually isn't too picky about where instructions come from. So instructions can come from a number of places, like the command line, a file that is downloaded directly into RAM (like a JavaScript file on a web page), or from a file in the computer's hard drive.

    A computer's hard drive is long term memory. Hard drives are the place to put things that you don't want the computer forget, ever. Even if the computer gets turned off. We will think of a hard drive as a collection of files. There are all kinds of files on a hard drive. Your hard drive probably has images, presentations, and rich text documents. Your hard drive also stores files containing instructions. When these instructions are executed by the computer, an arm swings out and finds the instructions on the hard drive, reads them, and sends them to RAM, and they are fed into the CPU for execution.

    A traditional hard drive is an array of platters and swinging arms, encased in an aluminum box. The whole system is very precise and delicate. At the end of the arm is a head, which can read and write to the platters. The head "flies" within 3 nanometers of the platter. The swinging arm and the spinning disk make traditional hard drives very slow relative to RAM (newer Solid State Drives, with no moving parts, are much faster). When the computer is shut down, the arms swing clear of the platters, so there is not danger of collision. If there is a collision, however, the hard drive can be corrupted. Now you know why it's not a good idea to jog with a laptop that is on :)

  9. How I built this blog

    Posted 2013-09-07 10:36 PM GMT

    For quite a while now, I have wanted a place to write the things I learn, even if it's only for my own benefit. A lot of the things that I have been learning lately are related to programming, so I needed a blog that would let me add nice code examples. I did what anyone would do, and searched for the best blogging platform for code snippets. I found this discussion, and decided to just build my own.

    I don't want to build my own blog

    The reason I was looking for a ready made solution is that, although I really enjoy building things, I am aware that there is an entire industry around publishing to the web. Having a background in business and accounting, I understand economies of scale; for the same reason I can't make a homemade hamburger as good or cheap as In-N-Out does it, I can't make a blog as good or cheap (free!) as Blogger or Tumblr or Wordpress. There is just one of me, and I already have a full time job.

    Why I built my own blog anyway

    I really like customization. It's one of the reasons I love programming, and Linux. I have a few ideas for posts that I would like to do in the near future that just wouldn't be possible on a traditional blogging platform. I had also mostly built the blog as a part of Udacity's Web Development Course.

    How this blog works

    The blog uses many of the concepts taught in the Udacity course mentioned above (though Udacity ignored semantic HTML—I have tried to do a better job with that). The blog is hosted and powered by Google's App Engine.

    I use Jinja templates for the markup. I am a fan of Dust, but I don't think asynchronous client-side templates are appropriate for this use case.

    I use Twitter's Bootstrap for basic styles because Bootstrap makes your site look good with so little effort.

    I use a Python markdown module instead of a rich text editor. For implementation details on App Engine, take a look at this post. The posts are all stored as markdown, and converted to HTML at run time.

    Currently, the only JavaScript on the site is Prettify for code snippets. That's all I really need for now.

  10. for loops and grammar

    Posted 2013-09-07 12:52 AM GMT

    I often struggle with pluralization. Especially when I try to mix a plural subject and singular object (e.g. "The data is the answer" or "The data are the answer"). I'm sure this is straightforward for most people, but it's hard for me.

    Recently I was thinking about code while I was having a conversation (I do that way too often), and the answer to a different, entirely unrelated pluralization problem became clear to me. Take this sentence:

    Each of the dogs are brown.

    That doesn't sound so bad. Now take a look at this code snippet (it's kinda Python):

    for each dog in dogs:
        assert.equals(dogs.color, 'brown')
    

    Do you see the problem? We're never using the dog variable, and the dogs variable is a list of dogs, so dogs doesn't have a color attribute. So, how about this:

    for each dog in dogs:
        assert.equals(dog.color, 'brown')
    

    Much better. Therefore:

    Each of the dogs is brown.

    So, now I know, if I'm using each, the subject is always singular. Thank you, for loops. Now, if only I could figure out that "data is", "data are" problem.