Wednesday, December 12, 2012

Final Grades and Analysis

I emailed the final grades yesterday. I'm excited that more than half the class received A's. They managed to build a sophisticated webapp, and in the process learn the basics of:

HTML, CSS, app engine API (Datastore, webapp, Jinja, BlobStore, URL Fetch, Image), Python, JavaScript, jQuery, DOM, AJAX, canvas, etc, etc.

The main challenge in teaching this class is that it is simply impossible to cover all the details of all the technologies involved in lecture: 1000 hours of lecture would not be enough. Thus, all I can do is provide an overview of how the new technologies work and then give the students a weekly homework that uses those technologies. Once they hit a wall trying to use the technology they can come back to me with their problem.

One-on-One Friday Classes

Of course, many times the problem they have has nothing to do with the technology at hand. For example, a homework on using the Datastore might not work because the student does not know that None != "" in Python (or, any one a million other bits of knowledge).

This is partly why I set up Friday classes to be an exclusive one-on-one session between the students and me, where they can ask me any questions about the project and I will debug it for them. I was also always available via email, IM, and SMS, and several students took advantage of this opportunity.

Attendance to the Friday one-on-one sessions was very low, around 25%, usually the same few students. The no-shows included some that did well in the class, and some that did not. Some od the no-shows were actually very active via email/IM/SMS, which is probably a better way to get help (except that I go to sleep and wake up much earlier than most students).

So, I think Friday classes worked out OK, but next time I will be taking attendance. Sometimes, you gotta cajole people into doing what is good for them.


This was also the first time I required the use of git+github. The students had to push their weekly homeworks to github so I could grade them.

I was a bit worried that they would get lost with the complexities of eclipse+egit+github, but after having a lecture and making a video on it, and helping them get it all installed it worked out very well. I used the simplest possible workflow: just commit to master and push to github when done. That is, all they had to understand was Team->Commit and Team->Push.

Still, there were a couple of students who had problems with their repos up until the end. I think because they were (accidentally?) using git commands they did not understand.

Also, most of the students were still just making one big commit just before turning in the weekly homework, even after constant reminders in class that they should be committing after each bit of functionality is implemented. But, I expected this. The same thing happens when I force students to use source control in 492.

Github really shined in helping me provide email/IM help to the students. Many times a student would email me saying that their program did not work. I could then just tell them to push it to github where I could see it all and figure out what was wrong. If needed, I could pull it and run it on my laptop. This is especially useful because most programmers at this stage suffer from what I call premature certainty, where they are sure the bug is in part X of the code, and will email you just that part of the code because that is where the bug is, when in reality the bug is in some other part of the program.

Project Complexity

The previous time I taught this class nearly all the students complained that it required too much programming. This time, I asked the students to do even more programming than last time. This is not because I enjoy their pain (I do) but simply because the contents of this class are guided by real-world demands, not students' desire for an easy A. Still, students did better. I think this is due mostly to self-selection. Last time there were still a few students that thought that building a webapp was just 'some HTML stuff'. Most students now know that building a webapp requires lots of programming (I think, because of that facebook movie) so most were ready to put in the time.

The amount of knowledge required to build modern webapps grows every year. Some things get easier to do, but this just results in a raising of the bar so more sophisticated webapps become the norm. This year I decided not to require the students to use backbone.js, or some other MVC framework, or to create persistent connections to the server, or use Memcache, or SASS, or build a responsive website, etc. But I will probably include some of those technologies next time simply because they will be the norm in webapp development by then. I am also hoping to use node.js instead of the appengine, if someone makes it easy to deploy and manage node.js applications. Can't wait!

Wednesday, December 5, 2012

Your GitHub Repo is Yours Forever

The friendly people at github like what you have been doing. So, they offered to let you keep your github repo for this class as long as you like. That is, I will not be deleting these repos at the end of the semester and they will persist indefinitely.

Of course, I recommend that you make it public at some point so you can use it as part of your resume. You can make the repo public in the 'Admin' tab.

Tuesday, December 4, 2012

Webapp Project

I talked a bit about the following opportunity in class earlier in the Semester:
This project will be to build a website and service for students, professors and other scholars. A significant problem in some parts of academia is that important announcements are made via a variety of electronic media platforms and are rarely machine-sortable by keyword or announcement type. One announcement might come out over a list serve and be a job announcement (here’s an example), while another is a Call For Papers over an RSS feed (here’s a HASTAC announcement – they use RSS), while a third could be the table of contents of a new book, sent to the emails of particular people. In this project, students will build a website which will aggregate announcements from across the disciplines of History and English from numerous social media platforms. Users should be able to select specific criteria of announcements they want to receive, for instance job announcements, Calls For Papers, etc., or announcements with certain key words in them. The website should process the language in the pool of all announcements it has collected for keywords specified by users. Ideally, the website would itself offer users multiple possibilities for receiving this information – over Twitter, Facebook, an RSS feed, email, in digest form, etc. I envision that the user basis for this would begin small – say about 10-20 users in the first month, but could grow quite rapidly to many thousands or more within 6 months. There is a golden opportunity here to provide a far better means of information-distribution than currently exist.

Student on the project would work in collaboration with Dr. Colin Wilder and staff at the Center for Digital Humanities at USC. If the project turns out well, students might be able to continue working at CDH in the summer or fall 2013 as well on other projects.

