→This assignment is due by Friday, October 11, 2024, 11:59 PM.←
→ As with all assignments, this must be an individual effort and cannot be pair programmed. Any debugging assistance must follow the course collaboration policy and be cited in the comment header block for the assignment.←
Jump To: Rubric Submission
In this assignment, we will focus on classes, vectors, strings, File I/O, and Functions!
Overview
Have you ever finished a book and wondered, "Geez, I wonder how many times each word occurs in this text?" No? This assignment illustrates a fundamental use of collections: storing related values in a single data structure, and then using that data structure to reveal interesting facts about the data.
For this assignment, you will read in a text file containing the story Green Eggs and Ham (plus some others). You will then need to count the number of occurrences of each word & letter and display the frequencies. You'll be amazed at the results!
The Specifics
For this assignment, download the starter code pack. This zip file contains several files:
main.cpp
- the predetermined main.cpp. This file shows the usage and functionality that is expected of your program. You are not allowed to edit this file. You will not be submitting this file with your assignment.Makefile
- the preset Makefile to build with your program.input/aliceChapter1.txt
- the first chapter of Alice in Wonderland in text format.input/greeneggsandham.txt
- the contents of Green Eggs and Ham in text format.input/happybirthday.txt
- the contents of singing Happy Birthday to Bjourne in text format.input/romeoandjuliet.txt
- the contents of Romeo and Juliet in text format.solutions/aliceChapter1.out
- the expected output when running your program against thealiceChapter1.txt
filesolutions/greeneggsandham.out
- the expected output when running your program against thegreeneggsandham.txt
filesolutions/happybirthday.out
- the expected output when running your program against thehappybirthday.txt
filesolutions/romeoandjuliet.out
- the expected output when running your program against theromeoandjuliet.txt
file
Object Oriented Programming
Referring to the implementation in main.cpp
, take note how the program reads as a series of subtasks and the provided comments are redundant.
The code is "self documenting" with the function names providing the steps that are occurring. Your task is to
provide the implementations for all the called functions. You will need to create four files: InputProcessor.h
& InputProcessor.cpp
and OutputProcessor.h
& OutputProcessor.cpp
to make the program work as intended.
You will want to make your program as general as possible by not having any assumptions about the data hardcoded in. Three public input files have been supplied with the starter pack. We will run your program against a fourth private input file.
Class Requirements
The UML of each class is given below.
The input, output, and task of each member function is described below as well. The functions are:
- InputProcessor::InputProcessor()
- InputProcessor::openStream()
- InputProcessor::read()
- InputProcessor::closeStream()
- InputProcessor::getAllWords()
- OutputProcessor::OutputProcessor()
- OutputProcessor::openStream()
- OutputProcessor::analyzeWords()
- OutputProcessor::write()
- OutputProcessor::closeStream()
InputProcessor::InputProcessor()
Input: None
Output: N/A
Task: Initializes any private data members to sensible values
InputProcessor::openStream()
Input: None
Output: Boolean - true if the stream opened successfully, false otherwise
Task: Prompt the user for the filename of the file they wish to open, then open an input file stream for
the given filename.
InputProcessor::read()
Input: None
Output: None
Task: Read all the words that are in the input stream and store in the private vector of all words.
InputProcessor::closeStream()
Input: None
Output: None
Task: Close the file stream.
InputProcessor::getAllWords()
Input: None
Output: A vector of strings containing all the words
Task: The function will return the private vector of strings.
OutputProcessor::OutputProcessor()
Input: None
Output: N/A
Task: Initializes private data members to sensible values (there are no words present).
OutputProcessor::openStream()
Input: None
Output: Boolean - true if the stream opened successfully, false otherwise
Task: Prompt the user for the filename of the file they wish to open, then open an output file stream for
the given filename.
OutputProcessor::analyzeWords()
Input: (1) A vector of strings containing all the words (2) A string denoting punctuation to remove
Output: None
Task: For each word in the provided vector, remove all occurrences of all the punctuation characters denoted
by the punctuation string and convert each character to its upper case equivalent. Store these modified strings in the
appropriate private vector.
The function will then compute the unique set of words present in the modified words vector. It will also count
the number of occurrences of each unique word in the entire text. The private vectors
will be the same size with element positions corresponding to the same word and count.
OutputProcessor::write()
Input: None
Output: None
Task: This function will print the following information to the output stream, in the order and format specified.
This output must match the specification exactly.
- How many words were read in
- How many unique words were read in
- The complete list of unique words and their associated counts
- The most frequent word
- The least frequent word
- A list of letters and their associated counts
- The most frequent letter
- The least frequent letter
How many words were read in & How many unique words were read in
Print how many total words and how many unique words were read in. Format the output as follows:
Read in #T words
Encountered #U unique words
The values correspond to the following :
#T
- The number of total words read in.#U
- The number of unique words read in.
An example (based on singing Happy Birthday to Bjourne) is shown below:
Read in 16 words
Encountered 5 unique words
Refer to the solution files for longer examples on the expected formatting.
The complete list of unique words and their associated counts
For each word, print out the word and its corresponding count. Format the output as follows:
WORD1 : #C
WORD2 : #C
...
WORDN : #C
Notice how there are two columns. We want the values aligned in each column. The columns correspond to the following values:
WORD
- The word. Left align all values. Allocate enough space for the length of the longest word present. (Assume the longest word will be at most 20 characters long.)#C
- The corresponding count of the letter. Right align all values. Allocate enough space for the length of the most frequent letter present in the file. (Assume there will be at most 1010 unique words.)
An example (based on singing Happy Birthday to Bjourne) is shown below:
HAPPY : 4
BIRTHDAY : 4
TO : 4
YOU : 3
BJOURNE : 1
Refer to the solution files for longer examples on the expected formatting.
The most frequent word & The least frequent word
Print out the two words that occur least often and most often. If there is more than one word that occurs the same number of times, print the one that is encountered first. Print out the following pieces of information:
- The word
- The number of occurrences
- The frequency of appearance as a percentage to 3 decimal places
Format the output as follows:
Most Frequent Word: WORD1 #C (#P%)
Least Frequent Word: WORD2 #C (#P%)
Notice how there are three columns of values. The columns correspond to the following values:
WORD#
- The word. Left align all values. Allocate enough space for the length of the longest word present. (Assume the longest word will be at most 20 characters long.)#C
- The corresponding count of the word. Right align all values. Allocate enough space for the length of the most frequent letter present in the file. (Assume there will be at most 1010 occurrences.)#P
- The frequency of the word. Right align all values. Print to three decimal places.
An example with actual values is shown below:
Most Frequent Word: HAPPY 4 ( 25.000%)
Least Frequent Word: BJOURNE 1 ( 6.250%)
Refer to the solution files for longer examples on the expected formatting.
A list of letters and their associated counts
For each letter, print out the letter and its corresponding count to the provided output stream. Format the output as follows:
A: #C
B: #C
...
Y: #C
Z: #C
Notice how there are two columns. We want the values aligned in each column. The columns correspond to the following values:
A
- The letter#C
- The corresponding count of the letter. Right align all values. Allocate enough space for the length of the most frequent letter present in the file. (Assume there will be at most 1010 occurrences of each letter.)
An example (based on singing Happy Birthday to Bjourne) is shown below:
A: 8
B: 5
C: 0
D: 4
E: 1
F: 0
G: 0
H: 8
I: 4
J: 1
K: 0
L: 0
M: 0
N: 1
O: 8
P: 8
Q: 0
R: 5
S: 0
T: 8
U: 4
V: 0
W: 0
X: 0
Y: 11
Z: 0
Refer to the solution files for longer examples on the expected formatting.
The most frequent letter & The least frequent letter
Print out the two letters that occur least often and most often to the provided output stream. If there is more than one letter that occurs the same number of times, print the one that comes first alphabetically. Print out the following pieces of information:
- The letter
- The number of occurrences
- The frequency of appearance as a percentage to 3 decimal places
Format the output as follows:
Most Frequent Letter: Z #C (#P%)
Least Frequent Letter: A #C (#P%)
Notice how there are three columns of values. The columns correspond to the following values:
A
- The letter.#C
- The corresponding count of the letter. Right align all values. Allocate enough space for the length of the most frequent letter present in the file. (Assume there will be at most 1010 occurrences.)#P
- The frequency of the letter. Right align all values. Print to three decimal places.
An example with actual values is shown below:
Most Frequent Letter: Y 11 ( 14.474%)
Least Frequent Letter: C 0 ( 0.000%)
Refer to the solution files for longer examples on the expected formatting.
OutputProcessor::closeStream()
Input: None
Output: None
Task: Close the file stream.
Extra Credit
For extra credit, sort the unique words and their associated counts. Sample outputs are provided and denoted by solutions/*_xc.out
. The sample output
for singing Happy Birthday is below:
BIRTHDAY : 4
BJOURNE : 1
HAPPY : 4
TO : 4
YOU : 3
Most Frequent Word: BIRTHDAY 4 ( 25.000%)
Least Frequent Word: BJOURNE 1 ( 6.250%)
Notice the additional change in the most frequent word selected.
Functional Requirements
- You may not make use of the standard library functions
std::sort()
,std::find()
,std::any_of()
or anything else from#include <algorithm>
. You must implement your own functions. (You are permitted, and encouraged, to usestd::string::find()
.) - DO NOT use global variables.
- You must use parameters & class members properly.
- For this assignment, the output must match the example solutions exactly. The public provided test files are expected to match the provided output files exactly. The private test file will need to generate the expected output as well.
Hints
- Do not wait until the day before this is due to begin.
- The first step is to create the files and class function stubs to get the program to compile and run.
- The second step is to implement each function one at a time. Verify the function is correct before moving on to the next function.
- Do not just dive into the assignment. Create a mental plan of what tasks your program needs to accomplish. Convert this to pseudocode. Tackle the first task (eg, "can I open the file ok?") and conduct a sanity check. Then tackle the next task (eg, "can I read all the words in the file, and store the frequencies of each word?") and conduct another sanity check. We strongly suggest writing your program (one step at a time!)
- You may modify
main.cpp
to verify each step is working properly, but you will not be submitting this file. Be sure your classes work with the expected provided files. - You may add additional functions to assist if you deem it necessary. A common task is determining how many digits are present in an integer.
Grading Rubric
Your submission will be graded according to the following rubric:
Points | Requirement Description |
0.5 | Submitted correctly by Friday, October 11, 2024, 11:59 PM |
0.5 | Project builds without errors nor warnings. |
2.0 | Best Practices and Style Guide followed. |
0.5 | Program follows specified user I/O flow. |
0.5 | Public and private tests successfully passed. |
2.0 | Fully meets specifications. |
6.00 | Total Points |
Extra Credit Points | Requirement Description |
+0.5 | Words sorted upon output. |
Submission
Always, always, ALWAYS update the header comments at the top of your main.cpp file. And if you ever get stuck, remember that there is LOTS of help available.
Zip together your InputProcessor.h, InputProcessor.cpp, OutputProcessor.h, OutputProcessor.cpp
files and name the zip file A3.zip
. Upload this zip file to Canvas under A3.
→This assignment is due by Friday, October 11, 2024, 11:59 PM.←
→ As with all assignments, this must be an individual effort and cannot be pair programmed. Any debugging assistance must follow the course collaboration policy and be cited in the comment header block for the assignment.←