主题: coding-practice
-
设计 Python 命令行工具:argparse、main() 与退出码
将接口放入注册为控制台脚本的 main(argv) -> int 函数中,用 argparse 的 type 和 choices 做校验,遵循退出码惯例(0 表示成功,2 表示用法错误,1 表示其他失败,仅在有文档说明时才使用 sysexits 代码),将结果输出到 stdout、诊断信息输出到 stderr,并妥善处理 SIGINT 和管道中断。
-
.NET 依赖注入惯例:生命周期、作用域与“被困依赖”陷阱
Microsoft.Extensions.DependencyInjection 会把服务以 transient(瞬时)、scoped(作用域)或 singleton(单例)三种生命周期之一注册到 `IServiceCollection` 上,并通过公共构造函数注入;官方文档规定的规则是:绝不能把 scoped 服务注入 singleton 中,容器创建的对象应由容器自己释放,应避免使用服务定位器(service locator)式调用,并应启用作用域校验,使“被困依赖”在启动时就报错,而不是在多个请求之间悄悄泄漏状态。
-
Comments that carry information the code cannot
Write comments for why, for constraints and for non-obvious consequences; do not restate what the code says. Keep comments next to the code they describe, delete them when the reason disappears, and prefer a better name or a test to a comment.
-
Refactoring in small, verified steps
Refactoring changes structure without changing behaviour; doing it in tiny steps with tests green between steps, and separating refactoring commits from behaviour changes, keeps it safe and reviewable.
-
Technische Schulden als bewusste Entscheidung mit Buchführung
Cunninghams Metapher: Nicht ganz richtiger Code ist ein Kredit, jede Minute Mehrarbeit daran ist der Zins. Die Metapher trägt nur, wenn die Schuld bewusst aufgenommen, notiert und regelmässig bewertet wird; als Sammelbegriff für alles Unschöne oder als Entschuldigung für Schlamperei ist sie wertlos.
-
Working practices for an AI agent changing a codebase
Read before writing, reproduce before fixing, change in small verified steps, run the project's own checks, never retry writes blindly, and report exactly what was tested; a methodology for agents that edit code.
-
TypeScript narrowing: unions, unknown and any
TypeScript shrinks a union type inside a branch after typeof, instanceof, in, equality and truthiness checks or a user-defined type predicate; discriminated unions plus a never check give exhaustiveness. unknown accepts any value but forbids using it until narrowed, whereas any switches checking off.
-
Technical debt as a metaphor and as a decision
Technical debt describes the future cost of a shortcut; the metaphor is useful when the debt is deliberate and tracked, and misleading when it excuses careless work or is used to describe every imperfection.
-
Naming identifiers so that code reads as intent
Choose names that state what a thing is or does in the domain's vocabulary, at a length proportional to its scope; avoid encodings, abbreviations and misleading types, and rename as understanding improves.
-
Consistent naming and casing of JSON fields
Pick one case convention for property names and apply it everywhere: Google's JSON style guide and ProtoJSON use lowerCamelCase, many APIs use snake_case. Beyond case, keep names meaningful, enums as strings, timestamps as RFC 3339 strings and 64-bit integers as strings.
-
Context managers in Python: guaranteeing clean-up
The with statement runs __enter__ and __exit__ around a block so that files, locks and connections are released even when an exception occurs; contextlib.contextmanager turns a generator into one.
-
Validating JSON with JSON Schema
JSON Schema describes the allowed shape of a document (types, required keys, enumerations, formats, bounds) and lets any language validate inputs before processing them; keep additionalProperties explicit.
-
Docstrings that tools and readers can use
PEP 257 defines where docstrings go and how they are formatted; a consistent style (Google or NumPy) with a one-line summary, argument and return descriptions and raised exceptions makes them usable by readers, editors and documentation generators.
-
Floating-point numbers: why 0.1 + 0.2 is not 0.3
Binary floating point represents most decimal fractions approximately, so arithmetic accumulates rounding error; compare with tolerances, sum carefully, use integers or decimal types for money and counts, and print with enough digits to round-trip.
-
Automated formatting and linting as a team contract
Delegating layout to a formatter and mechanical checks to a linter removes style debates from review; EditorConfig, PEP 8 and tools such as Ruff show how the contract can be encoded in the repository.
-
Feature scaling and categorical encoding: what to transform, and fit it on training data only
Distance- and gradient-based models need numeric features on comparable scales (StandardScaler, MinMaxScaler, RobustScaler); categorical columns become numbers by one-hot, ordinal or target encoding depending on cardinality and model type. Every transformer is fitted on the training split and applied unchanged to validation, test and production rows.
-
Protocol classes: structural typing for duck-typed Python
A typing.Protocol declares the methods and attributes a consumer needs; any object that has them satisfies the type without inheriting from it. Define protocols next to the code that depends on them, keep them minimal, and use runtime_checkable only where isinstance is really needed.
-
Reproducibility of a machine-learning experiment: seeds, environment, data and the limits of determinism
Rerunning an experiment and getting the same number requires fixed random states passed explicitly, pinned library versions, an identified dataset and split, and awareness that GPU kernels and library releases can still change results; the protocol makes runs repeatable where possible and documents where they are not.
-
Structured extraction from documents with JSON Schema, validation and bounded retries
Define the target record as a JSON Schema with additionalProperties false, ask the model for exactly that shape, validate every response with a real validator, retry a bounded number of times with the validation error in the prompt, and route what still fails to a person instead of guessing.
-
NULL in SQL: three-valued logic and its traps
NULL means unknown, so comparisons with NULL yield unknown rather than true or false; WHERE filters drop unknown rows, NOT IN with a NULL matches nothing, and aggregates skip NULLs. Use IS NULL, IS DISTINCT FROM and COALESCE deliberately.
机器可读: JSON