If you don’t see your question here, post it on Piazza or come to office hours! See the links in the navigation bar for both of those options.
Do we need to include docstrings in all of our functions?
Yes. For now and evermore!
I’m having trouble with some of the string-method puzzles. Any suggestions?
When using string methods like replace and split that take
one or more separate strings as inputs, keep in mind that you can
pass in a string that has more than one character.
When adding new methods to the Rectangle class, are we allowed
to include the self parameter in the header, even if the problem
doesn’t explicitly tell us to do so?
Yes! In order for a function to be a method, it must have the
special self parameter as its first parameter, so you should
make sure to include it in every method that you write.
How do I get the height and the width of an image?
Because we are representing images as 2-D lists of pixels, the height of the image is given by the number of rows in the 2-D list, and the width is given by the number of columns:
height = len(grid) width = len(grid[0])
When I test one of my image-processing functions, I get an error message indicating that an index is out of bounds. What am I doing wrong?
You are trying to access a pixel using a row and/or a column index that is either too big or too small.
For example, for an image that is only 10 pixels wide and 10 pixels tall, trying to set a pixel at row 15 and column 30 would produce an error message.
If you see this error, try to determine why your expressions for the row and/or column indices are incorrect.
It may also help to remember that row and column indices start from zero, just like list indices. For example, a 10 by 10 image does not have pixels at row 10 nor column 10.
When I try to use save_pixels to save the results of one of my
image-processing functions, I get an error message that includes the
following:
TypeError: object of type 'NoneType' has no len()
What am I doing wrong?
Make sure that your function ends by returning the new 2-D list of
pixels. If your function doesn’t return anything, it will
implicitly return the special value None, which will be assigned
to the variable that you are using for the results, and that will
lead to the above error message in save_pixels.
How can I implement left_right?
For this problem, you will again want to start by creating a new
image (you can use create_green_image for this purpose). Next, you will
go through every pixel in the original image, and decide where to
copy it into the new image. When we flip an image left to right,
every pixel will stay in the same row, but it will be put into a
new column.
Before you try to write code for this, it may help to create a table
that maps where pixels go in the flipped image based on their
column in the original image. Suppose w is the width of the
image. You will end up with a table that looks like this:
column c in original column in flipped
----------------- -----------------
0 w - 1
1 w - 2
2 w - 3
Given the table above, what is a general formula you could come up with to determine a pixel’s new column in the flipped image?
My left_right seems to be correct, but I’m getting a column of
green pixels in the result. What could I be doing wrong?
If you’re not careful, it’s easy to use the wrong expression for the column index in the flipped image. For example, some people mistakenly write assignments that look like this:
newpixels[r][-c] = pixels[r][c] # does NOT work!
In other words, they try to simply negate the column index c of a
column from the original image to get the index of the corresponding column
in the flipped image. But that doesn’t work! For example:
When c is 0 (for the leftmost column), the expression -c also
gives you 0, rather than giving an index that we can use for
the rightmost column.
When c is 1 (for the second column), -c is -1, which is
the index of the rightmost column, rather than the index of the
second-from-the-right column.
To find the correct expression, use a table like the one shown in the answer to the previous question.
How do I reflect an image?
Here again, you first want to create a new image using
create_green_image. Next, you want to reflect the top half of
the original image over the bottom half. One way to do this is to
adjust the range of one of your two loops so that you only iterate
over the pixels in the top half of the original image. Then, for
each pixel that you process from the top half, you should copy
that pixel twice: once to the same position in the top half of the
new image, and once to the appropriate location in the bottom half
of the image.
Also, don’t forget that if the image has an odd number of rows, the middle row in the mirrored image should contain the same pixels as the middle row in the original image. See the problem itself for an example of this.
In reflect, how can I determine where the “reflected”
version of a pixel should go?
Here again, we recommend making a table that lists what should happen in concrete cases, and then coming up with a formula that is based on that table.
More specifically, you should construct a table that lists where pixels from a given row in the top half of the image should be reflected in the bottom half of the image.
If the height of the image is h, here is what the beginning of
this table should look like:
row r in top half corresponding row in bottom half
----------------- --------------------------------
0 h - 1
1 h - 2
2 h - 3
Given the pattern that you see in this table, what is a general
formula for where a pixel from row r in the top half should be
mirrored in the bottom half?
My reflect seems to be correct, but I’m getting a row of
green pixels even for images like the Spam image that have an
even number of rows. What could I be doing wrong?
If you’re not careful, it’s easy to use the wrong expression for the row index in the bottom half of the image. For example, some people mistakenly write assignments that look like this:
newpixels[-r][c] = pixels[r][c] # does NOT work!
In other words, they try to simply negate the row index r of a
row from the top half to get the index of the corresponding row
from the bottom half. But that doesn’t work! For example:
When r is 0 (for the first row), the expression -r also
gives you 0, rather than giving an index that we can use for
the last row.
When r is 1 (for the second row), -r is -1, which is
the index of the last row, rather than the second-to-last.
To find the correct expression, use a table like the one shown in the answer to the previous question.
How should I start cut?
As mentioned in the hints that we’ve provided in the problem itself, one way to approach these problems is to have your nested loops go through each position in the new image and copy the appropriate pixel from the old image.
Answering the following questions should get you started:
What are the height and width of the new image that the function will produce?
Which pixel from the old image will go at 0,0 (top left corner) in the new image?
Which pixel from the old image will go at row 0, col 1 in the new image?
Which pixel from the old image will go at row 1, col 0 in the new image?
Which pixel from the old image will go at r,c for any row r or column c in the new image?
I’m finding it hard to figure out where the problem is in one of my image-processing functions since the 2-D lists of pixels are so big. Is there anything I can do?
In the ps7image folder, we’ve included a very small 9x9 image
called rainbow.png that you can use for debugging:

To do so, you should begin as usual by loading in its pixels:
>>> pixels = load_pixels('rainbow.png')
Then you should pass that 2-D list of pixels into the function you are debugging and store the results. For example:
>>> reflected = reflect(pixels)
And because rainbow.png is so small, you can actually look at the
resulting 2-D list of pixels in the console:
>>> reflected
result:
[[[255, 0, 0],
[255, 0, 0],
[255, 0, 0],
[255, 0, 0],
[255, 0, 0],
[150, 75, 0],
[150, 75, 0],
[150, 75, 0],
[150, 75, 0]],
[[255, 128, 0],
[255, 128, 0],
[255, 128, 0],
...
We have truncated the result above, but you can find the expected 2-D lists of pixels in the following files:
You can also focus on particular rows or cells of the results by entering the appropriate expression from the console. For example, to see the first row of the 2-D list obtained above, you could enter the following:
>>> reflected[0] [[255, 0, 0], [255, 0, 0], [255, 0, 0], [255, 0, 0], [255, 0, 0], [150, 75, 0], [150, 75, 0], [150, 75, 0], [150, 75, 0]]
And of course you can also use save_pixels to create an image from
the results and view that image – enlarging it as needed in your
image viewer to see it better. We have not provided the expected
image files, but in most cases you should be able to figure out if
the image looks correct based on what the function you are testing
is supposed to do.
The Autograder says that I’m failing a test for this problem, but my actual results match the expected ones. What is going on?
Make sure that you’re using the output_formatted helper
function that we’ve provided to output the results with
the correct formatting.
I’m failing the Autograder test that is testing a run of the program with inputs of Houston, TX followed by Tampa, FL, but the results look more or less correct. What could be going wrong?
Here are some things to check:
You should only ask for the name of the file once at the beginning of the program, as shown in the sample run.
If the user enters “quit” for the name of the city, you should not ask for the state abbreviation. Instead, the program should end immediately, as shown at the end of the sample run.
You should not include any extraneous print statements –
e.g., a statement that prints the city and state after the
user enters them.
As usual, you should not include any code in the global scope
(outside of the bodies of your functions). For example, you
should not include a line of code at the end of your file
that makes the call to main. Rather, you should test your
program by calling main() from the console.
In general, you should try to ensure that the output of your program matches the provided sample run as closely as possible.
Last updated on March 30, 2026.