Day 36, Parse or MySQL

Today is the first day of our client project and we spent many hours on debating between Parse or MySQL

Sprint reflections:
– People don’t like the way how client projects were introduced
– Marcus expressed that he really wanted to include authentication as one sprint but just could not find a time.

Standard

Day 35, memories

Have to leave all my old friends behind and rejoin the classroom. Now, back to work.

Notes on working on a client project:

Good projects are:
– under promise, over deliver
– many touch points including face-to-face, Skype, email

Bad projects are:
– No communication through out
– Big bang delivery in the end
– No hardstop
– Leaking client information on the blog

Advices are:
– Do NOT skip the regular check-in
– Be transparent about the progress

Before the kick-off meeting:
– Prepare questions

During the kick-off meeting:
– Take notes
– Try getting everything you need to kick off the project
– Try leverage the 30mins or 45mins effeiciently

Possible Questions for the kick-off meeting:

Tech/workflow
– Fork/pull vs branches
– Ticketing system
– Stack choices
– Web / mobile
– Third party integrations such as Stripe, Twilio or MailChimp

UI / UE
– Types of users
– User stories

Others:
– Business model
– Business roadmap

Standard

Day 33, Sinatra

Magic!!!!!!!!

That is what I am thinking all the time. I thought Ruby itself has enough magic, I was so wrong! When I say magic, I don’t mean anything negative. Please refer to this quotes – “Any sufficiently advanced technology is indistinguishable from magic.”

ActiveRecord:
– ORM
– generates many methods for you, such as model.findall_by_column_name
– amazing feature set. Used as a model for many other ORMs
– many Ruby frameworks use ActiveRecord

Sinatra:
– lightweight compared to Rails; JavaScript equivalent would be Express(?)
– used for a CRUD application with medium level complexity
– Rails would probably be a better choice for more complicated applications with a lot of user interactions and page by page navigations
– not sure about which site has the largest scale Sinatra App

Standard

Day 32, more review sprint, hello Backbone

Continuing my review sprint. Spend the morning working on MongoDB and the afternoon working on BackBone.

It was surprising nobody really knew enough about MongoDB. Guess all the instructors never really used MongoDB in their work because MongoDB was so new.

Backbone is an interesting one. I followed the video of http://backbonetutorials.com/. Instead of writing the app he was talking about, I re-wrote my own ChatClient. I paused the video many times and was able to finish my re-write. A couple of takeaways:
– Can’t believe how many small magics there are. The video tutorial really helped.
– I am constantly paralyzed by the number of choices I have. Basically, I can achieve the same result with many ways and I don’t know which one is the best practice. So, in that regard, the tutorial also helped. However, I am not sure that the tutorial itself is following the best practice all the time

Personal projects:
We talked a little bit more about personal projects. The criteria are:
– heavy in employer relevant skills. Note: using cutting edge tech-tools is also employer relevant. The tool itself might not be relevant, but your appetite for cutting edge tech is employer relevant.
– hackernews worthy. This is an interesting idea. The teachers went on to classify that hackernews worthy is different from a general audience worthy. For example, a fairly nerdy idea might not appeal to the general public but might be interested to the tech community.
– focus & viable in two weeks. It is better to have a focused and complete product than a half-baked large product.
– show relevant skills / interests in certain field

Tips:
In a one-to-many relationships, store the information in the many side. A good example is thinking about a celebrity and his/her many fans, only fans remember the celebrity, not the other way around.

Standard

Day 31, review sprint

For whatever reason, it was decided that instead of doing another Ruby sprint, we will do a review sprint instead. I was totally unprepared for this. Anyway, let’s just face it.

About 7 students were getting ready for the upcoming Quora contest on machine learning. I didn’t participate since I would be out of town on the day of contest. Oh, well…

The master says, get back to work. Yes, master. I finished the regex sprint and implemented a prefix tree. My data structure skills are kind of average and totally needs more attention. I end up pairing with Al on the prefix tree and he is a great pair to work with 🙂

Subclassing in JavaScript


// In JS, method is a free agent, unlike some other languages

var obj ={

  cat: 'mii',

  cow: 'muu'

};

