2015-07-28 69 views
0

作为一个新的学习者的问题,这个问题可能很简单,但我已经尝试了很多个小时,并且找不到答案,对不起。任何人都可以帮我用这个python TypeError

这是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命名屏幕取词得到了这个词的方法,短语看试探是否正确不,我回来之前做到这一点:

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

+2

请问您能否尝试将您的代码去掉尽可能少的行数,但仍然会重现该问题?你更有可能以这种方式获得帮助...... –

+0

你可以在'makeTrigger'函数的'params =''.join(params)''行后打印'params'。我有一种感觉,那就是导致错误。 – DJanssens

回答

0

问题的至少一部分是这行代码:

WordTrigger.changeText(self, text.upper()).split() 

您已经定义changeText为实例方法,但是你在类本身上调用它。尝试将其更改为这样:

self.changeText(text.upper()).split() 

您还需要作出类似的转换来的WordTrigger其他子类。

+0

谢谢,我已经解决了这个问题 – Eric

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 

您捕获任何异常,并仅打印异常。正常行为会打印出发生地点的完整回溯。或者完全删除此尝试 - 除了条款,或使用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,并且可能使用子类在参数类型(触发器,单词或短语)之间进行选择。

+0

我已经解决了由语法错误导致的参数数目的问题。而main_thread是由老师给出的,所以我忽略了关于try的这个细节...除了,谢谢 – Eric

+0

这个类型的差异是什么? makeTrigger docstring指示'triggerMap'应该只包含实例,但是你需要在其中放入类。这是你的'评估'类型错误的原因。 –

相关问题