diff --git a/ands/ds/BST.py b/ands/ds/BST.py
index 518bd088..291e1d9d 100755
--- a/ands/ds/BST.py
+++ b/ands/ds/BST.py
@@ -2,13 +2,18 @@
# -*- coding: utf-8 -*-
"""
+# Meta info
+
Author: Nelson Brochado
-Creation: July, 2015
+Created: 01/07/2015
+
+Updated: 28/08/2016
+
+# Description
-Last update: 28/08/2016
+### Coding Conventions
-## Names' Conventions
In general, if a variable name has more than one word,
those words are separated by _ (underscores).
Functions' names should roughly describe what the function does.
@@ -17,11 +22,13 @@
comments are usually provide on the first occurrence of the name,
in order to explain the purpose of such a variable.
-### Functions
+#### Functions
+
- Methods that start with _ should not be called,
because they might either be "helper" or private functions.
-### Parameters
+#### Parameters
+
- `u`, `v`, `z` and `w` are used to indicate that a general `BSTNode` object is expected.
- `s` is used to indicate that a source node is expected.
@@ -31,12 +38,14 @@
- `ls` is usually used to indicate that a list or a tuple is expected.
-### Local Variables
+#### Local Variables
+
- `c` usually indicates some "current" changing variable.
- `p` is usually `c`'s parent.
-### Docstrings
+#### Docstrings
+
Under methods' signatures, h in O(h) is the height of the tree.
Note that the height of a BST varies depending on how elements
are inserted and removed.
@@ -46,25 +55,22 @@
Other names are self-descriptive.
For example, "key" and "value" are self-descriptive.
-## Resources
-
-- [https://en.wikipedia.org/wiki/Binary_search_tree](https://en.wikipedia.org/wiki/Binary_search_tree)
-
-- [Introduction to Algorithms (3rd edition)](https://mitpress.mit.edu/books/introduction-algorithms) by CLRS, chapter 12
+# TODO
-- [http://algs4.cs.princeton.edu/32bst/](http://algs4.cs.princeton.edu/32bst/)
-
-- [http://www.cs.princeton.edu/courses/archive/spr04/cos226/lectures/bst.4up.pdf](http://www.cs.princeton.edu/courses/archive/spr04/cos226/lectures/bst.4up.pdf
-)
-
-- [http://algs4.cs.princeton.edu/32bst/BST.java.html](http://algs4.cs.princeton.edu/32bst/BST.java.html)
-
-## TODO
- Improve the "randomness" of insertion into the BSTImproved class.
- Add functions "intersection" and "union".
- Implement a recursive version of insert (OPTIONAL).
- implement "is balanced" function (http://codereview.stackexchange.com/questions/108459/binary-tree-data-structure)
- Maybe the methods of the BSTNode need an improvement in terms of implementation...
+
+# Resources
+
+- [https://en.wikipedia.org/wiki/Binary_search_tree](https://en.wikipedia.org/wiki/Binary_search_tree)
+- [Introduction to Algorithms (3rd edition)](https://mitpress.mit.edu/books/introduction-algorithms) by CLRS, chapter 12
+- [http://algs4.cs.princeton.edu/32bst/](http://algs4.cs.princeton.edu/32bst/)
+- [http://www.cs.princeton.edu/courses/archive/spr04/cos226/lectures/bst.4up.pdf](http://www.cs.princeton.edu/courses/archive/spr04/cos226/lectures/bst.4up.pdf)
+- [http://algs4.cs.princeton.edu/32bst/BST.java.html](http://algs4.cs.princeton.edu/32bst/BST.java.html)
+
"""
from random import randint
diff --git a/ands/ds/DSForests.py b/ands/ds/DSForests.py
index ab2f2dac..ac18dc41 100644
--- a/ands/ds/DSForests.py
+++ b/ands/ds/DSForests.py
@@ -2,15 +2,15 @@
# -*- coding: utf-8 -*-
"""
-## Meta info
+# Meta info
Author: Nelson Brochado
-Creation: 21/02/16
+Created: 21/02/2016
-Last update: 03/01/16
+Updated: 03/01/2016
-## Description
+# Description
A disjoint-set (forests) or union-find data structure is a data structure which keeps track of a set of elements
partitioned into disjoint (non-overlapping, i.e. their intersection is the empty set) sets.
@@ -31,34 +31,26 @@
These two techniques complement each other: applied together, the amortized time per operation is only O( α (n)).
-## References
+# TODO
-- Introduction to algorithms, 3rd, by C.L.R.S., chapter 21.3
+- Deletion operation (OPTIONAL, since it's usually not part of the interface of a disjoint-set data structure)
+- Pretty-print(x), for some element x in the disjoint-set data structure.
+- Implement the version explained [here](http://algs4.cs.princeton.edu/15uf/)
-- [https://en.wikipedia.org/wiki/Disjoint-set_data_structure](https://en.wikipedia.org/wiki/Disjoint-set_data_structure)
+# References
+- Introduction to algorithms, 3rd, by C.L.R.S., chapter 21.3
+- [https://en.wikipedia.org/wiki/Disjoint-set_data_structure](https://en.wikipedia.org/wiki/Disjoint-set_data_structure)
- [http://orionsword.no-ip.org/blog/wordpress/?p=246](http://orionsword.no-ip.org/blog/wordpress/?p=246)
-
- [http://stackoverflow.com/a/22945492/3924118](http://stackoverflow.com/a/22945492/3924118)
-
- [http://stackoverflow.com/q/23055236/3924118](http://stackoverflow.com/q/23055236/3924118)
-
- [https://www.cs.usfca.edu/~galles/JavascriptVisual/DisjointSets.html](https://www.cs.usfca.edu/~galles/JavascriptVisual/DisjointSets.html)
to visualize how disjoint-sets work.
-## TODO
-
-- Deletion operation (OPTIONAL, since it's usually not part of the interface of a disjoint-set data structure)
-
-- Pretty-print(x), for some element x in the disjoint-set data structure.
-
-- Implement the version explained [here](http://algs4.cs.princeton.edu/15uf/)
-
"""
class DSNode:
-
def __init__(self, x, rank=0):
# This attribute can contain any hashable value.
self.value = x
@@ -97,7 +89,6 @@ def __repr__(self):
class DSForests:
-
def __init__(self):
# keeps tracks of the DSNodes in this disjoint-set forests.
self.sets = {}
diff --git a/ands/ds/HashTable.py b/ands/ds/HashTable.py
index 849e7dc7..9cb77295 100644
--- a/ands/ds/HashTable.py
+++ b/ands/ds/HashTable.py
@@ -2,11 +2,15 @@
# -*- coding: utf-8 -*-
"""
+# Meta info
+
Author: Nelson Brochado
-Creation: June, 2015
+Created: 01/06/2015
+
+Updated: 21/02/2016
-Last update: 21/02/16
+# Description
Hash table that re-sizes if no more slot is available.
The process of re-sizing doubles the current capacity of the hash table each time (for now).
@@ -19,10 +23,11 @@
h[12] = 3
print(h[12])
-## References
-- [http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html](http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html)
+# References
+- [http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html](http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html)
- [http://stackoverflow.com/questions/279539/best-way-to-remove-an-entry-from-a-hash-table](http://stackoverflow.com/questions/279539/best-way-to-remove-an-entry-from-a-hash-table)
+
"""
from tabulate import tabulate
diff --git a/ands/ds/Heap.py b/ands/ds/Heap.py
index 5ad91b61..60d27f77 100755
--- a/ands/ds/Heap.py
+++ b/ands/ds/Heap.py
@@ -2,38 +2,37 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
-Creation: July, 2015
+Author: Nelson Brochado
-Updated: 21/01/2017
+Created: 01/07/2015
-Base abstract class to represent heaps.
-See `MinHeap` and `MaxHeap` if you want to instantiate heap objects.
+Updated: 05/02/2017
-## [NotImplementedError](https://docs.python.org/3/library/exceptions.html#NotImplementedError)
+# Description
-This exception is derived from `RuntimeError`.
-In user defined base classes,
-abstract methods should raise this exception
-when they require derived classes to override the method.
+This module contains currently the classes `HeapNode`, which is a class to represent nodes of heaps,
+the class `BinaryHeap` and a function which returns a pretty string representation of a heap passed as parameter.
-## References
+# References
- [http://www.math.clemson.edu/~warner/M865/HeapDelete.html](http://www.math.clemson.edu/~warner/M865/HeapDelete.html)
- Slides by prof. A. Carzaniga
- Chapter 13 of [Introduction to Algorithms (3rd ed.)](https://mitpress.mit.edu/books/introduction-algorithms) by CLRS
+- [NotImplementedError](https://docs.python.org/3/library/exceptions.html#NotImplementedError)
+
"""
import io
import math
+from collections import Iterable
-__all__ = ["BaseHeap", "Heap", "HeapNode"]
+__all__ = ["BinaryHeap", "HeapNode", "build_pretty_binary_heap"]
class HeapNode:
- """All elements of Heap objects are represented
- with objects of the class HeapNode."""
+ """All elements of heap objects are represented with objects of the class HeapNode."""
def __init__(self, key, value=None):
"""`key` is the priority used to heapify the heap,
@@ -69,15 +68,17 @@ def __repr__(self):
return str(self.value) + " -> " + str(self.key)
-class BaseHeap:
+class BinaryHeap:
+ """Abstract class to represent binary heaps.
+
+ `MinHeap`, `MaxHeap` and `MinMaxHeap` all derive from this class."""
+
def __init__(self, ls=None):
if ls is None:
ls = []
- self.heap = BaseHeap._create_list_of_heap_nodes(ls)
+ self.heap = BinaryHeap._create_list_of_heap_nodes(ls)
self.build_heap()
- # ABSTRACT METHODS
-
def push_down(self, i: int) -> None:
"""Classical so-called heapify operation for heaps."""
raise NotImplementedError()
@@ -86,6 +87,9 @@ def push_up(self, i: int) -> None:
"""Classical reverse-heapify operation for heaps."""
raise NotImplementedError()
+ def delete(self, i: int) -> HeapNode:
+ raise NotImplementedError()
+
def replace(self, i: int, x) -> HeapNode:
"""Replaces the `HeapNode` object at index `i` with `x`.
@@ -94,11 +98,6 @@ def replace(self, i: int, x) -> HeapNode:
whose key and value are equal to `x`."""
raise NotImplementedError()
- def delete(self, i: int) -> HeapNode:
- raise NotImplementedError()
-
- # BASE-IMPLEMENTED METHODS
-
def build_heap(self) -> list:
"""Builds the heap data structure from `self.heap`."""
if self.heap:
@@ -335,19 +334,11 @@ def is_on_odd_level(self, i: int) -> bool:
"""Returns `True` (`False`) if `self.is_on_even_level(i)` returns `False` (`True`)."""
return not self.is_on_even_level(i)
- # PRINT FUNCTIONS
-
def __str__(self) -> str:
return str(self.heap)
def __repr__(self) -> str:
- return HeapPrinter(self.heap).show()
-
- def show(self, total_width=36, fill=" ") -> None:
- """Pretty-prints this heap."""
- print(HeapPrinter(self.heap).show(total_width, fill))
-
- # STATIC FUNCTIONS
+ return build_pretty_binary_heap(self.heap)
@staticmethod
def _create_list_of_heap_nodes(ls: list) -> list:
@@ -371,75 +362,48 @@ def _create_list_of_heap_nodes(ls: list) -> list:
return nodes
-class Heap(BaseHeap):
- # Abstract class from which MinHeap and MaxHeap derive.
- # MinMaxHeap instead derives from the root abstract class BaseHeap.
-
- def __init__(self, ls=None):
- BaseHeap.__init__(self, ls)
-
- def delete(self, i: int) -> HeapNode:
- """Deletes and returns the `HeapNode` object at index `i`.
-
- `IndexError` is raised if `i` is not a valid index.
-
- Implementation based on:
- [http://www.math.clemson.edu/~warner/M865/HeapDelete.html](http://www.math.clemson.edu/~warner/M865/HeapDelete.html)
-
- **Time Complexity:** O(log2 h),
- where `h` is the number of nodes rooted at `i`."""
- if not self.is_good_index(i):
- raise IndexError("i is not a valid index.")
- if i == self.size() - 1:
- return self.heap.pop()
- self.swap(i, self.size() - 1)
- d = self.heap.pop()
- self.push_down(i)
- return d
+def build_pretty_binary_heap(heap: list, total_width=36, fill=" ") -> str:
+ """Returns a string (which can be printed) representing `heap` as a tree.
+ Adapted for Python 3 from: [http://pymotw.com/2/heapq/](http://pymotw.com/2/heapq/).
-class HeapPrinter:
- def __init__(self, heap):
- self.heap = heap
+ To increase/decrease the horizontal space between nodes,
+ just increase/decrease the float number h_space.
- def show(self, total_width=36, fill=" ") -> str:
- """Adapted for Python 3 from:
- [http://pymotw.com/2/heapq/](http://pymotw.com/2/heapq/).
+ To increase/decrease the vertical space between nodes,
+ just increase/decrease the integer number v_space.
+ Note that v_space must be an integer.
- To increase/decrease the horizontal space between nodes,
- just increase/decrease the float number h_space.
+ To change the length of the line under the heap,
+ you can simply change the line_length variable."""
+ if not isinstance(heap, Iterable):
+ raise TypeError("heap must be an iterable object")
+ if len(heap) == 0:
+ return "Nothing to print: heap is empty."
- To increase/decrease the vertical space between nodes,
- just increase/decrease the integer number v_space.
- Note that v_space must be an integer.
+ output = io.StringIO()
+ last_row = -1
- To change the length of the line under the heap,
- you can simply change the line_length variable."""
- if not self.heap:
- return "Nothing to print: heap is empty."
+ h_space = 3.0 # float
+ v_space = 2 # int
- output = io.StringIO()
- last_row = -1
-
- h_space = 3.0 # float
- v_space = 2 # int
+ for i, heap_node in enumerate(heap):
+ if i:
+ row = int(math.floor(math.log(i + 1, 2)))
+ else:
+ row = 0
- for i, heap_node in enumerate(self.heap):
- if i:
- row = int(math.floor(math.log(i + 1, 2)))
- else:
- row = 0
- if row != last_row:
- output.write("\n" * v_space)
+ if row != last_row:
+ output.write("\n" * v_space)
- columns = 2 ** row
+ columns = 2 ** row
- column_width = int(math.floor((total_width * h_space) / columns))
- output.write(str(heap_node).center(column_width, fill))
- last_row = row
+ column_width = int(math.floor((total_width * h_space) / columns))
+ output.write(str(heap_node).center(column_width, fill))
+ last_row = row
- s = output.getvalue() + "\n"
+ s = output.getvalue() + "\n"
- line_length = total_width + 15 # int
- s += ('-' * line_length + "\n")
- return s
+ line_length = total_width + 15 # int
+ s += ('-' * line_length + "\n")
+ return s
diff --git a/ands/ds/MaxHeap.py b/ands/ds/MaxHeap.py
index 0351f9b0..c52fc271 100644
--- a/ands/ds/MaxHeap.py
+++ b/ands/ds/MaxHeap.py
@@ -2,32 +2,35 @@
# -*- coding: utf-8 -*-
"""
+# Meta info
+
Author: Nelson Brochado
-Creation: 15/02/16
+Created: 15/02/2016
+
+Updated: 05/02/2017
-Last update: 28/08/16
+# Description
Mirror-class to the MinHeap class.
For more info, see the introductory doc-strings of the file [`MinHeap.py`](MinHeap.py).
-## References
+# References
- [https://en.wikipedia.org/wiki/Binary_heap](https://en.wikipedia.org/wiki/Binary_heap)
-
- Slides by prof. A. Carzaniga
-
- Chapter 13 of [Introduction to Algorithms (3rd ed.)](https://mitpress.mit.edu/books/introduction-algorithms) by CLRS
+
"""
-from ands.ds.Heap import Heap, HeapNode
+from ands.ds.Heap import BinaryHeap, HeapNode
__all__ = ["MaxHeap", "is_max_heap"]
-class MaxHeap(Heap):
+class MaxHeap(BinaryHeap):
def __init__(self, ls=None):
- Heap.__init__(self, ls)
+ BinaryHeap.__init__(self, ls)
def push_down(self, i: int) -> None:
"""'Max-heapify' this max-heap starting from index `i`.
@@ -81,6 +84,25 @@ def remove_max(self) -> HeapNode:
self.push_down(0)
return m
+ def delete(self, i: int) -> HeapNode:
+ """Deletes and returns the `HeapNode` object at index `i`.
+
+ `IndexError` is raised if `i` is not a valid index.
+
+ Implementation based on:
+ [http://www.math.clemson.edu/~warner/M865/HeapDelete.html](http://www.math.clemson.edu/~warner/M865/HeapDelete.html)
+
+ **Time Complexity:** O(log2 h),
+ where `h` is the number of nodes rooted at `i`."""
+ if not self.is_good_index(i):
+ raise IndexError("i is not a valid index.")
+ if i == self.size() - 1:
+ return self.heap.pop()
+ self.swap(i, self.size() - 1)
+ d = self.heap.pop()
+ self.push_down(i)
+ return d
+
def replace(self, i: int, x) -> HeapNode:
"""Replaces element at index `i` with `x`.
diff --git a/ands/ds/MinHeap.py b/ands/ds/MinHeap.py
index 6355463f..0ec524b6 100755
--- a/ands/ds/MinHeap.py
+++ b/ands/ds/MinHeap.py
@@ -2,11 +2,15 @@
# -*- coding: utf-8 -*-
"""
+# Meta info
+
Author: Nelson Brochado
-Creation: July, 2015
+Created: 01/07/2015
+
+Updated: 05/02/2017
-Last update: 28/08/16
+# Description
A binary min-heap is a data structure similar to a binary tree,
where the parent nodes are smaller or equal to their children.
@@ -29,23 +33,21 @@
Note that these indexes are for 0-index based lists (or arrays).
-## References
+# References
- [https://en.wikipedia.org/wiki/Binary_heap](https://en.wikipedia.org/wiki/Binary_heap)
-
- Slides by prof. A. Carzaniga
-
- Chapter 13 of [Introduction to Algorithms (3rd ed.)](https://mitpress.mit.edu/books/introduction-algorithms) by CLRS
"""
-from ands.ds.Heap import Heap, HeapNode
+from ands.ds.Heap import BinaryHeap, HeapNode
__all__ = ["MinHeap", "is_min_heap"]
-class MinHeap(Heap):
+class MinHeap(BinaryHeap):
def __init__(self, ls=None):
- Heap.__init__(self, ls)
+ BinaryHeap.__init__(self, ls)
def push_down(self, i: int) -> None:
"""'Min-heapify' this min-heap starting from index `i`.
@@ -103,6 +105,25 @@ def remove_min(self) -> HeapNode:
self.push_down(0)
return m
+ def delete(self, i: int) -> HeapNode:
+ """Deletes and returns the `HeapNode` object at index `i`.
+
+ `IndexError` is raised if `i` is not a valid index.
+
+ Implementation based on:
+ [http://www.math.clemson.edu/~warner/M865/HeapDelete.html](http://www.math.clemson.edu/~warner/M865/HeapDelete.html)
+
+ **Time Complexity:** O(log2 h),
+ where `h` is the number of nodes rooted at `i`."""
+ if not self.is_good_index(i):
+ raise IndexError("i is not a valid index.")
+ if i == self.size() - 1:
+ return self.heap.pop()
+ self.swap(i, self.size() - 1)
+ d = self.heap.pop()
+ self.push_down(i)
+ return d
+
def replace(self, i: int, x) -> HeapNode:
"""Replaces element at index `i` with `x`.
diff --git a/ands/ds/MinMaxHeap.py b/ands/ds/MinMaxHeap.py
index ad3ab73f..6e760a14 100644
--- a/ands/ds/MinMaxHeap.py
+++ b/ands/ds/MinMaxHeap.py
@@ -2,11 +2,15 @@
# -*- coding: utf-8 -*-
"""
+# Meta info
+
Author: Nelson Brochado
-Creation: 18/02/16
+Created: 18/02/2016
+
+Updated: 29/12/2016
-Last update: 29/12/16
+# Description
Min-Max Heap is a heap that supports find-min and find-max operations in constant time.
Moreover, both remove-min and remove-max are supported in logarithmic time.
@@ -51,24 +55,24 @@
- `merge` in O(n + m) time
- `clear` in O(1) time
-## TODO
+# TODO
- `find-kth`, i.e. find the kth smallest element in the structure, in O(1) time
- `delete-kth`, i.e. delete the kth smallest element, in O(log n) time
-## References:
+# References
- [Min-Max Heaps and Generalized Priority Queues](http://www.akira.ruc.dk/~keld/teaching/algoritmedesign_f03/Artikler/02/Atkinson86.pdf),
original paper describing and introducing the min-max heap data structure, by M. D. Atkinson, J.R. Sack, N. Santoro and T. Strothotte.
- [http://www.diku.dk/forskning/performance-engineering/Jesper/heaplab/heapsurvey_html/node11.html](http://www.diku.dk/forskning/performance-engineering/Jesper/heaplab/heapsurvey_html/node11.html)
"""
-from ands.ds.Heap import BaseHeap, HeapNode
+from ands.ds.Heap import BinaryHeap, HeapNode
-class MinMaxHeap(BaseHeap):
+class MinMaxHeap(BinaryHeap):
def __init__(self, ls=None):
- BaseHeap.__init__(self, ls)
+ BinaryHeap.__init__(self, ls)
def push_down(self, i: int) -> None:
"""Also called `bubble-down` or `shift-down`."""
diff --git a/ands/ds/Queue.py b/ands/ds/Queue.py
index 9f9520d8..09bd26cd 100755
--- a/ands/ds/Queue.py
+++ b/ands/ds/Queue.py
@@ -5,7 +5,9 @@
# Meta info
Author: Nelson Brochado
+
Created: 02/07/2015
+
Updated: 04/02/2017
# Description
diff --git a/ands/ds/RBT.py b/ands/ds/RBT.py
index 44f7a35e..fac02985 100755
--- a/ands/ds/RBT.py
+++ b/ands/ds/RBT.py
@@ -2,12 +2,15 @@
# -*- coding: utf-8 -*-
"""
+# Meta info
+
Author: Nelson Brochado
-Creation: July, 2015
+Created: 01/08/2015
-Last update: 28/08/16
+Updated: 28/08/2016
+# Description
## Red-black Tree Property
@@ -83,16 +86,16 @@
insert, etc, so the complexity of those operations is T(n) = O(h),
that is T(n) = O(log2 n), which is also the worst case complexity.
-## TODO
+# TODO
+
- Override needed methods inherited from BST.
-## References
+# References
- [https://en.wikipedia.org/wiki/Red%E2%80%93black_tree](https://en.wikipedia.org/wiki/Red%E2%80%93black_tree)
-
- Slides by prof. A. Carzaniga
-
- Chapter 13 of [Introduction to Algorithms (3rd ed.)](https://mitpress.mit.edu/books/introduction-algorithms) by CLRS
+
"""
import math
diff --git a/ands/ds/Stack.py b/ands/ds/Stack.py
index 54eb7f69..fd186d7f 100755
--- a/ands/ds/Stack.py
+++ b/ands/ds/Stack.py
@@ -5,7 +5,9 @@
# Meta info
Author: Nelson Brochado
+
Created: 05/07/2015
+
Updated: 04/02/2017
# Description
@@ -40,6 +42,7 @@
for the time complexity analysis of the size operation.
- [http://stackoverflow.com/questions/12342457/what-is-the-big-o-notation-for-the-len-function-in-python](http://stackoverflow.com/questions/12342457/what-is-the-big-o-notation-for-the-len-function-in-python),
for other time complexity analysis of the list class.
+
"""
from collections import Iterable
diff --git a/ands/ds/TST.py b/ands/ds/TST.py
index f36496b0..87e98fa4 100644
--- a/ands/ds/TST.py
+++ b/ands/ds/TST.py
@@ -5,7 +5,9 @@
# Meta info
Author: Nelson Brochado
+
Created: 05/09/2015
+
Updated: 03/02/2017
# Description
@@ -541,10 +543,10 @@ def keys_that_match(self, pattern: str) -> list:
A key `k` of length `m` matches `pattern` if:
- 1. m = length(pattern), and
- 2. Either k[i] == pattern[i] or k[i] == '.'.
- - Example: if `pattern == ".ood"`,
- then `k == "good"` would match, but not `k == "foodie"`.
+ 1. m = length(pattern), and
+ 2. Either k[i] == pattern[i] or k[i] == '.'.
+ - Example: if `pattern == ".ood"`,
+ then `k == "good"` would match, but not `k == "foodie"`.
If `pattern` is not a `str`, `TypeError` is raised.
If `pattern` is an empty string, `ValueError` is raised."""
diff --git a/tests/README.md b/tests/README.md
index 873b8db0..38d630a5 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -6,7 +6,9 @@
- Queue,
- Stack,
- - DSForests,
+ - DSForests,
+ - HeapNode
+ - BinaryHeap
- TST
which, as all other data structures, may nonetheless need to be improved!
diff --git a/tests/algorithms/crypto/test_caesar.py b/tests/algorithms/crypto/test_caesar.py
index 5bc92663..9ee82bd4 100755
--- a/tests/algorithms/crypto/test_caesar.py
+++ b/tests/algorithms/crypto/test_caesar.py
@@ -1,8 +1,14 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
+
"""
+# Meta info
+
Author: Nelson Brochado
+Created: 01/01/2017
+
+# Description
Tests for the caesar cipher algorithms.
"""
diff --git a/tests/algorithms/crypto/test_one_time_pad.py b/tests/algorithms/crypto/test_one_time_pad.py
index ebbd129e..fe51d3b9 100755
--- a/tests/algorithms/crypto/test_one_time_pad.py
+++ b/tests/algorithms/crypto/test_one_time_pad.py
@@ -1,8 +1,14 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
+
"""
+# Meta info
+
Author: Nelson Brochado
+Created: 01/01/2017
+
+# Description
Testing the one_time_pad algorithm.
"""
@@ -38,7 +44,3 @@ def test_random_size(self):
it = randint(3, 11)
size = randint(10, 1000)
self.template_test(it, size)
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/tests/algorithms/ode/test_forward_euler.py b/tests/algorithms/ode/test_forward_euler.py
index c9cd18c8..f6131ac5 100644
--- a/tests/algorithms/ode/test_forward_euler.py
+++ b/tests/algorithms/ode/test_forward_euler.py
@@ -1,8 +1,16 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
+
"""
+# Meta info
+
Author: Nelson Brochado
+Created: 01/05/2016
+
+# Description
+
+Testing the functions under forward_euler.py
"""
import unittest
@@ -11,7 +19,6 @@
class TestForwardEuler(unittest.TestCase):
-
def f(self, ti, yi):
return yi
@@ -56,7 +63,3 @@ def test_1(self):
self.assertIsNotNone(t)
self.assertIsNotNone(y)
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/tests/algorithms/recursion/test_ackermann.py b/tests/algorithms/recursion/test_ackermann.py
index 509a174c..2d43867d 100644
--- a/tests/algorithms/recursion/test_ackermann.py
+++ b/tests/algorithms/recursion/test_ackermann.py
@@ -1,11 +1,15 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
+
"""
-Author: Nelson Brochado
+# Meta info
+Author: Nelson Brochado
Created: 18/01/2017
+# Description
+
Testing the first 3*3 = 9 permutations for two inputs m and n from a domain {0, 1, 2}
"""
diff --git a/tests/algorithms/recursion/test_count.py b/tests/algorithms/recursion/test_count.py
index 515e3350..a3fe9678 100644
--- a/tests/algorithms/recursion/test_count.py
+++ b/tests/algorithms/recursion/test_count.py
@@ -2,10 +2,13 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
+Author: Nelson Brochado
Created: 15/01/2017
+# Description
+
Testing the method `count` from `ands.algorithms.recursion.count`.
"""
diff --git a/tests/algorithms/recursion/test_factorial.py b/tests/algorithms/recursion/test_factorial.py
index a8fbe4e9..78955aae 100644
--- a/tests/algorithms/recursion/test_factorial.py
+++ b/tests/algorithms/recursion/test_factorial.py
@@ -2,9 +2,14 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
+Author: Nelson Brochado
Created: 21/01/2017
+
+# Description
+
+Testing methods under `factorial.py`.
"""
import math
diff --git a/tests/algorithms/recursion/test_hanoi.py b/tests/algorithms/recursion/test_hanoi.py
index bc3b1cb2..d2bb259f 100644
--- a/tests/algorithms/recursion/test_hanoi.py
+++ b/tests/algorithms/recursion/test_hanoi.py
@@ -2,9 +2,14 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
+Author: Nelson Brochado
Created: 18/01/2017
+
+# Description
+
+Testing hanoi function.
"""
import unittest
diff --git a/tests/algorithms/recursion/test_is_sorted.py b/tests/algorithms/recursion/test_is_sorted.py
index 93b8938b..57afcafe 100644
--- a/tests/algorithms/recursion/test_is_sorted.py
+++ b/tests/algorithms/recursion/test_is_sorted.py
@@ -2,9 +2,14 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
+Author: Nelson Brochado
Created: 21/01/2017
+
+# Description
+
+Testing functions under is_sorted.py.
"""
import unittest
diff --git a/tests/algorithms/recursion/test_make_decimal.py b/tests/algorithms/recursion/test_make_decimal.py
index 85d81e4c..b8f68a4f 100644
--- a/tests/algorithms/recursion/test_make_decimal.py
+++ b/tests/algorithms/recursion/test_make_decimal.py
@@ -2,9 +2,14 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
+Author: Nelson Brochado
Created: 20/01/2017
+
+# Description
+
+Testing make_decimal function.
"""
import string
diff --git a/tests/algorithms/recursion/test_palindrome.py b/tests/algorithms/recursion/test_palindrome.py
index 11122d5a..c7bc841b 100644
--- a/tests/algorithms/recursion/test_palindrome.py
+++ b/tests/algorithms/recursion/test_palindrome.py
@@ -2,9 +2,14 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
+Author: Nelson Brochado
Created: 20/01/2017
+
+# Description
+
+Testing the recursive palindrome function.
"""
import string
diff --git a/tests/algorithms/recursion/test_power.py b/tests/algorithms/recursion/test_power.py
index 3188ad2d..9725129d 100644
--- a/tests/algorithms/recursion/test_power.py
+++ b/tests/algorithms/recursion/test_power.py
@@ -2,9 +2,14 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
+Author: Nelson Brochado
Created: 18/01/2017
+
+# Description
+
+Testing the recursive power function.
"""
import unittest
diff --git a/tests/algorithms/recursion/test_reverse.py b/tests/algorithms/recursion/test_reverse.py
index 7dc70f74..0b99da87 100644
--- a/tests/algorithms/recursion/test_reverse.py
+++ b/tests/algorithms/recursion/test_reverse.py
@@ -1,11 +1,15 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
+
"""
-Author: Nelson Brochado
+# Meta info
+Author: Nelson Brochado
Created: 16/01/2017
+# Description
+
Testing the recursive implementation of reversing a list.
"""
diff --git a/tests/ds/test_BST.py b/tests/ds/test_BST.py
index 174275c2..6f1c83d1 100755
--- a/tests/ds/test_BST.py
+++ b/tests/ds/test_BST.py
@@ -2,11 +2,13 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
-Creation: 13/02/16
+Author: Nelson Brochado
+Created: 13/02/2016
+Updated: 30/08/2016
-Last update: 30/08/16
+# Description
Tests for the BST class.
"""
@@ -324,7 +326,3 @@ def asserts():
b._switch(b.search(10), b.search(10).left.right)
asserts()
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/tests/ds/test_BSTNode.py b/tests/ds/test_BSTNode.py
index c015e77f..bb0deb3a 100755
--- a/tests/ds/test_BSTNode.py
+++ b/tests/ds/test_BSTNode.py
@@ -2,11 +2,13 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
-Creation: 15/02/16
+Author: Nelson Brochado
+Created: 15/02/2016
+Updated: 30/08/2016
-Last update: 30/08/16
+# Description
Tests for the BSTNode class.
"""
@@ -147,7 +149,3 @@ def test_uncle(self):
self.assertIsNone(n.uncle)
self.assertIsNone(n.sibling)
self.assertRaises(AttributeError, n.is_left_child)
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/tests/ds/test_BinaryHeap.py b/tests/ds/test_BinaryHeap.py
new file mode 100755
index 00000000..06ff98b5
--- /dev/null
+++ b/tests/ds/test_BinaryHeap.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+"""
+# Meta info
+
+Author: Nelson Brochado
+Created: 14/02/2016
+Updated: 05/02/2017
+
+# Description
+
+Tests for the abstract class BinaryHeap.
+"""
+
+import unittest
+
+from ands.ds.Heap import BinaryHeap
+
+
+class TestBinaryHeap(unittest.TestCase):
+ def test_heap_creation(self):
+ self.assertRaises(NotImplementedError, BinaryHeap, [12, 14, 28])
+ self.assertIsNotNone(BinaryHeap())
+ self.assertEqual(BinaryHeap().heap, [])
+ self.assertEqual(BinaryHeap([]).heap, [])
diff --git a/tests/ds/test_DSForests.py b/tests/ds/test_DSForests.py
index b2d0a2c9..29149da7 100755
--- a/tests/ds/test_DSForests.py
+++ b/tests/ds/test_DSForests.py
@@ -2,19 +2,17 @@
# -*- coding: utf-8 -*-
"""
-## Meta info
+# Meta info
Author: Nelson Brochado
+Created: 22/02/16
+Updated: 03/01/17
-Creation: 22/02/16
-
-Last update: 03/01/17
-
-## Description
+# Description
Tests for the DSForests class and associated classes.
-## Note
+# Note
Since find_iteratively internally asserts that its result is equal to find,
in these tests I'm using find_iteratively
@@ -193,7 +191,3 @@ def test_print_set(self):
ds.union(8, 13)
ds.print_set(3)
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/tests/ds/test_HashTable.py b/tests/ds/test_HashTable.py
index 51c9fbe4..a90c3987 100755
--- a/tests/ds/test_HashTable.py
+++ b/tests/ds/test_HashTable.py
@@ -1,12 +1,15 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
+
"""
-Author: Nelson Brochado
+# Meta info
-Creation: 21/02/16
+Author: Nelson Brochado
+Created: 21/02/2016
+Updated: 08/10/2016
-Last Update: 08/10/16
+# Description
Test the HashTable class.
"""
@@ -212,7 +215,3 @@ def test_empty_hash_table_capacity(self):
h = HashTable(capacity=i)
self.assertEqual(h.capacity, i)
self.assertEqual(h.size, 0)
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/tests/ds/test_Heap.py b/tests/ds/test_Heap.py
deleted file mode 100755
index 29c8e4ac..00000000
--- a/tests/ds/test_Heap.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-"""
-Author: Nelson Brochado
-
-Creation: 14/02/16
-
-Last update: 06/09/16
-
-Tests for the abstract class Heap.
-"""
-
-import unittest
-
-from ands.ds.Heap import Heap, HeapNode
-
-
-class TestHeap(unittest.TestCase):
- def test_heap_creation(self):
- self.assertRaises(NotImplementedError, Heap, [12, 14, 28])
- self.assertIsNotNone(Heap())
- self.assertEqual(Heap().heap, [])
- self.assertEqual(Heap([]).heap, [])
-
-
-class TestHeapNode(unittest.TestCase):
- def test_None(self):
- self.assertRaises(ValueError, HeapNode, None)
-
- def test_creation_key_value_same(self):
- n = HeapNode(26)
- self.assertIsNotNone(n.value)
- self.assertEqual(n.key, n.value)
-
- def test_creation_key_value_different(self):
- n = HeapNode(2, "two")
- self.assertIsNotNone(n.value)
- self.assertNotEqual(n.value, n.key)
-
- def test_less_and_greater_than(self):
- h = HeapNode(12)
- h2 = HeapNode(14)
- h3 = HeapNode(12, "Twelve")
-
- self.assertLess(h, h2)
- self.assertGreater(h2, h)
- self.assertLess(h3, h2)
- self.assertGreater(h2, h3)
- self.assertFalse(h < h)
- self.assertFalse(h > h)
- self.assertFalse(h2 < h2)
- self.assertFalse(h2 > h2)
- self.assertFalse(h3 < h3)
- self.assertFalse(h3 > h3)
-
- def test_equal_not_equal(self):
- h = HeapNode(12)
- h2 = HeapNode(14)
- h3 = HeapNode(12)
- h4 = HeapNode(14, "fourteen")
-
- self.assertEqual(h, h)
- self.assertEqual(h4, h4)
- self.assertEqual(h, h3)
- self.assertNotEqual(h, h2)
- self.assertNotEqual(h3, h2)
- self.assertNotEqual(h2, h4)
- self.assertEqual(h4, HeapNode(14, "fourteen"))
- self.assertNotEqual(h4, HeapNode("fourteen", 14))
-
- def test_less_and_greater_or_equal(self):
- h = HeapNode(12)
- h2 = HeapNode(14)
- h3 = HeapNode(12, "Twelve")
-
- self.assertLessEqual(h, h3)
- self.assertLessEqual(h3, h)
- self.assertGreaterEqual(h, h3)
- self.assertGreaterEqual(h3, h)
- self.assertLessEqual(h3, h3)
- self.assertLessEqual(h2, h2)
- self.assertLessEqual(h, h)
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/tests/ds/test_HeapNode.py b/tests/ds/test_HeapNode.py
new file mode 100644
index 00000000..de9e3161
--- /dev/null
+++ b/tests/ds/test_HeapNode.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+
+"""
+# Meta info
+
+Author: Nelson Brochado
+Created: 05/02/2017
+Updated: 05/02/2017
+
+# Description
+
+Tests for the HeapNode class in Heap.py.
+
+"""
+
+import unittest
+
+from ands.ds.Heap import HeapNode
+
+
+class TestHeapNode(unittest.TestCase):
+ def test_creation_argument_None(self):
+ self.assertRaises(ValueError, HeapNode, None)
+
+ def test_after_default_creation_same_key_value(self):
+ n = HeapNode(26)
+ self.assertIsNotNone(n.value)
+ self.assertEqual(n.key, n.value)
+
+ def test_creation_with_custom_value(self):
+ n = HeapNode(2, "two")
+ self.assertIsNotNone(n.value)
+ self.assertNotEqual(n.value, n.key)
+
+ def test_heap_node_equal_to_itself(self):
+ h = HeapNode(3, "three")
+ self.assertEqual(h, h)
+
+ def test_not_equal_when_different_values_but_same_keys(self):
+ a = HeapNode("3", 3)
+ b = HeapNode("3", "three")
+ self.assertNotEqual(a, b)
+
+ def test_not_equal_when_different_keys_but_same_values(self):
+ a = HeapNode("1", "x")
+ b = HeapNode("3", "x")
+ self.assertNotEqual(a, b)
+
+ def test_not_equal_when_different_keys_and_values(self):
+ a = HeapNode(2, "x")
+ b = HeapNode(3, "y")
+ self.assertNotEqual(a, b)
+
+ def test_equal_when_same_key_and_value(self):
+ a = HeapNode(2, "two")
+ b = HeapNode(2, "two")
+ self.assertEqual(a, b)
+
+ def test_less_than_when_key_is_smaller_and_values_equal_to_keys(self):
+ a = HeapNode(12)
+ b = HeapNode(14)
+ self.assertLess(a, b)
+
+ def test_greater_than_when_key_is_greater_and_values_equal_to_keys(self):
+ a = HeapNode(12)
+ b = HeapNode(14)
+ self.assertGreater(b, a)
+
+ def test_less_than_only_key_is_used(self):
+ a = HeapNode(3, "three")
+ b = HeapNode(5, "zero")
+ self.assertLess(a, b)
+
+ def test_greater_than_only_key_is_used(self):
+ a = HeapNode(3, 100)
+ b = HeapNode(4, "zero")
+ self.assertGreater(b, a)
+
+ def test_heap_node_not_greater_than_itself(self):
+ a = HeapNode(11)
+ b = HeapNode(11, "eleven")
+ self.assertFalse(a > a)
+ self.assertFalse(b > b)
+
+ def test_heap_node_not_smaller_than_itself(self):
+ a = HeapNode(11)
+ b = HeapNode(13, "thirteen")
+ self.assertFalse(a < a)
+ self.assertFalse(b < b)
+
+ def test_heap_node_is_less_than_or_equal_to_itself(self):
+ a = HeapNode(2, "two")
+ self.assertTrue(a <= a)
+ self.assertLessEqual(a, a)
+
+ def test_heap_node_is_greater_than_or_equal_to_itself(self):
+ a = HeapNode(2, "two")
+ self.assertTrue(a >= a)
+ self.assertGreaterEqual(a, a)
+
+ def test_greater_than_or_equal_keys_equal_to_values(self):
+ a = HeapNode(13)
+ b = HeapNode(17)
+ self.assertGreaterEqual(b, a)
+
+ def test_less_than_or_equal_keys_equal_to_values(self):
+ a = HeapNode(13)
+ b = HeapNode(17)
+ self.assertLessEqual(a, b)
+
+ def test_greater_than_or_equal_keys_not_equal_to_values(self):
+ a = HeapNode(13, "13")
+ b = HeapNode(17, "seventeen")
+ self.assertGreaterEqual(b, a)
+
+ def test_less_than_or_equal_keys_not_equal_to_values(self):
+ a = HeapNode(13, "one three")
+ b = HeapNode(17, "17")
+ self.assertLessEqual(a, b)
diff --git a/tests/ds/test_MaxHeap.py b/tests/ds/test_MaxHeap.py
index 969de632..45297536 100755
--- a/tests/ds/test_MaxHeap.py
+++ b/tests/ds/test_MaxHeap.py
@@ -2,11 +2,13 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
-Creation: 17/02/16
+Author: Nelson Brochado
+Created: 17/02/2016
+Updated: 05/02/2017
-Last update: 15/10/16
+# Description
Tests for the MaxHeap class.
"""
@@ -522,7 +524,3 @@ def test_is_on_odd_level(self):
self.assertFalse(h.is_on_odd_level(6))
self.assertTrue(h.is_on_odd_level(7))
self.assertTrue(h.is_on_odd_level(8))
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/tests/ds/test_MinHeap.py b/tests/ds/test_MinHeap.py
index 8aeb8c2c..e3c452ac 100755
--- a/tests/ds/test_MinHeap.py
+++ b/tests/ds/test_MinHeap.py
@@ -2,11 +2,13 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
-Creation: 14/02/16
+Author: Nelson Brochado
+Created: 14/02/2016
+Updated: 05/02/2017
-Last update: 01/01/17
+# Description
Tests for the MinHeap class.
"""
@@ -580,7 +582,3 @@ def test_is_on_odd_level(self):
self.assertFalse(h.is_on_odd_level(6))
self.assertTrue(h.is_on_odd_level(7))
self.assertTrue(h.is_on_odd_level(8))
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/tests/ds/test_MinMaxHeap.py b/tests/ds/test_MinMaxHeap.py
index 71ed1ad4..8a6e369c 100755
--- a/tests/ds/test_MinMaxHeap.py
+++ b/tests/ds/test_MinMaxHeap.py
@@ -2,11 +2,13 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
-Creation: 20/02/16
+Author: Nelson Brochado
+Created: 20/02/2016
+Updated: 05/02/2017
-Last Update: 08/10/16
+# Description
Tests for the MinMaxHeap class.
"""
diff --git a/tests/ds/test_Queue.py b/tests/ds/test_Queue.py
index 6f8cdf43..16d9b19c 100644
--- a/tests/ds/test_Queue.py
+++ b/tests/ds/test_Queue.py
@@ -3,8 +3,14 @@
"""
+# Meta info
+
Author: Nelson Brochado
Created: 24/01/2017
+
+# Description
+
+Tests for the Queue class.
"""
import unittest
diff --git a/tests/ds/test_RBT.py b/tests/ds/test_RBT.py
index 36484a3c..b01911e8 100755
--- a/tests/ds/test_RBT.py
+++ b/tests/ds/test_RBT.py
@@ -2,13 +2,16 @@
# -*- coding: utf-8 -*-
"""
-Author: Nelson Brochado
+# Meta info
-Creation: 15/02/16
+Author: Nelson Brochado
+Created: 15/02/2016
+Updated: 08/10/2017
-Last update: 08/10/16
+# Description
Tests for the RBT class.
+
"""
import unittest
@@ -435,7 +438,3 @@ def test_remove_min(self):
_m = rbt.remove_min()
self.assertEqual(m, _m)
self.assertIsNone(rbt.search(6))
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)