Skip to content

Commit

Permalink
Merge pull request #19 from JordanWelsman/0.5-bugfixes
Browse files Browse the repository at this point in the history
All tests pass. Merging now.
  • Loading branch information
JordanWelsman committed Mar 8, 2023
2 parents e80ca95 + f242560 commit 2c82aca
Show file tree
Hide file tree
Showing 20 changed files with 602 additions and 28 deletions.
2 changes: 1 addition & 1 deletion jutl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Dunder attributes
__version__ = "0.5.1"
__version__ = "0.5.2"
__author__ = "Jordan Welsman"
__license__ = "MIT"
__copyright__ = "Copyright 2023 Jordan Welsman"
1 change: 1 addition & 0 deletions jutl/datastructures/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Import submodule files so
# classes and functions are usable at
# 'from jutl.datastructures import _' level.
from .queue import *
from .stack import *

# Only show functions specified in
Expand Down
198 changes: 198 additions & 0 deletions jutl/datastructures/queue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# Module imports
from __future__ import annotations
from typing import Any
from jutl.exceptions import EmptyQueueError, FullQueueError
from jutl.formatting import apply

# External class visibility
__all__ = ['Queue']


class Queue(object):
"""
Class which implements a
first-in-first-out queue object
with queue methods.
"""
def __init__(self, name: str = None, capacity: int = None) -> None:
"Initialization method."
self.name: str = name
self._queue : list = []
self._capacity: int = capacity

def __repr__(self) -> str:
"""
Tells the interpreter how
to represent this class.
"""
string = f"{self.__class__.__name__}("
if self.name is not None:
string += f"{self.name}"
if len(self._queue) > 0:
string += f", " if self.name is not None else ""
string += f"{len(self._queue)}"
if self._capacity is not None:
string += f"/" if len(self) > 0 else ", " if self.name is not None else ""
string += f"{self._capacity}"
string += ")"
return string

def __call__(self) -> list:
"""
Tells the interpreter what to
do when an object of this
class is called directly.
"""
return self._queue

def __len__(self) -> int:
"""
Tells the interpreter what to
consider this class' length.
"""
return len(self._queue)

def __iter__(self) -> iter:
"""
Tells the interpreter what to
iterate over when iterator methods
are called on this class.
"""
raise NotImplementedError("Queues are not iterable.")

def __eq__(self, other) -> bool:
"""
Tells the interpreter how this class
handles equal operators.
"""
return self._queue == other._queue

def __ne__(self, other) -> bool:
"""
Tells the interpreter how this class
handles not equal operators.
"""
return self._queue != other._queue

def __gt__(self, other) -> bool:
"""
Tells the interpreter how this class
handles greater than operators.
"""
return len(self) > len(other)

def __ge__(self, other) -> bool:
"""
Tells the interpreter how this class
handles greater or equal operators.
"""
return len(self) >= len(other)

def __lt__(self, other) -> bool:
"""
Tells the interpreter how this class
handles less than operators.
"""
return len(self) < len(other)

def __le__(self, other) -> bool:
"""
Tells the interpreter how this class
handles less than or equal operators.
"""
return len(self) <= len(other)

def __add__(self, other) -> list:
"""
Tells the interpreter how to sum these objects.
"""
return self.extend(other=other)


def enqueue(self, *args: object) -> None:
"""
Adds an item to the back of the queue.
"""
for item in args:
if self.is_full:
raise FullQueueError("The queue is full.")
else:
self._queue.append(item)


def dequeue(self) -> Any:
"""
Removes the item from at front of the queue.
"""
if self.is_empty:
raise EmptyQueueError("The queue is empty.")
else:
dequeued = self.front
self._queue.pop(0)
return dequeued


def clear(self) -> None:
"""
Clears the queue.
"""
self._queue.clear()


@property
def front(self) -> Any:
"""
Returns the item at the front of
the queue without dequeueing it.
"""
if self.is_empty:
raise EmptyQueueError("The queue is empty.")
else:
return self._queue[0]


@property
def rear(self) -> Any:
"""
Returns the item at the rear of
the queue without dequeueing it.
"""
if self.is_empty:
raise EmptyQueueError("The queue is empty.")
else:
return self._queue[-1]


@property
def is_empty(self) -> bool:
"""
Returns whether the queue is empty.
"""
if len(self) <= 0:
return True
else:
return False


