2015-07-28 42 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'應該只包含實例,但是你需要在其中放入類。這是你的'評估'類型錯誤的原因。 –

相關問題