Let the syntax do the talking
Blog Contact Posts Questions Tags Hire Me

What is 2015_0919 Code Challenge?

The 2015_0919 Code Challenge is a learning exercise for students attending Dan's Linux JavaScript Class at 3pm on 2015-09-19 at Palo Alto Library [2nd Floor Green Meadow Room]:

We start with three tasks: Install Ubuntu, enhance it, and create account named ann:
  • Install Ubuntu 14.04.3 on your laptop
  • Useful:
  • Useful:
  • Enhance Ubuntu:
    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install autoconf bison build-essential libssl-dev libyaml-dev \
    libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3       \
    libgdbm-dev libsqlite3-dev gitk postgresql postgresql-server-dev-all  \
    libpq-dev emacs wget curl chromium-browser openssh-server aptitude    \
    ruby ruby-dev sqlite3
    sudo apt-get update
    sudo apt-get upgrade
  • Create account named ann:
    useradd ann -m -s /bin/bash
    passwd ann
    ssh -YA ann@localhost
Next, we learn some Emacs:
  • emacs ~ann/.emacs
  • Experiment with the controls at the top of the emacs window
  • Add this syntax to file: ~ann/.emacs
    ;; ~ann/.emacs
    (global-set-key "\C-xs" 'shell)
    (global-set-key "\em"   'buffer-menu-other-window)
    (global-set-key "\eR"   'rename-buffer)
    ;; end of .emacs
  • Figure out how to save and exit
  • Verify your work:
    cat ~ann/.emacs
  • Start 'bare' emacs:
  • Start a shell in emacs with ctrl-x then letter 's'.
  • I should see something like this:
  • Rename the shell to SHELL1 with esc-key, then letter 'R'
  • I should see something like this:
  • List all buffers in my emacs with esc-key, then letter 'm'
  • I should see something like this:

I see the buffer-menu as similar to the Mac-Dock, Ubuntu-Launcher or the Windows-Taskbar.

The buffer-menu is my favorite emacs feature; it allows my mind to QUICKLY switch focus among three types of objects:
  • different shells
  • different files
  • different folders

The buffer-menu floats 'hot' shells, files and folders to the top.

This is useful behavior.

I mostly do 4 types of tasks on a laptop:
  • Interact with file
  • Interact with folder
  • Interact with shell
  • Interact with browser

I can do the first three types inside of emacs.

When I coordinate tasks with emacs rather than a Dock, I work much faster (because of the buffer-menu).

That sequence of creating a shell, and renaming it is the most difficult task I need to know.

All other emacs tasks can be done using mouse and arrow keys.

If I am an emacs power-user, I know two ways to use emacs to interact with folders.

The GUI-way is to click on the file-cabinet at the top.

Another way, which is quicker, is to type command ctrl-x then letter 'f'.

I should see something like this:

  • After I learn some Emacs or some other editor, I Install Node.js in this folder: ~ann/node/
  • cd ~ann
    tar zxf node-v5.0.0-linux-x64.tar.gz
    rm -rf node
    mv node-v5.0.0-linux-x64 node
  • Then, I add Node.js to PATH:
    export       PATH="/home/ann/node/bin:${PATH}"
    echo 'export PATH="/home/ann/node/bin:${PATH}"' >> ~ann/.bashrc
  • Run a test:
    which node
    node -e 'console.log("hello world")'
  • Install CoffeScript to test npm:
    which npm
    npm install -g coffee-script
    ls -la /home/ann/node/lib/node_modules/
    which coffee
    coffee -e 'console.log "hello coffee!"'
  • Start work on an app:
    mkdir ~ann/app11
    cd    ~ann/app11
    echo  node_modules > .gitignore
    npm init # Creates package.json (displayed below)
    npm install --save http-server
  • Add HTML file to app: ~ann/app11/index.html
        alert('I am alert!');
  • Test the app:
    cd   ~ann/app11/
    node ~ann/app11/node_modules/http-server/bin/http-server
    visit: http://localhost:8080
  • Commit the app to a git repository:
    cd ~ann/app11/
    git init
    git add .
    git commit -am 'hello app11'

At this point I should have the app running on Linux on my laptop.

I can follow more steps to deploy the app to Heroku:
  • Enhance ~ann/app11/package.json so it has an "engines" property:
      "name": "app11",
      "version": "1.0.0",
      "description": "simple app",
      "main": "node_modules/http-server/bin/http-server",
      "scripts": {
        "test": "node /home/ann/app11/hello.js"
      "repository": {
        "type": "git",
        "url": "file:///home/ann/app11"
      "keywords": [
      "author": "Dan",
      "license": "ISC",
      "dependencies": {
        "http-server": "^0.8.0"
      "engines": {
        "node": "4.0.0"
  • Create a one-line Procfile:
    cd ~ann/app11/
    echo 'web: node node_modules/http-server/bin/http-server -p $PORT' > Procfile
  • Install Heroku Toolbelt (standalone):
    dan@dev06:~ $ 
    dan@dev06:~ $ 
    dan@dev06:~ $ cd ~ann
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ curl | grep tgz
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   975  100   975    0     0   1465      0 --:--:-- --:--:-- --:--:--  1495
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ wget
    --2015-09-14 18:52:29--
    Resolving (
    Connecting to (||:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 1828732 (1.7M) [application/x-gtar]
    Saving to: ‘heroku-client.tgz’
    100%[======================================>] 1,828,732    893KB/s   in 2.0s   
    2015-09-14 18:52:32 (893 KB/s) - ‘heroku-client.tgz’ saved [1828732/1828732]
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ tar zxf heroku-client.tgz 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ ls -la heroku-client/bin/
    total 12
    drwxr-xr-x 2 dan dan 4096 Aug 31 23:56 .
    drwxr-xr-x 6 dan dan 4096 Aug 31 23:56 ..
    -rwxr-xr-x 1 dan dan  644 Aug 31 23:56 heroku
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ echo export PATH=/home/ann/heroku-client/bin:${PATH} >> ~/.bashrc
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ export      PATH=/home/ann/heroku-client/bin:${PATH}
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ heroku help
    Usage: heroku COMMAND [--app APP] [command-specific-options]
    Primary help topics, type "heroku help TOPIC" for more details:
      addons    #  manage addon resources
      apps      #  manage apps (create, destroy)
      auth      #  authentication (login, logout)
      config    #  manage app config vars
      domains   #  manage domains
      logs      #  display logs for an app
      ps        #  manage dynos (dynos, workers)
      releases  #  manage app releases
      run       #  run one-off commands (console, rake)
      sharing   #  manage collaborators on an app
    Additional topics:
      buildpacks   #  manage the buildpack for an app
      certs        #  manage ssl endpoints for an app
      drains       #  display drains for an app
      features     #  manage optional features
      fork         #  clone an existing app
      git          #  manage git for apps
      help         #  list commands and display help
      keys         #  manage authentication keys
      labs         #  manage optional features
      local        #  run heroku app locally
      maintenance  #  manage maintenance mode for an app
      members      #  manage membership in organization accounts
      orgs         #  manage organization accounts
      pg           #  manage heroku-postgresql databases
      pgbackups    #  manage backups of heroku postgresql databases
      plugins      #  manage plugins to the heroku gem
      redis        #  list redis databases for an app
      regions      #  list available regions
      stack        #  manage the stack for an app
      status       #  check status of heroku platform
      twofactor    #  manage two-factor authentication settings
      update       #  update the heroku client
      version      #  display version
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
    dan@dev06:/home/ann $ 
  • Create Heroku Account (cost: $0.00!):
    Memorize login and password
  • Create ssh-key for ann account (assuming ann has none yet):
    ann@dev06:~$ ssh-keygen -t rsa
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/ann/.ssh/id_rsa): 
    Created directory '/home/ann/.ssh'.
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /home/ann/.ssh/id_rsa.
    Your public key has been saved in /home/ann/.ssh/
    The key fingerprint is:
    7c:73:e0:26:8b:62:f6:a4:1d:78:22:e5:cd:3a:5c:eb ann@dev06
    The key randomart image is:
    +--[ RSA 2048]----+
    |                 |
    |                 |
    |          .      |
    |       . . .     |
    |    .   S = .    |
    |   o +.. = o     |
    |  ..B.B..        |
    |   +oX..         |
    |    ooE          |
  • Give a copy of ann public ssh-key to heroku:
    heroku status
    heroku auth:login
    heroku auth:whoami
    heroku keys:add
  • Create Blank Heroku App and then git-push my app in:
    cd ~ann/app11/
    heroku create x20150914
    git add .
    git commit -am ready4heroku
    git push heroku master
    I should see something like this:
    dan@dev06:/home/ann/app11 $ 
    dan@dev06:/home/ann/app11 $ 
    dan@dev06:/home/ann/app11 $ heroku create x20150914
    Creating x20150914... done, stack is cedar-14 |
    Git remote heroku added
    dan@dev06:/home/ann/app11 $ 
    dan@dev06:/home/ann/app11 $ git add .
    dan@dev06:/home/ann/app11 $ 
    dan@dev06:/home/ann/app11 $ git commit -am ready4heroku
    On branch master
    nothing to commit, working directory clean
    dan@dev06:/home/ann/app11 $ 
    dan@dev06:/home/ann/app11 $ git push heroku master
    Counting objects: 6, done.
    Delta compression using up to 2 threads.
    Compressing objects: 100% (5/5), done.
    Writing objects: 100% (6/6), 700 bytes | 0 bytes/s, done.
    Total 6 (delta 0), reused 0 (delta 0)
    remote: Compressing source files... done.        
    remote: Building source:        
    remote: -----> Node.js app detected        
    remote: -----> Creating runtime environment        
    remote:        NPM_CONFIG_LOGLEVEL=error        
    remote:        NPM_CONFIG_PRODUCTION=true        
    remote:        NODE_ENV=production        
    remote:        NODE_MODULES_CACHE=true        
    remote: -----> Installing binaries        
    remote:        engines.node (package.json):  4.0.0        
    remote:        engines.npm (package.json):   unspecified (use default)        
    remote:        Downloading and installing node 4.0.0...        
    remote:        Using default npm version: 2.14.2        
    remote: -----> Restoring cache        
    remote:        Skipping cache (new runtime signature)        
    remote: -----> Building dependencies        
    remote:        Pruning any extraneous modules        
    remote:        Installing node modules (package.json)        
    remote:        http-server@0.8.0 node_modules/http-server        
    remote:        ├── opener@1.4.1        
    remote:        ├── corser@2.0.0        
    remote:        ├── colors@1.0.3        
    remote:        ├── http-proxy@1.11.2 (eventemitter3@1.1.1, requires-port@0.0.1)        
    remote:        ├── optimist@0.6.1 (wordwrap@0.0.3, minimist@0.0.10)        
    remote:        ├── union@0.4.4 (qs@2.3.3)        
    remote:        ├── portfinder@0.4.0 (async@0.9.0, mkdirp@0.5.1)        
    remote:        └── ecstatic@0.7.6 (url-join@0.0.1, mime@1.3.4, minimist@1.2.0, he@0.5.0)        
    remote: -----> Caching build        
    remote:        Clearing previous node cache        
    remote:        Saving 1 cacheDirectories (default):        
    remote:        - node_modules        
    remote: -----> Build succeeded!        
    remote:        └── http-server@0.8.0        
    remote: -----> Discovering process types        
    remote:        Procfile declares types -> web        
    remote: -----> Compressing... done, 11.9MB        
    remote: -----> Launching... done, v3        
    remote: deployed to Heroku        
    remote: Verifying deploy... done.        
     * [new branch]      master -> master
    dan@dev06:/home/ann/app11 $ 
    dan@dev06:/home/ann/app11 $ 
    dan@dev06:/home/ann/app11 $ curl
        alert('I am alert!');
    dan@dev06:/home/ann/app11 $ 
    dan@dev06:/home/ann/app11 $ 
    dan@dev06:/home/ann/app11 $ 
  • When I visit the page served by the app, I should see something like this:

  • Next I use the idea of 'outside-in' development to enhance ~ann/app11/
    I make changes to the 'outside' before changing the 'inside'.
  • 'Outside' means code which runs in browser: HTML first, then CSS, then client-side-JavaScript
    'Inside' means code which runs on Linux server: Node.js, SQL, Bash, Python, Ruby, R, C++, and Java
  • The 'Outside' of ~ann/app11 is ~ann/app11/index.html
    Enhance it:
    <html ng-app=''>
        <script src='/angular.min.js'>
        1 + 1 is {{1 + 1}}
          alert('I am alert!');
  • Next, I use wget to enhance the server (the 'Inside') so it can serve angular.js:
    cd ~ann/app11/
  • Now, I should be able to see this:

  • I push it to heroku to test it:
    cd ~ann/app11
    git add .
    git commit -am DanWasHere
    git push heroku master
  • I should see something like this:

That could be considered an adequate code challenge for a two hour Meetup.

If you have questions, e-me: Let the syntax do the talking
Blog Contact Posts Questions Tags Hire Me