GSOC 2010 Condition engine

From LimeSurvey Manual

This page is dedicated to the GSOC2010 Condition Engine Project


  • Will I have to implement an RPN parser?

In fact a first version of an RPN parser has already been integrated to LS2, ask macduy for more details (or check Expression engine for conditions to see how it works

Anyway here is an interresting link with algorithms for Infix to Postfix conversions and Postfix to infix conversions.

Also note that we'll not only need a way to do Infox to Postfix conversion (RPN) while defining a condition, but also Postfix to infox conversion in order to display a previously recorded condition and to build the PHP and/or Javascript evaluation code.

  • Why is this a difficult project ?

We want a generic condition engine, able to support multiple kind of conditions. The conditions can be based on static values (predefined string or number) or variable values (context dependant values such as a previous answer, or a user-specific value, ...). This also means we need to define a specific "grammar" to describe conditions operands.

We also want to make the GUI as user friendly as possible so that even if we can design complex conditions, simple conditions design doesn't become a hassle.

Moreover, conditions may have several usage in LS2, not only helping design question branching but also helping design assessments and so on. This means that implementing conditions may require a lot of communication between the "condition engine" team and the other LS2 developpers.

  • What is this "grammar" you're talking about to describe operands ?

Since we have several operands types and since we want to record conditions as a simple RPN string, we  need a grammar (a syntax) to "type" the different kinds of operands:

  • a constant
  • an answer from a previous question
  • a value from the participant's profile (equivalent from the token attribute in LS1)
  • another context specific variable (such as an assessment variable, or the result of a predefined function such as the sum of previous numerical answers).

This is not a proposal for a syntax, but just a stupid example of a condition in RPN using a syntax to type operands:

 {ANSWER: Q0001} {ANSWER: Q0002} >= {ANSWER: Q1234} {CONST: Yes} = AND

  • Do I have to understand how LS1 implements conditions ?

Understanding LS1 conditions is important because it will show you what is currently possible to do.

However you don't have to understand how everything is implemented.

Please carefully read The conditions documentation for LS1

I would highly recommend setting several surveys with conditions and see how it works:

- for question per page surveys, for group by group surveys, for all-in-one surveys: note how condition evaluation is either done on the server side, or on the client side

- also try several kind of conditions:

- conditions on previous answer compared to a static value or to another previous answer, conditions on token (user-dependant value),

- understand the difference between a condition using "not answer" and "not displayed" (the latest is not supported in LS1)

- think about a strategy for LS2 to better handle the "Chained conditions" issue and other gotchas from LS1 conditions

  • How does the condition engine relates to other parts of the LS2 core ?

Conditions will be used in a variety of ways: question branching, assessments, ...

What this means is that a condition will be mapped to an action.

For instance:

- in a question branching context: map the conditions to the "Display question XXX" action

- in an assessment context: map condition to the "update assessment score YYY by exectuing the following arithmetic operation ..."

For the question branching action, the condition engine, must:

- understand how answers are stored (either in SESSION, in DB or even in the HTML page if the evaluation is done by Javascript)

- understand how to access participant's specific data

- understand how LS2 handles mandatory questions and how to alter this behaviour if the question is hidden

- be able to reset an answer to "No answer" if a previously answered question becomes hidden because the participant changed his mind and modified a previous answer (see the deletenonvalue parameter).

- understand how to mark a question as "Not displayed"

  • I want to jump into LS2 code, what should I check ?

The following is a first answer I (lemeur) gave to the #limesurvey channel

<lemeur> First you must be aware of the fact that I implemented part of LS1 conditions and am a LS1 core developper so I'm very familiar with LS1.

         However I'm not very familiar with the LS2 codebase yet

         So I have several questions regarding LS2 for you, my future GSOC participant, regarding how questions are implemented in LS2.

         - are "mandatory" questions implemented and how

         ==> mandatory questions: questions that you can't skip (you can't proceed untill you've answered)

         ==> This is important to understand this, because when a mandatory question is hidden by conditions, you have to alter the mandatory property

         - Is there a "No answer was given" code recorded to DB

         ==> I mean, is there a way to know if teh question was displayed but no answer given

         ==> this must be different from "no answer recorded because the question was not displayed"

[22:31]    <lemeur>    this is the kind of questions I'm longing to know about LS2 because it will have so much implications for the Conditions engine project

[22:32]    <lemeur>    Another question regarding participants

<lemeur> Now regarding participants, in LS2 they are managed in a complete different way than what was done for LS1

         and since conditions can be based on information from the participant's profile, we need to understand how to reach participant's data from within the conditions engine we also need to understand if accessing the participants data is possible for all kind of surveys.

         - For instance is it possible for Anonymous surveys ? (should not)

<lemeur> You may now understand why I think the conditions engine has so much implications and dependances on the rest of the LS2 core