At last I understand. For quite some time now, I have been doing a lot of work on websites and web apps. Working on a variety of different frameworks, on several different projects. But I have always been working on the back end. Creating models, creating functionality, making interactive pages, and migrating data; Yet I never did any real work on the front end. I suppose my fantastical UI design for my TicTacToe app counts, and maybe the infinite beauty of my Crown Imports Mockup with Balsamiq, but no real front end web pages.
Today I at last learned how it is usually done. I also learned how bad I suck with photoshop, but thats another story.
Basically, you will hire some designer (perhaps even you can do it!) who knows a lot about making pretty things and making things that make sense for people who like things that make sense. This dude will whip up some totally awesome image of your webpage using photoshop or its equivalent. Then, after he has perfected every corner and nick nack, he will ship it over to you.
Hopefully, it is nicely layered and can be easily sliced, but even if its not you can still get the job done.
First, you need to decide which elements are going to be important and static. For example, most web pages have a fixed header and footer. You need to identify such items and extract them into their own images. Make sure you only grab parts that you know are going to be the same on pretty much every page.
Next, you find all the semi dynamic elements, like buttons and check boxes and such. There are some default buttons for most browsers, but you might want special buttons that look super cool and sparkle when you press them. Find these buttons and make sure you get both the default image, and the pressed image. You probably always want a mouse over image, so don't let your designer get away easy!
Once you have these elements, extract them out into their own images, keeping in mind they will be popping up all over the place.
Then, you spot out all the really dynamic items that are likely to change a lot. Animations, rotating picture frames, and text boxes/ text labels. All of these items will of course require different attention, but a few key things to keep in mind are make sure the text sizes the designer used will work in the browser and in your elements, make sure can include png images (Drew Diller has some useful tools for this), and make sure you rasterize any image you want to be transparent.
All these super dynamic items are going to require special attention, and there really isn't just one way good way (at least that I have come across) to handle them.
Finally, all these images and elements need to be shoved into some html so that they can be displayed on your web page. From what I have seen, some people like to use html tables to organize all the items, where as other people prefer using offsets to line everything up they way they like. You can do this in either html or css, or both, but css is a nice way to organize all the display information while also giving a lot of extra benefits.
Thats the general process of setting up the front end of a web page. After that you can add in some nice JavaScript to give you all the dynamic behavior you need, but make sure you are writing tests for that JS!
If you have any improvements or suggestions, or even good articles you know of that give further detail on the process, please let me know!
Thursday, April 8, 2010
Wednesday, April 7, 2010
Day 61
So, I was going to do a blog on how I set up my testing framework for JsUnit, and made a little interface to use it and all... but today I discovered ScrewUnit! After reading Corey Haines' blog on his stickies project , which was very much about testing JavaScript and all these neat ways to do TDD with it, I am now a complete convert. It is sooooooo much better than JsUnit. The error messages actually give line numbers! How weird is that?
BlueRidge and ScrewUnit are largely for Rails, but of course ScrewUnit can be used for just JS. It is an excellent framework, built up almost like RSpec, but of course the syntax is different. It is run in the browser, and you can just click on a test, or a describe block and it will run it. Very fantastical.
Since everything in JS is a object, and you can pass functions back and forth, most of the time mocking out objects is trivial. In fact, when you design your app using TDD, you can make it soooo versatile that you can just pass in functions or blocks that act as natural parameters, but can also do your test for you. Hopefully once I start my next project I will have some nice examples to show this in action.
I also learned a lot of JQuery today. How weird is it that you can get JQuery in one 6,000 line file? There are actually lots of JQuery libraries, but I just yoinked the recommended file for now. Pretty neat tool though. It will be nice not having to do a document.getElementById("") all the time, as well as making it easy to add classes to elements for easy styling. Something that will be exceedingly useful in the project I am about to start.
Speaking of which. I just estimated a new project, which is supposed to be a web app? The final nature of the program is still a bit of a mystery to me, which certainly causes issue with estimating, but it is supposed to be done nearly entirely with JavaScript. It is also a fairly large application. Not super complicated, it just has a lot of pages. This is why I wanted to learn a lot about ScrewUnit and JQuery, so that when I started working on this project I wouldn't do it page by page, but I would have the ability to create templates. It could take ages to finish if I had to design each page anew (there are actually a huge variety of them), but if I can get some really useful objects, then I am pretty sure I can start cruising!
Also, my classes are starting to become a pain now. Which is unfortunate. I have somewhat neglected them recently due to my apprenticeship challenges, and now it is coming back to haunt me!
BlueRidge and ScrewUnit are largely for Rails, but of course ScrewUnit can be used for just JS. It is an excellent framework, built up almost like RSpec, but of course the syntax is different. It is run in the browser, and you can just click on a test, or a describe block and it will run it. Very fantastical.
Since everything in JS is a object, and you can pass functions back and forth, most of the time mocking out objects is trivial. In fact, when you design your app using TDD, you can make it soooo versatile that you can just pass in functions or blocks that act as natural parameters, but can also do your test for you. Hopefully once I start my next project I will have some nice examples to show this in action.
I also learned a lot of JQuery today. How weird is it that you can get JQuery in one 6,000 line file? There are actually lots of JQuery libraries, but I just yoinked the recommended file for now. Pretty neat tool though. It will be nice not having to do a document.getElementById("") all the time, as well as making it easy to add classes to elements for easy styling. Something that will be exceedingly useful in the project I am about to start.
Speaking of which. I just estimated a new project, which is supposed to be a web app? The final nature of the program is still a bit of a mystery to me, which certainly causes issue with estimating, but it is supposed to be done nearly entirely with JavaScript. It is also a fairly large application. Not super complicated, it just has a lot of pages. This is why I wanted to learn a lot about ScrewUnit and JQuery, so that when I started working on this project I wouldn't do it page by page, but I would have the ability to create templates. It could take ages to finish if I had to design each page anew (there are actually a huge variety of them), but if I can get some really useful objects, then I am pretty sure I can start cruising!
Also, my classes are starting to become a pain now. Which is unfortunate. I have somewhat neglected them recently due to my apprenticeship challenges, and now it is coming back to haunt me!
Tuesday, April 6, 2010
8th Light Blog Post: JavaScriptness.prototype = new Class(); From Classical to Prototypal
JavaScript is a very misunderstood language.
It has gotten a bad rap because most people that use it don't look for its brighter side. Instead they will often look online for some code to copy paste, or they will hack something together using tiny snippets and in-lines to get a drop down menu.
It is also a very conflicted language. By nature, JavaScript is a Prototypal language where nearly everything is an Object and there are no classes. It is also somewhat Functional since all the functions are First Class Functions. They are just more objects that can be passed into and returned from other functions.
The issue is that many people try to use JavaScript like they would use Java or C++. They want a Classical language, where they strictly define all their types and then create instances of those types. Even though JavaScript can be jammed, beaten, or even mutilated into Classical structures (in fact the book JavaScript: The Definitive Guide spent a chapter on exactly that), this is betraying its nature and ignoring all the benefits that come with Prototypes.
The Classical Form
Lets take a look at a basic Classical implementation of a Square using JavaScript:
function Square (side) {
this.side = side;
}
Square.prototype.area = function () {
return this.side * this.side;
};
Square.prototype.perimeter = function () {
return this.side * 4;
};
var mySquare = new Square (5);
You will notice that JavaScript even has a new key word in an attempt to match a Classical implementation. The function Square () defines a class with a side attribute. It also has two instance methods, area and perimeter. We can then create mySquare in almost the same way we might do it in Java. This is JavaScript though, and the new works differently in JS. It creates a new, empty object and then calls the Square() function (or the constructor) passing the empty object into this . The constructor then populates that object with the specified behavior before returning it. This is particularly scary, because if you forget to put new in front of the constructor, this will refer to the Global Object, as will mySquare (meaning any further changes made to mySquare would also be on the Square 'class'). This is why, if you want to use JS in the Classical way, you should always capitalize the first letter of a constructor.
Ok, so we have our Square, but say we want to create a square that holds a X or an O. Well, we would want to inherit the properties of our current Square 'Class' and then add to them. We might do something like this:
function ContainerSquare (side, contents) {
this.superclass(side);
this.contents = contents;
}
ContainerSquare.prototype = new Square();
ContainerSquare.prototype.superclass = Square;
ContainerSquare.prototype.constructor = ContainerSquare;
ContainerSquare.prototype.getContents = function () {
return this.contents;
};
var myContainer = new ContainerSquare(6, "X");
We create a new 'Class' for the ContainerSquare which uses the Square's constructor to define the side attribute, along with the two instance methods. We then define our new contents attribute, along with an accessor method to go with it.
The ContainerSquare .prototype = new Square();
line sets up a Prototypal inheritance structure so that a ContainerSquare object will be linked to the proper prototype chain.
The prototype chain is the hierarchy of objects that a method or attribute call will traverse until it finds what it is looking for. In other words, when I call myContainer.size(), JavaScript will first check to see if the myContainer object has that function. If not, it will proceed to check the object's prototype, which is the ContainerSquare. Since ContainerSquare doesn't have the function, next in line is ContainerSquare's prototype, which is just Square. Square does in fact have a size() function, and since javascript will use the first function it finds, it will use Square's size() function.
Thus, by setting ContainerSquare's prototype to Square, we inherit any of the attributes or methods of Square.
Although this all works, and we have successfully mashed a Prototypal language into a Classical scheme, we should try this in the way JavaScript wants to be used.
The Prototypal Form
We can start with the Square. There are few pretty simple ways to achieve the same functionality using regular objects and their prototypes, and we will look at two of them. The first will create a square object that we can use. Then if we need more squares, we can make a copy of that object using its prototype. The second will create a squareMaker function, which can then be used to pop out new squares.
var firstSquare = {
side: 5,
area: function () {
return this.side * this.side;
},
perimeter: function () {
return this.side * 4;
}
};
Here, we already have a new and usable square at our disposal. We don't need to call a constructor and define any types. We can just take an object and mold it into the form we want.
Say we want another square though. We can't just write something like var secondSquare = firstSquare; because JS passes objects by reference, and thus the second square would just point to the first square. What we can do, and this is a technique developed by Douglas Crockford, is make a copy of our object by calling a new constructor with a prototype that points to our object. This new contructor creates a new empty object and assigns the values of our old object to the new empty object. You can do this yourself, or you can use Crockford's technique as follows:
if (typeof Object.beget !== 'function') {
Object.beget = function (o) {
var F = function () {};
F.prototype = o;
return new F();
}
}
var secondSquare = Object.beget(firstSquare);
secondSquare.side = 6;
You can see that we are actually defining an on the fly constructor F, using our object 'o' to define F's prototype (where 'o' is firstSquare). Then we create a new object using that constructor. This will give us a new copy of our object, with all its attributes and functions. If we now called secondSquare.area(); we would get 36.
If you wanted to then make a ContainerSquare, you could simply add a contents attribute to the second square, and then make copies of the secondSquare if you need more Containers. Keep in mind that since firstSquare is the prototype of secondSquare, if you were to add a contents attribute to firstSquare, you would then have that attribute on secondSquare; however, adding attributes to the secondSquare does not place them on the firstSquare.
Spawn More Protolords
The other way to get squares would be to make a squareMaker function. This function will return a new object with whatever attributes you define. I am also going to show you some closure so that the attributes are private, and only accessible through accessor methods.
var squareMaker = function(side) {
return {
getSide: function() {
return side;
},
area: function () {
return side * side;
},
perimeter: function () {
return side * 4;
}
};
};
var anotherSquare = squareMaker(5);
You will notice that the return value of the squareMaker is almost exactly like how we defined our firstSquare object. We are just returning the definition of a square, and thats quite awesome. Another thing you will notice is the bit of closure. We pass a value into the squareMaker, but it isn't stored anywhere. It is held in the scope of the squareMaker function, allowing those internal methods to use it, but hiding it from the outside (unlike the side attribute defined in the firstSquare). This sort of closure is another wicked awesome tool you can use in JS. In a way, this use of closure is like defining private variables to a class.
To get the Container functionality we create a containerMaker using the squareMaker, and some more closure, to make a new square object. We then dynamically add a getContents method to provide access to our private contents attribute.
var containerMaker = function(side, contents) {
var container = squareMaker(side);
container.getContents = function () {
return contents;
};
return container;
};
var anotherContainer = containerMaker(6, "O");
Conclusion
So we have now seen two ways to use some of the better parts of JavaScript to get the same functionality that we could get using the Classical scheme. We can also see some advantages in using JS in its natural form like: getting some closure (which can be exceedingly powerful), very dynamic objects ready to change in anyway you can think of, quickly defined objects which can be used and multiplied, and no need to predefine types. Pretty sweet right?
I will admit one slight inefficiency with the two solutions I showed you (although there are ways around this). Using the squareMaker, or making copies of the objects will make full copies, including the function objects defined inside. If you use the Classical scheme I showed, you are defining functions on the prototype rather than the object itself, thus there will only be one copy of the function.
You can, of course, do something similar in the JS scheme, but the optimization doesn't count for all that much in most cases (unless you are doing mobile development where you want to save everything you can!).
JavaScript isn't a Classical language, but instead a Prototypal language that is powerful enough to mimic a Classical language without breaking a sweat. There is much to be gained by recognizing this fact and changing your mindset to work with it. Trying to fit a square into a circular hole will just get you stuck. All languages are unique with a variety of their own advantages, and as good developers we should recognize these differences and reap all the benefits they have to offer.
Monday, April 5, 2010
Day 59
Java Script!! So I finished my unbeatable TicTacToe last night... or this morning really. For only having 4 days (2 of which I was still quite sick) to learn a new language (2 really, since I didn't know HTML very well at all either), to learn and customize a new testing framework, and to create a new TicTacToe program, ai, and interface, it turned out really awesome. The interface was a little spartan, but it was fully functional with bonus features.
Though this was probably just because of the tools I was using, I found that I had to be exceedingly careful with Java Script. There are a lot of little things you can do or forget to do that will really mess you up. Since the code is all compiled in the browser, and most things in the language are done at run time, the errors can be pretty tough to chase. Even when using a testing framework like JsUnit, you just don't get very much valuable feedback from error messages.
As a result, I worked extremely carefully, doing everything slowly and very incrementally. I never made a huge changes without running my tests again and again, and making sure everything still worked along the way. This way, most of the errors I had were found within just a few moment by scanning through the recently changed code. I was also fortunate enough to have all the basic rules of what to do and what not to do fresh in my mind from the Java Script: The Good Parts book.
Another thing that I did, that I know saved me in a huge number of cases, is I would very, very frequently stop moving forward and move back two steps. Rather than adding another test and getting a new feature done, I would look back at what I had and see if I could find any better implementations. At first I did this just to try to make use of some of the cool benefits of the Prototypal and Functional nature of JavaScript, but after awhile it just didn't make sense not to go back and refactor. I found time and time again that if I hadn't turned back to refactor when I did, if I had just delayed it for one or two more features, I would have been stuck with a mess. At that point, I probably would have just kept what I had and continued to develop a messier and messier program.
It was also really easy. It just seemed like Java Script is the type of language that wants to be refactored. Perhaps its because I wasn't used to it. But it is also possible, because the language is so straight forward, so direct, and so expressive, that there is almost always a obvious and significant improvement that you can make.
Testing JS was a bit of a pain at first. Actually, it was a bit of a pain most of the time. Once again, this may be from my lack of experience, but JS and HTML seemed so intertwined that decoupling the logic from the GUI was often a challenge.
For example, to include a JavaScript file from another JavaScript file you have to actually generate some HTML to include it! I didn't want to explicitly write out
Here is how I did it:
This made it easy to include more files, if need be, and was a guaranteed way to work across browsers.
I am completely exhausted now and am gonna go pass out. Something I discovered last night/morning - when you are at the point where your brain shuts off (maybe around 2:30 - 3 AM) but you still have to get things done... it might honestly help more to just start trying random things and use guess and check rather than thinking it through. After I spent about 45 -60 minutes trying to work through a problem step by step, with no success, I decided to just start switching the important variables in a nearly random manner with the key values, and within about 3 minutes I stumbled upon the solution. Of course in the morning I spotted in almost immediately, but desperate times often require desperate measures. And hot damn, it got the job done.
Tomorrow I will go over some of the ways I used JsUnit to test my code. I will also be handing in my 8thLight Blog submission tomorrow, so that should be interesting.
Though this was probably just because of the tools I was using, I found that I had to be exceedingly careful with Java Script. There are a lot of little things you can do or forget to do that will really mess you up. Since the code is all compiled in the browser, and most things in the language are done at run time, the errors can be pretty tough to chase. Even when using a testing framework like JsUnit, you just don't get very much valuable feedback from error messages.
As a result, I worked extremely carefully, doing everything slowly and very incrementally. I never made a huge changes without running my tests again and again, and making sure everything still worked along the way. This way, most of the errors I had were found within just a few moment by scanning through the recently changed code. I was also fortunate enough to have all the basic rules of what to do and what not to do fresh in my mind from the Java Script: The Good Parts book.
Another thing that I did, that I know saved me in a huge number of cases, is I would very, very frequently stop moving forward and move back two steps. Rather than adding another test and getting a new feature done, I would look back at what I had and see if I could find any better implementations. At first I did this just to try to make use of some of the cool benefits of the Prototypal and Functional nature of JavaScript, but after awhile it just didn't make sense not to go back and refactor. I found time and time again that if I hadn't turned back to refactor when I did, if I had just delayed it for one or two more features, I would have been stuck with a mess. At that point, I probably would have just kept what I had and continued to develop a messier and messier program.
It was also really easy. It just seemed like Java Script is the type of language that wants to be refactored. Perhaps its because I wasn't used to it. But it is also possible, because the language is so straight forward, so direct, and so expressive, that there is almost always a obvious and significant improvement that you can make.
Testing JS was a bit of a pain at first. Actually, it was a bit of a pain most of the time. Once again, this may be from my lack of experience, but JS and HTML seemed so intertwined that decoupling the logic from the GUI was often a challenge.
For example, to include a JavaScript file from another JavaScript file you have to actually generate some HTML to include it! I didn't want to explicitly write out
<script type="text/javascript" src="another.js"></script>right in my first JS file, so instead I added another function to the document object which creates a script element, and plugs in the file you want. This way, anytime I wanted to include another .js file, I could call that function in my current .js file, and avoid having to write out the script line (which btw is fickle way to do it because certain browsers (like IE7) will read your <> ... < / script > as the tag for the previous include, and thus will mess everything up. So you actually would have to do <> ... < / scr + ipt > so that the tags couldn't be read until they were concatenated by the parser, and thus safe).
Here is how I did it:
document.addAnotherJavaScriptFile = function (filePath) {
var head = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.setAttribute('type', 'text/javascript');
newScript.setAttribute('src', filePath);
head.appendChild(newScript);
};
document.addAnotherJavaScriptFile("game/computer.js");
This made it easy to include more files, if need be, and was a guaranteed way to work across browsers.
I am completely exhausted now and am gonna go pass out. Something I discovered last night/morning - when you are at the point where your brain shuts off (maybe around 2:30 - 3 AM) but you still have to get things done... it might honestly help more to just start trying random things and use guess and check rather than thinking it through. After I spent about 45 -60 minutes trying to work through a problem step by step, with no success, I decided to just start switching the important variables in a nearly random manner with the key values, and within about 3 minutes I stumbled upon the solution. Of course in the morning I spotted in almost immediately, but desperate times often require desperate measures. And hot damn, it got the job done.
Tomorrow I will go over some of the ways I used JsUnit to test my code. I will also be handing in my 8thLight Blog submission tomorrow, so that should be interesting.
Thursday, April 1, 2010
Day 57
So apparently driving for 24 hours straight can get you sick. I got back from my vacation to Florida, where I visited Panama City Beach (Amazing!), and Miami for the Ultra Music Festival, and the drive back was a grand total of about 1,400 miles and 24 hours of driving. Since we wanted to get back on Monday at a decent time, we drove straight through the night with scattered chunks of restless sleep as me and Tomato switched off. 5 monster energy drinks and a bunch of Oreos later I was home.
Unfortunately I must have caught something in Florida, and the lack of sleep mixed with a lack of nutrition and the overall unsanitary environment which is my car, my immune system was crashed.
Tuesday I felt under the weather, but was still able to get a lot of reading done. Colin, I finished the Java Script book, which was excellent by the way, and I can get it to you tomorrow. If you don't mind, I might want to keep it for reference though because I am going to do my 8th Light blog post on turning a Classical Object Oriented/Class driven batch of code into the true Prototypal nature which is Java Script.
Wednesday I was in bed for nearly the whole day, my body completely stripped of energy and trying to over come whatever it was I had/have. A soar throat, relentless coughing, wavering headaches, and a complete lack of energy left me almost completely worthless. I did still manage to mess around with getting some basic JavaScript and HTML interaction going. I was pleased to find out that it is actually exceedingly easy, but that was after I angrily grouched about trying to find out why certain things weren't working only to find out that there was a typo in the book! A simple little mistake, very illusive and sneaky. The book was defining a literal with one attribute and one function like so:
Can you spot it? The actual code chunk was a little bit larger, but this is where the error lies.
Having no real JScript experience, I was completely baffled why my very first test program (after some other simpler stuff like 'Hello World' and such) wasn't working.
See it yet?
Its the semicolon after the value: 0;
It is supposed to be a comma... Blast you editors not catching publish mistakes!!
When defining attributes of a literal you use the format
{ name: value,
name2: value2,
name2: value3
}
Oh well...
Today, although I still felt kinda crappy, I was able to get a lot done. After playing around a bit longer, getting a better feel for the relationship between JavaScript and HTML, I spiked out a complete TicTacToe interface which was totally playable and such, but no AI. Now I am working on the real interface using TDD and JSUnit. JSUnit is a lot like JUnit, but I am making my own test page thingy, which is pretty sweet.
I have a LOT to do yet, so tomorrow and this weekend are going to be packed tight!
Unfortunately I must have caught something in Florida, and the lack of sleep mixed with a lack of nutrition and the overall unsanitary environment which is my car, my immune system was crashed.
Tuesday I felt under the weather, but was still able to get a lot of reading done. Colin, I finished the Java Script book, which was excellent by the way, and I can get it to you tomorrow. If you don't mind, I might want to keep it for reference though because I am going to do my 8th Light blog post on turning a Classical Object Oriented/Class driven batch of code into the true Prototypal nature which is Java Script.
Wednesday I was in bed for nearly the whole day, my body completely stripped of energy and trying to over come whatever it was I had/have. A soar throat, relentless coughing, wavering headaches, and a complete lack of energy left me almost completely worthless. I did still manage to mess around with getting some basic JavaScript and HTML interaction going. I was pleased to find out that it is actually exceedingly easy, but that was after I angrily grouched about trying to find out why certain things weren't working only to find out that there was a typo in the book! A simple little mistake, very illusive and sneaky. The book was defining a literal with one attribute and one function like so:
var myObject = {
value: 0;
increment: function (inc) {
this.value += typeof inc === 'number' ? inc : 1;
}
};
myObject.increment();
document.writeln(myObject.value); // 1
Can you spot it? The actual code chunk was a little bit larger, but this is where the error lies.
Having no real JScript experience, I was completely baffled why my very first test program (after some other simpler stuff like 'Hello World' and such) wasn't working.
See it yet?
Its the semicolon after the value: 0;
It is supposed to be a comma... Blast you editors not catching publish mistakes!!
When defining attributes of a literal you use the format
{ name: value,
name2: value2,
name2: value3
}
Oh well...
Today, although I still felt kinda crappy, I was able to get a lot done. After playing around a bit longer, getting a better feel for the relationship between JavaScript and HTML, I spiked out a complete TicTacToe interface which was totally playable and such, but no AI. Now I am working on the real interface using TDD and JSUnit. JSUnit is a lot like JUnit, but I am making my own test page thingy, which is pretty sweet.
I have a LOT to do yet, so tomorrow and this weekend are going to be packed tight!
Monday, March 22, 2010
Day 54
I received my next two apprenticeship challenges today, and I am quite psyched to get them done! The first is to write a more formal and informational blog post for the 8th Light website. The second is to write an unbeatable Tic Tac Toe in a language I have never used before.
For the blog post I was thinking I would write a tutorial on how to get started on a new Limelight app, but it turns out Paul Pagel already wrote one of those. It might still be a good idea since Limelight has evolved quite a bit since that blog, but I am not sure yet.
As for the Tic Tac Toe in a new language, I was thinking I would do it in java script. Not my first choice in languages, but I will have to learn JS soon anyway to do a project Paul has been asking me to work on, which will be pretty much entirely done in JS, as well as a little html and css. I kind of want to do it in a functional language like clojure since I have almost no experience working in that frame of mind, but JS would be a twofer.
Here is the catch though. I have the next two weeks, plus a weekend, to finish these two tasks, and I will be gone in Florida for the rest of this week! That means I have only 7 days to get these two tasks done... I see some rough nights in my near future, and I am damn excited to make the most o them!
Today I did some more work on Limelight, getting some more tests to pass and fixing up the margins on the text area.
I also got royally pranked by two esteemed members of the 8th Light team. I will let them remain unnamed for their treachery, as no good prank is left unanswered.
Basically, I had gone to the DMV today to renew my license, but of course it turns out they are closed on Mondays. Either way, I mentioned this at lunch in the office. Later on, I left my iphone in the bathroom where it was recovered by one of the Craftsman to remain unnamed. Rather than return it to this unsuspecting, trusting, and apparently oblivious apprentice, this Craftsman, along with another Craftsman, decided to see what fun they can have.
At about 3 pm I get an email from a Jacob Carson, who says I left my ipone near the Libertyville DMV and they wish to claim the reward (I keep my info and a $50 reward offer as my phones default background). This completely blows my mind as I specifically remember walking into the office listening to a podcast when I returned from the DMV. Suddenly I start frantically retracing my steps in my mind trying to find out how this could be possible. Did I hallucinate having my phone when I came back? Could I have been listening to my nano? Was I thinking of a different day?
I eliminated all these possibilities, and it seemed to me that there remained only one possibility. Neither Micah nor I use an iPhone case, and thus they appear remarkably similar face down. I conceived that it was possible I had left mine in the bathroom, which Micah must have later gone into and mistakenly taken my phone for his, at which point he went out for lunch (with a client) at the subway right next to the DMV. There my phone must have somehow slipped out of his pocket, thus returning it to the place I had been earlier today. An outrageously unlikely possibility, but Eric Smith wasn't in the office that day, so it must be the case.
I went down and asked Micah if he had eaten at subway today, and of course he said no.
Perplexed... I proceeded on to the bathroom, to the origin of the problem. Once I step out, there lies my phone on the ground before me.
It was so obvious, but so very devious. Touche good sirs, touche.
For the blog post I was thinking I would write a tutorial on how to get started on a new Limelight app, but it turns out Paul Pagel already wrote one of those. It might still be a good idea since Limelight has evolved quite a bit since that blog, but I am not sure yet.
As for the Tic Tac Toe in a new language, I was thinking I would do it in java script. Not my first choice in languages, but I will have to learn JS soon anyway to do a project Paul has been asking me to work on, which will be pretty much entirely done in JS, as well as a little html and css. I kind of want to do it in a functional language like clojure since I have almost no experience working in that frame of mind, but JS would be a twofer.
Here is the catch though. I have the next two weeks, plus a weekend, to finish these two tasks, and I will be gone in Florida for the rest of this week! That means I have only 7 days to get these two tasks done... I see some rough nights in my near future, and I am damn excited to make the most o them!
Today I did some more work on Limelight, getting some more tests to pass and fixing up the margins on the text area.
I also got royally pranked by two esteemed members of the 8th Light team. I will let them remain unnamed for their treachery, as no good prank is left unanswered.
Basically, I had gone to the DMV today to renew my license, but of course it turns out they are closed on Mondays. Either way, I mentioned this at lunch in the office. Later on, I left my iphone in the bathroom where it was recovered by one of the Craftsman to remain unnamed. Rather than return it to this unsuspecting, trusting, and apparently oblivious apprentice, this Craftsman, along with another Craftsman, decided to see what fun they can have.
At about 3 pm I get an email from a Jacob Carson, who says I left my ipone near the Libertyville DMV and they wish to claim the reward (I keep my info and a $50 reward offer as my phones default background). This completely blows my mind as I specifically remember walking into the office listening to a podcast when I returned from the DMV. Suddenly I start frantically retracing my steps in my mind trying to find out how this could be possible. Did I hallucinate having my phone when I came back? Could I have been listening to my nano? Was I thinking of a different day?
I eliminated all these possibilities, and it seemed to me that there remained only one possibility. Neither Micah nor I use an iPhone case, and thus they appear remarkably similar face down. I conceived that it was possible I had left mine in the bathroom, which Micah must have later gone into and mistakenly taken my phone for his, at which point he went out for lunch (with a client) at the subway right next to the DMV. There my phone must have somehow slipped out of his pocket, thus returning it to the place I had been earlier today. An outrageously unlikely possibility, but Eric Smith wasn't in the office that day, so it must be the case.
I went down and asked Micah if he had eaten at subway today, and of course he said no.
Perplexed... I proceeded on to the bathroom, to the origin of the problem. Once I step out, there lies my phone on the ground before me.
It was so obvious, but so very devious. Touche good sirs, touche.
Sunday, March 21, 2010
Day 53
The presentation went quite well, and I got a lot of excellent feedback. I was also able to talk to my dad and get some more ideas.
Here is what I am going to do:
First I will lay out a hypothesis on what good code looks like. I will then choose a batch of code snippets that represent my hypothesis, and I will also select some snippets that are nothing like my hypothesis, as well as some random snippets.
Next I will collect audience feedback on the snippets and use it to refine my hypothesis. I will take their suggestions to refine the snippets and further polarize them.
After I implement the last group's suggestions, I will show the snippets to a new group and see if there has been any improvement. From this I can begin to derive some knowledge about what people 'think' good code looks like, and what people will actually rate as good code.
This discrepancy alone will be valuable because it will demonstrate whether or not we know how to write code that we will like. As most developer's know, their own code is always excellent and clever... for a few months, but when you come back to it a year later it might not be so good. This could be because we have gotten much better at writing code, but it could also be because we never really thought it was good in the first place. We merely implemented what we thought were good practices, and not what we actually valued in code.
Once I have gathered enough data, and refined my methods such that I can accurately predict if people will perceive a code segment as good or bad, I can then work to create a flurry of good code segments.
With these I can begin offering more talks, still collecting data, but also performing a little Clockwork Orange. I will be able to show slides with code that I know almost everyone agrees to be good, and use them to 'condition' the audience.
I can perform little experiments where everyone writes a small function at the start of the talk, and then every 5 slides people will pass their functions around and have others rate them. We will see if the average ratings change, and for what reasons. We would then write another function half way through, perform the same task, but see if the ratings have improved.
Lots of value to be gained here, and I don't even know the half of it.
Here is what I am going to do:
First I will lay out a hypothesis on what good code looks like. I will then choose a batch of code snippets that represent my hypothesis, and I will also select some snippets that are nothing like my hypothesis, as well as some random snippets.
Next I will collect audience feedback on the snippets and use it to refine my hypothesis. I will take their suggestions to refine the snippets and further polarize them.
After I implement the last group's suggestions, I will show the snippets to a new group and see if there has been any improvement. From this I can begin to derive some knowledge about what people 'think' good code looks like, and what people will actually rate as good code.
This discrepancy alone will be valuable because it will demonstrate whether or not we know how to write code that we will like. As most developer's know, their own code is always excellent and clever... for a few months, but when you come back to it a year later it might not be so good. This could be because we have gotten much better at writing code, but it could also be because we never really thought it was good in the first place. We merely implemented what we thought were good practices, and not what we actually valued in code.
Once I have gathered enough data, and refined my methods such that I can accurately predict if people will perceive a code segment as good or bad, I can then work to create a flurry of good code segments.
With these I can begin offering more talks, still collecting data, but also performing a little Clockwork Orange. I will be able to show slides with code that I know almost everyone agrees to be good, and use them to 'condition' the audience.
I can perform little experiments where everyone writes a small function at the start of the talk, and then every 5 slides people will pass their functions around and have others rate them. We will see if the average ratings change, and for what reasons. We would then write another function half way through, perform the same task, but see if the ratings have improved.
Lots of value to be gained here, and I don't even know the half of it.
Subscribe to:
Posts (Atom)