It’s Web Component Time – Making a Clock Using Web Components

Web Components are a way to approach application development on the web using reusable, encapsulated components. Although it is still currently under reviewed by W3C, with the help of polyfills, you can begin using them today for your app. Here are some main benefits:

  1. Encapsulation of styling within a component – you no longer have to worry about a minor CSS bug-fix leaking to other parts of your app
  2. DOM abstraction – instead of thinking the markup of your application in DIV and SPAN, you can now think of your DOM using custom tags that make sense semantically.
  3. High reusability – Since your HTML/CSS/JS are encapsulated, it is easy to recycle your components even across different projects

Timeless-Piece

GitHub    Demo

To demo how all of these works, I am going to create a clock using the Web Components standards. Before we dive into codes, let’s break our a clock down into smaller sub-components:

  • Clock Face – no functionality
  • Hour Hand – rotate to a certain degree based on hour and minutes of the moment
  • Minute Hand – rotate to a certain degree based on minutes of the moment
  • Second Hand – rotate to a certain degree based on seconds of the moment

You can see that each sub-component has a specific simple functional. We have almost already laid out exactly how we are going to build this. Let’s dive right in!

Timeless-Face

Link

We are going to start coding in a HTML file called timeless-face.html, and will be using the <template> tag. Template tag is a new element in HTML5. It allows one to create an inert chunk of DOM to be used later in the app. The content in a template is not rendered until it is appended to the DOM. So here is what our mark up will look like:

<template id="timeless-face">
    <style>
        .....CSS goes here.....
    </style>
    <div class="face">
         <div class="mark">XII</div>
         <div class="mark">I</div>
        .... and all the way to ....
         <div class="mark">X</div>
         <div class="mark">XI</div>
    </div>
</template>

Our markup will have one div(‘.face’) wrapped around 12 other divs(‘.mark’). We will style our div.face like this:

.face {
     width: 100%;
     height: 100%;
     border-radius: 50%;
     font-family: Oranienbaum;
     box-shadow: 0px 0px 5px black;
 }

and our div.mark like this:

.mark {
    position: absolute;
    width: 20%;
    height: 100%;
    text-align: center;
    left: 0;
    right: 0;
    margin: 0 auto 0 auto;
    font-size: 36px;
    letter-spacing: -5px;
    text-shadow: 0px 0px 1px rgba(0,0,0,0.4);
 }

And for every nth-elemnt of div.mark, we will rotate it by (n-1) * 30deg:

.mark:nth-child(2) {
    transform: rotate(30deg);
}

.mark:nth-child(3) {
    transform: rotate(60deg);
}

       ......

.mark:nth-child(12) {
    transform: rotate(330deg);
}

This will produce a circular clock face stretched to 100% of it’s container element.

Screen Shot 2015-12-02 at 1.25.51 AM

And then below our template tag, we will need to register our custom element using document.registerElement.

<script>
    (function() {
        var timelessFaceProto = Object.create(HTMLElement.prototype);
        var temp = document.currentScript.ownerDocument.querySelector('#timeless-face');
 
        timelessFaceProto.createdCallback = function() {
            var clone = document.importNode(temp.content, true);
            this.createShadowRoot().appendChild(clone);
        };

        document.registerElement('timeless-face', {prototype: timelessFaceProto});
    })();
</script>

First, we want to create a prototype object for our custom-element called timelessFaceProto. Then, we will set the createdCallback (to be invoked on creation of the element) of this prototype to do the following:

  1. Clone nodes in the template.
  2. Create a shadowRoot inside the main custom-element.
  3. Append cloned nodes into the shadowRoot.

Last, we will use document.registerElement to register a custom element called ‘timeless-face’, with the timelessFaceProto prototype. Next up, the second hand.

Timeless-Second

Link

The mark up for the second hand is just a simple div, styled as following:

.hand {
    position: absolute;
    display: inline-block;
    top: 5%;
    height: 45%;
    left: 0;
    right: 0;
    margin: 0 auto;
    width: 0.5%;
    background-color: red;
    box-shadow: 0px 0px 1px black;
    border-top-left-radius: 25%;
    border-top-right-radius: 25%;
    transform-origin: bottom;
 }

