Word Frequency Count: Part 2
Last modified
Background
Both user’s code should contain a barebones implementation of the
getopt
loop (see
example source ) that
parses -k
and -h
options.
-
Each group member implement a specific feature in your local code.
user1
: add error checking to thestrtol
call (see EXAMPLE section of man page forstrtol
). Only set the variable containing the value for k if a valid integer was present in the option argument for-k
. If no argument was given, or the argument did not contain an integer then print an error to standard error and exit.$ ./wordfreq -k ./wordfreq: option requires an argument -- 'k' Usage: wordfreq [-h] [-k N] $ ./wordfreq -k five No digits were found Usage: wordfreq [-h] [-k N]
Note that the first line of output shown is generated automatically by
getopt
if you configured it properly i.e. configuration string should be “k:”.user2
: add a-r
option that when present will cause the program to print the word list in reverse frequency order (least frequently used words first).$ ./wordfreq -r
The API for the analytics library has been updated to reflect support for sort options. The
opt
paramter tosort_counted_words
can be set to eitherAMAP_SORT_ASCENDING
orAMAP_SORT_DESCENDING
for sorting in ascending or descending order, respectively.Note:
user2
be sure to update the Usage message to include the-r
option:$ ./wordfreq -h Usage: wordfreq [-hr] [-k N]
-
Each group member add/commit and push changes to your own
origin
-
user1
pull changes fromuser2
’s remote:user1@local $ git pull user2 master
ideally git should merge the changes automatically. If you receive a message about a conflict in
main.c
you will need to open that file in an editor and perform a manual merge. -
Once
user1
has successfully merged, push the merged code back to your ownorigin
.user1@local $ git push origin master
-
user2
can now pull fromupstream
to update their local copy with the merged codeuser2@local $ git pull upstream master
Merge conflicts
Because both people will be modifying the top part of main where
veraibles are declared user1
will likely be notified of a conflic in
main.c
when they pull from user2
’s remote. When this occurs, open
main.c
in your text editor to see what the problem was, you will see
something like the following:
int main(int argc, char *argv[]) {
long int nlimit=10, val;
word_list_t wl;
word_map_t wm;
<<<<<<< HEAD
int opt;
char *endptr;
=======
int opt, sort_opt = AMAP_SORT_DESCENDING;
>>>>>>> 8ec39be37ec486ea8670ceb57fb70e4fa6b0b3aa
/* remainder of implementation */
}
You only need to concern yourselfe with code between the lines
starting with <<<<<<<
and >>>>>>>
, lines outside this region were
merged automatically by git. In the preceding example git is telling me that the lines
int opt;
char *endptr;
in user1
’s HEAD
(the current state of your code when you performed
the merge), and the line
int opt, sort_opt = AMAP_SORT_DESCENDING;
which were in the remote user’s code (the 40 character hexadecimal
string is the commit id of the particular commit of the merged
changes), are in conflict. In the example above, user1
has added
the char *endptr;
declaration which is used for the strtol
error
checking while user2
has added the sort_opt
declaration used for
the sort option. Both are needed, so in this case I could edit the
file to look like
int main(int argc, char *argv[]) {
long int nlimit=10, val;
word_list_t wl;
word_map_t wm;
int opt;
char *endptr;
int sort_opt = AMAP_SORT_DESCENDING;
/* remainder of implementation */
}
The result should be the complete, merged source file. Notably, you
must manually remove the three lines added by git (starting with
>>>>>>>
, <<<<<<<
and =======
) so that git
knows the conflict
has been resolved.
Once you have resoled a merge conflict by making the necessary changes to the associated files be sure to compile the program to make sure it works as expected, then add and commit the merged file:
$ git add main.c
$ git commit
Because the change is part of a merge git
will populate the commit
message with text about the merge. In most cases you will probably
just leave the generated message as is.
Submission
The source files should exist in their own git repository, if you change to the directory containing your source files and run ls -a
you should see a directory named .git
. If not, run git init
to initialize a git repository in the current directory. You should only run git init
once for each new project.
Push your git repository to the remote at git@ece2524.ece.vt.edu:USER/wordfreq.git
where USER
is your git user name.
If you have initialized a new repo but have not added a remote yet:
$ git remote add origin git@ece2524.ece.vt.edu:USER/wordfreq.git
where is your git user name.
If you have already added a remote named origin
, but the URL is incorrect, replace add
with set-url
in the above command. You can always check that remotes you have added by running git remote -v
.
Remember, if this is the first time pushing to a new remote you need to specify a destination branch (usually `master`). Using the `-u` option will save this default destination for future pushes.
$ git push -u origin master
Testing
Feature repo path: features/wordfreq
The following features will be tested using cucumber:
@compile
Feature: Compile
Background:
Given I am working from a clean git clone to "wordfreq"
And I cd to "wordfreq"
Scenario: Clean Repo
Then a file named "wordfreq" should not exist
Scenario: Compile
When I successfully run `clang -c -o main.o main.c`
Then a file named "main.o" should exist
When I successfully run `clang -o wordfreq -lanalytics main.o`
Then a file named "wordfreq" should exist
@part2 @no-clobber
Feature: Command Line Arguments
Background:
Given I cd to "wordfreq"
And a file named "fox.txt" with:
"""
the quick brown fox jumped over the lazy cow.
but the cow jumped over the moon!
what does the fox say?
"""
And a file named "numbers" with:
"""
four two four one
two four three three
three four
"""
Scenario: "-k option"
When I run the shell command "./wordfreq -k 5 < fox.txt"
Then its stdout should contain exactly 5 lines
And its stdout lines should match:
| ^\s*5\s+the$ |
| ^\s*2\s+cow$ |
| ^\s*2\s+fox$ |
| ^\s*2\s+jumped$ |
| ^\s*2\s+over$ |
And the exit status should be 0
Scenario: "-r option"
When I run the shell command "./wordfreq -r < numbers"
Then its stdout should contain exactly 4 lines
And its stdout lines should match:
| ^\s*1\s+one$ |
| ^\s*2\s+two$ |
| ^\s*3\s+three$ |
| ^\s*4\s+four$ |
And the exit status should be 0
Scenario: "-r and -k options"
When I run the shell command "./wordfreq -r -k 8 < fox.txt"
Then its stdout should contain exactly 8 lines
And its stdout lines should match:
| ^\s*1\s+brown$ |
| ^\s*1\s+but$ |
| ^\s*1\s+does$ |
| ^\s*1\s+lazy$ |
| ^\s*1\s+moon$ |
| ^\s*1\s+quick$ |
| ^\s*1\s+say$ |
| ^\s*1\s+what$ |
And the exit status should be 0
@part2 @no-clobber
Feature: Command Help Options
Background:
Given I cd to "wordfreq"
And a file named "numbers" with:
"""
four two four one
two four three three
three four
"""
Scenario: "-h option"
When I run the shell command "./wordfreq -h"
Then the exit status should be 0
Scenario: "invalid option"
When I run the shell command "./wordfreq -x < numbers"
Then the exit status should not be 0
And its stdout should contain exactly 0 lines
And its stderr should contain at least 1 line
And its stderr should contain at most 2 lines
And its stderr should contain a line matching /^Usage: (?:\.\/)?wordfreq \[-hr\] \[-k N\]$/
@part2 @no-clobber
Feature: Collaboration
Background:
Given I cd to "wordfreq"
Scenario: "Contributors"
Then the git repo should have at least 2 contributors
You can run the tests manually with
$ cucumber /usr/share/features/wordfreq
when logged in to your shell account. This command assumes your current working directory is your project directory.