[ale] 3-D arrays in python...

David Jackson deepbsd.ale at gmail.com
Sat Jun 27 15:10:36 EDT 2015


Oops, looks like I accidentally pasted the test_naivearr2.py twice!  Egad!
Sorry!

The test should end after

if __name__ == "__main__":
    unittest.main()

So solly!
Dave

On Sat, Jun 27, 2015 at 2:33 PM, David Jackson <deepbsd.ale at gmail.com>
wrote:

> Hi!
>
> So I'm having a little trouble in Python4.  One of the assignments is to
> create a 3-d array from a 2-d array, using the array module.  The array as
> introduced in the lesson is a list, but could be another data structure.
> For this assignment, it asks for a list implementation.  Here's the 2-d
> array as introduced in the text.  First, the test, since we're learning
> agile and test-driven development:
>
> *** snip of testarray.py ***
>
> #!/usr/bin/env python3
>
> """
> testarray.py: Test list-of-list based array implementations using tuple
> subscripting.
> """
>
> import unittest
> import arr_single_list as arr
>
> class TestArray(unittest.TestCase):
>
>     def test_zeroes(self):
>         for N in range(4):
>             a = arr.array(N, N)
>             for i in range(N):
>                 for j in range(N):
>                     #self.assertEqual(a[i][j], 0)
>                     self.assertEqual(a[i, j], 0)
>
>     def test_identity(self):
>         for N in range(4):
>             a = arr.array(N, N)
>             for i in range(N):
>                 #a[i][i] = 1
>                 a[i, i] = 1
>             for i in range(N):
>                 for j in range(N):
>                     #self.assertEqual(a[i][j], i==j)
>                     self.assertEqual(a[i, j], i==j)
>
>     def test_one_cell(self):
>         N = 10
>         a = arr.array(N,N)
>         a[2,3] = 1
>         for i in range(N):
>             for j in range(N):
>                 if i==2 and j==3:
>                     self.assertEqual(a[i,j], 1)
>                 else:
>                     self.assertEqual(a[i,j], 0)
>
>
>     def _index(self, a, r, c):
>         return a[r, c]
>
>     def test_key_validity(self):
>         a = arr.array(10, 10)
>         self.assertRaises(KeyError, self._index, a, -1, 1)
>         self.assertRaises(KeyError, self._index, a, 10, 1)
>         self.assertRaises(KeyError, self._index, a, 1, -1)
>         self.assertRaises(KeyError, self._index, a, 1, 10)
>
>
> if __name__ == "__main__":
>     unittest.main()
>
> *** end snip of test_array.py ***
>
> Here's the 2-D array called called arr_single_list.py:
>
> *** start snip of arr_single_list.py  ***
> #!/usr/bin/env python3
>
> """
> arr_single_list.py:  Class-based single-list allowing tuple subscripting.
> """
>
> class array:
>
>     def __init__(self, M, N):
>         "Create a list long enough to hold M*N elements."
>         self._data = [0] * M * N
>         self._rows = M
>         self._cols = N
>
>
>     def __getitem__(self, key):
>         "Returns the appropriate element for a two-element subscript
> tuple."
>         row, col = self._validate_key(key)
>         return self._data[row*self._cols+col]
>
>     def __setitem__(self, key, value):
>         "Sets the appropriate element for a two-element subscript tuple."
>         row, col = self._validate_key(key)
>         self._data[row*self._cols+col] = value
>
>     def _validate_key(self, key):
>         '''
>         Validates a key against the array's shape, returning good tuples.
>         Raises KeyError on problems.
>         '''
>         row, col = key
>         if (0 <= row < self._rows and 0 <= col < self._cols):
>             return key
>         raise KeyError("subscript out of range")
>
> ***  end snip of arr_single_list.py ***
>
> Okay, this all seems pretty simple, and it ran just fine through the
> tests.  The __{get|set}item__ methods
> seem to be row oriented and simply take successive rows and stick them
> each onto the end of the list.
> Fine.  So a third dimension, would, I should think, be fairly simple, but
> I seem to have missed something.
>
> Here's my file, called naivearr2.py:
>
> *** start snip of naivearr2.py  ***
> #!/usr/bin/env python3
>
> """
> naievearr2.py:  Naive implementation of 3-D array using lists and tuple
> subscripts
> """
>
> import array as sys_array
>
> class array:
>
>     def __init__(self, M, N, O):
>         "Create 3-D array of lists"
>         self._data = sys_array.array("i", [0] * M * N * O)
>         self._rows = M
>         self._cols = N
>         self._depth = O
>
>     def __getitem__(self, key):
>         "returns the appropriate element for a three-element subscript
> tuple."
>         row, col, depth = self._validate_key(key)
>         return self._data[row*self._cols+col*self._depth+depth]
>
>     def __setitem__(self, key, value):
>         "sets the appropriate element for a three-element subscript tuble."
>         row, col, depth = self._validate_key(key)
>         self._data[row*self._cols+col*self._depth+depth] = value
>
>     def _validate_key(self, key):
>         """Validates a key against the array's shape, returning good
> tuples.
>         Raises KeyError on problems."""
>         row, col, depth = key
>         if (0 <= row < self._rows and 0 <= col < self._cols and 0 <= depth
> < self._depth):
>             return key
>         raise KeyError("subscript out of range")
>
> *** end snip of naivearr2.py ***
>
>
> I thought for sure this would work, but there's a gotcha in there
> somewhere.  Sure enough, the
> __setitem__ sets the correct cells to '1' when in the code below, but I
> get extras set to one as well:
>
>
> *** start snip of test_naivearr2.py ***
> import unittest
> import naivearr2 as arr
>
>
> class TestArray(unittest.TestCase):
>     def test_zeroes(self):
>         for N in range(6):
>             a = arr.array(N, N, N)
>             for i in range(N):
>                 for j in range(N):
>                     for k in range(N):
>                         #print("N={}, i={}, j={}, k={}".format(N, i, j, k))
>                         self.assertEqual(a[i, j, k], 0)
>
>     def test_identity(self):
>         for N in range(6):
>             a = arr.array(N, N, N)
>             for i in range(N):
>                 a[i, i, i] = 1
>                 print("a[{},{},{}] ".format(i, i, i))
>             for i in range(N):
>                 for j in range(N):
>                     for k in range(N):
>                         if i==j==k:
>                             #print("***A[{},{},{}]".format(i, j, k))
>                             self.assertEqual(a[i, j, k], 1)
>                         if not i==j==k and a[i,j,k] == 1:
>                             print("Dammit!  A[{},{},{}] == 1".format(i, j,
> k))
>                             #self.assertEqual(a[i,j,k], 0)
>
>     def _index(self, a, r, c, d):
>         return a[r, c, d]
>
>     def test_key_validity(self):
>         a = arr.array(10, 10, 10)
>         self.assertRaises(KeyError, self._index, a, -1, 1, 1)
>         self.assertRaises(KeyError, self._index, a, 10, 1, 10)
>         self.assertRaises(KeyError, self._index, a, 1, -1, -10)
>         self.assertRaises(KeyError, self._index, a, 1, 10, -1)
>
>
>
> if __name__ == "__main__":
>     unittest.main()
> import unittest
> import naivearr2 as arr
>
>
> class TestArray(unittest.TestCase):
>     def test_zeroes(self):
>         for N in range(6):
>             a = arr.array(N, N, N)
>             for i in range(N):
>                 for j in range(N):
>                     for k in range(N):
>                         #print("N={}, i={}, j={}, k={}".format(N, i, j, k))
>                         self.assertEqual(a[i, j, k], 0)
>
>     def test_identity(self):
>         for N in range(6):
>             a = arr.array(N, N, N)
>             for i in range(N):
>                 a[i, i, i] = 1
>                 print("a[{},{},{}] ".format(i, i, i))
>             for i in range(N):
>                 for j in range(N):
>                     for k in range(N):
>                         if i==j==k:
>                             #print("***A[{},{},{}]".format(i, j, k))
>                             self.assertEqual(a[i, j, k], 1)
>                         if not i==j==k and a[i,j,k] == 1:
>                             print("Dammit!  A[{},{},{}] == 1".format(i, j,
> k))
>                             #self.assertEqual(a[i,j,k], 0)
>
>     def _index(self, a, r, c, d):
>         return a[r, c, d]
>
>     def test_key_validity(self):
>         a = arr.array(10, 10, 10)
>         self.assertRaises(KeyError, self._index, a, -1, 1, 1)
>         self.assertRaises(KeyError, self._index, a, 10, 1, 10)
>         self.assertRaises(KeyError, self._index, a, 1, -1, -10)
>         self.assertRaises(KeyError, self._index, a, 1, 10, -1)
>
>
>
> if __name__ == "__main__":
>     unittest.main()
>
> *** end snip of test_naivearr2.py ***
>
> Everything passes except test_identity.   Sure enough, a[0,0,0] = 1,
> a[1,1,1]=1, etc,
> but I also get
> A[0,2,1] == 1
> A[0,4,2] == 1
> A[1,3,2] == 1
> A[2,0,4] == 1
> A[2,4,3] == 1
> A[3,1,2] == 1
> A[4,0,2] == 1
> A[4,2,3] == 1
>
>
> So I guess my __setitem__ is goofy.  Or I guess I could be calling a value
> with
> __getitem__ that is the wrong value.
>
> Can anyone see what I'm doing wrong?
>
> Any help is appreciated, and thanks in advance!
>
> Dave
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.ale.org/pipermail/ale/attachments/20150627/7b2ac620/attachment.html>


More information about the Ale mailing list