Skip to content

Commit

Permalink
refactor: Arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
warmachine028 committed Jul 12, 2023
1 parent c4a924b commit e55320f
Show file tree
Hide file tree
Showing 25 changed files with 153 additions and 105 deletions.
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
updated: Sunday, 11th July 2023
updated: Wednesday, 12th July 2023

<div align=center>
<a href="https://github.com/warmachine028/datastax">
Expand Down Expand Up @@ -31,11 +31,10 @@

## What's New?

- Refactored linkedlists -> Lists
- Refactored arrays -> Arrays
- Refactored private_lists -> AbstractLists
- Refactored AbstractLists by converting all items to AbstractClass to prevent direct initialization.
- Module Conventions converted to uppercase CamelCase from lowercase snake_case
- Refactored Array Contents
- Added AbstractArray SubModule to abstract print logic
- Added more test cases for Queues
- Type Checked Arrays and Lists with mypy

## Table of Contents

Expand Down Expand Up @@ -202,4 +201,3 @@ pip install datastax
- Better TestCases for Huffman Tree
- Better TestCases for Segment Trees
- Test Cases for Fibonacci Tree
- Refactoring Arrays SubPackage
10 changes: 5 additions & 5 deletions datastax/Arrays/AbstractArrays/Array.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
from abc import ABC, abstractmethod
from abc import ABC as AbstractClass, abstractmethod
from sys import maxsize
from typing import Any


class Array:
class Array(AbstractClass):
_capacity = 0
_array = []
_array: list[Any] = []

@property
def capacity(self):
def capacity(self) -> int:
return self._capacity

@property
def array(self) -> list[Any]:
return self._array

def set_capacity(self, capacity: int):
def set_capacity(self, capacity: int | None) -> None:
if capacity is None:
self._capacity = maxsize
return
Expand Down
18 changes: 9 additions & 9 deletions datastax/Arrays/AbstractArrays/Queue.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from abc import ABC as AbstractClass, abstractmethod
from typing import Any, Optional
from typing import Any
from datastax.Utils import Commons
from datastax.Arrays.AbstractArrays import Array
from datastax.Arrays.AbstractArrays.Array import Array


class Queue(Array, AbstractClass):
Expand All @@ -23,7 +23,7 @@ def front(self) -> int:

@property
def array(self) -> list[Any]:
return self._array[self._front:self._rear]
return self._array[self.front:self.rear] if self._array else []

@property
def rear(self) -> int:
Expand All @@ -36,28 +36,28 @@ def __str__(self):
'└───────────────────┘'
padding = 4
max_breadth = max(
len((Commons.repr(item))) for item in self._array
len((Commons.repr(item))) for item in self.array
) + padding
middle_part = 'FRONT -> │'
upper_part = f"\n{' ' * (len(middle_part) - 1)}┌"
lower_part = f"{' ' * (len(middle_part) - 1)}└"
if self._front: # Representing Garbage Values with '╳'
for _ in self._array[:self._front]:
if self.front: # Representing Garbage Values with '╳'
for _ in self._array[:self.front]:
middle_part += f"{'╳'.center(max_breadth)}│"
upper_part += f"{'─' * max_breadth}┬"
lower_part += f"{'─' * max_breadth}┴"
upper_part = upper_part[:-1] + '╥'
middle_part = middle_part[:-1] + '║'
lower_part = lower_part[:-1] + '╨'
for item in self._array[self._front:]:
for item in self._array[self.front:]:
middle_part += f'{Commons.repr(item).center(max_breadth)}│'
upper_part += f"{'─' * max_breadth}┬"
lower_part += f"{'─' * max_breadth}┴"
upper_part = f"{upper_part[:-1]}"
lower_part = f"{lower_part[:-1]}"
upper_part += f"{'╖' if len(self._array) == self._front else '┐'}\n"
upper_part += f"{'╖' if len(self._array) == self.front else '┐'}\n"
middle_part += ' <- REAR\n'
lower_part += f"{'╜' if len(self._array) == self._front else '┘'}\n"
lower_part += f"{'╜' if len(self._array) == self.front else '┘'}\n"
return upper_part + middle_part + lower_part

@abstractmethod
Expand Down
8 changes: 6 additions & 2 deletions datastax/Arrays/AbstractArrays/Stack.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
from abc import ABC as AbstractClass, abstractmethod
from datastax.Utils import Commons
from datastax.Arrays.AbstractArrays import Array
from typing import Any
from datastax.Utils import Commons
from datastax.Arrays.AbstractArrays.Array import Array


