10.1. Comments

Like most programming languages, Python supports single-line comments and multiline comments. Any text that appears between the number sign # and the end of the line is a single-line comment. Although Python doesn’t have a dedicated syntax for multiline comments, a triple-quotes multiline string can serve as one. After all, a string value by itself doesn’t cause the Python interpreter to do anything. Look at this example:

>>> # This is a single-line comment.
>>> """This is a
>>> multiline string that
>>> also works as a multiline comment. """
'This is anmultiline string thatnalso works as a multiline comment. '

If your comment spans multiple lines, it’s better to use a single multi- line comment than several consecutive single-line comments, which are harder to read, as you can see here:

>>> """This is a good way
>>> to write a comment
>>> that spans multiple lines. """
>>> # This is not a good way
>>> # to write a comment
>>> # that spans multiple lines.
'This is a good waynto write a commentnthat spans multiple lines. '

Comments and documentation are often afterthoughts in the program- ming process or are even considered by some to do more harm than good. But as “Myth: Comments Are Unnecessary” on page 83 explained, com- ments are not optional if you want to write professional, readable code. In this section, we’ll write useful comments that inform the reader without detracting from the program’s readability. ## Comment Style Let’s look at some comments that follow good style practices:

# Here is a comment about this code: someCode() # Here is a lengthier block comment that spans multiple lines using # several single-line comments in a row. # # These are known as block comments. if someCondition: # Here is a comment about some other code: someOtherCode() # Here is an inline comment.

Comments should generally exist on their own line rather than at the end of a line of code. Most of the time, they should be complete sentences with appropriate capitalization and punctuation rather than phrases or single words 1. The exception is that comments should obey the same line-length limits that the source code does. Comments that span multiple lines 2 can use multiple single-line comments in a row, known as block com- ments. We separate paragraphs in block comments using a blank, single-line comment 3. Comments should have the same level of indentation as the code they’re commenting 4. Comments that follow a line of code are called inline comments 5 and at least two spaces should separate the code from the comment.

Single-line comments should have one space after the # sign:

>>> #Don't write comments immediately after the # sign.

Comments can include links to URLs with related information, but links should never replace comments because linked content could disap- pear from the internet at any time:

>>> # Here is a detailed explanation about some aspect of the code
>>> # that is supplemented by a URL. More info at https://example.com

The aforementioned conventions are matters of style rather than con- tent, but they contribute to the comments’ readability. The more readable your comments are, the more likely programmers will pay attention to them, and comments are only useful if programmers read them. ## Inline Comments Inline comments come at the end of a line of code, as in the following case: while True:

>>> # Keep asking player until they enter a valid move.

Inline comments are brief so they fit within the line-length limits set by the program’s style guide. This means they can easily end up being too short to provide enough information. If you do decide to use inline com- ments, make sure the comment describes only the line of code it imme- diately follows. If your inline comment requires more space or describes additional lines of code, put it on its own line.

One common and appropriate use of inline comments is to explain the purpose of a variable or give some other kind of context for it. These inline comments are written on the assignment statement that creates the variable:

>>> TOTAL_DISKS = 5
>>> # More disks means a more difficult puzzle.

Another common use of inline comments is to add context about the values of variables when you create them:

>>> month = 2 # Months range from 0 (Jan) to 11 (Dec).
>>> catWeight = 4.9 # Weight is in kilograms.
>>> website = 'inventwithpython.com' # Don't include "https://" at front.

Inline comments should not specify the variable’s data type, because this is obvious from the assignment statement, unless it’s done in the com- ment form of a type hint, as described in “Backporting Type Hints with Comments” later in this chapter. ## Explanatory Comments In general, comments should explain why code is written the way it is rather than what the code does or how it does what it does. Even with the proper code style and useful naming conventions covered in Chapters 3 and 4, the actual code can’t explain the original programmer’s intentions. If you wrote the code, you might even forget details about it after a few weeks. Present You should write informative code comments to prevent Future You from cursing Past You. For example, here’s an unhelpful comment that explains what the code is doing. Rather than hinting at the motivation for this code, it states the obvious:

>>> currentWeekWages=1
>>> currentWeekWages *= 1.5
>>> # Multiply the current week's wages by 1.5

This comment is worse than useless. It’s obvious from the code that the currentWeekWages variable is being multiplied by 1.5 , so omitting the com- ment entirely would simplify your code. The following would be a much bet- ter comment:

>>> currentWeekWages *= 1.5
>>>
>>> # Account for time-and-a-half wage rate.This comment explains the intention behind this line of code rather

than repeating how the code works. It provides context that even well-­ written code cannot. ## Summary Comments Explaining the programmer’s intent isn’t the only way comments can be use- ful. Brief comments that summarize several lines of code allow the reader to skim the source code and get a general idea of what it does. Programmers often use a blank space to separate “paragraphs” of code from each other, and the summarizing comments usually occupy one line at the start of these paragraphs. Unlike one-line comments that explain single lines of code, the summarizing comments describe what the code does at a higher level of abstraction.

For example, you can tell from reading these four lines of code that they set the playerTurn variable to a value representing the opposite player. But the short, single-line comment spares the reader from having to read and reason about the code to understand the purpose of doing this:

# Switch turns to other player: if playerTurn == PLAYER_X:

playerTurn = PLAYER_O

elif playerTurn == PLAYER_O:

playerTurn = PLAYER_X

