Top  | Previous | Next

Working with Different Datatypes

You'll encounter lots of different datatypes when scripting in Python. This guide should help you through the snags of working with some of the more complex types.

Numbers

Working with numbers is very easy in Python, and requires no special considerations. You can use the built-in function int() to attempt to coerce values to integers, and float() to coerce values to floating-point values. Both will throw ValueError if the coercion fails.

 

information2 If you are new to programming, the following might throw you off. Python, like nearly all programming languages, uses integer division when dividing two integers. This means that 1/2  will result in 0. This is because both 1 and 2 are integers, so the result of the division must be an integer. The result of 0.5 gets truncated to 0. If either operand is a float, the result will be a float, so 1 / 2.0 will result in 0.5.

Strings

Strings are used frequently in scripting. Strings can be defined using double quotes or single quotes. Learning how to use String Formatting is a very useful technique. You can user the built-in function str() to coerce values into strings.

Colors

Working with colors in Python is remarkably easy. You can simply use any tuple of 3 or 4 integers to represent a color in RGB or RGBA. For example, to set a label's text color to red, you can simple do something like this:

label = event.source

label.foreground = (255,0,0)

Dates

Dates are one of the trickier datatypes to deal with in scripting. It turns out that it is easier to deal with dates using the Java classes java.util.Date and java.util.Calendar than it is to use Python's time module.

Creating Dates

To create an arbitrary date, you can use the java.util.Calendar class. It has various functions to alter the calendar fields, like Calendar.HOUR, Calendar.MONTH, etc. After you're done manipulating the Calendar, you can use its getTime() function to retrieve the Date represented by the calendar. It also has a handy set() function that takes the common parameters of a Date. The one major gotcha here is that January is month zero, not month one. For example:

 

from java.util import Calendar

cal = Calendar.getInstance()

 

# set year, month, day, hour, minute, second in one call

# This sets it to Feb 25th, 1:05:00 PM, 2010

cal.set(20101251350)

myDate = cal.getTime()

 

Date Arithmetic

Often you'll have a Date object from a component like the Popup Calendar and want to alter it programmatically. Say, subtracting 8 hours from it, or something like that. The java.util.Calendar class is used for this as well. Following the example above, this code would subtract 8 hours from the variable myDate.

 

from java.util import Calendar

cal = Calendar.getInstance()

 

cal.setTime(myDate)

cal.add(Calendar.HOUR, -8)

myNewDate = cal.getTime()

 

Date Formatting

To format a date as a String, you can use the system function system.db.dateFormat. This function uses a format string to give it a hint as to how you want your date formatted. The format string is full of various placeholders that will display different parts of the date. These are case-sensitive! The most common placeholders are:

 

y

Year

M

Month

d

Day

E

Day of Week

a

am/pm marker

H

Hour of day (0-23)

h

Hour in am/pm (1-12)

m

Minute

s

Second

S

Millisecond

z

Time zone

 

These placeholders can be repeated for a different effect. For example, M will give you 1-12, MM will give you 01-12, MMM will give you Jan-Dec, MMMM will give you January-December. Here are some examples:

 

from java.util import Date

 

now = Date() # creates a new date, for right now

 

# Common format for databases

print system.db.dateFormat(now, "yyyy-MM-dd H:mm:ss")

 

# Nice human-readable format for just the date

print system.db.dateFormat(now, "MMM d, yyyy")

 

# Formating just the time in am/pm style

print system.db.dateFormat("h:mm a")

 

Datasets

It is very common to deal with datasets in scripting, as datasets power many of the interesting features in Ignition, like charts and tables. The system.dataset library provides various functions for manipulating and creating datasets.

 

The main confusion when dealing with datasets is the difference between the DataSet object and the PyDataSet object. DataSet is the kind of object that Ignition uses internally to represents datasets. When you get the data property out of a Table, for example, you'll get a DataSet. The PyDataSet is a wrapper type that you can use to make DataSets more accessible in Python. You can convert between the two with system.dataset.toPyDataSet and system.dataset.toDataSet.

Accessing data in a DataSet

DataSets have various properties and functions that you can access through Python.

rowCount - returns the number of rows in the dataset
columnCount - returns the number of columns in the dataset
getColumnName(index) - returns the name of the column at the given index
getValueAt(row, column) - returns the value from the dataset at the given location. column can be either an integer or a column name, which is treated case-insensitive.

 

For example, you could iterate through every item in a DataSet in scripting like this:

# Pull the dataset property off a Table component

data = event.source.getComponent("Table").data

 

for row in range(data.rowCount):

   for col in range(data.columnCount):

      print data.getValueAt(row, col)

 

or you could find specific values from each row in a DataSet like this:

# Pull the dataset property off a Table component

data = event.source.getComponent("Table").data

 

for row in range(data.rowCount):

   temp = data.getValueAt(row, "Temperature")

   speed = data.getValueAt(row, "Speed")

   print temp, speed

 

Accessing data in a PyDataSet

You can convert a dataset to a PyDataSet, which lets you use it more like a Python sequence. You don't have to do this, its purely a convenience. A PyDataSet is like a list of dictionaries, and so it can use the normal for loop syntax. These examples are equivalent to the examples above.

 

Iterating through a PyDataSet

# Pull the dataset property off a Table component

data = event.source.getComponent("Table").data

 

# Convert to a PyDataSet

pds = system.dataset.toPyDataSet(data)

 

for row in pds:

   for value in row:

      print value

 

Finding specific values in a PyDataSet

# Pull the dataset property off a Table component

data = event.source.getComponent("Table").data

 

# Convert to a PyDataSet

pds = system.dataset.toPyDataSet(data)

 

for row in pds:

   temp = row["Temperature"]

   speed = row["Speed"]

   print temp, speed

 

Accessing specific elements in a PyDataSet

# Pull the dataset property off a Table component

data = event.source.getComponent("Table").data

 

# Convert to PyDataSet

pds = system.dataset.toPyDataSet(data)

 

# Grab the first item of the first row

value = pds[0][0]

print value

Altering Datasets

Technically, you cannot alter a dataset. Datasets are immutable, meaning they cannot change. You can, however, create new datasets. So to alter a dataset, you really create a new one and then replace the old one with the new one. Because this is so common, there are special functions under system.dataset that are designed for this. You can use the following functions to create datasets that are altered version of existing datasets:

system.dataset.addRow
system.dataset.deleteRow
system.dataset.setValue
system.dataset.updateRow

 

The important thing to realize about all of these datasets is that, again, they do not actually alter the input dataset. They return a new dataset. You need to actually use that returned dataset to do anything useful. For example, this code would set the "Quantity" column in the selected row of a table to 15.8:

 

table = event.source.parent.getComponent("Table")

selRow = table.selectedRow

if selRow != -1:

   # Create a new dataset

   newData = system.dataset.setValue(table.data, selRow, "Quantity"15.8)

 

   # Replace the Table's data property with the new dataset

   table.data = newData

 

Creating Datasets

Sometimes you'll want to create a new dataset from scratch. This can be easily done with the system.dataset.toDataSet

function. All it needs are the column headers and a list of the rows in the dataset. Each row must have the same number of elements as the header list. For example, this code would create a dataset that contained some information about US cities:

 

headers = ["City""Population""Timezone""GMTOffset"]

data = []

 

data.append(["New York"8363710"EST", -5])

data.append(["Los Angeles"3833995"PST", -8])

data.append(["Chicago"2853114"CST", -6])

data.append(["Houston"2242193"CST", -6])

data.append(["Phoenix"1567924"MST", -7])

 

cities = system.dataset.toDataSet(headers, data)