Variables and treatments optional
Define values once at the start of each submission. Reuse them in question and explanation text with $name or ${name}, and in control logic or skip rules. Write $$ for a literal dollar sign. Answer labels, the title and introduction stay fixed.
Use Python arithmetic, comparisons, booleans, lists and dictionaries; abs, min, max, sum, len and round; math.sqrt, log, exp, floor, ceil; and np.array, mean, sum, clip, random.choice, random.uniform and random.normal. numpy also works. Definitions can use earlier variables. Conditions must return True or False; random draws belong in definitions.
Language reference and limits
Operators: + - * / // % **, comparisons == != < <= > >=, in, not in, and, or, not, and a if condition else b. Values include numbers, strings, True, False, None, lists and dictionaries with string keys. Indexing is supported.
abs(x), min(values) / min(a, b, …), max(values) / max(a, b, …), sum(values, start=0), len(x), round(number, ndigits=0).
math.sqrt(x), math.log(x, base=math.e), math.exp(x), math.floor(x), math.ceil(x); constants math.pi, math.e, math.tau.
np.array(values), np.mean(values, axis=None), np.sum(values, axis=None), np.clip(values, a_min, a_max).
np.random.choice(a, size=None, replace=True, p=None), np.random.uniform(low=0, high=1, size=None), np.random.normal(loc=0, scale=1, size=None). Choice weights must sum to one. Distribution parameters are scalar; sample size is an integer. Omitting size draws one value.
At most 50 variables. Numbers must be finite within ±1e100; exponents and rounding precision within ±100. Collections and random samples have at most 256 entries; arrays have at most two dimensions. Definitions cannot import modules, read files, loop, mutate values or redefine names. This is a limited expression language, not all of Python or NumPy.
Recorded answers in conditions
Use answers["q1"] == "Yes" for a recorded choice, or answers["q2"] > 10 for a number. Multiple selections are lists of labels. Guard skipped questions with "q1" in answers and answers["q1"] == "Yes". Conditions can use earlier answers; skip rules can also use the current answer. Original protected selections are never available.