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.
How can I implement upside_down
?
For this problem, you will first want to create 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. Every pixel will have the same
column index as it did in the original image, but it will be put
into a new row.
Before you try to write code for this, it may help to draw a table
that maps where pixels go in the flipped image based on their
row in the original image. Suppose h
is the height of the
image. You will end up with a table that looks like this:
row r in original row in flipped ----------------- -------------- 0 h - 1 1 h - 2 2 h - 3
Given the table above, what is a general formula you could come up with to determine a pixel’s new row in the upside-down image?
In reflect
, how can I determine where the “reflected”
version of a pixel should go?
Here again, we recommend making a table that specifies 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 column in the left half of the image should be reflected in the right half of the image.
If the width of the image is w
, here is what the beginning of
this table should look like:
col c in left half corresponding column in right half ------------------ ---------------------------------- 0 w - 1 1 w - 2 2 w - 3
Given the pattern that you see in this table, what is a general
formula for where a pixel from column c
in the left half should be
reflected in the right half?
My reflect
seems to be correct, but I’m getting a column of
green pixels even for images like the Spam image that have an
even number of columns. 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 right 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 column index c
of a
column from the left half to get the index of the corresponding column
from the right half. 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 should I start shrink
?
As mentioned in the hints for shrink
, 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:
>>> ud = upside_down(pixels)
And because rainbow.png
is so small, you can actually look at the
resulting 2-D list of pixels in the console:
>>> ud result: [[[150, 75, 0], [150, 75, 0], [150, 75, 0], [150, 75, 0], [150, 75, 0], [255, 0, 0], [255, 0, 0], [255, 0, 0], [255, 0, 0]], [[100, 255, 255], [100, 255, 255], ...
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:
>>> ud[0] [[150, 75, 0], [150, 75, 0], [150, 75, 0], [150, 75, 0], [150, 75, 0], [255, 0, 0], [255, 0, 0], [255, 0, 0], [255, 0, 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.
I’m unclear about how to structure this problem. Can you clarify?
As the problem indicates, you should write two separate functions:
a function called main
that does not take any inputs, and that
will be used to start the program. This will be somewhat similar
to the main
function that we wrote for Lab 8, Tasks 1 and
2 and the tts
function in PS 6, Problem
4.
a second function that takes in three strings (the name of the
data file, the name of the city, and the state abbreviation) and
that processes the data file and prints out any results that
are found for the specified city/state combination. This function
will be somewhat similar to the extract_results
function that
we covered in lecture on 11/3. The name that you use for this
function is up to you – but pick something descriptive!
main
will include a user-interaction loop that gets inputs from
the user and calls the second function to perform the necessary
file processing. The loop should repeat until the user enters the
word “quit” for the name of the city, at which point the main
function – and the program itself – should end.
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 the formatting of your results is correct. In particular, you must:
use either string concatenation or the join
method to
put a single tab character \t
between the values on a given line
of the output
use the specified call to the format
function to format the
population.
Make sure that you don’t include any extra space characters in the
output besides the ones provided by the call to format
.
See also question 4 below for some other possible issues.
I think I’ve formatted the results correctly, but the output doesn’t look correct in Spyder.
It’s possible for tabs and spaces to look different on different machines – and that may be the reasons that things don’t look as they should when you run the program on Spyder. If you think your formatting is correct (see question 2 above), try submitting your file on Gradescope to see if it passes the preliminary tests.
I’m still failing an Autograder test for this problem, even though I’ve taken care of the possible spacing issues mentioned above. What else could be going wrong?
Here are some other 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 25, 2024.