Lab 11 - Grid
Due by 11:59pm on February 25, 2025
Starter Files
Download lab11.zip. Inside the archive, you will find starter files for the questions in this lab.
Important: Your code for this lab should go in
Grid.py
.
Grid Class
In this lab, we're going to build a simple grid class. Grids can be used to store values in a 2D space. We will build different tools to construct and work with grids.
-
Grid(width, height)
- constructs new grid. Initially all locations areNone
-
Grid.width
,Grid.height
- width/height properties -
Grid.get(x, y)
- returns contents at(x, y)
(error if(x, y)
out of bounds) -
Grid.set(x, y, val)
- sets value into the grid at(x, y)
(error if(x, y)
out of bounds)
Q1: Initializing
First, we will implement the Grid
class constructor. This constructor takes two arguments:
- An integer as the
width
of the grid - An integer as the
height
of the grid
Use these to create a list of length height
and each element will be a list of length width
. Each element of the inside lists should be initialized as None
. Each Grid
instance will keep track of these three values with instance attributes called width
, height
and array
.
Hint: List concatenation could be helpful for creating our array.
def __init__(self, width, height):
"""
Create grid `array` width by height. Create a Grid object with
a width, height, and array. Initially all locations hold None.
>>> grid = Grid(2, 2)
>>> grid.array
[[None, None], [None, None]]
"""
The array should be constructed so it looks something like this, but with the correct specified dimensions for width and height of the outer and inner lists. This example shows a representation of a grid object Grid(2, 2):
[[None, None],
[None, None]]
Testing
We're writing a class that is designed to be imported into other programs. To test your class as you are writing it, you should create a separate python file to write code to test your Grid class. Create that file now and add an import line to the top of it:
from Grid import Grid
Then try creating a new grid object and accessing the height and width attributes. If you don't get any errors, you are good to go. Otherwise, work with your lab partners and TAs to figure out what is not working. Now you are ready to add functionality to the class.
Q2: get
and set
Write out a get
method and a set
method with the function signatures given below. Get should take in an x
and y
coordinate and return the value at that cell in the grid. Set will use an x
and y
coordinate and set that cell to val
. Set returns None
.
def get(self, x, y):
"""
Gets the value stored value at (x, y).
(x, y) should be in bounds.
>>> grid = Grid(2, 2)
>>> grid.array = [[1, 2], [4, 5]]
>>> grid.get(0, 1)
4
>>> grid.get(1, 0)
2
"""
def set(self, x, y, val):
"""
Sets a new value into the grid at (x, y).
(x, y) should be in bounds.
>>> grid = Grid(2, 2)
>>> grid.set(1, 1, "Milk")
>>> grid.set(1, 0, "Dud")
>>> grid.array
[[None, 'Dud'], [None, 'Milk']]
"""
Both of these methods should validate that the x
and y
coordinates are valid and within the width and height specified for the grid. In lab, if they are invalid, the methods should print an error. In the next lab, which focuses on exceptions, you'll revisit these methods and add the functionality for them to throw exceptions when the positions are out of bounds.
Since you'll need it for both get
and set
, you should write an in_bounds()
method that checks to see if the x and y coordinates are valid. You'll also need that check in other parts of the Grid
class later on.
Q3: __str__
and __repr__
Now we'll create the __str__
and __repr__
methods.
def __str__(self):
def __repr__(self):
The __str__
method should return a "human-readable" string that represents the class. For our implementation, we'll have __str__
return the following:
Grid(<height>, <width>, first = <first element>)
Where <height>
and <width>
are the values stored in the instance variables and <first value>
is the first value (index 0,0) in the data array.
The __repr__
function is supposed to return a string that if we pasted it into a Python script or called Python's eval()
function, would recreate the object. We don't yet have everything in this class we need to do that. You'll add that part of the class in Homework 3. For now, just have __repr__
return the same value as the __str__
method.
If you're having trouble knowing the difference between these here's an analogy. Consider the difference between drawing a flower and writing out the word 'flower'. Drawing a flower is like the
__repr__
function, because the drawing will look like the object. Writing out the word 'flower' is like__str__
, because it's a text description, not a visual representation.
Q4: __eq__
The __eq__
dunder method is what python calls when you use the ==
operator to compare the instances of class. Write a function that can compare two Grid
s and decide if the arrays are the same size and contain the same values.
The function signature for this method is:
def __eq__(self, other):
where the variable other
is the Grid
object that we are comparing with.
This method should make two checks:
- First, it should check to see if
other
is anotherGrid
object (use Python'sisinstance()
function). If not, it should returnFalse
. - Second, return
self.array == other.array
. This will check both:- That
self
andother
have the same dimensions - That each space in
self
andother
match
- That
Submit
Submit the Grid.py
file on Canvas to Gradescope in the window on the assignment page.