var shout = function(input){

  console.log(this[input]);

};

obj.shout = shout;

obj.shout('cat');

//or we can call the function in the context of 'obj'

shout.call(obj, 'cat');

As Larry said, this seems to be irrelevant to subclassing, but it is indeed very relevant.

var Phone = function(color){
  this.color = color;
};
Phone.prototype.changeColor = function(newColor){
  this.color = newColor;
  console.log("Phone has a new color: ", this.color);
};

nokiaPhone = new Phone('black');
nokiaPhone.changeColor('grey');

//now subclassing
var SmartPhone = function(color, screenSize){
  Phone.call(this,color); // see the similarity?
  this.screenSize = screenSize;
};
SmartPhone.prototype = Object.create(Phone.prototype);
SmartPhone.prototype.constructor = SmartPhone;
SmartPhone.prototype.changeColor = function(newColor){
  Phone.prototype.changeColor(newColor);
  console.log("I, as a smart phone, am proud of my " + this.screenSize +" inch screen");
};

palmPhone = new SmartPhone('white', 4);
palmPhone.changeColor('red');

Larry also mentioned the beauty of bind. I understand the concept but should have used them more frequently in all the jQuery callbacks.

var obj ={
  cat: 'mii',
  cow: 'muu'
};

var shout = function(input){
  console.log(this[input]);
};

shout('cat'); //undefined
shout = shout.bind(obj);
shout('cat'); //now always run in the context of 'obj'

Oh, for our entire class with 20+ people, we have 7 client projects to pick from. Everyone is supposed to submit their top 3 choices and we will know the result tomorrow. Since only 7 people will be picked, I guess I should be thinking hard about my Plan B. I am thinking about doing a Flickr client…

Standard

Day 30, the master says

The master says ” just like a feather, your code is floating in the air. ”

This is from the RubyMonk and we were having a blast going through it. Way way better than the CodeSchool Ruby Intro. When I was going through the CodeSchool Ruby Intro, I was like, “why people love Ruby again?”. When I was going through RubyMonk, now I knows why. Plus, the master has some really cool quotes there.

Some cool functions that I liked when I was going through this Ruby intro sprint: [].map, [].find, [].find_all, [].inject, {}.to_str (makes obj string-like). When I was using Ruby, I kept thinking that Matz must have spent thousands of hours thinking about all those functions. It is day and night compared to JavaScript and I am not sure one way is better than the other.

Lambda vs. Proc vs. Block

Note: just trying to be mostly right here. Totally needs to read more on this.

Blocks are like Procs without visible name. Blocks can be converted to Procs easily.

Lambda errors out with the wrong number of arguments; one of them has power to return differently(?)

##lambda
f1 = lambda do |args|
  puts args
end
f1.call 'this is aha'

##Proc
f1 = Proc.new do |args|
  puts args
end
f1.call 'this is aha'

##Block, not sure
['this is aha'].each do |args|
  puts args
end

JavaScript

var f1 = function(args){
  console.log(args);
};

f1.call(this, 'this is aha');

They are very tricky when used as callbacks

Case 1:

def f1
  yield('passing args')
end

f1 do |args|
  puts args
end

Case 2:

def f1
  yield('passing args')
end

callback = lambda do |args|
  puts args
end

f1(&callback)

Case 3:

def f1(&cb)
  cb.call('passing args')
end

f1 do |args|
  puts args
end

Case 4:

def f1(&cb)
  cb.call('passing args')
end
callback = lambda do |args|
 puts args
end

f1(&callback)

The master says: yo, time to go to bed.

Standard

Day 29, Ruby

This is the fifth week. Scary!

Most students were unsatisfied with the database sprint setup and we spent a hour on the sprint reflection. I like the fact that Marcus and other stuff members took those feedbacks very seriously.

Primer on algorithms:

Two constrains are execution time and relative memory allocation; three major tasks are store data, sort data and search data. As the hiring day is approaching for us, I would spend significant more time on this topic.

Ruby

The principle of least surprise(?)

Good parts:

– tons of built-in functions; some very nice datatypes such as date or currency

