[greatcodeclub] Create impressive side-projects - part 3

FRONT-END WEB FRAMEWORK

INTRODUCTION

Front-end web frameworks can help you create really fast web applications. You click a link and BAM ! It’s already there. How do they do this?

The trick is they don’t wait for a response from the server. Everything is done in the browser. From changing the URL in the address bar to updating content on the page.

In this project, we’ll uncover the methods used to build single page applications, and the frameworks that support them.

You will understand how the routing system of Backbone, Ember and Angular work inside.

Ready? Let’s do this!

TOOLS WE’LL USE

Here are three important tools and APIs we’ll use to build our own front-end framework.

THE HISTORY OBJECT

HTML5 introduced the pushState method to push a new entry into the history of your browser and update the URL in the address bar.

// To change the URL in the address bar.
history.pushState({}, "", "/some/path")

// To know when the user hits back (or forward).
$(window).on('popstate', function() {
  console.log('URL changed to ' + location.pathname)
})

HANDLEBARS

Handlebars is a popular JavaScript template engine. We’ll use it to render templates from inside the browser.

Dynamic portions of the template are wrapped in {{ ... }} . The rest is plain HTML.

var source = "<p>{{ name }}</p>"

// Handlebars compiles the template to a function.
var template = Handlebars.compile(source)

// Call the function to render the template passing the data to use.
var html = template({ name: 'Marc' })

A trick often used to embed templates in an HTML page is to put them in <script> tags.

<script type="text/x-handlebars-template">
  <p>{{ name }}</p>
</script>

FUNCTION.APPLY

At some point in our framework, we’ll need to pass an array as a list of arguments to a function. apply to the rescue!

// Take this callback function as an example
function callback(a, b, c) {
  return [this, a, b, c]
}

// We want to pass these as the a, b, c arguments.
var args = [1, 2, 3]

callback.apply(null, args) // => [window, 1, 2, 3]
// Same result as calling:
callback(1, 2, 3)

// The first argument controls the value of `this`.
var object = {}
callback.apply(object, args)
// Same result as:
object.callback = callback
object.callback(1, 2, 3)

SETUP YOUR ENVIRONMENT

Get the code:

$ git clone https://github.com/greatcodeclub/front.git # or your fork
$ cd front

STARTING THE SERVER

After you’ve cloned the repo, start the web server:

# (in front)
# If you have Python installed
$ python -m SimpleHTTPServer 3000

# Or, if you have Ruby installed
$ ruby -run -ehttpd . -p3000

(See this list for other ways to start a static web server.)

Then browse to http://localhost:3000/ and marvel at my wonderful and snappy blog.

READY?

Ready to build a simple front-end web framework to run a single page app? Jump to the next module and lets do this!

PART 1: ROUTING

In this first part, we’ll implement a routing system in the browser using history.pushState .

At the end of this video, we’ll end up with the following API for our framework:

Front.route('/', function() {
  // ...
})

Front.route('/:permalink', function(permalink) {
  // ...
})

RECAP

  1. We use Handlebars to render the index template.
  2. We implement Front.navigate(url) using pushState .
  3. Front.load() is then called to load a page. And hooked to the popstate event.
  4. In the app code, we capture all link clicks and forward them to Front.navigate .
  5. We define routes using Front.route(path, callback) .
  6. The proper route is found and called in Front.load .
  7. Finally, we add support for named parameters in routes ( :permalink ).

GET THE CODE

To get the code:

$ git checkout -b part1 origin/part1

If you want to re-code this part on your own, use the start-part1 branch:

$ git checkout -b my-part1 origin/start-part1

EXERCISE: FALLBACK TO USING HASH

As mentioned in the introduction, pushState is not supported by all browsers. That’s why front-end frameworks fallback back to a second, and more widely supported approach. Using location.hash and onhashchange event.

GET SETUP

Follow the instructions to setup your environment.

Then, get the code for the exercise by checking out the exercise branch.

$ git checkout -b exercise origin/exercise

Here are the changes you’ll need to make:

  • Use location.hash = '#' + path instead of pushState .
  • Bind to the hashchange event instead of popstate .
  • Use location.hash instead of location.pathname to determine the current URL.