A scattering of these summary comments throughout your program makes it much easier to skim. The programmer can then take a closer look at any particular points of interest. Summary comments can also prevent programmers from developing a misleading idea about what the code does. A brief, summarizing comment can confirm that the developer properly understood how the code works. ## “Lessons Learned” Comments When I worked at a software company, I was once asked to adapt a graph library so it could handle the real-time updates of millions of data points in a chart. The library we were using could either update graphs in real time or support graphs with millions of data points, but not both. I thought I could finish the task in a few days. By the third week, I was still convinced that I could finish in a few days. Each day, the solution seemed to be just around the corner, and during the fifth week I had a working prototype.

During this entire process, I learned a lot of details about how the graph- ing library worked and what its capabilities and limitations were. I then spent a few hours writing up these details into a page-long comment that I placed in the source code. I knew that anyone else who needed to make changes to my code later would encounter all the same, seemingly simple issues I had, and that the documentation I was writing would save them literally weeks of effort.

These lessons-learned comments, as I call them, might span several paragraphs, making them seem out of place in a source code file. But the information they contain is gold for anyone who needs to maintain this code. Don’t be afraid to write lengthy, detailed comments in your source code file to explain how something works. To other program- mers, many of these details will be unknown, misunderstood, or easily overlooked. Software developers who don’t need them can easily skip past them, but developers who do need them will be grateful for them. Remember that, as with other comments, a lessons-learned comment is not the same as module or function documentation (which docstrings handle). It also isn’t a tutorial or how-to guide aimed at users of the soft- ware. Instead, lessons-learned comments are for developers reading the source code.

Because my lessons-learned comment concerned an open source graph library and could be useful to others, I took a moment to post it as an answer to the public question-and-answer site https://stackoverflow.org, where others in a similar situation could find it. ## Legal Comments Some software companies or open source projects have a policy of includ- ing copyright, software license, and authorship information in comments at the top of each source code file for legal reasons. These annotations should consist of a few lines at most and look something like this:

>>> """Cat Herder 3.0 Copyright (C) 2021 Al Sweigart. All rights reserved.
>>> See license.txt for the full text."""
'Cat Herder 3.0 Copyright (C) 2021 Al Sweigart. All rights reserved.nSee license.txt for the full text.'

If possible, refer to an external document or website that contains the full text of the license rather than including the entire lengthy license at the top of every source code file. It’s tiring to have to scroll past several screen lengths of text whenever you open a source code file, and including the full license doesn’t provide additional legal protection. ## Professional Comments At my first software job, a senior co-worker I greatly respected took me aside and explained that because we sometimes released our products’ source code to clients, it was important that the comments maintain a professional tone. Apparently, I had written “WTF” in one of the comments for an espe- cially frustrating part of the code. I felt embarrassed, immediately apolo- gized, and edited the comment. Since that moment, I’ve kept my code, even for personal projects, at a certain level of professionalism.

You might be tempted to add levity or vent your frustrations in your program’s comments, but make it a habit to avoid doing so. You don’t know who will read your code in the future, and it’s easy to misinterpret the tone of a text. As explained in “Avoid Jokes, Puns, and Cultural References” on page 64, the best policy is to write your comments in a polite, direct, and humorless tone. ## Codetags and TODO Comments Programmers sometimes leave short comments to remind themselves about work that remains to be done. This usually takes the form of a codetag: a comment with an all-uppercase label, such as TODO , followed by a short description. Ideally, you would use project management tools to track these sorts of issues rather than burying them deep in the source code. But for smaller, personal projects that aren’t using such tools, the occasional TODO comment can serve as a helpful reminder. Here’s an example:

_chargeIonFluxStream() # TODO: Investigate why this fails every Tuesday.

You can use a few different codetags for these reminders:

TODO Introduces a general reminder about work that needs to be done

FIXME Introduces a reminder that this part of the code doesn’t entirely work

HACK Introduces a reminder that this part of the code works, perhaps barely, but that the code should be improved

XXX Introduces a general warning, often of high severity

You should follow these always-uppercase labels with more specific descriptions of the task or problem at hand. Later, you can search the source code for the labels to find the code that needs fixing. The downside is that you can easily forget about these reminders unless you happen to be reading the section of your code that they’re in. Codetags shouldn’t replace a formal issue tracker or bug reporter tool. If you do use a codetag in your code, I recommend keeping it simple: use only TODO and forgo the others. Magic Comments and Source File Encoding You might have seen .py source files with something like the following lines at the top:

>>> #!/usr/bin/env python3
>>> # -*- coding: utf-8 -*-

These magic comments, which always appear at the top of the file, pro- vide interpreter or encoding information. The shebang line 1 (introduced in Chapter 2) tells your operating system which interpreter to use to run the instructions in the file.

The second magic comment is an encoding definition line 2. In this case, the line defines UTF-8 as the Unicode encoding scheme to use for the source file. You almost never need to include this line, because most editors and IDEs already save source code files in the UTF-8 encoding, and Python versions starting with Python 3.0 treat UTF-8 as the defined encoding by default. Files encoded in UTF-8 can contain any character, so your .py source file will be just fine whether it includes English, Chinese, or Arabic letters. For an introduction to Unicode and string encodings, I highly recommend Ned Batchelder’s blog post, “Pragmatic Unicode” at https://nedbatchelder.com/ text/unipain.html.