class Stack(Array, AbstractClass):
def append(self, data: Any) -> None:
raise NotImplementedError

@property
def array(self) -> list[Any]:
return self._array

def insert(self, data: Any) -> None:
raise NotImplementedError

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Priority Queue implementation using Lists (Pseudo Arrays)
from typing import Any, Callable
from typing import Any, Callable, Optional

from datastax.Arrays.Queue import Queue
from datastax.errors import OverFlowError, UnderFlowError


class PriorityQueue(Queue):
def __init__(self, *, capacity: int = None,
custom_comparator: Callable = None):
comparator: Callable

def __init__(self, *, capacity: Optional[int] = None,
custom_comparator: Optional[Callable] = None):
super().__init__(capacity=capacity)
self.comparator = custom_comparator or max

Expand Down
24 changes: 11 additions & 13 deletions datastax/Arrays/Queue.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
# Queue Implementation using Lists (Pseudo Arrays)
from typing import Any
from typing import Any, Optional

from datastax.errors import OverFlowError, UnderFlowError
from datastax.Arrays.AbstractArrays import Queue as AbstractQueue


class Queue(AbstractQueue):
def __init__(self, *, capacity: int = None):
def __init__(self, *, capacity: Optional[int] = None):
self._array = []
self.set_capacity(capacity)

def is_full(self) -> bool:
return len(self._array) == self._capacity
return len(self.array) == self.capacity

def is_empty(self) -> bool:
return not self._array
return not self.array

def enqueue(self, item: Any) -> int:
if self.is_full():
Expand All @@ -24,19 +25,16 @@ def enqueue(self, item: Any) -> int:
return 0

def dequeue(self) -> Any:
if self.is_empty() or self._front >= self._rear:
if self.is_empty() or self.front >= self.rear:
raise UnderFlowError(self)
deleted_item = self._array[self._front]
deleted_item = self._array[self.front]
self._front += 1
return deleted_item

def __len__(self):
return len(self.array)

def peek(self) -> Any:
if self.is_empty() or self._front >= self._rear:
return "QUEUE EMPTY"
return self._array[self._front]

x = Queue()
x.enqueue(10)
x.enqueue(20)
x.dequeue()
print(x)
return self._array[self.front]
22 changes: 9 additions & 13 deletions datastax/Arrays/Stack.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,35 @@
# Stack Implementation using Lists (Pseudo Arrays)
import math
from typing import Any
from typing import Any, Optional

from datastax.errors import UnderFlowError, OverFlowError
from datastax.Arrays.AbstractArrays import Stack as AbstractStack


class Stack(AbstractStack):
def __init__(self, *, capacity: int = None):
def __init__(self, *, capacity: Optional[int] = None):
self._array = []
self.set_capacity(capacity)

@property
def array(self) -> list[Any]:
return self._array

def is_full(self) -> bool:
return len(self._array) == self.capacity
return len(self.array) == self.capacity

def is_empty(self) -> bool:
return not len(self._array)
return not self.array

def push(self, item: Any) -> int:
if self.is_full(): # Overflow Condition
raise OverFlowError(self)

self._array.append(item)
self.array.append(item)
return 0

def pop(self) -> Any:
if self.is_empty(): # Underflow Condition handled
raise UnderFlowError(self)
return self._array.pop()
return self.array.pop()

def __len__(self):
return len(self._array)
return len(self.array)

def peek(self) -> Any:
return 'STACK EMPTY' if self.is_empty() else self._array[-1]
return 'STACK EMPTY' if self.is_empty() else self.array[-1]
2 changes: 1 addition & 1 deletion datastax/Arrays/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .priority_queue import PriorityQueue
from .Queue import Queue
from .Stack import Stack
from .PriorityQueue import PriorityQueue

