Monthly Archives: October 2013

Hacker School Day 10: About TCP/IP & a Node.js Hello World

.Where. .to. .begin. .?.

I began today slightly bored of Nefario Teaches Typing. There’s a WHOLE lot more I could do with it, but I won’t learn anymore by doing those things. I mean, sure, I’d get a little faster at some simple stuff, but I’m ready to be CHALLENGED, PUZZLED, PERPLEXED. So I put that on the shelf for now (I think I’ll still work on it in the evenings, as a little side-project) and sought some facilitator advices. M suggested that I either delve into a meaty client-side project such as a drum music simulator thing or that I try to write my own super-simple, crappy web server. Since I know little (NOTHING) of sockets and such, I figured that’d be a worthy pursuit. I proceeded to spend the rest of today reading up on Node.js, packets, sockets, TCP/IP, and other bizarre terms. From this, I think I’ve extracted a bit of knowledge. Please see below:

TCP/IP

The what? TCP stands for Transmission Control Protocol. That means nothing. What they should call it is: Reliable Communication Command Center, the RCCC. Because that’s what it does. TCP is a protocol (read: set of rules or instructions) for sending and receiving lil’ packets of info between and within computers. [NOTE: feel free to well-actually me in the comments: I won’t be offended, I’ll merely learn better.] Okay, so, from what I understand, TCP works with the IP (Internet Protocol, another set of instructions) to coordinate communication between computers in packet-switched networks.
“What’s a packet-switched network?” I’m glad you asked! It’s when things (computers in this case) transfer data in little packets instead of via a constant bit stream. This means: you can send some data then stop, then send more; the packets can travel via different routes to get to the same place; you can check for errors in delivery, and you can grab data from multiple hosts (computers serving up data). Packets are great! Let’s talk more about what a packet actually is:

Packets

Packets are like datagrams, but not quite. Datagrams are little chunks of data, packed light for travel. Datagrams contain some header info about where they’ve come from and where they’re headed and what type of data they contain, then they have some sort of body of data, called the data payload. I picture this as a Chinese Dragon head that barfs up addresses and types, stuck to a dump-truck of solid gold data bars. (It’s been a long day.) The thing about datagrams is they don’t pay attention to their own survival. They contain no way to tell whether they’ve reached their final destination, and no data about error-checking for their missing friends or limbs. No guarantees! Sent then forgotten. Packets, on the other hand, are souped-up dragon-trucks: in addition to the basic datagram info, packets also contain info about which of them belong together and in what order, and they (somehow) have ways to instruct their receiver about how to test them for errors (I think this has to do with some magical size computation that would detect missing data).

IP Addresses

This is just cool. You know how when you get your IP address it just seems like a bunch of numbers? Well, it is, but there is a little logic to it. Everything in the header of these packets has a specified (by the protocol) amount of data it can take up, which I imagine makes it easier to parse and such. The amount allotted for an IP address is 4 bytes (each 8 bits long), which means the “address” is 4 “numbers” long, each separated by a period, each between 0 and 255 (which are all the numbers you can make with 8 bits: 00000000 – 11111111), hence something like 127.0.0.1. Cool, huh? I thought so. Also, IP addresses are the personal address of your computer. Something like that.

Node.js

Today I read a bunch about node and learned how to write the teeniest web server. Here it is:

// require the http module in node:
var http = require('http');

// write a listener function that will do something (send a response, ideally) when the server receives a request:
var webListener = function (request, response) {
    if (request.method == 'GET') { // what to do if this is a GET request (most are!)
        console.log("Request was a GET"); // just tell the terminal that it was a get request for now
        console.log("URL: " + request.url); // tell me that url, please!
    }
    response.writeHead (
        200, // that code means the request was successful, tell the client "200, yay!"
        { 'Content-Type' : 'text-plain' } // We're going to send back some plain ol' text
    );
    response.end('Hello World!'); // end our response with the data (text) that we want to send back
}

// make a new instance of the server object and pass it our fancy listener function from above
var server = new http.createServer(webListener);

// tell the server to listen up! (and give it a port number to listen on and a host to use -- localhost)
server.listen(8124, "127.0.0.1");

// tell me you're working, server!
console.log("Server running at http://127.0.0.1:8124");