There is no funding for this project, but you could do it as a 498 class this Spring (we could even count it as a 500-level elective for your degree) with me as the faculty advisor. It would look great on your resume, much better and an easy class, and it could lead to further employment (ask Mike Helms about that).

Email me if you are interested.

Sunday, December 2, 2012

PubSub on Wednesday

On Wednesday, for our last lecture of the semester, we will have another guest lecturer. Jonathan Mayhak will be talking about messaging queues. Specifically, using the pubsub design pattern to decouple metric tracking code on the web server from the database.

See you then!

Friday, November 30, 2012

Thursday, November 29, 2012

Backbone on Monday

Brad's talk about Backbone.js which was supposed to be last Monday, will now be this next Monday in class. So, be there! or be....boneless?

Wednesday, November 28, 2012

Final Grades

I will be dropping the lowest grade from your homeworks, before calculating your final grade. More than half the class already has an average higher than 90 so, math tells us, they can not do anything for the last homework and still get an A.

Regardless, I hope all of you put some effort into this last homework. You should make your app your own: distinct from all the other pinboards. Then you can put it in your own public github repo and it will become part of your online resume, because more and more nowadays github is your resume (HN discussion, resume generator).

Sunday, November 25, 2012

HW12: The Last One

For this homework you will finish up your pinboard project in any way you want, as long as the work involved is roughly the same (or more, if you want) as the other weekly projects. There is a lot left to learn about building webapps, more than we can cover in this class, so pick one thing that you are interested in.

Here are some possibilities:

  1. Let the users save their pins, or boards, to their google drive, dropbox, evernote, skydrive, etc. Pick a service that you like, read their API, and integrate into your pinboard. The integration could be as simple as saving the pin and its caption.
  2. Expand on our current canvas board by letting the user draw on it, or put frames (which you provide) around selected pictures, or write text messages in the canvas.
  3. Allow people to comment on pins.
  4. Re-write your JavaScript code using backbone.js, or some other JavaScript MVC framework.

Or, something else? email me your idea. As long as it is roughly the same amount of work, I will approve it.

This homework is due Friday, December 7 @9am.

Make sure you explain all your new features in your README.

Wednesday, November 14, 2012

Invited Talks

I have arranged for a few speakers to come and talk to us about some topics relevant to webapp development. Note that attendance to these lectures is mandatory. I am also making them open to the public so if you know of someone who is interested, invite them along.


On Monday, November 26, Brad Dunbar will talk about Backbone.js.

Brad is an alumnus of our department. He is a front-end engineer. He currently works at Pathable Inc. writing javascript (and coffeescript) and I does a lot of open source work for Backbone and Underscore.

Building rich, model-centric, event-driven web apps using EF, Razor & open source

On Wednesday, November 28. Jamie Thomas

In this interactive walk-through, we will create a custom application from scratch using proven Microsoft tools and technologies and a healthy dose of new approaches to software development. This session will demonstrate how easy it can be to create rich single page applications and robust client experiences while still leveraging .NET languages and tools to define the bulk of the business logic and processes (not just a tangled mess of JavaScript). While this will be a high-level demonstration, it still show how to handle hard-core problems like symmetric client and server-side template rendering, complex custom validation and event-driven model manipulation using both client and server-side rules. Though the problems solved will be hard, the solutions demonstrated will be both elegant and easy to understand.

Jamie Thomas is the Director of Software Development at VC3, an IT and software services company, headquartered here in downtown Columbia, in the IT-ology building.

Building Chrome Extensions

On Friday, November 30. Jarrell Waggoner, will show us how to build an extension for the Chrome browser.

Jarrell Waggoner is a PhD student in our department. He implemented the nonpartisan me which received some attention.

Sunday, November 11, 2012

HW11: Resizing Images in Canvas

For this homework you will write code to allow users to change the size of their pins in the canvas view of the board, as well as position (which you did before). The new widths and heights in the canvas are stored in the server the moment the user unclicks (mouseup) the pin. The GUI consists of circles on the three corners of the pin which the user can use to re-size the pin, as demonstrated in the video:

There are also a few more requirements:
  1. You must implement a Vector class with add and subtract operations. I want you to practice using JavaScript inheritance. Also, being able to add and subtract vectors will make your code much much simple. Specifically, when a user clicks and moves inside a pin, I want you to move the pin as thought the user grabbed it at that point. You cannot move the top-left of the pin to where the user clicked, as we did in the previous homework. This is all much easier to do if you think/code with vectors. I'll explain more in class.
  2. You cannot use any third-party libraries. There are many libraries out there that do this, and more. You cannot use them, or anything else besides jQuery.

As always, when you are done push your code to your public github repo, by Monday, 26 November @9am: the Monday after Thanksgiving.

Friday, November 9, 2012

JavaScript Programming Job

I wrote this interactive quiz webapp some time ago and now they want me to add some features to it. First thing, add a keypad to it so it can be used from an iPad (without having to pull up its virtual keyboard).

They cannot pay for now, so you would be doing it just for the experience (or, for class credit, we can talk about that). But, they are applying for grant support so you might get paid to work on it in the future.

So, let me know if you are interested.

Sunday, November 4, 2012

HW10: URL Fetch, Blobs, and Images APIs

