Monday, February 28, 2011

Chrome Developer Tool Tips

Some really cool tips on using Chrome's developer tools are shown on this video:

HW6 Graded and my Solution

I have just emailed the grades for HW 6. People seem to be having trouble with creating closures. Below is my solution to the this homework. Notice how the makeDisperse function creates other functions (closures), each of which with possibly different 'neighbors' depending on the arguments passed to makeDisperse.

//Returns a list of the 4 elements that are North, South, East and West of the 
// button with id= 'b' + row + col
function getNeighbors (row, col) {
 var result = [];
 var nrow = (row == 0) ? SIZE - 1 : row - 1;
 var ncol = col;
 result.push(document.getElementById('b'+ nrow + ncol));
 nrow = row
 ncol = (col + 1) % SIZE;
 result.push(document.getElementById('b' + nrow + ncol));
 nrow = (row + 1) % SIZE;
 ncol = col;
 result.push(document.getElementById('b' + nrow + ncol));
 nrow = row;
 ncol = (col == 0) ? SIZE - 1 : col -1;
 result.push(document.getElementById('b' + nrow + ncol));
 return result;
}


//Creates and returns an event handler which is a closure that holds
// 'neighbors', a list of the 4 elements that are North, S, E, West of the
// button at row,col. The function it returns distributes the value of this
// over the 4 neighbors.
function makeDisperse(row, col){
 var neighbors = getNeighbors(row,col);
 function disperse () {
  var myNumber = Number(this.value);
  while (myNumber > 0){
    for (var i =0; i < neighbors.length; i++){
     var nelement = neighbors[i];
     nelement.value = Number(nelement.value) + 1;
     myNumber--;
     if (myNumber <= 0 ) { break;}
    }
  }
  this.value = 0;
  updateScore();
 };
 return disperse;
}

//This method on <body onload="setup()". It sets an event-handler for every button.
function setup(){
 for (var row =0; row < SIZE; row++){
  for (var col=0; col < SIZE; col++){
   var button = document.getElementById('b' + row + col);
   button.onclick = makeDisperse(row,col);
  }
 }
}


//Updates the value of the score button to be the count of all the zeros in all the buttons.
function updateScore(){
 var total = 0;
 for (var row =0; row < SIZE; row++){
  for (var col=0; col < SIZE; col++){
   var button = document.getElementById('b' + row + col);
   if ('0' == button.value) {
    total++;
   }
  }
 }
 var scoreButton = document.getElementById('score');
 score.value = total;
}

People do a lot of JavaScript programming without understanding closures. Still, they are a really useful and powerful feature of the language: used for creating private variables, custom functions (as above), and namespaces, among other uses. I think you will be a much better developer if you understand and use them as needed.

HW7: A JavaScript Math Quiz App

For this homework you will build a stand-alone math quiz/drill program. If you have ever visited the Khan Academy you will see that, in addition to all the cool videos, Kahn also has a webapp for practicing math. For this homework you will build JavaScript application that asks the user simple math questions, and provides him with feedback on his progress. Note that this will be a stand-alone application, independent of the survey webapp we have been developing (for now?). You will be using jQuery for this and jQueryUI if you want.

There are a few things that we know, from educational and video game research, about how to build these types of apps.

  1. Students should be given immediate feedback. So, you should immediately tell the user if his answer is right or wrong, and give him the correct answer.
  2. Achievements (badges, medals, etc.) keep them hooked. So, we are going to have a lot of them.
  3. You can never have too much eye candy.
