Parameters#
A script can expose the values it depends on as controls — sliders, toggles, dropdowns, file pickers — so that it can be re-run with different inputs without anyone editing Python. This is for the cases where the shape of the work is settled but the numbers are not: a wall thickness to sweep, a mesh density to trade against runtime, a new file to load.
radius = param("Radius", 10.0, min=2.0, max=40.0)
height = param("Height", 40.0, min=5.0, max=120.0)
sides = param("Sides", 36, min=8, max=160)
show_edges = param("Show element edges", True)
tube = shapes.cylinder(radius=radius, height=height, circ_div=sides)
draw(tube, style={"lines": {"visible": show_edges}})
output("Elements", tube.n_elems())
param() does two things at once: it declares a control, and it returns the
value that control currently holds. So the default sits next to the code that
uses it and cannot drift away from it, and the script is its own description of
what can be configured. There is no separate schema to keep in step.
Run once before the controls exist#
The controls are discovered by running the script. Until a run has reached a
param() call, nothing knows that parameter is there — so a script you have
just written has no controls yet. Run it once and they appear.
It is worth noting that a parameter with nothing chosen may stop the run, so a script with two of those can take three runs before the panel is complete. Giving each one a default avoids that.
Which control you get#
You do not choose the control directly. It follows from the default you give and the bounds you set:
param("Smoothing", 0.3, min=0.0, max=1.0) # slider
param("Iterations", 5) # number box
param("Close the surface", False) # toggle
param("Profile", "round", options=["round", "square", "hex"]) # dropdown
param("Job name", "run-01") # text box
A slider needs both ends to be meaningful, so a number with min and max
becomes one and a number without them stays a number box. options always
wins: a fixed set of choices is a dropdown whatever its type, and the value
you get back keeps that type, so options=[1, 2, 4] returns an int.
The default’s type is also what incoming values are read as. Give 0.3 and the
parameter is a float forever; give 0 and it is an integer, so write 0.0 if
you meant a float that happens to start at zero.
Reporting computed values#
output() adds a value to a results section at the bottom of the panel, so
that a script can report what it has computed.
output("Elements", mesh.n_elems())
output("Surface area", mesh.area(), unit="mm²", format=".2f")
output("Min thickness", t_min, label="Thinnest wall", unit="mm")
It returns its argument, so it can wrap an expression already in use:
thickness = output("Mean wall thickness", volume / area, unit="mm", format=".2f")
if thickness < limit:
print("Thinner than the limit — increase the offset.")
format takes a fixed-pont spec such as ".2f" and unit is a string
shown after the value. Both are presentation only — neither changes what the
script computes.
Offering named sets of values#
param_preset() offers a set of values the controls can be filled from in
one click — useful when a handful of combinations get used over and over:
param_preset("Draft", {"Divisions": 8, "Smoothing": 0.0})
param_preset("Production", {"Divisions": 64, "Smoothing": 0.6})
A preset names the parameters it sets and leaves the rest alone. The panel shows which one is loaded, and stops showing it as soon as any value moves away from it — because at that point the configuration is no longer that preset.
Choosing an input file#
param_file() asks for one of the files in the workspace and returns its
name, which is exactly what load() takes:
mesh = load(param_file("Scan", accept=[".stl", ".ply"], default="artery.stl"))
Giving the file input a default lets the script run to completion the first time, so the whole panel appears at once instead of one parameter at a time. Without a default the run stops and asks for a file after declaring the control, so that first run is what produces the picker you then choose from, but anything declared below that line is missing until you have chosen and run again.
Naming an output file#
param_filename() asks for a name to write to, and pairs with save()
or save_simulation():
out = param_filename("Mesh file", "quadmesh.inp", accept=[".inp"])
save_simulation(simulation_setup, out)
Unlike param_file(), the default here is required and positional — an
author naming their own output is the normal case.
Only a bare filename is accepted. A value containing a path separator is refused, because the name becomes a file in a workspace and a separator there is either a mistake or an attempt to write somewhere else. Saving over a name that already exists replaces it, which is usually what re-running a script is meant to do.
Running the code versus running the controls#
Which view you have open decides what Run means.
With the controls showing, the script runs with the configuration on screen.
With the code showing, it runs as written — the controls are ignored, and
every parameter takes the default in the source. That is what makes editing a
default take effect immediately: change param("Divisions", 24) to 32, run,
and you get 32, rather than the 24 a slider was still holding.
The consequence is worth remembering: a value you set by hand is not used by a run started with the code showing, and the panel afterwards shows what actually ran. If you have tuned something and want to keep using it, run from the controls view. A past run’s values can also be put back from the run history.
Things to know#
Declaring the same parameter twice is fine if the settings match. A helper called once per loop iteration does exactly that. Declaring the same name with different settings is an error, because the control would be ambiguous.
``group=`` sorts controls under a heading, in the order the script declares them. Nothing is sorted alphabetically — the script’s order is taken as how the author meant the thing to be configured.
``locked=True`` shows a value but refuses to change it. For a number something else depends on: a surrogate model trained at one mesh density, a tolerance a downstream tool assumes. The declared value always wins, and a supplied one is reported and discarded.
``label=`` and ``help=`` are presentation only. The name is what the value round-trips under, so renaming a parameter loses whatever was set for the old name; a
labelcan be reworded freely.``step=`` only affects how a slider moves. It does not constrain what the script accepts.
Reset returns every control to the value the script declares, discarding anything set by hand. It is greyed out when the controls are already showing the script’s own values.