A colophon is a section of a book that describes how the book was made. I’ve often appreciated it when people include a colophon on a website, because it helps me understand how the site was put together, and why certain design decisions were made.

Substack maintains fairly consistent styling across its platform. That said, there are some conventions I use on Mostly Python to try to write more clearly about code, that might be helpful for some people to know.

Note: I have a separate section called Using Substack. If you’re a Substack writer or are thinking about using the platform, you might find some useful suggestions in that section.

Code blocks

Code blocks are at the heart of any newsletter that discusses code. Unfortunately, Substack’s code blocks are quite simple because they need to be presentable in a wide range of email clients. However, there are some conventions that make them more useable:


For posts involving one file, I don’t usually mention a filename. If you want to run the code, you can copy and paste the code and use just about any filename you want. If you really want to see the filename I used, you can follow the link mentioned in the Resources section at the end of the post.

For posts involving multiple files, I usually mention the filename in the explanatory text.

Changes to a program

Most nontrivial programs are shown or explained over a series of code blocks. Most code blocks after the first one include a bit of context from the last code block. I also try to use bold text to indicate which lines are new:

message = "Hello Substack world!"

message = "I hope you like it here. :)"

A couple bold lines of code looks okay, but bold text doesn’t work well for longer listings. I try to use bold lines to indicate where to look in a listing to identify the new code. For example if a function appears for the first time in a listing, you might see just the function definition in bold. I also use bold lines to highlight code that’s discussed in the text that follows.

Omitted code is usually indicated by an ellipsis, but they get distracting if they’re used too often. When context should make them unnecessary, I try to leave them out.

Full listings of code files

Every post that includes a fully developed program has a corresponding folder in the mostly_python GitHub repo. At the bottom of every such post, in the Resources section, there’s a link to the folder containing full listings for each file that was developed or discussed in the post.

Every post that includes program listings has a Resources section.

I used to try to match folder in names in the repository to the post number, but that gets difficult to manage for posts that are scheduled a couple weeks out.

Terminal sessions

There are two main kinds of terminal sessions: Python terminal sessions, and terminal sessions where OS-specific commands are given.

Python terminal sessions are indicated by a triple angle bracket prompt, and the actual Python code is usually shown in bold:

>>> print("Hello terminal world!")
Hello terminal world!

Regular terminal sessions are indicated by a dollar sign prompt:

$ python3 --version
Python 3.12.0

There are a number of different prompts used across the different operating systems in use today, and sometimes you’ll see different prompts in use on one system. The dollar sign is a stand-in for any terminal prompt. If a command is OS-dependent, that will usually be explained in the text.1

Better code blocks in emails?

I’m hoping Substack improves their code blocks before too long. MP #19 discusses a proposal for improving code blocks in technical newsletters; I think there are improvements that can be made, despite the limitations that email delivery services face. Specifically, I’m hoping to see support for neatly formatted filenames, the option to highlight lines, and perhaps include line numbers as well.

Code style

I’ve always been a fan of style guidelines like PEP 8. When people in a community follow a consistent set of conventions, it’s easier to communicate about code. I was skeptical at first, but I’ve also become a fan of formatters like Black.

However, formatting code that’s going to be viewed on mobile devices favors a different set of conventions. I tend to do a number of things to make code more legible on narrower devices, and to keep listings as short as possible:

  • Use shorter variable names;

  • Use shorter lines;

  • Break longer lines in a way that balances width and length of the given code block.

I also tend to use single quotes in my code, because that’s what Python still uses by default in much of its output.

When you’re writing your own code, I encourage you to follow the suggestions in PEP 8, and consider using a formatter such as Black.

Use of AI tools

I was skeptical of AI assistants when they were released in the fall of 2022, but by spring of 2023 they had proven their worth for a wide variety of use cases. I use AI assistants when working on code, and when finalizing posts before publication.

I don’t use AI tools to do any actual writing, because I don’t want to lose my voice as a writer. I use OpenAI’s GPT-4 almost exclusively, because it does everything I need well enough at this point.

Working on code

When writing code over much of the last decade, I’d have a browser window open with many tabs: Python docs, library docs, Stack Overflow pages, and more. These days I also have a tab with a long-running GPT-4 session.

LLM-based AI assistants are non-deterministic, which is part of what makes them useful. But it’s also the feature that causes them to make stuff up. I still have documentation and SO pages open while programming, because I end up validating a lot of the suggestions I get from GPT. That said, when I get stuck, GPT can often get me working again in just a couple minutes. Many of these situations would have taken half an hour of reading to resolve in the past. In some situations, I can tell that GPT is saving me hours of reading and trying different approaches.

I’m doing a lot of work involving subprocess calls these days. If you haven’t used it, the subprocess module lets you make system calls from Python. Sometimes that’s a simple call, and sometimes it means opening a pipe and managing system input, output, and errors yourself. GPT makes this kind of work so much more efficient, at least for my current use cases. It’s also incredibly efficient at helping sort out cross-platform issues.

I don’t have clear thoughts at this point about how AI assistants will affect the learning process for people who are newer to programming. A lot of the efficiency I gain from using GPT depends on the understanding I already have of programming. If it helps me connect a few ideas, I can get back up and running quickly. There are many times where I can see that if you didn’t already have a good understanding of programming, it might lead you off into some mess of overly complex or non-functional code.

Reviewing posts

I don’t think I’ll ever use an AI assistant to do any original writing for me. I’ve spent decades developing my voice as a writer, and I don’t want to lose that. I also don’t think we need more AI-generated content in the world.

I do, however, find AI assistants really helpful in the final stages of reviewing a written piece. I have a long list of tasks I run through when working on a post. One of the last steps is to run the post through GPT, with a specific prompt each time. Here’s an excerpt from that prompt:

I'd like to share a post, and ask if you have any critique or feedback before I publish it. I'd like you to point out if I've said anything inaccurate or misleading.

I'm not looking for a detailed grammatical review. If you spot any obvious typos or grammar errors please mention them, but don't offer rewording of my writing. I have a tendency to write a little more than I need to, so if you see anything that can be shortened, simplified, or left out, please mention that.

I review my writing enough before this stage that GPT doesn’t call out a whole lot. But it does end up catching some things I’ve missed at times, and I always appreciate those suggestions. Overall, my posts are usually a little more polished after doing this review. I also end up ignoring a lot of the recommendations, because it often tells me to put more self-promotional content in.

screenshot of GItHub issue
Every post starts out as an issue on GitHub. I run through along list of tasks before publishing each post; one of the last tasks is running the post through GPT for a quick review.

If you’re new to working in terminal environments, you don’t need to type the prompt symbol yourself. You’ll never type the >>> or $ prompt on your keyboard; that symbol appears in your terminal, and means your system is waiting for you to enter a Python command (>>>), or an OS command ($).