Houdini & Procedural Workflows / Houdini / Python
Day 4 - Numbers in Houdini with Python | Houdini 10 Day Introduction to Python
Written guide

Playing loads YouTube content. YouTube processes data after activation.
Watch on YouTubeIf the player is blocked or unavailable, use Watch on YouTube.
Day four connects Python arithmetic to a visible Houdini result: a box whose dimensions come from variables and whose base rests on the ground. Before creating that geometry, the lesson compares operators, numeric conversion, rounding and a few mathematical functions. The distinction between a value and a string containing digits from day three becomes a practical debugging tool here.
Work in a new shelf tool and keep the Python Shell visible for output. Apply the edited tool definition, then run the tool to test it; applying code and executing it are separate actions. The examples below normalize the narrated Python 3 syntax. The recording’s exact Houdini and Python builds are not identified.
Verify arithmetic before assigning it to geometry
At 01:01, assign x = 5 and y = 10. The basic operator trials produce these results:
| Expression | Result | Operation |
|---|---|---|
x + y |
15 | Addition |
x - y |
-5 | Subtraction |
x * y |
50 | Multiplication |
x / y |
0.5 | Division |
x ** y |
9765625 | Exponentiation |
x % y |
5 | Remainder for this positive-number example |
y % x |
0 | Reversing the operands changes the remainder |
Inspect the printed result after each edit. Two asterisks mean exponentiation; they are not a second way to write multiplication. The division example also shows that integer inputs can produce a floating-point result in Python 3. These simple checks isolate arithmetic from the additional questions of which Houdini node and parameter the script will later address.
Convert numeric text before doing numeric addition
At 04:01, the code tries to add a string containing digits to an integer and raises an error. Convert the text deliberately before adding it. These normalized examples illustrate the two successful forms discussed:
print(int("11") + 5) # 16
print(float("5.5") + 11) # 16.5
int() can read the integer-form string in the first example. float() accepts the decimal-form string in the second. The next source experiment tries int("5.5") and fails: a decimal point in a string does not make it an accepted integer literal. This is different from converting an already numeric float, which is not the failing operation being demonstrated.
If input may contain a decimal part, choose conversion according to the intended data instead of assuming everything can become an integer. The lesson does not implement input validation or exception handling; the immediate check is to identify the incoming type and the exact conversion that failed.
Choose a rounding rule rather than guessing from one example
At 06:00, round(3.14) returns 3. The following comparison is especially useful: round(3.5) and round(4.5) both return 4. For those exact halfway cases, Python selects the even choice. It does not always round a trailing five upward.
The optional second argument controls decimal places, as in round(3.14, 1), which returns 3.1. Python’s built-in function reference confirms the tie rule and notes that binary floating-point representation can make decimal rounding results surprising. Treat the recorded examples as specific results, not proof that every decimal-looking tie is represented exactly.
At 09:01, import math and compare directional rounding:
import math
print(math.floor(3.14)) # 3
print(math.floor(3.9)) # 3
print(math.ceil(3.14)) # 4
print(math.ceil(3.9)) # 4
print(abs(-5)) # 5
The captions’ “seal” means ceil. Floor selects the greatest integer less than or equal to the input; ceiling selects the least integer greater than or equal to it. Those definitions also avoid the mistaken assumption that either operation simply removes the decimal digits for every sign. The math reference supplies the precise definitions.
abs() is a built-in function, so it does not need the math. prefix. In the source’s positive and negative five examples, it returns distance from zero. Zero itself remains zero; absolute value is not necessarily strictly positive.
Create the nodes, then address their actual parameter names
At 12:00, the lesson returns to Houdini’s hou module. Retrieve /obj, create a geometry object named myGeo, then create a Box SOP named myBox inside it. Retain the returned node objects in variables so subsequent operations do not require repeatedly spelling out the entire path. The day-two node-creation lesson covers that setup in more detail.
Node type names and node instance names serve different purposes. The type string geo chooses a Geometry object; myGeo names this particular instance. The source inspects an existing node’s information to find the type rather than assuming its displayed label is the type string.
Declare numeric width, height and depth variables. At that point the box still has its default dimensions: creating Python variables alone does not edit any Houdini parameter. The following fragment assumes box already refers to the created Box SOP and those three numeric variables have already been assigned:
box.parm("sizex").set(width)
box.parm("sizey").set(height)
box.parm("sizez").set(depth)
box.parm("ty").set(height / 2)
This is a normalized parameter-setting fragment, not a standalone tool or a claim about the exact unnamed dimensions used on screen. The source hovers over parameter labels to reveal the internal names. Size X, Y and Z use the lowercase component names shown here; the center’s Y component is corrected to ty during the demonstration. Preserve their case. A deliberately capitalized component produces an error near the end.
Check the grounded box and the scope of the calculation
At 18:02, the box appears with its base on the grid after the center is set to half its height. For the unrotated, centered box in this exercise, half its vertical extent lies below its center. Moving that center up by half the height places the bottom at zero.
The expression height / 2 is evaluated by Python and its resulting number is passed to set(). This fragment does not establish a live channel relationship to Size Y. Changing the box height afterward would require updating the center again or creating a separate parameter-expression relationship, which is outside this demonstration. SideFX distinguishes setting a parameter value from setting an expression in the hou.Parm reference.
Review three levels independently: printed arithmetic, the values displayed on the Box SOP, and the box’s position against the grid. If arithmetic is correct but geometry is unchanged, inspect node references and parameter names. If the dimensions change but the base is below the grid, inspect the center assignment. The source finishes with a reminder that arithmetic precedence still applies; use parentheses when the intended calculation needs an explicit grouping.