Then, we will follow the same pattern from previous example to register the custom element, but this time, we are adding two methods:

timelessSecondProto.attributeChangedCallback = function(name, oldVal, newVal) {
    if (name === 'second') {
        this.setSecond(newVal);
    }
};

timelessSecondProto.setSecond = function(seconds) {
    var deg = ((seconds % 60) / 60) * 360;
    this.hand.style.transform = 'rotate(' + deg + 'deg)';
};

The setSecond method will rotate the second hand to a certain degree based on the number of seconds you pass in. The attributeChangedCallback will call setSecond everytime you change an attribute on the element.

Timeless-Minute and Timeless-Hour

These two sub-components follow Timeless-Second’s pattern. Try to implement them on your own. Look here and here for code in GitHub.

Bring Them Together – Timeless-Piece

Link

So now, you can import all of the sub-components you created and put them in timeless-piece.html.

<link rel="import" href="./timeless-face.html">
<link rel="import" href="./timeless-hour.html">
<link rel="import" href="./timeless-minute.html">
<link rel="import" href="./timeless-second.html">

The <link> tag allows you to import HTML files into your current html file. After that, the template of your main component is simply:

<template id="timeless-piece">
    <style>
       /* :host reference the custom-element itself */
       :host {
            display: inline-block;
            position: relative;
        }
    </style>
    <timeless-face></timeless-face>
    <timeless-hour></timeless-hour>
    <timeless-minute></timeless-minute>
    <timeless-second></timeless-second>
</template>

And then create our prototypes:

timelessPieceProto.createdCallback = function() {
    var clone = document.importNode(temp.content, true);
    this.createShadowRoot().appendChild(clone);
    this.hour = this.shadowRoot.querySelector('timeless-hour');
    this.minute = this.shadowRoot.querySelector('timeless-minute');
    this.second = this.shadowRoot.querySelector('timeless-second');
    this.tick();
};

timelessPieceProto.tick = function() {
    var now = new Date();
    var hours = now.getHours();
    var minutes = now.getMinutes();
    var seconds = now.getSeconds();
    this.hour.setAttribute('hour', hours);
    this.hour.setAttribute('minute', minutes);
    this.minute.setAttribute('minute', minutes);
    this.second.setAttribute('second', seconds);
    setTimeout(this.tick.bind(this), 1000);
};

here we are registering methods to update attributes for each hand once every second. Because of the attributeChangedCallback in each of our sub-components, the rotation of each hand will be updated whenever we set an attribute of the hand.

Go to the demo page, open up the console and try messing around with different CSS changes. Such as putting this on body:

* {
    border: 1px solid blue;
}

Normally this would put a blue border on every single element on the page, but not the case here because the shadowDOM encapsulate styles within a component!

Web Components are tools that allow us to write clean, reusable code when developing for the web. I strongly urge everyone to start leveraging this new standard and push the web forward.

Happy Hacking!

Advertisements

Dynamic Programming – Knapsack Problem

Dynamic Programming has two key attributes:

  1. Recursive Substructure
  2. Memo-ization

A recursive substructure is a basic programming concept in which you break down your problem into smaller sub-problems, and that solution to the problem can be constructed using solution to the sub-problems. After find the recursive substructure, we can then keep track of the intermediate result of the sub-problems, and then solve intermediate sub-problems in a specific order to optimize the efficiency of the algorithm.

Here is a youtube video that does a great job explaining the concepts.

To illustrate the power of dynamic problem, I am going to solve the classic knapsack problem. Basically, you are given a backpack with limited capacity, and a list of items with various weight and values. Your algorithm should return a list of quantities of items that you can fit in your backpack to yield the highest value. You will see that this is the general pattern for most dynamic programming problems, in which you are given a constraint and different attributes, and then optimize for a specific attributes.

Instead of start with a bag of 0 items, like we would do in a recursive-backtracking approach, we should imagine starting with a bag with optimal values, and then reverse engineer to an empty bag. Here is the first question we need to ask ourselves.

Pretend we already have the solution, what was the last step we took to get to the solution?

In this case, the last step we took was putting one of the items in our backpack. Following this logic, we can then assume:

//best is a function that yields best value based on given capacity
//n is total capacity
//i is weight of current item
//P(i) is value of the current item
Best(n) = Maximum of ( P(i) + Best(n-i) )
//Where i iterates from first to last items;

So now, with a mental model, our solution will be:

See it on GitHub
function knapsack(capacity,items){
 //Object to store optimal values of different capacity
 var best = {};

 //Find optimal value based on given capacity
 var recurse = function(cap){
   //Base case
   if(cap <= 0 ) return 0;

   //Iterate over items
   items.forEach(function(item){
     //Return if cap is negative after subtracting item weight
     if(cap - item[0] < 0) return;

     //Set value equal to item value + recurse(new capacity)
     var value = item[1] + recurse(cap-item[0]);

     //Ternary operation 
     //IF best[cap] doesn't exit, 
     // set value
     //otherwise set greater of value OR best[cap]
     best[cap] = !best[cap] ? value : value > best[cap] ? value : best[cap];
   })

 return best[cap]
 };

 recurse(capacity);
 return best[capacity];
};

Our algorithm is functional now. Let’s test it!

var things = [[1,1],[2,3],[3,6],[4,10],[5,13]];
console.log(knapsack(1,things));  // 1
console.log(knapsack(13,things)); // 33
console.log(knapsack(22,things)); // 56
console.log(knapsack(56,things)); // .... NOTHING!

My Macbook Pro won’t return anything for 56 because the algorithm is too expensive. Here is the awesome part of dynamic programming! We simply have to add one line of code to memo-ize the result.

See it on GitHub
function knapsack(capacity,items){
 //Object to store optimal values of different capacity
 var best = {};

 //Find optimal value based on given capacity
 var recurse = function(cap){
 //Base case
 if(cap <= 0 ) return 0;

 // Return Memo-ized
 if(best[cap]) return best[cap];

 //Iterate over items
 items.forEach(function(item){
 //Return if cap is negative after subtracting item weight
 if(cap - item[0] < 0) return;

 //Set value equal to item value + recurse(new capacity)
 var value = item[1] + recurse(cap-item[0]);

 //Ternary operation 
 //IF best[cap] doesn't exit, 
 // set value
 //otherwise set greater of value OR best[cap]
 best[cap] = !best[cap] ? value : value > best[cap] ? value : best[cap];
 })

 return best[cap]
 };

 recurse(capacity);
 return best[capacity]
};

Now if you test the algorithm again:

var things = [[1,1],[2,3],[3,6],[4,10],[5,13]];
console.log(knapsack(1,things));    // 1
console.log(knapsack(13,things));   // 33
console.log(knapsack(22,things));   // 56
console.log(knapsack(56,things));   // 144
console.log(knapsack(77,things));   // 199
console.log(knapsack(2123,things)); // 5519

So just how much time did we save? Let’s look at the table below:

Screen Shot 2015-03-18 at 6.45.05 PM

So what caused the dramatic improvement? By returning the memo-ized result and skipping the rest of the recursive call, we saved a lot of repeated work. I will illustrate the call stack of the example below.

// Find B(5), List of 3 Items [1,1],[2,3],[3,5]
// P(1) is Value of item 1
// W(1) is Weight of item 1
// B(5) is Optimal value with capacity of 5
i = 0, B(5) = P(1) + B(4)  // this is triggered B(4)
i = 0, B(4) = P(1) + B(3)  // B(3)
i = 0, B(3) = P(1) + B(2)  // B(2)
i = 0, B(2) = P(1) + B(1)  // B(1)
i = 0, B(1) = P(1) + B(0)  // B(0) return 0, memo-ized B(1) = 1
i = 1, B(1) = P(2) + B(-1) // B(-1) hit negative, stop B(1)
i = 0, B(2) = P(1) + B(1)  // B(1) return 1, memo-ized B(2) = 1
i = 1, B(2) = P(2) + B(0)  // B(0) return 0, memo-ized B(2) = 3
i = 2, B(2) = P(3) + B(-1) // B(-1) hit negative, stop B(2)
i = 0, B(3) = P(1) + B(2)  // B(2) return 3, memo-ized B(3) = 3
i = 1, B(3) = P(2) + B(1)  // B(1) return 1, memo-ized B(3) = 4
i = 2, B(3) = P(3) + B(0)  // B(0) return 0, memo-ized B(3) = 5
i = 0, B(4) = P(1) + B(3)  // B(3) return 5, memo-ized B(4) = 6
i = 1, B(4) = P(2) + B(2)  // B(2) return 3, no change to B(4)
i = 2, B(4) = P(3) + B(1)  // B(1) return 1, no change to B(4)
i = 0, B(5) = P(1) + B(4)  // B(4) return 6, memo-ized B(5) = 7
i = 1, B(5) = P(2) + B(3)  // B(3) return 5, memo-ized B(5) = 8
i = 2, B(5) = P(3) + B(2)  // B(2) return 3, no change to B(5)