Oh right, first install node (use homebrew!). Then put the above code in a file, and call it example.js. Save it somewhere, navigate to that place in Terminal (someday I’ll write a super-teeny Terminal intro), then type “node example.js”. BAM! Web server, up n’ runnin’.
Phew! That’s it. I’ll go into more detail tomorrow about what the particulars of each of these are, but in general, the client (your computer) connects to a host (now my computer) and they say “coo’, let’s talk.” So your client computer requests something from mine (you want to see my website, of course) at the address that is my computer, connected to the port that my server is listening to. My server gets that request and responds however I tell it to (in this case by sending you back “Hello World!”). Tomorrow’s goal: send back an html file. I guessed that I would have to read a file’s content into some sort of buffer and send it appended to a packet, and I think I’m right. I haven’t yet looked too far into the details of that, but I’ve got a general idea of how it’ll work.

Stay tuned, folks! And thanks for reading.

FORGOT! Here’s my illustrated understanding of TCP and IP:photo

Hacker School Day 9: SICP review, Sinatra solutions, JS productivity

I dabbled in too much today! But I think it’s okay. Just for today.

First up, I want to write about SICP*, and what I reviewed today. Hopefully that will help cement these complex thoughts a little more firmly into my malleable medium of brain. I started working through SICP again with another (SLOWER) group. This is more to my liking, as I merely want this to be an enlightening side-project.

SICP Exercise 1.5

(define (p) (p))

(define (test x y)
    (if (= x 0)
    0
    y))

