Programming Style Guide for CS 115

Comments allow us to write in natural language to clarify the intent of the program. You should comment programs internally with clear, coherent statements in concise English, using good grammar, punctuation, and spelling. You should try writing the comments (or at least the design) first, then write the program code from that. Use a spellchecker on the program or at least the comments.

Each variable should have a comment describing its purpose. Provide a short description of the logical role played by each variable. Organize this section as a "variable dictionary". Don't just say that a variable is "a counter"; say what it is counting. Don't just say that a variable is "an integer"; say that it is "the first number input by the user" or "a roll of the die" or "the sum of the ages of the students". For example, you might have:

        MAXPKG = 25  # maximum weight allowed for a package
        Weight = 0   # The package's weight in kilograms
        nPackages = 0  # number of packages loaded on van
        pkgCount = 0  # counter for packages processed

Name your variables carefully. Names are the heart of programming. In the past people believed knowing someone's true name gave them magical power over that person. If you can think up the true name for something, you give yourself and the people coming after power over the code. Don't laugh!

The most important consideration in choosing a name for a data item or function in a program is that the name convey as much information as possible about what the data item is or what the function does. If you find all your names could be Thing and DoIt then you should probably rethink your design. If you have a flag named Error that is TRUE if there ARE NO errors, you are setting yourself up for a bug.

Suffixes are sometimes useful:

For example: RetryMax to mean the maximum number of retries, RetryCnt to mean the current retry count.

Prefixes are sometimes useful:

For example:
if IsHitRetryLimit() ...

Identifiers for variables should be nouns. Usually every function that does not return a value or returns values through its parameter list performs an action, so the name should make clear what it does: CheckForErrors() instead of Error(), DumpDataToFile() instead of DataFile(). Because of the way that value-returning functions are invoked, their names should be nouns or occasionally adjectives. Here are some examples:
Variables address, price, radius, monthNumber
functions that don't return a value or return values through their parameter lists GetData, ClearTable, PrintBarChart
Value-returning functions CubeRoot, Greatest, Color, AreaOf, IsEmpty

Use capitalization properly. Most variable names should be lower case or mixed case, either "power" or "interestRate". Underscores can make a variable name easier to read, too, as in "money_borrowed". Remember that Python is case sensitive; the case of an identifier name makes a difference. Remember that while most reserved words are all lower case, some do have upper case letters.

Formatting Source Code

Formatting refers to the way statements are placed in a program -- indentation, blank lines, etc. Good formatting can make a program far easier to understand.

Python allows you to break a long statement and continue on the next line. The preferred method of doing this is to enclose the expression in parentheses, and break the line within the parentheses:

meanOfMax = ((max(value11, value12, value13) + 
		max (value21, value22, value23) + 
		max (value31, value32, value33)) / 3.0) 

print( "This is a very long message",
     "indeed, isn't it?")
You can also break a line by putting the symbol \ at the end of the first line to tell Python there is another line that is part of this one. If you use the \ character to break a line, note that you cannot put a comment at the end of that line, or any other character for that matter. For example:
meanOfMax = (max(value11, value12, value13) + \
		max (value21, value22, value23) + \
		max (value31, value32, value33)) / 3.0

You cannot split a line in the middle of an identifier or a literal constant. Anywhere you can put a space in a statement, you can go to the next line. You should choose a point that is logical and readable. Try to take advantage of any patterns or repeating expressions.

White space is essential for clarity. This includes spaces around identifiers, operators, at the beginning and end of comments, as well as blank lines, especially to separate blocks and different sections of blocks.

x = y + 3 * z - 5 * y
is easier to read than
x=y+3*z-5*y

Comments at the ends of blocks are useful, especially if the block is rather long. Example:

while ct < 10:
	code
	code
	code
 # end of while controlled by ct

Indentation

The purpose of indenting statements in a program is to provide visual cues to the reader and to tell Python how code is grouped together. Indentation makes the difference between statements that are inside a loop body and outside a loop body.

while count <= 10:
     print(num)
     if num >= 0:
        count += 1
        num = 1
print(count)
print(num)
compared to
while count <= 10:
     print(num)
     if num >= 0:
        count += 1
        num = 1
     print(count)
     print(num)

Some people prefer to indent by 3, 4, 5 or even more spaces. The important thing is to choose a value and be consistent. Using both tabs and spaces for indentation may cause Python to raise a TabError due to inconsistent indentation. Most editors will have a standard indentation amount.

Statements should be indented when they are subordinate, that is, when they are part of another structure or statement. The body of each function should be indented. For another example, the If-Then-Else contains two parts, the then-clause and the else-clause. The statements within both clauses are indented; this makes the if and matching else stand out.

if age > 65:
	Eligible = True
	SSctr  = SSctr + 1
else:
	Eligible = false

Nested if-then-elses can be indented as other if statements, but it tends to push them across the page. A better format is:

if (month == "January"):
	monthIndex = 1
elif (month == "February"):
	monthIndex = 2
elif (month == "March"):
	monthIndex = 3
else:
	monthIndex = 0

Loop bodies should be indented. Examples:

while (count <= 10):
	value = int(input("value:"))
	sum = sum + value
	count += 1

for count in range(1, numS)
	print("*")

for count in range(10, 0, -1)
	x = int(input())
	print (x)

Bad example: This shows how many people who are beginning programmers indent:

num = int(input("Enter num"))
	if (num > 0):
	print ("positive")
	else: print ("non-positive")
print("All Done")

This would lead you to believe that the if statement was dependent on the input statement in some way. That is definitely not the case. They are both statements in a sequence structure, and should be indented at the same level.

Blank lines placed before and after each control structure makes them stand out. Too many levels of nesting can make a program difficult to understand.

Documenting Source Code

There is such a thing as too many comments. They can actually obscure the code itself. And if they don't agree with what the actual code is doing, they can be a source of errors! A comment is NOT necessary on every single line of source. Each loop should have a comment, as well as each if statement. An assignment statement needs a comment if it is important or if the right hand side is particularly complicated. Other statements need comments if they are not self-documenting. print("hello") does not need a comment like # output hello.

Pre-conditions and Post-conditions
Every function should have documentation, at its prototype. You should be able to state the purpose of the function in a sentence or two. This sentence should be coherent and grammatically correct. It should involve all of the function's parameters. "The function displays a square on the screen that is size rows high and width characters wide."

Each parameter should be documented. Any parameter that is passed by reference should be especially noted. Why are you changing it? Is it returning a value? If it is being passed as reference for efficiency's sake, say that.

Local variables need documentation just like other variables. The return type of the function, if not void, should be documented. Don't just say what type is being returned; say what the returned value means. "The function returns the average of the 4 parameters" "The function returns the largest number input" "The function returns true if the data was in the correct format, false otherwise".