@property
def is_full(self) -> bool:
"""
Returns whether the queue is full.
"""
if self._capacity is not None:
if len(self) >= self._capacity:
return True
else:
return False
else:
return False


def extend(self, other: Queue) -> Queue:
"""
Extends this queue with another queue.
"""
for item in other._queue:
self.enqueue(item)
return self

85 changes: 71 additions & 14 deletions jutl/datastructures/stack.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Module imports
from __future__ import annotations
from typing import Any
from jutl.exceptions import EmptyStackError, FullStackError
from jutl.formatting import apply

# External class visibility
Expand All @@ -9,13 +11,14 @@
class Stack(object):
"""
Class which implements a
first-in; first-out stack object
first-in-last-out stack object
with stack methods.
"""
def __init__(self, name: str = None):
def __init__(self, name: str = None, capacity: int = None) -> None:
"Initialization method."
self.name = name
self._stack = []
self.name: str = name
self._stack: list = []
self._capacity: int = capacity

def __repr__(self) -> str:
"""
Expand Down Expand Up @@ -106,29 +109,83 @@ def __add__(self, other) -> list:
return self.extend(other=other)


def push(self, *args: object):
def push(self, *args: object) -> None:
"""
Pushes an item onto the stack.
"""
for item in args:
self._stack.append(item)
if self.is_full:
raise FullStackError("The stack is full.")
else:
self._stack.append(item)


def pop(self) -> object:
def pop(self) -> Any:
"""
Removes the last added item from the stack.
Removes the item at the top of the stack.
"""
popped = self.top
self._stack.remove(self.top)
return popped
if self.is_empty:
raise EmptyStackError("The stack is empty.")
else:
popped = self.top
self._stack.pop(-1)
return popped


def clear(self) -> None:
"""
Clears the stack.
"""
self._stack.clear()


@property
def top(self) -> object:
if len(self) > 0:
def top(self) -> Any:
"""
Returns the item at the top of
the stack without popping it.
"""
if self.is_empty:
raise EmptyStackError("The stack is empty.")
else:
return self._stack[-1]


@property
def bottom(self) -> Any:
"""
Returns the item at the bottom
of the stack without popping it.
"""
if self.is_empty:
raise EmptyStackError("The stack is empty.")
else:
return self._stack[0]


@property
def is_empty(self) -> bool:
"""
Returns whether the stack is empty.
"""
if len(self) == 0:
return True
else:
return False


@property
def is_full(self) -> bool:
"""
Returns whether the stack is full.
"""
if self._capacity is not None:
if len(self) >= self._capacity:
return True
else:
return False
else:
raise IndexError("Stack is empty.")
return False


def extend(self, other: Stack) -> Stack:
Expand Down
6 changes: 5 additions & 1 deletion jutl/exceptions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
# classes and functions are usable at
# 'from jutl.exceptions import _' level.
from .emptypipeline import *
from .emptyqueue import *
from .emptystack import *
from .fullqueue import *
from .fullstack import *
from .invalidformatting import *
from .missinginput import *

# Only show functions specified in
# submodule files to the outside world.
__all__ = emptypipeline.__all__, invalidformatting.__all__, missinginput.__all__
__all__ = emptypipeline.__all__, emptyqueue.__all__, emptystack.__all__, fullqueue.__all__, fullstack.__all__, invalidformatting.__all__, missinginput.__all__
6 changes: 3 additions & 3 deletions jutl/exceptions/emptypipeline.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Module imports
from .jutlexception import JutilsException

# External class visibility
__all__ = ['EmptyPipelineError']

class EmptyPipelineError(Exception):
def __init__(self, message):
self.message = message
class EmptyPipelineError(JutilsException):
pass
8 changes: 8 additions & 0 deletions jutl/exceptions/emptyqueue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Module imports
from .jutlexception import JutilsException

# External class visibility
__all__ = ['EmptyQueueError']

class EmptyQueueError(JutilsException):
pass
8 changes: 8 additions & 0 deletions jutl/exceptions/emptystack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Module imports
from .jutlexception import JutilsException

# External class visibility
__all__ = ['EmptyStackError']

class EmptyStackError(JutilsException):
pass
8 changes: 8 additions & 0 deletions jutl/exceptions/fullqueue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Module imports
from .jutlexception import JutilsException

# External class visibility
__all__ = ['FullQueueError']

class FullQueueError(JutilsException):
pass

0 comments on commit 2c82aca

Please sign in to comment.