Evaluate (test 0 (p))
This exercise tries to demonstrate the difference between Applicative-Order Evaluation and Normal-Order Evaluation. Let me try to explain: in Applicative-Order Evaluation (which is similar to how the Scheme interpreter actually evaluates code), you evaluate the parameters of the function or expression FIRST, then plug your results into the outer function(s). In Normal-Order Evaluation, you leave your parameters as junk-words and expand out the outer functions as much as possible. In fact, you expand everything down to simple operations as much as possible, THEN you go through and evaluate it all back up and simplify. So, in the case of the code above, approaching it Applicatively, we would FIRST evaluate 0 and (p) (since these are our parameters to the test function). When we try to evaluate (p), we are returned the function (p), which then returns the function (p), which then returns the function (p), etc. The program runs forever, just trying to get some real stuff to put into the parameters of test. Yikes! When we approach this Normally (ha! except not really — please note my use of capital “N”), we first expand out our function: (if (= 0 0) 0 [STOP!]. With if, since it’s a special form and not a normal procedure, we don’t plug everything in everywhere up front; we instead plug in our first test case and evaluate it, then either evaluate the success expression or evaluate the else expression. In this case, we get to (= 0 0) (does 0 equal 0? why, yes, it does!) and we return 0. Done. Easy. No infinite loop.

SICP Exercise 1.6

In this exercise, Alyssa P. Hacker and her friend Eva Lu Ator (author’s names, not mine) decide that if is just a sub-set of cond (conditional), where there is only one test case, so they decide to write their own if function based on cond:

(define (new-if predicate then-clause else-clause)
    (cond (predicate then-clause)
    (else else-clause)))

This works fine if you’re just evaluating a few simple numbers, but if you use it for a process involving iteration, it may cause an endless loop. Here’s why: (SICP example slightly simplified)
Let’s write a function called improve guess where we say “if (guess is good enough) (return guess) else (improve guess),” and improve guess calls itself. If we use the normal special form if as defined by Scheme (or any language, really), the interpreter knows to only look at the else clause IF the first clause is false. Fine. Great. What’s the big deal? If we instead use our homemade function new-if, we have to plug in: (new-if: (good enough?) (guess) (improve guess)) into our function. As I talked about above, if we were to evaluate this Applicatively, similar to the way the Scheme interpreter does, we would FIRST evaluate our parameters before doing the outer function stuff, which means we would FIRST evaluate the parameter “improve guess” which means we would call our function all over, plug in the same parameters, evaluate them (which would mean evaluating “improve guess”, which would mean calling our function yet again, plugging in the parameters, evaluating them (which would mean …)). And if you run this code in the Dr Racket interpreter (in which I declare the language to be Scheme), it only quits when it’s run out of its allotted memory. Ha! SO. THAT is why some functions are built-in to languages with SPECIAL instructions, such as IF, AND, OR. Take that, Alyssa P. Hacker and Eva Lu Ator! I guess that’s whatcha get for tryin’ tah be clever.

Sinatra!

Not Frank. The other one. Less dancy, unfortunately. This one is a light-weight Ruby web server (I think). Anyway, I used it for my tiny gmail filter maker about a month ago, so when a classmate was struggling with it I offered to lend an eye. While we didn’t make leaps and bounds of progress, it challenged us both to think about harder about GETs and POSTs and how to see what of our parameters were getting properly delivered. Ultimately, I think she’ll need to switch to session variables, which I would love to learn how to do with Ruby and Sinatra, but I also had to get back to work on:

Nefario Teaches Typing

… my typing game. Progress so far: added the beginnings of a keyboard, changed the frame rate of the character’s animation, added scoring, added pause and resume. Next up: do more with the keyboard, pull some of the html-building out of the JavaScript and let it just be already in the html the way I want (will try to do this as a new “branch” so that I can go back to it… that will be an experiment/learning opportunity with git). I also need to refine the “rules” so that the level can be won or lost and is somewhat tailored to the player’s typing speed and accuracy. So much to do!

*SICP = Structure and Interpretation of Computer Programs, a fundamental work about what it means to write programs, used at MIT, “changed my life,” blah, blah, blah. It’s actually pretty cool, though quite dense.

Hacker School Day 8.Friday: On which I “implemented” a “stack” in JavaScript!

Yes!!!

This afternoon, in a matter of just a few hours, I learned:

  • What is meant by a “stack”: a data structure in which you pile things on top, much like books. These are not meant for accessing data from the earliest elements — they are intended for pushing (adding items to the top) and popping (taking items off the top).
  • What it means to “implement” your own “__________” (in this case a stack): build your own version of the thing, ideally using fewer built-in functions or structures than would be handy. (See below for an example.)
  • What a “linked list” is: (sorta) A data structure in which you store each element and it’s “pointer” to the element before it. This means in order to get from element “a” at the beginning of a stack, to element “f” that you’ve stacked up to now, you’ve got to go from “f” to “e”, then from “e” to “d”, etc., until you get back to “a”. Not sure what situations this would be super-helpful for (same way I feel about a stack), but I guess it’s good if you only need the most recent few elements? (Comments, enlightenment, and such are most welcome!)
  • Node is easy to install with homebrew: literally (first remember to update and doctor your brew):
    ~$ brew update
    ~$ brew doctor
    ~$ brew install node

    DONE! Now I can run js files in the terminal!

On “Implementing” a “Stack”:

Okay, so in JavaScript (as in most higher-level programming languages), there are built-in tools that do the stack-y things you need to do already, so a Super Cheaty Implementation of a stack in JS might be something like this:

function CheatingStack () {
	this.contents = [];
}
CheatingStack.prototype.push = function (item) {
	this.contents.push(item);
};
CheatingStack.prototype.pop = function () {
	return this.contents.pop();
}
CheatingStack.prototype.isEmpty = function () {
	return (this.contents.length === 0);
}

That makes use of built in methods push() and pop(), which put an item on and pop an item off the stack, respectively.

That sort of implementation is neither challenging nor interesting, so naturally I had to try harder. The facilitator, AO, who was helping me with this hinted that soon in SICP (the fundamental book of computer programming that I’m reading), the author will break all data down into pairs, and he showed me how pairs could just be “implemented” in JavaScript as an object with two parameters and two properties. From there, with some on-paper reasoning help from my lovely fellow student RS, I figured it out! I then tested it using console.log(), but I would like to implement more unit-testing methods that AO demonstrated. The trick (for the non-technical readers that I someday hope to have) is to create a tiny “Item” object that merely stores a value and a “pointer” (in this case, the item that comes before it). Then in your stack when you push a new element in, you make a new “item” object for it containing itself as the value and the last head object of your list as what it points to. All you have to track in your “stack” is what object you are currently pointing to. Then when you want to pop an item off the top of your list, you grab that head object, and fetch from inside it the object it’s set to point to and make that your new head. In my initial round of code, I was also storing an extra property called “prev” in my stack, but another facilitator, AK, kindly showed me that was entirely unnecessary! (Another great reason to show someone your code immediately.) For the technically inclined and curious, here’s a link to the code: Implementation of a Stack in JavaScript (gist).

Hacker School Day 6: On which I felt lost and found

It’s week two, day two (day six overall), and I feel behind. There hasn’t been enough time to do as much as I want, and I felt overwhelmed and a bit lost today. I also feel I haven’t been living up to the goals I had set myself (such as blogging daily). I started two other posts last week, but finished neither of them. I set myself up a huge chunk of tasks to finish over the weekend, but ended up doing life bits like laundry and a touch of leftover work instead.

I came to school early today (7:30am), which felt great. I’m still here now (9:40pm), and I still feel great (albeit tired). Obviously this is not sustainable, nor do I intend to maintain this pace, but I wanted to reset a bit today. I wanted to play catch-up, or at least not fall further behind. I am afraid to acknowledge that in the 14 hours I have spent here today, I have barely maintained pace. I suppose that means my goals are too big.

I had the opportunity to speak with an alum today who helped me see the beauty in focus (or rather the danger of spreading myself too thin). If I delve deep into one language, I’ll get down to the good parts and learn about how best to structure complex pieces of code and solve tough problems; whereas if I try to learn two or more languages, I’ll stay in the shallow waters with both. In light of that, I’m concerned with the amount of time I’m spending on studying this SICP stuff, but I think the mindset I’ll gain from it is worth a significant chunk of time. I’m also delighted at how hard it is. A large part of me wants to give up and consider myself stupid for being unable to maintain pace with the others in the class, but I refuse to give in to that familiar voice and course of action. It’s fine if I feel like the dumbest there. It’s even fine if I AM the dumbest there (though I refuse to believe that such a thing exists–degree of dumbness is not a linear spectrum… more like a sphere within which we all float). In response to the fear that wells up when I find my head swimming in terms I can’t quite grasp, today I admitted my struggles and accepted an offer of help.

In accepting help on math and logic (things I generally consider strengths of mine), I felt somewhat like a belly-up beached whale, flopping helplessly and shamefully, resigned to the help of another for my survival. That’s okay. It helped that I was beyond tired and hungry, so my brain was functioning at about one third capacity, rendering me even more willing, lowering my usual self-standards to the point of asking for a refresher on logarithms. Again, that’s okay. It felt good to let myself not understand. I am usually the one explaining things, so this was a huge role-reversal for me. Again, it was uncomfortable but healthy.

After another stab at some SICP problems (with no measurable result or success), I put down my pencil and opened this window. ‘Twas time to blog the day.

For tomorrow: I want to understand window.requestAnimationFrame and why I’m using it. It’s doing great things, but I would rather control my elements individually with many setInterval() calls. Therefore, my goals for tomorrow are: picking apart that mysterious function (and/or replacing it altogether), implementing a sprite png for my character, seeking advice on how to structure the pile of spaghetti that is my game, determining when my character hits a block, … and that is more than enough.

That’s all for now, folks!

P.S. While I’ve nothing directly technical to report (and I’m too tired to write it clearly even if I did), I learned about Proof by Induction today. I hate it, but it’s darn useful. Here’s the example A used to help me understand: if I can get on a rung of a ladder, and if being on one rung implies the ability to get to the next rung, then I can get to every rung after that initial (base case) rung. I think! Please comment if I’m wrong. I’ve tried to restate this about 20 times today and keep confusing the assumption/condition and the result/proven statements. Aye!

Hacker School Day 3: on which I realized that every day now is the best day of my life

Today I boldly decided to challenge myself to work through SICP, the classic text for learning the foundations of computer programming. There is a group of fellow students that are working through it together, so I seized the opportunity and joined the club despite my mild terror at the density of the book and the pressure of a book club. Luckily a few other folks joined late with me today, so the group postponed discussion of the first exercises until tomorrow. I was/am tickled at the familiar challenge of a formidable book that will surely cause my brow to furrow.

The morning was quickly consumed by checkins, the SICP meeting, and some preliminary SICP reading. At noon I joined a gaggle of javascripters seeking wisdom from the uber-cool M, who let us throw all kinds of questions her way while she patiently (and humorously) demonstrated the intricate puzzles of javascript prototypal inheritance. Don’t ask me what that phrase means because I have too many disjointed thoughts on the matter to tell you anything lucid. I might assign myself a mini project of explaining (perhaps illustrating) what I think I learned there today. It was like a brain race, dizzying and exhilarating, magically shedding light into dark corners only to reveal more unexplored pathways.

After the javascript party, I set my fried brain upon some SICP exercises until a fellow student was ready to pair program in Ruby. We worked on simplifying her slick Roman Numeral converter, and I was impressed with some of my own knowledge and experience. When we hit a terrific road block and posted a help request on our in-house irc client, one of the facilitators sprung to our aid. As Z helped us rewrite our broken nested hash reference, I felt a chunk of understanding finally click into place after years of vague reliance on shadowy comprehension and unpredictable results. For the technically-inclined, a brief explanation: (please don’t judge that it’s taken so long for me to grasp this simple concept in a sturdy way)
When accessing nested elements of a hash/dictionary/associative array in a for each loop (or .each do block in Ruby), the “value” of your new (key, value) pair IS the first nested hash, whereas I thought it was the first element of that nested hash. An example will explain far better than words:

If you have the associative array (sorry, I come from a php background… also I’ve met many cats of varying sizes):

cat_weights = {
  'plump' => {'oreo' = 15, 'adina' = 11, 'monty' = 19},
  'healthy' => {'leela' = 8, 'rosie' = 9},
  'skinnypants' => {'bosch' = 7, 'ziggy' = 5, 'curie' = 6}
}

and you’re doing a do block on each of the elements of cat_weights, as such:

cat_weights.each do |size, names|
  ...
end

and you want to access adina’s weight at some point, I initially thought you’d access it within the do block with size[‘adina’]. This is wrong! Size refers to the three strings: ‘plump’, ‘healthy’, and ‘skinnypants’, NOT hashes. The VALUES of those keys are hashes, hence you would access adina’s weight with names[‘adina’], since names is the pointer for the hash full of cat names and weights (the subhash to fatness levels, aka size). BAM! Now I finally know how to predictably access nested elements in a hash. Yessss!

After an hour or more of Ruby, I attended a Git lesson and learned about merging branches. After that I worked furiously on a small SICP exercise and became ensnarled in simple logic that I failed to wield correctly. At long last, I attacked the problem differently and got a working solution. For the logically inclined: given three numbers, how do you get the sum of the squares of the largest two using only combinations of logical functions and the multiplier? I’m either dumb or it’s harder than it seems. Regardless, getting a working solution felt so great simply because it didn’t come on my first or second try.

At the tail end of the day, wobbly with hunger, I sought to push my solution to github but forgot the proper command to link up my new local master to my new remote empty repo. I sought the help of T who gladly advised me and showed me a bunch of cool tidbits for working in Scheme. In posting my code and using a new IDE (Dr Racket for Scheme), I found myself in exactly the situation that Z had taught us about earlier at the Git session: Dr Racket had created a temp file that I did not want in my commit but had already staged! Fear not: I scrunched my face and pulled from my brain the command I’d learned earlier in the day (to remove specific files from my staging area: git reset HEAD filename). Brilliant! I also created a .gitignore file–another task I had learned at the Git session. So fun to put knowledge to use IMMEDIATELY. That’s what I’m doing all day long now. This is my version of heaven.

Hacker School Day 1

Welcome to Hacker School!

Amazing first day. Simply wonderful: a room jam-packed with interesting, intelligent, FRIENDLY people from all over, here to learn by doing for three months.

Technical Tidbits I learned today:

  • Learned a little about homebrew (package manager for OSX)
  • ‘bash’ is actually a language of its own; some handy commands that I already knew: pwd: print working directory (where you at), cd: change directory (go somewhere else), chown: change ownership of a file, mkdir: make a directory (folder), mv oldfilename newfilename: move a file by renaming it, rm: remove a file, ls: list (contents of a directory), ls -a: list all (even hidden files), | (pipe character): take output from one command and feed it into the next, touch filename: make file called filename
  • new bash commands I learned: open . : (shows the file in finder), grep: find everything that contains search term, cat: concatenate,
  • Also got a git overview and pushed some code up. I now have a better understanding of what a branch is and what the master is and what the origin is.
  • JavaScript:
  • found out that mozilla has some decent documentation, but was warned not to follow it too freely as some features there are only supported by firefox.
  • use chrome’s dev tools to explore built-in browser js objects like document and window.
  • .addEventListener(‘event’,’callbackfunction’,false) Can’t remember why we set false as third param… not sure if it prevents default or prevents propagation or what.
  • event: keydown returns an object chock full of stuff. I was able to fetch from this object the keyCode and translate it to its respective letter. (haven’t tackled modifier keys, numbers or any weird stuff yet)

Personal Reminders:

  • D said to be grateful for such a unique opportunity. I am! I really feel soooo lucky and thankful to be a part of this program.
  • Do things that make you uncomfortable (such as asking for help and pair programming)
  • Keep records of what you’ve done and want to do to help yourself stay on track

Overall, I feel somewhat exhausted, overwhelmed and DELIGHTED. Just tickled that I’m going to spend the next three months learning, doing, exploring, and working with wonderful people. This is clearly the beginning of a new phase in my life. Hallelujah!!