Skip to content

[mypy] Fix and add type annotations in data_structures/queue/double_ended_queue.py #5618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 27, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 18 additions & 54 deletions data_structures/queue/double_ended_queue.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,32 @@
"""
Implementation of double ended queue.
"""
from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Iterable


class Deque:
"""
Deque data structure.

Operations
----------
append(val: Any) -> None

appendleft(val: Any) -> None

extend(iter: Iterable) -> None

extendleft(iter: Iterable) -> None

pop() -> Any

popleft() -> Any


Observers
---------
is_empty() -> bool


Attributes
----------
_front: _Node
front of the deque a.k.a. the first element

_back: _Node
back of the element a.k.a. the last element

_len: int
the number of nodes
"""
Expand All @@ -51,13 +41,12 @@ class _Node:
"""

val: Any = None
next: "Deque._Node" = None
prev: "Deque._Node" = None
next: Deque._Node | None = None
prev: Deque._Node | None = None

class _Iterator:
"""
Helper class for iteration. Will be used to implement iteration.

Attributes
----------
_cur: _Node
Expand All @@ -66,10 +55,10 @@ class _Iterator:

__slots__ = ["_cur"]

def __init__(self, cur: "Deque._Node") -> None:
def __init__(self, cur: Deque._Node | None) -> None:
self._cur = cur

def __iter__(self) -> "Deque._Iterator":
def __iter__(self) -> Deque._Iterator:
"""
>>> our_deque = Deque([1, 2, 3])
>>> iterator = iter(our_deque)
Expand All @@ -95,9 +84,10 @@ def __next__(self) -> Any:

return val

def __init__(self, iterable: Iterable = None) -> None:
self._front = self._back = None
self._len = 0
def __init__(self, iterable: Iterable[Any] | None = None) -> None:
self._front: Any = None
self._back: Any = None
self._len: int = 0

if iterable is not None:
# append every value to the deque
Expand All @@ -108,7 +98,6 @@ def append(self, val: Any) -> None:
"""
Adds val to the end of the deque.
Time complexity: O(1)

>>> our_deque_1 = Deque([1, 2, 3])
>>> our_deque_1.append(4)
>>> our_deque_1
Expand All @@ -117,7 +106,6 @@ def append(self, val: Any) -> None:
>>> our_deque_2.append('c')
>>> our_deque_2
['a', 'b', 'c']

>>> from collections import deque
>>> deque_collections_1 = deque([1, 2, 3])
>>> deque_collections_1.append(4)
Expand All @@ -127,7 +115,6 @@ def append(self, val: Any) -> None:
>>> deque_collections_2.append('c')
>>> deque_collections_2
deque(['a', 'b', 'c'])

>>> list(our_deque_1) == list(deque_collections_1)
True
>>> list(our_deque_2) == list(deque_collections_2)
Expand All @@ -153,7 +140,6 @@ def appendleft(self, val: Any) -> None:
"""
Adds val to the beginning of the deque.
Time complexity: O(1)

>>> our_deque_1 = Deque([2, 3])
>>> our_deque_1.appendleft(1)
>>> our_deque_1
Expand All @@ -162,7 +148,6 @@ def appendleft(self, val: Any) -> None:
>>> our_deque_2.appendleft('a')
>>> our_deque_2
['a', 'b', 'c']

>>> from collections import deque
>>> deque_collections_1 = deque([2, 3])
>>> deque_collections_1.appendleft(1)
Expand All @@ -172,7 +157,6 @@ def appendleft(self, val: Any) -> None:
>>> deque_collections_2.appendleft('a')
>>> deque_collections_2
deque(['a', 'b', 'c'])

>>> list(our_deque_1) == list(deque_collections_1)
True
>>> list(our_deque_2) == list(deque_collections_2)
Expand All @@ -194,11 +178,10 @@ def appendleft(self, val: Any) -> None:
# make sure there were no errors
assert not self.is_empty(), "Error on appending value."

def extend(self, iter: Iterable) -> None:
def extend(self, iter: Iterable[Any]) -> None:
"""
Appends every value of iter to the end of the deque.
Time complexity: O(n)

>>> our_deque_1 = Deque([1, 2, 3])
>>> our_deque_1.extend([4, 5])
>>> our_deque_1
Expand All @@ -207,7 +190,6 @@ def extend(self, iter: Iterable) -> None:
>>> our_deque_2.extend('cd')
>>> our_deque_2
['a', 'b', 'c', 'd']

>>> from collections import deque
>>> deque_collections_1 = deque([1, 2, 3])
>>> deque_collections_1.extend([4, 5])
Expand All @@ -217,7 +199,6 @@ def extend(self, iter: Iterable) -> None:
>>> deque_collections_2.extend('cd')
>>> deque_collections_2
deque(['a', 'b', 'c', 'd'])

>>> list(our_deque_1) == list(deque_collections_1)
True
>>> list(our_deque_2) == list(deque_collections_2)
Expand All @@ -226,11 +207,10 @@ def extend(self, iter: Iterable) -> None:
for val in iter:
self.append(val)