– Rails is probably the reason why Ruby is so popular

Other parts:

– Server side only

Compared to JS:

– Ruby has block level scope


for obj.keys do |key|

#block scope

end

While in JS, block scope doesn’t exist, hence the necessity to wrap blocks with function(){}. It makes sense since most people want to run the same code block with some arguments, we might as well use function instead.


var f1 = function(){

//function scope

}

– in hash or object, the key can be other types beyond string. Instead of using key:value, the notation is hash rocket, meaning key=>value.

– callbacks

Ruby. Thought process: since we rarely pass more than one callback function(block), let’s always give the function a block that can be used as a callback; in that case, we might as well give the function a default name: yield. (Note: this is not 100% accurate. )


def f1
  yield('sample_args')
end

f1 do |args|

  puts args

end

JavaScript


var f1 = function(callback){
  callback('sample_args');
};
var callback = function(args){
  console.log(args);
};
f1(callback);

– collection iterations. Ruby has its built-in each method while JavaScript has to rely on underscore.js.

[1,2,3].each do |ele|
puts ele
end

JavaScript

_([1,2,3]).each(function(ele){
  console.log(ele);
})

– class
Ruby has the class keyword while JavaScript doesn’t.

class Person
  @@n_hands = 2 # class level variable
  attr_accessor :age
  def initialize age
    @age = age
  end
end
a = Person.new(30)
p a.age
p Person.class_variable_get(:@@n_hands)

Same code in JavaScript:

var Person = function(age){
  this.age = age;
};
Person.n_hands = 2;
var a = new Person(30);
console.log(a.age);
console.log(Person.n_hands);

– private or public properties/methods of objects
Ruby only exposes methods, meaning all properties are private. For examples, obj.keys means obj.keys(). To get/set properties, one has to generate getter/setter by themselves. There is a shortcut to do so using “attr_accessor :some_var”. According to instructors,

#attr_accessor :some_var
#literally means inserting the following two blocks of code
def some_var
  @some_var
end
def some_var= input #'some_var=' is the function name, and input is the parameter
  @some_var = input
end

JavaScript doesn’t care.

Standard

How to write an ORM

ORM stands for Object Relationship Mapping, basically an abstraction layer on top the database.

Basic ORM structure:


var _ = require('underscore');
var mysql = require('mysql');

var connection = mysql.createConnection({
  user     : 'root',
  password : "root",
  database : 'chat',
  socketPath  : '/Applications/MAMP/tmp/mysql/mysql.sock',
});

connection.connect(function(err) {
  if (err) {
    console.log('db_connection_err', err);
    return;
  }
});


//do NOT use 'new'
var makeORM = function(name){
  //class-level variables
  var tableName = name;

  //plese use 'new'
  var ORM = function(param){
    this.tableName = tableName;
    if(param){
      //init variables on instance
      this.msg_id = param.msg_id;
      this.text = param.text;
    }
  };

  ORM.findAll = function(callback){
    var sql_query = "select * from " + tableName;
    connection.query(sql_query,  function(err, rows){
      var result = _(rows).map(function(row){
        return ( new ORM(row) );
      });
      callback(result);
    });
  };

  ORM.find = function(){

  };

  ORM.prototype = {
    getID: function(){
      return this.msg_id;
    },
    save: function(){
      //
    },
    update: function(){
      //
    }
  }

  return ORM;
};

//this refers to the 'messages' table
var Messages = makeORM('messages');
Messages.findAll(function(result){
  console.log('result', result);
  _(result).each(function(obj){
    console.log( 'each result also has methods such as getID: ', obj.getID() );
  });
});

connection.end();

ORM results vs. normal database query results

ORM provides another layer of abstraction, and ORM queries tend to return non-generic objects.

Regular database query returns a generic object or most likely, an array of generic objects. Those generic objects haven’t gone through construction, hence don’t have methods. On a side note, SQL language was designed such that the query only specify what is returned but not how the result is returned.

Join table vs join query

Join table is indeed a real table existing in the database.

A join query tends to produce a temporary join table during execution, but that temporary join table is destroyed as soon as the join query is finished.

Standard