Expressions in KTL Python¶
Expression
instances are used in KTL Python to satisfy waitFor()
conditions. All of Python’s logical and mathematical operators are supported,
and KTL keywords can be used as operands for all valid operations; not all
keyword types support all operations, just as some Python types cannot be used
with specific operators. The Python documentation on built-in types describes the range of available operations for the
various native Python types. When an Expression
is evaluated, the
rich-comparison functions of the Keyword
class are used. The behavior
of these functions mimics the behavior of native Python types.
Inline function calls are not supported by the Expression
class,
though support may be added in the future.
Basic expressions¶
Though there is no real incentive to do so, one can create Expression
instances that do not contain KTL keywords. Here are a few examples
demonstrating simple syntax; the following expressions all evaluate to True:
3 < 4
3 + 4 == 7
3 + 4 >= 6
(3 + 4) * 5 == 35
foobar + cat == foobarcat
foo * 3 == foofoofoo
Quoting in Expressions¶
Any Python quoting syntax is valid for values within an Expression
.
If multiple levels of quoting are present, only the first level of quoting
will be ‘stripped’, same as if one were creating Python strings. As in the
simple examples above, there is no requirement that a string be quoted when
used in an Expression
unless it contains whitespace, begins with
a $
character, or matches a valid mathematical or logical operator. All
non-quoted whitespace in an Expression
is removed by the parser.
Consider the following examples, which all evaluate to True:
foo == foo
foo == 'foo'
foo != 'foo '
foo != '$foo'
foo != "'foo'"
foo == '''foo'''
foo == """foo"""
foo != """'foo'"""
KTL keywords in expressions¶
Any readable KTL keyword can be used as part of an Expression
regardless of whether the KTL service is already open elsewhere in the
program, or whether a given KTL keyword is already being monitored.
The specific syntax for using keywords will vary according to how the
Expression
is initialized, but all such declarations are prefixed
with a single $
character. Consistent with other usage in KTL Python,
service names are case sensitive, and keyword names are case insensitive.
If a default service is specified (as implied when using
Service.waitFor()
), the service name does not need to be specified.
Otherwise, the service name must be included as part of the KTL keyword
declaration. KTL Python adopts the established convention that service and
keyword names are joined with a single .
character.
The following examples use the keyword BAR
from the service foo
.
If the keyword has the value 5, these expressions will evaluate to True:
$foo.BAR == 5
$foo.bar < 10
$Bar >= 5
$BAR * 5 == 25
There is no limit to the number of keywords that may be used in an
Expression
. Consider this moderately complex example:
($foo.BAR < 55) or ($foo.BAZ > 215) or ($foo.STATUS != Ready)
If any of those sub-conditions evaluates to True, the whole Expression
will evaluate to True.
How Expressions work¶
When an Expression
instance is intantiated, it will parse the
expression string for any embedded KTL keywords. If a KTL service is not opened,
it will be opened; if a keyword is not monitored, it will be monitored.
Services opened in this fashion will not be closed, and keyword monitoring
will not be disabled, regardless of whether the specific Expression
instance is still in use.
Upon creation, the Expression.evaluate()
method can be invoked at any
time to fully evaluate itself. Expression.wait()
may be used to block
waiting for an Expression
to evaluate to True.
The Expression class¶
-
class
ktl.
Expression
(expression, services=None, default=None, keywords=None, case=False, wait=True)¶ Parse a string into clauses using a shunting-yard algorithm. Expressions may contain a mixture of mathematical and logical operators, and can be evaluated at any time.
-
callback
(function, remove=False, preferred=False)¶ Register (or unregister if remove is set to True) a callback function with all identified
Keyword
instances that are part of thisExpression
instance.
-
evaluate
(final=False)¶ Determine the current value of the
Expression
instance. If aKeyword
in an Expression has no value (as might occur if its initial broadcast is still pending),Expression.evaluate()
will return None. If final is False, theExpression
will be fully evaluated for each individual keyword broadcast; if final is True, only a single evaluation will be performed, using only the most recent broadcast for each keyword.
-
wait
(timeout=None)¶ Wait for this
Expression
to evaluate to True. timeout is specified in seconds; if a timeout is provided and it expires,wait()
will return False.
-