Skip to content

Commit f6fe03d

Browse files
committed
separated sparse array from sparse array using slices, have all tests passing, probably need more tests
1 parent 3ed5433 commit f6fe03d

File tree

4 files changed

+197
-2
lines changed

4 files changed

+197
-2
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ slides_sources/build
33
#ignore compiled files, sublime workspace and project files
44
*.pyc
55
*.sublime*
6-
6+
*.*~
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
2+
"""
3+
example of emulating a sequence using slices
4+
"""
5+
6+
class SparseArray(object):
7+
8+
def __init__(self, my_array=()):
9+
self.length = len(my_array)
10+
self.sparse_array = self.convert_to_sparse(my_array)
11+
12+
def convert_to_sparse(self, my_array):
13+
sparse_array = {}
14+
for index, number in enumerate(my_array):
15+
if number:
16+
sparse_array[index] = number
17+
return sparse_array
18+
19+
def __len__(self):
20+
return self.length
21+
22+
def __getitem__(self, index):
23+
print('index', index)
24+
print('length', self.length)
25+
# create a list of the slice they want returned
26+
mini_array = []
27+
if isinstance(index, int):
28+
return self.get_single_value(index)
29+
elif isinstance(index, slice):
30+
start, stop, step = index.indices(len(self))
31+
if step is None:
32+
step = 1
33+
key = start
34+
mini_array = []
35+
while key < stop + 1:
36+
print('key', key)
37+
mini_array.append(self.get_single_value(key))
38+
key += step
39+
else:
40+
raise TypeError("index must be int or slice")
41+
return mini_array[:]
42+
43+
def get_single_value(self, key):
44+
if key >= self.length:
45+
raise IndexError('array index out of range')
46+
else:
47+
return self.sparse_array.get(key, 0)
48+
49+
def __setitem__(self, index, value):
50+
if isinstance(index, int):
51+
self.set_single_value(index, value)
52+
elif isinstance(index, slice):
53+
start, stop, step = index.indices(len(self))
54+
if step is None:
55+
step = 1
56+
key = start
57+
for each in value:
58+
print('key', key)
59+
self.set_single_value(key, each)
60+
key += step
61+
else:
62+
raise TypeError("index must be int or slice")
63+
64+
def set_single_value(self, key, value):
65+
if key > self.length:
66+
raise IndexError('array assignment index out of range')
67+
if value != 0:
68+
self.sparse_array[key] = value
69+
else:
70+
# if the value is being set to zero, we probably need to
71+
# remove a key from our dictionary.
72+
self.sparse_array.pop(key, None)
73+
74+
def __delitem__(self, key):
75+
# we probably need to move the keys if we are not deleting the last
76+
# number, use pop in case it was a zero
77+
if key == self.length - 1:
78+
self.sparse_array.pop(key, None)
79+
else:
80+
# since we need to adjust all of the keys after the one we are
81+
# deleting, probably most efficient to create a new dictionary
82+
new_dict = {}
83+
for k, v in self.sparse_array.iteritems():
84+
if k >= key:
85+
new_dict[k - 1] = v
86+
else:
87+
new_dict[k] = v
88+
# note we don't want to do update, since we need to make sure we are
89+
# getting rid of the old keys, when we moved the value to a new key
90+
self.sparse_array = new_dict
91+
# length is now one shorter
92+
self.length -= 1
93+
94+
95+
96+
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import pytest
2+
from slice_sparse import SparseArray
3+
4+
5+
def set_up():
6+
my_array = [2, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, 0, 2, 9]
7+
my_sparse = SparseArray(my_array)
8+
return (my_array, my_sparse)
9+
10+
def test_object_exists():
11+
my_array, my_sparse = set_up()
12+
assert isinstance(my_sparse, SparseArray)
13+
14+
def test_get_non_zero_number():
15+
my_array, my_sparse = set_up()
16+
assert my_sparse[4] == 3
17+
18+
def test_get_zero():
19+
my_array, my_sparse = set_up()
20+
assert my_sparse[1] == 0
21+
22+
def test_get_element_not_in_array():
23+
my_array, my_sparse = set_up()
24+
with pytest.raises(IndexError):
25+
my_sparse[14]
26+
27+
def test_get_slice():
28+
my_array, my_sparse = set_up()
29+
assert my_sparse[2:4] == [0, 0, 3]
30+
31+
def test_get_lenght():
32+
my_array, my_sparse = set_up()
33+
assert len(my_sparse) == 14
34+
35+
def test_change_number_in_array():
36+
my_array, my_sparse = set_up()
37+
my_sparse[0] = 3
38+
assert my_sparse[0] == 3
39+
# make sure others aren't changed
40+
assert my_sparse[1] == 0
41+
# make sure still same length
42+
assert len(my_sparse) == 14
43+
44+
def test_change_number_in_array_to_zero():
45+
my_array, my_sparse = set_up()
46+
my_sparse[4] = 0
47+
assert my_sparse[4] == 0
48+
# make sure still same length
49+
assert len(my_sparse) == 14
50+
51+
def test_change_number_in_array_from_zero():
52+
my_array, my_sparse = set_up()
53+
my_sparse[1] = 4
54+
assert my_sparse[1] == 4
55+
# make sure still same length
56+
assert len(my_sparse) == 14
57+
58+
def test_change_slice():
59+
my_array, my_sparse = set_up()
60+
my_sparse[1:3] = [2, 3, 4]
61+
assert my_sparse[1:3] == [2, 3, 4]
62+
63+
def test_delete_number():
64+
my_array, my_sparse = set_up()
65+
del(my_sparse[4])
66+
# if we delete the 4 position, should now be zero
67+
assert my_sparse[4] == 0
68+
# should have smaller length
69+
assert len(my_sparse) == 13
70+
71+
def test_delete_zero():
72+
my_array, my_sparse = set_up()
73+
del(my_sparse[5])
74+
# should still be zero, but should have shorter length
75+
assert my_sparse[5] == 0
76+
assert len(my_sparse) == 13
77+
78+
def test_delete_last_number():
79+
my_array, my_sparse = set_up()
80+
del(my_sparse[13])
81+
# should get an error?
82+
print 'print some stuf damnit'
83+
with pytest.raises(IndexError):
84+
my_sparse[13]
85+
assert len(my_sparse) == 13
86+
87+
def test_indices_change():
88+
my_array, my_sparse = set_up()
89+
del(my_sparse[3])
90+
# next index should have changed
91+
# my_sparse[4] was 3 now
92+
# my_sparse[3] should be 3
93+
assert (my_sparse[3] == 3)

Solutions/Session08/test_sparse_array.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,16 @@ def test_delete_last_number():
7070
my_array, my_sparse = set_up()
7171
del(my_sparse[13])
7272
# should get an error?
73-
print 'print some stuf damnit'
7473
with pytest.raises(IndexError):
7574
my_sparse[13]
7675
assert len(my_sparse) == 13
7776

77+
def test_indices_change():
78+
my_array, my_sparse = set_up()
79+
del(my_sparse[3])
80+
# next index should have changed
81+
# my_sparse[4] was 3 now
82+
# my_sparse[3] should be 3
83+
assert (my_sparse[3] == 3)
7884

7985

0 commit comments

Comments
 (0)