From f8b41980292063dc7c93f48fa40e995ab2c83738 Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Tue, 22 Oct 2019 18:23:04 +0530 Subject: [PATCH 1/4] code added for dynamic arrays --- .../linear_data_structures/__init__.py | 1 + .../linear_data_structures/arrays.py | 57 ++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/__init__.py b/pydatastructs/linear_data_structures/__init__.py index 6225a2054..c13973d94 100644 --- a/pydatastructs/linear_data_structures/__init__.py +++ b/pydatastructs/linear_data_structures/__init__.py @@ -6,5 +6,6 @@ from .arrays import ( OneDimensionalArray, + DynamicOneDimensionalArray ) __all__.extend(arrays.__all__) diff --git a/pydatastructs/linear_data_structures/arrays.py b/pydatastructs/linear_data_structures/arrays.py index 2979a6189..58b3d1988 100644 --- a/pydatastructs/linear_data_structures/arrays.py +++ b/pydatastructs/linear_data_structures/arrays.py @@ -2,7 +2,8 @@ from pydatastructs.utils.misc_util import _check_type, NoneType __all__ = [ -'OneDimensionalArray' +'OneDimensionalArray', +'DynamicOneDimensionalArray' ] class Array(object): @@ -112,3 +113,57 @@ def fill(self, elem): elem = self._dtype(elem) for i in range(self._size): self._data[i] = elem + +ODA = OneDimensionalArray + +class DynamicArray(Array): + """ + Abstract class for dynamic arrays. + """ + pass + +class DynamicOneDimensionalArray(DynamicArray, OneDimensionalArray): + """ + """ + + def __new__(cls, dtype=NoneType, *args, **kwargs): + obj = super().__new__(cls, dtype, *args, **kwargs) + obj._load_factor = kwargs.get('load_factor', 0.25) + obj._num = 0 if obj._size == 0 or obj[0] == None else obj._size + obj._last_pos_filled = obj._num - 1 + return obj + + def _modify(self): + if self._num/self._size < self._load_factor: + arr_new = ODA(self._dtype, 2*self._num + 1) + j = 0 + for i in range(self._last_pos_filled + 1): + if self[i] != None: + arr_new[j] = self[i] + j += 1 + self._last_pos_filled = j - 1 + self._data = arr_new._data + self._size = arr_new._size + + def append(self, el): + if self._last_pos_filled + 1 == self._size: + arr_new = ODA(self._dtype, 2*self._size + 1) + for i in range(self._last_pos_filled + 1): + arr_new[i] = self[i] + arr_new[self._last_pos_filled + 1] = el + self._last_pos_filled += 1 + self._size = arr_new._size + self._num += 1 + self._data = arr_new._data + else: + self[self._last_pos_filled + 1] = el + self._last_pos_filled += 1 + self._num += 1 + self._modify() + + def delete(self, idx): + if idx <= self._last_pos_filled and idx >= 0 and \ + self[idx] != None: + self[idx] = None + self._num -= 1 + self._modify() From 3da00c401fc48e943436daacc793638143e2f5e1 Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Tue, 22 Oct 2019 18:49:28 +0530 Subject: [PATCH 2/4] testing complete for dynamic arrays --- .../linear_data_structures/arrays.py | 2 ++ .../tests/test_arrays.py | 20 ++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/arrays.py b/pydatastructs/linear_data_structures/arrays.py index 58b3d1988..e57b4699d 100644 --- a/pydatastructs/linear_data_structures/arrays.py +++ b/pydatastructs/linear_data_structures/arrays.py @@ -126,6 +126,8 @@ class DynamicOneDimensionalArray(DynamicArray, OneDimensionalArray): """ """ + __slots__ = ['_load_factor', '_num', '_last_pos_filled', '_size'] + def __new__(cls, dtype=NoneType, *args, **kwargs): obj = super().__new__(cls, dtype, *args, **kwargs) obj._load_factor = kwargs.get('load_factor', 0.25) diff --git a/pydatastructs/linear_data_structures/tests/test_arrays.py b/pydatastructs/linear_data_structures/tests/test_arrays.py index fe3adf0e4..525b702f2 100644 --- a/pydatastructs/linear_data_structures/tests/test_arrays.py +++ b/pydatastructs/linear_data_structures/tests/test_arrays.py @@ -1,4 +1,5 @@ -from pydatastructs.linear_data_structures import OneDimensionalArray +from pydatastructs.linear_data_structures import ( + OneDimensionalArray, DynamicOneDimensionalArray) from pydatastructs.utils.raises_util import raises @@ -17,3 +18,20 @@ def test_OneDimensionalArray(): raises(TypeError, lambda: ODA(int, 5.0)) raises(TypeError, lambda: ODA(int, set([1, 2, 3]))) raises(ValueError, lambda: ODA(int, 3, [1])) + +def test_DynamicOneDimensionalArray(): + DODA = DynamicOneDimensionalArray + A = DODA(int, 0) + A.append(1) + A.append(2) + A.append(3) + A.append(4) + A.delete(0) + A.delete(0) + A.delete(15) + A.delete(-1) + A.delete(1) + A.delete(2) + assert A._data == [4, None, None] + A.fill(4) + assert A._data == [4, 4, 4] From a35e6391f17a1f5760553992f4bbb65821afbe53 Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Tue, 22 Oct 2019 19:00:34 +0530 Subject: [PATCH 3/4] added docs --- .../linear_data_structures/arrays.py | 72 ++++++++++++++++++- .../tests/test_arrays.py | 1 + 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/arrays.py b/pydatastructs/linear_data_structures/arrays.py index e57b4699d..d13bebb87 100644 --- a/pydatastructs/linear_data_structures/arrays.py +++ b/pydatastructs/linear_data_structures/arrays.py @@ -124,18 +124,84 @@ class DynamicArray(Array): class DynamicOneDimensionalArray(DynamicArray, OneDimensionalArray): """ + Represents dynamic one dimensional arrays. + + Parameters + ========== + + dtype: type + A valid object type. + size: int + The number of elements in the array. + elements: list/tuple + The elements in the array, all should + be of same type. + init: a python type + The inital value with which the element has + to be initialized. By default none, used only + when the data is not given. + load_factor: float, by default 0.25 + The number below which if the ratio, Num(T)/Size(T) + falls then the array is contracted such that at + most only half the positions are filled. + + Raises + ====== + + ValueError + When the number of elements in the list do not + match with the size. + More than three parameters are passed as arguments. + Types of arguments is not as mentioned in the docstring. + The load factor is not of floating point type. + + Note + ==== + + At least one parameter should be passed as an argument along + with the dtype. + Num(T) means the number of positions which are not None in the + array. + Size(T) means the maximum number of elements that the array can hold. + + Examples + ======== + + >>> from pydatastructs import DynamicOneDimensionalArray as DODA + >>> arr = DODA(int, 0) + >>> arr.append(1) + >>> arr.append(2) + >>> arr[0] + 1 + >>> arr.delete(0) + >>> arr[0] + >>> arr[1] + 2 + >>> arr.append(3) + >>> arr.append(4) + >>> [arr[i] for i in range(arr.size)] + [None, 2, 3, 4, None, None, None] + + References + ========== + + .. [1] http://www.cs.nthu.edu.tw/~wkhon/algo09/lectures/lecture16.pdf """ __slots__ = ['_load_factor', '_num', '_last_pos_filled', '_size'] def __new__(cls, dtype=NoneType, *args, **kwargs): obj = super().__new__(cls, dtype, *args, **kwargs) - obj._load_factor = kwargs.get('load_factor', 0.25) + obj._load_factor = float(kwargs.get('load_factor', 0.25)) obj._num = 0 if obj._size == 0 or obj[0] == None else obj._size obj._last_pos_filled = obj._num - 1 return obj def _modify(self): + """ + Contracts the array if Num(T)/Size(T) falls + below load factor. + """ if self._num/self._size < self._load_factor: arr_new = ODA(self._dtype, 2*self._num + 1) j = 0 @@ -169,3 +235,7 @@ def delete(self, idx): self[idx] = None self._num -= 1 self._modify() + + @property + def size(self): + return self._size diff --git a/pydatastructs/linear_data_structures/tests/test_arrays.py b/pydatastructs/linear_data_structures/tests/test_arrays.py index 525b702f2..420882665 100644 --- a/pydatastructs/linear_data_structures/tests/test_arrays.py +++ b/pydatastructs/linear_data_structures/tests/test_arrays.py @@ -33,5 +33,6 @@ def test_DynamicOneDimensionalArray(): A.delete(1) A.delete(2) assert A._data == [4, None, None] + assert A.size == 3 A.fill(4) assert A._data == [4, 4, 4] From ab6b019027db9809bca0a4b55f1b4f726528a9cc Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Tue, 22 Oct 2019 19:07:03 +0530 Subject: [PATCH 4/4] removed python2.7 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1d67b35cc..70dc76969 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ sudo: false language: python python: - - "2.7" - "3.5" install: - pip install -r requirements.txt