__all__ = [
'Queue',
Expand Down
4 changes: 2 additions & 2 deletions datastax/Lists/AbstractLists/LinkedList.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Optional, Self
from typing import Any, Optional, Self, Iterable
from datastax.Lists.AbstractLists.Node import Node
from datastax.Utils import Commons
from abc import abstractmethod, ABC as AbstractClass
Expand Down Expand Up @@ -67,5 +67,5 @@ def insert(self, data: Any) -> None:
...

@abstractmethod
def _construct(self, array: Optional[list[Any]]) -> Self:
def _construct(self, array: Iterable[Any]) -> Self:
...
5 changes: 2 additions & 3 deletions datastax/Lists/CircularLinkedList.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from typing import Any

from datastax.Lists import LinkedList
from datastax.Lists.LinkedList import LinkedList
from datastax.Lists.AbstractLists import CircularLinkedList as AbstractList


class CircularLinkedList(AbstractList,
LinkedList):
class CircularLinkedList(AbstractList, LinkedList):
def append(self, data: Any) -> None:
super().append(data)
self.tail.set_next(self.head)
Expand Down
13 changes: 4 additions & 9 deletions datastax/Lists/DoublyCircularList.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
from typing import Any, Optional, Self
from typing import Any

from datastax.Lists import DoublyLinkedList
from datastax.Lists.DoublyLinkedList import DoublyLinkedList
from datastax.Lists.CircularLinkedList import CircularLinkedList
from datastax.Lists.AbstractLists import DoublyCircularList as AbstractList


class DoublyCircularList(AbstractList, DoublyLinkedList):

def _construct(self, array: Optional[list[Any]]) -> Self:
if array and array[0] is not None:
for item in array:
self.append(item)
return self
class DoublyCircularList(AbstractList, CircularLinkedList, DoublyLinkedList):

def append(self, data: Any) -> None:
super().append(data)
Expand Down
9 changes: 5 additions & 4 deletions datastax/Lists/DoublyLinkedList.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Any, Optional, Iterable, Self

from datastax.Lists import DoublyNode, LinkedList
from datastax.Lists.DoublyNode import DoublyNode
from datastax.Lists.LinkedList import LinkedList
from datastax.Lists.AbstractLists import DoublyLinkedList as AbstractList


Expand All @@ -13,16 +14,16 @@ def __init__(self, items: Optional[Iterable[Any]] = None,
tail.set_prev(head)
super().__init__(items, head, tail)

def _construct(self, array: Optional[list[Any]]) -> Self:
def _construct(self, array: Iterable[Any]) -> Self:
return super()._construct(array)

def set_head(self, head: Optional[DoublyNode] = None):
def set_head(self, head):
if head is not None and not isinstance(head, DoublyNode):
raise TypeError("The 'head' parameter must be an "
"instance of DoublyNode or its subclass.")
super().set_head(head)

def set_tail(self, tail: Optional[DoublyNode] = None):
def set_tail(self, tail):
if tail is not None and not isinstance(tail, DoublyNode):
raise TypeError("The 'tail' parameter must be an "
"instance of DoublyNode or its subclass.")
Expand Down
4 changes: 2 additions & 2 deletions datastax/Lists/DoublyNode.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from typing import Any, Self, Optional

from datastax.Lists import Node
from datastax.Lists.Node import Node
from datastax.Lists.AbstractLists import DoublyNode as AbstractNode


class DoublyNode(AbstractNode, Node):
def __init__(self, data: Optional[Any] = None,
def __init__(self, data: Any,
_next: Optional[Self] = None,
prev: Optional[Self] = None):
super().__init__(data)
Expand Down
17 changes: 10 additions & 7 deletions datastax/Lists/LRUCache.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"""
from typing import Any

from datastax.Lists import DoublyLinkedList, DoublyNode
from datastax.Lists.DoublyLinkedList import DoublyLinkedList
from datastax.Lists.DoublyNode import DoublyNode


class LRUCache(DoublyLinkedList):
Expand All @@ -26,24 +27,25 @@ def __init__(self, capacity: int):
self.tail.set_prev(self.head)
self.head.set_next(self.tail)

def get(self, key: int) -> int:
def get(self, key: int) -> int | None:
if key not in self._cache:
return -1
node = self._cache[key]
self._enqueue(node)
return node.data[1]
return node.data[1] if node.data else None

def put(self, key: int, value: int) -> None:
def put(self, key: int, value: int):
if key not in self._cache:
node = DoublyNode([key, value])
if len(self._cache) == self._capacity:
self._dequeue()
else:
node = self._cache[key]
node.data[1] = value
if node.data:
node.data[1] = value
self._enqueue(node)

def _enqueue(self, node: DoublyNode) -> None:
def _enqueue(self, node: DoublyNode):
if node.prev:
node.prev.set_next(node.next)
if node.next:
Expand All @@ -52,7 +54,8 @@ def _enqueue(self, node: DoublyNode) -> None:
node.set_next(self.tail)
self.tail.prev.set_next(node)
self.tail.set_prev(node)
self._cache[node.data[0]] = node
if node.data:
self._cache[node.data[0]] = node

def _dequeue(self) -> None:
node = self.head.next
Expand Down
Loading

0 comments on commit e55320f

Please sign in to comment.