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.out.write(json.dumps(jsonObject))
            self.response.headers.add_header('Content-type', 'text/json')
        else:
            self.response.out.write("""
<html>
  <head>
    <title>Hello</title>
    <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() {
        $.ajax('/jtest',{
          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]];
            }
            data.addRows(rows);
            // 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});            
          }
          });
     }

    $(document).ready(function(){ 
      // Set a callback to run when the Google Visualization API is loaded.
      google.setOnLoadCallback(drawChart);
    });
    </script>

  </head>

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

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:

$(document).ready(
  $('li').click(function() {
   $('#title').hide('slow');
   $('li').hide('slow');
  })
);

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