Skip to content

Commit 64bb29b

Browse files
czgdp1807pratikgl
andauthored
Backport 0.0.1 (#430)
* Changed version to 0.0.1-alpha * pydatastructs -> pydatastructs_ for PyPI * pydatasturcts_ -> cz-pydatastructs * Removed incorrect topic * Updated installation instructions on website * Minor typo fix in documentation * Doc improvements (ODA, DODA) and addition of checks in ``graph`` (#424) * Made the API of ``RangeQueryStatic`` consistent (#425) * Added notebook for California road network (#426) * Added salient features of PyDataStructs (#428) * Bumped to 0.0.1-beta * Bumped to 0.0.1 * Updated for master Co-authored-by: Pratik Goyal <pratikgoyal2712@gmail.com>
1 parent 2a89817 commit 64bb29b

17 files changed

+346
-43
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,11 @@ Keep contributing!!
101101
Thanks to these wonderful people ✨✨:
102102

103103
<table>
104-
<tr>
105-
<td>
106-
<a href="/codezonediitj/pydatastructs/graphs/contributors">
107-
<img src="https://contrib.rocks/image?repo=codezonediitj/pydatastructs" />
108-
</a>
109-
</td>
110-
</tr>
104+
<tr>
105+
<td>
106+
<a href="/codezonediitj/pydatastructs/graphs/contributors">
107+
<img src="https://contrib.rocks/image?repo=codezonediitj/pydatastructs" />
108+
</a>
109+
</td>
110+
</tr>
111111
</table>

docs/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
sphinx==4.2.0
2-
sphinx-readable-theme==1.3.0
2+
sphinx-readable-theme==1.3.0
3+
myst_nb==0.13.1

docs/source/conf.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
master_doc = 'index'
2727

2828
# The full version, including alpha/beta/rc tags
29-
release = '0.0.1-dev'
29+
release = '1.0.1-dev'
3030

3131

3232
# -- General configuration ---------------------------------------------------
@@ -36,9 +36,12 @@
3636
# ones.
3737
extensions = [
3838
'sphinx.ext.autodoc',
39-
'sphinx.ext.napoleon'
39+
'sphinx.ext.napoleon',
40+
'myst_nb'
4041
]
4142

43+
jupyter_execute_notebooks = "off"
44+
4245
napoleon_numpy_docstring = True
4346

4447
# Add any paths that contain templates here, relative to this directory.

docs/source/index.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ the other,
4040

4141
Make sure that your python version is at least ``3.8``.
4242

43+
Why PyDataStructs?
44+
==================
45+
46+
1. **Single package for all your data structures and algorithms** - We have and are
47+
implementing many popular and useful data structures and algorithms.
48+
49+
2. **Consistent and Clean Interface** - The APIs we have provided are **consistent** with each other,
50+
**clean** and **easy to use**. We make sure of that before adding any new data structure or algorithm.
51+
52+
3. **Well Tested** - We thoroughly test our code before making any new addition to PyDataStructs.
53+
**99 percent** lines of our code have already been tested by us.
54+
55+
So, **you can easily rely on PyDataStructs** for any data structure or algorithm you want to use
56+
**without worrying about implementing** it **from scratch**. Everything is just a few calls away.
57+
4358
Why do we use Python?
4459
=====================
4560

@@ -59,6 +74,7 @@ Contents
5974
:maxdepth: 1
6075

6176
tutorials.rst
77+
pydatastructs_sphinx_graphs
6278
contributing.rst
6379
authors.rst
6480
pydatastructs/pydatastructs.rst

docs/source/pydatastructs_sphinx_graphs.ipynb

Lines changed: 243 additions & 0 deletions
Large diffs are not rendered by default.

docs/source/tutorials.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Tutorials
44
We provide the following tutorials to show how ``pydatastructs``
55
APIs can help in solving complicated data structures and algorithms
66
problems easily. For now the problems are abstract. However, we plan
7-
to add some examples showing usage of ``pydatastructs`` on real world
7+
to add some more examples showing usage of ``pydatastructs`` on real world
88
data sets such as `Stanford Large Network Dataset Collection <https://snap.stanford.edu/data/>`_
99
and `Urban Dictionary Words And Definitions <https://www.kaggle.com/therohk/urban-dictionary-words-dataset>`_.
1010
If you are interested in playing around with the above datasets using our API,

pydatastructs/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.0.1-dev"
1+
__version__ = "1.0.1-dev"
22

33
from .linear_data_structures import *
44
from .trees import *

pydatastructs/graphs/adjacency_list.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ def __new__(cls, *vertices):
2626
@classmethod
2727
def methods(self):
2828
return ['is_adjacent', 'neighbors',
29-
'add_vertex', 'remove_vertex', 'add_edge',
30-
'get_edge', 'remove_edge', '__new__']
29+
'add_vertex', 'remove_vertex', 'add_edge',
30+
'get_edge', 'remove_edge', '__new__']
3131

3232
def is_adjacent(self, node1, node2):
3333
node1 = self.__getattribute__(node1)
@@ -52,8 +52,21 @@ def remove_vertex(self, name):
5252
node_obj.adjacent.remove(name)
5353

5454
def add_edge(self, source, target, cost=None):
55+
source, target = str(source), str(target)
56+
error_msg = ("Vertex %s is not present in the graph."
57+
"Call Graph.add_vertex to add a new"
58+
"vertex. Graph.add_edge is only responsible"
59+
"for adding edges and it will not add new"
60+
"vertices on its own. This is done to maintain"
61+
"clear separation between the functionality of"
62+
"these two methods.")
63+
if not hasattr(self, source):
64+
raise ValueError(error_msg % (source))
65+
if not hasattr(self, target):
66+
raise ValueError(error_msg % (target))
67+
5568
source, target = self.__getattribute__(source), \
56-
self.__getattribute__(target)
69+
self.__getattribute__(target)
5770
source.add_adjacent_node(target.name)
5871
if cost is not None:
5972
self.edge_weights[source.name + "_" + target.name] = \

pydatastructs/graphs/adjacency_matrix.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ def remove_vertex(self, node):
5757

5858
def add_edge(self, source, target, cost=None):
5959
source, target = str(source), str(target)
60+
error_msg = ("Vertex %s is not present in the graph."
61+
"Call Graph.add_vertex to add a new"
62+
"vertex. Graph.add_edge is only responsible"
63+
"for adding edges and it will not add new"
64+
"vertices on its own. This is done to maintain"
65+
"clear separation between the functionality of"
66+
"these two methods.")
67+
if source not in self.matrix:
68+
raise ValueError(error_msg % (source))
69+
if target not in self.matrix:
70+
raise ValueError(error_msg % (target))
71+
6072
self.matrix[source][target] = True
6173
if cost is not None:
6274
self.edge_weights[source + "_" + target] = \

pydatastructs/graphs/graph.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ class Graph(object):
4949
==========
5050
5151
.. [1] https://en.wikipedia.org/wiki/Graph_(abstract_data_type)
52+
53+
Note
54+
====
55+
56+
Make sure to create nodes (AdjacencyListGraphNode or AdjacencyMatrixGraphNode)
57+
and them in your graph using Graph.add_vertex before adding edges whose
58+
end points require either of the nodes that you added. In other words,
59+
Graph.add_edge doesn't add new nodes on its own if the input
60+
nodes are not already present in the Graph.
61+
5262
"""
5363

5464
__slots__ = ['_impl']
@@ -89,15 +99,16 @@ def neighbors(self, node):
8999

90100
def add_vertex(self, node):
91101
"""
92-
Adds the input vertex to the node.
102+
Adds the input vertex to the node, or does nothing
103+
if the input vertex is already in the graph.
93104
"""
94105
raise NotImplementedError(
95106
"This is an abstract method.")
96107

97108
def remove_vertex(self, node):
98109
"""
99110
Removes the input vertex along with all the edges
100-
pointing towards to it.
111+
pointing towards it.
101112
"""
102113
raise NotImplementedError(
103114
"This is an abstract method.")

pydatastructs/graphs/tests/test_adjacency_list.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from pydatastructs.graphs import Graph
22
from pydatastructs.utils import AdjacencyListGraphNode
3+
from pydatastructs.utils.raises_util import raises
34

45
def test_adjacency_list():
56
v_1 = AdjacencyListGraphNode('v_1', 1)
@@ -38,3 +39,6 @@ def test_adjacency_list():
3839
g.remove_vertex('v')
3940
assert g.is_adjacent('v_2', 'v') is False
4041
assert g.is_adjacent('v_3', 'v') is False
42+
43+
assert raises(ValueError, lambda: g.add_edge('u', 'v'))
44+
assert raises(ValueError, lambda: g.add_edge('v', 'x'))

pydatastructs/graphs/tests/test_adjacency_matrix.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from pydatastructs.graphs import Graph
22
from pydatastructs.utils import AdjacencyMatrixGraphNode
3+
from pydatastructs.utils.raises_util import raises
34

45
def test_AdjacencyMatrix():
56
v_0 = AdjacencyMatrixGraphNode(0, 0)
@@ -25,3 +26,6 @@ def test_AdjacencyMatrix():
2526
assert neighbors == [v_1]
2627
g.remove_edge(0, 1)
2728
assert g.is_adjacent(0, 1) is False
29+
30+
assert raises(ValueError, lambda: g.add_edge('u', 'v'))
31+
assert raises(ValueError, lambda: g.add_edge('v', 'x'))

pydatastructs/linear_data_structures/arrays.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ def __str__(self) -> str:
1515

1616
class OneDimensionalArray(Array):
1717
'''
18-
Represents one dimensional arrays.
18+
Represents one dimensional static arrays of
19+
fixed size.
1920
2021
Parameters
2122
==========
@@ -269,7 +270,8 @@ class DynamicArray(Array):
269270

270271
class DynamicOneDimensionalArray(DynamicArray, OneDimensionalArray):
271272
"""
272-
Represents dynamic one dimensional arrays.
273+
Represents resizable and dynamic one
274+
dimensional arrays.
273275
274276
Parameters
275277
==========

pydatastructs/miscellaneous_data_structures/algorithms.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ class RangeQueryStatic:
5353
>>> from pydatastructs import minimum
5454
>>> arr = OneDimensionalArray(int, [4, 6, 1, 5, 7, 3])
5555
>>> RMQ = RangeQueryStatic(arr, minimum)
56-
>>> RMQ.query(3, 5)
56+
>>> RMQ.query(3, 4)
5757
5
58-
>>> RMQ.query(0, 5)
58+
>>> RMQ.query(0, 4)
5959
1
60-
>>> RMQ.query(0, 3)
60+
>>> RMQ.query(0, 2)
6161
1
6262
6363
Note
@@ -97,9 +97,7 @@ def query(start, end):
9797
start: int
9898
The starting index of the range.
9999
end: int
100-
The index just before which the range ends.
101-
This means that this index will be excluded
102-
from the range for generating results.
100+
The ending index of the range.
103101
"""
104102
raise NotImplementedError(
105103
"This is an abstract method.")
@@ -121,7 +119,7 @@ def methods(cls):
121119
return ['query']
122120

123121
def query(self, start, end):
124-
_check_range_query_inputs((start, end), self.bounds)
122+
_check_range_query_inputs((start, end + 1), self.bounds)
125123
return self.sparse_table.query(start, end)
126124

127125

@@ -140,14 +138,14 @@ def methods(cls):
140138
return ['query']
141139

142140
def query(self, start, end):
143-
_check_range_query_inputs((start, end), (0, len(self.array)))
141+
_check_range_query_inputs((start, end + 1), (0, len(self.array)))
144142

145-
rsize = end - start
143+
rsize = end - start + 1
146144

147145
if rsize == 1:
148146
return self.func((self.array[start],))
149147

150148
query_ans = self.func((self.array[start], self.array[start + 1]))
151-
for i in range(start + 2, end):
149+
for i in range(start + 2, end + 1):
152150
query_ans = self.func((query_ans, self.array[i]))
153151
return query_ans

pydatastructs/miscellaneous_data_structures/sparse_table.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,8 @@ def query(self, start, end):
8686
start: int
8787
The starting index of the range.
8888
end: int
89-
The index just before which the range ends.
90-
This means that this index will be excluded
91-
from the range for generating results.
89+
The ending index of the range.
9290
"""
93-
end -= 1
9491
j = int(math.log2(end - start + 1)) + 1
9592
answer = None
9693
while j >= 0:

pydatastructs/miscellaneous_data_structures/tests/test_range_query_static.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ def _test_RangeQueryStatic_common(func, gen_expected):
1212

1313
array = OneDimensionalArray(int, [1])
1414
rq = RangeQueryStatic(array, func)
15-
assert rq.query(0, 1) == 1
16-
raises(ValueError, lambda: rq.query(0, 0))
17-
raises(IndexError, lambda: rq.query(0, 2))
15+
assert rq.query(0, 0) == 1
16+
raises(ValueError, lambda: rq.query(0, -1))
17+
raises(IndexError, lambda: rq.query(0, 1))
1818

1919
array_sizes = [3, 6, 12, 24, 48, 96]
2020
random.seed(0)
@@ -38,18 +38,18 @@ def _test_RangeQueryStatic_common(func, gen_expected):
3838
def test_RangeQueryStatic_minimum():
3939

4040
def _gen_minimum_expected(data, i, j):
41-
return min(data[i:j])
41+
return min(data[i:j + 1])
4242

4343
_test_RangeQueryStatic_common(minimum, _gen_minimum_expected)
4444

4545
def test_RangeQueryStatic_greatest_common_divisor():
4646

4747
def _gen_gcd_expected(data, i, j):
48-
if j - i == 1:
48+
if j == i:
4949
return data[i]
5050
else:
5151
expected_gcd = math.gcd(data[i], data[i + 1])
52-
for idx in range(i + 2, j):
52+
for idx in range(i + 2, j + 1):
5353
expected_gcd = math.gcd(expected_gcd, data[idx])
5454
return expected_gcd
5555

@@ -58,6 +58,6 @@ def _gen_gcd_expected(data, i, j):
5858
def test_RangeQueryStatic_summation():
5959

6060
def _gen_summation_expected(data, i, j):
61-
return sum(data[i:j])
61+
return sum(data[i:j + 1])
6262

6363
return _test_RangeQueryStatic_common(summation, _gen_summation_expected)

setup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
long_description = fh.read()
55

66
setuptools.setup(
7-
name="pydatastructs",
8-
version="0.0.1-dev",
7+
name="cz-pydatastructs",
8+
version="1.0.1-dev",
99
author="PyDataStructs Development Team",
1010
author_email="pydatastructs@googlegroups.com",
1111
description="A python package for data structures",
@@ -17,7 +17,6 @@
1717
"Programming Language :: Python :: 3",
1818
"License :: OSI Approved :: BSD License",
1919
"Operating System :: OS Independent",
20-
"Topic :: Education :: Data Structures",
2120
"Topic :: Scientific/Engineering",
2221
"Topic :: Scientific/Engineering :: Information Analysis",
2322
"Topic :: Software Development :: Libraries"

0 commit comments

Comments
 (0)