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 241 of the coursepack as well as a related program.
I’m stuck on the weave
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 template
of the necessary loop. It will allow you to consider one index i
at
a time, and to use i
to access the character at position i
in
both s1
and s2
.
Because s1
and s2
may have different lengths, we have used
the length of the shorter string 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” characters
in the longer of the two strings – concatenating them to the result.
To figure out the logic for handling the “extra” characters, try considering concrete cases. For example, consider this call:
weave('extra', 'LETTERS')
The length of the shorter string ('extra'
) is 5, so your loop
will be responsible for weaving together the first 5 characters of
each string. At the conclusion of the loop, result
will have a
value of 'eLxEtTrTaE'
. The code that you put after the loop will
need to concatenate the extra characters from the second string
('RS'
) to give a final result of 'eLxEtTrTaERS'
.
Here are some questions that may help you to determine the logic:
How can I determine whether s1
or s2
has extra letters?
When one of the strings has extra letters, how can I access them?
In the example above, the extra letters begin at position 5
of s2
. How is that value of 5 related to other values that
I already know or can compute?
How can I construct a general expression that gives me the
extra characters for any case in which s1
has extra letters?
for any case in which s2
has extra letters?
I’m stuck on the index
function. Do you have any suggestions?
In lecture on 3/19, we considered two functions that each
process a sequence using a loop, and that include two return
statements: one inside the loop, and one after the loop has
completed. This problem is somewhat similar to those functions, so you
should review them and see how you could apply a similar approach
to this problem.
In addition, don’t forget to ask yourself one of the key questions that we pose when designing a loop-based solution: is an element-based loop sufficient, or do you need an index-based loop?
How do I approach the “time-travel” investment strategy (option 7)?
We discussed a similar function in lecture on 3/21 (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 difference between
buy and sell prices and the corresponding days. This problem is
similar to diff_indices
, so make sure to read it over and
understand how it works. Note: You want the largest value
obtained when you compute sell_price - buy_price
, and
that it’s possible that the largest such difference will be
0 or even negative.
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 take advantage of index-based loops to ensure that your inner loop only considers the appropriate set of sell prices for a given buy price?
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 April 28, 2025.