Как использовать __str __ () и __repr __ () для односвязного списка в Python 3.6? - PullRequest
0 голосов
/ 27 мая 2018

все.У меня есть небольшая проблема, с которой мне нужно разобраться, и я надеялся на помощь в том, что делать.Итак, у меня есть задание 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 голосов
/ 27 мая 2018

Чтобы заставить TestInitialization работать, ваша функция инициализации должна обеспечить связывание

3.141592 -> 2 -> "one"

, если init (...) редактировалось с ("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.

...