Gotcha: Before setting location.hash , you’ll need to make the URL relative, use the following regular expression: path.replace(/(\/\/|[^\/])*/, "")

SOLUTION

To get the solution, check out the solution branch.

$ git diff origin/solution

You can also view the diff on GitHub.

PART 2: A NICER API

The fun part of creating a framework is giving it the shape you want.

In this video, I’ll show you how I turn the previous code into:

new Front.Router({
  '/': function() {
    this.render('index', { posts: posts })
  },

  '/:permalink': function(permalink) {
    var post = _.findWhere(posts, { permalink: permalink })
    this.render('post', post)
  }
})

RECAP

  1. We define the Front.Router constructor function.
  2. We define a render method on the Router class.
  3. Tada! Our own custom front-end framework.

GET THE CODE

To get the code:

$ git checkout -b part2 origin/part2

If you want to re-code this part on your own, use the start-part2 branch:

$ git checkout -b my-part2 origin/start-part2

EXERCISE: EXTEND THE FRAMEWORK

I’m sure you’ve got some crazy ideas to make the ideal front-end framework. Here’s your chance to create your own! Use the code from this project to get started.

Some frameworks like Backbone are more flexible and some others like Ember impose more conventions. Each one has their own set of pros and cons.

The limits are endless. But keep in mind, it’s all about designing an API that look nice, will be easy to use and understand. Here are a few ideas to get you started.

INSPIRED BY RAILS
Front.routes(function(map) {
  map('/', 'posts#index')
  // Send to PostsController.prototypte.index defined bellow

  map('/:permalink', 'posts#show')
})

PostsController = Front.Controller.extend({
  'index': function() { ... },
  'show': function(permalink) { ... }
})
CHAINING GALORE
Front.route('/').
      renders('index')

Front.route('/:permalink').
      renders('post').
      with(function(permalink) {
        return _.findWhere(posts, { permalink: permalink })
      })

Good luck!

GET SETUP

Click the WORK ON YOUR PROJECT button in the top right to get started working on your own framework.

Follow the instructions to setup your environment.

Once you’re ready, implement your own Router API like I did in the second part.

RESOURCES

WEB API REFERENCES

POPULAR FRONT-END WEB FRAMEWORKS

MORE ABOUT PUSHSTATE

REAL IMPLEMENTATIONS

NEURAL NETWORK

INTRODUCTION

Can you make a computer think? Have a brain? Well… that’s not really possible (yet …). But we can get pretty close with artificial intelligence and Neural Networks.

Neural Networks, technically Artificial Neural Networks, are inspired by the way our brain works. They can be used to estimate outputs that depend on a large number of inputs. For example, recognizing hand-written characters in images.

In this project we’ll implement a Neural Network from scratch and use it to recognize numbers drawn with pixels:

Character

In this first video, we’ll see the concepts and algorithms powering Neural Networks.

FEEDFORWARD NEURAL NETWORKS

Neurons are simple processing units. Inputs in, one output out. That’s it. But their full power comes when they work together. The output of a neuron will be the input of another neuron and on like so until we reach the end of the network.

In the Neural Network we’ll build, neurons are arranged in layers. Each neuron of a layer feeds its output to all the neurons of the following layer. Which is why we call it a Feedforward Neural Network.

IMPORTANT PROPERTIES ON A FEEDFORWARD NEURAL NETWORK

  • A neuron can have multiple inputs, but only one output.
  • All inputs and outputs are numbers between 0 and 1.
  • A neuron is connected to all the neurons of the next layer, and vice versa.
  • By consequence, all neurons of a layer have the same number of inputs.
  • The number of inputs in the first layer is the number of inputs that we to feed to the Neural Network.
  • The number of neurons in the last layer (the output layer), sets the number of outputs produced by the Neural Network.

Wooh! That’s a lot of stuff. We’ll cover each one of those points, one at a time, in the upcoming videos.

ALGORITHMS

Here is a summary of the algorithms we’ll use when building our Neural Network.

The origin of these algorithms is described in great details in the book Artificial Intelligence: A Modern Approach by Stuart Russell and Peter Norvig. You can also jump to the Resource page if you’d like to learn more.

PROCESSING INPUTS IN A NEURON

The output of a neuron is the sum of all its inputs multiplied by the weight of the branch they came from. To normalize the output to a number between 0 and 1, we feed it to the Sigmoid function ( S ).

