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)