#extra while loop condition because it's possible that in the process of deletion we changed the next node to be none and
    # it naively changes it to none
    while currentNode is not None and currentNode.next is not None:
        searchNode = currentNode
        while searchNode.next is not None:
            if searchNode.next.data == currentNode.data:
                searchNode.next = searchNode.next.next
            else:
                searchNode = searchNode.next
        currentNode = currentNode.next


print("===========Test 1==========")
head = Node(4)
head.createLinkedListFromList([5, 6, 4])
head.printLinkedList()
removeDup(head)
print("Remove Duplicates")
head.printLinkedList()

print("===========Test 2==========")
head2 = Node(1)
head2.createLinkedListFromList([1, 1, 1, 1, 2, 2, 3, 3])
head2.printLinkedList()
print("Remove Duplicates")
removeDup(head2)
head2.printLinkedList()

print("===========Test 3==========")
head3 = Node(4)
head3.createLinkedListFromList([5, 6, 4])
#much better version
#remember that deleting a node is just rearranging its next pointer to skip the one we want to delete
#also I don't have to shift the whole linked list
#finally and most importantly, look at the linked list as a whole. Realize that what we were trying to achieve didn't require shifting the whole array
# ex. 1->2->3->4->5 and we want to delete 3 then we would get 1->2->4->5
# from this example we should realize that the 4 is in the old place of the three!
def better_del_middle_node(mNode):
    if mNode is None or mNode.data == None:
        return False

    mNode.data = mNode.next.data
    mNode.next = mNode.next.next
    return True


testLinkedlist = Node(1)
testLinkedlist.createLinkedListFromList([2, 3, 4, 5])
targetNode = getNode(testLinkedlist, 3)

better_del_middle_node(targetNode)

testLinkedlist.printLinkedList()

testLinkedlist2 = Node(1)
testLinkedlist2.createLinkedListFromList([2, 3, 9, 5])
targetNode2 = getNode(testLinkedlist2, 9)

better_del_middle_node(targetNode2)

testLinkedlist2.printLinkedList()