diff --git a/projects/Data_structure/README.md b/projects/Data_structure/README.md
new file mode 100644
index 000000000..81e2b0021
--- /dev/null
+++ b/projects/Data_structure/README.md
@@ -0,0 +1,15 @@
+# Data Structures
+
+### Types of data structures available
+- **Doubly LinkedList**
+
+
+
+### Doubly LinkedList Methods
+ Push
+ Pop
+ Get_Previous
+ Get_item
+ Get_list
+ Updata
+ Delete
diff --git a/projects/Data_structure/doubly_linkedlist.py b/projects/Data_structure/doubly_linkedlist.py
new file mode 100644
index 000000000..959831a05
--- /dev/null
+++ b/projects/Data_structure/doubly_linkedlist.py
@@ -0,0 +1,221 @@
+"""
+A queue system based on a "Doubly Linked-list" principle
+"""
+import warnings
+
+
+class LinkedError(Exception):
+ pass
+
+
+class NegativeNumber(LinkedError):
+ pass
+
+
+class EmptyLinked(LinkedError):
+ pass
+
+
+class EmptyLinkedWarnings(RuntimeWarning):
+ pass
+
+
+class DoublyLinkedNode:
+ """Queue with previous"""
+
+
+ def __init__(self, data=None):
+ self.data = data
+ self.next = None
+ self.previous = None
+
+
+class DoublyLinkedList:
+ """Doubly Linked-list"""
+
+ def __init__(self):
+ self.head = None
+ self.length = -1
+
+
+ def __len__(self):
+ return self.length + 1
+
+
+ def is_empty(self):
+ """
+ Check that the list is empty
+ """
+ return True if self.head is None else False
+
+
+ def push(self, data):
+ """
+ Push item inside the queue
+ """
+ new_node = DoublyLinkedNode(data)
+ if self.is_empty():
+ self.head = new_node
+ self.length += 1
+ return new_node
+ current_node = self.head
+
+ while current_node.next is not None:
+ current_node = current_node.next
+ new_node.previous = current_node
+ current_node.next = new_node
+ self.length += 1
+ return current_node
+
+
+ def valid_number(self, number):
+ """
+ Check that number is valid or not.
+ """
+ try:
+ if number < 0 and number.is_integar():
+ raise ValueError("Previous is None.!")
+ except (TypeError, ValueError):
+ raise NegativeNumber(
+ (
+ """That linked-list is an
+ empty and not support negative number."""
+ )
+ )
+ if number > self.length:
+ raise EmptyLinked("That number greater than linked length")
+ return number
+
+
+ def pop(self):
+ """
+ Remove the following item from the queue
+ """
+ try:
+
+ self.length = self.valid_number(self.length)
+ temp = self.head.data
+ self.head = self.head.next
+ self.length -= 1
+
+ except EmptyLinked:
+ warnings.warn(
+ "That Linked is Empty please add items first",
+ EmptyLinkedWarnings,
+ stacklevel=3,
+ )
+ return temp
+
+
+ def get_item(self, index):
+ """
+ Get the following item from the queue
+ Note get is just get
+ """
+ current = 0
+ data = self.head
+ try:
+ if index < 0:
+ raise ValueError('sdfsdf')
+ index = self.valid_number(index)
+ except (NegativeNumber, ValueError):
+ warnings.warn("""The element before the
+ first element cannot be displayed
+ """,
+ EmptyLinkedWarnings,
+ stacklevel=3
+ )
+ index = 0
+ while index > current:
+ data = data.next
+ current += 1
+ return data.data
+
+
+ def get_list(self):
+ """
+ Get all items from the queue
+ """
+ elements = []
+ current_node = self.head
+ while current_node is not None:
+ elements.append(current_node.data)
+ current_node = current_node.next
+ return elements
+
+
+ def get_previous(self, index=None):
+ """
+ Get the item that accepted the current element of the queue
+ """
+ if index is None:
+ return self.head.previous
+ index -= 1
+ return self.get_item(index)
+
+
+ def delete(self, index):
+ current_node = self.head
+ current_index = 0
+ while current_index < index:
+ current_node = current_node.next
+ current_index += 1
+ current_node.previous.next = current_node.next
+ del current_node
+
+
+ def update(self, new_value, index: int):
+ current_index = 0
+ current_node = self.head
+ while current_index < index:
+ current_node = current_node.next
+ current_index += 1
+ current_node.data = new_value
+ return current_node.data
+
+
+# Remove commit for Testing
+# # -------------------------
+# my_list = DoublyLinkedList()
+# my_list.push(1)
+# my_list.push(2)
+# my_list.push(3)
+# my_list.push(4)
+
+# print(my_list.get_previous(0))
+# print('=' * 25, 'Length', '=' * 25)
+# length = len(my_list)
+# assert length == 4, "Error Test Length Interrelated List"
+# print(length)
+#
+# print('=' * 25, 'Pop', '=' * 25)
+# item = my_list.pop()
+# assert item == 1, """
+# Test error Take the next item out of the queue doubly linked-list
+# """
+# print(item)
+#
+# print('=' * 25, 'Show Items', '=' * 25)
+# elements_list = my_list.get_list()
+# assert len(elements_list) == 3, "Test error Create a list of items"
+# print(elements_list)
+#
+# print('=' * 25, 'Update Value', '=' * 25)
+# new = my_list.update(10, 1)
+# print(new)
+#
+# print('=' * 25, 'Get updated value', '=' * 25)
+# new = my_list.get_item(1)
+# assert new == 10, "Error Test Update Specific Node Value"
+# print(new)
+#
+# print('=' * 25, 'Show Items', '=' * 25)
+# print(my_list.get_list())
+#
+# print('=' * 25, 'Delete', '=' * 25)
+# my_list.delete(1)
+#
+# print('=' * 25, 'Show Items', '=' * 25)
+# length = len(my_list.get_list())
+# assert length == 2, "Error Test Delete Specific Node"
+# print(my_list.get_list())