Chapter 12 - Designing and Deploying Command Line Programs (Python)
Here's a concise walkthrough of the main ideas in Chapter 12, each with a small example.
Designing and Deploying Command Line Programs (intro)
Goal: move from running code in Mu to running scripts as real commands from the terminal, using virtual environments, pip, and deployment techniques.
A Program by Any Other Name
Defines terms: program, script, command, shell script/batch file, application, app, web app, and how they differ.
Example shell script:
#!/usr/bin/env bash
echo "Starting backup..."
python backup_to_zip.py
echo "Done."
Using the Terminal
Explains what CLI/terminal/shell/console are and how to open them on each OS, plus how prompts look and how to run Python or a .py file from the terminal.
Example (Windows):
C:\Users\al> python C:\Users\al\Scripts\yourScript.py
Example (Linux/macOS):
python3 yourScript.py
The cd, pwd, dir, and ls Commands
cdchanges current directory.pwd(macOS/Linux) prints working directory.cdwith no args on Windows shows current dir.dir(Windows) andls(macOS/Linux) list contents.
Example (Windows):
C:\Users\al> cd Desktop
C:\Users\al\Desktop> cd ..
C:\Users\al>
Example listing:
ls
# or
dir
The PATH Environment Variable
PATH is a "search list" of folders the shell looks in to find commands like python or ls.
- Windows: checks CWD first, then folders in
PATH. - macOS/Linux: only
PATH; use./programfor CWD.
Example:
echo $PATH
# /home/al/.local/bin:/usr/local/bin:/usr/bin:...
PATH Editing
Recommends a Scripts folder under your home and adding it to PATH so you can run your scripts from anywhere.
- Windows: edit user "Path" via "Edit environment variables for your account", add
C:\Users\al\Scripts. - macOS: add
export PATH=/Users/al/Scripts:$PATHto~/.zshrc. - Linux: add
export PATH=/home/al/Scripts:$PATHto~/.bashrc.
The which and where Commands
which name(macOS/Linux)where name(Windows)
Show where a command actually lives in PATH.
Example:
which python3
# /Library/Frameworks/.../python3
where python
# C:\Users\al\AppData\Local\Programs\Python\Python313\python.exe
Virtual Environments
Motivation: different projects may need conflicting versions of the same package; system Python on macOS/Linux is used by the OS, so avoid polluting it. Use venv to create isolated environments.
Creating a Virtual Environment
In Scripts folder:
# Windows
cd C:\Users\al\Scripts
python -m venv .venv
# macOS/Linux
cd ~/Scripts
python3 -m venv .venv
Creates a .venv folder containing its own Python and pip.
Activating a Virtual Environment
Windows:
C:\Users\al\Scripts> cd .venv\Scripts
C:\Users\al\Scripts\.venv\Scripts> activate.bat
(.venv) C:\Users\al\Scripts\.venv\Scripts> where python.exe
# first entry is ...\.venv\Scripts\python.exe
macOS/Linux:
cd ~/Scripts/.venv/bin
source activate
(.venv) ...$ which python3
# ~/Scripts/.venv/bin/python3
python -m pip list inside venv shows only minimal packages.
Notes:
- Use one venv per project ideally; for small scripts, one shared venv in
Scriptsis OK. - On macOS/Linux, avoid installing third-party packages into system Python; use venv instead.
- Mu has its own venv; packages in
Scripts/.venvaren't visible to Mu's F5 runs.
Deactivate: deactivate.bat (Windows) or deactivate (macOS/Linux) or close the terminal; delete .venv folder to remove the environment.
Installing Python Packages with pip
Use python -m pip / python3 -m pip rather than bare pip to ensure you hit the right Python.
Installing, Listing, Upgrading, Uninstalling
Install:
python -m pip install package_name
List:
python -m pip list
Upgrade:
python -m pip install -U package_name
Install specific version:
python -m pip install package_name==1.17.4
Uninstall:
python -m pip uninstall package_name
Warning: if using Anaconda, use conda instead of pip inside conda envs.
Installing the automateboringstuff3 Package
Meta-package that pins all book-used packages and their versions.
# Windows
python -m pip install automateboringstuff3
# macOS/Linux
python3 -m pip install automateboringstuff3
Self-Aware Python Programs
Shows built-ins and modules that let your script know about itself and environment.
Key pieces:
__file__– path to the current.pyfile as a string (not in the interactive shell).Path(__file__)– handy for locating resources next to your script.sys.executable– path to the Python executable.sys.version/sys.version_info– version info.os.name–'nt'(Windows) or'posix'(macOS/Linux).sys.platform–'win32','darwin','linux'.platformmodule – more detailed OS/CPU info.
Example:
from pathlib import Path
import sys, os, platform
print(Path(__file__)) # script path
print(sys.executable) # interpreter path
print(sys.version_info.major) # e.g. 3
print(os.name, sys.platform) # 'nt' 'win32' or 'posix' 'darwin'
print(platform.system()) # 'Windows'/'Darwin'/'Linux'
Checking whether a module is installed:
import sys
try:
import nonexistentModule
except ModuleNotFoundError:
print('nonexistentModule is required. Please install it.')
sys.exit(1)
Text-Based Program Design
Motivates "TUI" programs and introduces several design patterns for CLIs.
Short Command Names
Advocates short, type-friendly command names (cp vs copy) for commands you'll run often; use which/where and web search to ensure you don't collide with existing commands.
Example: choose ccwd for "copy current working directory" instead of a long name.
Command Line Arguments
Explains sys.argv and how to design simple argument sets; suggests argparse for more complex scenarios.
Example:
python yourScript.py spam eggs
Inside yourScript.py:
import sys
print(sys.argv)
# ['yourScript.py', 'spam', 'eggs']
With spaces in one argument:
python yourScript.py "hello world"
# sys.argv == ['yourScript.py', 'hello world']
Clipboard I/O
Pattern: pyperclip.paste() → process → pyperclip.copy(), so your script acts like a filter over the clipboard.
General steps:
import pypercliptext = pyperclip.paste()- transform
text pyperclip.copy(result)
Example mini-tool:
import pyperclip
text = pyperclip.paste()
result = text.strip().upper()
pyperclip.copy(result)
print('Transformed text copied to clipboard.')
Colorful Text with Bext
Introduces bext for colored text and simple TUI features; only works from real terminals, not Mu.
Install:
python -m pip install bext
Basic colors:
import bext
bext.fg('red')
print('This text is red.')
bext.bg('blue')
print('Red text on blue background.')
bext.fg('reset')
bext.bg('reset')
Other helpers:
bext.clear()– clear screen.bext.width(),bext.height()– terminal size.bext.hide(),bext.show()– cursor.bext.title(text)– window title.bext.goto(x, y)– move cursor.bext.get_key()– wait for and return key name.
Key reading example:
import bext
print('Press a key...')
key = bext.get_key()
print('You pressed:', key)
Terminal Clearing
Gives bext.clear() and also a pure-Python one-liner using os.system and a conditional expression.
Custom clear():
import os
def clear():
os.system('cls' if os.name == 'nt' else 'clear')
Sound and Text Notification
Discusses using sound sparingly as a notification tool; introduces playsound3 for simple audio playback.
Install:
python -m pip install playsound3
Example:
import playsound3
playsound3.playsound('hello.mp3')
Notes:
playsound()blocks until audio finishes; long files pause your program.- If filenames with odd characters cause exceptions, pass a
Pathobject instead of a plain string.
Also notes: text output should remain pipe-friendly (e.g. usable in Unix pipelines), so noisy, verbose output can reduce composability; keep CLIs focused and predictable.
Overall idea of the chapter
Chapter 12 covers everything needed to turn Python scripts into real command-line tools: terminal navigation, PATH setup, virtual environments for isolation, pip for package management, self-awareness (__file__, sys, platform), and TUI design patterns (arguments, clipboard I/O, colored text, sound notifications).