CSC108H Style Rules
Here are some guidelines for writing code with good style.
Formatting Style
-
Use Python style conventions for your function and variable names. This means that you should
use pothole case: lowercase letters with words separated by underscores (
_
) to
improve readability. For example, the variable name dog_name
is good but
dogName
is not.
-
Choose meaningful names for your functions and variables. For example,
num_bright_spots
is more helpful and readable than nbs
.
-
Do not use the tab character to indent code. Instead, use four spaces for each indentation
level.
-
Put a blank space before and after every operator. For example, the first line below is good but
the second line is not:
# Good
b = 3 > x and 4 - 5 < 32
# Bad
b= 3>x and 4-5<32
-
For each function, write a docstring according to our design recipe. (See below for guidelines
on the content of your docstrings.)
Put the docstring's closing quotation marks on their own line.
-
Each line must be less than 80 characters long including spaces. (In Wing IDE, the
red vertical line indicates 80 characters.) You should break up long lines as follows:
-
Within a docstring, put a blank line between the type contract and description, and between the
description and the examples.
-
Put a blank line between the docstring and the function body.
Programming Style
-
Do not compare a Boolean expression to True or to False. For example, the first is good, the
second is not:
# Good
if a and b:
return 100
# Bad
if (a and b) == True:
return 100
- Replace if statements of this form:
# Bad
if x > 100:
return True
else:
return False
with a single-line statement like this:
# Good
return x > 100
-
Replace if statements of this form:
# Bad
if x > 100:
n = n
else:
n = n + 1
with a single if statement like this:
# Good
if x <= 100:
n = n + 1
-
Avoid duplicate code by calling on helper functions.
Commenting
For complicated bits of code inside functions, you may add an internal comment to remind yourself (or
another hypothetical reader) understand how the code works. We frequently see CSC108 students
"over-commenting", by adding comments for every line of code. Please don't do this: assume the reader of
the code is a proficient Python programmer. If you have at most one comment per logical chunk of code
(whether that is a small function or a coherent piece of a larger function), you're on-track.
Here are some suggestions about where comments would be useful.
-
Use comments to explain tricky spots in the code.
-
Use comments to explain the meaning of a variable, if
it is subtle.
A good variable name can go a long way.
For example, "num_students" tells you more than just "num".
But sometimes the meaning is subtle enough that
the variable name can't fully convey it (without being ridiculously
long!).
For instance, you might have a variable called "next" and a
comment that says "The index within s1 from which to search
for the next occurrence of s2."
-
Use comments to explain what you know is true at key
moments. For example, after a while loop has ended, you
know that the loop condition has failed.
There are often crucial implications from this that
require some reasoning to see.
Write those down!
-
Use comments to summarize chunks of code.
For example, if 5 lines of code as a whole accomplish some
task, it can be helpful to have a short comment summarizing
that task. Of course, if you use helper functions well,
this won't be necessary terribly often.
-
Do not write comments that simply rephrase a line of code in English.
For example "Increase n by one" does not add anything that
"n = n + 1" doesn't already say.
-
Do not write a comment for every line of code.
That's too much. Instead, use the guidelines above to
decide when a comment is appropriate.
Docstring
Follow the design recipe for writing functions. This means that in addition to the header and body, you
must include a docstring with an example, type contract, and description. Follow these rules when
writing the description portion of the docstring:
-
Describe precisely what the function does.
-
Do not reveal how the function does it.
-
Make the purpose of every parameter clear.
-
Use the name of every parameter.
-
For functions that return values, be clear on what the return value represents.
-
Explain any conditions that the function assumes are true. These conditions should not
refer to type requirements, because those are already covered by the type contract. However,
sometimes there are conditions not covered by types, and you should include those. For example,
if a function requires parameters
x
and y
to be even, include x
and y must both be even
.
-
Be concise and grammatically correct.
-
Write the description as a command (e.g.,
Return the first ...
) rather than a
statement (e.g., Returns the first ...
)