Specifically, you will implement the following features.

  1. When loading the page the user is asked whether we wants to practice addition, subtraction, or multiplication.
  2. In this game the user is asked one question at a time. They all consist of a problem using the digits 0 to 9. For example: 4 + 2 = __. The user answers the question by typing in the number and hitting enter.
  3. Rather than generating numbers from a flat random probability, which generates too many 0,1, and 5s, pick them randomly from this list: [0,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,9,9].
  4. Do not ask subtraction questions for which the answer is a negative number.
  5. If the answer is wrong, the program tells the user he was wrong and tells him the right answer. If we was right the program tells him. In both cases the user is immediately presented with the next question.
  6. The app show the latest 2 questions and their answer. You should show both the answer the user gave and the correct answer, if different. Correct answers should look different than wrong answers (different color, strikethru, etc.). Below these (or above) we see the current question. When a new question appears it should smoothly scroll the oldest question off. The is no scroll bar, this is an automatic scrolling.
  7. There is a clock that countdowns the 10 seconds the user has to answer the question. If the user does not answer within the 10 seconds then the answer is considered wrong, the right answer is shown and a new question appears.
  8. There is a bar that keeps track of the number of consecutive correct answers.
  9. There are achievements that appear, and fade away slowly, for different events:
    1. when the user gets 10, 20, 30,....consecutive correct answers.
    2. when the user correctly answers 10 questions in less than 20 seconds total, 20 in less than 40 seconds, and so on. Basically, he is averaging less than 2 secs per answer (that might be too hard, feel free to change the exact time to what you think is a good number).
    3. when the user has had a total of 10 correct (not necessarily consecutive) answers, 20, 30, and so on
  10. Each one of the 3 type of achievements above should appear with a different animation. Try to be creative. Use jQueryUI if you want, or even a jQuery sound plugin, if you want (not required). Remember, you cannot have too much eye candy when giving out achievements.

This homework is due on Monday, March 14 @11am, you can turn it in here.

Required Reading

Friday, February 25, 2011

How Not to do onclick

Check out the following code, which is live in this page.

<!DOCTYPE html>
<html>
<body>
<input type="button" value="0" id="a" onclick="increase()"/>
<input type="button" value="10" id="b"/> <script> function increase(){ this.value = Number(this.value) + 1; } document.getElementById('b').onclick = increase; </script> </body> </html>

In my chrome and firefox, clicking on the first button does nothing, while clicking on the second one increases the number by 1. If we open up firebug and print out the onclick properties for the two elements, we can see why the first one does not work.

> document.getElementById('a').onclick
function onclick(event) {
  increase()
}

> document.getElementById('b').onclick
function increase(){
 this.value = Number(this.value) + 1;
}

The first one has a function called onclick wrapped around the call to increase. So, in the first case, increase gets called as a global function which means that this will be bound to the global object. In the second case increase is called as a method of the input element.

Why this distinction? I don't know. What do you need to know? 1) Use the second form for this homework and 2) always use a good javascript library for setting up and handling events; like jQuery, which you will start using next week.

John Resig on jQuery

Below is John Resig, jQuery author, on jQuery. The first part of the video is about JavaScript. You can skip to the 0:30 mark, or so, where he starts to talk about jQuery.

Theory and History of the DOM

Crockford is back, this time discussing the Document Object Model. We will be talking about this, and jQuery, next week.

Wednesday, February 23, 2011

JavaScript: The Good Parts: The Video

Basically, you should think of Crockford as the one teaching CSCE 242 and me as the TA.

JavaScript Closures: Used for Privacy

I mentioned in class how you could use closures to create private variables, just like Java has. The code below shows how this is done. Notice that the only way to get at joe's name is using the given functions. If you wanted to make the name a constant then you could just get rid of setName and no one would be able to change joe's name. Pretty cool!

//This is how you make an object with private variables.
function Employee(){};

function newEmployee(theName) {
 var name = theName;
 Employee.prototype.getName = function(){return name;}
 Employee.prototype.setName = function(n){name = n;}
 return new Employee();
}

//The only way to change joe's name is by calling joe.setName.
joe = newEmployee('Joe');
joe.getName(); //get his name
joe.setName('bob'); //he is now bob

You don't need the name variable, we could have just used theName instead. But, maybe this makes it clearer? I find it a bit more intuitive this way.

Challenge Round: First Group

This Friday we start the challenge rounds. The following students will report to my office at the given times.

  • 11:30, Abbot
  • 11:40, Boykin
  • 11:50, Carroway
  • 12:00, Clarke

