如何在Python 3.6中将__str __()和__repr __()用于单链表?

时间:2018-05-27 08:08:42

标签: python singly-linked-list

大家。我需要解决一些问题,我希望能帮助你做些什么。所以,我有关于Singly Linked Lists的Python 3.6任务。到目前为止,我的大多数用于追加/前置,从前面和后面移除以及完全删除节点的测试用例都很顺利。但是,我的一些测试用例存在一些问题。问题围绕着我使用__str__(self)__repr__(self)函数。

下面是我提供的代码。 (编辑:我只留下了需要修复的测试代码。所有其他测试用例都很好):

class LinkedList(object):
    class Node(object):
        # pylint: disable=too-few-public-methods
        ''' no need for get or set, we only access the values inside the
        LinkedList class. and really: never have setters. '''

        def __init__(self, value, next = None):
            self.value = value
            self.next = next

        def __repr__(self):
            return repr(self.value)

        def __str__(self):
            return str(self.value) + "; "

    def __init__(self, initial=None):
        self.front = self.back = self.current = None

    def empty(self):
        return self.front == self.back == None

    def __iter__(self):
        self.current = self.front
        return self

    def __str__(self):
        string = 'List[ '
        curr_node = self.front

        while curr_node != None:
            string += str(curr_node)
            curr_node = curr_node.next()
        string += ']'

        return string

    def __repr__(self):
        nodes = []
        curr = self.front

        while curr:
            nodes.append(repr(curr))
            curr = curr.next
        return '[' +', '.join(nodes) + ']'

    def __next__(self):
        if self.current:
            tmp = self.current.value
            self.current = self.current.next
            return tmp
        else:
            raise StopIteration()

    def push_front(self, value):
        x = self.Node(value, self.front)

        if self.empty():
            self.front = self.back = x
        else:
            self.front = x

#you need to(at least) implement the following three methods

    def pop_front(self):      
        if self.empty():
            raise RuntimeError("Empty List")
        x = self.front.value
        self.front = self.front.next
        if not self.front:
            self.back = None
        return x

    def push_back(self, value):
        if self.empty():
            self.front = self.back = self.Node(value, None)
        else:
            x = self.Node(value, None)
            self.back.next = x
            self.back = x

    def pop_back(self):
        if self.empty():
            raise RuntimeError("Empty List")
        y = self.back.value
        if not self.front.next:
            self.front = self.back = None
        else:
            x = self.front
            while x.next is not self.back:
                x = x.next
            x.next = None
            self.back = x
        return y

class TestInitialization(unittest.TestCase):
    def test(self):
        linked_list = LinkedList(("one", 2, 3.141592))
        self.assertEqual(linked_list.pop_back(), "one")
        self.assertEqual(linked_list.pop_back(), 2)
        self.assertEqual(linked_list.pop_back(), 3.141592)

class TestStr(unittest.TestCase):
    def test(self):
        linked_list = LinkedList((1, 2, 3))
        self.assertEqual(linked_list.__str__(), '1, 2, 3')

class TestRepr(unittest.TestCase):
    def test(self):
        linked_list = LinkedList((1, 2, 3))
        self.assertEqual(linked_list.__repr__(), 'LinkedList((1, 2, 3))')


if '__main__' == __name__:
    unittest.main()

现在,随着代码的出现,我将提供我在控制台中遇到的问题:

1) Error at TestInitialization. RuntimeError("Empty List")
2) Failure at TestRepr. AssertionError: '[]' != 'LinkedList((1, 2, 3))'
- []
+ LinkedList((1, 2, 3))
3) Failure at TestStr. AssertionError: 'List[ ]' != '1, 2, 3'
- List[ ]
+ 1, 2, 3

我讨厌成为一个麻烦,但我想请求任何建议或提示,以帮助我纠正我的两个失败,并防止一个错误。那么,我有什么方法可以尝试这样做吗?我将不胜感激。

1 个答案:

答案 0 :(得分:0)

要使TestInitialization正常工作,你的init函数将提供

的链接
3.141592 -> 2 -> "one"

如果使用("one", 2, 3.141592)初始化(...) - 您可以看到通过检查测试用例,它从后面弹出,您需要匹配提供的值。 你可以通过在init中将每一个推到前面来解决它:

def __init__(self, initial=None):
    self.front = self.back = self.current = None
    for i in initial:
        self.push_front(i)  

# I find this counterintuitive, blame your teacher.

要使TestStr正常工作,请使用(1,2,3)启动它,并且必须提供'(1,2,3)'的输出 - 由于__init__现在的工作方式,您需要收集所有内容将节点放入列表中,并将其反向连接(或从后到前通过列表):

def __str__(self):
    elem = []
    curr_node = self.front

    while curr_node != None:
        elem.append(str(curr_node.value)) # collect node values, not the "7; " str  
        curr_node = curr_node.next()
    # join reversed list 
    return ', '.join(elem[::-1]) # need to reverse the list due to how __init__ works

要使TestRepr有效,您需要__str__输出,并在'LinkedList((''))'

前缀/后缀
def __repr__(self):
    return 'LinkedList(('+ str(self) + '))'

我无法像NameError: name 'unittest' is not defined一样对自己进行测试。