class LinkedListNode:
    """
    Node to be used in linked list

    === Attributes ===
    value - data this LinkedListNode represents
    next_ - successor to this LinkedListNode
    """
    value: object
    next_: 'LinkedListNode'

    def __init__(self, value: object, next_:'LinkedListNode'=None)->None:
        """
        Create LinkedListNode self with data value and successor next_.
        """
        self.value, self.next_ = value, next_


class LinkedList:
    """
    Collection of LinkedListNodes
    === Attributes ==
    front - first node of this LinkedList
    back - last node of this LinkedList
    size - number of nodes in this LinkedList a non-negative integer
    """
    front: LinkedListNode
    back: LinkedListNode
    size: int
    def __init__(self) -> None:
        """
        Create an empty linked list.
        """
        self.front, self.back, self.size = None, None, 0

    def prepend(self, value):
        if self.size==0:
            n1=LinkedListNode(value, None)
            self.front=n1
            self.back=n1
            self.size+=1
        else:
            n2=LinkedListNode(value,self.front)
            self.front=n2
            self.size+=1


    def append(self, value):
        if self.size==0:
            n1=LinkedListNode(value, None)
            self.front=n1
            self.back=n1
            self.size+=1
        else:
            n2=LinkedListNode(value,None)
            self.back.next_ = n2
            self.back=n2
            self.size+=1

    def __str__(self):
        i=self.front
        s=''
        while not i==None:
            s += " {} ->".format(i.value)
            i=i.next_
        return s+ "|"

LL = LinkedList()
print(LL)
LL.prepend(4)
print(LL)
LL.prepend(5)
print(LL)
LL.prepend(6)
print(LL)
print(LL)
LL.append(1)
print(LL)
LL.append(2)
print(LL)
LL.append(3)
print(LL)
