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 keep getting index out of bounds errors. What should I do?
This is an excellent opportunity to hone your debugging skills!
If you get this error, it means you are using an index that does
not correspond to one of the elements of the sequence that you are
processing. To solve this, look at what ranges of values your
indices can have. If the ranges seem alright, add print
statements to display the indices.
For example, consider the following nested loop, which is designed
to process a 2-D list called grid:
for r in range(len(grid)): for c in range(len(grid[0]): print('r =', r, ' and c =', c) # the rest of the loop goes here
Note that we’ve added a print statement inside the loop to print
the values of the loop variables r and c. Print statements like
this one can point you in the direction of what’s wrong with your code.
I’m still unclear about how to draw memory diagrams and to trace function calls that involve references. Do you have any suggestions?
Try viewing the following video: https://mymedia.bu.edu/media/t/1_idn42697
It traces through the extra-practice exercise from page 240 of the coursepack as well as a related program.
I’m stuck on the diff function. Do you have any suggestions?
First, make sure that you are using an index-based loop. In the hints,
we’ve given you a suggested template that includes the header
of the necessary loop. It will allow you to consider one index i at
a time, and to use i to access the number at position i in
both vals1 and vals2.
Because vals1 and vals2 may have different lengths, we have used
the length of the shorter list when constructing the range of index
values that the loop will consider. Then, after the loop has
completed, you will need to take care of any “extra” values
in the longer of the two lists.
To figure out the logic for handling the “extra” values, try considering concrete cases. For example, consider this call:
diff([3, 5, 1], [1, 8, 2, 6, 4])
The length of the shorter list is 3, so your loop will be
responsible for finding the absolute values of the differences in
the first 3 positions of the lists. At the conclusion of the
loop, result will have a value of [2, 3, 1], since those are
absolute values of the differences (3 - 1), (5 - 8), and (1 - 2).
Then, your code after the loop will need to include the extra
elements from the longer list so that you end up with a final
return value of [2, 3, 1, 6, 4].
How do I approach the “time-travel” investment strategy (option 7)?
We discussed a similar function in lecture on 3/19 (the
diff_indices function) that we encourage you to use as a model.
For this task, the indices of the list represent days. We are
interested in finding the largest positive difference between
any two prices and the days on which they occur. This problem is
similar to diff_indices, so make sure to read it over and
understand how it works.
The hard part will be creating your nested for loops. Answering
these two questions should help you get started:
For each stock price, what other prices should you compare it with?
Can you get the necessary prices by somehow slicing the original
prices list? (Hint: This should give you the list for your
inner for loop.)
How do I get the dimensions of the grid given to copy?
We discussed this in the lecture on 2-D lists.
num_rows = len(grid) num_cols = len(grid[0])
When I call print_grid to print one of my grids, getting the
following error message:
TypeError: object of type 'NoneType' has no len()
What is going on?
In Python, when a function doesn’t return a value, it implicitly
returns a special value called None. For example, consider the
following function, which doubles each element in a list of integers:
def double_elems(vals): for i in range(len(vals)): vals[i] *= 2
Since the function changes the internals of the list, we don’t need it to return anything, because those changes will still be there after the function returns. As a result, when we call the function, we won’t see a return value:
>>> vals1 = [2, 5, 9]
>>> double_elems(vals1)
# No result is displayed!
>>>
However, it turns out that the function is returning the special
value called None, and we can see that if we make the call inside
of a print statement:
>>> vals1 = [2, 5, 9] >>> print(double_elems(vals1)) None
Given this information, there are two possible reasons why you
may be seeing the above error when you use print_grid:
One of your functions that should be returning a value isn’t
actually doing so. As a result, when you assign the return value
to a variable, you will actually be assigning None.
For example, let’s say that your copy() function isn’t
returning a value, and you then do the following:
>>> grid1 = diagonal_grid(3, 3) >>> grid2 = copy(grid1)
If copy isn’t actually returning the 2-D list that it creates,
it will implicitly return None, and you will end up assigning
None to grid2. If you then try to call print_grid(grid2),
you will get the error message mentioned above.
To fix this, make sure that any function that is supposed to return a value is actually doing so.
You are calling one of your functions that shouldn’t return a value as part of an assignment.
For example, consider the double_with_cap function that you are
writing for Problem 5. It should not be returning a value,
and thus it will implicitly return the special value None.
Because it doesn’t return a value, you should call it like this:
>>> grid1 = [[1, 2, 3], [4, 5, 6]] >>> double_with_cap(grid1, 9) # no assignment needed!
You should not call it like this:
>>> grid1 = double_with_cap(grid1, 9) # don't do this!
If you do, you will end up assigning None to grid1, and
you will lose the 2-D list to which grid1 used to refer!
Last updated on March 23, 2026.