Examples

First Example

Here is a very simple example of a qscript program. It demonstrates 2 types of questions:

	simple_example_1 {
	q1 "q1. This is a Range Question"
		sp int32_t (1-3, 4, 7-9);

	stubs agree5 = 
			" strongly disagree" 1
			" disagree " 2
			" neutral " 3
			" agree " 4
			"strongly agree" 5;
	q2 "q2. This is a named stub question"
		sp int32_t agree5;

	q3 "q3. This is a multicoded Range stub question"
		mp(5) int32_t (1-20);

	stubs vegetables =
		"egg plant/brinjal" 1
		"tomatoes" 2
		"potatoes" 3
		"carrots" 4
		"okra" 5
		"cauliflower" 6
		"beetroot" 7;


	q4 "q4. This is a multicoded Named stub question"
		mp(3) int32_t vegetables;
	}
	

As you can see in the above example - all questions have the same format:

Second Example: Mutually Exclusive Codes

This program demonstrates how to setup mutually exclusive codes for Range and Named Stub Questions

	inp_mutex {

	q1 "Q1. This is question 1" mp(4) int32_t (1,2,3,4, 97, 98, 99) mutex (98, 99);

	stubs dummy1 = 
		"stub 1" 1
		"stub 2" 2
		"stub 3" 3 
		"Other stub 97" 97
		"Refused stub 98" 98 mutex
		"DK stub 99" 99 mutex;
	q2 "Q2. This is question 1" mp(4) int32_t dummy1;

	}
	
In the above example - the codes 98 and 99 will not be allowed with any other code, although q1 and q2 are multi-coded questions.

Simple If Condition

	inp_if_else_branches {
		// test to see how to handle
		// undo / redo , visit previous questions 
		// in case of if conditions
		q1 "Q1. " sp int32_t (1,2,3,4);


		if(q1 in (1,2))
			q2 "Q2. " sp int32_t (5,6);
		else 
			q3 "Q3. " sp int32_t (5,6);

		if (q1 in (3)) {
			q3_2 "q3_2" sp int32_t (1-5);
		} else {
			1;
		}
		
		q4 "Q4. " sp int32_t (1,2,3,4,5,6);
		if(q4 in (1,2)){
			q5 "Q5. " sp int32_t(7,8);
			q6 "Q6. " sp int32_t(7,8);
		} else if (q4 in (3)) {
			q7 "Q7. " sp int32_t(7,8);
			q8 "Q8. " sp int32_t(7,8);
		} else if (q4 in (4) ){
			q9 "Q9. " sp int32_t(7,8);
			q10 "Q10. " sp int32_t(7,8);
		} else {
			q11 "Q11 " sp int32_t(1, 3);
		}
	}
	

The above example introduces the "if" conditional and the operator "in". The syntax for the if conditional is just like "C"-syntax. In the above example, on the right hand side of operator "in" we have a range set. The left hand side has the question being tested. It is best to use this syntax when the question is single coded - as is the case for "q1".

In the if condition for question q3_2, you can see a redundant else clause which just contains "1;" in the else block. This redundant else clause is necessary for now, to help the compiler generate the correct code to clear the answer at q3_2 if the question was not taken. If this else block is not put by the programmer, the compiler will flag an error, displaying the if condition which is missing the else block and suggest the above fix.

The if conditions on q4 demonstrate "else if" clauses.

For Loops
	inp_for {
		int32_t i1=0;
		int32_t i2=0;

		for(i1=0; i1 < 5; i1=i1+1){
			if (i1 > 2) {
				for(i2=0; i2 < 2; i2=i2+1){
					q1 "Q1. This is question 1" sp int32_t (1,2,3,4);
				}
			}
			for(i2=0; i2 <3; i2=i2+1){
				q2 "Q2. This is question 1" sp int32_t (1,2,3,4);
			}

			q3 "Q1. This is question 3" sp int32_t (1,2,3,4);
		}
	}
	

The above example demonstrates a for loop. It also shows how to declare an integer variable and initialize it. As you can see, it is possible to nest for loops and the language can handle this. There is a restriction on the bounds of the for loop - it has to be a constant integer, a variable will not do. So, for example this will work

	for (i=0; i<2*3; i=i+1)
	
