These are the general Java style qualities that we expect your programs to have in order to receive full credit. Certainly it is possible to write good code that violates these guidelines, and you may feel free to contact us if you are unclear about or disagree with some of them. But we do expect you to follow these rules (unless there is an error in this document). In most professional work environments you are expected to follow that company's style standards. Learning to carefully obey a style guide, and writing code with a group of other developers where the style is consistent among them, are valuable job skills.

Oracle/Sun's Official Java Coding Conventions are a more comprehensive guide to proper Java programming. The practices outlined on their web site are encouraged for use in CS 106A.

Work in progress.

Indenting

Increase your indentation by one tab on each brace {, and decrease it once on each closing brace }.

Control Statements and Braces

Always use {} on control statements. With Java's control statements such as if and for, the {} braces are technically optional if the body of the control statement contains only a single line. Regardless of this, always use the {} braces. Always :) The reason is that if you come back later to add additional statements to the bodies, you may forget to add braces, and your code will not work as you expect.

// bad
if (beepersPresent())
    pickBeeper();
// good
if (beepersPresent()) {
    pickBeeper();
}
Line Breaks

Place a line break after every { .

// bad
if (beepersPresent()) { pickBeeper(); }
// good
if (beepersPresent()) {
    pickBeeper();
}
One Statement Per Line

Do not place more than one statement on the same line.

// bad
move();  move();  pickBeeper();
// good
move();
move();
pickBeeper();	
Avoid Long Lines

Avoid lines longer than 100 characters. When you have a long line, break it into two shorter lines.

Spacing

Place a blank line between methods and between groups of statements.

private void foo() {
	...
}
								// this blank line here
private void bar() {
	...
}		
Naming

Give methods descriptive names, such as walkToEdge or grabAllBeepers. Avoid one-letter names or non-descriptive names, like x or go or method1.

Methods Should Be Private

Unless explicitly specified, all methods you write should be private, not public.

Capitalization

Name methods with camel-casing likeThis.

run As a Concise Summary

As much as possible, avoid having much of your program's functionality directly in run. Instead, have run call other methods that perform the functionality. For example, run should not directly call move. In this way, run is easy to read and forms a concise summary of the overall behavior of the program.

Minimize Redundant Code

If you repeat the same code block two or more times, find a way to remove the redundant code so that it appears only once. For example, you can place it into a method that is called from both places.

Long Methods

Each method should perform a single, clear, coherent task. No one method should do too large a share of the overall work. If you have a single method that is very long, break it apart into smaller sub-methods. If you try to describe the method's purpose and find yourself using the word "and" a lot, that probably means the method does too many things and should be split into sub-methods.

Short Methods

It can be useful to have a short method if it wraps another method with some additional control flow or if it contributes to a easier to understand name.

// bad
private void makeLeftTurn() {
	turnLeft();
}
// good
private void safePickup() {
	if (beepersPresent()) {
		pickBeeper();
	}
}
Recursion

Recursion (which you'll learn about in CS 106B/X) is when methods call themselves. Mutual recursion is where you have two methods that each call the other to form a cycle of calls. In CS 106A assignments, we discourage recursion or mutual recursion, as it is sometimes tricky to understand and debug, even though it can allow for elegant solutions. In many cases, recursion can be replaced with a for or while loop instead.

// discouraged (recursion)
public void methodOne() {
	if (frontIsClear()) {
		move();
		methodOne();
	}
}
// encouraged
private void moveToWall() {
	while (frontIsClear()) {
		move();
	}
}
// discouraged (mutual recursion)
private void methodOne() {
	if (frontIsClear()) {
		move();
		methodTwo();
	}
}

private void methodTwo() {
	if (frontIsClear()) {
		move();
		methodOne();
	}
}
Avoid Empty if or else.

When using if/else statements, you shouldn't have an if or else branch that is blank. Rephrase your condition to avoid this.

// bad
if (frontIsBlocked()) {
    // do nothing
} else {
    move();
}
// good
if (frontIsClear()) {
    move();
}
for vs. while

Use a for loop when the number of repetitions is known; use a while loop when the number of repetitions is unknown.

// for: picks up 5 beepers
for (int i = 0; i < 5; i++) {
    pickBeeper();
}
// while: picks up all beepers present
while (beepersPresent()) {
	pickBeeper();
}
if/else Factoring

Move common code out of if/else statements to reduce repetition.

// bad
if (beepersPresent()) {
    move();
    pickBeeper();
    move();
    turnLeft();
    turnLeft();
    move();
} else {
    move();
    move();
    turnLeft();
    turnLeft();
    move();
}
// good
move();
if (beepersPresent()) {
    pickBeeper();
}
move();
turnLeft();
turnLeft();
move();
Infinite Loops

Except for infinite animation, avoid writing loops that never stop, such as the example below. An infinite loop will cause your program to never stop executing. Replace an infinite loop with a loop that does terminate.

// bad if front is blocked
// but left is clear!
while (leftIsClear()) { if (frontIsClear()) { move(); } }
// good
while (frontIsClear()) {
    move();
}
File Comments

Place a descriptive comment heading on the top of every .java file in your project with your name, section leader, a description of that file's purpose, and a citation of all sources you used to help write your program. Assume that the reader of your comments is an intelligent programmer but not someone who has seen this program or assignment before. It should describe behavior, but not go into great detail about how each piece is implemented.

Method Comments

Place a comment heading on each method of your file. The heading should describe the method's behavior. If your method makes any assumptions (preconditions), mention this in your comments. If it leaves the program in a certain state when it is done (postcondition), mention this as well. Describe the method's behavior, but don't include great detail about how it is implemented. Don't mention language-specific details like it uses an if/else statement, etc. Here is an example of a good method header comment:

/*
 * Jumps Karel over one hurdle of arbitrary height by walking north over it,
 * and then back down to his original row.
 * Pre:  Karel is next to a jumpable hurdle, facing east.
 * Post: Karel will be over the hurdle, one column to the right, facing east.
 */
private void jumpHurdle() {
	...
}
Inline Comments

Inside various methods, if you have sections of code that are lengthy, complex or non-trivial, place small inline comments near these code blocks describing what they are doing.

Trivial Comments

Do not include obvious or redundant comments about the meaning of statements.

// bad
turnLeft(); 		// turns Karel counter-clockwise
move();				// tells Karel to move forward
Wording

Your comment headers should be written in complete sentences, and should be written in your own words, not copied from other sources (such as copied verbatim from the homework spec document).

TODOs

You should remove any // TODO: comments from your programs before turning them in.

Commented-Out Code

It is considered bad style to turn in a program with chunks of code "commented out". It's fine to comment out code as you are working on a program, but if the program is done and such code is not needed, just remove it.

On Assignment 1, you must limit yourself to the Java features shown in the Karel coursereader. There are too many features to list them all, but in general you should match the Java features used in the sample programs in class and in the Karel coursereader and not use any Java features outside of those. In particular, you should not use the following:

Variables

You are not allowed to use any variables, such as:

// bad
int steps = 42;
while (steps > 0) {
	move();
	turnLeft();
	steps = steps - 1;
}
Instance Variables

These are the 'private' variables that are declared outside of methods. These are just another form of variables and should not be used on Assignment 1.

// bad
public class MyKarel extends Karel {
	private int count;

	public void run() {
		count = 5;
		...
	}
}
break, return and continue

You should not use any of these keywords on Assignment 1, as they are not included in the Karel coursereader.

Parameters

Java methods are able to accept parameters that affect their behavior. This is not included in the Karel coursereader and is not permitted on Assignment 1.

// bad
private void walk(int numSteps) {
	for (int i = 0; i < numSteps; i++) {
		move();
	}
}
Same as for the previous assignment.
Everything from the previous assignment, plus:

Returning booleans

If you have an if/else statement that returns a boolean value based on a test, just directly return the test's result instead.

// bad
if (score1 == score2) {
    return true;
} else {
    return false;
}
// good
return score1 == score2;
Redundancy + Parameters

If you repeat the same code two or more times that is nearly but not entirely the same, try making a helper function that accepts a parameter to represent the differing part.

// bad
foo();
x = 10;
y++;
...

foo();
x = 15;
y++;
// good
helper(10);
helper(15);
...

private void helper(int newX) {
    foo();
    x = newX;
    y++;
}
Everything from the previous assignment, plus:

break and continue
In general, you should avoid using the break or continue statements in loops unless absolutely necessary. A break can often be avoided by rewriting the loop test or reordering the statements in/near the loop.
if/else patterns

When using if/else statements, properly choose between various if and else patterns depending on whether the conditions are related to each other. Avoid redundant or unnecessary if tests.

// bad
if (points >= 90) {
    println("You got Gold!");
}
if (points >= 70 && points < 90) {
    println("You got Silver!");
}
if (points >= 50 && points < 70) {
    println("You got Bronze!");
}
...
// good
if (points >= 90) {
    println("You got Gold!");
} else if (points >= 70) {
    println("You got Silver!");
} else if (points >= 50) {
    println("You got Bronze!");
}
...
Testing booleans

Don't test whether a boolean value is == or != to true or false. It's not necessary! Remember that all booleans (expressions and variables) evaluate to true or false on their own.

// bad
if (x == true) {
    ...
} else if (x != true) {
    ...
}
// good
if (x) {
    ...
} else {
    ...
}
Same as for the previous assignment.
Types

Choose appropriate data types for your variables. If a given variable can store only integers, give it type int rather than double.

Names

Name variables with camel-casing likeThis.

Scope

Declare variables in the narrowest possible scope. For example, if a variable is used only inside a specific if statement, declare it inside that if statement rather than at the top of the method or at the top of the file.

Declaration/Initialization

Never declare or initialize more than one variable in a single statement.

// bad
int a = 7, b = -43, c = 19;
// good
int a = 7;
int b = -43;
int c = 19;
Constants

If a particular constant value is used frequently in your code, declare it as a constant, and always refer to the constant in the rest of your code rather than referring to the corresponding value. Name constants in uppercase with underscores between words LIKE_THIS.

private static final int DAYS_IN_WEEK = 7;
Save method call results in a variable

If you are calling a method and using its result multiple times, save that result in a variable rather than having to call the method multiple times.

// bad
if (getElementAt(x, y) != null) {
	remove(getElementAt(x, y));
}
// good
GObject obj = getElementAt(x, y);
if (obj != null) {
	remove(obj);
}
You may now use Java features. However, you may not use the following:

System.exit()

Java contains a System.exit method that immediately exits your entire program. You should never call this method in our assignments for any reason. Your program should always exit naturally by reaching the end of your run function and returning.

Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Everything from the previous assignment, plus:

Avoid Unnecessary Instance Variables

Use instance variables only when they are required to implement certain functionality, or if it makes sense for that variable to persist outside of any given method. Only use them to store important data that is relevant to the whole program.

Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Empty Catch

Don't ever catch an exception with an empty catch block.

// bad
try {
    foo();
    bar();
} catch (NullPointerException e) {}
Don't Catch Programmer Errors

Don't use try/catch to cover up an error that your program is generating. Only use it for unavoidable program errors such as file errors. If your program is generating an error, debug and sidestep the error to prevent it from happening instead.

// bad
try {
    myFunctionThatCrashesForSomeReason();
} catch (IndexOutOfBoundsException e) {
    //no crash now...
}
Don't catch(Exception e)

Don't ever catch (Exception e) unless told explicitly to do so, because this will catch a huge number of errors and will suppress important system error messages. You should instead catch a more specific subcategory of exceptions such as IOException or FileNotFoundException.

// bad
try {
    foo();
    bar();
} catch (Exception e) {}
Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Same as for the previous assignment.
Private Instance Variables

Properly encapsulate your objects by making any instance variables in your class private.

public class Player {
	private int numberOfLives;
	...
}
Avoid Unnecessary Instance Variables

Use instance variables only when they are required to implement certain functionality, or if it makes sense for that variable to persist outside of any given method. Don't use them to store temporary values used in only a single call to one method, for instance; use them to store important data of your objects.

Avoid Empty Zero-Argument Constructors

If you don't need to do anything to initialize your object, just omit the constructor.

public class Player {
	...
	public Player() {}
}			
Helper or Internal Methods

If you add a method to a class that is not part of the homework spec, or that is an internal helper method, make it private so that other external code cannot call it.

public class Player {
	...
	private double computeScoreHelper() {
		...
	}
}
Instance vs. Static

A static variable in a class is a single occurrence shared by that class and all of its objects. An instance variable is one that each object has its own copy of. When designing your class, any data that should be unique to each object should be an instance variable. This still holds even if the assignment only happens to construct one instance of your class.

public class Player {
	private static int numberOfLives;  // all players share one life count (bad)
	private int numberOfLives;  // each player has their own life count (good)

	public Player() {
		numberOfLives = 10;
	}
}
Same as for the previous assignment.