2012-04-03 3 views
0

Использование того же кода в доктрине и в оболочке дает разные выходы.
У меня есть функция под названием a(), которая проходит через несколько тестов.
Те же тесты используются в doctest (test()).
С() я получаю OBJECT-BLANKLINE-OBJECT, в то время как test() дает мне ошибку и показывает только первый объект OBJECT.
Является ли это недостатком в модуле доктрины?Выход Doctest отличается от выходного сигнала оболочки

Вот весь файл как с() и тест() в верхней части:

''' 
>>> u1 = User("[email protected]", "simples") 
>>> u2 = User("[email protected]", "complicada") 
>>> u2.askFriend(u1) 
>>> u1.recvRequest(u2) 
>>> u1.confirmFriend(u2) 
>>> p1 = Post(u1, "O ultimo post", "http://www.wikipedia.org") 
>>> p2 = Post(u2, "A ultima resposta", "http://www.google.com") 
>>> c = Comments() 
>>> c.add(p1) 
>>> c.add(p2) 
>>> f1 = c.search(user="[email protected]") 
>>> print(f1) 
A ultima resposta 
http://www.google.com 
0 Gosto, 0 Nao gosto 
>>> f2 = c.search(likes=1) 
>>> print(f2) 
<BLANKLINE> 
>>> f3 = c.search(text='post') 
>>> print(f3) 
O ultimo post 
http://www.wikipedia.org 
0 Gosto, 0 Nao gosto 
<BLANKLINE> 
A ultima resposta 
http://www.google.com 
0 Gosto, 0 Nao gosto 
''' 

def test(): 
    import doctest 
    doctest.testmod() 

def a(): 
    u1 = User("[email protected]", "simples") 
    u2 = User("[email protected]", "complicada") 
    u2.askFriend(u1) 
    u1.recvRequest(u2) 
    u1.confirmFriend(u2) 
    p1 = Post(u1, "O ultimo post", "http://www.wikipedia.org") 
    p2 = Post(u2, "A ultima resposta", "http://www.google.com") 
    c = Comments() 
    c.add(p1) 
    c.add(p2) 
    f3 = c.search(text="post") 
    print(f3) 

import string 

class User: 

    def __init__(self,email,passwd): 
     self.email = email 
     self.passwd = passwd 
     self.name = None 
     self.year = None 
     self.active = True 
     self.recv = [] 
     self.conf = [] 
     self.setPassword(self.passwd) 

    def __str__(self): 
     if self.name == None and self.active == True: 
      return str(self.email) + ':' + 'ativa' 

     elif self.name != None and self.active == True: 
      return str(self.name) + ':' + str(self.email) + ':' + 'ativa' 

     elif self.name != None and self.active == False: 
      return str(self.name) + ':' + str(self.email) + ':' + 'inativa' 

     else: 
      return str(self.email) + ':' + 'inativa' 

    def getEmail(self): 
     return self.email 

    def setPassword(self,passwd): 
     abc = string.ascii_lowercase 
     cifra = abc[3:] + abc[:3] 
     dec = list(passwd) 
     passwdCif = "" 
     for i in dec: 
      cif = cifra[abc.find(i)] 
      passwdCif += cif 
     self.passwd = passwdCif 

    def getPassword(self): 
     return self.passwd 

    def setName(self,name): 
     self.name = name 

    def getName(self): 
     return self.name 

    def setBirth(self,year,month,day): 
     self.year = year 
     self.month = month 
     self.day = day 

    def getBirth(self): 
     if self.year == None: 
      return None 
     else: 
      return '(' + str(self.year) + ', ' + str(self.month) + ', ' + str(self.day) + ')' 

    def isActive(self): 
     if self.active == True: 
      return True 
     else: 
      return False 

    def setActive(self): 
     self.active = True 

    def setInactive(self): 
     self.active = False 

    def askFriend(self,u): 
     self.conf.append(u) 

    def recvRequest(self,u): 
     self.recv.append(u) 

    def confirmFriend(self,u): 
     if len(self.recv) == 0: 
      return None 
     else: 
      for i in self.recv: 
       if i == u: 
        self.recv.remove(i) 
        self.conf.append(i) 
       else: 
        return None 


    def isFriend(self,u): 
     if u in self.conf: 
      return True 
     elif self == u: 
      return True 
     else: 
      return False 

    def showPending(self): 
     if len(self.recv) == 0: 
      return None 
     else: 
      for i in self.recv: 
       print i 

    def showFriends(self): 
     if len(self.conf) == 0: 
      return None 
     else: 
      for i in self.conf: 
       print i 

