Logic Syntax
This article will explain the syntax and functions for any logic statements, AKA formulas.
Background
When authoring a survey, you can use Logic Syntax to reference respondent data, access lookup files, do mathematical operations, etc.
This can be useful in the following scenarios:
- Hiding/displaying questions and responses under certain scenarios.
- Jumping to a certain page or question conditionally (skip logic)
- Pre-populating a question's response based on previous responses (autocoding/backcoding).
- Calculating the value for a variable.
You'll recognize formula fields when you are prompted for a condition, or a formula.
- Logic Block Pages:
- Question Level (Display/Skip Logic in the Advance tab):
Referencing Question Responses in Formulas
Question responses can be referenced in formulas by using the question name, and response value.
Mutually Exclusive Questions - Checking Specific Responses
For mutually exclusive questions, just the question name is enough to get a respondent’s answer. For instance, in the example below you can get the user’s answer to Q5 just by typing Q5; you can then compare that against a numeric value to see if the respondent answered something specific for example:
Q5 = 1 (evaluates to true if the respondent answered 1 for Q5)
You could also check if the respondent did not answer the question a specific way by using the inverse:
Q5 != 1 (evaluates to true if the respondent DID NOT answer 1 for Q5)
Non-mutually Exclusive Questions - Checking Specific Responses
For non-mutually exclusive question types, such as checkbox type questions, checking a respondent's answer for a specific response requires both the question name and the response name. In the example below, in order to get the respondent's answer for Q6: Sprite, you would type Q6_1 you can then compare that to 1 (checked) or 0 (unchecked) to see if the respondent selected Sprite for Q6:
Q6_1 = 1 (evaluates to true if the respondent selected Q6_1 (Sprite))
If you wanted to instead check that the user DID not select a specific response you can instead do:
Q6_1 = 0 (evaluates to true if the respondent DID NOT select Q3_1 (Sprite))
Non-mutually Exclusive Questions - Checking Responses (the easier way)
With non-mutually exclusive questions it is likely that we will want to check if a respondent selected ONE OR MORE specific response(s). We can check for this by using the HAS operator, for example:
Q3 HAS [1, 2 OR 3] (evaluates to true if the respondent selected 1, 2 or 3 for Q3)
If you wanted to check the opposite to see if the respondent did not select specific ONE OR MORE responses you can use the inverse, for example:
!(Q3 HAS [1, 2 OR 3]) (evaluates to true if the respondent DID NOT select 1, 2 or 3 for Q3)
Instead of checking that the respondent has 1 or more of the specified responses it is also possible to check that they selected ALL of the specified responses by using AND in place of OR when using the HAS operator, for example:
Q3 HAS [1, 2 AND 3] (evaluates to true if the respondent selected 1, 2 AND 3 for Q3)
If you want to check instead that the respondent did not select any of the specified responses you can inverse the check, for example:
!(Q3 HAS [1, 2 AND 3]) (evaluates to true if the respondent DID NOT select 1, 2 AND 3 for Q3)
Non-mutually Exclusive Questions - Checking Number of Selections
For non-mutually exclusive questions it is common to want to check that respondent selected a certain number of responses, this can be accomplished by combining other checks together and comparing the sum of the responses against a number, for example if we wanted to check that the respondent selected 3 or more responses for Q4:
(Q4_1+Q4_2+Q4_3+Q4_4+Q4_5) >= 3 (evaluates to true if the respondent selected 3 or more responses for Q4)
Logic Syntax Reference
The following is a comprehensive list of the operators and functions available via the logic syntax. NOTE: All operators are case sensitive, and should be written in UPPERCASE:
Operator | Name | Syntax | Description | Example |
= == (both are equivalent) |
Equals | VALUE1 = VALUE2 VALUE1 == VALUE2 |
Returns TRUE or FALSE Compares two values and returns true if they are the same, false otherwise. Can be used for Boolean, Numeric or Text values. |
You want to see if Q1 equals Q2: Q1 = Q2 Q1 == Q2 |
!= | Not equals/ Doesn't equal |
VALUE1 != VALUE2 | Returns TRUE or FALSE Compares two values and returns true if they are NOT the same, false otherwise. Can be used for Boolean, Numeric or Text values. |
You want to see if Q1 does not equal Q2: Q1 != Q2 |
< | Less than | VALUE1 < VALUE2 | Returns TRUE or FALSE Compares two values and returns true if the one on the left is less than the one on the right, false otherwise. Can be used for Boolean, Numeric or Text values. Note: For Boolean values, false is considered less than true. For String values, they are compared in alphabetical ascending order, i.e. A is less than Z. |
You want to see if Q1 is less than Q2: Q1 < Q2 |
> | Greater than | VALUE1 > VALUE2 | Returns TRUE or FALSE Compares two values and returns true if the one on the left is greater than the one on the right, false otherwise. Can be used for Boolean, Numeric or Text values. Note: For Boolean values, true is considered greater than true. For String values, they are compared in alphabetical ascending order, i.e. Z is greater than A. |
You want to see if Q1 is greater than Q2: Q1 > Q2 |
<= | Less than or equal to | VALUE1 <= VALUE2 | Returns TRUE or FALSE Compares two values and returns true if the one on the left is less than or equal to the one on the right, false otherwise. Can be used for Boolean, Numeric or Text values. |
You want to see if Q1 is less than or equal to Q2: Q1 <= Q2 |
>= | Greater than or equal to | VALUE1 >= VALUE2 | Returns TRUE or FALSE Compares two values and returns true if the one on the left is greater than or equal to the one on the right, false otherwise. Can be used for Boolean, Numeric or Text values. |
You want to see if Q1 is greater than or equal to Q2: Q1 >= Q2 |
. | Concatenate | VALUE1 . VALUE2 | Returns Concatenated String Concatenates two values and turns them into a string. |
If you want to nest a variable like gender and age together using logic. Q1 . Q2 |
+ | Plus | VALUE1 + VALUE2 | Returns Resulting Number Sums two numeric values and returns the result. |
If you need to add more than one item together Q1 + Q2 |
- | Minus | VALUE1 - VALUE2 | Returns Resulting Number Subtracts the value on the right from the value on the left and returns the result. |
If you need to subract items. Q1 - Q2 |
* | Multiply | VALUE1 * VALUE2 | Returns Resulting Number Multiplies two numeric values and returns the result. |
If you need to multiply items. Q1 * Q2 |
/ | Divide | VALUE1 / VALUE2 | Returns Resulting Number Divides the value on the left by the value on the right and returns the result. |
If you need to divide items. Q1 / Q2 |
^ | Power | VALUE1 ^ VALUE2 | Returns Resulting Number Elevates the value on the left to the ‘nth power as specified by the value on the right. |
If you need to get the result of Q1 to the fifth power Q1 ^ 5 |
! | Logical Not | ! LOGIC1 | Returns TRUE or FALSE Negates a Boolean value or logical expression. |
If you want to use an inverse statement !( Q1 = 2 ) Helpful if you have a long combination of logic |
( ) | Precedence modifier | ( Expression ) | The expression between parentheses will be evaluated before the one outside. Can be used to modify natural operator precedence. Won’t change the type of the return value of the expression inside. | Used the same way as basic mathematic equations using order of operartions (Q1_1 + Q1_2) - (Q2_2 * 2) |
AND | Logical And | LOGIC1 AND LOGIC2 | Returns TRUE or FALSE Returns true if both LOGIC1 and LOGIC2 are true. |
If you want to see if more than one statement is true Q1=1 AND Q2=5 |
OR | Logical Or | LOGIC1 OR LOGIC2 | Returns TRUE or FALSE Returns true if at least one of LOGIC1 and LOGIC2 is true. |
If you want to see if at least one statement is true Q1=1 OR Q2=5 |
LIKE | Text Like | TEXT1 LIKE TEXT2 | Returns TRUE or FALSE Returns true if TEXT1 is like TEXT2, uses % as a wildcard if it’s present on TEXT2. This is case sensitive as well. |
If you need to check that two text questions are identical. Usually for confirming email address: Q1_1 LIKE Q1_2 If you want to see if a specific word or phrase ("computer: for example) is contained within the text entered in a text question: Q1_1 LIKE "%computer" |
MATCHES | Regular expression Match | TEXT1 MATCHES REGEX | Returns TRUE or FALSE Returns true if TEXT1 matches the regular expression defined as a string in TEXT2. Regular expression is in PCRE syntax: http://php.net/manual/en/pcre.pattern.php |
. |
HAS [ AND ] | Multiselect question has all responses | QUESTION1 HAS [ NUMBER1, NUMBER2 AND NUMBER3] QUESTION1 HAS [ NUMBER1 ] QUESTION1 HAS NUMBER1 |
Returns TRUE or FALSE Checks if the multiselect question QUESTION1, has all the responses listed between the square brackets. A comma appears between each value in the list (Values must be literals). The AND can be omitted. |
If you have a checbox question with 10 responses and you want to see if … Option 3 has been selected: Q1 HAS [3] Both options 2 and 3 have been selected: Q1 HAS [2 AND 3] Items 1, 2 and 5 have been selected: Q1 HAS [1, 2 AND 3] |
HAS [ OR ] | Multiselect question has any of the listed responses | QUESTION1 HAS [ NUMBER1, NUMBER2 OR NUMBER3] | Returns TRUE or FALSE Checks if the multiselect question QUESTION1, has any of the responses listed between the square brackets. A comma appears between each value in the list (Values must be literals). The OR must be specified, otherwise it will be interpreted as an AND. |
If you have a checbox question with 10 responses and you want to see if … Option 3 has been selected: Q1 HAS [3] Options 2 or 3 have been selected: Q1 HAS [2 OR 3] Items 1, 2 or 5 have been selected: Q1 HAS [1, 2 OR 5] |
COUNT | Count responses | COUNT QUESTION:RESPONSE1 | Returns Resulting Number Count how many completes there are in the survey with the given response. It includes people in progress for the last 5 minutes, or the value set in inactivity timeout. NOTE: - This is the only formula that does not use parentheses - Can be used with most question types including Radios and Checkboxes |
You have a checkbox question and you want to use a formula tied to how many completes you have for Q1_1: COUNT Q1_1 COUNT(Q1_1) will not work |
COUNT_ITEMS | Gives you the count of selected, or non/empty items. | COUNT_ITEMS ( QUESTION/VARIABLE ) | Returns Resulting Number It can be used for any multiple response types: checkbox/numerics/text/highlighters/sliders/concepts |
If you want to count how many items in a checkbox question that were selected: COUNT_ITEMS (Q1) |
PARSE | Evaluate string as if it was a formula | PARSE STRING | Returns the evaluation’s result. Parse will evaluate the given string as if it were a formula on its own. Useful for building dynamic question names. This is currently the only way to refer to grid sub-questions in a filter. | Used for filtering. If you have checkbox questions, Q1 (awareness) and Q2 (usage) with the same response list, and you want to only show the items in Q2 selected in Q1: PARSE ("Q1_" . X ) != 1 |
TRY | Evaluate string as if it was a formula | TRY STRING | Returns the evaluation’s result. Parse will evaluate the given string as if it were a formula on its own. Useful for building dynamic question names. This is currently the only way to refer to grid sub-questions in a filter. The difference between this and PARSE is that it will not give you an error if the formula is invalid. If any part inside the TRY is invalid (missing datapoint, invalid formula syntax, etc), the whole TRY function will be replaced with an empty string? |
Used for filtering. If you have checkbox questions, Q1 (awareness) and Q2 (usage) with the same response list, and you want to only show the items in Q2 selected in Q1: TRY ("Q1_" . X ) != 1 |
PAD | Zero padding | PAD (NUMBER1 , NUMBER2) | Returns the Modified String Adds zero-padding to NUMBER1 to have at least as many characters as specified by NUMBER2. It also converts the number to a string. |
. |
FORMAT_DATE | Change date format | FORMAT_DATE ( DATE, FORMAT ) | Returns Date Takes a date in "MM/DD/YYYY HH24:MI:SS" format, for EST time zone, and converts it into the format specified by FORMAT. FORMAT can be any of the ones specified in: http://php.net/manual/en/function.date.php | . |
FORMAT_NUMBER | Allows you to control how many decimal points you have and delimiter symbols | FORMAT_NUMBER ( QUESTION/VARIABLE, DECIMAL_PLACES, "DECIMAL_SYMBOL", "THOUSANDS_DELIMITER") | - QUESTION/VARIABLE: This is an existing question/variable in your survey. You can use other formulas here as well. - DECIMAL_PLACES: Are the number of decimal places you wish to have. With US currency, it is usually 2 - "DECIMAL_SYMBOL": Must be in quotes. Is the decimal symbol. With US currency, its a period, ".". - "THOUSANDS_DELIMITER": Must be in quotes. Is the thousands delimiter symbol. With US currency, its a comma, ",". |
. |
AT_INDEX | Get element in space separated string at a specified index. | AT_INDEX ( STRING, INDEX_NUMBER ) | Returns a single element. Return the element from STRING at the index INDEX_NUMBER. STRING is a space-separated string of values. The first element of the string is at index 1. |
. |
INDEX_OF | Returns the position something was asked in. | INDEX_OF ( VALUE, QUESTION/VARIABLE ) | You give it a VALUE, and it looks for it in a multidimensional question/variable, it returns the position number of where it found it, or empty if it didn't find it. | . |
AT | Get element in array at a specified index. | AT ( ARRAY, INDEX_NUMBER ) | Returns a single element. Return the element from ARRAY at the index INDEX_NUMBER. ARRAY is an array returned by another function, or the responses to a question, variable or concept. The first element of the array is at index 1. Elements are returned in the order they were shown to the respondent. |
. |
INTERSECT | Return elements from the intersection of two arrays. | INTERSECT ( ARRAY_1, ARRAY_2 ) | Returns resulting array. Return only the elements which are present in both ARRAY_1 and ARRAY_2. |
. |
FILE_LOOKUP |
Get a specific value from a given file. | FILE_LOOKUP ( "FILE_NAME", LOOKUP_VALUE, "MATCH_COLUMN" , "FETCHED_COLUMN" ) | Returns the value found in file. File lookup will search in the uploaded lookup named "FILE_NAME" for where the column "MATCH_COLUMN" contains the value LOOKUP_VALUE. It will then return the value found in the "FETCHED_COLUMN" column for that record. |
You have been provided a spreadsheet with passcodes and respondent name and you want to append this to the data. You upload a file to the survey and name it DATA. You would use the following to set the corresponding variables you created. - "FILE_NAME" = DATA - LOOKUP_VALUE = RESP_TOKEN (passcode) - "MATCH_COLUMN" = Column in lookup that has the LOOKUP_VALUE (CODE for example) - "FETCHED_COLUMN" column name containing the name FILE_LOOKUP("DATA", RESP_TOKEN, "CODE", "NAME") |
SURVEY_LOOKUP |
Returns answers for a specific respondent from any survey, including the one you are programming. | SURVEY_LOOKUP ( SURVEY_ID, LOOKUP_VALUE, "MATCH_VARIABLE" , "FETCHED_VARIABLE" ) | - SURVEY_ID can be any survey, including the one you are programming - LOOKUP_VALUE would be the variable/question/or hardcoded value you are looking for. - "MATCH_VARIABLE" would be the question/variable where we are looking for it - "FETCHED_VARIABLE" would be a value you want to bring from that respondent NOTE: Its important that both the "MATCH_VARIABLE" and "FETCHED_VARIABLE" are enclosed in double quotes, because otherwise they are going to be evaluated for the current survey, before being passed into the formula. |
You want to look in survey 123, for a respondent that has a RESP_TOKEN = 10, and bring their Q1 value. : SURVEY_LOOKUP ( 123, 10, "RESP_TOKEN" , "Q1" ) |
PROJECT_LOOKUP |
Returns answers for a specific respondent from any project, including the one you are programming. | PROJECT_LOOKUP ( PROJECT_ID, LOOKUP_VALUE, "MATCH_VARIABLE" , "FETCHED_VARIABLE" ) | - PROJECT_ID can be any project, including the one you are programming - LOOKUP_VALUE would be the variable/question/or hardcoded value you are looking for. - "MATCH_VARIABLE" would be the question/variable where we are looking for it - "FETCHED_VARIABLE" would be a value you want to bring from that respondent NOTE: Its important that both the "MATCH_VARIABLE" and "FETCHED_VARIABLE" are enclosed in double quotes, because otherwise they are going to be evaluated for the current project, before being passed into the formula. |
You want to look in project 456, for a respondent that has a RESP_TOKEN = 10, and bring their Q1 value. : PROJECT_LOOKUP ( 456, 10, "RESP_TOKEN" , "Q1" ) |
USE_RANDOM_LOOKUP | Use a value at random from a given file and return it. | USE_RANDOM_LOOKUP ( "FILE_NAME", "FETCHED_COLUMN" ) | Returns the value found in file. Use random lookup will get a record at random from the uploaded lookup named "FILE_NAME", marking it as used so it won’t be returned by this function anymore, and returns the value found in the "FETCHED_COLUMN" column for that record. |
. |
TEXT | Get the programmer defined content for the question/variable’s response. | To get the content for the respondent’s response(s): QUESTION:TEXT VARIABLE:TEXT To get the content for a specific response, regardless of respondent’s response: QUESTION:RESPONSE:TEXT VARIABLE:RESPONSE:TEXT |
Returns the content string. The TEXT identifier will return the programmer specified content, in the locale for the current respondent. This does not return the user’s open text response (for text fields or specify for instance). When used with the QUESTION:TEXT syntax, it will return the content for the respondent’s answer(s). When used with the QUESTION:RESPONSE:TEXT syntax, it will return the content for the specified response regardless of what the respondent selected. |
. |
LOWER | To lowercase | LOWER TEXT1 | Returns the Modified String Converts the string specified by TEXT1 into lowercase letters. |
If you have a radio question using a response list starting with capital letters and you want to pipe them into a followup so that it makes sense: [[LOWER Q1:TEXT]] |
UPPER | To uppercase | UPPER TEXT1 | Returns the Modified String Converts the string specified by TEXT1 into uppercase letters. |
If you have a radio question using a response list starting with capital letters and you want to pipe them into a followup in capital letters: [[UPPER Q1:TEXT]] |
PROPER | To proper case | PROPER TEXT1 | Returns the Modified String Converts the string specified by TEXT1 into proper case, capitalizing the first letter of every word. |
If you have a response list and you want to pipe them into a followup with the first letter of each word capitalized: [[PROPER Q1:TEXT]] |
SP | Get the Other/specify value of a response. | For single select questions: QUESTION:RESPONSE:SP For multi select questions, numeric and text: QUESTION_RESPONSE:SP |
Returns the response’s string value. The SP identifier will return the other/specify value given by the respondent to a specific response. This always requires the response name to be given, since there can be multiple other/specify boxes even on a single select question. |
If you need to pipe in the 'Other Specify' text from a… Radio question: [[Q1:6:SP]] Multi Select question: [[Q1_6:SP]] |
IS_QUOTA_CLOSED | Checks to see if a quota is closed | IS_QUOTA_CLOSED ( QUESTION/VARIABLE) | Returns TRUE or FALSE Checks to see if a quota is closed |
You have Q1 asking gender and you have a quota of 50 males and 50 females. Use this formula to use logic to check to see if the quota has closed: IS_QUOTA_CLOSED (Q1) |
QUOTA | Checks specific quota counts | QUOTA ( QUESTION/VARIABLE) | Gives you the count of a specific quota variable. If there is no quota defined, it will be empty | You want to reference the quota limit set for a specific question/variable: Example: You want the limit currently set for Q1 response 2: QUOTA (Q1:2) |
CELL_QUOTA | Checks specific quota limits based on an intersection of rows and columns | CELL_QUOTA ( QUOTA_ROW_QUESTION/VARIABLE, QUOTA_COLUMN_QUESTION/VARIABLE) | For the question/variable, the first parameter must match a question/variable used as a quota row, the second a quota column. It also returns the actual limit, or empty if there's no quota defined. This is not a quota check but rather returns the limit. |
|
RANDOM | Random value | RANDOM | Returns Resulting Number Gets a random value between 0 (inclusive) and 1 (exclusive). |
. |
FLOOR | Floor number | FLOOR NUMBER1 | Returns Resulting Number Removes the decimal piece of a non-integer value. |
. |
CEIL | Ceil number | CEIL NUMBER1 | Returns Resulting Number Always round any decimals up to the next integer. |
. |
ROUND | Round number | ROUND NUMBER1 | Returns Resulting Number Rounds a number to the nearest integer. |
. |
TIME | Current time | TIME | Returns a Date string The current system time is returned in MM/DD/YYYY HH24:MI:SS format, for EST. |
If you need to use the Date/Time |
LOI | Length of Interview | LOI | Returns resulting Number (seconds) Returns the current respondent’s length of interview, or the final they have already finished in seconds. |
If you wanted to term people if they completed the survey in less than 5 minutes: Doing the math in the system: LOI < (5*60) Do the math before hand (5mins X 60sec): LOI < 300 |
TEST | Test user | TEST | Returns String “Y” or “N” Returns the system variable that says if a user is a test user or not. |
You can use this to show or hide questions for testing. Usually to confirm hidden variables to confirm. If you want to skip a question if you are not a test person use: TEST equals NO: TEST="N" TEST doesn't equal YES: TEST!="Y" |
ID or CID | System ID | ID | Returns Resulting Number This is the ID number that the respondent has assigned within the CMIX platform. NOTE: This is not the passcode |
Used for Bulk Updating Data. Also called recoding. |
SORT_DESC | Sort values of a question or variable | SORT_DESC (QUESTION/VARIABLE) | Used to sort response values in descending order | Can be used to set variables to rank responses: Usually used with the AT formula to determine specific rank compared to the rest. Will return the highest rated item in position 1. AT((SORT_DESC(Q1)),1) |
SORT_ASC | Sort values of a question or variable | SORT_ASC (QUESTION/VARIABLE) | Used to sort response values in ascending order | Can be used to set variables to rank responses: Usually used with the AT formula to determine specific rank compared to the rest. Will return the lowest rated item in position 1. AT((SORT_ASC(Q1)),1) |
CONST_e | Euler's Constant | CONST_e | Returns Euler's Constant This is a hard coded value. 2.718281828459 |
Can be used with LOG functions needing Euler's Constant |
LOG | Logarithmic Function | LOG( $BASE, $VALUE) |
Returns the logarithmic function $BASE is the base to be used for the logarithmic function, and $VALUE is the value that you're trying to get the log for |
Examples: LOG (10, 100) would resolve to 2 LOG (2, 8 ) would be 3 |
IS_SIMULATED |
Allows a user to use logic to see if data was run using the Test Data Generation feature | IS_SIMULATED |
Returns TRUE or FALSE Checks to see if data was created using the Test Data Generation feature. |
Examples: You can use say: if IS_SIMULATED and it will be either true or false. You can also say: if IS_SIMULATED == 'true' |
TERMINATION_CODE | Allows a user to use logic tied to a specific termination code | TERMINATION_CODE |
Returns TRUE or FALSE Checks to see if respondent was terminated for a specific reason. This is used primarily for the Export Files feature. |
Examples: You can use say: if TERMINATION_CODE = 1234 |
Things to Keep in Mind
- You cannot use a formula to retrieve the 'STATUS'.