So far in your app the images added to the pins have remained at the original host. All you have been doing is adding img tags whose src attribute points to the original image. For this homework you will change your webapp so that it downloads the images from the host server to your server, stores them as blobs in your database, calculates their original width and height, and then serves these images from your server.

That is, GET /pin/123.jpg now returns the actual image (a jpeg file, you can assume that all images added are jpegs for this homework) of the pin 123. You would have added that image to your datastore when the user initially did a POST /pin to add the pin.

Also, you must store in your datastore the width and height (in pixels) of the original image. You will be using these numbers in the next homework.

Required Reading

In order to do this you will need to use a couple of new service from the app engine:

The URL Fetch API allows your python code (server) to issue GET requests to other servers. This is what you will use to fetch the images from the other servers.

Once you have the image you can simply use the BlobProperty type to store it in your database. This article on Serving Dynamic Images gives you step by step instructions on how to store and then serve images in the app engine.

Finally, you need to store the width and height of the image. In order to determine those number you will need to use the Images API. These are a set of python calls that let you get information about and manipulate images.

As usual, push it to your github repo by Monday, November 12 @9am.

Tuesday, October 23, 2012


The grades for HW8 where not up to par. I know you can do this, and since the next homework really depends on getting this one right, I'm changing the schedule.

For this Monday your homework will be HW8, again. This time, make sure to get a 100.

Note that your grade for HW8 "A New Beginning" will still remain, you will just get a second grade for HW8 "The Final Try". HW9 is now postponed 1 week. We will thus have 12 homeworks in in the class instead of the original 13.

Sunday, October 21, 2012


The canvas element is a simple 2D grid where you can draw things. It is the way your JavaScript code can draw arbitrary pixels on the page, and the way to make animations.

HW9: Canvas

In this homework you will convert your boards into something that behaves more like a real-world pinboard. You will do this by using the canvas element.

Specifically, the new url /canvas/123 will correspond to the same board as /board/123 but the board will be shown in a canvas object of 854x480 pixels. The images will all be scaled to 200x200 pixels (in the browser, and for now, we will fix this in upcoming homeworks). The owner of the board will be able to move the images around by just clicking on one and moving it around. When the user moves the mouseup, the image will stay, there.

That is, your board entity will now need to store the x,y coordinate of each pin. These values are to be dynamically sent, via XHR requests, back to the server as the owner of the board moves the images on the board, as I demonstrate in the video below:

Note that you cannot use any third-party libraries for this homework, except jQuery. I know there are libraries out there that do canvas drag-an-drop, but you will learn more by doing this yourself.

Also notice that one pin can be in multiple boards.

Required Reading

The new topic for this week is canvas, you will want to read the canvas tutorial and the Using images tutorial that explains how to use the drawImage primitive, which is what you will need to use to draw the photos.

As always, publish your final code to appspot, and push it to your private github repo by Monday, November 5 @9am.

Monday, October 15, 2012

JSON and jQuery XHR Requests

The following video shows how to get JSON replies from jQuery XHR requests.

Sunday, October 14, 2012

HW8: JSON & Dynamic Board Editing

For this homework you will add a responsive user interface to your boards and you will provide both your pin and board data in json format.

Lets start with the server side. You will have the following methods (the json methods are new):

GET /when logged-in, shows links to "My Pins" (/pin) and "My Boards" (/board)
GET /pinlists all the users' pins and links us to each one, as before. Also, this page should let the user add a new pin.
GET /pin?fmt=jsonreturns a json representation of all the pins this user own.
POST /pincreates a new pin, as before
GET /pin/123shows pin 123, and a form for editing it, as before.
GET /pin/123.json
GET /pin/123?fmt=json
returns pin 123 in json format.
POST /pin/123updates pin 123 (caption or url), or deletes it, as before.
GET /boardlists all my boards. If not logged in re-direct to /, and do similarly for all the other URLs. Also, this page should let the user add a new board.
POST /boardCreates a new board and then redirects the user to it.
GET /board/123If my board then list all the pins in the board and a form for editing it. If not mine but public then list the pins in the board. If not mine and private then re-direct to /
GET /board/123.json
GET /board/123?fmt=json
If my board then return the board in json format
POST /board/123Update board 123's information. The possible changes are: new title, add pin, delete pin, mark as private/public, delete board. Then redirect the user back to GET /board/123

On the client side you will implement a board editor that works as shown in the video below. Basically, each pin not in the board is shown with an 'add' button. When the user clicks on it the pin is added to the board. Note that the adding of the pin to the board has to happen in the client. That is, all the adding and removing must be done without reloading the page, ever. It is all done via XHR requests.

The way you will implement the board is by delivering to the client an empty board (no pins) with some javascript that immediately does a GET back to the board to get the board and its pins in json format, and another one to get all of the user's pins, in json format. Your javascript code then puts all these pins in the appropriate places in the page. After that it sets up the appropriate event handlers so that when the user clicks 'add' or 'remove' the pins are first moved in the page (javascript) and then an XHR request is sent to the server to tell it about the change.

Finally, you must handle server errors by undoing the last change. That is, if the user adds a pin, the pin immediately moves, but if the XHR requests fails (error:) then your code will move the pin back and display a message to the user about it. You can easily test this by changing your POSTs to return 500.

Required Reading

The main new thing is JSON, which is just the JavaScript object literal notation. But, since you will also be using it Python, you will want to use the Python json library.