class Post(): 
    def __init__(self,u,text='',link=None): 
     self.u = u 
     self.text = text 
     self.link = link 
     self.seg = None 
     self.ant = None 
     self.likeList = [] 
     self.dislikeList = [] 

    def __str__(self): 
     if self.link == None: 
      return str(self.text) + '\n' + str(len(self.likeList)) + ' Gosto, ' + str(len(self.dislikeList)) + ' Nao gosto' 
     else: 
      return str(self.text) + '\n' + str(self.link) + '\n' + str(len(self.likeList)) + ' Gosto, ' + str(len(self.dislikeList)) + ' Nao gosto' 

    def updateText(self,text): 
     self.text = text 

    def updateLink(self,link): 
     self.link = link 

    def like(self,u): 
     if (u in self.u.conf) or (u == self.u): 
      if u in self.dislikeList: 
       self.dislikeList.remove(u) 
       self.likeList.append(u) 
      elif u in self.likeList: 
       return None 
      else: 
       self.likeList.append(u) 
     else: 
      return None 

    def dislike(self,u): 
     if (u in self.u.conf) or (u == self.u): 
      if u in self.likeList: 
       self.likeList.remove(u) 
       self.dislikeList.append(u) 
      elif u in self.dislikeList: 
       return None 
      else: 
       self.dislikeList.append(u) 
     else: 
      return None 

class Comments(): 
    def __init__(self, u=None, text='', link=None): 
     self.u = u 
     self.text = text 
     self.link = link 
     self.topo = None 
     self.fim = None 

    def __str__(self): 
     actual = self.topo 
     s = '' 
     if actual == None: 
      return '' 
     while actual != None: 
      if actual.seg == None: 
       s += str(actual) 
       actual = actual.seg 
      elif actual.seg != None: 
       s += str(actual) + '\n' + '\n' 
       actual = actual.seg 
     return s 

    def add(self,comment): 
     if self.topo == None: 
      comment.ant = None 
      comment.seg = None 
      self.topo = comment 
      self.fim = comment 
     else: 
      comment.ant = None 
      comment.seg = self.topo 
      self.topo.ant = comment 
      self.topo = comment 

    def remove(self,comment): 
     actual = self.topo 
     if (self.topo == self.fim) and (self.topo == comment): 
      self.topo = None 
      self.fim = None 
      actual = None 
     while actual!=None: 
      if actual == comment: 
       if actual.ant == None: 
        self.topo = actual.seg 
        actual.seg.ant = None 
       elif actual.seg == None: 
        self.fim = actual.ant 
        actual.ant.seg = None 
       else: 
        actual.seg.ant = actual.ant 
        actual.ant.seg = actual.seg 
       break 
      else: 
       actual = actual.seg 

    def countLike(self): 
     count = 0 
     actual = self.topo 
     while actual != None: 
      if len(actual.likeList) >= 1: 
       count += 1 
       actual = actual.seg 
      else: 
       actual = actual.seg 
     return count 

    def showRecentComments(self,n): 
     count = 1 
     actual = self.topo 
     sC = '' 
     if actual == None: 
      return None 
     while actual != None: 
      if count < n: 
       if actual.seg == None: 
        sC += str(actual) 
        count += 1 
        actual = actual.seg 
       else: 
        sC += str(actual) + '\n' + '\n' 
        count += 1 
        actual = actual.seg 
      elif count == n: 
       sC += str(actual) 
       count += 1 
       actual = actual.seg 
      elif count > n: 
       break 
     print sC 

    def search(self, user=None, likes=None, dislikes=None, text=None): 
     result = [] 
     actual = self.topo 
     cR = Comments() 
     if actual == None: 
      return None 

     while actual != None: 
      if user != None: 
       if actual.u.email != user: 
        actual = actual.seg 
       elif actual.u.email == user: 
        result.append(actual) 
        actual = actual.seg 
      elif user == None: 
       break 
     actual = self.topo 

     while actual != None: 
      if likes != None: 
       if likes > len(actual.likeList): 
        actual = actual.seg 
       elif likes <= len(actual.likeList): 
        if actual in result: 
         actual = actual.seg 
        else: 
         result.append(actual) 
         actual = actual.seg 
      elif likes == None: 
       break 
     actual = self.topo 

     while actual != None: 
      if dislikes != None: 
       if dislikes > len(actual.dislikeList): 
        actual = actual.seg 
       elif dislikes <= len(actual.dislikeList): 
        if actual in result: 
         actual = actual.seg 
        else: 
         result.append(actual) 
         actual = actual.seg 
      elif dislikes == None: 
       break 
     actual = self.topo 

     while actual != None: 
      if text != None: 
       if text not in actual.text: 
        actual = actual.seg 
       elif text in actual.text: 
        if actual in result: 
         actual = actual.seg 
        else: 
         result.append(actual) 
         actual = actual.seg 
      elif text == None: 
       break 
     if len(result) != 0: 
      for i in result: 
       cR.add(i) 
     return cR 