The bias is the trigger of our function. If the sum of all inputs times their weights is greater than the bias, then the neuron activates. Consider the bias like a weight of a branch that always receives the input 1 .

TRAINING A NEURON

Training is done by feeding the network with inputs for which we know the final output(s). We then compute the error (difference between the expected and actual output) for each neuron.

Once we have the error, we know how much to adjust the weights and bias to reduce future errors.

To compute the error of the neurons in the output layer:

Error = Target - Output

Target being the expected output, and Output the actual output.

For the neurons in the hidden layers:

Error = Delta of neuron #1 in next layer * Weight of the branch to that neuron +
        Delta of neuron #2 in next layer * Weight of the branch to that neuron +
        ...

Once we have the error, we can compute the delta.

Delta = Output * (1 - Output) * Error

Notice that for the hidden layers, we needed the deltas of the next layer to compute the error. Thus, we’ll need to compute the error starting from the last layer (output layer) and move backward from there.

Finally, using the delta, we update the weights and bias of the neuron.

Weight += Learning rate * Input * Delta
Bias += Learning rate * Delta

The Learning rate is a percentage that ensures the neurons don’t learn too fast and focus too much on one output.

ETUP YOUR ENVIRONMENT

Get the code:

$ git clone https://github.com/greatcodeclub/neural.git # or your fork
$ cd neural

RUNNING THE CODE

Make sure you have Node installed.

To run a demo:

# (in neural)
$ node demos/character_recognition.js

READY?

Ready to build our Neural Network? Jump to the next module and lets do this!

PART 1: PROCESSING

In this project, we’ll use our Neural Network to recognize numbers from 0 to 3 drawn in pixels (in a 4x5 matrix). Here’s the layout of our network: 20 inputs, one hidden layer containing 10 neurons, and two neurons in the output layer.

Each input correspond to a pixel. 1 being a pixel, and 0 blank, in the character image. The outputs will be the recognized number in binary format.

RECAP

  1. We create the Neuron class, holding the weights and bias.
  2. We implement the Neuron.prototype.process method to process the inputs and return the output.
  3. The Layer class groups the neurons together and make them all process the same inputs and collect their outputs.
  4. The Network class make each layer process the inputs, and feeds their outputs to the next layer.

GET THE CODE

To get the code:

$ git checkout -b part1 origin/part1

If you want to re-code this part on your own, use the start-part1 branch:

$ git checkout -b my-part1 origin/start-part1

PART 2: TRAINING

At this point, our network is dumb. It has all the neurons and layers it needs, but the weights and bias have been set randomly. When you run the demo you might get the correct answer sometimes, but that’s just plain luck.

To make our network smarter, we must train it. We’ll train it by feeding it examples of good answers.

Refer back to the Algorithms page for the list of equations we’ll use.

RECAP

  1. We feed a few training examples to our network.
  2. We create a Network.prototype.train method to train the network using those examples.
  3. For each examples we get the inputs and the expected outputs ( targets ).
  4. We process the inputs through the network to get the actual outputs ( outputs ).
  5. We compute the errors and deltas of the neurons in the output layer.
  6. We continue computing the errors and deltas backward to the previous layers.
  7. We update the weights and bias of the neurons, using the deltas we just computed.
  8. Finally, we do this whole process many times until we reach a low enough error ( errorThreshold ) or have done a fixed number of iterations.

GET THE CODE

To get the code:

$ git checkout -b part2 origin/part2

If you want to re-code this part on your own, use the start-part2 branch:

$ git checkout -b my-part2 origin/start-part2

USE CASES & APPLICATIONS

Neural Networks can be used to solve many kinds of problems. You’ll find another demo, in the master branch of the project repository, in which we use the network to estimate XOR. Although this is useless a application, it shows how a Neural Network can be used to estimate any kind of equation.

You’ll find another great demo online, using the brain JavaScript library, in which you train a network to recognize color contrast.

GET SETUP

Click the WORK ON YOUR PROJECT button in the top right to get started using our Neural Network.

Follow the instructions to setup your environment.

Once you’re ready, setup your own network and make that magic happen!

RESOURCES

BOOKS

ARTICLES

CODE