Groovy Syntax


Operators

Groovy Operators

Arithmetic Operators

Operator Purpose Examples
+ Addition 2 + 2 = 4
- Subtraction 2 - 2 = 0, 4 - 2 = 2
* Multiplication 2 * 2 = 4, 4 * 2 = 8, 10 * 0 = 0
/ Division 10 / 5 = 2
% Modulo (remainder) 4 % 3 = 1, 10 % 2 = 0
** Power 2 ** 2 = 4, 5 ** 2 = 25,2 ** 4 = 16

Relational Operators

Relational operators are used to compare two objects. In groovy the following operators are available. The result of an expression using a relational operator is either TRUE or FALSE.

Operator Purpose Examples
== Equals 1 + 2 == 3, TRUE, 1 + 2 == 4, FALSE
!= Different (does not equal) 1 + 3 != 4, FALSE, 3 != 2.5, TRUE, “model” == “MODEL”, TRUE
> Greater than 0 > 8, FALSE, 0 > -2, TRUE, 0 > 0, FALSE
>= Greater than or equal to 0 >= 8, FALSE, 0 >= -2, TRUE, 0 >= 0, TRUE
< Less than 0 < 8, TRUE, 0 < -2, FALSE, 0 < 0, FALSE
<= Less than or equal to 0 <= 8, TRUE, 0 <= -2, FALSE, 0 <=0, TRUE

Logical Operators

Logical operators allow us to combine boolean expressions:

Operator Purpose Examples
&& and true && true, TRUE, true && false, FALSE, (1 == 1) && (1 > 2), FALSE
|| or true || true, TRUE, true || false, FALSE
! not !true, FALSE, !false, TRUE

If/Else Statements

If/Else statements are used to perform different actions based on conditional statements.

Basic if/else logic

As an example, let’s say we want to write an expression that when provided with an hour of the day (24 hour clock), returns to us whether the time is AM or PM.

One logical, plain language solution would be to say, if the hour provided is less than 12, return AM, if not, return PM. Let’s implement this in groovy.

if (hour < 12) {
   “AM”
} else {
   “PM”
}

Here is what is going on. We start the if statement with if, followed by an expression in parenthesis. The expression in the parenthesis will be evaluated for truth. If the expression is TRUE, groovy will return the value in the curly braces. If it is FALSE, it will move on to the next statement.

We should go through the calculations a few times to make sure we know what is happening and our logic is sound.

Example Evaluation
hour = 6 6 < 12 is TRUE, the expression returns AM
hour = 20 20 < 12 is FALSE, the expression skips the first set of curly braces. It then evaluates the else statement, which is always TRUE and therefore returns PM.
hour = 12 12 < 12 is FALSE, the expression skips the first set of curly braces. It then evaluates the else statement, which is always TRUE and therefore returns PM. For more on operators, read here.
hour = 26 26 < 12 is FALSE, the expression skips the first set of curly braces. It then evaluates the else statement, which is always TRUE and therefore returns PM. But wait, this doesn’t make sense since there is no hour 26 in a day.
hour = -5 -5 < 12 is TRUE, the expression returns AM. Once again, this doesn’t make sense in the context of our problem because hours in the day cannot be negative.

Expanding our if/else logic

As we witnessed in the example above, sometimes we need to expand our if/else statements in order to include more logic. One way to do this is to add an else if to our expression, in order to evaluate additional conditions. After considering the last two examples above, we can expand our pseudo code into, if the hour provided is not between 0 and 24, inclusive, return an error, otherwise, if the hour provided is less than 12, return AM, if not, return PM. Let’s implement this in groovy.

if (h < 0 || h > 24) {
   "Error"
} else if (h < 12) {
   "AM"
} else {
   "PM"
}

Once again, we can walk through the expression to make sure we know what is going on. First we evaluate (h < 0), then (h > 24). If either is TRUE, meaning h is outside our range of 0 - 24, our expression returns Error. If both are FALSE, groovy will move on and evaluated the next statement, just as we did in our example above.

For good measure, let’s run through our examples again.

Example Evaluation
hour = 6 6 < 0 is FALSE, 6 > 24 is FALSE, 6 < 12 is TRUE, the expression returns AM.
hour = 20 20 < 0 is FALSE, 20 > 24 is FALSE, 20 < 12 is FALSE, the expression skips the first set of curly braces. It then evaluates the else statement, which is always TRUE and therefore returns PM.
hour = 12 12 < 0 is FALSE, 12 > 24 is FALSE, 12 < 12 is FALSE, the expression skips the first set of curly braces. It then evaluates the else statement, which is always TRUE and therefore returns PM.
hour = 26 26 < 0 is FALSE, 26 > 24 is TRUE, the expression returns Error
hour = -5 -5 < 0 is TRUE, -5 > 24 is FALSE, the expression returns Error