Make sure you publish to appspot and push to github by the deadline of Monday, October 22 @9am

Thursday, October 11, 2012

Webdev Jobs at the CDH

USC's Center for Digital Humanities needs a couple of students to do some web development, see their ad.

Mike Helms did a directed study with me,where he helped me migrate our department's website to Drupal 7, before going to work at the CDH.

Monday, October 8, 2012

Y U No stopPropagation()?

I figured out why my code in class was not working: My HTML was illegal. It turns out we cannot have a div inside a p element (one block element inside another one). Illegal HTML makes it impossible to setup event handlers properly. Lesson learned. Anyway, it is now fixed in the lecture repo.

Sunday, October 7, 2012


In the next homework you will redo some of your existing forms to use Ajax instead of the POST-reload loop. That is, you are going web 2.0. The video below explains how to make Ajax requests with jQuery.

Friday, October 5, 2012

HW7: Ajax

In this homework you will change the /pin edit form to use XHR requests to submit changes to the caption and the private back to the server. We are also eliminating the possibility of changing the URL (I figured, it makes more sense to the user to just delete the pin).

The video below show how this will look like in your app.

Also, when a non-owner of a public pin (say, 5) goest to /pin/5 he will be able to see the pin (as he can now) but will not get the editing javascript code. Also, he should not be able to edit the pin.

Required Reading

  1. The jQuery ajax documentation is where you want to look for all things ajax.
  2. You also want to read the jQuery events documentation. Specifically, make sure you read the jQuery on() documentation page, all of it.

Thursday, October 4, 2012

JavaScript Closures and Private Properties

Closures are lots of fun and often very useful. The video below explains why and shows how we can use them to simulate Java's private properties.

Monday, October 1, 2012

JavaScript Events and EventHandlers

In the video below I describe how to build and use JavaScript event handlers, using jQuery.

Sunday, September 30, 2012

Building a Bookmarklet

The video below shows how to build a bookmarklet.

Note: The code in the video does not set the host properly. Use the code below for your bookmarklet:

JavaScript DOM Manipulation

For the next homework you will be writing JavaScript that modifies the DOM (by getting images out then replacing the current page with a whole new page). The video below talks about the JavaScript methods that modify the DOM.

Thursday, September 27, 2012


The webapp you are building follows (mostly, I took some liberties) a REST architecture.

Most modern webapps follow a REST-ful style, so, when you design your own webapp you should keep these principles in mind. I think that after you are done building our Pinboard app you will realize how this architecture saved you a lot of coding and confusion. In the video below I explain what REST is and how your Homework app implements REST principles.

JavaScript: Inheritance

And now, to the wonderful world of Prototype inheritance:

Wednesday, September 26, 2012

HW6: Bookmarklet

People will never use our Pinboard if they have to manuall cut-n-paste the URL for every image they want to add. What we need is a painless way for them to enter images from whatever page they are browsing directly into our Pinboard. Thus, we need a bookmarklet, or a browser extension (which are basically just bookmarklets with some extra browser-specific files added).

This week you will implement a bookmarklet that lets the user painlessly add img URLs to his pinboard. Specifically, you will:
  1. Add the bookmarklet to the / page, for logged-in users only.
  2. When the user clicks on your bookmarklet, your JavaScript code will erase the current page and show only the imgs in that page.
  3. Each image will be surrounded by a form that lets the user add a caption and then submit that image back to your server (the user can only submit one image)
  4. After submitting the user is re-directed to the page showing his new pin.

Required Reading

This is our first JavaScript homework. You will need to know quite a bit of JavaScript to do this. My videos cover the specific topics you need to know. But you should also use: When done, push your homework to your private github repo, and publish on with Version: 6, by Monday, October 8 @9am. Note: My solution to this homework does not use jQuery (or any other library) and I recommend that neither should yours. If you do, you will be downloading a second script file whenever the user clicks on the bookmarklet (so, making the button a bit slower), and it is a good learning experience to write a bit of JavaScript using only the built-in DOM manipulators.

Tuesday, September 25, 2012

JavaScript: Variables and Functions

OK, we are now ready to start having fun with JavaScript. First, variables:

and then, functions:

Monday, September 24, 2012

Python, Indentation, and Eclipse

I'm noticing that many of you are not being careful about consistent indentation. In Python, indentation is code. So, while the program might work if the then-part of an if-else is over-indented, this will cause problems later on when you add more code.

Also, don't use tabs! You can tell eclipse to only use spaces (instead of tabs) by going to Preferences, as shown in the images.

Sunday, September 23, 2012

The Big Picture

By now you are all getting a good idea of what the big picture of webapp development looks like: that is all a bunch of GETs and POSTs, each of which you have to write an eventHandler for, or dispatch from a static file.

I thought I would summarize it in this video (I also talk about Ajax calls, which you will be doing in a couple of weeks).

Saturday, September 22, 2012

Many-to-Many Relationships

In the video below I show one way to setup a many-to-many relationship in the datastore: between Posts and Tags.

Friday, September 21, 2012

HW5: Boards

In this homework you will extend upon the previous database model by adding a Board. Basically, a user can create any number boards. Each board has a title, which the user can set. The user can add any number of his pins to any one of his boards (a pin can be in more than one board).

