The objective of this assignment is to implement a contiguous implementation of the Vector ADT described below. For our purposes, "Vector" is synonymous with "List". The Vector ADT, like other List ADTs, describes a mutable sequence type that dynamically resizes as items are added or removed. The Vector ADT below includes a subset of the functionality of Python's built-in list type. For those methods that Vector does provide, the functionality of the Vector class will be mostly the same as the functionality of Python's list class, with some exceptions described below.
Advice on implementation can be found in Section 2.2 of our textbook. That section describes the implementation of many of Python's list methods. Your implementation doesn't need to follow those descriptions exactly, but efficiency does matter. For example, you will lose points if your implementation requires O(n) time to complete some operation that could be completed in O(1) time.
You must use the provided Array class defined in the module t_array.py as the underlying data structure for your Vector class. This is similar to the Array class described in our textbook with a few key differences. First, this Array class has visualization code that will allow us to inspect the contents of all of the arrays that are in existence at any one time. Second, objects of this array class need to be explicitly released when they are no longer needed.
In Python (and Java) there is a garbage collection process that
automatically frees up memory that is
no longer being referenced. In some programming languages, like C or
C++, it is the responsibility of the programmer to explicitly
release any memory that is no longer being used. The Array class
defined in t_array.py
brings with it that same
responsibility: the garbage collector will not free Array objects
automatically.
Part of your grade for this project will be based on writing code that has no "memory leaks". A memory leak occurs when some memory is no longer referenced, but has not been explicitly released.
Here is the pydoc documentation for the Array class:
class Array(__builtin__.object) | Array class that supports turtle graphics visualization. | | There are two public, class-level variables that can be used | to control the visualization: | | Array.visible - Set this to False to turn off graphics. | Array.speed - Set this value to change the speed of the animation. | This value indicates the length of the pauses (in seconds) | between updates. | | Methods defined here: | | __getitem__(self, index) | Returns the contents of the indicated array entry. | | __init__(self, size) | Creates an array with a given capacity. | | __len__(self) | Returns the size of the array. | | __setitem__(self, index, value) | Stores the value at the indicated index. | | free(self) | Frees this array. | | The array will no longer appear in the visualization, and may | be garbage collected as long as no external references exist. | | ----------------------------------------------------------------------
UPDATED 10/3.
I am providing the following set of unit tests to get you
started: vector_tests.py. This set of
unit tests is not complete. There are no tests for the
methods pop
, count
or reverse. Fifteen
percent of your grade on this programming assignment will be based on
providing appropriate tests for those methods.
For some of the methods below, you have the option of implementing functionality beyond the minimum requirements of this project. If you choose to implement something extra, you should update the provided unit tests to reflect those changes, and you should document the changes in the header comments of your Vector class.
In the following ADT description, italicized entries refer to
built-in Python methods and operators that your class will override. For example, you
will implement the length()
method by defining
a function with the signature __len__(self)
.
Vector()
length()
contains(item)
item
is contained in the vector. equals(v)
notequals(v)
equals(v)
.) getitem(indx)
indx
in the vector. Raises IndexError if the index is out of range.
v[-1]
is
equivalent to v[len(v) + (-1)]
. Since several methods
will need to handle converting negative indices and checking for
illegal index values, it makes sense to write a "private" helper
method for handling these tasks.
setitem(indx, item)
indx
to be item
. Raises IndexError if the index is out of range. string()
getSlice(indx1, indx2)
indx1
to position indx2 - 1
. Raises IndexError if either indx1
or indx2 - 1
are outside of range. Returns an empty vector if indx1 > indx2 - 1
.
getSlice
should not override the built-in slicing
operator. (If you want to fully implement slicing, you are
welcome to do so. The correct way of supporting slicing is through
the use of
slice objects that are automatically passed to
the __getitem__
method.)
You do need to handle negative indices. The behavior described above
refers to index values after they have been converted from
their negative form by adding the length of the list. iterator()
append(item)
item
to the end of the vector. extend(items)
items
, which can be of any iterable type.
insert(indx, item)
a.insert(0, x)
inserts at the front of the vector, and a.insert(len(a), x)
is equivalent to a.append(x)
. Raises an IndexError if indx
is outside of the valid range.
remove(item)
item
. Raises ValueError error if there is no such element. pop([indx])
a.pop()
removes and returns the last item in the vector. Raises IndexError if the vector is empty or the index is out of range. (The square brackets around the indx
in the method signature denote that the parameter is optional, not that you should type square brackets at that position. You will see this notation frequently in the Python Library Reference.) index(item)
item
. Raises ValueError if there is no such element. count(item)
item
appears in the vector.reverse()
Your vector class will be responsible for freeing Arrays that are
no longer referenced. This means that there must be some way for
vector objects to know that they are no longer referenced.
When a vector object is released by the garbage collector it will need
to explicitly release any Arrays that it is still holding onto. This
can be accomplished by overriding the built in Python
operator __del__
. That method should be called
automatically when there are no more references to the vector.
If you've done everything correctly, the following python script should terminate with no arrays remaining on the screen.
from vector import Vector vec = Vector() for i in range(8 span>): vec.append(i) # Overwrite the reference to our vector so that it can be garbage # collected. The __del__ method of vec will be called. vec = "Goodbye!"
Note that, under normal circumstances, YOU WOULD NEVER NEED TO OVERRIDE __del__. You are only doing this because this project exists in a Bizarro world where Python garbage collection does not exist for some classes.
vector.py
containing your completed Vector class, and an
updated version of the unit testing module. As always, your code
should conform to the CS240 Python
Coding Conventions. You do not need to provide docstrings for the
methods in the unit testing class.
Several of the method descriptions above are copied from the Python tutorial description of Python's list methods, © 2001-2010 Python Software Foundation; All Rights Reserved. Here is a copy of the PSF License: psf_license.txt. The documentation has been modified for clarity and consistency with this project.
The project as a whole is based on Programming Project 2.1 from Data Structures and Algorithms Using Python. Rance D. Necaise, Wiley, 2011.