Monday, February 21, 2011

HW5 Grades Out

I emailed grades earlier. Those of you who did not get it to work, please do so. Let me know if you need help. At worst, I can finish the coding for you (which will be better than you starting over with someone else's code). You will need this code in a couple of weeks when we start putting our JavaScript skills to work on prettying up the webapp.

Lecture Examples

I added some comments to the class example (see the script.js and jspage.html files). I'll be talking more about JavaScript and closures on Wednesday. Next week we will cover DOM manipulation and jQuery.

The example files show a simple way to handle events. However, the recommended way is to use a JavaScript library. Different browsers implement event-handling in different ways (they are converging, but there are a lot of old browsers in use) and there are many good javascript libraries that deal with all this ugliness so we don't have to. We will be using jQuery.

We will be building again on our surveys webapp in future weeks: adding some drag-and-drop editing and AJAX functionality, and graphics, gotta have graphics! Stay tuned.

HW6: JavaScript Practice

This homework is a short stand-alone JavaScript+HTML program that will give you some practice with the JavaScript basics. You will write one HTML page and one JavaScript file that together implement a simple game (well, game-like thing). Specifically:

  1. You will write an HTML with 100 buttons in a 10 by 10 table. Every button has the number 1 in it.
  2. When the user clicks a button the number in that button gets distributed among its North, East, South, and West neighbors, with wraparound. For example, if the button has the number 2 button to the North will have its number increased by one, as well as the number to the East. The button that had the 2 will now have 0.
  3. There is a score button which always contains the number of zeroes in the game board.
  4. You will use closures for implementing the onclick methods. I know that this homework can be done without using closures, but I want you to practice using closures. Specifically, you will write one function that generates a function for each button.
  5. You cannot use any JavaScript libraries. We will be using jQuery in the next homework, but not for this one.

You can turn it in here. The deadline is Monday, February 28 @11am. Also, make you you post it on your appspot.com site. You can just put in in a /test directory and add that directory as a static_dir in your app.yaml. Make sure you put the url to your published code in the source code you turn in.

Required Reading

  1. The videos from the previous post.
  2. The JavaScript Guide.

Here is a quick demo of what it should look like:

Unable to display content. Adobe Flash is required.

Friday, February 18, 2011

JavaScript: The Most Used Programming Language in the Universe

Next week we begin our journey into the magical realm of JavaScript. I will be trying to show you some of the most important bits about the language in class, but I highly recommend you also listen to the lectures below by Douglas Crockford: Master Yoda of JavaScript.

Introduction to JavaScript Lectures

Advanced JavaScript Lectures

These videos come from the YUI theater, which we will be attending often. The Mozilla foundation has some really good tutorials on JavaScript, in case you want some online reading material. I also recommend you read the two recommended JavaScript books if you can afford it. You can skim over the big JavaScript book, but you are cheating yourself if you don't savor every page of "The Good Parts" (except for those strange diagrams, I don't know what Doug was thinking).

Wednesday, February 16, 2011

App Engine Datastore in Depth

Below are two talks which give more details on building good sophisticated apps using the datastore.

Above is Building Scalable Complex Apps in the App Engine

Above is Next Gen queries for the app engine.

Tuesday, February 15, 2011

HW4 Grades Out

I emailed your grades for HW4 last night. I have a couple of general comments.

  1. Use template inheritance. It is not just that I am pig-headed (I am), it is also because as we add more and more pages to the webapp you will want an easy way to change the <head> of all your pages, as well as the general layout, CSS, etc. This is trivial to do if you have one main template from which all others inherit. It is really hard to do if you have 40 different html files.
  2. Re-use your URL space. Remember that you can both GET and POST to the same url. As I explained in class, the standard way of organizing a website (following ye ole REST principles) is:
    • GET /resources: returns a list of resources
    • GET /resources/42: returns resource 42
    • POST /resources/42: creates or updates resource 42
    I will try to follow this general pattern in the webapp in the homeworks.

Monday, February 14, 2011

Datastore Code Samples

The various revisions of the code I'm using today can be found at the github. The slides are here.

Friday, February 11, 2011

HW5: Survey Question Management

In this homework you will implement the basic survey question creation, listing, answering, and summarizing capabilities. Specifically, you will extend the previous webapp to have the following features.

  1. Any logged-in user will be able to create a survey question at /survey. A question consist of the text of the question and up to five different answer choices. If the user leaves some of the choices blanks then the question will ignore these and have fewer answer choices. Only logged-in users can create questions.
  2. You will give each question its own unique url of the form /1234, for any integer number. That is, use a counter that is incremented by 1 every time a question is created. Use a transaction, as explained in class, to increment this counter. If you are feeling up to it, try implementing a counter that uses A-Za-z0-9 as the digits (this is optional).
  3. The /user/<username> page will list all the questions that username has created, along with his name. This page is viewable by anyone. If someone clicks on one of the questions he is taken to the page for that question.
  4. If a user visits the page of one of the questions he created (/1234) then he sees the question but he cannot submit the answers. Instead, next to each choice is the number of times others have submitted that choice. Also at the end of the page, the owner of the question will see a 'Delete' button. If he clicks on it the question is deleted.
  5. If either an anonymous (non-logged in) or a non-owner user visits a question page he can provide an answer. However, if he has already provided an answer he cannot give another answer and instead sees the number of submitted answers. You can use the IP number of the client to keep track of who has already submitted a question, see self.request.remote_addr.

This homework is due Monday, February 21 @11am, you can turn it in here. You do not need to upload your CSS files.

Thursday, February 10, 2011

App Engine Datastore Lecture

Next week I will be going over the datastore in a bit more detail. The video below goes into some details about the app engine and how it works. It is really good. Watch it. Here are the slides.

Wednesday, February 9, 2011

Web Design Tools and Software Shows

In case you did not take notes in class, here a few very useful links Jason mentioned:

  1. Color Scheme Designer: you will want to use this for this homework.
  2. 960 Grid: you might want to switch over to this for your layout.
  3. 5by5 TV: shows on web design and software development. The Dev Show looks cool. I'm going to check it out.

Monday, February 7, 2011

HW3 Grades Out

I have just emailed the HW3 grades. I do not have a solution for this homework and probably won't for future homeworks. If people want I can post the solution of a student who had a good, but not too good, implementation (too good sometimes makes for hard-to-read code).

Many of you should read about template inheritance, which I demoed in class, and re-write your templates using it. You want one base template and a couple of other templates which inherit from this base. It might be more work now but it will save you a lot of work as we add more and more pages to the app.

HW4: CSS and Mobile

You will now use what you have learned about web design and CSS and build two style sheets: one for the desktop and one for mobile, and incorporate these into your website. Specifically, you will:

  1. Create a style sheet for the whole website. All the pages (/, /account, /user) should use this style. Note that you will need to modify your app.yaml for the stylesheets to be downloadable.
  2. Your style should have a coherent color scheme, a logo (can be just text in a different font), distinct login bar, and, well, it should have a bit of style.
  3. Create a new dummy page, /question which lists a sample question (in the next homework you will be implementing the question-entering form). Remember that this is a multiple-choice question, with radio buttons for answering. This new page should also use the style.
  4. Create an alternate mobile style for the /question page. This style should be optimized for viewing in an iphone or android phone. If you don't have one, you can use safari to preview it, otherwise, just make your browser window really small.

This homework is due on Monday, February 14 @11am. You can upload it at i-am-done.appspot.com/242/HW4.

Required Reading

Recommended Reading

Saturday, February 5, 2011

Always Check the Homework Comments

When you visit any of the homework pages always check the comments. I will add there any further clarifications or requirements to the homework. Also, if you have a questions about the homework you can post it there. These comments are emailed instantly to me so, it is just as fast as emailing me directly, but everyone else gets to see the question.

Wednesday, February 2, 2011

A Solution to HW2

The program I discussed in class today can be found here.