А вот выход я получаю, используя одновременно() и тест():

>>> a() 
O ultimo post 
http://www.wikipedia.org 
0 Gosto, 0 Nao gosto 

A ultima resposta 
http://www.google.com 
0 Gosto, 0 Nao gosto 
>>> test() 
********************************************************************** 
File "__main__", line 22, in __main__ 
Failed example: 
    print(f3) 
Expected: 
    O ultimo post 
    http://www.wikipedia.org 
    0 Gosto, 0 Nao gosto 
    <BLANKLINE> 
    A ultima resposta 
    http://www.google.com 
    0 Gosto, 0 Nao gosto 
Got: 
    A ultima resposta 
    http://www.google.com 
    0 Gosto, 0 Nao gosto 
********************************************************************** 
1 items had failures: 
    1 of 16 in __main__ 
***Test Failed*** 1 failures. 
>>> 

Я также хотел бы извиниться за мой предыдущий плохо задаваемый вопрос.
Надеюсь, этот человек поможет мне и другим.

+0

Вероятно, вы должны сузить свой код до кратчайшей версии, все еще генерируя такое же поведение. Таким образом, вы, вероятно, найдете проблему самостоятельно. – marue

+0

Вы действительно должны взглянуть на это: http://stackoverflow.com/questions/how-to-ask. Хотя вы предоставляете много кода, вы оставляете нас в темноте об обстоятельствах, при которых вы его используете: по крайней мере, покажите ваш код для тестов. – marue

+0

Вопрос переписан. –

ответ

2

Существует одна очевидная разница между doctest и вашей функции: В то время как ваша функция а делает это:

# previous code 
c.add(p2) 
f3 = c.search(text="post") 
print(f3) 

ваш doctest делает это:

# previous code 
c.add(p2) 
f1 = c.search(user="[email protected]") 
print(f1) 
f2 = c.search(likes=1) 
print(f2) 
f3 = c.search(text='post') 
print(f3) 

Я не знаю, что именно там происходит , но, вероятно, вы должны написать свою функцию, чтобы сделать то же самое. Если результат по-прежнему отличается, что-то не так с doctest, иначе с вашим кодом.

редактировать:

Теперь я начинаю понимать, почему вы неприятности, и это deeeeeeep беда. Она начинается с этой линии прямо на верхней части функции поиска:

actual = self.topo 

Я думаю, вы не знаете, каким образом Python присваивает свойства. Позже в коде изменить фактическими, а затем присвоить self.topo фактических снова:

actual.seg = "somevalue" # sorry, i can't remember what you did" 
actual = self.topo 

Это вторая линия совершенно бессмысленно, так как фактические уже self.topo! Это не значение self.topo, но это self.topo.

Вместо того чтобы писать

actual.seg = "somevalue" 

вы могли бы просто написать

self.topo.seg = "somevalue" 

Обе линии делают то же самое. Поэтому, пока вы думали, что изменили какое-то независимое свойство actual, вы действительно изменили self.topo все время. И это означает, что actual не равен при каждом запуске функции, но всегда имеет значение, которое он имел при последнем запуске c.search.

Я только что видел, что вы делаете это в некоторых других функциях, а это значит, что вы изменяете состояние экземпляра ваших комментариев c каждый раз, когда вы вызываете такую ​​функцию. Это, конечно же, приводит к разным результатам для каждого теста.

Чтобы сделать это более понятным, вот пример со списком:

>>> a_list = ['one','two','three'] 
>>> b_list = a_list 
>>> b_list.pop() 
'three' 
>>> a_list 
['one', 'two'] 

Как вы видите: Allthoug я сделал поп элемент из b_list, он ушел из a_list, а также. Это связано с тем, что в заявлении b_list = a_list буквально означает, что b_list теперь совпадает с a_list.

Надеюсь, это поможет.

+0

Как я могу «очистить» параметры, не теряя в нем сообщений? Я пробовал несколько вещей внутри функции поиска, но теперь я не знаю, как это сделать. –

+0

К сожалению. Исправленный мой ответ, объяснение было неправильным. Возможно, у меня есть время, чтобы заглянуть в нее позже. – marue

+0

Объяснение было фактически неправильным, как вы сказали. Я сделал несколько дополнительных тестов, и текстовая часть не работает должным образом –

Смежные вопросы