2017-04-23 71 views
1

我是新來的Python,我很困惑,爲什麼我得到一個覆蓋錯誤。我正在嘗試構建一個類網絡,並將其表示爲由BST代表的字典。字典中的鍵可以是具有值列表的課程對象的Student對象,也可以是具有值列表的學生的課程(字符串)。問題是,當分析課程是否在字典中時,它儘管是一個字符串對象,仍然使用Student類的平等。這裏是我的代碼:平等覆蓋問題

def getClassList(): 
ClassList = []  # an empty list to be filled from class.csv file 
with open('lab6.csv', 'rb') as f: # access local file 'class.csv' 
    reader = csv.reader(f)   # connects reader object to file 
    for row in reader:    # reads one text line at a time 
     ClassList += [row]   # .. and appends to the ClassList 
return ClassList 

class Student: 
    def __init__(self, lastname, firstname, favcolor): 
    # assert(True) 
    self.lastname = lastname 
    self.firstname = firstname 
    self.favcolor = favcolor 

    def __eq__(self, other): 
    assert(type(other) == type(self)) 
    if (self.lastname == other.lastname and self.firstname == other.firstname and self.favcolor == other.favcolor): 
     return True 
    else: 
     return False 

def __repr__(self): 
    return str(self.firstname)+' '+str(self.lastname) 

class ClassNetwork: 
def __init__(self): 
    #creating an empty graph 
    self.rep=Dictionary() 
    #using the getClassList function to get the necessary info to create the graph 
    classlist=getClassList() 
    #not using the first list since it doesn't contain info 
    classlist=classlist[1:] 

    #traversing the list of lists 
    for i in range(len(classlist)): 
     #constructing a new student from each list (Student object) 
     newStudent=Student(classlist[i][0],classlist[i][1],classlist[i][3]) 
     #getting a course from each list (str type) 
     newCourse=str(classlist[i][2]) 

     #HANDLING THE COURSE 
     #checking if the course exists or not 
     if self.rep.lookup(newCourse)=='No entry': 
      #if not, add it 
      self.rep.put(newCourse,[newStudent]) 
     #if course already exists, update the student list 
     else: 
      upCo=self.rep.lookup(newCourse)+[newStudent] 
      self.rep.put(newCourse,upCo) 

     #HANDLING THE STUDENT 
     #checking if the student exists or not 
     if self.rep.lookup(newStudent)=='No entry': 
      #if not, add them - use put method 
      self.rep.put(newStudent,[newCourse]) 
     #if the student already exists, update course list 
     else: 
      #updated value=old courses+the new course 
      upSt=self.rep.lookup(newStudent)+[newCourse] 
      self.rep.put(newStudent,upSt) 

def __repr__(self): 
    return repr(self.rep.rep.inorderlist()) 

錯誤:

Exception raised: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/doctest.py", line 1315, in __run 
    compileflags, 1) in test.globs 
    File "<doctest __main__[0]>", line 1, in <module> 
    CN = ClassNetwork() 
    File "/homes/user/cs106/Lab 6/lab6.py", line 93, in __init__ 
    if self.rep.lookup(newStudent)=='No entry': 
    File "/homes/user/cs106/Lab 6/lab6.py", line 181, in lookup 
    return self.rep.lookup(key) 
    File "/homes/user/cs106/Lab 6/BST.py", line 81, in lookup 
    elif self.root()[0] == key: 
    File "/homes/user/cs106/Lab 6/lab6.py", line 56, in __eq__ 
    assert(type(other) == type(self)) 
AssertionError 
+0

你最想如果到'返回FALSE'了'學生'不匹配一個字符串。目前,您只使用'assert',因此當比較返回False時爲什麼會引發'AssertionError'。 –

+1

謝謝你的幫助!它解決了我的問題。 – Silvia

+1

我在下面重複了我的回答 - 如果您可以將此標記爲接受的答案,那將非常棒。謝謝。 –

回答

0

你應該return False而不是使用assert

def __eq__(self, other): 
    if type(other) != type(self): 
     return False 
    if (self.lastname == other.lastname and self.firstname == other.firstname and self.favcolor == other.favcolor): 
     return True 
    else: 
     return False 

使用assert將拋出AssertionError如果比較返回False

0

正如羅伯特希曼提到的assert如果聲明的條件爲假,則會產生AssertionError。發生這種情況時,將打印一條錯誤消息,並終止您的程序。你可能不要想要發生。 ;)相反,您應該在的類型檢查中作爲您的平等測試中的第一項,如下所示。

assert聲明應該而不是用於測試數據的有效性。斷言旨在捕獲程序邏輯中的缺陷:如果assert測試失敗,這應該表明您的程序的邏輯錯誤,並且您需要修復它。

,而不是做型式試驗與type功能,最好使用isinstance,如

if isinstance(other, Student): 

它也更靈活:如果other是這是一個從Student得出的測試將傳遞一個類。

不要做

if some_condition: 
    return True 
else: 
    return False 

相反,使用這種更緊湊的版本:

return some_condition. 

如果some_condition實際上不是一個布爾(FalseTrue),你實際需要函數返回一個布爾值,你可能做

return bool(some_condition) 

將其轉換爲布爾值,但這通常不是必需的。

另外,看起來你還在使用Python 2.你應該定義你的類繼承自object,否則你會得到舊式的類而不是優秀的新式類(在Python 3中,所有的類都是新的風格,所以你不需要明確從object繼承)。

方法有改進的餘地Student.__repr__方法。看起來,所有Student實例屬性(lastname,firstnamefavcolor)都是字符串,因此無需在其上調用str。你可以連接字符串使用+,但它通常更方便使用.format.join方法。另外,__repr__是供程序員使用的,理想情況下它應該返回一個可以用來重新構造對象的字符串;使用__str__來創建一個用戶友好的字符串。 (如果某個類定義了__repr__但未定義__str__,則當您在該對象上調用str時將使用__repr__)。

這是你的Student類的改進版本,可運行於Python 2和Python 3的

from __future__ import print_function 

class Student(object): 
    def __init__(self, lastname, firstname, favcolor): 
     self.lastname = lastname 
     self.firstname = firstname 
     self.favcolor = favcolor 

    def __eq__(self, other): 
     return (isinstance(other, Student) and self.lastname == other.lastname 
      and self.firstname == other.firstname and self.favcolor == other.favcolor) 

    def __repr__(self): 
     return 'Student({!r}, {!r}, {!r})'.format(self.lastname, self.firstname, self.favcolor) 

    def __str__(self): 
     return '{} {}'.format(self.firstname, self.lastname) 

# test 

students = [ 
    Student('Smith', 'John', 'red'), 
    Student('Jones', 'Fred', 'blue'), 
    'not a student', 
] 

for s1 in students: 
    print(s1) 
    for s2 in students: 
     print(' {!r} : {}'.format(s2, s1 == s2)) 

輸出

John Smith 
    Student('Smith', 'John', 'red') : True 
    Student('Jones', 'Fred', 'blue') : False 
    'not a student' : False 
Fred Jones 
    Student('Smith', 'John', 'red') : False 
    Student('Jones', 'Fred', 'blue') : True 
    'not a student' : False 
not a student 
    Student('Smith', 'John', 'red') : False 
    Student('Jones', 'Fred', 'blue') : False 
    'not a student' : True