Have an idea?

Visit Sawtooth Software Feedback to share your ideas on how we can improve our products.

How do I refer to CBC attributes/levels in Perl?

I'm trying to figure out how I can get the displayed level values of each attribute for each option in a CBC exercise in Perl. Basically, if this is the particular randomized task a respondent is looking at:

                            Option 1                 Option 2                 Option 3
                        ________________________________________
Attribute 1 |     Level 2          |         Level 1           |          Level 2       |
Attribute 2 |     Level 1          |         Level 1           |          Level 4       |
Attribute 3 |     Level 3          |         Level 2           |          Level 3       |
Attribute 4 |     Level 2          |         Level 1           |          Level 1       |

I want to be able to know that they're seeing level 2 for attribute 1 in option 1.

I have no experience with Perl specifically and very little experience doing anything more complicated in SSI, so I'm a little lost looking through some of the documentation. The exercise is called "CBC," so I tried using CBCAttributeValue("CBC",1,1) to get the value of the level for option 1, attribute 1, but that didn't work out, so I'm reaching out here for help.
asked Jun 30, 2016 by ldulude (205 points)

2 Answers

+2 votes
 
Best answer
I think you want to use CBCDesignLevelText or CBCDesignLevelValue.  The former will return the text of the level; the latter will return the position of the level.  Here's an example of each in SSI Script:

[% CBCDesignLevelText(CbcExer_Random1, 1, 1) %]
[% CBCDesignLevelValue(CbcExer_Random1, 1, 1) %]


Or how they would be used in unverified Perl:

CBCDESIGNLEVELTEXT('CbcExer_Random1', 1, 1)
CBCDESIGNLEVELVALUE('CbcExer_Random1', 1, 1)


In either case, "CbcExer" should be replaced with the exercise name and "Random1" should be replaced with the current question in the exercise.

If you tell me more about what you need this Perl code to do, I'd be happy to help you write up the code.
answered Jun 30, 2016 by Zachary Platinum Sawtooth Software, Inc. (121,725 points)
selected Jun 30, 2016 by ldulude
If you don't mind helping, I would really appreciate it. It sounds like the above might not work for my situation because it's specific to each question, but I need it to work for all questions in the exercise.

There are a couple of things I'm trying to do:
1. I'm trying to create a summed total price. I know the prices for each level of each attribute and want to be able to add up the prices so I can display the total price (based on the prices for the displayed levels in each attribute) at the bottom of each option.
For example, if I know based on the levels displayed that the prices for attributes 1-4 in option 1 are $10, $7, $18, and $20, I could display $55 at the bottom of the option. I know you can do something like this pretty easily in ACBC, but for other reasons, my team wants to use CBC for this particular study.

2. I want to be able to multiply the total price by the number of people in your party, so if you said earlier in the study that you have 2 people, I'd want to be able to multiply that $55 by 2: $110.
Alright, I've got the Perl finished.  Let's go step-by-step.  Here's the base code that will calculate the price of the first concept:

[% Begin Unverified Perl
my $concept = 1;

my $price = 0;

# Attribute 1
my $att1 = CBCDESIGNLEVELVALUE(QUESTIONNAME(), $concept, 1);
if ($att1 == 1) { $price += 1; }
elsif ($att1 == 2) { $price += 2; }
elsif ($att1 == 3) { $price += 3; }

# Attribute 2
my $att2 = CBCDESIGNLEVELVALUE(QUESTIONNAME(), $concept, 2);
if ($att2 == 1) { $price += 10; }
elsif ($att2 == 2) { $price += 20; }
elsif ($att2 == 3) { $price += 30; }

# Attribute 3
my $att3 = CBCDESIGNLEVELVALUE(QUESTIONNAME(), $concept, 3);
if ($att3 == 1) { $price += 100; }
elsif ($att3 == 2) { $price += 200; }
elsif ($att3 == 3) { $price += 300; }

# Party multiplier
$price *= GETVALUE('NumericQ');

# Return
return $price;
End Unverified %]


The first change you should make is to replace "NumericQ" with the name of the question that contains the number of people in the party.

Next, you should update the attribute section with your price information.  I started with 3 attributes with 3 levels each, but you can repeat the patterns to meet your number of attributes and levels.

The code is now complete for the first concept.  For the other concepts, you can use the same code with line 2 updated.
Thank you so much! It's amazing how you can see code like this and be able to read it but be unable to produce it.

So QUESTIONNAME() pulls the current CBC exercise name?

How would you recommend incorporating this? Putting it in the footer somehow? Or making a final attribute that is the summed price and finding a way to pull the concept number like how you pulled the question name?
Yes, QUESTIONNAME() returns the name of the current question, which will be "CBC_Random1", "CBC_Fixed2", etc. in this case.

I'd be hesitant to use a sort of "dummy" attribute for summed price, as I don't know what effects that might have on analysis.  It may actually be totally fine, but I don't know for sure.

I would go the footer route.  JavaScript / jQuery can be used to add a new row to the table, then you can use the unverified Perl inside the JS to get the values that should be put in the table.
Makes sense -- thank you again!
I just tried to make edits to this and it's returning a 0 instead of a summed price -- did I maybe edit incorrectly?

In this test conjoint I'm using, I have 3 attributes. Attribute 1 has 2 levels, attribute 2 has 5 levels, and attribute 3 has 3 levels.

Here's the code I ended up with (just for the first concept to test it out and without an attempt at the party multiplier):
[% Begin Unverified Perl
my $concept = 1;
my $price = 0;
 
# Attribute 1
my $att1 = CBCDESIGNLEVELVALUE(QUESTIONNAME(), $concept, 1);
if ($att1 == 1) { $price += 120; }
elsif ($att1 == 2) { $price += 150; }
 
# Attribute 2
my $att2 = CBCDESIGNLEVELVALUE(QUESTIONNAME(), $concept, 2);
if ($att2 == 1) { $price += 100; }
elsif ($att2 == 2) { $price += 200; }
elsif ($att2 == 3) { $price += 200; }
elsif ($att2 == 4) { $price += 200; }
elsif ($att2 == 5) { $price += 150; }
 
# Attribute 3
my $att3 = CBCDESIGNLEVELVALUE(QUESTIONNAME(), $concept, 3);
if ($att3 == 1) { $price += 50; }
elsif ($att3 == 2) { $price += 0; }
elsif ($att3 == 3) { $price += 55; }
 
# Return
return $price;
End Unverified %]


It might also be relevant to say that I just threw this in the page header (Survey Settings > Page Header and Footer > Header), starting with the Begin Unverified Perl tag. Do I need to do anything additional to make the script work? I assume it's probably working since it did return a value, just not the right value.
The problem is that QUESTIONNAME doesn't know what name to return when it is called in the page header.  This code needs to go in one of the CBC settings (e.g., the CBC footer) in order to work.
Works perfectly in the CBC footer -- thank you!
0 votes
Hey Laura,

This is possible using advanced perl coding in Sawtooth.

We need to associate a value against every level. On the page where we are showing task, we need to extract the level displayed, sum their value and display summed price like we get in ACBC.

Once you have extracted the value, you can do any operation on the same and display on task smartly.

We recently did a study in which did this type of mathematics with price as well as deducted the price as per discount shown as per design:

Demo link:

https://websurvey.sawtoothsoftware.com/summed/cgi-bin/ciwweb.pl?studyname=summed

Regards,
Saurabh
answered Jun 30, 2016 by Saurabh Aggarwal Gold (31,425 points)
...