but this will not work
	int32_t bounds=10;
	for (i=0; i<bounds; i=i+1)
	
because "bounds" is a not a constant.

In the above example, note the condition on i1 - greater than 2 i.e. q1 gets asked when i1 == 3. Also note that arrays count from zero and i1==0 in the loop initially. Hence, q1 will only be asked on the 4th (i1==3) and 5th (i1==3) iterations of the loop. Also, q1 will have a total of 10 iterations, q2 a total of 15 iterations and q3 a total of 5 iterations.

A more complicated example using for loops
inp_for_more_complicated_example {

stubs fuel_types=	
"Diesel" 1
"Petrol" 2
"CNG" 3
"LPG" 4;

S5	"What fuel do you use in your vehicle? What is the average monthly consumption ?"
	mp(4) int32_t fuel_types;
	int32_t i1=0;

	for (i1=0; i1 < 4; i1=i1+1) {
		int32_t code = i1+1;
		if ( (code) in S5 ) {
s5_1			"Average litres/kgs"
			sp int32_t (1-10000);
s5_2			"Average Price"
			sp int32_t (1-1000000);
		} else {
			1;
		}
	}


	int32_t sum=0;
	for (i1=0; i1 < 6; i1=i1+1) {
q1		"what is the approximate percentage share of different oil companies?"
		sp int32_t (0-100);
		sum = sum + q1[i1];
	}
	if (sum != 100) {
		clear (q1[0]);
	}
}

	

In the above example, code we want to probe further, if a respondent is using a certain type of fuel. The for loop indices run from 0 to 3, but the codes for qs5 are from 1 to 4. we create a variable "code" that is set to the value that we want. Also note that you can create variables like "i1" anywhere in the script.

Note, that in the above example, in the test

		if ( (code) in S5 ) 
	
"code" appears on the left hand side of operator "in" and the question on the right hand side. To understand operator "in", it always checks the left hand side is a subset of the right hand side. In this example, S5 is a multi-coded question. Contrast this case with the Simple If Condition demo, where we had "q1 in (1,2)" but q1 was single coded. In, this particular case "(code) in S5" the expression "(code)" is not a SET, like in the Simple If Condition, rather it is an expression. So if we want to check multiple codes, we need to split it up into multiple tests. i.e. this will not compile
			if ( (code1, code2) in S5) 
		
It needs to be split up like this:
			if ( (code1) in S5 && (code2) in S5)
		

In the second part of the above example, we want to ensure that the percentages add up to 100. The comparison of sum with 100 and clearing the response if it doesn't match is enough to achieve this functionality. At this point of time you cannot add an error message to the clear statement, but a future version will allow you to pass an error message. Also note that single coded questions can directly be used in arithmetic operations - for example:

 sum = sum + q1[i1] 

Masking Question Codes under Certain conditions
	inp_mask_stubs {

		stubs make =
			"toy " 1
			"nis " 2
			"gm " 3
			"frd " 4
			"vlv " 5;

		stubs model = 
			"cor " 1
			"ech " 2
			"yrs " 3
			"tii " 4
			"snny" 5
			"optr" 6
			"vctr" 7
			"ikn" 8
			"endv" 9
			"s40" 10
			"s60" 11;
		unset(model);

	q1	"q1"
		sp int32_t (1-4);

	q2	"q2:make"
		sp int32_t make;

		if (q2==1) {
			setadd(model, (1-3));
		}
		if (q2==2) {
			setadd(model, (4,5));
		}
		if (q2==3) {
			setadd(model, (6,7));
		}
		if (q2==4) {
			setadd(model, (8,9));
		}
		if (q2==4) {
			setadd(model, (10,11));
		}

	q3	"q3:model"
		sp int32_t model;

	q4	"q4"
		sp int32_t (5-8);

	}
	

Consider the above example: in automotive studies, an often used technique is to ask for the make, and then the model. The setadd model allows you to selectively enable a code. First, you unmask all codes in the stub list using the "unset" statement: in the above example it is unset(model). Then, looking at the response at q1, we selectively set the mask for model, before q2.

There is also an setdel statement, which you can find the "inputs" directory distributed along with the compiler source code.