def extendleft(self, iter: Iterable) -> None:
def extendleft(self, iter: Iterable[Any]) -> None:
"""
Appends every value of iter to the beginning of the deque.
Time complexity: O(n)

>>> our_deque_1 = Deque([1, 2, 3])
>>> our_deque_1.extendleft([0, -1])
>>> our_deque_1
Expand All @@ -239,7 +219,6 @@ def extendleft(self, iter: Iterable) -> None:
>>> our_deque_2.extendleft('ba')
>>> our_deque_2
['a', 'b', 'c', 'd']

>>> from collections import deque
>>> deque_collections_1 = deque([1, 2, 3])
>>> deque_collections_1.extendleft([0, -1])
Expand All @@ -249,7 +228,6 @@ def extendleft(self, iter: Iterable) -> None:
>>> deque_collections_2.extendleft('ba')
>>> deque_collections_2
deque(['a', 'b', 'c', 'd'])

>>> list(our_deque_1) == list(deque_collections_1)
True
>>> list(our_deque_2) == list(deque_collections_2)
Expand All @@ -262,24 +240,20 @@ def pop(self) -> Any:
"""
Removes the last element of the deque and returns it.
Time complexity: O(1)

@returns topop.val: the value of the node to pop.

>>> our_deque = Deque([1, 2, 3, 15182])
>>> our_popped = our_deque.pop()
>>> our_popped
15182
>>> our_deque
[1, 2, 3]

>>> from collections import deque
>>> deque_collections = deque([1, 2, 3, 15182])
>>> collections_popped = deque_collections.pop()
>>> collections_popped
15182
>>> deque_collections
deque([1, 2, 3])

>>> list(our_deque) == list(deque_collections)
True
>>> our_popped == collections_popped
Expand All @@ -302,24 +276,20 @@ def popleft(self) -> Any:
"""
Removes the first element of the deque and returns it.
Time complexity: O(1)

@returns topop.val: the value of the node to pop.

>>> our_deque = Deque([15182, 1, 2, 3])
>>> our_popped = our_deque.popleft()
>>> our_popped
15182
>>> our_deque
[1, 2, 3]

>>> from collections import deque
>>> deque_collections = deque([15182, 1, 2, 3])
>>> collections_popped = deque_collections.popleft()
>>> collections_popped
15182
>>> deque_collections
deque([1, 2, 3])

>>> list(our_deque) == list(deque_collections)
True
>>> our_popped == collections_popped
Expand All @@ -340,14 +310,12 @@ def is_empty(self) -> bool:
"""
Checks if the deque is empty.
Time complexity: O(1)

>>> our_deque = Deque([1, 2, 3])
>>> our_deque.is_empty()
False
>>> our_empty_deque = Deque()
>>> our_empty_deque.is_empty()
True

>>> from collections import deque
>>> empty_deque_collections = deque()
>>> list(our_empty_deque) == list(empty_deque_collections)
Expand All @@ -359,14 +327,12 @@ def __len__(self) -> int:
"""
Implements len() function. Returns the length of the deque.
Time complexity: O(1)

>>> our_deque = Deque([1, 2, 3])
>>> len(our_deque)
3
>>> our_empty_deque = Deque()
>>> len(our_empty_deque)
0

>>> from collections import deque
>>> deque_collections = deque([1, 2, 3])
>>> len(deque_collections)
Expand All @@ -379,19 +345,17 @@ def __len__(self) -> int:
"""
return self._len

def __eq__(self, other: "Deque") -> bool:
def __eq__(self, other: object) -> bool:
"""
Implements "==" operator. Returns if *self* is equal to *other*.
Time complexity: O(n)

>>> our_deque_1 = Deque([1, 2, 3])
>>> our_deque_2 = Deque([1, 2, 3])
>>> our_deque_1 == our_deque_2
True
>>> our_deque_3 = Deque([1, 2])
>>> our_deque_1 == our_deque_3
False

>>> from collections import deque
>>> deque_collections_1 = deque([1, 2, 3])
>>> deque_collections_2 = deque([1, 2, 3])
Expand All @@ -400,12 +364,15 @@ def __eq__(self, other: "Deque") -> bool:
>>> deque_collections_3 = deque([1, 2])
>>> deque_collections_1 == deque_collections_3
False

>>> (our_deque_1 == our_deque_2) == (deque_collections_1 == deque_collections_2)
True
>>> (our_deque_1 == our_deque_3) == (deque_collections_1 == deque_collections_3)
True
"""

if not isinstance(other, Deque):
return NotImplemented

me = self._front
oth = other._front

Expand All @@ -422,18 +389,16 @@ def __eq__(self, other: "Deque") -> bool:

return True

def __iter__(self) -> "_Iterator":
def __iter__(self) -> Deque._Iterator:
"""
Implements iteration.
Time complexity: O(1)

>>> our_deque = Deque([1, 2, 3])
>>> for v in our_deque:
... print(v)
1
2
3

>>> from collections import deque
>>> deque_collections = deque([1, 2, 3])
>>> for v in deque_collections:
Expand All @@ -449,7 +414,6 @@ def __repr__(self) -> str:
Implements representation of the deque.
Represents it as a list, with its values between '[' and ']'.
Time complexity: O(n)

>>> our_deque = Deque([1, 2, 3])
>>> our_deque
[1, 2, 3]
Expand Down