Assignment 13: String objects; Working with files
due by 9:00 p.m. EST on Thursday 3/7/24
Preliminaries
In your work on this assignment, make sure to abide by the collaboration policies of the course.
For each problem in this problem set, we will be writing or evaluating some Python code. You are encouraged to use the Spyder IDE which will be discussed/presented in class, but you are welcome to use another IDE if you choose.
If you have questions while working on this assignment, please post them on Piazza! This is the best way to get a quick response from your classmates and the course staff.
Programming Guidelines
-
Refer to the class Coding Standards for important style guidelines. The grader will be awarding/deducting points for writing code that comforms to these standards.
-
Every program file must begin with a descriptive header comment that includes your name, username/BU email, and a brief description of the work contained in the file.
-
Every function must include a descriptive docstring that explains what the function does and identifies/defines each of the parameters to the function.
-
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 (
_
). -
Make sure that your functions return the specified value, rather than printing it. None of these functions should use a
print
statement. -
If a function takes more than one input, you must keep the inputs in the order that we have specified.
-
You should not use any Python features that we have not discussed in class 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.
-
You must test your work before you submit it You can prove to yourself whether it works correctly – or not – and make corrections before submission. If you need help testing your code, please ask the course staff!
-
Do not submit work with syntax errors. Syntax errors will cause the Gradescope autograder to fail, resulting in a grade of 0.
Warnings: Individual Work and Academic Conduct!!
-
This is an individual assignment. You may discuss the problem statement/requirements, Python syntax, test cases, and error messages with your classmates. However, each student must write their own code without copying or referring to other student’s work.
-
It is strictly forbidden to use any code that you find from online websites including but not limited to as CourseHero, Chegg, or any other sites that publish homework solutions.
-
It is strictly forbidden to use any generative AI (e.g., ChatGPT or any similar tools**) to write solutions for for any assignment.
Students who submit work that is not authentically their own individual work will earn a grade of 0 on this assignment and a reprimand from the office of the Dean.
If you have questions while working on this assignment, please post them on Piazza! This is the best way to get a quick response from your classmates and the course staff.
Task 1: Using string methods
30 points; individual-only
This task will give you practice with using the methods that are inside every string object.
Begin by downloading this file: a13_strings.py
.
When you open the file in Spyder, you’ll see that we’ve given you the following strings:
s1 = 'Three little kittens lost their mittens' s2 = 'Star light, star bright' s3 = 'Nothing YOU can do, but YOU can learn how to be YOU in time'
We have also given you the solution to the first puzzle.
Warmup
Run a13_strings.py
in Spyder, so that the strings s1
and s2
will be
available to you in the Python Shell (i.e., the interactive console).
Next, enter the following method calls and other expressions from the Shell, and take note of the values that are returned:
>>> s1.upper() >>> s1 >>> s2.lower() >>> s2 >>> s1.title() >>> s1 >>> s2.count('s') >>> s2.lower().count('s') >>> s1.count('tt') >>> s1.replace('th', 'f') >>> s1.lower().replace('th', 'f') >>> s2.replace('r', 'x') >>> s2.replace('ar', 'amp') >>> s1 >>> s2
-
Write a function
to_upper_case(s, word)
that will process a string variables
, and return a new string in which all occurrences of the stringword
have been changed to upper case, but all other words remain unchanged.For example:
>>> s1 = 'Three little kittens lost their mittens' >>> to_upper_case(s1, 'little') Three LITTLE kittens lost their mittens >>> to_upper_case(s1, 'tt') Three liTTle kiTTens lost their miTTens
You can accomplish this using only methods on the string object. Do not use any loops or the accumulator pattern.
After you get the “basic” version working, you should re-write it to handle some special cases, such as when the word to replace is in all lower case, or in title case (first letter capitalized).
For example:
>>> s2 = 'Star light, star bright' >>> to_upper_case(s2, 'star') STAR light, STAR bright
-
Write a function
count_vowels(s)
that will return the count of all vowels in the strings
. You have written a function like this before, but now you must use the string methodcount
. You may not iterate over each character in the string, as we did previously.For example:
>>> s1 = 'Three little kittens lost their mittens' >>> count_vowels(s1) 11
The function should work just as well with either upper or lower case letters:
For example:
>>> s2 = 'Star light, star bright' >>> count_vowels(s2.upper()) 4 >>> s3 = 'Nothing YOU can do, but YOU can learn how to be YOU in time' >>> count_vowels(s3) 20
Task 2: Reading and writing files
50 points; individual-only
In this task, you will work with some text files to read/process the contents, as well as to create a new (output) file. The simplest way to use text files from within Python is to put the files in the same directory (folder) as your Python code files.
Here are some text files for you to download and work with:
- time.txt: “Time”, a poem by Yehudah Amichai
- all_you_need.txt: “All You Need is Love”, a song by the Beatles
- romeo.txt: “Romeo and Juliet”, by William Shakespeare
- grapes.txt: “The Grapes of Wrath”, by John Steinbeck
You may also use any other (ASCII-only) text file as well.
Do all of the work for this task in a file called a13_file_operations.py
.
-
The unix operating system (including all MacOS computers) includes a pattern-matching program called
grep
.grep
searches for a pattern in one or more files, and prints out all matching lines.Here is an example of using
grep
in a Macbook Terminal window. The commandgrep print functions.py
searches for all occurrences of the patternprint
in the filefunctions.py
.Write the function
grep(pattern, filename)
to search for thepattern
in the file identified byfilename
. The function must return a string containing all matching lines, with line breaks (the character\n
) inserted where appropriate.For example:
>>> fn = 'a02_functions.py' >>> print(grep('print', fn)) print("cube(3) = ", cube(3)) print("slope(1, 2, 3, 4) = ", slope(1, 2, 3, 4)) print("cylinder_volume(4, 2) = ", cylinder_volume(4, 2))
Note! This function is not printing – it is returning a string, which contains embedded line breaks (
'\n'
) characters). If you call the function at the console, but not in a print statement, you will see the string returned with the embedded characters.>>> fn = 'a02_functions.py' >>> grep('print', fn) # find all occurences of 'print' in the file 'print("opposite(3) = ", opposite(3))\nprint("cube(3) = ", cube(3))\nprint("slope(1, 2, 3, 4) = ", slope(1, 2, 3, 4))\nprint("cylinder_volume(4, 2) = ", cylinder_volume(4, 2))\n'
The simplest way to accomplish this result is to use an accumulator pattern to process the file, one line at a time. For each line (a string), use one of the string methods to determine if that line contains the
pattern
. If it does, accumulate that line into your result.If there are no occurrences of the
pattern
, the function will return an empty string. -
The
grep
program also has a way to count the number of lines within a file that contain the patter.Here is an example of using
grep -c
in a Macbook Terminal window. The commandgrep print functions.py
searches for all occurrences of the patternprint
in the filefunctions.py
, and returns the count of the number of matching lines.Notice how this version (with the
-c
flag) returns the number of occurrences, but not the actual matching lines.Write the function
grep_count(pattern, filename)
to search for thepattern
in the file identified byfilename
. The function will return an integer, which is the count of the number of lines containing thepattern
.For example:
>>> fn = 'a02_functions.py' >>> grep_count('print', fn) 4 >>> grep_count('(', fn) 13 >>> grep_count('+', fn) 0
The simplest way to accomplish this result is to use an accumulator pattern to process the file, one line at a time. For each line (a string), use one of the string methods to determine if that line contains the
pattern
. Count that line as one match within your accumulation. -
Write the function
find_and_replace(input_filename, output_filename, old_pattern, new_pattern)
that will process the file identified byinput_filename
, and replace all occurences of the stringold_pattern
with the stringnew_pattern
. The function will write the results to a file identified byoutput_filename
.The function will also produce several print outs, to provide some explanation of how it worked.
For example, here’s is some client code to read the file
"all_you_need.txt"
, and create the result file"all_you_need.txt"
. It replaces all occurrences of"Love"
with"Chocolate"
, and produces 3 lines of output to the console:>>> input_filename = "all_you_need.txt" >>> output_filename = "all_you_need_out.txt" >>> find_and_replace(input_filename, output_filename, "Love", "Chocolate") Read input file `all_you_need.txt`. Replaced 30 occurences of `Love` with `Chocolate`. Wrote output file `all_you_need_out.txt`.
Here are the first few lines of the output file:
All You Need is Chocolate Lennon/McCartney Chocolate, love, love Chocolate, love, love Chocolate, love, love
You will notice that all occurrences of the string
"Love"
have been replaced by"Chocolate"
, but"love"
(with a lower case'l'
) has not been replaced.Begin by testing a version to make these replacements. Once it works, you should enhance your function to handle several permutations of the
old_pattern
, and replace each with the corresponding permutation of thenew_pattern
:-
the actual
old_pattern
should be replaced bynew_pattern
-
the UPPERCASE version of
old_pattern
should be replaced by an UPPERCASE version ofnew_pattern
-
the lowercase version of
old_pattern
should be replaced by a lowercase version ofnew_pattern
-
the Title version of
old_pattern
should be replaced by a Title version ofnew_pattern
For example (enhanced version):
>>> input_filename = "all_you_need.txt" >>> output_filename = "all_you_need_out.txt" >>> find_and_replace(input_filename, output_filename, "Love", "Chocolate") Read input file `all_you_need.txt`. Replaced 30 occurences of `Love` with `Chocolate`. Replaced 44 occurences of `love` with `chocolate`. No occurences of `LOVE` were found. Wrote output file `all_you_need_out.txt`.
Here are the first few lines of the new output file:
All You Need is Chocolate Lennon/McCartney Chocolate, chocolate, chocolate Chocolate, chocolate, chocolate Chocolate, chocolate, chocolate
Hints:
-
You can solve this the hard way: using one or more loops and accumulators and decision statements, or...
-
You can solve this the easy way: using some of the string object’s methods to obtain the UPPERCASE, lowercase, and Title versions of the strings.
-
Submitting Your Work
20 points; will be assigned by code review
Log in to GradeScope to submit your work.
Be sure to name your files correctly!
You will submit two files for this assignment:
a13_strings.py
and
a13_file_operations.py
.
When you upload the files, the autograder will test your program.
Notes:
-
Upload these files to Gradescope before the deadline.
-
When you upload, the autograder script will process your file(s).
-
You may resubmit as many times as you like before the deadline, and only the grade from the last submission will be counted.
Warning: Beware of Global print
statements
-
The autograder script cannot handle
print
statements in the global scope, and their inclusion causes this error:The autograder failed to execute correctly. Please ensure that your submission is valid. Contact your course staff for help in debugging this issue. Make sure to include a link to this page so that they can help you most effectively.
-
You can prevent this error by not having any
print
statements in the global scope. Instead, create anif __name__ == '__main__':
section at the bottom of the file, and put any test cases/print statements in that controlled block. -
print
statements inside of functions do not cause this problem.