Condition¶
This guide provides an overview and brief instructions on how to use Condition blocks to switch workflow branches depending on configurable conditions.
Getting started¶
With the Condition block, you can:
- Validate input parameters. For example, make sure that the user-specified parameter values are within the valid range.
- Control the computation order. For example, switch between workflow branches that implement the computation in different ways.
- Make decisions based on intermediate results. For example, stop or continue the calculation cycle depending upon the value of a certain variable.
These capabilities are provided by switching between output port groups depending upon the conditions imposed on the input data. The block matches the input data with the conditions specified in it and, if the data meets any of the conditions, outputs the data to the corresponding port group. Each condition has its own output port group. Data that does not meet any of the specified conditions is output to a separate default port group.
Setting up the input ports¶
Data arrives through the input ports of the block. The block starts running only if there is data on each input port. Otherwise, the block does not output any data.
Drag the block onto the workflow design surface, and then double-click it to open the configuration dialog. Initially, the block has no ports. When configuring the block, you first need to add ports to receive input data.
In the configuration dialog, click the button next to the Ports field to add the desired ports. Enter a suitable name for each port. This name identifies the input port, its associated variable in the condition expressions, and the corresponding output port in each output port group.
After adding ports, you can proceed to setting up conditions.
Setting up conditions¶
Conditions are built upon logical expressions that can include pieces of
input data. Expressions use double-quoted input port names as variables
representing input data. The input data meets the condition if the
condition expression evaluates to True
.
To add conditions, in the configuration dialog, click the button in the Conditions pane. Enter a suitable name for each condition. This name also identifies the output port group for the corresponding condition.
When the block is running, its conditions are checked from top to bottom
in the list. Input data is output to the port group of the first
condition that it matches. The output port group of the last condition
in the list is used to output data that does not match any of the
specified conditions. This condition is named else
by default, has no
configurable expression, and can be considered the negation of all
conditions that precede it in the list.
You can change the order of checking conditions by moving them up and
down the list. To do this, use the
and
buttons in the
Conditions pane. The else
condition that ends the list cannot be
moved.
Condition expressions allow the use of basic comparison operators, such
as "equals" ("a"=="b"
), "less than" ("a"<"b"
), "greater or equal"
("a">="b"
) and so on, as well as the logical and
and or
operators.
Arithmetic operators are also allowed. The in
operator can be used to
check if a value is contained in a certain array ("v" in "arr"
) or in
a certain string as a substring ("v" in 'some long string'
).
Parentheses allow you to control the order in which the expression is
evaluated.
When composing expressions, observe the following basic rules:
- Each variable name must be enclosed in double quotes. For example, the
expression
"x"<0
checks the value of the input port namedx
. The variable name representing the port value is enclosed in double quotes:"x"
. -
If the variable value is an array, the element index must be outside the double quotes surrounding the name of the variable, for example
"result"[2]<0
(list item),"result"[3][0]>1
(matrix element).Array indexing is zero-based, so for example
"result"[2]
is the third element of the value received to theresult
input port. -
If the variable value is a dictionary, the item key must be outside the double quotes, for example
"dict"['key']=='value'
.
For more on composing expressions, see Condition expressions.
Reviewing output port groups¶
The number of ports in each output port group is the same as the number of the block input ports. Each output port group is associated with one of the block conditions. If the input port values meet a certain condition, they are sent to the output ports of the group associated with that condition.
The identifier of the output port group is the name of its condition.
The name of each output port in the group is composed of the condition
name and the name of the respective input port. The dot is used as a
separator: condition-name.port-name
.
For example, a Condition block with two input ports x1
, x2
and two
conditions case A
and case B
will have the following output ports:
case A
(condition)case A.x1
(port)case A.x2
(port)
case B
(condition)case B.x1
(port)case B.x2
(port)
else
(default condition)else.x1
(port)else.x2
(port)
Assuming that in the block configuration dialog the conditions are
placed in the above order (first case A
, then case B
), this
configuration works as follows:
- If the values of
x1
andx2
meet the conditioncase A
, they are output tocase A.x1
andcase A.x2
, respectively, and the block finishes. - Otherwise, the block continues to check the condition
case B
. If the input values meet this condition, they are output tocase B.x1
andcase B.x2
, and the block finishes. - If the input values do not meet any of the above conditions, they are
output to
else.x1
andelse.x2
.
Condition expressions¶
Conditions are defined by logical expressions that evaluate to True
or
False
. A condition is deemed met if its expression evaluates to True
.
Condition expressions must conform to the basic Python syntax for
expressions and may contain variables, literals, and operators.
Names of the variables in the condition expression are the names of the input ports. When evaluating an expression, each variable is replaced with the value of the corresponding port.
Strings and numbers can be used as literals. A literal string must be
enclosed in single quotes ('string'
) - you cannot use double quotes
as a double-quoted string is considered a variable identifier.
Compound values, such as lists, matrices, and dictionaries, can be
passed to expression variables through block input ports. The creation
of such values within an expression is not allowed. For instance, a list
literal ([1, 2, 3]
) in an expression will cause an error when
evaluating the expression.
The expression is successfully evaluated when the values of expected
data types are substituted into it from the input ports. If the port
value does not match the expected data type of the respective variable,
evaluation of the expression may fail. For instance, a numeric value of
the variable "x"
results in an error when evaluating the expression
"x"[2]<0
because "x"
is expected to be a list.
Operators¶
The following operators are allowed in condition expressions:
Comparison operators
==
- equal to, not to be confused with the=
assignment operator; when used with strings, the comparison is case-sensitive<
- less than>
- greater than<=
- less than or equal to>=
- greater than or equal to
Arithmetic operators
+
- addition-
- subtraction*
- multiplication/
- division%
- division modulo (remainder of division)
Logical operators
and
-True
if both operands areTrue
; otherwise,False
or
-True
if either operand isTrue
; otherwise,False
not
-True
if the operand isFalse
;False
if the operand isTrue
Membership test operator
in
-True
if the left operand is contained in the right one; with strings, works as a substring search.
Examples¶
Some typical condition expressions are:
"x">=0 and "x"<=1
- check if the numeric value of thex
port is in the range from 0 to 1."r0"<"r1" and "r1"<"r2" and "r2"<"r3"
- check if the numeric values of the portsr0
,r1
,r2
, andr3
are strictly in ascending order."f_error"/"f"<0.05
- assuming that values of thef_error
andf
ports are numeric, check that thef_error
tof
ratio is less than0.05
."func"[0]<"func"[1]
- assuming the value of thefunc
port is a list of numbers, check if the first number in the list is less than the second number (note that indexing is zero-based)."preset"=='Mode N'
- check if the value of thepreset
port is the string'Mode N'
. Such a condition can be used, for example, to switch between workflow branches depending upon values of a certain port. String comparisons are case-sensitive:'mode n'
is not equal to'Mode N'
."name" in 'universe'
- check if the string value of thename
port is a substring of'universe'
. For example, this expression evaluates toTrue
if the value of thename
port is'verse'
, or'nive'
, or'ver'
. Such tests are also case-sensitive:'I'
is not in'universe'
."dict"['preset']=='default'
- assuming the value of thedict
port is a dictionary, check if the value under the'preset'
key is the string'default'
.