Variables

Variables are containers for storing data values. They can store numbers, text, objects, or collections.

In Modelshop, it can be helpful and best practice to define a variable rather than call a function multiple times. Consider the following expression.

if (model.sampleDataList.findAll{it.exampleField > 1} == null) {
  null
} else if (model.sampleDataList.findAll{it.exampleField > 1}.size == 1){
  “We only have one!”
} else {
  model.sampleDataList.findAll{it.exampleField > 1}.average{it.otherField}
}

We make three identical findAll queries in this expression. First to check if the query is empty, second to see if its size is equal to 1 and finally, if the size of the collection is not null or size 1, we get the average of Other Field. This is more work for us and more work for the computer. Let’s use a variable to make this cleaner and easier.

def sampleQuery = model.sampleDataList.findAll{it.exampleField > 1}

if (sampleQuery == null) {
  null
} else if (sampleQuery.size == 1){
  “We only have one!”
} else {
  sampleQuery.average{it.otherField}
}

Much cleaner and neater. Additionally, if we now want to change our findAll query, we only have to edit one place, rather than three.

Built-in Funtions

Math (Beyond Arithmetic)

Modelshop has built-in functions to handle many mathematical operations beyond the arithmetic operators. These functions are organized within the Math module.

To get the absolute value:

Math.abs(sampleValue)

To get the square route:

Math.sqrt(sampleValue)

To get the natural logarithm:

Math.log(sampleValue)

To get the log base 10:

Math.log10(sampleValue)

Dealing with Dates

Modelshop has the ability to efficiently and effectively deal with dates.

Today

To access today’s date:

Date.today()

Date Details

Get the month:

sampleDate.getMonth()

Get the day of the month:

sampleDate.getDay()

Or the day of the week:

sampleDate.getDay()

Get the year:

sampleDate.getYear()

Get the week of the year:

sampleDate.getWeek()

Or the week of the month:

sampleDate.getWeekOfMonth()

Is it a business day?:

sampleDate.getWeekOfMonth()

Is it a US holiday?:

sampleDate.isHoliday("United States")

Or a Canadian holidy?

sampleDate.isHoliday("Canada")

Difference Between Dates

Adding days:

sampleDate.plusDays(1)

Subtracting days:

sampleDate.plusDays(-5)

Or business days:

sampleDate.plusBusinessDays(1)

Adding weeks:

sampleDate.plusWeeks(1)

Adding months:

sampleDate.plusMonths(1)

Adding years:

sampleDate.plusYears(1)

Difference Between Dates

In days:

sampleDate.ageDays(Date.today())

In months:

sampleDate.ageMonths(Date.today())

In years:

sampleDate.ageYears(Date.today())

Or business days:

sampleDate.ageBusinessDays(Date.today())

Handling Text

Handling text can be a challenge in business intelligence and spreadsheet software. Modelshop allows more comprehensive control of text using a full programming language. Let’s go over a few of the important methods for handling text.

For these examples, let us use sampleText = “The quick brown fox”

Indexing

To access a specific letter in the text string use it’s index value:

sampleText[0] = T
sampleText[1] = h
sampleText[2] = e

We can also index from the end of the text string:

sampleText[-1] = x
sampleText[-2] = o
sampleText[-3] = f

Or get multiple indices:

sampleText[0,5,10] = Tub

Slicing

We slice our text string using the indices as well.

sampleText[0..2] = The
sampleText[4..12] = quick bro

We can mix the positive and negative indices, too.

sampleText[0..-1] = The quick brown fox

Since 0 is the index of the first letter and -1 is the index for the last, we get the entire text string.

Concatenation

We can also join strings together by simply using the + operator:

sampleText.split(" ")[1] + sampleText.split(" ")[0] = quickThe
sampleText.split(" ")[1] + “ “ + sampleText.split(" ")[0] = quick The

Text Functions

Modelshop also has several built in functions for handling text.

Slicing from the left:

Text.left(sampleText, 6) = The qu

You may notice this is the same as:

sampleText[0..5]

We can also split our text string:

sampleText.split(" ")[1] = quick
sampleText.split(" ")[0] = The

In this example, we are splitting the text where there is a space (“ ”). Then we can access each chunk by it’s index.

We can also get the length of a text string:

sampleText.length()