There will be five take-home lab assignments, each consisting of 3 to 4 exercises. The main objectives of these assignments are for you to practice, and for us to provide feedback on your programming. As lab assignments are primarily used for formative assessment, we have kept their weightage low -- 5% of your final grade, to encourage you, especially beginners, to work on your own without the fear of losing too many marks. With this, we hope that you would be motivated to do all these programs all by yourself instead of resorting to copying or asking for help from others.
Copying others' programs or relying on others to help you on these assignments will only offer short-term reprieve. When Practical Exam (PE) time comes, your inadequacy will be exposed and the consequence would be dire.
Some advice:
Please note that:
A student who is caught copying program from others, or knowingly allowed his program to be copied, will have his Attempt Mark revoked for that lab assignment and his identity noted. In the case of a repeat offender, he will be referred to the School for disciplinary action.
Lab assignments are to be attempted individually so reasons such as collaboration, intentional or arising from convenience (such as sharing of laptop), will not be accepted.
Should there be any dispute or appeal, please consult your respective lecturer.
The 1 mark Attempt Mark is awarded to you for each lab assignment if you satisfy ALL the following conditions:
* Generally your submission is deemed unsatisfactory if your feedback mark is below 50. Your discussion leader will have the discretion.
For your Feedback Mark, below are the general grading guidelines given to the graders. Each exercise has a maximum of 100 marks. Unless otherwise stated, correctness of a program constitutes 60 marks, while design and style make up the other 40 marks.
CodeCrunch determines program correctness by feeding a set of test data into your program and comparing your output with the correct output. Normally 10 set of testing data will be applied to your program.
If your program cannot be compiled (and hence it cannot be run), you will get zero mark for correctness.
If you hardcode your output, you will also get zero mark for correctness, even though your output may happen to be correct. (Hardcoding the output means, for example, you write in your program "printf("100\n");" and hope that one of the test data's answer is indeed 100. Even if it is so, you won't get the mark.)
In general, our concern on design and style include (but not limited to) the following and may vary slightly from lab to lab:
Style
Design
Should any discrepancy, dispute or queries arise in grading, the students should first approach their respective discussion leader for clarification. The discussion leader should exercise his/her good judgment in granting appeals, bearing in mind the marking consistency among other programs with similar issues. If the appeal cannot be resolved with the discussion leader, the lecturer shall be the final arbiter in deciding an appropriate resolution.
There are generally agreed typographical style for C programming. Here we include a few more specific guidelines on the typographical style for CS1010. The main goal of the recommendations here is to improve readability and thereby the understanding and maintainability of the code. Violations to this guide are allowed if they enhance readability.
For example,
// PREFERRED double x,y,z; // Coordinates of a particle
As opposed to:
// AVOID double x; double y; double z;
Use descriptive names for variables so that their meanings are immediately clear when they appear in the code. For example, "int coins;" is an appropriate variable but not "int c;". Avoid using single character for variable names.
There are some exceptions, however, as shown below:
Despite the recommendation for descriptive names, identifiers can be short yet descriptive by using abbreviations and/or common naming conventions. For example,
// AVOID MAXIMUM_LENGTH, numberOfElements, currentNodePointer, table_number
can be shortened without losing their descriptive form:
// PREFERRED MAX_LEN, nElems, pcurr, table_num
Negated variables often result in hard-to-read double-negatives in an expression like !isNotError.
// AVOID isNotError, isNotFound, isNotValid, cannotOpenFile
// PREFERRED isError, isFound, isValid, canOpenFile
Avoid direct use of magic numbers for those values of special meaning (e.g., define PI as a constant for 3.1415926). Constant literals should be named accordingly and their named identifiers should be used in its place. For example:
// AVOID
for (i=0; i<100; i++) {
...
}
// PREFERRED
#define MAX_LEN = 100;
...
for (i=0; i<MAX_LEN; i++) {
...
}
MAX_ITERATIONS, MAX_LEN, GOLDEN_RATIO, COLOR_DEFAULT, PI
Code should be properly and neatly indented to emphasize the nested logical structure of the program. An indentation of 4 spaces is recommended (8 is too wide and 2 is too cramp).
Every block that follows a for, while, if-else, switch, do-while statement must be indented from its enclosing block.
Comments within a block should follow the indentation level of its enclosing block. For example,
for (i=0; i<3; i++) { // Trailing open-braces is OK
// Comments should be indented too
while (j != i) // Leading open-braces OK as well
{
// More indented comments
printf("Hello\n");
}
}
Major segments of code should have explanatory comments for their purposes. Complex logic also needs to be commented to help readers understand your logic.
A comment such as:
i++; /* add one to i */
serves no purpose, adds clutter to a program and does more harm than good.
As programs get more complex, program design becomes increasingly important. Decomposing a complex program into smaller, more manageable units and the design of the interfaces between the units are fundamental to good programming.
(Students to note: You may skip this section for a start, and return to read this at a later point of time.)
Each function should consist of closely related elements. If a function consists of a mixed-bag of unrelated elements, it often indicates a need to modularize the code into further cohesive program units.
As a general rule, each function should do only one thing. This should be done so that the conceptual unit can be understood easily. Sometimes it will be convenient to do two things in a function because you are working on the same data. Try to resist this temptation. Make two functions if you reasonably can.
Often the naming of the function indicates its cohesiveness. Does the function only do what its name says, or does it do more than that? If you find that a complete name for one of your functions is like openInputAndReadVectorAndComputeSum(..), it is time to break the multi-tasked function into its sub-constituents.
Segments of code which are repeated should be abstracted into a function. This not only results in shorter programs but also makes it easier to maintain and read. The abstracted function then forms a cohesive unit by itself.
Simplicity is a virtue. Wherever possible, your program should be simple, compact, and easy to read. For example, long chains of nested if-else statements can often be replaced with a more compact form by evaluating the logic. If you find that the logic in your code is getting very unwieldy, rethink and rewrite it.
Some labs may expressly disallow the use of certain syntax. Generally, using syntax or statements which are not yet covered in class is strongly discouraged. The lab assignments are designed such that you should not need to do so. If the objective of the assignment is undermined, the penalty for using such forbidden syntax will be heavy.
Although in CS1010 we are not too concerned about order-of-growth efficiencies, any obvious inefficiencies which can easily be avoided must not be present, or they will be penalized.