Tuesday, April 26, 2011


So, we have covered a lot: from the basics of HTTP, to HTML, CSS, Python, the google app engine, the noSQL datastore, webapp framework, Django templates, JavaScript, the DOM, REST, JSON, JSONP, jQuery, Ajax, HTML5, localStorage, and canvas, among others. I think the weekly homeworks is really the only way to not just lecture you about these technologies (which is completely useless, no one learns to program by listening to a lecture and taking a test) but to actually get you to build real webapps. But, what do you think?

The form below can be filled out anonymously. You could also comment on this post so that next year's students can see them and be properly warned.

Wednesday, April 20, 2011

HW13: Facebook App: Polaroid Collage

Picasa Collage

We finish the semester with a simple facebook app, hosted on the google app engine, and using canvas. Your facebook app will be a 'canvas' app. It will fetch the user's friends' profile pictures and use a canvas to display them all in random positions, with random rotation, and with a white border around each one, like the collage shown here. Specifically you will do the following.

  1. Implement a new google app engine app which you will register as a facebook app.
  2. Your app will let the facebook user log in. Once logged in, and you have obtained permission to view his friends list, your app will fetch his friends list, then fetch the profile picture for each friend, and finally it will display these photos in one large canvas.
  3. Also, under each photo you will place that person's name.

