Part I due by 11:59 p.m. on Thursday, March 27, 2025.
Part II due by 11:59 p.m. on Sunday, March 30, 2025.
In your work on this assignment, make sure to abide by the collaboration policies of the course.
If you have questions while working on this assignment, please
come to office hours, post them on Piazza, or email
cs111-staff@cs.bu.edu
.
Make sure to submit your work on Gradescope, following the procedures found at the end of Part I and Part II.
Create a subfolder called ps6
within your
cs111
folder, and put all of the files for this assignment in that
folder.
Problems 0, 1 and 2 will all be completed in a single PDF file. To create it, you should do the following:
Access the template that we have created by clicking on this link and signing into your Google account as needed.
When asked, click on the Make a copy button, which will save a copy of the template file to your Google Drive.
Select File->Rename, and change the name of the file to
ps6pr012
.
Add your work for Problems 0, 1 and 2 to this file.
Once you have completed all of these problems, choose
File->Download->PDF document, and save the PDF file in your ps6
folder. The resulting PDF file (ps6pr012.pdf
) is the one that you
will submit. See the submission guidelines at the end of Part I.
Consider the following function, which uses a for
loop to
process a list of numbers:
def foo1(vals): for x in vals: if x % 5 == 0: return False return True
a. Trace the execution of the following call to this function
foo1(range(1, 5))
To do so, complete the template that we have provided in
section 0-3a of ps6pr012
to show how the values of the
loop variable and the if
condition change over time,
and the final return value of the function. Note: It’s possible
that the function won’t end up processing all of the numbers
in the list vals
, so you may not need all of the rows of
the table.
b. Now trace the execution of the following call to this function
foo1([9, 10, 11])
To do so, complete the template that we have provided in
section 0-3b of ps6pr012
to show how the values of the
loop variable and the if
condition change over time,
and the final return value of the function. Here again,
you may not need all of the rows of the table.
Consider the following function foo2
. It is similar to the
foo1
function above, but with an important difference!
def foo2(vals): for x in vals: if x % 5 == 0: return False else: return True
a. Trace the execution of the following call to this function
foo2([2, 4, 5, 8, 10])
To do so, complete the template that we have provided in
section 0-4a of ps6pr012
to show how the values of the
loop variable and the if
condition change over time,
and the final return value of the function. Here again,
you may not need all of the rows of the table.
b. Now consider the following call to this function:
foo2(range(1, 250))
The expression range(1, 250)
produces 249 integers. When
that range of integers is passed into foo2
, how many
repetitions will the for
loop perform? Explain your
answer briefly.
10 points; individual-only
Consider the following Python program, which uses a nested loop:
for p in ['re', 'pre']: for w in ['view', 'cede', 'board']: print(p + w) print(w[-1] + p[0]) print(p)
In section 1-1 of ps6pr012
, we have given you a template that you
should complete to specify how the variables change over time
and what the program outputs. You may not need all of the rows
in the table.
Consider the following Python program, which uses also uses a nested loop:
for x in [3, 4, 5]: for y in range(2, x): print(x * y) print(x, y)
In section 1-2 of ps6pr012
, we have given you a template that you
should complete to specify how the variables change over time
and what the program outputs. You may not need all of the rows
in the table.
Hint: The lecture and lab exercises include similar traces.
10 points; individual-only
Consider the following Python program
def mystery(x, vals): for i in range(len(vals)): vals[i] += 3 x *= 5 # what do things look like in memory at this point? return x x = 2 v1 = [2, 3, 4] v2 = v1 v3 = v1[:] mystery(x, v1) print(x) print(v1) print(v2) print(v3)
In section 2-1 of ps6pr012
, we have given you the beginnings of
a memory diagram. It includes:
two stack frames: one for the global scope, and one for
the call mystery(x, v1)
the list to which the variable v1
refers.
Complete the provided memory diagram so that it shows what things
look like in memory at the end of the call to
mystery
—just before it returns.
To do so, you should:
Click on the diagram and then click the Edit link that appears below the diagram.
Make whatever changes are needed to the diagram. Below the thick horizontal line, we have given you a set of extra components that you can use as needed by dragging them above the thick line and putting them in the correct position. You may not need all of the provided components.
You can also edit the value inside of any cell by clicking on that cell and making whatever change is needed.
Once you have made all of the necessary changes, click the Save & Close button.
What is the output of the program?
20 points; pair-optional
This is the only problem of the assignment that you may complete with a partner. See the rules for working with a partner on pair-optional problems for details about how this type of collaboration must be structured.
In Spyder, open a new editor window using File -> New File,
and save it to your ps6
folder using the name ps6pr3.py
.
Important guidelines
Here are the guidelines that you should follow for this and all remaining Python problems over the course of the semester:
Include comments at the top of the file
that are similar to the ones that we gave you at the top of
ps1pr3.py
.
Your functions must have the exact names specified below,
or we won’t be able to test them. Note in particular that the
case of the letters matters (all of them should be lowercase),
and that some of the names include an underscore character (_
).
As usual, each of your functions should include a docstring that describes what your function does and what its inputs are. In addition, you should include any other comments that might be necessary to explain your code. More generally, you should aim to make your code easy to read. For example, you should choose descriptive names for your variables. In addition, we encourage you to leave a blank line between logical parts of your function.
If a function is supposed to return a value, make sure that it actually returns the specified value, rather than printing it.
You should not use any Python features that we have not discussed in lecture or read about in the textbook.
Your functions do not need to handle bad inputs – inputs with a type or value that doesn’t correspond to the description of the inputs provided in the problem – unless the problem explicitly states otherwise.
Leave one or two blank lines between functions to make things more readable.
If you want to add test calls to this or any other Python file,
please do so in appropriate test function like the one that we
gave you at the bottom of the
ps1pr3.py
starter file for Problem
Set 1. After running your Python file, you can call the
test
function (by entering test()
) to see the results of
all of the test calls.
Do not add any lines of code that belong to the global scope of the program (i.e., lines that are outside of any function).
Write a function BUtify(s)
that takes as input an arbitrary
string s
and uses a loop to determine and return
a new string in which all lower-case b
s are replaced by
upper-case B
s and all lower-case u
s are replaced by upper-case
U
s. For example:
>>> BUtify('you be you') result: 'yoU Be yoU' >>> BUtify('beautiful') result: 'BeaUtifUl' >>> BUtify('unbelievable') result: 'UnBelievaBle'
Write a function weave(s1, s2)
that takes as inputs two strings
s1
and s2
and uses a loop to construct and return
a new string that is formed by “weaving” together the characters
in the strings s1
and s2
to create a single string. In other
words, the new string should alternate characters from the two
strings: the first character from s1
, followed by the first
character from s2
, followed by the second character from s1
,
followed by the second character from s2
, etc. If one of the
strings is longer than the other, its “extra” characters – the
ones with no counterparts in the shorter string – should appear
immediately after the “woven” characters (if any) in the new
string.
Here are some examples:
>>> weave('aaaaaa', 'bbbbbb') 'abababababab' >>> weave('abcde', 'VWXYZ') 'aVbWcXdYeZ' >>> print(weave('abcde', 'VWXYZ')) aVbWcXdYeZ >>> weave('aaaaaa', 'bb') # four extra 'a' characters at the end 'ababaaaa' >>> weave('aaaa', 'bbbbbb') # two extra 'b' characters at the end 'ababababbb' >>> weave('aaaa', '') # all of the 'a' characters are extra! 'aaaa' >>> weave('', 'bbbb') # all of the 'b' characters are extra! 'bbbb' >>> weave('', '') ''
You solved a similar problem using recursion in Problem Set 2, but for this problem set you must use a loop.
Hints:
You will need to use an index-based loop so that you can access the corresponding characters from each string at the same time. We took a similar approach for some of the functions in problem 9 of Problem Set 5.
After the loop, you will need to handle any “extra” characters from the longer string (for cases in which the strings don’t have the same length).
Write a function index_first(elem, seq)
that takes as inputs an element
elem
and a sequence seq
, and that uses a loop to
find and return the index of the first occurrence
of elem
in seq
. The sequence seq
can be either a list or a string.
If seq
is a string, elem
will be a single-character string; if
seq
is a list, elem
can be any value.
Don’t forget that the index of the first element in a sequence is 0.
Important notes:
If elem
is not an element of seq
, the function should
return -1.
You may not use the in
operator in this function to
test for the presence of elem
in seq
. However, you are
welcome to use in
as part of the header of a for
loop.
In addition, the only built-in functions that you may use
are len
and range
.
Here are some examples:
>>> index_first(5, [4, 10, 8, 5, 3, 5]) result: 3 >>> index_first('b', 'banana') result: 0 >>> index_first('a', 'banana') result: 1 >>> index_first('i', 'team') result: -1 >>> index_first('a', '') # the empty string result: -1 >>> index_first(42, []) # the empty list result: -1
You solved this problem using recursion in Problem Set 3, but for this problem set you must use a loop.
Hint: One way to solve this problem is to have two return
statements: one inside the loop, and one after the loop has completed.
Write a function square_evens(vals)
that takes a list of
integers called vals
, and that modifies the internals of
the list so that all of its even elements are replaced
with their squares, but all of its odd elements are left
unchanged.
This function should not return a value. Rather,
it should use an index-based loop to modify the internals of the
original list as needed. For example, to modify element i
of the
list vals
, you should perform an assignment that looks like
this:
vals[i] = expression
where expression
is replaced with an appropriate expression for the
new value of vals[i]
. We performed this type of item assignment
in this week’s lectures and lab.
For reasons that we discussed in lecture, any changes that the function makes to the internals of the list using item assignment will still be there after the function returns.
For example:
>>> vals1 = [1, 2, 3, 4, 5, 6] >>> square_evens(vals1) >>> vals1 result: [1, 4, 3, 16, 5, 36] >>> vals2 = [7, 3, 10, 8] >>> square_evens(vals2) >>> vals2 result: [7, 3, 100, 64]
Note: As shown above, when you call the function from the console, you should not see a result. That’s because your function should not return a value.
Login to Gradescope by clicking the link in the left-hand navigation bar, and click on the box for CS 111.
You will make submissions to two separate assignments on Gradescope. The steps needed for the two submissions are different, so please make sure to follow carefully the procedures outlined below.
PS 6: Problems 0, 1 and 2
Submit your ps6pr012.pdf
file using these steps:
If you still need to create a PDF file, open your file
on Google Drive, choose File->Download->PDF document, and
save the PDF file in your ps6
folder.
IMPORTANT: Your PDF should be three pages in length, and the headings that we provided for Problems 1 and 2 should be at the very top of their pages.
Click on the name of the assignment in the list of assignments on Gradescope. You should see a pop-up window labeled Submit Assignment. (If you don’t see it, click the Submit or Resubmit button at the bottom of the page.)
Click the Select PDF button and find the PDF file that you created. Then click the Upload PDF button.
You should see a question outline along with thumbnails of the pages from your uploaded PDF. For each question in the outline:
As you do so, click on the magnifying glass icon for each page and doublecheck that the pages that you see contain the work that you want us to grade.
Once you have assigned pages to all of the problems in the question outline, click the Submit button in the lower-right corner of the window. You should see a box saying that your submission was successful.
If needed, use the Resubmit button at the bottom of the page to resubmit your work.
PS 6: Problem 3
IMPORTANT: If you chose to work on this pair-optional problem with a partner, only one person from the pair should submit the file, and that person should add the other person as a group member following step 6 below.
Submit your ps6pr3.py
file using these steps:
Click on the name of the assignment in the list of assignments. You should see a pop-up window with a box labeled DRAG & DROP. (If you don’t see it, click the Submit or Resubmit button at the bottom of the page.)
Add your file to the box labeled DRAG & DROP. You can either drag and drop the file from its folder into the box, or you can click on the box itself and browse for the file.
Click the Upload button.
You should see a box saying that your submission was successful.
Click the (x)
button to close that box.
The Autograder will perform some tests on your file. Once it is done, check the results to ensure that the tests were passed. If one or more of the tests did not pass, the name of that test will be in red, and there should be a message describing the failure. Based on those messages, make any necessary changes. Feel free to ask a staff member for help.
Note: You will not see a complete Autograder score when you submit. That is because additional tests for at least some of the problems will be run later, after the final deadline for the submission has passed. For such problems, it is important to realize that passing all of the initial tests does not necessarily mean that you will ultimately get full credit on the problem. You should always run your own tests to convince yourself that the logic of your solutions is correct.
If you worked with a partner and you are the one who is submitting the file:
Click on the Add Group Member link that appears below your name above the results of the Autograder.
In the pop-up box that appears, click on the Add Member link.
Type your partner’s name or choose it from the drop-down menu.
Click the Save button.
Check to ensure that your partner’s name now appears below your name above the results of the Autograder.
If needed, use the Resubmit button at the bottom of the page to resubmit your work.
Near the top of the page, click on the box labeled Code. Then click on the name of each file to view its contents. Check to make sure that the files contain the code that you want us to grade.
Important
It is your responsibility to ensure that the correct version of every file is on Gradescope before the final deadline. We will not accept any file after the submission window for a given assignment has closed, so please check your submissions carefully using the steps outlined above.
If you are unable to access Gradescope and there is enough
time to do so, wait an hour or two and then try again. If you
are unable to submit and it is close to the deadline, email
your homework before the deadline to
cs111-staff@cs.bu.edu
30 points; individual-only
This problem involves using loops to process a list of stock prices. You will also gain experience in writing a program that involves repeated user interactions.
The premise behind this problem is that you have been hired by an investment firm called Time Travel Securities, Inc. (also known as TT Securities or TTS). They want you to write a program that will perform a variety of tasks involving a list of stock prices.
We will discuss this application in lecture and look at an example user-interaction loop. Begin by downloading the following file:
Begin by downloading this file: ps6pr4.py
Make sure to put the file in your ps6
folder. If your browser
doesn’t allow you to specify where the file should be saved, try
right-clicking on the link above and choosing Save as... or
Save link as..., which should produce a dialog box that allows you
to choose the correct folder for the file.
Open the file in Spyder. You should see some starter code that is based on the code from lecture. You will add the code needed to support the functionality described below.
Important
You may not use the built-in sum
, min
, or max
functions
for this problem. Instead, you should use loops of your own
construction to compute the necessary values.
You should continue to follow the guidelines that we gave you earlier. Those guidelines apply to this and all remaining Python code that you write for this course!
In particular, do not add any lines of code that belong to the global scope of the program (i.e., lines that are outside of any function).
Running the program
The starter code that we’ve given you includes a function called
tts()
that serves as the “main” function–the one that handles the
user interactions.
To run the program, you should call this function. Run ps6pr5.py
in Spyder, and then make the following function call from the console:
>>> tts()
Required functionality
The program should present the user with the following menu of choices:
(0) Input a new list of prices (1) Print the current prices (2) Find the latest price (3) Find the average price (4) Find the min price and its day (5) Find the max single-day change and its day (6) Test a threshold (7) Your investment plan (8) Quit Enter your choice:
Our starter code includes support for a few of these options. You will need to implement the rest of them. In particular, you should perform tasks 0-5 outlined below.
A sample run that illustrates what the behavior of the program should look like is available here.
Read over the starter code that we’ve given you. Make sure that you understand how the various functions work, and how they fit together.
Add support for option 3: finding the average price
First, write a function called avg_price
that takes a list of 1
or more prices and computes and returns the average price.
Don’t forget that you cannot use the built-in sum
, min
, or
max
functions. Instead, you should use a loop of your own
construction to perform the necessary computations.
Here are two examples:
>>> avg_price([10, 20, 18]) result: 16.0 >>> avg_price([5, 8, 5, 3]) result: 5.25
Next, you should integrate this function into the overall program by doing the following:
Update the display_menu
function to print the description
of this menu option.
Add code to the tts
function to call your avg_price
function whenever the user chooses option 3, and to print the
result that it returns. See the sample run
for an example of what the output of this option should look like.
Important: The printing of the result should be done in
tts
. Your avg_price
function should not do any
printing. In general, none of the new functions that you
write should do any printing. Rather, you should add code
to tts
to print the results in the proper format.
Add support for option 4: finding the minimum price and its day
Write a function called min_day
that takes a list of 1 or more
prices and computes and returns the day (i.e., the index) of
the minimum price. Don’t forget that you cannot use the
built-in sum
, min
, or max
functions.
Here are two examples:
>>> min_day([20, 10, 18]) result: 1 >>> min_day([15, 22, 18, 12, 17]) result: 3
Next, you should integrate this function into the overall program,
taking steps similar to the ones that you took above. In
printing the result, tts
should print both the day
of the minimum price and the minimum price itself. See the
sample run for an example of what the output should look
like.
Add support for option 5: finding the maximum single-day change and its day
Write a function called max_change_day
that takes a list of 2 or more
prices and computes and returns the day (i.e., the index) of
the maximum single-day change in price. For example, consider the
following list of prices:
[10, 30, 70, 80, 60, 10]
The maximum single-day change in this list occurs on day 2, when the price increases to 70, which is 40 more than the price on day 1, and no other single-day change in the list is greater than 40. (Note that the change from 60 to 10 at the end of the list is a decrease – i.e., a negative change – so it is not greater than the change from 30 to 70.) Thus, the function would return 2 (the index of the 70) for this list of prices.
Don’t forget that you cannot use the built-in sum
, min
, or
max
functions.
Here are two example calls:
>>> max_change_day([10, 30, 70, 80, 60, 10]) result: 2 >>> max_change_day([10, 30, 20, 15, 50]) result: 4
Next, you should integrate this function into the overall program,
taking steps similar to the ones that you took above. In
printing the result, tts
should print both the day of
the maximum change and the prices before and after the change.
See the sample run for an example of what the output
should look like.
Add support for option 6: testing a threshold
Begin by writing a function called any_above
that takes a list of
1 or more prices and an integer threshold, and uses a loop to
determine if there are any prices above that threshold. The
function should return True
if there are any prices above the
threshold, and False
otherwise. For example:
>>> any_above([30, 20, 15], 35) result: False >>> any_above([10, 20, 15], 12) result: True
Important: Make sure that you return either the boolean
literal True
or the boolean literal False
. Do not include
quotes around these values.
Next, you should integrate this function into the overall program.
In addition to the types of steps that you’ve taken for the
previous options, you will also need to get the threshold from
the user. Add an input
statement to tts
that obtains the
threshold, and don’t forget to convert the string that is returned
by input
to an integer. See our starter code for an example of
this.
Add support for option 7: the “time travel” investment
strategy discussed in lecture
First, write a function called find_tts
that takes a list of 2
or more prices, and that uses one or more loops to find the best
days on which to buy and sell the stock whose prices are given in
the list of prices. The buy and sell days that you determine
should maximize the profit earned, but the sell day must be
greater than the buy day. The function should return a
list containing three integers:
For example:
>>> find_tts([40, 10, 20, 35, 25]) result: [1, 3, 25]
In this case, the function returns a list that indicates that the best investment plan is to buy on day 1 and sell on day 3, which gives a profit of $25. Here’s another example:
>>> find_tts([5, 10, 45, 35, 3]) result: [0, 2, 40]
Hint: In implementing this function, you may find it helpful to
adapt the example diff
function that we covered in lecture.
Don’t forget to integrate this function into the overall program, taking similar steps to the ones that you took for the earlier options. See the sample run for an example of what the output of this option should look like.
25 points; individual-only
We will discuss the concepts needed for this problem in Wednesday’s lecture.
This problem involves writing functions that create and manipulate two-dimensional lists of integers. You should continue to follow the guidelines that we gave you earlier.
Getting started
Begin by downloading this file:
ps6pr5.py
Make sure to put the file in your ps6
folder.
Open that file in Spyder, and put your work for this problem in that file.
In ps6pr5.py
, we’ve given you the following functions:
create_grid(num_rows, num_cols)
, which creates and returns a 2-D list
of 0s with the specified dimensions
print_grid(grid)
, which takes a 2-D list grid
and prints it in
2-D form, with each row on its own line
random_grid(num_rows, num_cols)
, which creates and
returns a 2-D list with the specified dimensions in which
each cell is assigned a random integer between 0 and 9
For example (although the actual values of the cells will vary):
>>> grid = random_grid(4, 5) >>> print_grid(grid) [[0, 0, 3, 1, 9], [2, 8, 1, 3, 3], [7, 5, 2, 4, 9], [1, 8, 8, 7, 3]]
Your tasks
Based on the example of random_grid
, write a function
row_index_grid(num_rows, num_cols)
that creates and returns
a 2-D list with the specified dimensions in which each cell has
as its value the index of the row to which the cell belongs. For
example:
>>> grid = row_index_grid(5, 4) >>> print_grid(grid) [[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]] >>> grid = row_index_grid(7, 3) >>> print_grid(grid) [[0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4], [5, 5, 5], [6, 6, 6]]
Your function should take the same approach as random_grid
:
Use create_grid
to create a 2-D list with the specified
dimensions and assign it to a variable.
Use nested loops to modify the internals of the 2-D list. However, instead of assigning a random integer, you should assign the row index of the cell.
Return the modified 2-D list.
Write a function num_between(grid, n1, n2)
that takes a 2-D
list of integers grid
and two integers n1
and n2
, and that
returns the number of values in grid
that are between n1
and
n2
– i.e., greater than or equal to n1
and less than or equal
to n2
. For example:
>>> grid = [[0, 4, 8], [6, 10, 5]] >>> num_between(grid, 4, 6) result: 3 >>> num_between(grid, 7, 11) result: 2 >>> num_between(grid, 1, 3) result: 0 >>> num_between(grid, 11, 7) result: 0
As we’ve seen in lecture, copying a list variable does not actually copy the list. To see an example of this, try the following commands from the console:
>>> grid1 = [[0, 0], [0, 0]] >>> grid2 = grid1 # copy value of grid1 into grid2 >>> print_grid(grid2) [[0, 0], [0, 0]] >>> grid1[0][0] = 1 >>> print_grid(grid1) [[1, 0], [0, 0]] >>> print_grid(grid2) [[1, 0], [0, 0]]
Note that changing grid1
also changes grid2
! That’s because the
assignment grid2 = grid1
did not copy the list represented by
grid1
; it copied the reference to the list. Thus, grid1
and grid2
both refer to the same list!
To avoid this problem, write a function copy(grid)
that creates and returns a deep copy of grid
–a new, separate
2-D list that has the same dimensions and cell values as grid
.
Note that you cannot just perform a full slice on grid
(e.g.,
grid[:]
), because you would still end up with copies of the
references to the rows! Instead, you should do the following:
Use create_grid
to create a new 2-D list with the same dimensions
as grid
, and assign it to an appropriately named variable.
(Don’t call your new list grid
, since that is the name
of the parameter!) Remember that len(grid)
will give you the
number of rows in grid
, and len(grid[0])
will give you the
number of columns.
Use nested loops to copy the individual values from the cells of
grid
into the cells of your newly created grid.
Make sure to return the newly created grid and not the original one!
To test that your copy
function is working properly, try the
following examples:
>>> grid1 = row_index_grid(3, 4) >>> print_grid(grid1) [[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2]] >>> grid2 = copy(grid1) # should get a deep copy of grid1 >>> print_grid(grid2) [[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2]] >>> grid1[0][1] = 7 >>> print_grid(grid1) [[0, 7, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2]] >>> print_grid(grid2) # should NOT see a 7 in the top row [[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2]]
Write a function double_with_cap(grid, cap)
that takes a
2-D list of integers grid
and a single integer cap
,
and that modifies the internals of grid
. Specifically, the
function should double the value of each element unless doing so
would cause the value of the element to be greater than cap
. If
doubling the element produces a value that is greater than cap
,
the element should be replaced with the value of cap
instead.
For example:
>>> grid = [[1, 3, 4], [6, 0, 5]] >>> print_grid(grid) [[1, 3, 4], [6, 0, 5]] >>> double_with_cap(grid, 9) >>> print_grid(grid) [[2, 6, 8], [9, 0, 9]]
Note that most of the elements in the grid have been doubled. However, in the bottom row:
doubling 6
gives 12
, which is greater than the cap of 9
,
so 6
is replaced with 9
instead
doubling 5
gives 10
, which is greater than the cap of 9
,
so 5
is replaced with 9
instead.
Important notes:
Unlike the functions that you wrote for parts 1 and 3 of this problem, this function should not create and return a new 2-D list. Rather, it should modify the internals of the existing list.
Unlike the previous functions that you wrote for this problem,
this function should not have a return
statement,
because it doesn’t need one! That’s because the parameter
grid
gets a copy of the reference to the original 2-D
list, and thus any changes that it makes to the internals of
that list will still be visible after the function returns.
Here’s another example that should help to reinforce your understanding of references:
>>> grid1 = row_index_grid(5, 4) >>> print_grid(grid1) [[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]] >>> grid2 = grid1 >>> grid3 = grid1[:] >>> double_with_cap(grid1, 5) >>> print_grid(grid1) [[0, 0, 0, 0], [2, 2, 2, 2], [4, 4, 4, 4], [5, 5, 5, 5], [5, 5, 5, 5]]
As you can see above, the value of grid1
has been changed.
What about grid2
and grid3
?
Before entering the statements below, see if you can predict
what has happened to grid2
and grid3
. If we print
them, will we see the original grid or the modified one?
Test your understanding by first entering the following:
>>> print_grid(grid2)
What do you see? Why does this make sense?
Now enter the following:
>>> print_grid(grid3)
What do you see? Why does this make sense?
(You don’t need to record your answers to these questions, but we strongly encourage you to make sure that you understand what happens here. Feel free to ask for help if you don’t understand.)
Write a function sum_evens_in_col(grid, colnum)
that takes a
2-D list of integers grid
and an integer colnum
, and
that computes and returns the sum of the even values in the column
of grid
whose index is colnum
.
For example:
>>> grid1 = [[1, 3, 4], [4, 5, 6], [8, 9, 10]] >>> print_grid(grid1) [[1, 3, 4], [4, 5, 6], [8, 9, 10]] >>> sum_evens_in_col(grid1, 0) result: 12 >>> sum_evens_in_col(grid1, 1) result: 0 >>> sum_evens_in_col(grid1, 2) result: 20
Note: Unlike the other functions that you are writing for this problem, this function should not need nested loops. Rather, a single loop should suffice.
Login to Gradescope by clicking the link in the left-hand navigation bar, and click on the box for CS 111.
Submit your ps6pr4.py
and ps6pr5.py
files under the assignment
labeled PS 6: Problems 4 and 5 using these steps:
Click on the name of the assignment in the list of assignments. You should see a pop-up window with a box labeled DRAG & DROP. (If you don’t see it, click the Submit or Resubmit button at the bottom of the page.)
Add your files to the box labeled DRAG & DROP. You can either drag and drop the files from their folder into the box, or you can click on the box itself and browse for the files.
Click the Upload button.
You should see a box saying that your submission was successful.
Click the (x)
button to close that box.
The Autograder will perform some tests on your files. Once it is done, check the results to ensure that the tests were passed. If one or more of the tests did not pass, the name of that test will be in red, and there should be a message describing the failure. Based on those messages, make any necessary changes. Feel free to ask a staff member for help.
Note: You will not see a complete Autograder score when you submit. That is because additional tests for at least some of the problems will be run later, after the final deadline for the submission has passed. For such problems, it is important to realize that passing all of the initial tests does not necessarily mean that you will ultimately get full credit on the problem. You should always run your own tests to convince yourself that the logic of your solutions is correct.
If needed, use the Resubmit button at the bottom of the page to resubmit your work. Important: Every time that you make a submission, you should submit all of the files for that Gradescope assignment, even if some of them have not changed since your last submission.
Near the top of the page, click on the box labeled Code. Then click on the name of each file to view its contents. Check to make sure that the files contain the code that you want us to grade.
Important
It is your responsibility to ensure that the correct version of every file is on Gradescope before the final deadline. We will not accept any file after the submission window for a given assignment has closed, so please check your submissions carefully using the steps outlined above.
If you are unable to access Gradescope and there is enough
time to do so, wait an hour or two and then try again. If you
are unable to submit and it is close to the deadline, email
your homework before the deadline to
cs111-staff@cs.bu.edu
Last updated on March 26, 2025.