Don't like ads? PRO users don't see any ads ;-)
Guest

Test9

By: a guest on Jul 10th, 2012  |  syntax: Python  |  size: 10.28 KB  |  hits: 237  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. >>> ================================ RESTART ================================
  2. >>>
  3. testNewsStoryConstructor (__main__.ProblemSet5NewsStory) ... ok
  4. testNewsStoryGetGuid (__main__.ProblemSet5NewsStory) ... ok
  5. testNewsStoryGetLink (__main__.ProblemSet5NewsStory) ... ok
  6. testNewsStoryGetSubject (__main__.ProblemSet5NewsStory) ... ok
  7. testNewsStoryGetSummary (__main__.ProblemSet5NewsStory) ... ok
  8. testNewsStoryGetTitle (__main__.ProblemSet5NewsStory) ... ok
  9. test1TitleTrigger (__main__.ProblemSet5) ... ok
  10. test2SubjectTrigger (__main__.ProblemSet5) ... ok
  11. test3SummaryTrigger (__main__.ProblemSet5) ... ok
  12. test4NotTrigger (__main__.ProblemSet5) ... ok
  13. test5AndTrigger (__main__.ProblemSet5) ... ok
  14. test6OrTrigger (__main__.ProblemSet5) ... ok
  15. test7PhraseTrigger (__main__.ProblemSet5) ... ok
  16. test8FilterStories (__main__.ProblemSet5) ... ok
  17. test8FilterStories2 (__main__.ProblemSet5) ... ok
  18. test9UserTriggers (__main__.ProblemSet5) ... found line!
  19. # 6.00 Problem Set 5
  20. # RSS Feed Filter
  21.  
  22. import feedparser
  23. import string
  24. import time
  25. from project_util import translate_html
  26. from news_gui import Popup
  27.  
  28. #-----------------------------------------------------------------------
  29. #
  30. # Problem Set 5
  31.  
  32. #======================
  33. # Code for retrieving and parsing
  34. # Google and Yahoo News feeds
  35. # Do not change this code
  36. #======================
  37.  
  38. def process(url):
  39.     """
  40.    Fetches news items from the rss url and parses them.
  41.    Returns a list of NewsStory-s.
  42.    """
  43.     feed = feedparser.parse(url)
  44.     entries = feed.entries
  45.     ret = []
  46.     for entry in entries:
  47.         guid = entry.guid
  48.         title = translate_html(entry.title)
  49.         link = entry.link
  50.         summary = translate_html(entry.summary)
  51.         try:
  52.             subject = translate_html(entry.tags[0]['term'])
  53.         except AttributeError:
  54.             subject = ""
  55.         newsStory = NewsStory(guid, title, subject, summary, link)
  56.         ret.append(newsStory)
  57.     return ret
  58.  
  59. #======================
  60. # Part 1
  61. # Data structure design
  62. #======================
  63.  
  64. # Problem 1
  65.  
  66. class NewsStory(object):
  67.  
  68.     def __init__(self, guid, title, subject, summary, link):
  69.         self.guid = guid
  70.         self.title = title
  71.         self.subject = subject
  72.         self.summary = summary
  73.         self.link = link
  74.  
  75.     def get_guid(self):
  76.         return self.guid
  77.     def get_title(self):
  78.         return self.title
  79.     def get_subject(self):
  80.         return self.subject
  81.     def get_summary(self):
  82.         return self.summary
  83.     def get_link(self):
  84.         return self.link
  85.  
  86. #======================
  87. # Part 2
  88. # Triggers
  89. #======================
  90.  
  91. class Trigger(object):
  92.     def evaluate(self, story):
  93.         """
  94.        Returns True if an alert should be generated
  95.        for the given news item, or False otherwise.
  96.        """
  97.         raise NotImplementedError
  98.  
  99. # Whole Word Triggers
  100. # Problems 2-5
  101.  
  102. class WordTrigger(Trigger):
  103.  
  104.     def __init__(self, word):
  105.         self.word = word.lower()
  106.  
  107.     def is_word_in(self, text):
  108.         text = text.lower()
  109.         for e in string.punctuation :
  110.             if e in text: text = text.replace(e, " ")
  111.         return self.word in text.split()
  112.        
  113. class TitleTrigger(WordTrigger):
  114.     def evaluate(self, story):
  115.         return self.is_word_in(story.title)
  116.  
  117. class SubjectTrigger(WordTrigger):
  118.     def evaluate(self, story):
  119.         return self.is_word_in(story.subject)
  120.  
  121. class SummaryTrigger(WordTrigger):
  122.     def evaluate(self, story):
  123.         return self.is_word_in(story.summary)
  124.    
  125. # Composite Triggers
  126. # Problems 6-8
  127.  
  128. class NotTrigger(Trigger):
  129.     def __init__(self, trigger):
  130.         self.trigger = trigger
  131.     def evaluate(self, story):
  132.         return not self.trigger.evaluate(story)
  133.  
  134. class AndTrigger(Trigger):
  135.     def __init__(self, trigger1, trigger2):
  136.         self.trigger1 = trigger1
  137.         self.trigger2 = trigger2
  138.     def evaluate(self, story):
  139.         return self.trigger1.evaluate(story) and self.trigger2.evaluate(story)
  140.  
  141. class OrTrigger(Trigger):
  142.     def __init__(self, trigger1, trigger2):
  143.         self.trigger1 = trigger1
  144.         self.trigger2 = trigger2
  145.     def evaluate(self, story):
  146.         return self.trigger1.evaluate(story) or self.trigger2.evaluate(story)
  147.  
  148. # Phrase Trigger
  149. # Question 9
  150.  
  151. class PhraseTrigger(Trigger):
  152.     def __init__(self, phrase):
  153.         self.phrase = phrase
  154.     def evaluate(self, story):
  155.         return (self.phrase in story.title) or (self.phrase in story.subject) or (self.phrase in story.summary)
  156.  
  157. #======================
  158. # Part 3
  159. # Filtering
  160. #======================
  161.  
  162. def filter_stories(stories, triggerlist):
  163.     """
  164.    Takes in a list of NewsStory-s.
  165.    Returns only those stories for whom
  166.    a trigger in triggerlist fires.
  167.    """
  168.     story_filter = []
  169.     for story in stories:
  170.         for trigger in triggerlist:
  171.             if trigger.evaluate(story) == True:
  172.                 story_filter.append(story)
  173.                 break
  174.     return story_filter
  175.  
  176. #======================
  177. # Part 4
  178. # User-Specified Triggers
  179. #======================
  180.  
  181. def readTriggerConfig(filename):
  182.     """
  183.    Returns a list of trigger objects
  184.    that correspond to the rules set
  185.    in the file filename
  186.    """
  187.  
  188.     triggerfile = open(filename, "r")
  189.     all = [ line.rstrip() for line in triggerfile.readlines() ]
  190.     lines = []
  191.     phrase = ""
  192.     triggers = {}
  193.     trigger_list = []
  194.    
  195.     for line in all:
  196.         if len(line) == 0 or line[0] == '#':
  197.             continue
  198.         lines.append(line)
  199.  
  200.     for i in range(len(lines)):
  201.         lines[i] = lines[i].split()
  202.  
  203.     for e in lines:
  204.         if e[0] == "ADD":
  205.             for x in e[1:]:
  206.                 trigger_list.append(triggers[x])
  207.         elif e[1] == "TITLE":
  208.             triggers[e[0]] = TitleTrigger(e[2])
  209.         elif e[1] == "SUBJECT":
  210.             triggers[e[0]] = SubjectTrigger(e[2])
  211.         elif e[1] == "SUMMARY":
  212.             triggers[e[0]] = SummaryTrigger(e[2])
  213.         elif e[1] == "NOT":
  214.             triggers[e[0]] = NotTrigger(triggers[e[2]])            
  215.         elif e[1] == "AND":
  216.             triggers[e[0]] = AndTrigger(triggers[e[2]], triggers[e[3]])            
  217.         elif e[1] == "OR":
  218.             triggers[e[0]] = OrTrigger(triggers[e[2]], triggers[e[3]])            
  219.         elif e[1] == "PHRASE":
  220.             phrase = e[2]
  221.             for x in e[3:]:
  222.                 phrase += " " + x
  223.             triggers[e[0]] = PhraseTrigger(phrase)
  224.  
  225.     return trigger_list
  226.    
  227. import thread
  228.  
  229. def main_thread(p):
  230.     # A sample trigger list - you'll replace
  231.     # this with something more configurable in Problem 11
  232.     #    t1 = SubjectTrigger("Obama")
  233.     #    t2 = SummaryTrigger("MIT")
  234.     #    t3 = PhraseTrigger("Supreme Court")
  235.     #    t4 = OrTrigger(t2, t3)
  236.     #    triggerlist = [t1, t4]
  237.    
  238.     # TODO: Problem 11
  239.     # After implementing readTriggerConfig, uncomment this line
  240.  
  241.     triggerlist = readTriggerConfig("triggers.txt")
  242.     print triggerlist
  243.    
  244.  
  245.     guidShown = []
  246.    
  247.     while True:
  248.         print "Polling..."
  249.  
  250.         # Get stories from Google's Top Stories RSS news feed
  251.         stories = process("http://news.google.com/?output=rss")
  252.         # Get stories from Yahoo's Top Stories RSS news feed
  253.         stories.extend(process("http://rss.news.yahoo.com/rss/topstories"))
  254.  
  255.         # Only select stories we're interested in
  256.         stories = filter_stories(stories, triggerlist)
  257.    
  258.         # Don't print a story if we have already printed it before
  259.         newstories = []
  260.         for story in stories:
  261.             if story.get_guid() not in guidShown:
  262.                 newstories.append(story)
  263.        
  264.         for story in newstories:
  265.             guidShown.append(story.get_guid())
  266.             p.newWindow(story)
  267.  
  268.         print "Sleeping..."
  269.         time.sleep(SLEEPTIME)
  270.  
  271. SLEEPTIME = 60 #seconds -- how often we poll
  272. class Trigger(object):
  273.    def evaluate():
  274.        return False
  275. class WordTrigger(Trigger):
  276.             def __init__(self, word):
  277.                 self.word = word.lower()
  278.                 print "Injected!"
  279.             def hash(self):
  280.                 raise NotImplementedError
  281. class SubjectTrigger(Trigger):
  282.     def __init__(self, word):
  283.         self.word = word.lower()
  284.         print "Injected Subject!"
  285.     def hash(self):
  286.         return "SUBJECT-" + self.word
  287. class TitleTrigger(WordTrigger):
  288.     def hash(self):
  289.         return "TITLE-" + self.word
  290. class SummaryTrigger(WordTrigger):
  291.     def hash(self):
  292.         return "SUMMARY-" + self.word
  293. class NotTrigger(Trigger):
  294.     def __init__(self, trigger):
  295.         self.trigger = trigger
  296.         print "Injected!"
  297.     def hash(self):
  298.         return "NOT-" + self.trigger.hash()
  299. class PhraseTrigger(Trigger):
  300.     def __init__(self, phrase):
  301.         self.phrase = phrase
  302.         print "Injected!"
  303.     def hash(self):
  304.         return "PHRASE-" + self.phrase
  305. class CompositeTrigger(Trigger):
  306.     def __init__(self, trigger1, trigger2):
  307.         self.trigger1 = trigger1
  308.         self.trigger2 = trigger2
  309. class AndTrigger(CompositeTrigger):
  310.     def hash(self):
  311.         t1_hash = self.trigger1.hash()
  312.         t2_hash = self.trigger2.hash()
  313.         if t1_hash > t2_hash:
  314.             return "AND-" + t1_hash + "-" + t2_hash
  315.         else:
  316.             return "AND-" + t2_hash + "-" + t1_hash
  317. class OrTrigger(CompositeTrigger):
  318.     def hash(self):
  319.         t1_hash = self.trigger1.hash()
  320.         t2_hash = self.trigger2.hash()
  321.         if t1_hash > t2_hash:
  322.             return "OR-" + t1_hash + "-" + t2_hash
  323.         else:
  324.             return "OR-" + t2_hash + "-" + t1_hash
  325.  
  326.  
  327.  
  328. Injected Subject!
  329. Injected!
  330. Injected!
  331. {'SUBJECT-sports': False, 'OR-SUMMARY-obama-PHRASE-Hillary Clinton': False}
  332. ERROR
  333.  
  334. ======================================================================
  335. ERROR: test9UserTriggers (__main__.ProblemSet5)
  336. ----------------------------------------------------------------------
  337. Traceback (most recent call last):
  338.   File "/home/sakh/MIT/6.00 Intro to CS/ps5/ps5_test.py", line 269, in test9UserTriggers
  339.     trigger_list = readTriggerConfig("triggers.txt")
  340.   File "compile-errors", line 205, in readTriggerConfig
  341. NameError: global name 'TitleTrigger' is not defined
  342.  
  343. ----------------------------------------------------------------------
  344. Ran 16 tests in 0.495s
  345.  
  346. FAILED (errors=1)