The user will also be able edit his board after creating it. He is able to edit the title, add and delete pins, and set it to private or not. If a board or pin is marked 'private' then only its owner can see it, if it is not marked private then everyone can see it (but still, only the owner can edit it).

A non-owner of a board can still see it, but cannot see the edit controls, nor can he edit it via direct POSTs (security).

The screenshots here provide a guide as to how your app will look like.

GET /when logged-in, shows links to "My Pins" (/pin) and "My Boards" (/board)
GET /pinlists all the users' pins and links us to each one, as before. Also, this page should let the user add a new pin.
POST /pincreates a new pin, as before
GET /pin/123shows pin 123, and a form for editing it, as before.
POST /pin/123updates pin 123 (caption or url), or deletes it, as before.
GET /boardlists all my boards. If not logged in re-direct to /, and do similarly for all the other URLs. Also, this page should let the user add a new board.
POST /boardCreates a new board and then redirects the user to it.
GET /board/123If my board then list all the pins in the board and a form for editing it. If not mine but public then list the pins in the board. If not mine and private then re-direct to /
POST /board/123Update board 123's information. The possible changes are: new title, add pin, delete pin, mark as private/public, delete board. Then redirect the user back to GET /board/123

Required Reading

This homework makes more use of the datastore, so you will need to continue using the datastore documenation

For storing the list of pins in a board I suggest you use the ListProperty on a Board. However, you can also use a mapping table, as is often done when one wants to implement a many-to-many relationship in a database (for those of you who have taken 520). In any case, you will need to be careful that when a pin is deleted from a board that the pin is no longer listed as belonging to that board.

As I will explain in class, these type of data-consistency checks are best implemented as methods to your Model class.

Push your final changes to your private github repo and publish your app to by Monday, October 1 @9am.

Wednesday, September 19, 2012

Organizing Request Handlers

Below I give an example of how you might organize your Python code

Monday, September 17, 2012

Solutions and Lecture Code

I have just pushed my solutions to HW3. I also setup a repo with the code I write in the lecture, which I'll be updating after each lecture.

Saturday, September 15, 2012

Datastore Queries

The datastore supports a fairly complex query language (but, not as complex as full SQL). The two most often used operators are filter and order.

Datastore Keys

Every item (entity) in the datastore can be referenced by its Key, which works the same way as a key in a hash table (an index in an array). The keys can be generated from an item's ID and its entity type. I explain below:

The Datastore

Google app engine uses the datastore, which works a lot like a regular database (SQL) but is actually implemented as a gigantic distributed hash table, and is supposed to automatically scale to as many machine as you can pay for.

The video below give a quick introduction.

Tuesday, September 11, 2012

HW4: The Datastore

In this homework you will start using the datastore to store the pins that each user adds to his account and later displaying them. Note that you will not be storing the images themselves (the *.png or *.jpg). You will only be storing the URL to the image.

First, create a directory called /pic in your project and add a few of your favorite jpegs from the net. You will use these when debugging your app. They will save you time as your browser will not have to keep fetching images from the net (and, you can code offline).

You will then create a Pin(db.Model) with imgUrl, caption, date, and owner properties. That is, each Pin will have a URL, a caption, a date of creation, and an owner associated with it. Each pin will also have a unique id, but you can just use the built-in key. That is, the Pin's id will be given by self.key().id().

The way your app will work is as follows:
  1. As before, on 'GET *' if the user is not logged in he is shown the login page. If he is logged in then 'GET /' returns a form asking him for the img URL and caption. You do not need to check if it is a valid URL.
  2. When the user hits 'submit' on the form (for adding a image) you will generate a 'POST /pin/' that sends the information of the new pin to the server. Your server code will store this new pin information in the datastore and then forward the user (self.redirect()) to the new pin's page: /pin/1234 (or, whatever number you have the pin).
  3. '/pin/1234' will show pin 1234. It will also show the URL and caption values in text boxes, allowing the user to change this. If the user changes them and clicks on the 'update Pin info' button you will generate a 'POST /pin/1234' with the new information and update the info on the server accordingly, then come back to 'GET /pin/1234' which will then be updated.
  4. The '/pin/1234' will also have a 'delete this pin' button which does as it says.
  5. A 'GET /pin/' will return a page with thumbnails of all the pins owned by the user, each one linked to its pin page. In the header of all pages it will say 'My Pins' which is just a link to '/pin'.

What we are going for here is a fairly standard REST API for getting and editing your pins.

To summarize:

GET /when logged-in, shows a form for adding a pin
GET /pinlists all the users' pins and links us to each one.
POST /pincreates a new pin
GET /pin/123shows pin 123, and a form for editing it
POST /pin/123updates pin 123 (caption or url), or deletes it

Required Reading

  • You will need to read the Datastore example and consult the Datastore API for all the details of its operation (you only need to know the basics for this homework).
  • You will be using the users API to let users log in and determining if the person is logged-in or not. Almost everything you need from 'users' is covered in this Using Users Service example.


As always, push it your github repo by Monday, September 24 @9am

A Note on Proper Googling

You will have notice that whenever you search for a web-related term like 'css font-family' your first results are always at Now, I have nothing against that website but they are kinda sucky.

What I do is prepend every search with 'mdn', as in 'mdn css font-family'. That way I end up at the much nicer Mozilla Developer Network.

Monday, September 10, 2012

Static CSS Files in the App Engine

If you link to a CSS with, say href="/css/style.css" then the browser is going to do a GET /css/style.css. But, since you are running the app engine this means that, by default, this will go to your Python file where it will look to see if there is a handler defined for /css/style.css.

Since our CSS files are static we don't want the python code to be called to fetch them. We just want the webapp2 to serve these as old-fashioned static files. To do this you need to edit your app.yaml and tell it which files or directories you want to be static. Read the docs on Static File and Directory handlers for the details. Basically, you add something like:
- url: /css
  static_dir: css

to your app.yaml file.

My Solutions

I have pushed my solutions to HW2 to the pinboard github repo so you can take a look at how I did it. I added a link to this repo on the menu at the right. I will be pushing all future solutions to that repo.

Sunday, September 9, 2012

CSS Examples

At first, it is hard to imagine that significant visual effects can be achieved by using the CSS properties. But, that is only due to lack of imagination. The sites below showcase the power of CSS. Browse them for ideas, and CSS code.

  • CSS Zen Garden is the original CSS showcase site. Every time you click on a design on the right you will see a different design. But, note that all designs use the same HTML. The only thing that changes is the CSS file.
  • CSS Deck is a new site for showing off cool CSS tricks. Like, how to build a macbook pro entirely out of CSS.
  • The Shapes of CSS blog post shows how to generate geometric shapes with CSS.
  • Colour Lovers is just colors, but they have some pretty colors.
  • CSS3 generator will generate the CSS for shaded, rounded boxes.

Saturday, September 8, 2012

CSS Boxes

In the following video I explain a bit more about CSS margin, border, and padding.

Cascading Style Sheets

Below I give a quick introduction to CSS. You should read over the MDN CSS documentation to learn CSS.

Friday, September 7, 2012

HW3: CSS, users

For this homework you will add a CSS file to your webapp to make it look pretty, and you will use the app engine users library to provide login and logout capabilities.

That CSS Look

Your website should look like the screenshots you see here. Namely, it must have:
  1. A header which shows either the login button, or the email of the currently logged-in user and the logout button. Both of these must be right-justified.
  2. A title, as shown, more or less.
  3. A box that is centered on the page and shows either the login message or asks for input (same as the previous homework). The background of the box must be a different color from the rest of the page.
  4. The footer, with your name centered on it.

