Q & A : Randomization of categorical codes

A few days ago we where asked the following,

Q: I have a categorical question that i would like to randomize the responses. However some of the responses must be randomized , but must not be next to each other.

To randomize the response on a categorical question is easy , we just use the ran keyword, for example ,

Q1 "Text" categorical [1]
    {
    	_01 "1",
    	_02 "2",
    	_03 "3",
    	_04 "4",
    	_05 "5",
    	_06 "6",
    	_07 "7",
    	_08 "8",
    	_09 "9"

    } ran;

but to say that

s "3,4,5" cannot be next to each other is a different story, but it can be done. First off we need to make an array of the 
s and the 
s that cannot be next to each other,
' Codes that can be together
aTexts = split("_01,_02,_06,_07,_08,_09",",")

' Codes not allowed to be together
bTexts = split("_03,_04,_05",",")

Next we are going to produce a list of random numbers between 1 and 8 and then try and place the

s that are not allowed to be together into the final array , checking to see if they are next to each other, and if they are , we will move onto the next random number , until all three 
s are placed.
iCount = 0
' Place 
s not allowed to be next to each other
aRandom = ransequence(0,8,1)
For Each aRan in aRandom
	If ( aRan = 0 ) Then
		If FinalArray[aRan + 1] <> "" Then
			' move on
		Else
			FinalArray[aRan] = bTexts[iCount]
			iCount = iCount + 1
			if ( iCount > 2 ) Then Exit For
		End If
		Goto NextCat
	End If

	If ( aRan = 8 ) Then

		If FinalArray[aRan - 1] <> "" Then
			' move on
		Else
			FinalArray[aRan] = bTexts[iCount]
			iCount = iCount + 1
			if ( iCount > 2 ) Then Exit For
		End If

		Goto NextCat
	End If

	If FinalArray[aRan + 1] <> "" or FinalArray[aRan - 1] <> "" Then
		' move on
	Else
		FinalArray[aRan] = bTexts[iCount]
		iCount = iCount + 1
		if ( iCount > 2 ) Then Exit For
	End If

NextCat:

Next

In memory , if our random set of numbers was "1,2,5,8,7,0,3,6,4" what we would end up with at this stage is an array that looks like this,

FinalArray[0]
FinalArray[1] = 3
FinalArray[2]
FinalArray[3]
FinalArray[4]
FinalArray[5] = 4
FinalArray[6]
FinalArray[7]
FinalArray[8] = 8
FinalArray[8]

so now all we need to do is to randomize the remaining

s and add them to the empty spaces in the array,
' Add the remaining 
s
iCount = 0
For Each aCode in aTexts
	TryAgain:
		If FinalArray[iCount] = "" Then
			FinalArray[iCount] = aCode
		Else
			iCount = iCount + 1
			Goto TryAgain
		End If
Next

and then finally we need to take our new order and set our question order to it.

sLine = ""

For iCount = 0 to 8
	sLine = sLine + FinalArray[iCount] + ","
Next

debug.log(sLine)

Q1.Categories.Order = OrderConstants.oCustom
Q1.Categories.Filter = CCategorical("{" + Left(sLine,Len(sLine)-1) + "}")
Q1.Ask()

And there you have it

 that will randomize and not place certain 

s together. Now after i sent this 

 back to the user, they modified it and produced two generic functions that will do this. If you would like to get your hands on the 

 then you can find the functions in the Code Corner.

1 thought on “Q & A : Randomization of categorical codes”

  1. HI,

    There is another way to do this:

    metadata:
    q1 “Text” categorical [1..]
    {
    _1 “1”,
    _2 “2”,
    _3 “3 – “,
    _4 “4 – “,
    _5 “5 – “,
    _6 “6”,
    _7 “7”,
    _8 “8”,
    _9 “9”

    } ran;
    routing:
    dim a,i,j,k,norm,excl,sortcat
    norm = {_1,_2,_6,_7,_8,_9}
    excl = {_3,_4,_5}
    norm=norm.ran(len(norm))
    excl=excl.ran(len(excl))
    do
    a=sortasc(ransequence(0,8,1,3))
    loop while (clong(format(mid(a,0,1),”b”))+1=clong(format(mid(a,1,1),”b”)))_
    or (clong(format(mid(a,1,1),”b”))+1=clong(format(mid(a,2,1),”b”)))
    j=0
    k=0
    for i=0 to 8
    if i=clong(format(mid(a,j,1),”b”)) then
    sortcat=sortcat+mid(excl,j,1)
    j=j+1
    else
    sortcat=sortcat+mid(norm,k,1)
    k=k+1
    end if
    next
    q1.Categories=sortcat
    q1.Categories.Order=orderconstants.oCustom
    q1.Ask()

    Best regards

Leave a Comment