Homework Four

Published

March 6, 2025

Due 2025-03-13 at the start of class

Download Starter Files Submit on Gradescope

Objectives

  • Demonstrate your ability to write a for loop
  • Demonstrate your ability to write a while loop
  • Demonstrate your ability to write a recursion function
  • Demonstrate your expanding ability to use conditional statements and manipulate strings

Getting started

For this assignment, we have another four functions for you to write. Please pay attention to all of these instructions. Even this front matter, which may look the same (and many of you skip over) has changed.

For this assignment, we have provided a starter file so that we can give you some extra helper functions. Please do all of your work in the enclosed file.

Feel free to work through the functions in any order. We do, however, suggest that you take the time to test each one as you go rather than trying to write all four out like they were part of an essay and then testing at the very end. Treat these are four totally separate and distinct problems (which they are).

Submit your solution on Gradescope using the button above. Feel free to resubmit as your complete each problem to check your progress.

Python subset

For this assignment, you now have recursion, while loops, and for loops in your toolbox. We are still working on your skills and intuition with respect to this, so read the problem description closely. Most of them specify which approach we would like you to use, and your solution should use the specified approach to receive credit.

While you are not reimplementing any core functions with this assignment, we are still getting very close to some standard methods that we would like you to continue to avoid for the time being. Unless explicitly permitted in the problem description, the only functions you are allowed are

  • the type converters (bool(), float(), int(), str())
  • string methods upper() and lower()
  • character converters ord() and char()
  • len()
  • range()

Satisfactory vs. Excellence

A solution for these questions that is excellent will have the all of the following qualities

Style

An excellent function will have a docstring that is formatted in the way shown in the lectures. It should include:

  • the purpose of the function
  • the type and purpose of each parameter (if any)
  • the type and meaning of the output (if any)

In addition, you should follow some of the PEP8 guidelines on whitespace. The ones we will be looking at are:

  • no whitespace between names and ( or [ (e.g., f (5) should be f(5) and s [3:5] should be s[3:5])
  • there should be a single space around operators (e.g., x=4+1 should be x = 4 + 1 and y = 3 -2 should be y = 3 - 2)
  • there should be a space after commas, but not before (e.g., f(4 , 5) or f(4,5) should be f(4, 5))

Special cases and requirements

For some of the problems, we have identified special cases or requirements that we have deemed potentially more challenging and not essential to a satisfactory solution. An excellent solution will cover all cases. These cases will be identified in the autograder by tests with * at the end of the title (so make sure you submit frequently as you are working).

Problem 1: Same count

Write a function called same_count, which takes three string arguments: text, sub1, and sub2. The function should return True if sub1 appears the same number of times in text as sub2, and False if it does not. This function should use a loop.

same_count
Parameters
text str
sub1 str
sub2 str
Return type bool

Examples

>>> same_count("abcdef", "mn", "st")
True
>>> same_count("abcdef", "ab", "de")
True
>>> same_count("aaaaabbbbbabab", "a", "b")
True
>>> same_count("aabbaaabb", "a", "b")
False

Problem 2: Caesar cipher

The Caesar cipher is a substitution cipher in which each letter is substituted with a different letter \(n\) positions away in the alphabet. The value \(n\) is called the key.

If the key is 3, our substitutions will look like this:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
D E F G H I J K L M N O P Q R S T U V W X Y Z A B C

So, the word “cat” would become “fdw”. Notice that when we run out of letters, we wrap around and start the alphabet again.

The algorithm is:

  • convert each letter to a number between 0 and 25 (we have provided a function called letter_to_index to help with this)
  • shift the number by the key, remembering to wrap around if the index exceeds the number of letters in the alphabet Hint: the module operator (%) might be useful here.
  • convert the number back to a letter (we have provided a second function called index_to_letter to help with this)

To decode an encrypted message, we simply reverse this process.

For more information about the Caesar Cipher, see this article:

You should write a function called caesar_cipher which takes three arguments:

  • message - a string containing the message
  • key - an integer key
  • encode - a boolean indicating if we are encoding (True) or decoding (False)

Any character that is not alphabetical (A-Z or a-z) should be copied into the output directly (e.g., whitespace, punctuation, numbers, etc…). Yes, this does compromise the security a bit – but not as much as converting spaces and making it very easy for an adversary to work out the key.

This function should use a for loop.

To receive a mark of excellent, encoded/decoded characters should retain their case.

caesar_cipher
Parameters
message str
key int
encode bool
Return type str

Examples

>>> caesar_cipher("cat", 3, True)
'fdw'
>>> caesar_cipher("fdw", 3, False)
'cat'
>>> caesar_cipher("You can't read this.", 10, True)
"Iye mkx'd bokn drsc."
>>> caesar_cipher("Iye mkx'd bokn drsc.", 10, False)
"You can't read this."
>>> caesar_cipher("abcdefghijklmnopqrstuvwxyz", 4, True)
'efghijklmnopqrstuvwxyzabcd'

Problem 3: Word extractor

Write a function called word_extractor that takes in a single string called text. text is a string containing (potentially) multiple words, separated by spaces. The function will “neaten” the words, returning a new string with the words separated by a comma and a single space.

This function should be recursive and should not use any loops.

word_extractor
Parameters
text str
Return type str

Examples

>>> word_extractor("abc def ghi jkl")
'abc, def, ghi, jkl'
>>> word_extractor("abc        def  ghi    jkl   ")
'abc, def, ghi, jkl'
>>> word_extractor("  abc        def  ghi    jkl   ")
'abc, def, ghi, jkl'
>>> word_extractor("  not just  three letter words      in here ")
'not, just, three, letter, words, in, here'

Problem 4: Skip around

Write a function called skip_around. which takes a string parameter called data and an integer parameter max_length. The function will read the string and return a new string containing the characters it found. If the function walked the string as many of our examples have (one character at a time from left to right), it would return a copy of data. However, embedded in the string there will be commands that instruct the function to change the direction it is reading and the size of the interval between characters it visits. The function will continue to move in the new direction and with the new step size until it reaches a new command or the function ends.

  • The function’s initial direction is forwards with a step size of 1.
  • If the function reads an “F”, it reads the next character which should be a digit between 1-9 inclusive. The “F” means to move forwards through the data (increasing index), and the number provides the size of the steps to take (starting from the “F”).
  • If the function reads an “B”, it reads the next character which should be a digit between 1-9 inclusive. The “B” means to move backwards through the data (decreasing index), and the number provides the size of the steps to take (starting from the “R”).
  • If the function reads any other character, it saves it to the output string (if the function lands on the digit associated with a command, it is treated as a normal character).
  • If the size of the output string reaches max_length, the function stops and returns the output string.
  • If the function walks off either end of the data, the function stops and returns the output string.
skip_around
Parameters
data str
max_length int
Return type str

Examples

>>> skip_around("abcdefg", 20)
'abcdefg'
>>> skip_around("abcdefg", 3)
'abc'
>>> skip_around("abcF2defg", 20)
'abcdf'
>>> skip_around("abcF2deB3g", 20)
'abcd2b'
>>> skip_around("abcF2deB2g", 20)
'abcddddddddddddddddd'