Note: Style is hard. If you are struggling with it, I empathize with you; it's something I struggled with a lot and struggle with again every time I have to work on a project in a new language. I wish I could give you a list saying "this is right and this is wrong," but style is often subjective (although it certainly has objective components) and what may work well in one situation may not work well in another. It really takes a lot of practice to get a good feel for what is good style; sometimes you have to encounter abysmal code in order to understand why something that appears good at first is actually not a good idea. While I obviously cannot pregrade your assignment, if you have specific questions, I am always more than happy to help.
Also note: Don't freak out about style for assignment 1. We won't necessarily be grading easier than normal, but we also understand that you may not have heard much about what makes "good" style yet, and ultimately the assignment 1 style grade will be a very small portion of your final grade. We will do our best to give detailed style feedback on your first assignment, which will help a lot throughout the rest of the quarter.
buildColumn
probably should not also move to the next column (conceptually, moving between columns isn't part of building columns).
Getting a sense of what is "unexpected" takes some practice; I have probably developed some of that myself by reading code from existing projects and going "uhh, wtf?" several times. If you are not sure, feel free to email me.Do I have a comment for every function?
Make sure to have a comment above every function. If the comment doesn't give any more information than the function name, your comment may not be descriptive enough, or you may be over-decomposing. (There are exceptions; for example, the function comment for turnAround
wouldn't include much more than "turns around.")
Do I include inline comments where necessary? You can provide comments inside of a function to make code more skimmable or to document some especially obscure or unexpected functionality. It isn't required, but it can help make your code more readable and can help your section leader understand what you are trying to do. However, be careful of using too many comments. If an inline comment doesn't add anything that's not already obvious in the code, you don't need the comment. Be careful of writing too many inline comments because at some point, they become a pain to manage.
1/**
2 * Creates a vertical column of three beepers.
3 * Preconditions: Karel is standing where a column should be formed, facing east.
4 * Postconditions: Karel is at the base of the column, again facing east.
5 */
6function buildColumn() {
7 turnLeft();
8
9 // Build the column
10 repeat(2) {
11 placeBeeper();
12 move();
13 }
14 placeBeeper();
15
16 // Move to the base of the column
17 turnAround();
18 repeat(2) {
19 move();
20 }
21 turnLeft();
22}
Note:
Developing a sense of balance when commenting is hard. Not commenting enough is obviously bad, but too many comments also adds problems; at best, over-commenting makes your code too long and too hard to skim, and at worst, over-commenting creates severe maintainence problems. Comments need to be updated if code changes, and I have had my fair share of times when I've read a comment that says "this code does this" and the code clearly did not do that thing. I then spent the next two hours trying to figure out whether the code actually did do that thing but in an unexpected way, or whether the comment was just out of date.
In general, err on the side of being concise, but make sure you provide enough detail for someone to understand your code.
Do I use proper naming convention?
Use lower camel case (e.g. someName
) for functions and variables and upper snake case (e.g. SOME_NAME
) for constant names.
Do my functions have "verby" names in imperative form? By defining a function, you are defining a new "command" that the computer can execute, so its name should sound like a command. "wall" is a bad command/function name — wall what? — but "buildWall" is a good command/function name.
Are my names descriptive enough?
This is only relevant for assignment 2, but a variable name should imply what that variable contains, given a reasonable amount of information about the context. Avoid abbreviating names if the abbreviation isn't clear, and definitely avoid one-letter names except for loop counter variables and coordinate names like x
and y
.
A function name should reasonably capture what the function does. (This is easier if you have decomposed well.) If you were to see the name without seeing the function's code, you should have a reasonable idea of what the function does.
Are my names overly verbose? If a name is 5 words long, it's pushing it; if it's 8 words long, it's definitely too verbose.
Aside: How do I find balance between the two extremes? It takes practice. Note that your name doesn't have to describe everything the function does, but given the name, nothing the function does is surprising. Think of the function name like a mini thesis statement for your function; it doesn't have to say everything the function does, but it does summarize it, and everything in the function should be "on-topic" given that name.
Have I indented properly? Don't lose easy points! I haven't yet figured out if JSKarel includes a way to automatically indent code, but you can paste your code at http://jsbeautifier.org/ to have it automatically format your code.
Is my spacing and bracketing consistent? Don't do things like this:
1if (someCondition) {
2 doSomething();
3} else {
4 doSomethingElse();
5}
6
7// and then later...
8
9if(someCondition){ // First example had space before (, space after )
10 doSomething();
11} // First example had `else` on same line
12else{ // First example had space before {
13 doSomethingElse();
14}
Do I have multiple statements on a single line?
A statement is something ending with a semicolon. move();
is a statement. You should never have multiple statements on the same line.
Do I have proper spacing throughout the rest of the code?
You should have spaces on both sides of binary operators (e.g. x = 4
, not x=4
; x == y + 4
, not x==y+4
), no spaces before unary operators (e.g. i++
, not i ++
), no spaces before opening parenthesis for function call (e.g. move()
, not move ()
), etc. I don't actually take off for this unless it's egregious, but it still very important and I will be much happier if your code is pretty :)
Are there magic numbers in my code? Wherever reasonable, use constants instead of magic numbers. This is important for two reasons: so that values can be changed later, and so that values are labeled (it once took me hours to figure out why some numbers in some encryption code were set to the values they were).
Sometimes it's not reasonable to use constants, and that's okay with me. If neither of those two reasons apply, don't use them. If you're checking for three-of-a-kind, then you are fundamentally going to use the number 3 (it isn't going to change) and it's obvious why (as long as it's obvious that part of the code is checking for three-of-a-kind). If you were to use a constant in that case, I'm not sure what you'd name it other than THREE
, which is just silly, so it's fine to just use 3
instead.