Share
Appendices
Appendix A: Python Quick Reference
A single-page reference for the syntax and built-ins you use every day.
Built-in Types
| Type | Example | Notes |
|---|---|---|
int |
42, -7, 0 |
Arbitrary precision |
float |
3.14, -0.5 |
64-bit IEEE 754 |
complex |
3+4j |
real and imag attributes |
bool |
True, False |
Subclass of int |
str |
"hello", 'world' |
Immutable, Unicode |
bytes |
b"hello" |
Immutable byte sequence |
list |
[1, 2, 3] |
Mutable sequence |
tuple |
(1, 2, 3) |
Immutable sequence |
set |
{1, 2, 3} |
Mutable, unordered, unique |
frozenset |
frozenset({1, 2}) |
Immutable set |
dict |
{"a": 1} |
Key-value, ordered (3.7+) |
None |
None |
The null value |
Numeric Operations
10 // 3 # 3 — floor division
10 % 3 # 1 — modulo
2 ** 10 # 1024 — exponentiation
abs(-5) # 5
round(3.567, 2) # 3.57
divmod(10, 3) # (3, 1)
String Methods
s = " Hello, World! "
s.strip() # "Hello, World!"
s.lower() # " hello, world! "
s.upper() # " HELLO, WORLD! "
s.replace("Hello", "Hi") # " Hi, World! "
s.split(", ") # [" Hello", "World! "]
", ".join(["a","b","c"]) # "a, b, c"
s.startswith(" H") # True
s.endswith("!") # False (has trailing spaces)
s.strip().endswith("!") # True
f"{'hello':>10}" # " hello"
f"{3.14159:.2f}" # "3.14"
f"{1_000_000:,}" # "1,000,000"
List Operations
lst = [3, 1, 4, 1, 5, 9]
lst.append(2) # [3, 1, 4, 1, 5, 9, 2]
lst.extend([6, 5]) # in-place extend
lst.insert(0, 0) # insert at index
lst.remove(1) # remove first occurrence of 1
lst.pop() # remove and return last
lst.pop(0) # remove and return at index
lst.sort() # in-place sort
lst.sort(reverse=True) # descending
lst.reverse() # in-place reverse
lst.index(4) # index of first 4
lst.count(1) # count of 1s
sorted(lst) # new sorted list
sorted(lst, key=abs) # sort by key
Dictionary Operations
d = {"a": 1, "b": 2}
d["c"] = 3 # add/update
d.get("x", 0) # 0 — safe get with default
d.setdefault("y", []) # set if missing, return value
del d["a"] # delete key
"b" in d # True
d.keys() # dict_keys(["b", "c"])
d.values() # dict_values([2, 3])
d.items() # dict_items([("b", 2), ("c", 3)])
d.pop("b") # remove and return
d.update({"e": 5}) # merge in-place
{**d, "f": 6} # merge into new dict (3.9+: d | {"f":6})
Set Operations
a = {1, 2, 3}
b = {2, 3, 4}
a | b # {1, 2, 3, 4} — union
a & b # {2, 3} — intersection
a - b # {1} — difference
a ^ b # {1, 4} — symmetric difference
a.issubset(b) # False
a.issuperset(b)# False
a.isdisjoint({5, 6}) # True
Control Flow
# Ternary
x = "yes" if condition else "no"
# Walrus operator (3.8+)
if (n := len(data)) > 10:
print(f"Too many: {n}")
# Match statement (3.10+)
match command:
case "quit":
quit()
case "help" | "?":
show_help()
case str(msg) if msg.startswith("/"):
handle_command(msg)
case _:
print("Unknown")
Comprehensions
# List
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
# Dict
word_len = {w: len(w) for w in words}
# Set
unique_lengths = {len(w) for w in words}
# Generator (lazy)
gen = (x**2 for x in range(10**9))
next(gen) # 0
# Nested
matrix = [[i*j for j in range(3)] for i in range(3)]
flat = [x for row in matrix for x in row]
Functions
def greet(name: str, greeting: str = "Hello") -> str:
"""Return a greeting string."""
return f"{greeting}, {name}!"
# Unpack
def add(*args: int) -> int:
return sum(args)
def configure(**kwargs: str) -> None:
for key, val in kwargs.items():
print(f"{key} = {val}")
# Lambda
double = lambda x: x * 2
# Call with unpack
args = [1, 2, 3]
add(*args)
d = {"name": "Ada"}
greet(**d)
Built-in Functions
len(obj) # length
range(n) # 0 to n-1
range(a, b, step) # a to b-1, stepping
enumerate(iterable) # (index, value) pairs
zip(a, b) # pair up iterables
map(fn, iterable) # apply fn lazily
filter(fn, iterable)# filter by fn lazily
sorted(iterable) # new sorted list
reversed(sequence) # reversed iterator
sum(iterable) # numeric sum
min(iterable) # minimum
max(iterable) # maximum
any(iterable) # True if any truthy
all(iterable) # True if all truthy
isinstance(obj, T) # type check
issubclass(A, B) # class hierarchy check
hasattr(obj, name) # attribute check
getattr(obj, name) # attribute access
setattr(obj, name, val) # attribute set
dir(obj) # list attributes
vars(obj) # __dict__
id(obj) # memory address
type(obj) # type
repr(obj) # developer string
hash(obj) # hash value
callable(obj) # is it callable?
open(path, mode) # file handle
print(*args, end="\n", sep=" ", file=sys.stdout)
input(prompt) # read user input
int(), float(), str(), bool(), list(), dict(), set(), tuple()
Appendix B: Standard Library Cheat Sheet
The most useful modules from the Python standard library:
os — Operating System Interface
import os
os.getcwd() # current directory
os.chdir("/path") # change directory
os.listdir(".") # list files
os.makedirs("a/b", exist_ok=True) # create dirs
os.remove("file.txt") # delete file
os.rename("old", "new") # rename
os.environ.get("HOME") # env var
os.path.join("a", "b.txt") # path join (prefer pathlib)
os.path.exists("file.txt") # existence check
os.cpu_count() # CPU count
pathlib — File Paths (Modern)
from pathlib import Path
p = Path("/home/user/data.csv")
p.name # "data.csv"
p.stem # "data"
p.suffix # ".csv"
p.parent # Path("/home/user")
p.exists() # True/False
p.is_file() # True
p.is_dir() # False
p.read_text() # file contents as string
p.write_text("hello")
p.read_bytes() # binary content
p.mkdir(parents=True, exist_ok=True)
list(p.glob("*.csv")) # matching files
list(p.rglob("*.py")) # recursive
p.with_suffix(".json") # change extension
p / "subdir" / "file.txt" # path joining
p.stat().st_size # file size bytes
p.stat().st_mtime # modification time
sys — System Information
import sys
sys.argv # command-line arguments
sys.exit(0) # exit with code
sys.path # module search path
sys.version # Python version string
sys.platform # "linux", "win32", "darwin"
sys.stdin # standard input
sys.stdout # standard output
sys.stderr # standard error
sys.getsizeof(obj) # size in bytes
sys.getrecursionlimit()
sys.setrecursionlimit(2000)
datetime — Dates and Times
from datetime import datetime, date, timedelta, timezone
now = datetime.now()
today = date.today()
utc_now = datetime.now(tz=timezone.utc)
# Create
dt = datetime(2024, 12, 25, 9, 30, 0)
d = date(2024, 12, 25)
# Format
dt.strftime("%Y-%m-%d %H:%M:%S") # "2024-12-25 09:30:00"
dt.isoformat() # "2024-12-25T09:30:00"
# Parse
datetime.strptime("2024-12-25", "%Y-%m-%d")
datetime.fromisoformat("2024-12-25T09:30:00")
# Arithmetic
tomorrow = today + timedelta(days=1)
last_week = today - timedelta(weeks=1)
diff = dt2 - dt1 # timedelta
# Attributes
dt.year, dt.month, dt.day
dt.hour, dt.minute, dt.second
dt.weekday() # 0=Monday, 6=Sunday
collections — Specialised Containers
from collections import defaultdict, Counter, deque, namedtuple, OrderedDict
# defaultdict
word_count = defaultdict(int)
word_count["hello"] += 1
# Counter
c = Counter(["a", "b", "a", "c", "a", "b"])
c.most_common(2) # [("a", 3), ("b", 2)]
# deque — fast append/pop from both ends
q = deque(maxlen=5)
q.append(1)
q.appendleft(0)
q.pop()
q.popleft()
# namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(1, 2)
p.x, p.y
# OrderedDict (mostly redundant since Python 3.7 dicts are ordered)
od = OrderedDict()
itertools — Iterator Building Blocks
import itertools
itertools.chain([1,2], [3,4]) # 1 2 3 4
itertools.chain.from_iterable([[1,2],[3]]) # flatten
itertools.count(10, 2) # 10 12 14 ...
itertools.cycle([1,2,3]) # 1 2 3 1 2 3 ...
itertools.repeat(7, 3) # 7 7 7
itertools.islice(gen, 5) # first 5
itertools.takewhile(pred, it) # while pred is true
itertools.dropwhile(pred, it) # drop while pred true
itertools.filterfalse(pred, it) # where pred is false
itertools.compress([1,2,3], [1,0,1]) # 1 3
itertools.starmap(fn, [(a,b)]) # fn(*args)
itertools.accumulate([1,2,3,4]) # 1 3 6 10
itertools.groupby(sorted_data, key_fn)
itertools.combinations([1,2,3], 2) # (1,2) (1,3) (2,3)
itertools.permutations([1,2,3], 2) # all 2-perms
itertools.product([1,2], [3,4]) # cartesian product
itertools.batched(it, 3) # groups of 3 (3.12+)
functools — Higher-Order Functions
from functools import reduce, partial, lru_cache, wraps, cached_property
reduce(lambda acc, x: acc + x, [1,2,3,4]) # 10
double = partial(pow, exp=2) # pow with exp=2
@lru_cache(maxsize=128)
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
@wraps(original_fn) # preserve metadata on wrapped functions
def wrapper(*args, **kwargs): ...
class Circle:
@cached_property # computed once, then cached
def area(self): return 3.14 * self.radius ** 2
json — JSON Encoding/Decoding
import json
# Encode
json.dumps({"name": "Ada", "age": 36}) # string
json.dumps(data, indent=2, sort_keys=True) # pretty
json.dump(data, file_handle) # to file
# Decode
json.loads('{"name": "Ada"}') # dict from string
json.load(file_handle) # from file
# Custom encoder
class DateEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, date):
return obj.isoformat()
return super().default(obj)
json.dumps(data, cls=DateEncoder)
re — Regular Expressions
import re
re.match(r"^\d+", text) # match at start
re.search(r"\d+", text) # first match anywhere
re.findall(r"\d+", text) # all matches
re.finditer(r"\d+", text) # iterator of matches
re.sub(r"\s+", " ", text) # replace
re.split(r"[,;]\s*", text) # split
# Compile for reuse
pattern = re.compile(r"(\d{4})-(\d{2})-(\d{2})")
m = pattern.search("Date: 2024-12-25")
m.group(0) # "2024-12-25"
m.group(1) # "2024"
m.groups() # ("2024", "12", "25")
# Flags
re.search(r"hello", text, re.IGNORECASE)
re.DOTALL # . matches newline
re.MULTILINE # ^ and $ match line starts/ends
subprocess — Run System Commands
import subprocess
# Simple run
result = subprocess.run(
["git", "log", "--oneline", "-5"],
capture_output=True,
text=True,
check=True, # raises if returncode != 0
)
print(result.stdout)
print(result.returncode) # 0
# Shell command (avoid when possible — injection risk)
subprocess.run("ls -la | grep .py", shell=True)
typing — Type Hints
from typing import Optional, Union, Any, Callable, TypeVar
from typing import Sequence, Mapping, Iterable
from collections.abc import Generator, Iterator, AsyncGenerator
# Python 3.10+ — use | instead of Union
def foo(x: int | None) -> str | int: ...
T = TypeVar("T")
def first(items: list[T]) -> T:
return items[0]
# Callable
Handler = Callable[[str, int], bool]
# TypedDict
from typing import TypedDict
class Movie(TypedDict):
title: str
year: int
Appendix C: Virtual Environment and Project Setup Cheat Sheet
Quick Start (venv)
# Create and activate
python -m venv .venv
# Windows
.venv\Scripts\activate
# Mac/Linux
source .venv/bin/activate
# Install and freeze
pip install requests pandas
pip freeze > requirements.txt
pip install -r requirements.txt
# Deactivate
deactivate
Quick Start (uv — recommended)
# Install uv
pip install uv
# New project
uv init myproject
cd myproject
# Add dependencies
uv add requests pandas pytest
# Run
uv run python script.py
uv run pytest
# Sync from lockfile
uv sync
Project Structure Template
my-project/
├── src/
│ └── my_project/
│ ├── __init__.py
│ ├── core.py
│ └── utils.py
├── tests/
│ ├── conftest.py
│ ├── test_core.py
│ └── test_utils.py
├── docs/
├── scripts/
├── .env.example
├── .gitignore
├── pyproject.toml
├── README.md
└── Makefile
Python .gitignore (essential lines)
# Virtual environments
.venv/
venv/
env/
# Python cache
__pycache__/
*.py[cod]
*.pyo
# Distribution
dist/
build/
*.egg-info/
# Pytest
.pytest_cache/
.coverage
htmlcov/
# Environment variables
.env
# IDE
.idea/
.vscode/
*.swp
# OS
.DS_Store
Thumbs.db
Appendix D: Git Quick Reference
# Setup
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
# Start
git init
git clone https://github.com/user/repo.git
# Core workflow
git status
git add file.py
git add .
git add -p # interactive staging
git commit -m "feat: add user login"
git log --oneline --graph
# Branches
git switch -c feature/login
git switch main
git merge feature/login
git branch -d feature/login
# Remote
git remote add origin https://github.com/user/repo.git
git push -u origin main
git pull
git fetch origin
# Undo
git restore file.py # discard changes
git restore --staged file # unstage
git revert HEAD # undo last commit safely
git stash
git stash pop
# Useful
git diff
git show HEAD
git log --author="You" --since="1 week ago"
git tag v1.0.0
git bisect start
Conventional Commits
feat: new feature
fix: bug fix
docs: documentation change
test: add or update tests
refactor: code change with no feature/fix
perf: performance improvement
chore: build, config, or tool change
ci: CI/CD configuration
Appendix E: pytest Quick Reference
# Basic test
def test_add():
assert add(1, 2) == 3
# Exception testing
def test_divide_zero():
with pytest.raises(ZeroDivisionError):
divide(1, 0)
# Parametrize
@pytest.mark.parametrize("a, b, expected", [
(1, 2, 3),
(0, 0, 0),
(-1, 1, 0),
])
def test_add(a, b, expected):
assert add(a, b) == expected
# Fixture
@pytest.fixture
def db():
conn = sqlite3.connect(":memory:")
init_db(conn)
yield conn
conn.close()
def test_query(db):
result = query(db, "SELECT 1")
assert result == [(1,)]
# Mock
from unittest.mock import patch, Mock
def test_api_call():
with patch("mymodule.requests.get") as mock_get:
mock_get.return_value.json.return_value = {"status": "ok"}
result = fetch_status()
assert result == "ok"
pytest # run all tests
pytest -v # verbose
pytest tests/test_core.py # specific file
pytest -k "login" # filter by name
pytest --cov=src # coverage
pytest --cov=src --cov-report=html # HTML report
pytest -x # stop on first failure
pytest --tb=short # shorter tracebacks
Appendix F: f-String Formatting Reference
name = "Ada"
value = 3.14159
count = 1_000_000
# Basic
f"Hello, {name}!" # "Hello, Ada!"
f"Pi = {value}" # "Pi = 3.14159"
# Debug (3.8+)
f"{name=}" # "name='Ada'"
f"{value=:.2f}" # "value=3.14"
# Number formatting
f"{value:.2f}" # "3.14"
f"{value:.4e}" # "3.1416e+00"
f"{count:,}" # "1,000,000"
f"{count:_}" # "1_000_000"
f"{0.1234:.0%}" # "12%"
f"{255:#010b}" # "0b11111111"
f"{255:#x}" # "0xff"
# Alignment
f"{'left':<10}" # "left "
f"{'right':>10}" # " right"
f"{'center':^10}" # " center "
f"{'padded':*^10}" # "**padded**"
# Width from variable
width = 10
f"{'hello':>{width}}" # " hello"
# Nested expressions
f"{2 + 2}" # "4"
f"{'yes' if True else 'no'}" # "yes"
f"{', '.join(['a','b','c'])}" # "a, b, c"