Welcome, Guest
Username: Password: Remember me

TOPIC: Ultra complicated logic (i.e. Long shot it will work)

Ultra complicated logic (i.e. Long shot it will work) 3 years 1 month ago #63357

  • vadindot
  • vadindot's Avatar
  • OFFLINE
  • Senior Lime
  • Posts: 51
  • Thank you received: 1
  • Karma: 0
Okay, this is possibly the most complicated thing I have asked of the Limesurvey community, I am not holding my breath that it can be done.

Here are 6 questions from a survey, they all have the same answers listed below
Q4 When you think of Stouts or Porters what brand comes to mind first? (List-Radio)
Q6 What others come to mind? (Multiple - checkbox)
Q7 Which have you drunk in the past 3 months? (Multiple - checkbox)
Q15 Which Stout or Porter have you seen advertisements for in the past 3 months? (Multiple - checkbox)
Q19 Which Stout or Porter have you seen in promoted in pubs/bars in the past 3 months? (Multiple - checkbox)
Q22 (only asked if Q21=2) What Stout or Porter is your favorite? (List-Radio)

Answer List:
1 Guiness Draught
2 Murphy's Stout
3 Samuel Adams Imperial Stout
4 Beamish Stout
5 Courage Imperial Russian Stout
6 Marston's Oyster Stout
7 Rouge Ale's Chocolate Stout
8 Porterhouse Brewing Company Plain Porter
9 Don't remember
10 Other (Specify)

Q28 and Q29 are 2 arrays which are going to be asked of two brands. Here is the logic as to how it gets decided, this is in order of how they are to be chosen:

Q28:
1. If Guiness (1) is mentioned in any question, this is the brand for 28, if not...
2. If Murphy's (2) Sam Adams (3) or Beamish (4) are mentioned in Q4 Q6 Q7 Q15 or Q19, randomly select one, if not...
3. Randomly select another brand mentioned in Q4 Q6 Q7 Q15 or Q19 (except for Don't know or Other)

Q29:
1. Response to Q22 if it is not Guiness or Don't Know, if not....
2. If Murphy's (2) Sam Adams (3) or Beamish (4) are mentioned in Q4 Q6 Q7 Q15 or Q19, randomly select one that hasn't already been picked for Q28, if not...
3. Randomly select another brand mentioned in Q4 Q6 Q7 Q15 or Q19 (except for Don't know or Other) that wasn't chosen for Q28
The administrator has disabled public write access.

Re: Ultra complicated logic (i.e. Long shot it will work) 3 years 1 month ago #63362

  • TMSWhite
  • TMSWhite's Avatar
  • OFFLINE
  • LimeSurvey Team
  • Posts: 759
  • Thank you received: 82
  • Karma: 36
vadindot-

Someone else will have to answer about whether/how this could be done using LimeSurvey 1.91+.

Below is how you would do it with the ExpressionManager extensions, which may be available as early as 1.92. I also put this response in this thread so that we have all of our really hard logic examples in one place. See that thread for more background information on ExpressionManager.
vadindot wrote:
Okay, this is possibly the most complicated thing I have asked of the Limesurvey community, I am not holding my breath that it can be done.

Here are 6 questions from a survey, they all have the same answers listed below
Q4 When you think of Stouts or Porters what brand comes to mind first? (List-Radio)
Q6 What others come to mind? (Multiple - checkbox)
Q7 Which have you drunk in the past 3 months? (Multiple - checkbox)
Q15 Which Stout or Porter have you seen advertisements for in the past 3 months? (Multiple - checkbox)
Q19 Which Stout or Porter have you seen in promoted in pubs/bars in the past 3 months? (Multiple - checkbox)
Q22 (only asked if Q21=2) What Stout or Porter is your favorite? (List-Radio)

Answer List:
1 Guiness Draught
2 Murphy's Stout
3 Samuel Adams Imperial Stout
4 Beamish Stout
5 Courage Imperial Russian Stout
6 Marston's Oyster Stout
7 Rouge Ale's Chocolate Stout
8 Porterhouse Brewing Company Plain Porter
9 Don't remember
10 Other (Specify)

Q28 and Q29 are 2 arrays which are going to be asked of two brands. Here is the logic as to how it gets decided, this is in order of how they are to be chosen:

Q28:
1. If Guiness (1) is mentioned in any question, this is the brand for 28, if not...
2. If Murphy's (2) Sam Adams (3) or Beamish (4) are mentioned in Q4 Q6 Q7 Q15 or Q19, randomly select one, if not...
3. Randomly select another brand mentioned in Q4 Q6 Q7 Q15 or Q19 (except for Don't know or Other)

It looks as though Q28 is always asked - you just need to tailor the text of the question. So, I'd create three hidden Equation questions to address the broad criteria #s 1-3.
GuinessMentioned = (count(Q4==1, Q6==1, Q7==1, Q15==1, Q19==1, Q22==1) >= 1)
SecondTierMentioned = (count((Q4>=2 and Q4<=4), (Q6>=2 and Q6<=4), (Q7>=2 and Q7<=4), (Q15>=2 and Q15<=4), (Q19>=2 and Q19<=4), (Q22>=2 and Q22<=4)) >= 1)
PickBrand = if(GuinessMentioned,1,if(SecondTierMentioned,(floor(rand() * 2.999)+ 2),(floor(rand() * 3.999) + 5)))

One of the functions I expect to add to ExpressionManager is this:
FunctionSyntaxDescription
getAnsOptiongetAnsOption(X)
getAnsOption(X,Y)
returns the text corresponding to the selected option for node X
returns the text corresponding to the option at index Y of node X

So, using that function, the text for Q28 might be (depending upon what you're really asking):
Here are some more questions about {getAnsOption(Q4,PickBrand)}.  
vadindot wrote:
Q29:
1. Response to Q22 if it is not Guiness or Don't Know, if not....
2. If Murphy's (2) Sam Adams (3) or Beamish (4) are mentioned in Q4 Q6 Q7 Q15 or Q19, randomly select one that hasn't already been picked for Q28, if not...
3. Randomly select another brand mentioned in Q4 Q6 Q7 Q15 or Q19 (except for Don't know or Other) that wasn't chosen for Q28

As I've seen too often in textbooks, "The solution to this problem is left as an excercise for the student".

Seriously however, this is no harder than the criteria for Q28.

/Tom
Last Edit: 3 years 1 month ago by TMSWhite. Reason: missing link
The administrator has disabled public write access.

Re: Ultra complicated logic (i.e. Long shot it will work) 3 years 1 month ago #63397

  • tpartner
  • tpartner's Avatar
  • OFFLINE
  • LimeSurvey Team
  • Posts: 4133
  • Thank you received: 763
  • Karma: 347
vadindot, are the questions on separate pages?
Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.

LimeSurvey is open-source and run entirely by volunteers so please consider donating to support the project.
Last Edit: 3 years 1 month ago by tpartner.
The administrator has disabled public write access.

Re: Ultra complicated logic (i.e. Long shot it will work) 3 years 1 month ago #63401

  • vadindot
  • vadindot's Avatar
  • OFFLINE
  • Senior Lime
  • Posts: 51
  • Thank you received: 1
  • Karma: 0
yes they are all on separate pages and in separate groups
The administrator has disabled public write access.

Re: Ultra complicated logic (i.e. Long shot it will work) 3 years 1 month ago #63436

  • tpartner
  • tpartner's Avatar
  • OFFLINE
  • LimeSurvey Team
  • Posts: 4133
  • Thank you received: 763
  • Karma: 347
Okay, I couldn't resist the challenge. The script is a little heavy but here's a JavaScript solution with the following caveates:

- These scripts are designed for plain array questions (array-flexible-row).
- All answer/sub-questions must be identical.
- The arrays must be on their own page - except for a hidden text question - see below.
- Survey is in group-by-group mode.

1) Set up your survey to use JavaScript.

2) Add a text question to each array group to store the label value for the shown row. We'll hide these with JavaScript.

3) Add the following script to the source of one of the questions in the Q28 group. Replace all SGQA values in rows 5-10.
<script type="text/javascript" charset="utf-8">
 
	$(document).ready(function() {
 
		var q4 = '{INSERTANS:11111XG4XQ4}'; // SGQA of q4
		var q6 = '{INSERTANS:11111XG6XQ6}'; // SGQA of q6
		var q7 = '{INSERTANS:11111XG7XQ7}'; // SGQA of q7
		var q15 = '{INSERTANS:11111XG15XQ15}'; // SGQA of q15
		var q19 = '{INSERTANS:11111XG19XQ19}'; // SGQA of q19
		var q22 = '{INSERTANS:11111XG22XQ22}'; // SGQA of q22
 
		// Hide all rows of the array
		$('tbody[id^="javatbd"]').hide();
		// Hide the hidden text question
		$('.text-short').hide();
 
		var ansString1 = q4+', '+q6+', '+q7+', '+q15+', '+q19+', '+q22;
		var ansString2 = q4+', '+q6+', '+q7+', '+q15+', '+q19;
 
		var match1 = /Guiness Draught/;
		var match2 = /(Murphy's Stout|Samuel Adams Imperial Stout|Beamish Stout)/;
		var arr2 = new Array("Murphy's Stout","Samuel Adams Imperial Stout","Beamish Stout");
		var arr3 = new Array("Courage Imperial Russian Stout","Marston's Oyster Stout","Rouge Ale's Chocolate Stout", "Porterhouse Brewing Company Plain Porter");
		var prevText = $('.text-short input.text').val();
 
		// Scenario 1
		if(match1.test(ansString1)) {
			// Show the first row if we find "Guiness Draught" in the answers and uncheck everything else
			$('tbody[id^="javatbd"]:contains("Guiness Draught")').show().addClass('array1');
			$('tbody[id^="javatbd"]:hidden input.radio').attr('checked', false);
		}
		// Scenario 2
		else if(match2.test(ansString2)) {
			// Filter out all options that were not selected in Q4 Q6 Q7 Q15 or Q19
			$(arr2).each(function(i){
				if (ansString2.indexOf(this) < 0) {
					var value = this;
					arr2 = jQuery.grep(arr2, function (a) { return a != value; });
				}
			});
			// Check for previous visit with valid row shown
			$(arr2).each(function(i){
				if (this == $.trim(prevText)) {
					$('tbody[id^="javatbd"]:contains("'+$.trim(prevText)+'")').show();
					$('tbody[id^="javatbd"]:hidden input.radio').attr('checked', false);
				}
			});
			// Okay, nothing valid from previous visit, pick a random option from those selected in Q4 Q6 Q7 Q15 or Q19
			if($('tbody[id^="javatbd"]:visible').length < 1) {
				// Random number between 0 and the length of the edited array
				var randNum = Math.floor(Math.random()*arr2.length);
				var labelText = arr2[randNum];
				$('tbody[id^="javatbd"]:contains("'+labelText+'")').show();
				$('tbody[id^="javatbd"]:hidden input.radio').attr('checked', false);
			}
		}
		// Scenario 3
		else {
			// Filter out all options that were not selected earlier
			$(arr3).each(function(i){
				if (ansString2.indexOf(this) < 0) {
					var value = this;
					arr3 = jQuery.grep(arr3, function (a) { return a != value; });
				}
			});
			// Check for previous visit with valid row shown
			$(arr3).each(function(i){
				if (this == $.trim(prevText)) {
					$('tbody[id^="javatbd"]:contains("'+$.trim(prevText)+'")').show();
					$('tbody[id^="javatbd"]:hidden input.radio').attr('checked', false);
				}
			});
			// Okay, nothing valid from previous visit, pick a random option from those selected in Q4 Q6 Q7 Q15 or Q19
			if($('tbody[id^="javatbd"]:visible').length < 1) {
				// Random number between 0 and the length of the edited array
				var randNum = Math.floor(Math.random()*arr3.length);
				var labelText = arr3[randNum];
				$('tbody[id^="javatbd"]:contains("'+labelText+'")').show();
				$('tbody[id^="javatbd"]:hidden input.radio').attr('checked', false);
			}
		}
 
		// Fix up the row display
		$('tbody[id^="javatbd"]:visible tr').removeClass('array1').addClass('array2');
 
		// Load the hidden question
		$('.text-short input.text').val($('tbody[id^="javatbd"]:visible th').text());
 
	});
 
</script>

4) Add the following script to the source of one of the questions in the Q29 group. Replace all SGQA values in rows 5-11. This is the same as the previous script with additions at lines 11, 36 and 63 to eliminate the row displayed in Q28.
<script type="text/javascript" charset="utf-8">
 
	$(document).ready(function() {
 
		var q4 = '{INSERTANS:11111XG4XQ4}'; // SGQA of q4
		var q6 = '{INSERTANS:11111XG6XQ6}'; // SGQA of q6
		var q7 = '{INSERTANS:11111XG7XQ7}'; // SGQA of q7
		var q15 = '{INSERTANS:11111XG15XQ15}'; // SGQA of q15
		var q19 = '{INSERTANS:11111XG19XQ19}'; // SGQA of q19
		var q22 = '{INSERTANS:11111XG22XQ22}'; // SGQA of q22
		var q28Hidden = '{INSERTANS:11111XG28XQHidden}'; // SGQA of the hidden text question in q28's group
 
		// Hide all rows of the array
		$('tbody[id^="javatbd"]').hide();
		// Hide the hidden text question
		$('.text-short').hide();
 
		var ansString1 = q4+', '+q6+', '+q7+', '+q15+', '+q19+', '+q22;
		var ansString2 = q4+', '+q6+', '+q7+', '+q15+', '+q19;
 
		var match1 = /Guiness Draught/;
		var match2 = /(Murphy's Stout|Samuel Adams Imperial Stout|Beamish Stout)/;
		var arr2 = new Array("Murphy's Stout","Samuel Adams Imperial Stout","Beamish Stout");
		var arr3 = new Array("Courage Imperial Russian Stout","Marston's Oyster Stout","Rouge Ale's Chocolate Stout", "Porterhouse Brewing Company Plain Porter");
		var prevText = $('.text-short input.text').val();
 
		// Scenario 1
		if(match1.test(ansString1)) {
			// Show the first row if we find "Guiness Draught" in the answers and uncheck everything else
			$('tbody[id^="javatbd"]:contains("Guiness Draught")').show().addClass('array1');
			$('tbody[id^="javatbd"]:hidden input.radio').attr('checked', false);
		}
		// Scenario 2
		else if(match2.test(ansString2)) {
			// Remove the option shown in Q28
			arr2 = jQuery.grep(arr2, function (a) { return a != $.trim(q28Hidden); });
			// Filter out all options that were not selected in Q4 Q6 Q7 Q15 or Q19
			$(arr2).each(function(i){
				if (ansString2.indexOf(this) < 0) {
					var value = this;
					arr2 = jQuery.grep(arr2, function (a) { return a != value; });
				}
			});
			// Check for previous visit with valid row shown
			$(arr2).each(function(i){
				if (this == $.trim(prevText)) {
					$('tbody[id^="javatbd"]:contains("'+$.trim(prevText)+'")').show();
					$('tbody[id^="javatbd"]:hidden input.radio').attr('checked', false);
				}
			});
			// Okay, nothing valid from previous visit, pick a random option from those selected in Q4 Q6 Q7 Q15 or Q19
			if($('tbody[id^="javatbd"]:visible').length < 1) {
				// Random number between 0 and the length of the edited array
				var randNum = Math.floor(Math.random()*arr2.length);
				var labelText = arr2[randNum];
				$('tbody[id^="javatbd"]:contains("'+labelText+'")').show();
				$('tbody[id^="javatbd"]:hidden input.radio').attr('checked', false);
			}
		}
		// Scenario 3
		else {
			// Remove the option shown in Q28
			arr3 = jQuery.grep(arr3, function (a) { return a != $.trim(q28Hidden); });
			// Filter out all options that were not selected earlier
			$(arr3).each(function(i){
				if (ansString2.indexOf(this) < 0) {
					var value = this;
					arr3 = jQuery.grep(arr3, function (a) { return a != value; });
				}
			});
			// Check for previous visit with valid row shown
			$(arr3).each(function(i){
				if (this == $.trim(prevText)) {
					$('tbody[id^="javatbd"]:contains("'+$.trim(prevText)+'")').show();
					$('tbody[id^="javatbd"]:hidden input.radio').attr('checked', false);
				}
			});
			// Okay, nothing valid from previous visit, pick a random option from those selected in Q4 Q6 Q7 Q15 or Q19
			if($('tbody[id^="javatbd"]:visible').length < 1) {
				// Random number between 0 and the length of the edited array
				var randNum = Math.floor(Math.random()*arr3.length);
				var labelText = arr3[randNum];
				$('tbody[id^="javatbd"]:contains("'+labelText+'")').show();
				$('tbody[id^="javatbd"]:hidden input.radio').attr('checked', false);
			}
		}
 
		// Fix up the row display
		$('tbody[id^="javatbd"]:visible tr').removeClass('array1').addClass('array2');
 
		// Load the hidden question
		$('.text-short input.text').val($('tbody[id^="javatbd"]:visible th').text());
 
	});
 
</script>
Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.

LimeSurvey is open-source and run entirely by volunteers so please consider donating to support the project.
Last Edit: 3 years 1 month ago by tpartner.
The administrator has disabled public write access.
Moderators: ITEd
Time to create page: 0.250 seconds
Donation Image