Functions

Functions are code that can be called repeatedly from other places. Functions can have parameters passed into them, and may return a resulting value. Some functions, like len, are built-in. Some functions, like system.gui.messageBox(), are part of the scripting libraries provided by Ignition. Some functions, like math.sqrt(), are provided by the Python standard libraray.

Functions are invoked by using their name followed by an argument list surrounded in parentheses. If there are no arguments, you still need an open and close parenthesis.

Defining Functions

Functions are defined using the def keyword. A function needs a name, and needs a list of the arguments that it can be passed. For example, this code defines a function that tests whether or not a number is odd. It returns a true value (1) if the number is odd. It is then used in a loop to print out the odd numbers between 0 and 9.

def isOdd(num):
return num % 2 == 1 # uses the modulus (or remainder) operator
for x in range(10):
if isOdd(x):
print x

Function Arguments

When a function accepts arguments, the names of those arguments become variables in the function's namespace. Whatever value was passed to the function when it was invoked becomes the value of those variables. In the example above, the value of x inside the for loop gets passed to the isOdd function, and becomes the value of the num argument.

Arguments can have default values, which makes them optional. If an argument is omitted, then its default value will be used. The following code defines a function calledcap, which will take a number, and make sure it is within an upper and lower limit. The limits default to 0 and 100.

def cap(x, min=0, max=100):
if x < min:
return min
elif x > max:
return max
else:
return x
# This will print out "0"
print cap(-1)
# This will print out "100"
print cap(150)
# this will print out "150", because it uses a max of 200
print cap(150, 0, 200)

Keyword Arguments

Arguments can also be specified by keyword instead of by position. In the above example, the only way someone would know that the 200 in the last call to cap specified the max is by its position. This can lead to hard-to-read function invocations for functions with lots of optional arguments. You can use keyword-style invocation to improve readability. The following code is equivalent to the last line above, using 200 for the max and the default for the min.

print cap(150, max=200)

Note that not all functions in the standard library and the Ignition library can be called with keyword invocation. Functions that accept keyword invocation, like system.tag.queryTagHistory , will say so in their documentation.

Functions are Objects

Perhaps one of the most foreign concepts for new Python users is that in Python, functions are first-class objects. This means that functions can be passed around to other functions (this concept is similar to the idea of function pointers in C or C++).

Lets go back to the isOdd example above. Suppose we wanted a more general way to filter a list. Maybe sometimes we want the odd entries, while other times we want even ones, or entries less than 3, etc. We can define a function called extract that takes a list and another function, and returns only entries that "pass" through the other function.

def isOdd(num):
return num % 2 == 1
def isEven(num):
return num % 2 == 0
def isLessThan(num, max=3):
return num < max
def extract(filterFunction, list):
newList = []
for entry in list:
if filterFunction(entry):
newList.append(entry)
return newList
# prints out [0, 2, 4, 6, 8]
# notice that isEven as not _invoked_, but passed to the filter function
print extract(isEven, range(10))

Now, it just so happens that Python has a built-in function that does exactly what our extract function does - its called filter.

We would also be remiss at this point if we didn't mention another language feature called list comprehensions. This is a great little bit of syntax that helps make new lists out of other lists. Instead of using our filter function, we could have simply done this:

def isEven(num):
return num % 2 == 0
print [x for x in range(10) if isEven(x)]

If that looks cool to you - read more about list comprehensions at http://docs.python.org/tutorial/datastructures.html#list-comprehensions

In Ignition, you'll most commonly see functions used as objects when using the system.util.invokelater function. This function takes a function and executes it after all pending event handling has finished processing.

Next ...