For all the highlighted lines, since we had already memo-ized the intermediate results, the algorithm would return the intermediate results without continue the iteration. Had we not used memo-ization, each of the highlighted lines would result in another iteration of the list of items. We effectively saved 5 * 3 = 15 iterations!

Now, if you want to challenge yourself, the original knapsack question asked for an array of quantities as output, instead of just optimal value. For example, B(1) in the previous example would return [1,0,0]. The complete solution is posted here on my GitHub page.

Happy Hacking!

Hack Reactor Afterthought

Yesterday, I graduated from Hack Reactor and am now officially an alumni of the best coding school in the world.

It was a very intensive 12 weeks, and I probably would have struggled a lot if I hadn’t over-prepared myself by going through the entire curriculum once before the course begins. This preparation allowed me to focus on learning best practices, design patterns, and other high-level concepts, without having to worry about technical details. I would recommend anyone who is joining Hack Reactor to do the same.

The amount of technical expertise I got out of the past 12 weeks was unbelievable. I can now solve problems that I couldn’t even understand before. I become an expert in recursion, data structure, and full stack development. Most importantly, I am very confident in my learning ability now, and I feel like I can pick up any new technologies in a very short amount of time.

However, this is not the best thing I got out of Hack Reactor. Before Hack Reactor, I was an accountant working at a small firm in Larkspur. Although my work was consistently praised by my manager, I was not happy. I craved for opportunity to work on interesting ideas, and opportunity to solve challenging problems. I felt lost, depressed, insecure, that this could be it for my career, that being a professional was about tolerating these negative feelings.

Now I have a different view on career and life. I now know that it is possible to do something that I love, while being appreciated and respected. It is possible to go to work everyday with a smile on my face, as if I am just going to work out my brain. Much of it has to do with how Hack Reactor enables me to be in a growth mindset, as well as surrounding me with people who have the same mindset. For the past 12 weeks, I was laser-focused on learning, and almost nothing else in life matters. I neither care about how others judge me, nor how my work impress others. I do not know how much I can maintain the same focus going forward, but I know that this experience will shape my future career, because I know how much I can accomplish when I am focused.

Create the Universe in Three.js

Three.js is a JavaScript library that uses HTML5 canvas and WebGL to render 3D graphics on a web browser. It is well-documented and has a very intuitive API.  I am going to walk through the steps of creating the universe in Three.js (or just 10000 cubes floating in 3D space).

<!DOCTYPE html>
<html>
  <head>
    <title>Three Test</title>
   <style>
     body {
       background-color: black;
       overflow: hidden;
     }
   </style>
   <script src='http://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js'></script>
   <script src='./bower_components/jquery/dist/jquery.min.js'></script>
  </head>
   <body>
   </body>
   <script src='./main.js'></script>
</html>

You will first need to create a index.html page like the one above, as well as a main.js file in the same folder.

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75,window.innerWidth/ window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

In your main.js file, you will need to instantiate a scene, camera, and renderer like the example above. A scene represents the 3D space where your objects will live in. A camera represents the point-of-view in which you are looking at your scene. A renderer  represents the canvas element that is appended to your DOM.

var directionalLight = new THREE.DirectionalLight(0xffffff,1);
directionalLight.position.set(7,5,-5);
scene.add(directionalLight);

