$24.99
1
The goal of this assignment is to give you practice at C programming. You will be building on this ability in the 2
remainder of the course (and subsequent programming assignments will be more difficult than this one). You 3
are to create a program (called uqwordiply) which allows users to play the Wordiply game (wordiply.com).
4
it operates. The assignment will also test your ability to code to a particular programming style guide, and to 6
use a revision control system appropriately. 7
Student Conduct 8
the assignment specification with fellow students, including on the discussion forum. In general, questions like 10
“How should the program behave if hthis happensi?” would be safe, if they are seeking clarification on the 11
specification. 12
You must not actively help (or seek help from) other students or other people with the actual design, structure 13
and/or coding of your assignment solution. It is cheating to look at another student’s assignment code 14
and it is cheating to allow your code to be seen or shared in printed or electronic form by others. 15
collusion, formal misconduct actions will be initiated against you, and those you cheated with. That’s right, if 17
you share your code with a friend, even inadvertently, then both of you are in trouble. Do not post your 18
code to a public place such as the course discussion forum or a public code repository. (Code in private posts 19
extensions so do not post your code to any public repository until at least three months after the result release 21
access your computer – you must keep your code secure. Never leave your work unattended. 23
You must follow the following code referencing rules for all code committed to your SVN repository 24
(not just the version that you submit): 25
Code Origin Usage/Referencing
Code provided to you in writing this semester by CSSE2310/7231 teaching staff (e.g. code hosted on Black-
Code you have personally written in a previous enrolment in this course or in another ITEE course and where that code has not been shared or published.
Code (in any programming language) that you have taken inspiration from but have not copied .
Code Origin Usage/Referencing
26
many cooperate with us in misconduct investigations. 28
The teaching staff will conduct interviews with a subset of students about their submissions, for the purposes 29
of establishing genuine authorship. If you write your own code, you have nothing to fear from this process. If 30
you legitimately use code from other sources (following the usage/referencing requirements in the table above) 31
then you are expected to understand that code. If you are not able to adequately explain the design of your 32
solution and/or adequately explain your submitted code (and/or earlier versions in your repository) and/or 33
be able to make simple modifications to it as requested at the interview, then your assignment mark will be 34
subject to a misconduct investigation where your interview responses form part of the evidence. Failure to 36
submission (particularly from artificial intelligence tools) is likely to increase the probability of your selection 38
for an interview. 39
In short - Don’t risk it! If you’re having trouble, seek help early from a member of the teaching staff. 40
Don’t be tempted to copy another student’s code or to use an online cheating service. Don’t help another 41
relationship. You should read and understand the statements on student misconduct in the course profile and 43
44
Specification 45
The uqwordiply game asks you to enter five words (guesses) that contain a given 3- or 4- letter combination of 46
letters (known as the starter word ). The goal is to enter valid words (based on some dictionary) that are as 47
long as possible. After entering the words, your score is reported as the sum of the lengths of the words entered, 48
and the longest possible word(s) from the dictionary are also reported. 49
You can choose to play the game with a particular starter word, or the game will choose a random one for 50
you. An example game play session is shown below. The command and guesses entered on standard input are 51
shown in bold green for clarity. Other lines are output to standard output. Note that the $ character is the 52
shell prompt – it is not entered by the user nor output by uqwordiply. 53
Uploading or otherwise providing the assignment specification or part of it to a third party including online
Example 1: Example uqwordiply game session
$ ./uqwordiply
Welcome to UQWordiply!
The starter word is: TOP Enter words containing this word.
Enter guess 1: topographical Enter guess 2:
stopping Enter guess 3: topological Enter guess 4: utopian Enter guess 5: hilltop
Total length of words found: 46 Longest word(s) found:
TOPOGRAPHICAL (13)
Longest word(s) possible:
AMINOACETOPHENETIDINE (21)
MAGNETOPLASMADYNAMICS (21) $
Full details of the required behaviour are provided below. 54
Command Line Arguments 55
Your program (uqwordiply) is to accept command line arguments as follows: 56
./uqwordiply [--start starter-word | --len length] [--dictionary filename] 57
The square brackets ([]) indicate optional arguments. The pipe symbol (|) indicates a choice – i.e. in this 58 case either the --start or the --len option argument (with associated value) can be given but not both. The 59 italics indicate placeholders for user-supplied arguments. 60
Some examples of how the program might be run include the following : 61
./uqwordiply 62
./uqwordiply --start top 63 ./uqwordiply --len 3 64 ./uqwordiply --dictionary mywords --start row 65 ./uqwordiply --start row --dictionary ./mywords 66
67
Options can be in any order, as shown in the last two examples. 68
The meaning of the arguments is as follows: 69
• --start – if specified, this option argument is followed by a 3 or 4 letter starter word (combination of 70 letters, in uppercase, lowercase or mixed-case) to be used when playing the game. (This argument can 71 only be specified if the --len argument is not given.) 72
• --len – if specified, this option argument is followed by the number 3 or 4, to indicate the length of the 73 random starter word to be chosen. (This argument can only be specified if --start is not given.) 74
• --dictionary – if specified, this option argument is followed by the name of a file that is to be used as 75 the dictionary of valid words. 76
If the --start argument is not supplied, then the program must choose a random starter word using the 77 supplied get_wordiply_starter_word() function – see the Provided Library section on page 7. If the --len 78 argument is given then the random starter word must have that length. If the --len argument is not given, 79 then the random starter word can be either 3 or 4 letters long, i.e. 0 must be supplied as the argument to 80 get_wordiply_starter_word(). 81
If a dictionary filename is not specified, the default should be used (/usr/share/dict/words). 82
Prior to doing anything else, your program must check the command line arguments for validity. If the 83 program receives an invalid command line then it must print the message: 84
Usage:uqwordiply [--start starter-word | --len length ] [--dictionary filename ]
Usage: uqwordiply [--start starter-word | --len length] [--dictionary filename] 85 to standard error (with a following newline), and exit with an exit status of 1. 86
88
associated value argument. 89
• Both the --start and --len option arguments (with associated values) are specified on the command 90
line. 91
• The value associated with the --len argument is neither 3 nor 4. 92
• Any of the option arguments are listed more than once (with associated values). Note that the command 93
line arguments --start --start would not be an invalid command line – this would be an invalid starter 94
word error – see below. 95
• An unexpected argument is present. 96
Checking whether the starter-word and/or filename arguments (if present) are valid is not part of the usage 97
checking – that is checked after command line validity – see the next section. 98
Starter Word Checking 99
If the command line arguments are valid, and the --start argument is present with an associated value, then 100
the starter-word value must be checked for validity. If the value is invalid, then your program must print the 101
message: 102
uqwordiply: invalid starter word 103
to standard error (with a following newline), and exit with an exit status of 2. 104
Invalid starter words are: 105
• those whose length is neither 3 nor 4, and/or 106
• those that contain characters other than letters (uppercase and/or lowercase). 107
In other words, a valid starter word will be 3 or 4 letters long – where those letters (A to Z) can be uppercase 108
or lowercase or a combination of both. 109
Dictionary File Name Checking 110
By default, your program is to use the dictionary file /usr/share/dict/words. If the --dictionary argument 111
is supplied, then your program must instead use the dictionary whose filename is given as the value associated 112
with that option argument. If the given dictionary filename does not exist or can not be opened for reading, 113
your program must print the message: 114
uqwordiply: dictionary file "filename" cannot be opened 115
to standard error (with a following newline), and exit with an exit status of 3. (The italicised filename is 116
replaced by the actual filename, i.e. the value from the command line. The double quotes must be present.) 117
This check happens after the command line arguments and starter word (if supplied) are known to be valid. 118
The dictionary file is a text file where each line contains a “word”. (Lines are terminated by a single newline 119
Program Operation 124
If the checks above are successful, then your program must determine a starter word if one is not given on the 125
command line. It does this by calling get_wordiply_starter_word() – see details of this provided library 126
function on page 7. 127
Your program must then print the following to standard output (with a newline at the end of each line): 128
Welcome to UQWordiply! 129
The starter word is: STARTER 130
Enter words containing this word. 131
• A valid option argument is given (i.e. --start, --len or --dictionary) but it is not followed by an
STARTER 132
Your program must then repeatedly prompt the user for a guess by printing the following message to standard 133
output (with a following newline): 134
Enter guess N: 135
where N is replaced by the guess number (from 1 to 5 as appropriate). 136
Guesses are entered on standard input and are terminated by a newline (or pending EOF). The guess must 137
then be checked for validity – with checks happening in the following order. 138
If the guess contains characters other than letters A to Z (can be any case, i.e. lowercase or uppercase), then 139
your program must print the following message to standard output (followed by a newline) and then re-prompt 140
for that guess: 141
Guesses must contain only letters - try again. 142
If the guess does not contain the starter word (with letters of any case), then your program must print the 143
following message to standard output (followed by a newline) and then re-prompt for that guess: 144
Guesses must contain the starter word - try again. 145
This same message is printed if the guess is the empty string. 146
If the guess is the starter word itself (with letters of any case), then your program must print the following 147
message to standard output (followed by a newline) and then re-prompt for that guess: 148
Guesses can’t be the starter word - try again. 149
If the guess is an invalid word (i.e. can not be found in the dictionary with letters of any case), then your 150
program must print the following message to standard output (followed by a newline) and then re-prompt for 151
that guess: 152
Guess not found in dictionary - try again. 153
If the guess is a valid word containing the starter word but you have previously guessed that word (with 154
letters of any case), then your program must print the following message to standard output (followed by a 155
newline) and then re-prompt for that guess: 156
You’ve already guessed that word - try again. 157
If a valid new word containing the starter word is entered, then your program must prompt for the next 158
word. Once five valid different words have been entered, or end-of-file (EOF ) is detected at the start of the 159
line when attempting to read a word, then your program must behave as follows. 160
If no valid guesses have been entered (e.g. EOF detected at the start of the line when reading the first 161
guess), then your program is to exit silently (no message is printed) with exit status 4. 162
If one or more valid guesses has been entered, then your program must print a blank line followed by the 163
following lines to standard output and then exit with exit status 0. 164
Total length of words found: N1 165
Longest word(s) found: 166
LONGWORD (N2) 167
Longest word(s) possible: 168
BESTWORD (N3) 169
N1 is replaced by the sum of the lengths of the valid guesses entered. LONGWORD (N2) is replaced by the 170
longest word that was guessed (printed in upper case), with its length in parentheses. If two or more words 171
are the equal longest then all words of that length are printed (in upper case, each with their length N2 in 172
parentheses). The order in which multiple words is printed is the same order in which there were entered. 173
BESTWORD (N3) is replaced by the longest valid word found in the dictionary that contains the starter word. 174
The word is printed in upper case, with its length (N3) in parentheses. If two or more words are the equal 175
longest then all words of that length are printed (in upper case, each with their length N3 in parentheses). The 176
order in which multiple words is printed is the same order in which they are found in the dictionary. (If the 177
word is present more than once in the dictionary then it is output multiple times.) 178
Other Requirements 179
Your program must open and read the dictionary file only once and store its contents (or a subset of its contents, 180
e.g. only words containing the starter word) in dynamically allocated memory. Your program must free all 181
allocated memory before exiting. 182
where is replaced by the 3 or 4 letter starter word (printed in upper case).
Example Game Sessions 183
Example 2: Example uqwordiply game session showing a variety of invalid guesses.
$ ./uqwordiply --start ism Welcome to UQWordiply!
The starter word is: ISM
Enter words containing this word. Enter guess 1: csse2310
Guesses must contain the starter word - try again. Enter guess 1: ism
Guesses can't be the starter word - try again. Enter guess 1: teachism
Guess not found in dictionary - try again. Enter guess 1: transcendentalism Enter guess 2: TRANSCENdentALISM
You've already guessed that word - try again. Enter guess 2:
UnProfessionalISM Enter guess 3:
POSTEXPRESSIONism Enter guess 4: anthropomorphisms Enter guess 5: antirepublicanism
Total length of words found: 85 Longest word(s) found: TRANSCENDENTALISM (17) UNPROFESSIONALISM (17) POSTEXPRESSIONISM (17) ANTHROPOMORPHISMS (17) ANTIREPUBLICANISM (17)
Longest word(s) possible:
ANTIDISESTABLISHMENTARIANISM (28) $
Example 3: Example uqwordiply game session showing multiple longest words.
$ ./uqwordiply --start tiES Welcome to UQWordiply!
The starter word is: TIES Enter words containing this word.
Enter guess 1: oddities Enter guess 2: twenties Enter guess 3: loftiest Enter guess 4: eighties
Enter guess 5: niceties
Total length of words found: 40 Longest word(s) found:
ODDITIES (8) TWENTIES (8) LOFTIEST (8) EIGHTIES (8) NICETIES (8)
Longest word(s) possible:
ARCHCONFRATERNITIES (19) CIRCUMSTANTIALITIES (19) IRRECONCILABILITIES (19) NONRESPECTABILITIES (19) NONRESPONSIBILITIES (19)
UNCONVENTIONALITIES (19)
$
The example below shows a blank line being input at the first prompt (i.e. no characters were present before 184 the newline). The first valid guess (governments) has been terminated by an EOF – e.g. the user typed Ctrl-D 185 Ctrl-D after typing governments rather than typing a newline. This pending EOF terminated the word, and 186 when an attempt was made to read the next line (guess 2), the EOF was detected. 187
Example 4: Example uqwordiply game session – with early termination.
$ ./uqwordiply
Welcome to UQWordiply!
The starter word is: MENT Enter words containing this word. Enter guess 1:
Guesses must contain the starter word - try again. Enter guess 1: governmentsEnter guess 2:
Total length of words found: 11 Longest word(s) found:
GOVERNMENTS (11)
Longest word(s) possible:
ANTIDISESTABLISHMENTARIANISM (28) $
188
A library has been provided to you with the following function which your program must use (when no starter 189
word is provided on the command line): 190
const char* get_wordiply_starter_word(unsigned int wordLen); 191
The function is described in the get_wordiply_starter_word(3) man page on moss. (Run 192
man get_wordiply_starter_word.) 193
To use the library, you will need to add #include <csse2310a1.h> to your code and use the compiler flag 194
-I/local/courses/csse2310/include when compiling your code so that the compiler can find the include 195
file. You will also need to link with the library containing this function. To do this, use the compiler arguments 196
-L/local/courses/csse2310/lib -lcsse2310a1. 197
Provided Library: libcsse2310a1
198
Your program must follow version 2.3 of the CSSE2310/CSSE7231 C programming style guide available on the 199
course Blackboard site. Your submission must also comply with the Documentation required for the use of AI 200
tools if applicable. 201
Hints 202
1. The string representation of a single digit positive integer has a string length of 1. 203
toupper() and/or tolower(). Note that these functions operate on individual characters, represented as 205
integers (ASCII values). 206
strdup(), exit(), fopen(), fprintf(), and fgets(). You should consult the man pages for these 208
functions. 209
4. The style guide shows how you can break long string constants in C so as not to violate line length 210
requirements in the style guide. 211
can process more complicated combinations of command line arguments. See the getopt(3) man page for 215
details. Note that short forms of arguments are not to be supported, e.g. the arguments “-s word” (for 216
specifying a starter word) should result in a usage error. To allow for the use of a getopt() family function, 217
we will not test your program’s behaviour with the argument -- (which is interpreted by getopt() as a 218
special argument that indicates the end of option arguments). We also won’t test abbreviated arguments, 219
e.g. --star, --st, --le etc. 220
Suggested Approach 221
It is suggested that you write your program using the following steps. Test your program at each stage and 222
commit to your SVN repository frequently. Note that the specification text above is the definitive description 223
of the expected program behaviour. The list below does not cover all required functionality. 224
1. Write a program that outputs the usage error message and exits with exit status 1. This small program 225
it thinks everything is a usage error! 227
2. Detect the presence of the --len command line argument and, if present, check the presence/validity of 228
the argument that follows it. Exit appropriately if not valid. 229
3. Detect the presence of the --start command line argument and, if present, check the presence/validity 230
of the argument that follows it. Exit appropriately if not valid. 231
4. Detect the presence of the --dictionary command line argument and, if present, check the presence of 232
the argument that follows it. Exit appropriately if not valid. 233
5. Check whether the dictionary can be opened for reading or not. Exit appropriately if not. (If it can be 234
opened, leave it open – you’ll need to read from it next.) 235
6. Have your program print out the welcome message 236
7. Read the dictionary line by line, saving the words (or an appropriate subset of words) into dynamically 237
allocated memory. 238
8. Have your program repeatedly prompt for words (guesses). 239
Style
240
10. Implement remaining functionality as required ... 241
Forbidden Functions 242
assignment. 244
• goto 245
• longjmp() and equivalent functions 246
• system() 247
• popen() 248
• execl() or any other members of the exec family of functions 249
• POSIX regex functions 250
• Functions described in the man page as non standard, e.g. strcasestr() 251
Submission 252
Your submission must include all source and any other required files (in particular you must submit a Makefile). 253
Do not submit compiled files (eg .o, compiled programs) or dictionary files. 254
Your program (named uqwordiply) must build on moss.labs.eait.uq.edu.au with: 255
make 256
Your program must be compiled with gcc with at least the following options: 257
-pedantic -Wall -std=gnu99 258
than .c and .h files as part of the build process – such files will be removed before building your program. 260
If any errors result from the make command (i.e. the uqwordiply executable can not be created) then you 261
Your program must not invoke other programs or use non-standard headers/libraries. 264
Your assignment submission must be committed to your subversion repository under 265
https://source.eait.uq.edu.au/svn/csse2310-sem1-sXXXXXXX/trunk/a1 266
where sXXXXXXX is your moss/UQ login ID. Only files at this top level will be marked so do not put source 267
will not be considered in marking – they will not be checked out of your repository. 269
You must ensure that all files needed to compile and use your assignment (including a Makefile) are commit- 270
ted and within the trunk/a1 directory in your repository (and not within a subdirectory) and not just sitting 271
in your working directory. Do not commit compiled files or binaries. You are strongly encouraged to check out 272
a clean copy for testing purposes. 273
To submit your assignment, you must run the command 274
2310createzip a1 275
on moss and then submit the resulting zip file on Blackboard (a GradeScope submission link will be made 276
available in the Assessment area on the CSSE2310/7231 Blackboard site) . The zip file will be named 277
sXXXXXXX_csse2310_a1_timestamp.zip 278
where sXXXXXXX is replaced by your moss/UQ login ID and timestamp is replaced by a timestamp indicating 279
the time that the zip file was created. 280
The 2310createzip tool will check out the latest version of your assignment from the Subversion repository, 281
ensure it builds with the command ‘make’, and if so, will create a zip file that contains those files and your 282
9. Check the guesses for validity.
283
part of this process in order to check out your submission from your repository. You will be asked to confirm 284
references in your code. 285
You must not create the zip file using some other mechanism and you must not modify the zip file prior 286
is submitted via GradeScope on Blackboard, and not the time of your last repository commit nor the time of 288
creation of your submission zip file. 289
for details. 292
Note that Gradescope will run the test suite immediately after you submit. When complete you will be 293
able to see the results of the “public” tests. 294
to attend an interview about your assignment and you are unable to adequately respond to questions – see the 297
Student conduct section above. 298
Provided your code compiles (see above) and does not use any prohibited statements/functions (see above), and 300
your zip file has been generated correctly and has not been modified prior to submission, then you will earn 301
for that feature, even if you claim to have implemented it. For example, if your program can never open 305
a dictionary file then we can not determine if your program can determine word validity correctly. If your 306
to remove code without academic merit). 309
5. Program correctly handles games with only invalid or blank guesses – with EOF 315
6. Program correctly plays game (and outputs final messages) with only valid guesses made 317
Tests for categories 2 and higher will take place with a variety of valid command lines. If your program doesn’t 321
detect a particular set of command line options as valid, or doesn’t handle a particular option (e.g. --len) or 322
are other dependencies between categories. For example, if your program doesn’t correctly print the welcome 324
Style Marking 326
Style marking is based on the number of style guide violations, i.e. the number of violations of version 2.3 of 327
You should pay particular attention to commenting so that others can understand your code. The marker’s 330
decision with respect to commenting violations is final – it is the marker who has to understand your code. To 331
more than your functionality mark – this prevents the submission of well styled programs which don’t meet at 333
least a minimum level of required functionality. 334
You are encouraged to use the style.sh tool installed on moss to style check your code before submission. 335
This does not check all style requirements, but it will determine your automated style mark (see below). Other 336
elements of the style guide are checked by humans. 337
All .c and .h files in your submission will be subject to style marking. This applies whether they are 338
compiled/linked into your executable or not . 339
.c and/or .h files are unable to be compiled by themselves then your automated style mark will be zero (0). 342
(Automated style marking can only be undertaken on code that compiles. The provided style.sh script checks 343
this for you.) 344
If your code does compile then your automated style mark will be determined as follows: Let 345
• W be the total number of distinct compilation warnings recorded when your .c files are individually built 346
(using the correct compiler arguments) 347
• A be the total number of style violations detected by style.sh when it is run over each of your .c and 348
.h files individually . 349
Your automated style mark S will be 350
S = 5 − (W + A) 351
penalised incorrectly then please bring this to the attention of the course coordinator and your mark can be 354
errors not picked up when you run style.sh on moss. This will not be considered a marking error – it is your 356
responsibility to ensure that all of your code follows the style guide, even if styling errors are not detected in 357
some runs of style.sh. You can check the result of Gradescope style marking soon after your Gradescope 358
submission – when its test suite completes running. 359
and “other”. The meanings of words like appropriate and required are determined by the requirements in the 362
style guide. Note that functions longer than 50 lines will be penalised in the automated style marking. Functions 363
that are also longer than 100 lines will be further penalised here. 364
Mark Description
0 The majority (50%+) of comments present are inappropriate OR there are many required comments missing
0.5 The majority of comments present are appropriate AND the majority of required comments are present
1.0 The vast majority (80%+) of comments present are appropriate AND there are at most a few missing comments
1.5 All or almost all comments present are appropriate AND there are at most a few missing comments
2.0 Almost all comments present are appropriate AND there are no missing comments
2.5 All comments present are appropriate AND there are no missing comments
366
Naming (1 mark) 367
Mark Description
0 At least a few names used are inappropriate
0.5 Almost all names used are appropriate
1.0 All names used are appropriate
368
Mark Description
0 One or more functions is longer than 100 lines of code OR there is more than one global/static variable present inappropriately OR there is a global struct variable present inappropriately OR there are more than a few instances of poor modularity (e.g. repeated code)
0.5 All functions are 100 lines or shorter AND there is at most one inappropriate non-struct global/static variable AND there are at most a few instances of poor modularity
1.0 All functions are 100 lines or shorter AND there are no instances of inappropriate global/static variables AND there is no or very limited use of magic numbers AND there is at most one instance or poor modularity
1.5 All functions are 100 lines or shorter AND there are no instances of inappropriate global/static variables AND there is no use of magic numbers AND there are no instances of poor modularity
370
will be graded according to the following principles: 373
• Appropriate use and frequency of commits (e.g. a single monolithic commit of your entire assignment will 374
yield a score of zero for this section) 375
• Appropriate use of log messages to capture the changes represented by each commit. (Meaningful messages 376
explain briefly what has changed in the commit (e.g. in terms of functionality) and/or why the change 377
has been made and will be usually be more detailed for significant changes.) 378
The standards expected are outlined in the following rubric: 379
Mark
(out of 5) Description
0 Minimal commit history – only one or two commits OR all commit messages are meaningless.
1 Some progressive development evident (three or more commits) AND at least one commit message is meaningful.
2 Progressive development is evident (multiple commits) AND at least half the commit messages are meaningful.
3 Multiple commits that show progressive development of ALL functionality (e.g. no large commits with multiple features in them) AND at least half the commit messages are meaningful.
4 Multiple commits that show progressive development of ALL functionality AND meaningful messages for all but one or two of the commits.
5 Multiple commits that show progressive development of ALL functionality AND meaningful messages for ALL commits.
380
381
and developing sound software engineering practices by documenting your changes as you go. In general, tiny 383
changes deserve small comments – larger changes deserve more detailed commentary. 384
Total Mark 385
Let 386
• F be the functionality mark for your assignment (out of 60). 387
• S be the automated style mark for your assignment (out of 5). 388
• H be the human style mark for your assignment (out of 5). 389
• C be the SVN commit history mark (out of 5). 390
• V is the scaling factor (0 to 1) determined after interview(s) (if applicable – see the Student Conduct 391
section above) – or 0 if you fail to attend a scheduled interview without having evidence of exceptional 392
circumstances impacting your ability to attend. 393
Your total mark for the assignment will be: 394
M = (F + min{F,S + H} + min{F,C}) × V 395
out of 75. 396
Pretty code that doesn’t work will not be rewarded! 398
Late Penalties 399
Late penalties will apply as outlined in the course profile. 400
Specification Updates 401
Any clarifications or updates to the assignment specification will be summarised here. Any updated versions 402
specification errors or omissions can be discussed on the discussion forum or emailed to csse2310@uq.edu.au. 404
405
• Clarified other arguments we won’t test (to allow getopt() implementations) 407
• Fixed typo in description of relationships between marking criteria 408
• Fixed formatting error in usage message – no spaces before closing square brackets 409
We understand that you are just getting to know Subversion, and you won’t be penalised for a few “test