This project will help you demonstrate your mastery of strings and vectors (while maintaining your handle on functional design, branching, and repetition).
Your company has decided that their current office suite can't handle form letter generation as well as they'd hoped/expected. They've come to you to implement a system [prototype] for filling in form letters. Another team will then make measurements as to the efficiency of your system vs. the office suite's capabilities and recommend whether your system should be completed or scrapped.
Just to bring you up to speed on form letter processing, the main idea is that a template of a letter is drawn up with special place-holders instead of key information. During processing, the place-holders are filled in with actual information about a person, account, etc. and the result is printed out for mailing.
For example, here is a sample form letter to inform an interviewee they've not been selected for the job:
Dear $Interviewee, After careful consideration of your qualifications, $first, we've decided not to hire you. Although your background in $field_1 is exemplary, other candidates showed equal prowess. We also felt your work with $field_2 could have used a bit more depth. We appreciate your interest in the $position position and will be glad to keep your application on file for future reference. Please send us any updates to your qualifications so we may keep your file as complete and up to date as possible. Sincerely, $dept_head $department
(Notice that such a letter is simply a long string with \n characters in it. Especially notice that there are many blank lines — so you should allow the user to enter a blank line as valid data for their letter. Since you still need a way to know when the letter is over, have them enter a special symbol like ~ or # or $ on a line by itself to signal their letter is ended. That way, they can still use the symbol in their letter, but when it is alone on an other-wise empty line, you still know it's time to stop reading/storing the letter.)
Then, you might have a set of actual replacement data such as:
Placeholder | Candidate 1's Replacement Text |
Candidate 2's Replacement Text |
Candidate 3's Replacement Text |
---|---|---|---|
Interviewee | Mr. Hong Smith | Ms. Imelda Chang | Mr. James Ramirez |
first | Hong | Imelda | Jim |
field_1 | biological warfare | nuclear engineering | paint drying |
field_2 | soybean research | cockroach longevity | basket weaving |
position | actuary | mail clerk | custodial engineer |
dept_head | Sarah Ratts | Dr. Lita Heintz | Ng Lippman |
department | Information Technology | Customer Service | Floral Design |
Your program should read in the original document with place-holders, read in the individual replacement data for the form for each candidate (a column from the above table), perform the replacements, and print the resulting letter. Sounds simple, no? Well...no, it isn't quite that simple.
Your choice as to how you represent the replacement/place-holder mapping can affect the performance of your program. Your choice of replacement strategies can also affect your solution's speed. You should choose wisely among the alternatives.
The primary ideas you've seen for storing the data of a map (here we are mapping place-holders to replacement text) are:
parallel vectors of string: one for place-holder and one for replacement text; multiple 'candidates' repeat (duplicate) their place-holder text; each 'candidate's' data is a contiguous sub-sequence within this layout
vector of structures: each structure element contains a place-holder and replacement text for that place-holder; multiple 'candidates' repeat their place-holder text; each 'candidate's' data is a contiguous sub-sequence within this layout
parallel vectors: one of string for place-holders and one of vectors of string for replacement texts associated with the place-holder; place-holder text isn't repeated for each 'candidate'; replacement texts are parallel so that each 'candidate's' information is in a like position within the vector associated with each place-holder position in the first vector
a vector of structures: each structure contains place-holder text and a vector of strings for replacement texts for that place-holder; the replacement texts in this vector member are parallel across outer vector elements so that a particular 'candidate's' data is in like positions throughout
etc.
It would probably be a good idea when deciding amongst these data layout patterns for you to draw a little diagram of how the above letter and 3 candidates would fit in such a design. Take note of things like redundant storage of information and difficult to access data (as in 'hard to use size_types for').
Ideas you've had for replacing the place-holders are:
use find and replace
use find, erase, and insert
use find, substr, and + or +=
When deciding amongst these ideas, consider ease of implementation and possible speed effects.
You must decide which of these will yield the best performance or your project will be wasted and the company will continue to use the current office suite.
To prototype your solution, a menu-driven test application would be best:
1) enter Form 2) enter a Replacement set 3) Print filled in forms 4) Quit
As always, allow the user to choose options by number or significant (capitalized above) letter.
When entering the form, take note of (i.e. you detect) all [unique] place-holders you'll need replacement text for. They will be indicated, as in the example above, by a single $ and a [single] word. Any occurance of two dollar signs ($$) in the form should produce a single dollar sign (no special replacement text necessary) in the final, filled in form.
The user can choose 'enter replacement set' as many times as they like. Each time, they'll enter a set of replacement data that represents a single 'candidate's' information. Place this information appropriately into your mapping structure.
When the user chooses the 'print filled in forms' option, run through the original form and print out a version that has been filled in with each set of replacement data (3 'candidates', 3 printings). (Since you'll be filling in the form multiple times, you won't want to destroy the original form. Instead, make a copy of the form and fill that copy in. Then, repeating this for each candidate, you'll always have the original to work from.)
Note that your filled in version of the form may not be very pretty, don't worry about that. Fixing that is accounted for by options below.
Here's a second form letter example to help clarify/elucidate any misconceptions you may still be having.
$student $class-$section Category | Points | Weight | Weighted Points -----------------+--------------+--------------+----------------------- $asgn_cat1 | $asgn_pts1 | $asgn_wgt1 | $asgn_wgpt1 $asgn_cat2 | $asgn_pts2 | $asgn_wgt2 | $asgn_wgpt2 $asgn_cat3 | $asgn_pts3 | $asgn_wgt3 | $asgn_wgpt3 $asgn_cat4 | $asgn_pts4 | $asgn_wgt4 | $asgn_wgpt4 -----------------+--------------+--------------+----------------------- Totals | $wgt_tot | $wgpt_tot Average: $stu_avg You would need to average $get_A% for the rest of the semester to get an A. You would need to average $get_B% for the rest of the semester to get an B. You would need to average $get_C% for the rest of the semester to get an C.
Note that to get the table to line up, the person filling in the replacement text will have to space it correctly — that's not up to you. *smile*
Here's a third form letter example to help clarify/elucidate any misconceptions you may still be having.
Letter of Recommendation for $student_full To: $school_rep $school $student_first has been an exemplary student in my $courses class$course_plural. $stu_pronoun_cap has $work_gift $subjects and has done quite well in my class$course_plural. Although it will be sad to see $student_first go, I'm sure $stu_pronoun_lc will make a fine addition to $school. Sincerely, $teacher
Note how some replacements are used more than once. Also note that several
of these will have long phrases as replacement text
($courses
could be just CSC121 or it could be introductory programming (in C++) or even CSC121, CSC122, and CSC216;
$work_gift
could be a natural gift for or worked
very hard at).
This assignment is (Level 5).
Add (Level 3) to wrap the lines of the filled in form at about 70 characters. You should try mightily to break the lines at word boundaries, but if you are in the 'middle' of a particularly long word (7 or more characters), hyphenate it instead.
The hyphen need not be at a sensible location. Just try not to hyphenate before the middle of the word (leave at least 3 chars of a 7 letter word with the hyphen on the first line, for instance).
Also, if part of one line wraps, it should attach to the next line unless the next line is blank. Blank lines are to be considered paragraph boundaries and are immutable.
Add (Level 2) to fully justify their resulting line to the 70-char length (mentioned in the previous option). This should insert spaces evenly through the line to make it the 70 chars long. (Don't simply add the necessary spaces all at one location — it should look as natural as possible.)
Be careful that you don't alter any leading space on the front of a line as this might be placed there for indention purposes. (Justification should not alter this indention in any way.)
Also note that, if combined with the option above, the last (wrapped) line should not be justified (like the last line of a paragraph).
(For other tips about line wrapping, hyphenation, and justification, see the appropriate related lab.)
Add (Level 1) to provide a menu option to allow the user to set the line length, justification style, or even turn off wrapping (it wouldn't work well in the table example above, would it? *grin*).
(For other ideas about a configuration menu option/submenu, see the appropriate related lab.)
Add (Level 1.5) to allow the user to tell you what the place-holder-marking character is. This would make a great menu option. It should default to the $ as above. Note that anything they change it to, if doubled in the form text, should automatically result in a single of that in the filled in form. (i.e. If they want @ to be the place-holder marker, then @@ in the form would result in a single @ in the filled in version...and a $$ in the form would just come through as $$ in the filled in form since $ is not the place-holder marker — @ is!)
Add (Level 1.5) to time your implementation using the first method mentioned in the timing notes. (Increase this by another (Level 1.5) to use the second method.)
Add another (Level 1.5) to use your Timer class to perform the timing.
If you did all above options, this project could be worth as much as (Level 17).