diff --git a/apqueue.py b/apqueue.py
new file mode 100644
index 0000000000000000000000000000000000000000..a1343c3aaf3878cd99d521f26eb4b6e7336309e0
--- /dev/null
+++ b/apqueue.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`apqueue` module
+
+:author: `FIL - Faculté des Sciences et Technologies -
+          Univ. Lille <http://portail.fil.univ-lille1.fr>`_
+
+:date: 2015, september
+:last revision: 2024, March
+
+A module for queue data structure.
+
+:Provides:
+
+* class ApQueue
+
+and methods
+
+* `enqueue`
+* `dequeue`
+* `is_empty`
+"""
+from typing import TypeVar
+T = TypeVar('T')
+
+class ApQueueEmptyError(Exception):
+    """
+    Exception for empty stacks
+    """
+    def __init__(self, msg):
+        self.message = msg
+
+
+class ApQueue():
+    """
+    $$$ ap_queue = ApQueue()
+    $$$ ap_queue.is_empty()
+    True
+    $$$ ap_queue.enqueue(1)
+    $$$ ap_queue.is_empty()
+    False
+    $$$ ap_queue.enqueue(2)
+    $$$ str(ap_queue)
+    '→2|1→'
+    $$$ ap_queue.dequeue()
+    1
+    $$$ ap_queue.dequeue()
+    2
+    $$$ ap_queue.is_empty()
+    True
+    $$e ap_queue.dequeue()
+    ApQueueEmptyError
+    """
+    ARROW = chr(0x2192)
+
+    def __init__(self):
+        """
+        build  a new empty queue
+        precondition: none
+        """
+        self.__content = []
+
+    def enqueue(self, elt: T):
+        """
+        insert an element at the begining of the queue
+        precondition: none
+        """
+        self.__content.insert(0, elt)
+
+    def dequeue(self) -> T:
+        """
+        return the element on top of self
+        Side effect: self contains an element less
+        precondition: self must be non empty
+        """
+        if len(self.__content) > 0:
+            res = self.__content.pop()
+        else:
+            raise ApQueueEmptyError('empty queue, nothing to dequeue')
+        return res
+
+    def is_empty(self) -> bool:
+        """
+        return:
+          * ``True`` if s is empty
+          * ``False`` otherwise
+        precondition: none
+        """
+        return self.__content == []
+
+    def __str__(self) -> str:
+        """
+        return the string representation of this queue.
+        """
+        return ApQueue.ARROW + \
+            "|".join(str(el) for el in self.__content) + \
+            ApQueue.ARROW
+
+    def __len__(self) -> int:
+        """
+        return the length of this queue
+        """
+        return len(self.__content)
+
+if __name__ == '__main__':
+    import apl1test
+    apl1test.testmod('apqueue.py')
diff --git a/apstack.py b/apstack.py
new file mode 100644
index 0000000000000000000000000000000000000000..16b68409a76d56573cb2e28f06ffcd1305947d0c
--- /dev/null
+++ b/apstack.py
@@ -0,0 +1,132 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`stack` module
+
+:author: `FIL - Faculté des Sciences et Technologies - 
+          Univ. Lille <http://portail.fil.univ-lille1.fr>`_
+
+:date: 2015, september
+:last revision: 2017, october
+
+A module for stack data structure.
+
+:Provides:
+
+* class ApStack
+
+and methods
+
+* `push`
+* `pop`
+* `top`
+* `is_empty`
+
+:Examples:
+"""
+from typing import TypeVar
+T = TypeVar('T')
+
+class ApStackEmptyError(Exception):
+    """
+    Exception for empty stacks
+    """
+    def __init__(self, msg):
+        self.message = msg
+
+
+class ApStack():
+    """
+    $$$ stak = ApStack()
+    $$$ stak.is_empty()
+    True
+    $$$ stak.push(1)
+    $$$ stak.is_empty()
+    False
+    $$$ stak.push(2)
+    $$$ stak.top()
+    2
+    $$$ stak.pop()
+    2
+    $$$ stak.top()
+    1
+    $$$ stak.pop()
+    1
+    $$$ stak.is_empty()
+    True
+    $$e stak.pop()
+    ApStackEmptyError
+    """
+    
+    def __init__(self):
+        """
+        build a new empty stack
+        précondition : none
+        """
+        self.__content = []
+        
+    def push(self, el: T):
+        """
+        add el on top of the stack.
+        précondition : none
+        """
+        self.__content.append(el)
+
+    def pop(self) -> T:
+        """
+        return the element on top of self
+        
+        Side effect: self contains an element less
+        
+        précondition : self must be non empty
+        """
+        if len(self.__content) == 0:
+            raise ApStackEmptyError('empty stack, nothing to pop')
+        return self.__content.pop()
+
+    def top(self) -> T:
+        """
+        return the element on top of self without removing it
+        
+        précondition : self must be non empty
+        """
+        if len(self.__content) == 0:
+            raise ApStackEmptyError('empty stack, nothing to pop')
+        return self.__content[-1]
+
+    def is_empty(self) -> bool:
+        """
+        return:
+           * ``True`` if s is empty
+           * ``False`` otherwise
+                précondition : none
+        """
+        return self.__content == []
+
+    def __str__(self) -> str:
+        """
+        return a stack representation 
+        """
+        mlen = 1
+        if not self.is_empty():
+            mlen = max(len(str(el)) for el in self.__content)
+        res = []
+        for el in self.__content:
+            pad = mlen - len(str(el))
+            left = pad // 2
+            right = pad - left
+            res.insert(0, "|" + " " * left + str(el) + " " * right + "|")
+        res.append("+" + "-" * mlen + "+")
+        return "\n".join(res)
+
+    def __len__(self) -> int:
+        """
+        Return the stack length.
+        """
+        return len(self.__content)
+
+
+if (__name__ == '__main__'):
+    import apl1test
+    apl1test.testmod('apstack.py')