Contributing¶
The one rule¶
No page hand-types what a program prints.
A lesson marks the spot:
and tools/run_examples.py fills it from a real run of my_lesson/examples/my_lesson_java.java. Inside the markers is generated; outside is yours. There is a second kind, source:, which pastes the program itself, for the pages where the code is the lesson.
This is not tidiness. A hand-pasted output block is a claim that was true on the day someone ran it, and it silently stops being true when a JDK changes behaviour. A generated one breaks the build instead.
Adding a lesson¶
mkdir -p NN_Chapter/my_lesson/examples- Write
examples/my_lesson_java.java. Single file, no dependencies,public class Mainis fine — the file name does not have to match. Stems must be unique repo-wide; the convention is a_java/_pysuffix. - Write
README.mdwith a**Level:**line, a**One line:**summary, and anoutput:block. python3 tools/run_examples.py --updateto record the answer key.python3 tools/run_examples.py --checkto confirm it is reproducible.
Why the environment is pinned¶
Examples run under LC_ALL=C with -Duser.language=en -Duser.country=US -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8. All four are load-bearing, and this repo learned each of them the hard way:
Locale.getDefault()comes from the OS on macOS, not from the environment, so without the two locale flags the answer key depends on whose machine recorded it.System.outfollows the console encoding, notfile.encoding. UnderLC_ALL=Cthat is US-ASCII, and Java transliterates anything it cannot encode to a literal?with no error. The first run of this library recordedza????as the correct answer forzażółć.
A lesson whose subject is the locale or the charset overrides this inside the program, in view of the reader — never by asking the runner for an exception.
Don't put the environment in an answer key¶
Two things went into keys on the first day and both broke CI immediately, which is the system working:
java.versioncarries the patch level (25.0.4.1locally,25.0.3on the runner), so printing it locks the key to one JDK build. PrintRuntime.version().feature()— the feature release is what a lesson ever means.native.encoding's raw string is platform-specific:US-ASCIIon macOS,ANSI_X3.4-1968on Linux, one charset with two IANA names. Canonicalise withCharset.forName(raw).name().
The rule generalises: if a value comes from the host rather than from the idea being taught, either canonicalise it or don't print it.
Examples that fail on purpose¶
Some lessons are about code that does not compile. The runner records combined stdout and stderr and appends [exit status: N] when the exit code is non-zero, so "this is a compile error" is an answer key rather than a claim.
Prose conventions¶
- Don't hard-wrap paragraphs. One paragraph, one line.
- Link a folder by naming its
README.md—[label](some_folder/README.md), never[label](some_folder/). MkDocs does not rewrite the bare form and the published link 404s. - Level tags are
**Level:** <rung> · <audience>where the rung is 101 / 201 / 301. - Be fair to Java. The point is to be accurate, which means saying plainly where Java is good — it is, in several places — and where a sibling language made a better choice.