Singly Linked List

class Node:

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

class LinkedList:

    def __init__(self,value):
        new_node = Node(value)
        self.head = new_node
        self.tail = new_node
        self.length = 1

    def printlist(self):
        temp = self.head
        for _ in range(self.length):
            print(temp.value,"-> ", end='')
            temp=temp.next

    def append(self,value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node
        self.length+=1
        return True

    def pop(self):
        temp = self.head
        prev = self.head
        if temp:
            while temp.next:
                prev=temp
                temp = temp.next
            prev.next = None
            self.tail = prev
            self.length-=1
            if self.length==0:
                self.head=None
                self.tail=None
        else:
            return False

    def prepend(self,value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
            self.tail = new_node
        else:
            new_node.next = self.head
            self.head = new_node
        self.length+=1
        return True

    def pop_first(self):
        if self.head is not None:
            self.head = self.head.next
        else:
            self.head = None
            self.tail = None
        self.length-=1
        return True

    def get(self, index):
        if index>=self.length or index<0:
            return None
        temp = self.head
        for _ in range(index):
            temp = temp.next
        return temp

    def insert(self, index, value):
        if index<0 or index>self.length:
            return None
        if index == 0:
            self.prepend(value)
        if index == self.length:
            self.append(value)
        else:    
            new_node = Node(value)
            temp = self.get(index-1)
            new_node.next = temp.next
            temp.next=new_node
            self.length+=1
        return True

    def set_value(self,index, value):
        temp = self.get(index)
        if temp is not None:
            temp.value = value
        else:
            return None