You can use the same colors I used, which are USC's colors, or choose your own color template. Note, if you don't know much about visual design (as I don't), the best thing to do is to use someone else's color scheme and try to pick one with fewer than six colors. The fewer colors you use the more professional it will look.


The login and logout button should work, as expected: login and logout the user. When the user is logged in you should display his email address in the header. You will do this using the app engine's users library, which means that people will be logging in with their gmail/google credentials. Notice that with this method you do not need to store anything. Google takes care of the authentication process.

Required Reading

To do this homework you will to have read:

  1. Using the users service: getting started guide. More details in the users service API.
  2. MDN CSS Tutorial

You are free to google (or bing, or whatever you're into) for this and all homeworks as much as you want. However, be warned, you must understand what every line code in your program does! This is good to do not just for this class but for your whole career. If you cut-n-paste some piece of code from the interwebs into your program and you don't know exactly what it does you are asking for big-time trouble later on. When your app crashes the next day, is it because of the code you pasted? You have no idea! Blind pasting is the equivalent of agreeing to take in an international flight a suitcase that some stranger just gave you.

As always, push your code to your github repo by Monday, Sept. 17 @9am.

Tuesday, September 4, 2012

Jinja2 Templates

Below is a short intro to the Jinja2 templates as used in the app engine. You will need to consult the Jinja2 documentation to use them.

Monday, September 3, 2012

HTML Forms

Below I cover the basics of HTML forms.

HW1 Graded

I have graded HW1 and emailed you your grades. I am using your address. If you want me to email it somewhere just let me know.

I don't have a solution for this HW since it was mostly about making you have everything installed and know your way around chrome tools.

Saturday, September 1, 2012


Below is a short introduction to the main features of Python.

Another fun way to learn python is by doing the codeacadempy Python track.

Friday, August 31, 2012

Publish your App. Use Only one Eclipse Project

After you finish HW1, and you made sure that it runs locally (http://localhost:8080), you can then publish it for the whole world to see!

Just go to and click on "create application". Find an "application identifier" (app id) for your app (I suggest the same project name as your github repo, to keep things simple) that isn't taken, use all the other default values and create it. Then just copy the app id into your app.yaml under 'application: your-app-id' then click 'deploy' on your google app engine launcher. It will copy all your files to the google app engine and deploy. You can look at the log file to track its progress.

Your app will then appear at

Note that if you later on decide to buy your own domain name, say, it is just a matter of filling out a form to get the app to appear under your domain name.

You will have Only One Eclipse Project

I have noticed that some of you made an eclipse project called HW1. That's a bad name. You will only have one eclipse project for the whole semester. Each week you will be adding more features to this project. A good eclipse project name is the name of the github repo I gave you, or something similar.

HW2: jinja2 templates, HTML forms

In this homework you will allow your webapp to accept a URL, for an image, and a caption (text). Your app will not save these to the database (we will do that next week) but will simply display these back to the user.

Your app must use the jinja2 templates. Specifically, it will use a base.html template from which your other template inherits from. The base.html is a general template that all your other templates will inherit from. Thus, it contains the basic layout of the site. For this homework it is fine if this is a minimal template, but later on we will be adding headers and footers here.

The page after the user clicks 'submit'.
Your page should look like this, except 'Homework 1' should be '2', my bad.

Required Reading

To get this done you will have to read getting started using the webapp2 framework and handling forms. You will also want to consult the webapp2 framework documentation and the jinja2 documentation.

Turning it in

Push your code to your github repo by Monday Sept. 10 @9am.

Also, in your app.yaml set the version to 2 (for HW2) and publish it to That is, go to and create a new application. Set its name in your app.yaml and click on the "Deploy" button on your appserver. When you start working on HW3 change the version to 3 (and so on). In this way I will be able to view your previous at work even while you might already be testing a new version (at least, I hope it works out)

Wednesday, August 29, 2012

eGit User Guide

There is a comprehensive Users Guide for eGit which I forgot to mention. The Gettig Started section shows you how to set up a local repo, and also how to push/pull from a github repo.

While I'm here. If your eclipse workspace is in dropbox and you use it in more than one machine (say, laptop and desktop) then you should make sure to use dropbox's "Selective Sync" option and do NOT sync the .metadata folder in your eclipse workspace.  As this stackoverflow question atests, you should then be Ok. I have had this setup and shared a workspace between my laptop and desktop for over a year without any issues. The only thing is, I do have to 'import existing project' on the second machine after creating in on the first one.

Monday, August 27, 2012

Git Command Line Tutorial

There are like, 10,000 tutorials on git. Here is another one, on getting started with git using the command line:

HTML Basics

Below I talk about the basics of HTML. You should read over the MDN HTML documentation to make sure you are up to speed on basic HTML.

Sunday, August 26, 2012

HW1: Hello World, HTML and Git

For the first homework you will write a simple HTML page and push it to github. The goal is to make sure you have all (well, most) of the needed software installed on your laptop and understand the basic workflow.

First, write an index.html file, using the HTML5 DOCTYPE, that contains:
  1. Matching title and h1 with "HW1: Your-name"
  2. Nicely-formated answers to the following questions: (You should use chrome tools to find the answers)
    1. What webserver and OS is used by

    2. List all the JavaScript files loaded by

    3. List all the CSS files loaded by

    4. List the keys of all the cookies used by

    5. In, for the word "Campuses" on the left-hand menu, what is the margin-top?

    6. What webserver and CMS is used by

    7. Go to, change the line that says "About the college" (in the top left) to say "Engineers Get Things Done!". Take a screenshot. Add the screenshot image to index.html, with a width of 400 pixels.
  3. Make sure your page validates.

Finally, create the "Hello World" app engine application, as explained in this post and in the app engine Getting Started tutorial. Run it locally with the appserver to make sure it says hello world. You do not need to publish it (but you can, if you want to). Finally, add the index.html and related images to this new project, add them to the git repo, and push to your github repo.

This homework is due Monday, September 3 @9am.

Pushing your App Engine Project to Github

The video below shows you how add your eclipse appengine project to your local git and then push this local git repo to github, making sure the local master branch is tracking the remote ('origin') master branch at github. Thus, afterwards everytime you want to push to github all you have to do is 'Team->Push to Upstream'.

Also, I give a quick tip on setting up Quick Diff.

I forgot to show how to add a .gitignore file, but all you have to do is add a text file called '.gitignore' to your project's top-level folder, and in this file put the names of all the files you do not want to be added to your repo, one per line. Namely, add '.project' and '.pydevproject'.

Setting Up Eclipse and the App Engine

The video below shows how to set up eclipse and the app engine (etc.) for this class. I am using eclipse Helios in the video. You will find all the files you need at the appengine downloads page.

If you are using a newer eclipse, like for example Juno (the latest one, which I am using in class), then you should follow google's instructions for installing the google app engine plugin for eclipse. Note: I just upgraded to Juno from Helios and for it to work I had to first uninstall, in eclipse, all the Google plugins I had, then upgrade to Juno, then install the google plugin as per google's instructions.

I did forget to mention in the video that you should also install the eGit eclipse plugin. That is, when you are in the eclipse marketplace also search for 'egit' and install.

Also, you probably want to install and setup git itself in your laptop, in case you want to use git from the command line. The github guide on setting up git will show you how. Note mac users: if you use homebrew (and you should), just type brew install git to install it. Linux users already know they just have to apt-get install git.

Saturday, August 25, 2012

Chrome Developer Tools

On the previous video I used Chrome Developer tools, showing you a bit how to use them. You will be using these a lot in this class. Below is a very quick tutorial to get you started. You can learn best by just clicking around in devtools.

The video below has some very useful tricks (which might not make much sense to you now, but will make perfect sense in a few weeks as we cover more topics):

Watch Google I/O 2012 - Chrome Developer Tools Evolution to learn about the latest features in chrome tools.

Friday, August 24, 2012

Class Philosophy

This is a 'technical' class, meaning that we will solely focus on actually building a web application (a pinterest-like webbapp, this semester). We will be using the Google App Engine as our platform, the Python version. We will also be making heavy use of JavaScript and the jQuery library.

As in past years, I will try to 'flip' this class in that I will expect you to watch the videos and do the assigned readings before coming to class. During class time I will try to do as little lecturing as possible and instead provide individual help to each one of you for that week's homework. So, bring your laptop to class. The first couple of weeks we will have more traditional lectures as we have some material to cover before you get started coding.

The grading is described in the grading page.

The recommended online resources and books are in the about page.

All the videos I make and use for this class are in this youtube playlist. I will also posts here some videos by others which I think are helpful.

You will turn in your homeworks on github (nearly) every Monday morning, 9am. Thus, Friday's class will be an especially good time to ask me questions. Note that I go to bed early (my kids have to be at school at 7:30am) so do not expect me to be on IM on Sunday night. My solution to each week's homework will appear as a github project every Monday 9:01am. Thus, absolutely no late homeworks will be accepted.

Finally, this is an easy class. There are no complex algorithms to understand, no strange mathematical notation, no tests to take, and (almost) nothing to memorize. However, it is programming, and programming takes time, lots of time. Unfortunately, the only way to learn to code is by coding so, there is no other way until we get the Matrix brain plugs. If you are not ready to put in at least 8 hours/week of coding/reading time for this class then it is better that you do not take it.

The Internet and the Web

The first thing you need to understand is a bit about how the Internet works, and a bit more about how the World Wide Web works (and, the fact that they are not the same thing). First, a quick video on the Internet:

Next, a video about how the web works:

You should also bookmark the Mozilla Developer Network (MDN) and read their HTML Tutorials.

Tuesday, August 14, 2012

Git and Github for Homeworks

During the course of this class you will build a fairly sophisticated webapp, one small step at a time. Specifically, (almost) every week there will be a new homework which will involve adding more features to the webapp from last week.
You will turn in the weekly homeworks by using git and github.  The folks at github have been nice enough to give me 20 free 'private' repos. We have to use private repos because all of you will be working on the same project so, we don't want others copying your work. 
The way this will work is:
  1. You get a account.
  2. You email me your github account name and I will then create a private repo for you and give you commit privileges on it. After that you and I will be the only ones who can see or edit the repo.
  3. Before every deadline you will 'push' to github. I will 'pull' every project just after the deadline. Make sure your code is on the 'master' branch.
Alternatively, you can go to here and tell them you are a student and want your own couple of private repos. Then you can create your own repos yourself.  It takes them a couple of weeks to answer so, do it now. The advantage of this is that you will have the repo after class is over, whereas the repos I create will eventually get deleted when I teach this class again.
Either way, at the end of the semester you will have a nice little project on your github account that you can make public to show prospective employers your webapp building skills.
If all this sounds confusing, no worries, I will spend a lecture on git and on the specific workflow you will use (really just, 'commit', 'commit', then 'push' when you are ready).

Required Reading

Friday, February 10, 2012

This class will be taught again in the Fall 2012

It looks like I will be teaching this class again in the Fall 2012. Cool. Please sign up!

If you are a graduate student and want to take this class come talk to me about getting 700-level credit for taking this class.

By the way, here is a positive (anonymous) comment from a student in last year's class:

"I loved this class. There was a lot of programming involved but it was, I believe the perfect amount of work.

However, that does not mean that I was able to finish every assignment on time. I would recommend to future students that you do not take a heavy course load when taking this class. To get the most out of this class you really want to be able to spend time on this.

This has been one of the most interesting and get this, fun programming classes I have taken. I hope that you continue to offer it more frequently in the future."

and another (sorry, no money for a TA, but if any graduates of this class happen to be reading this and are willing to TA for free, talk to me)
"Great class and attendance set up. I could go to lecture if i needed help but didn't have to if i understood the topic. I feel that the homework were for the most part interesting and fair (by fair i mean there were usually only 4 or 5 things that were required instead of 9-10). This class has really gotten me interested in building web-applications and i have already started building some in my spare time. Before this class i had no real passion in the computing field, but now i have a specific passion that i would like to one day turn into a career. Thanks for teaching this class and hopefully it will continue. One suggestion for future classes would be to get a TA (which may not be an option) or a student who has done well in the class or who knows the subjects to assist you with helping students. There where times when i would chat with you and you might have been away and didn't answer my question. I feel that if there are multiple outlets then students will have an easier time getting help, which well keep them motivated."

and another, mostly positive (but, good point, I will do more jQuery/Javascript time)
"I feel that the amount of material covered was just right. I feel that we learned a little about a lot of useful techniques and that the more important and complicated techniques (Javascript, JQuery/Ajax, getting information via API) were given more time than the more basic techniques (HTML, Canvas, Off-Line data)."

And here is a negative one:
"Far, far, far, far, far too much. Most of the topics could have been covered over the course of a semester and still be too much. I have other classes and work a lot, so I didn't stand a chance."

If you just want to learn HTML, CSS, and a little bit of JavaScript, then take CSCE 102. If you want to go beyond that and learn how to build web applications (jQuery, DOM, app engine, databases, ORMs, REST APIs, canvas, HTML5, templates, etc.), then take this class.

Finally, you might be wondering how in demand these technologies are in the real world. Well, a survey done by of their users reveals that 42% of software developers describe their occupation as "Web Application Developer" (Question 7).

Update: And, one more thing, if you can't wait to get started, Udacity is teaching a class on web applications that starts in April 16. It is taught by the guy who created Reddit. They are using the google app engine, just like we will!