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.
You may also find it helpful to consult the general questions from the PS 1 FAQ and PS 2 FAQ, and the page we have assembled with info about common Python errors.
Can you explain how we are supposed to use num_occur_lc
or
num_occur_rec
in our work on most_occur
?
In lecture, we considered a function called best_word
that took
a list of words and found the word with the highest scrabble
score. This function is very similar to that one, but it needs to
find the word with the most occurrences of the character c
. In
the same way that best_word
used scrabble_score
as a helper
function, most_occur
should use either num_occur_lc
or
num_occur_rec
as a helper function – and it should do so in the
context of the list-of-lists technique that we used in
best_word
.
Any hints for the encipher
function?
As the hint that accompanies the problem itself suggests,
the structure of this function should end up being similar to the
scrabble_score
function that you wrote for Problem Set
2. In the same way that scrabble_score
called
letter_score
to determine the score of a single letter and added
it to the score of the rest of the word, encipher
should call
rotate
to determine the rotated version of a singlce character and
use concatenation to add it to the rotated version of the rest of
the string.
Don’t forget that rotate
takes two inputs: a single character c
and the shift amount n
, so you will need to pass it appropriate
inputs.
For example, let’s say that you are solving the problem
encipher('hello', 2)
:
The first recursive call will be encipher('ello', 2)
,
and it should give you back the string 'gnnq'
, since that is
the result of shifting 'ello'
by 2 places.
You should then call rotate('h', 2)
to shift the 'h'
by
2 places, which should give you 'j'
You can then concatenate 'j' + 'gnnq'
to get 'jgnnq'
, which
is the value that you should return.
Any hints for the decipher
function?
Make sure to follow the approach that is outlined in the problem set.
Focus on one step at time, and make sure that each step works
before going on to the next step. You can utilize temporary
print
statements in your function to check if you are getting
the right values for each step.
For example, after you complete step (a), add a temporary print
statement that prints the list that has been assigned to the
variable options
. Then try calling the function for a short
string, and see if you get the appropriate value for
options
. For example, if you make the call decipher('hello')
,
the beginning of the list assigned to options
should look like
the following:
['hello', 'ifmmp', 'jgnnq', 'khoor', 'lipps', ...
Note that the first 5 strings in options
are the results of
rotating 'hello'
by 0, 1, 2, 3, and 4 places. The rest of the
list should show all of the remaining possible rotations of
'hello'
(by 5 through 25 places).
Then, after each of the remaining steps, you can add a temporary
print
statement to see if the results make sense for some
sample inputs.
How can I pick the most likely option in decipher
?
In lecture, we covered a lists-of-lists technique for
problem-solving, and we went over a very similar problem of choosing
the scrabble word with the highest score. Look over the
best_word
function in the lecture notes, and think about how you
could take the list-of-lists technique that we used there and apply
it to the decipher problem.
My index_first
function works in some cases, but not in others.
Do you have any suggestions?
As usual, it can help to consider some concrete cases. For example, let’s assume that you’re taking our typical approach and making recursive calls on a slice that includes everything but the first element.
Consider the initial call index_first(5, [2, 3, 4, 5, 6, 7])
. It will
involve a series of calls:
index_first(5, [2, 3, 4, 5, 6, 7]) index_first(5, [3, 4, 5, 6, 7]) index_first(5, [4, 5, 6, 7]) etc.
Given those calls, ask yourself two questions:
How far do the recursive calls need to go? Do they need to go
all the way to the empty list, or is it possible to stop
earlier? If it is possible to stop early in some cases, make
sure to include the base case(s) that will do so. If not, make
sure to have a base case for the empty list. Remember that you
are not allowed to use the in
operator in this function.
What do I need to do with the value that is returned by the
recursive call? Remember that the recursive call is solving a
smaller subproblem. How can you use the solution to that smaller
subproblem to determine the solution to the original problem?
For the example above, how could you use the solution to the
subproblem index_first(5, [3, 4, 5, 6, 7])
to determine the solution
to index_first(5, [2, 3, 4, 5, 6, 7])
?
Next consider the initial call index_first(8, [2, 3, 4, 5, 6, 7])
–
which is a call in which the value does not appear in the list at
all. It will involve a series of calls:
index_first(8, [2, 3, 4, 5, 6, 7]) index_first(8, [3, 4, 5, 6, 7]) index_first(8, [4, 5, 6, 7]) etc.
Given those calls, ask yourself two questions:
How far do the recursive calls need to go? Do they need to go
all the way to the empty list, or is it possible to stop
earlier? If it is possible to stop early in some cases, make
sure to include the base case(s) that will do so. If not, make
sure to have a base case for the empty list. Remember that you
are not allowed to use the in
operator in this function.
What do I need to do with the value that is returned by the
recursive call? Remember that the recursive call is solving a
smaller subproblem. How can you use the solution to that smaller
subproblem to determine the solution to the original problem?
For the example above, how could you use the solution to the
subproblem index_first(8, [3, 4, 5, 6, 7])
to determine the
solution to index_first(8, [2, 3, 4, 5, 6, 7])
?
Finally, keep in mind the following hint from the problem:
When deciding what to do after the recursive call returns, you will need to base your decision on the result of the recursive call.
That means that you will need an if
statement in the recursive
case, and it needs to have a condition that is based on the result
of the recursive call. In other words, you need to look at the
value that is returned by the recursive call in order to decide
what you should return.
Last updated on April 28, 2025.