作为一个新学习者的问题,这个问题可能非常简单,但我已经尝试了很多个小时而无法找到答案,抱歉。
这是edx的python课程的一个问题。
我将粘贴所有代码,但是我已经完成了大部分代码并且正确。第4部分是我正在进行的。 首先,文件的内容是:
# subject trigger named t1
t1 SUBJECT world
# title trigger named t2
t2 TITLE Intel
# phrase trigger named t3
t3 PHRASE New York City
# composite trigger named t4
t4 AND t2 t3
# the trigger set contains t1 and t4
ADD t1 t4
,
import feedparser
import string
import time
from project_util import translate_html
from Tkinter import *
#======================
# Code for retrieving and parsing RSS feeds
#======================
def process(url):
"""
Fetches news items from the rss url and parses them.
Returns a list of NewsStory-s.
"""
feed = feedparser.parse(url)
entries = feed.entries
ret = []
for entry in entries:
guid = entry.guid
title = translate_html(entry.title)
link = entry.link
summary = translate_html(entry.summary)
try:
subject = translate_html(entry.tags[0]['term'])
except AttributeError:
subject = ""
newsStory = NewsStory(guid, title, subject, summary, link)
ret.append(newsStory)
return ret
#======================
# Part 1
# Data structure design
#======================
class NewsStory(object):
def __init__(self, guid, title, subject, summary, link):
self.guid = guid
self.title = title
self.subject = subject
self.summary = summary
self.link = link
def getGuid(self):
return self.guid
def getTitle(self):
return self.title
def getSubject(self):
return self.subject
def getSummary(self):
return self.summary
def getLink(self):
return self.link
#======================
# Part 2
# Triggers
#======================
class Trigger(object):
def evaluate(self, story):
"""
Returns True if an alert should be generated
for the given news item, or False otherwise.
"""
raise NotImplementedError
# Whole Word Triggers
class WordTrigger(Trigger):
def __init__(self, word):
self.word = word
def changeText(self, text):
for i in string.punctuation:
text = text.replace(i, ' ')
return text
def isWordIn(self, text):
return self.word.upper in self.changeText(self, text.upper()).split()
class TitleTrigger(WordTrigger):
def evaluate(self, story):
return self.isWordIn(self, story.getTitle())
class SubjectTrigger(WordTrigger):
def evaluate(self, story):
return self.isWordIn(self, story.getSubject())
class SummaryTrigger(WordTrigger):
def evaluate(self, story):
return self.isWordIn(self, story.getSummary())
# Composite Triggers
class NotTrigger(Trigger):
def __init__(self, trigger):
self.trigger = trigger
def evaluate(self,story):
return not self.trigger.evaluate(story)
class AndTrigger(Trigger):
def __init__(self, trigger1, trigger2):
self.trigger1 = trigger1
self.trigger2 = trigger2
def evaluate(self, story):
return self.trigger1.evaluate(story) and self.trigger2.evaluate(story)
class OrTrigger(Trigger):
def __init__(self, trigger1, trigger2):
self.trigger1 = trigger1
self.trigger2 = trigger2
def evaluate(self, story):
return self.trigger1.evaluate(story) or self.trigger2.evaluate(story)
# Phrase Trigger
class PhraseTrigger(Trigger):
def __init__(self, phrase):
self.phrase = phrase
def evaluate(self, story):
return self.phrase in story.getSubject() or self.phrase in story.\
getSummary() or self.phrase in story.getTitle()
#======================
# Part 3
# Filtering
#======================
def filterStories(stories, triggerlist):
"""
Takes in a list of NewsStory instances.
Returns: a list of only the stories for which a trigger in triggerlist fires.
"""
temp = stories[:]
for i in stories:
for j in triggerlist:
if (not j.evaluate(i)) and j == triggerlist[-1]:
temp.remove(i)
elif j.evaluate(i):
break
stories = temp[:]
return stories
这就是我所做的并且正确无误。因为下一个函数需要TitleTrigger,SubjectTrigger,SummaryTrigger,NotTrigger,AndTrigger,PhraseTrigger,OrTrigger,并且所有触发器都需要NewsStory,所以我保留它们。
#======================
# Part 4
# User-Specified Triggers
#======================
def makeTrigger(triggerMap, triggerType, params, name):
"""
Takes in a map of names to trigger instance, the type of trigger to make,
and the list of parameters to the constructor, and adds a new trigger
to the trigger map dictionary.
triggerMap: dictionary with names as keys (strings) and triggers as values
triggerType: string indicating the type of trigger to make (ex: "TITLE")
params: list of strings with the inputs to the trigger constructor (ex: ["world"])
name: a string representing the name of the new trigger (ex: "t1")
Modifies triggerMap, adding a new key-value pair for this trigger.
Returns a new instance of a trigger (ex: TitleTrigger, AndTrigger).
"""
if triggerType == 'TITLE':
triggerMap[name] = TitleTrigger
if triggerType == 'SUBJECT':
triggerMap[name] = SubjectTrigger
if triggerType == 'PHRASE':
triggerMap[name] = PhraseTrigger
if triggerType == 'SUMMARY':
triggerMap[name] = SummaryTrigger
if triggerType == 'AND':
triggerMap[name] = AndTrigger
if triggerType == 'OR':
triggerMap[name] = OrTrigger
if triggerType == 'NOT':
triggerMap[name] = NotTrigger
if triggerType == 'AND' or triggerType == 'OR':
tempt = triggerMap[name](triggerMap[params[0]],triggerMap[params[1]])
elif triggerType == 'NOT':
tempt = NotTrigger(triggerMap[params[0]])
else:
params = ' '.join(params)
tempt = triggerMap[name](params)
return tempt
def readTriggerConfig(filename):
triggerfile = open(filename, "r")
all = [ line.rstrip() for line in triggerfile.readlines() ]
lines = []
for line in all:
if len(line) == 0 or line[0] == '#':
continue
lines.append(line)
triggers = []
triggerMap = {}
for line in lines:
linesplit = line.split(" ")
# Making a new trigger
if linesplit[0] != "ADD":
trigger = makeTrigger(triggerMap, linesplit[1],
linesplit[2:], linesplit[0])
# Add the triggers to the list
else:
for name in linesplit[1:]:
triggers.append(triggerMap[name])
return triggers
这是我正在研究的部分,readTriggerConfig由老师提供。
import thread
SLEEPTIME = 60 #seconds -- how often we poll
def main_thread(master):
# A sample trigger list - you'll replace
# this with something more configurable in Problem 11
try:
# TODO: Problem 11
# After implementing makeTrigger, uncomment the line below:
triggerlist = readTriggerConfig("triggers.txt")
# **** from here down is about drawing ****
frame = Frame(master)
frame.pack(side=BOTTOM)
scrollbar = Scrollbar(master)
scrollbar.pack(side=RIGHT,fill=Y)
t = "Google & Yahoo Top News"
title = StringVar()
title.set(t)
ttl = Label(master, textvariable=title, font=("Helvetica", 18))
ttl.pack(side=TOP)
cont = Text(master, font=("Helvetica",14), yscrollcommand=scrollbar.set)
cont.pack(side=BOTTOM)
cont.tag_config("title", justify='center')
button = Button(frame, text="Exit", command=root.destroy)
button.pack(side=BOTTOM)
# Gather stories
guidShown = []
def get_cont(newstory):
if newstory.getGuid() not in guidShown:
cont.insert(END, newstory.getTitle()+"\n", "title")
cont.insert(END, "\n---------------------------------------------------------------\n", "title")
cont.insert(END, newstory.getSummary())
cont.insert(END, "\n*********************************************************************\n", "title")
guidShown.append(newstory.getGuid())
while True:
print "Polling . . .",
# Get stories from Google's Top Stories RSS news feed
stories = process("http://news.google.com/?output=rss")
# Get stories from Yahoo's Top Stories RSS news feed
stories.extend(process("http://rss.news.yahoo.com/rss/topstories"))
# Process the stories
stories = filterStories(stories, triggerlist)
map(get_cont, stories)
scrollbar.config(command=cont.yview)
print "Sleeping..."
time.sleep(SLEEPTIME)
except Exception as e:
print e
if __name__ == '__main__':
root = Tk()
root.title("Some RSS parser")
thread.start_new_thread(main_thread, (root,))
root.mainloop()
最后一部分由teacher.thanks提供
我在SubjectTrigger,TitleTrigger,PhraseTrigger和AndTrigger中添加了一个名为getWord的方法,以获取单词,短语以查看诱惑是否正确,并在返回之前执行此操作:
print tempt
print tempt.getWord()
return tempt
它给了我:
<__main__.SubjectTrigger object at 0x000000000849B898>
world
<__main__.TitleTrigger object at 0x000000000849B8D0>
Intel
<__main__.PhraseTrigger object at 0x000000000849B898>
New York City
<__main__.AndTrigger object at 0x000000000849B8D0>
(<class '__main__.TitleTrigger'>, <class '__main__.PhraseTrigger'>)
Polling . . .
Traceback (most recent call last):
File "C:\Users\Administrator\Desktop\python\ProblemSet7\ps7.py", line 292, in main_thread
stories = filterStories(stories, triggerlist)
File "C:\Users\Administrator\Desktop\python\ProblemSet7\ps7.py", line 161, in filterStories
if (not j.evaluate(i)) and j == triggerlist[-1]:
TypeError: unbound method evaluate() must be called with SubjectTrigger instance as first argument (got NewsStory instance instead)
似乎我已经得到了正确的诱惑,但在第161行中有一些错误
答案 0 :(得分:0)
至少部分问题是这行代码:
WordTrigger.changeText(self, text.upper()).split()
您已将changeText
定义为实例方法,但您在类本身上调用它。尝试将其更改为:
self.changeText(text.upper()).split()
您还需要对WordTrigger
的其他子类进行类似的转换。
答案 1 :(得分:0)
你的第一个问题显然是一个带有意外数量的参数的实例创建,但第二个问题是你要丢弃可以准确告诉你在哪里的追溯。在您的代码中:
def main_thread(master):
# A sample trigger list - you'll replace
# this with something more configurable in Problem 11
try:
pass # Lots of code here
except Exception as e:
print e
您捕获任何异常,并仅打印异常。正常行为将打印出它发生的完整回溯。完全删除此try-except子句,或使用traceback
模块恢复更多信息:
except:
import traceback
traceback.print_exc()
进一步阅读时,您的核心问题似乎在makeTrigger
,特别是它如何在triggerMap
中使用不同的类型。它试图首先将一个类分配到地图中,然后使用该类创建一个实例,但逻辑是有缺陷的:
if triggerType == 'AND' or triggerType == 'OR':
tempt = triggerMap[name](triggerMap[params[0]],triggerMap[params[1]])
if triggerType == 'NOT':
tempt = NotTrigger(triggerMap[params[0]])
else:
params = ' '.join(params)
tempt = triggerMap[name](params)
首先,正如您所发现的那样,第一个if
与后者不同;这个块不是三个分支,而是顺序的两个分支路径,可以使用elif
轻松修复。其次,triggerMap[name]
永远不会被设置为创建的实例。这打破了逻辑触发器中的假设,其中triggerMap[params[n]]
应该是触发器实例,而不是类。尝试评估triggerMap条目导致未绑定的方法调用。解决此问题的一种方法是triggerMap[name] = tempt
。
我们也可以减少特殊情况;我会考虑用字典替换triggerType ifs,并且可能使用子类在参数类型(触发器,单词或短语)之间进行选择。