You will turn it in on Wednesday, April 27 @11am here. Make sure you include both the URL to your facebook app (http://apps.facebook.com/yourappname) and the appspot name of your deployed app (http://yourgoogleapp.appspot.com).

Required Reading

Tuesday, April 19, 2011

Research Experiences for Undergraduates (REU) Position this Summer

I have a Summer REU project that involves writing some Python code to use the google search API (more JSON goodness) to track memes in the blogosphere. Its $3000 for the summer, 20 hours/week assumed, only undergrads can apply.

Thursday, April 14, 2011

Challenge Round

Just a couple left for tomorrow:

  • 11:15 Neelands
  • 11:30 Rowe
  • 11:45 Dillon

Wednesday, April 13, 2011

Canvas and WebGL

Checkout this post to see some awesome demos of what JavaScript and canvas WebGL (3D) can do. You will need to use a new Chrome, Firefox or Safari.

HW12: Canvas, Flickr, and JSONP

In this homework you will practice using the ever more popular canvas API. You will implement a javascript program (along with its supporting HTML file, of course) which fetches the 'interesting' photos from flickr and displays them in an art gallery view. Specifically, you will write JavaScript code to do the following:

  1. Create a request that calls the flickr.interestingess.getList method to fetch today's most interesting photos at flickr, in JSONP format. Note that this is a JSONP request, not JSON. This is a sample call. You will need to read the jQuery .ajax() documentation to see how jQuery handles JSONP requests with .ajax() in a very similar way to regular XHR requests (even thought JSONP requests are not XHR, I will explain in class).
  2. You will then make a 4x4 art gallery, similar to this art gallery example but populated with the flickr interesting photos you got. To to this, you will need to create photo source urls from the data you just got. Note that the gallery is an HTML table where each cell is a canvas object of two images: the frame image and the photo image. Use the frame image from the example. It's OK your photo does not fill up the entire frame.
  3. You will also add the 'title' of each photo just below it (either in the canvas object, or in HTML). And you will randomly draw a big red X across some photos (probability 1/2). The X's should be re-determined every time the page is loaded.

This homework is due on Wednesday, April 20 @11am. You can turn it in here. Remember to always include a URL to your published app.

Required Reading

  1. Flickr API pertinent sections.
  2. JSONP overview.

Wednesday, April 6, 2011

HW11: localStorage

For this homework you will write code that deals gracefully with the problem of a user going online/offline while editing a question text. In the current implementation of a question editing session you are doing an XHR request whenever the user clicks on the 'save' button (or, goes out of focus). But, what happens if the user is offline at that moment?

One use case you will implement is the following.

  1. The user goes to his questions at /123.
  2. He goes offline: unplugs his ethernet cable and turns off wi-fi.
  3. He goes back to his browser and edits the question at /123
  4. He shuts off the browser.
  5. He goes back online.
  6. He starts his browser and visits /123.
  7. The page should show the question as it was before he turned off the browser, including all his changes. The page will also immediately try again to do an XHR update of the new question.

You will implement this using the localStorage object. In class, I will explain more on how to achieve this effect.

Required Reading

This homework is due on Wednesday, April 13 @11am. You can turn it in here

Tuesday, April 5, 2011

Google App Engine Status

is here. Quote:
Unfortunately, an issue encountered as part of the maintenance period has caused the downtime period to last longer than expected. We currently expect read-only to complete between 6:15 and 6:30 pm PDT and will update this thread as we have a more accurate target. Thank you for your patience.

Monday, March 28, 2011

HW9 Grades and Solution

The grades are in your inbox. Below is my sample partial solution. I think a few of you were trying to make this a lot more complicated that it is. All we are doing is turning an object into a string and back, and thats done by the library.

The solution you see below is running here. Of course, you would put all your html, python, and javascript in separate files. I'm putting them in one to make it easier to understand.

"""A sample partial solution to the json homework"""        
class JasonTest(webapp.RequestHandler):
    def get(self): #/jtest will draw a chart, /jtest?fmt=json will return the json that is the data for the chart
        if self.request.get('fmt') == 'json':
            jsonObject = {'qtext': "How easy is this?", 'choices': ["Super easy", "Very easy", "Impossible"], 'votes': [5,10,20]}
            self.response.headers.add_header('Content-type', 'text/json')
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>    
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      // Load the Visualization API and the piechart package.
      google.load('visualization', '1', {'packages':['corechart']});
      //callback that generates an XHR call, when that returns we create the graph.
      function drawChart() {
          type: 'GET',
          data: {fmt: 'json'},
          dataType: 'json',
          success: function(question){ //got the json data, now make the graph
            // Create our data table.
            var data = new google.visualization.DataTable();
            data.addColumn('string', 'Choice');
            data.addColumn('number', 'Votes');
            rows = []
            for (var i=0; i < question.choices.length; i++){
               rows[i] = [question.choices[i], question.votes[i]];
            // Instantiate and draw our chart, passing in some options.
            var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
            chart.draw(data, {width: 400, height: 240, is3D: true, title: question.qtext});            

      // Set a callback to run when the Google Visualization API is loaded.


    <!--Div that will hold the pie chart-->
    <div id="chart_div"></div>

HW10: Refactoring and Memcache

For this homework you will be cleaning up the existing codebase and implementing one small new feature. The new feature is the memcaching of an question. In the use-case where a teacher posts a survey question we expect up to hundreds of hits on that question in a short amount of time. Since they are all seeing the exact same question it seems like a perfect time to use a memory cache, so you will. The parts of this homework are below:

  1. You will first clean up your web app of all the cruft it has accumulated. This includes:
    1. Eliminating all links to any specific homeworks (hw6, hw7...)
    2. Making sure there are no dead links or links that cause your app to crash.
    3. Make sure that after creating a question the user is taken to that question's page.
    4. Adding all the needed navigation links so the user can move easily move around.
    5. We can see all the questions of a user.
    6. The app is simple to use.
  2. Refactor your code. This means to clean up your code without changing its functionality. Get rid of any unnecessary code. Simplify.
  3. Implement a memcache of the unanswered questions. That is, the first GET /123 will fetch the question from the datastore but the ones after will fetch it from the memcache. Remember to clear the cache if the owner of the question changes it.

This homework is due on Wednesday, April 6 @11am. You can turn it in here

Required Reading

Thursday, March 24, 2011

Friday Challenge Round

For tomorrow's challenge round it will be:

  • 11:15 Hui
  • 11:25 Hussey
  • 11:35 Jackson
  • 11:45 Johnson
  • 11:55 Motley

Wednesday, March 23, 2011

Google Visualization API

Below is a talk that introduces the Google Visualization API, which you are using in your current homework.

Tuesday, March 22, 2011

HW8 Graded and My Partial Solution

Earlier today I emailed the grades for the last homework. Most of you did not do as well as usual. Things to get complicated once we start to try to put all these topics together into a nice app. Below is my partial solution to the homework (also here, just view-source). It's in the form of a jsfiddle so you can open it on its own window and start playing around with it to make sure you understand how its doing its magic, just press the '+' on the top right. I might be upgrading it as you provide me with bug reports.

A few tips:

  1. As mentioned in class, the .live jQuery function comes in really handy when you want to register events to elements that (dis)appear dynamically. With it, you don't have to remember to re-register events on each creation (and delete on deletion to avoid memory leaks).
  2. The .each() function is also very useful.
  3. You don't need to have ids for everything. The jQuery selectors are very powerful: use them.

Monday, March 21, 2011

HW9: JSON and Charts

In this homework you will be adding charts that show the number of answers given to each survey question choice (how many voted for which). You will be doing this by first providing the answer data in JSON format, so maybe a third-party can use that data in their own visualization, and then using that data yourself along with the google visualization API to draw your own chart. Specifically, you will implement the following extensions to your webapp.

  1. You will change your python code such that a GET /1234?fmt=json will return the text and choices of question 1234, along with the number of answers given for each choice, in JSON format. You are free to choose the specific format of your JSON object.
  2. You will use the Google visualization API to show a chart of the answers given thus far on the pages where you show the answers. That is, when either the owner or someone who has already answered question 1234 goest to /1234 they will see the question and answer choices, as before, but also a bar chart showing how many people have chosen each choice.
    1. The title of the bar chart should be the question text and the choices should be labelled with the appropriate choice text.
    2. You will get the data for this chart by first doing a ajax call back to /1234?fmt=json to get the data in JSON format. You will use this JSON data to populate the chart. The advantage of this approach is that it will easy then to embed this chart, using an iframe, in any other website. (You don't need to provide the 'embed' button, but you can if you feel up to it. I would suggest having /1234?fmt=chart return just the HTML+JS for showing the chart, then iframe that.)

This homework is due Monday, March 28 @11am. You can turn it in here. Remember to add a URL to you published webapp in the comments at the top of your file.

Required Reading

Wednesday, March 16, 2011

Challenge Round

This Friday it will be:

  • 11:15 Cormier
  • 11:25 Hoskins
  • 11:35 Greenberger
  • 11:45 Griggs
  • 11:55 Grant

Monday, March 14, 2011

HW8: Ajaxifying the Question Editor

In this homework we go back to our survey app and implement an ajaxy question editor. That is, you will replace the current question functionality, which only lets the user create a new question or delete an existing question, with new functionality that will let the user edit existing question parts, and which will do this without a full-page reload (which is sooo 10-years ago). Specifically, you will implement the following features:

  1. You should start by changing the /survey page. When the user first visits the page it should show some sample text for the question text and two sample choices. The user will be able to edit this question as follows:
    1. The text of the question will show as normal text but if the user hovers over it its background color changes (CSS:hover) . If the user clicks on it the text transforms into a textbox whose value is the current text (same effect as used in flickr, picasaweb and other photo sites to edit the title of a photo), along with a 'save' and 'cancel' button. If the user clicks on 'save' then the new text is saved.
    2. The choices bill be editable in the same way.
    3. Next to each choice there will be an 'X' (or little garbage can if you like). When the user clicks on it that choice will be deleted from the question.
    4. After the last choice there will be a '+'. If the user clicks on it then you will add a new choice field with some sample text in it.
    When he hits the 'create' button then you will generate the POST request that actually creates that question in the database, gives it a unique number, and the re-directs the user to the new question page. For example, if the new question got the number 1234 then the user is redirected to page /1234.
    Notice that this /survey page does not make any XHR calls; it is just one big POST at the end.
  2. You will then re-implement the /[0-9]+ pages. These question pages stay the same for anyone who is not the owner of the question. But, the owner of the question will now have the same editing functionality that he has in the /survey page. That is, he will be able to edit the text and add/edit/delete the choices. The be difference is that every time he makes an edit you will perform an XHR POST /1234 request to update that question on the server. Also, there is no 'create' button on this page.
    Note that, even though the user is changing each part of the question separately, it will probably be a lot easier for you to re-submit the whole question each time he changes some part of it. That way you only have to write one 'update question' method, instead of writing a 'change text', 'change choice', 'delete choices' etc. methods. I'll explain more in class.

This homework is due on Monday, March 21 @11am. You can submit it here.

Required Reading

SCGTUG Meeting Tomorrow

The South Carolina Google Technology Users Group is meeting tomorrow.

Friday, March 11, 2011

Ajax and jQuery Video

Next week we will be learning how to get things done in an Ajax-y way using jQuery on the app engine. The video below goes over an example from the author's book (which is a good, high-level introduction to using the app engine) so it might be a bit confusing at first. Basically, he is building a chat application where each client uses setTimeout to send back an XHR request every 4 seconds asking for all messages. The client then displays all (maybe some new) messages. I will be doing a different example in class.

Using Google App Engine: JavaScript, AJAX, and jQuery from Charles Severance on Vimeo.

Wednesday, March 2, 2011

jQuery Animations Run in Parallel

I said something wrong in class today (well, every day, but this time I noticed it). When you run animations in jQuery they will appear to run in parallel. For example, this code:

  $('li').click(function() {

will make the title and line items appear to disappear in parallel. You can see it action and view the source code (jquery-test.html and script2.js)

The reason the appear to run in parallel, even thought there are no threads involved, is that the way the animation are implemented are by successive callbacks from setInterval. In reality, what is happening is that the first animation moves to the next 'frame', then second one moves one frame, then back to the first and so on. Pretty cool. If you want one animation to start at the end of the other you will have to use setTimeout to tell the second one to start later.

Tuesday, March 1, 2011

Challenge Round: Second Group

The following students will meet me in my office this Friday. If you are going to be out of town just let me know so we can re-schedule.

  • 11:15 Cormier
  • 11:25 Denmark
  • 11:35 Dillon
  • 11:45 Gavel
  • 11:55 Goss

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;
     if (myNumber <= 0 ) { break;}
  this.value = 0;
 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) {
 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>
<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) {

> 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.

Monday, January 31, 2011

HW2 Grades are Out

I have just emailed everyone their grades for HW2. If you did not get it, let me know.

On Wed. I will go over a solution. I might post someone's solution here if there is enough demand from you. Please keep in mind that you have to keep with these as they will all build on each other. Even if you got it right, you should refactor your code before starting on HW3.

HTML Lecture Slides

Here are the slides I used for today's presentation, and here is the templates tutorial.

HW3: HTML and Templates

In this homework you will flesh out and organize the HTML generated by your app using templates. Specifically you will implement the following features.

  1. The app will use a base template which contains the overall layout of the site. The layout must include parts for the
    1. login-bar (that bar at the top that shows your username and lets you logout, if you are logged in, or lets you log in if you are not),
    2. the title (logo),
    3. the body,
    4. and a footer.
    You can add other sections if you want.
  2. Create a new page, /user, which provides a list of all users (their names) that have created accounts in the site. This template must use the template's for loop.
  3. Change the app to make it impossible for a user to change his name to a name that has spaces or other non-url friendly characters.
  4. Make it so the page /user/<username> takes us to a page that shows us the user's name. In a later homework, you will write code to show the user's questions in this page.

The homework is due on Monday, February 7 @11am, you can turn it in here.

Required Reading

UPDATE: See my 'comments' below.

Saturday, January 29, 2011

App Engine Help

Like any other big software library, the app engine has a large online community of users where you can post your questions about specific issues, or search the mailing list to see if someone already had the same problem you are having. Someone almost always has had and solved every problem I have had. Failing that, there is also stackoverflow.

Wednesday, January 26, 2011

Moving to your Own Domain

I did not mention in class that once you deploy your app in the appengine you can easily buy your own domain name and have it point to your app. If you have already taken our computer networks class then you would already know this since you know all about DNS (the Domain Name System which maps domain names like www.sc.edu to IP numbers, which are fixed).

Anyway, there are already many business running on the app engine. This list has a few case studies, which are already about a year old.

No Friday Lectures

There will be no lecture this or any subsequent Friday, unless otherwise noted. Instead, I will be in my office ready to answer all questions you might have about the imminent homework, on top of my regular office hours. We will start the Friday challenge rounds soon.

Also, here is the code from today's class.

Tuesday, January 25, 2011

From Database Rows to Objects: The db.Model

On Wednesday I will be introducing the app engine datastore. You use the datastore via the db.Model. This Model is an implementation of an Object Relational Mapping (ORM) which is code that maps a database table to a Class in an object-oriented language. Most modern webapp frameworks implement an ORM: Rails uses ActiveRecord, Java Servlets use Hibernate, Django uses Models, etc., and they all operate in very similar ways.

Below is a video describing the design of the Google datastore and how to use it. The resolution is rather low so I recommend you follow by reading the slides from the talk.

Monday, January 24, 2011

Configuring Eclipse for the App Engine

Checkout this step by step tutorial on installing app engine support on eclipse, after you install the app engine. Note that you have to install PyDev. The "Installing Pydev for Eclipse" section works for win/mac/linux. The "starting your first project" section will be different on a mac/linux.

On the mac, when you try to create a new "Pydev google app engine project" it will ask you for the google_appengine directory. This directory is buried under GoogleAppEngineLauncher.app so eclipse can't see it. What I ended up doing was going to the terminal and typing (this creates a symbolic link on the filesystem) :

ln -s /Users/jmvidal/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine google_appengine
then telling eclipse that the app engine directory is at /Users/jmvidal/google_appengine.

Finally, while you are installing eclipse plugins, you will also want to install the eclipse web tools platform (WTP) which you can do via Help->install new software and then using this repository (it might already be under your "Available Software Sites" link, depending on which version of Eclipse you installed). WTP provides eclipse with fancy editors for HTML, CSS, and JavaScript, which you will need in a couple of weeks.

myPoll webapp: A Roadmap

Most of the homeworks in this class are small steps that will result in the development of a web app for online polling and quizes. I got the idea for this app from an article I read about the iClicker device. The iclickers are handheld remotes that are handed out to students in a large lecture so the teacher can quickly poll the whole class and see a nice bar chart of the result. That is, they function just like the "ask the audience" lifeline in Who wants to be a millionaire?

Since most students have, or will soon have, a web browser with them at all times (iphone, ipad, android, netbook, etc.), we can do the same thing the iclicker does, and more, with just a little bit of software. Software that you will be writing. Below are the basic use cases I am thinking about.

Class Poll

A user logs in to the webapp and creates a multiple-choice question. The question is saved and the user gets (or asks for) a simple url. During class he gives this url to the students. The students visit it and see the question, answer it, and then see a pretty bar chart summarizing the answers. The teacher also sees the bar chart (which he might be projecting on the front of the classroom) as it gets updated with incoming answers. Note that the student did not need to log in to provide an answer. We prevent someone from answering many times by remembering their IP address (or, using a cookie?). The teacher has a nice ajaxy gui for editing his questions, he can delete options, re-order the options with drag-an-drop, inline-edit the existing options, etc.

Class Quiz

A quiz is also a multiple choice question but it has a correct answer, which the teacher tells our webapp. When a user enters his answer he is told what the correct answer is. Only someone who is logged in can see and answer a quiz question. The teacher can see a chart of all the answers as well as a table listing everyone's answer. Only the teacher can see this table.

Class Test

A test is a collection of quiz questions (with added free-form answers?). The web app will use the new html5 javascript calls so the whole test is downloaded to the user's browser and he can see it and answer questions even when offline. When the student hits submit then all answers are posted to the website.

Mobile Version

Many of the people answering the questions will be using small-screen devices. We must, therefore, provide them with a mobile-optimized version of the website.

Poll your Friends

Our user wants to do a quick poll of his friends, say, ask them about the airspeed velocity of an unladen swallow. He creates a poll question then this question is automatically posted to his facebook wall, twitter, emailed to his friends etc. The user has to first set up which services/friends he wants to poll. Future work could include multiple multicast lists (social circles).

Facebook App

Make it into yet another facebook polling app.

Other ideas...

That's all I could think of. Please feel free to provide your own ideas in the comments. This roadmap is not set in stone so, many of the details might change, perhaps in response to your input.

Friday, January 21, 2011

HW2: User Management

We now start building our webapp. The one thing that nearly all webapps need is user management. Luckily, the app engine provides us with some very nice functionality in the form of the Users API which you will use for this project. Remember that you will be building on this code throughout the semester so, keep it clean.

Your code will implement the following features:

  1. A simple homepage, at /, that welcomes a visitor and lets him log in with google (or openid) account.
  2. When a logged-in visitor goes to / he should, instead, see his email address and a 'logout' link which lets him log out, as well as an "account" link.
  3. When the user clicks on the "account" link he is taken to a page that shows his name in a textbox. The name is initially set to the part of his email before the @. From that page the user can edit his name. That is, he can change the name in the textbox and hit a "save" button (or Enter) which will change his name. You will need to use the datastore for this.
  4. Make sure that if the user logs out and logs back in again that his nickname is still the one he changed to.
  5. Make sure that a user can change only his name, and not the name of others. Users expect that much control over their names.

Required Reading

Turning it In

You will upload all your code files to http://i-am-done.appspot.com/242/HW2 by Monday, January 31 @11am. You will also publish your webapp to appspot.com. At the top of your main code file include a comment with your name and the full URL of your deployed app.

HW1 Graded

By now, you should have received an email with your grade for the first homework. If you didn't then email me. Now, it's Python time: always look on the bright side of life.

App Engine: Getting Started

On Monday I will be showing you how to write a simple app engine app. All the documentation for the app engine can be found here. Go there and browse around.

You will also want to get going and download and install the Google app engine SDK. You might also want to download the eclipse plugin, which I use for my own development (and you will see me using in class). In lecture I will be following the getting started tutorials.

Below is the short intro video that Google provides, to get you started.

And, this is a good video of a talk by Guido van Rossum on the App Engine. It gives a bigger picture of what it does and how it works. He gives a nice overview of all the APIs the app engine provides. We will be going over these in more detail later on in class, as we learn to use them.

Wednesday, January 19, 2011

Learning Python Videos

On Friday I will be going over Python basics in class. I highly recommend that you dig deeper by reading the recommended Python book and watching the Google's Python class videos. The first one of which is embedded below. The first 3 videos (day 1, parts 1,2,3) cover most of what you will need. Note that since the app engine does not let us read/write files you can skip that part.

You will need to install the google app engine eclipse plugin which (if I remember correctly) will also install the pydev plugin for eclipse automatically. You might also need to install python itself, if you don't already have it.

Monday, January 17, 2011

A Short History of the Web

Below is presentation I used the first day in class. There is more stuff I would like to put in there but, I don't know how to organize it so it makes sense.

Sunday, January 16, 2011

Facebook Will be Replaced by a Protocol

Friday we talked about how everyone used to be online, at AOL, until Tim created the web kept the protocols open and the whole world followed. That is, AOL was replaced by HTTP. The same thing happened a decade earlier when email was a product, sold by different vendors, each one incompatible with the others (that is, you could not send email from one to the others). Then, slowly but surely, all those companies disappeared as everyone moved to SMTP.

Right now, Facebook is in the same position AOL was 20 years ago. It has a closed system and tons of users. Inevitably, people will grow tired of the lock-in and a social-network protocol will take over (maybe, opensocial? I don't know, it seems over-complicated to me). After that, you will be able to "friend" or "follow" anyone in the Internet, regardless of which social app they use, just like you can email anyone regardless of which mail reader they use.

And, that, is just my opinion. Dvorak has similar complaints, but he is just another old curmudgeon, like me. Tim Berners-Lee is very concerned, and rightly so, that we should prefer open standards over giving all our data to one company who does not let others access it. What do you think?

Friday, January 14, 2011

Are There Jobs in Web Applications Development?

Yes, but, Why? I think because:

  1. Many of the fastest-growing technology companies (facebook, twitter, google, salesforce, and tons of other small companies) are web application companies.
  2. Old technology companies like Microsoft, IBM, SAP, and Oracle are "moving to the cloud", which means they are moving many of their applications from the desktop to the web.
  3. Many other regular companies (banks, insurance companies, etc.) are converting their old desktop-based (Visual Basic) software to web applications because of demand from their clients and employees. Others are keeping the old apps but making all the new apps as web apps.
  4. The iphone and android devices are largely used as communication devices (yelp, facebook app, evernote, etc.) that talk to a web application. Well, that, and as really expensive and really annoying to use Nintendo DSs.

One data point is stackoverflow's recent survey which showed that 40% of stackoverflow users describe themselves as Web Application Developer (question 7). That is a huge number. I think its a bit inflated due to self-selection bias (web app developers are more likely to read the blog).

HW1: HTTP and Firebug

The goal of this homework is to show that you understand how HTTP works and how to use firebug/chrome/etc. to see and understand everything that is happening as a web page loads.

First, install firebug in or browser, or use chrome. Then use it to answer the following questions:

  1. What server is used by www.sc.edu?
  2. How many GET calls are required to show that one page?
  3. Are they using jquery? google analytics? list all the 3rd-party libraries they use.
  4. How many cookies are being used? what are their keys?
  5. What us the full path name of the facebook image (the little F) that appears at the bottom of the page?

You will turn in this homework by writing all your answers in a text file. When you are done upload it to i-am-done.appspot.com/242/HW1. This homework is due on Friday January 21 @ 11am. Please note that simply doing the homework is not enough to learn everything you need to know. You will also need to do the required reading (below) and play with firebug to make sure you understand what it is doing.

Required Reading

Recommended Reading

  • You can view this rather long but interesting interview with Tim Berners-Lee about his life and the early days of the web.
  • Read URL Design: a short post on how to design your URL space. You will need to know about URL design when we start building our web app in a couple of weeks.

Wednesday, January 12, 2011

Recommended Reading

Below is a set of books that cover the topics we will be covering in this class. I have read these and like them, especially Javascript: The Good Parts. You should either have a copy of each one or a similar book/website you plan to use as reference.

While programming, I like to use gotapi.com as a reference.