You can make your scene more interesting by adding directional lighting.  It is as simple as instantiating a directional light object, and adding it to you scene.

var geometry = new THREE.BoxGeometry(1,1,1);
var material = new THREE.MeshLambertMaterial({color: 0xffffff});

To prepare ourselves for creating cubes, we will need to instantiate a geometry object to indicate that we will be using a unit cube, and a material object to indicate that we will be using lambert material.

var cubes = [];

for (var i = 0; i < 10000 ; i++) {
 var rx = Math.random()*2000-1000;
 var ry = Math.random()*1000-500;
 var rz = Math.random()*10000-5000;
 cubes[i] = new THREE.Mesh(geometry,material);

 cubes[i].position.x = rx;
 cubes[i].position.y = ry;
 cubes[i].position.z = rz;
 scene.add(cubes[i]);
};

Now here is the fun part. We are going to create 10000 cube in random places using the for..loop above, and add them to our scene.

camera.position.z = 20;
camera.position.x = 0;
camera.position.y = 0;

We are almost there! Before we render, we will need to position our camera.

//Render Loop
function render() {
 requestAnimationFrame(render);
 camera.position.z -= 5;
 for(var i = 0; i < cubes.length; i++){
 cubes[i].rotation.x += 0.05; 
 cubes[i].rotation.y += 0.05;
 }

 renderer.render(scene,camera);
}


render();

Finally, we use the render function above to render the scene. The render function will be invoked about 30 times per second for smooth animation. You will see from the example above that for every iteration, I am rotating each of the 10000 cubes by 0.05 degrees.

Have fun hacking!

Why You Should Put Linux on Your Chromebook

The Chromebook is a low-power, low-budget laptop that is mainly designed for people who lives in the cloud. As a web developer, most of the time all I need is a text editor and browser in order to work, which makes the Chromebook a very appealing choice.

One of the first things I did when I decided to attend Hack Reactor with a Chromebook was tinkering with it to dual-boot with Linux. There are cloud-based development environment out there, such as Cloud9, that allows you to connects to a virtual Linux environment for coding. However, one of the down sides of that is you must have access to internet in order to work. One of my favorite things about dual-booting Linux is that I can go to any coffice in the city and start working without worrying about having good internet connections. Another advantage is that it forces you to master using the Linux terminal, which is a highly valuable skill for a software engineer.

(You can follow tutorial and put Linux on your Chromebook in under 15 minutes.)

Here is a few tools you will want to use:

  1. GNOME DO – App launcher so you don’t need to use your trackpad.
  2. Sublime 3 – The BEST text editor out there
  3. Node and NPM – MUST HAVE for web developers.
  4. Bower – Another MUST HAVE for web developers.

Triumpet – Indoor Mapping

Visit Triumpet Project Page

Last week was solo week at Hack Reactor, and my teammates and I were working on a project called Triumpet. We had about 10 days to work on this project, and it was a tremendously valuable experience for all of us. The original scope of our project was to map out floor plan of a retail space, and then track indoor position of users utilizing iBeacon or motion sensors on their mobile devices. We soon discovered that 10 days is too little time to achieve our original scope, and we had to reassess and put position tracking to the backlog for future iterations. Also, we didn’t want to spend too much time on learning new frameworks or technology, so we decided to use the MEAN stack that we were already famililar with, and D3.js for rendering the indoor maps.

Treeify – Visualizing DOM Tree

My cohort-mate Daniel and I just finished a project called Treeify.js. The idea is to use what we’ve learned during the first two week of Hack Reactor, and put it all in use in one project. Treeify.js does the following:

See it in action!

  1. Make AJAX call to get HTML of a website
  2. ParseHTML using JQuery
  3. Reconstruct data into a tree using recursion
  4. Visualize data using D3.

The result is surprisingly beautiful.

See Treeify in Github


GIZMODO
gizmodo

GOOGLE
google

 TWITTER
twitter

 YOUTUBE

(Something crazy going on here..)

youtube

ALSO YOUTUBE, but close up for finer details
youtubecloseup

FACEBOOKfacebook

YAHOOyahoo

Codecademy

codecademy


FBI.GOV

fbi


 NSA.GOV

nsa