Notes: Recitation 11
From 6.00 reference wiki
Contents |
Final Project
Here is the basic trigger code from the final project:
class TrueTrigger: def evaluate(self, newsitem): """ Returns True if an alert should be generated for the given news item, or False otherwise. """ return True
A NewsItem Class
There is a glaring omission from the specification of evaluate in the filter interface. It does not specify the type of the argument newsitem.
What is the type of this argument? Does it matter?
Suppose we want to access the subject of the news item. How do we do this?
If we called evaluate by passing in one of the elements from the entries list returned by feedparser, we would have to do the following:
newsitem.tags[0]['term']
Similarly, in order to access the title, we would have to use:
translate_html(newsitem.title)
This will work, but it is the wrong way to handle news items inside triggers. One reason is that each trigger would have to call translate_html on a news item's title. Since there are many triggers, translate_html would be called many times per item, when we only need to call it once per item. This is inelegant.
In our triggers, we want to be able to use something like:
newsitem.subject
To access the news item's subject.
The way to do this is to use a NewsItem class.
class NewsItem: """ A news item with the following fields: guid: string (unique identifier) title: string (plain text, not html) subject: string (plain text) summary: string (plain text) link: string (URL, address) """ ...
You should be able to figure out how to fill in the code for the above class. If you are confused, read section 10.4 in Zelle again. You only need to add a constructor to this class, but you can add other methods too.
Outside the trigger, your program will need to take the entries list provided by feedparser and use it to create a list of NewsItem objects (this will be like the printing loop you have right now). Then you should discard the entries list and use the more abstract NewsItem objects in the alert-generation part of your program.
Make sure you understand why we're adding this class. It has to do with the encapsulation and abstraction ideas discussed in the book and in lecture.
A Simple Subject Filter
Let's implement a simple subject-based trigger. Here is the class definition for that trigger.
class BasicSubjectTrigger: """ Implements a trigger that fires when a news item has a specific subject. An instance of this class created with the argument "Technology" will fire for every news item where the subject is exactly equal to "Technology". """ ...
The first step is to choose and document the class's fields. In this case we have a single field:
# subject: string (the subject value this trigger fires on)
Notice that we have declared this field as a comment, instead of as part of the class's specification (see NewsItem to contrast). Since we don't actually want code outside the class accessing this field, there is no reason to document it in the class's specification string. We still have to declare the variable.
The next step is to add a constructor to the class:
def __init__(self, subject): self.subject = subject
Since we want this class to implement the filter interface, we need to provide an evaluate method that does the right thing:
def evaluate(self, newsitem): if newsitem.subject == self.subject: return True else: return False
This is the complete code for the class:
class BasicSubjectTrigger: """ Implements a trigger that fires when a news item has a specific subject. An instance of this class created with the argument "Technology" will fire for every news item where the subject is exactly equal to "Technology". """ # subject: string (the subject value this trigger fires on) def __init__(self, subject): self.subject = subject def evaluate(self, newsitem): if newsitem.subject == self.subject: return True else: return False
Make sure you understand this filter, before you implement your own.
More Web Scripts
Last week we looked at some basic Python web scripts. The basic difference between web scripts and normal Python programs is where the code is executed. In a normal program, you run it on your machine, and everything it prints out is displayed on your screen. For a web script, you run it by entering the address of that script in your browser's address bar; the script runs remotely on another machine; and after that program has finished, everything it printed out is displayed on your computer's screen, in your browser.
This week we will look at how to get input from users when we're writing web scripts. This is more complicated than calling input because the user is on another computer, perhaps in another country.
Web scripts must seperate the input part of the program from the processing part of the program. A first script asks the user for the required inputs, the request is displayed to the user, and the user types in their inputs and submits them by hitting a submit button in their browser. Once the user has hit the submit button, another Python web script is started, and the user's inputs are passed to it.
Greeting by name
Lets write a pair of web scripts to ask the user their name, and then to display a personalized greeting.
The script that asks the user for their name is given below. The WebForm class is a class that allows us to easily create a HTML page that has a form for input. Look at the creation of the WebForm object here. submit_hello.py is the remote Python script that will be run when the user hits the submit button.
import cgitb; cgitb.enable() from web_form import * # create the form form = WebForm("Greetings", "submit_hello.py") # ask a question form.begin_question("What is your name?") form.write_text("Please type in your name below.") form.new_paragraph() form.add_input_text("name") form.end_question() # print out the HTML form.print_html()
The program that processes the inputs submitted by the user is given below. Notice that this program, like every Python web script, must produce some HTML output (otherwise the user sees an 'internal server error' message in your browser).
import cgitb; cgitb.enable() from web_form import * from html_util import * # create a helper to generate the HTML doc = HTMLDocument("Hello") # get the values submitted by the user d = get_submitted_form_data() # is there a valid name there? if "name" in d: name = d["name"] else: name = None if name: # generate a basic greeting if we know who it is. doc.new_section("Hello %s" % name) doc.new_paragraph() doc.write_text("It's nice to meet you.") else: # we don't know the user's name. doc.new_section("Who are you?") doc.new_paragraph() doc.write_text("I don't know who you are... You should really go back and type in your name.") # output the HTML doc.print_html()
IQ Test
The pair of scripts below implement an IQ test. One script generates the test questions and shows them to the user. The other script processes the user's answers and generates a score.
Display the 'IQ' test questions:
Score the submitted answers:
Student Signup
Remember the signup form you had to submit at the start of the class? Here's the code for a version of it.
Display the signup form:
Save the submitted information:
You can look at last week's user authentication example and modify the signup script so that it authenticates a user by his/her MIT certificate.
Recitation Example Code
The code for the above examples, and their required modules, is online: