1.

제목에 (53/53) 이라고 마지막 숫자를 채워넣었다.
부서를 돌아다니며 내가 알고 있는 여러분들께
인사를 드렸다.

이렇게 끝나는구나. 마지막은 다소 허무한, 마지막 날.
송별회. 소중한 사람들.
나중에 다시 만날 수 있을까요?
여러분들이 마련해주신 소중한 자리, 소중한 선물.
그렇게 인턴생활 종료...

안녕- TNS RI☆

저작자 표시
신고
블로그 이미지

카펠

1차 목표를 이룬, 이제는 다가올 기회에 대비하는 나 그리고 나의 공간.

1.

8시간만에 다시 회사 도착. 오늘 새벽 1시에도 여기 있었으니까. 하하 기분이 이상하다.
이번주는 프로젝트에 참여하는 기간이 길어서 따로 포스팅 할 만한 소재가 없었다.

저작자 표시
신고
블로그 이미지

카펠

1차 목표를 이룬, 이제는 다가올 기회에 대비하는 나 그리고 나의 공간.

1. 

정규식쪽으로 가닥을 잡았다.
문항번호는 AQ1, AQ2, AQ3, AQ4 ... 이렇게 나간다.
그리고 만약 AQ33번이 3DGrid문항이라면,
내부의 문항Object들은
AQ33_1st
AQ33_2nd
AQ33_3rd
AQ33_4th
...
이렇게 나가게된다.
( ※ 순위를 묻는 문항에만 해당)
그렇다면 내부문항들을 참조할 수 있는 이름들은
3DGridQuestionName + _ + num + st,nd,rd,th,th,th,th...
이렇게 나가게 되는데, 저 조합을 일반화 하면 되겠다.

우선 맨 앞의 3DGridQuestionName.
CurrentForm()을 사용하기로 했다.
(아래는 CurrentForm()에 대한 자세한 설명)

CurrentForm is used in validation code (or in functions called from validation code) and returns the
question ID (string) of the question currently being validated. From Confirmit 9.0 this is also true for
questions inside 3D grids: Used inside the validation code field of one of the questions inside the 3D
grid, it will give the question id of that question instead of the id of the 3D grid itself.
You can use this to write generic code that can be reused without having to change the question ID.

자, 우선 3DGrid 문항의 경우 validation code는 맨 마지막 Object에 넣는다는 규칙에서 힌트를 얻었다.
(그리고 내가 아는 한 이 방법이 아니면 이 문제는 해결할 수 없다.)

사용자 삽입 이미지


위의 경우, AQ34_6th에 validation code를 넣고, CurrentForm()을 사용하면,

사용자 삽입 이미지

짜잔. 이렇게 성공적으로 받아옴을 알 수 있다.
이제 저 패턴을 분석하기로 하자.
...

앞에는 문자 및 숫자가 나오고 underbar 이후에 기수가 나온다.
이걸 정규식으로 표현하면,
/^([A-Za-z0-9]*\_)([0-9]+)([A-Za-z]*)/
이렇게 된다.

이렇게 만든 새로운 코드

function check3d()                                                 // 3DGrid의 각 column값이 중복되는지 validation해 주는 function
{

   var temp = CurrentForm();                                  // 현재 question의 ID가 들어온다.
   var obj = /^([A-Za-z0-9]*\_)([0-9]+)([A-Za-z]*)/; // 토큰별로 분리해주는 정규식

   var preqid = temp.replace(obj, '$1');                     // 앞부분을 preqid에 저장
   var insnum = temp.replace(obj, '$2');                  // 숫자부분을 insnum에 저장
   var postfix;                                                       // 서수를 저장하는 변수
   var currentValue;                                               // 해당 행에서 프리코드 값을 저장하는 변수
   var currentValues = new Array();                          // 프리코드 값들을 저장하는 변수

   insnum = parseInt(insnum, 10);                         // 숫자부분을 10진수로 변환

   var allQIDArr= new Array();                                 // 3DGrid 내부의 qid들을 저장할 배열 선언
       
   for (var i=insnum; i>=1; i--)                               // 마지막 문항에서부터 첫문항까지 (내부 문항의 개수만큼)
   {
      if (i%10 == 3)                                                // 10으로 나눈 나머지가 3이면
           postfix = "rd";                                             // third를 붙인다.
      else if (i%10 == 2)                                         // 10으로 나눈 나머지가 3이면
           postfix = "nd";                                            // second를 붙인다.
      else if (i%10 == 1)                                         // 10으로 나눈 나머지가 3이면
           postfix = "st";                                             // first를 붙인다.
      else                                                              // 그밖엔
           postfix = "th";                                             // th를 붙인다.
     
      allQIDArr[i] = preqid+i+postfix;                        // qid를 조합, 배열에 넣는다.
     
      ShowAlert(allQIDArr[i]);


      currentValue = f(allQIDArr[i])                         // 우선 하나씩 precode값을 currentvalue에 넣는다.
      currentValue = parseInt(currentValue, 10);     
      currentValues[i] = currentValue;                     // 그리고 그걸 배열에 차례대로 넣는다.

   }


   for (var j=0;j<currentValues.length;j++)              // 그 배열의 길이동안
    {
        for (var k=(j+1);k<currentValues.length;k++) // 바로 다음의 항들과 
        {
               if (currentValues[j] == currentValues[k])  // 값을 비교해서 같으면,
               {
                    RaiseError();                                   // 에러메시지 출력
                    SetErrorMessage(LangIDs.ko,ErrorTemplate("각 순위에는 다른 값을 선택해 주세요."));
               }    
        }
   }
}


사용법.

사용자 삽입 이미지

이렇게 Script Object를 하나 만들고,
그 안에 코드를 넣고

사용자 삽입 이미지

마지막으로,

사용자 삽입 이미지
< 다시 아까의 구조.  >

3DGrid를 구성하는 맨 마지막 항목 (여기서는 AQ34_6th) 의
validation code 에,

사용자 삽입 이미지

이렇게 간단하게(!) 한줄만 넣으면 준비 끝.
예전처럼 Set 선언하고 그 안에 QID를 일일이 넣어줄 필요가 없게 됐다.

처음에 JH대리님이 말씀하셨을 때는 안 될 것 같았는데,
역시 세상에 안되는 일은 없다는 말이 꼭 맞는 듯!
실행시켜보면,

사용자 삽입 이미지

기존 버전처럼 여전히 잘 동작하는 것을 알 수 있다.

여기서 드는 성능에 대한 의문.
그럼, 몇개까지 가능할까?
나는 우선 이렇게 만들어 보았다.

사용자 삽입 이미지

24순위다.
설마 24순위 이상 물어보는 경우가 있을까.
마찬가지로 맨 마지막의 'AQ34_24th'의 val에,
check3d();
라고 넣고 실행하면.

사용자 삽입 이미지

이렇게 잘 동작하는 것을 알 수 있다.
정규식의 강력한 성능으로 볼때, 24개뿐만 아니라
Javascript의 배열이 허용하는 만큼까지 가능할 듯.

그렇다면 자바스크립트는 어디까지 허용할까?


3DGrid Validation 완료!!

저작자 표시
신고
블로그 이미지

카펠

1차 목표를 이룬, 이제는 다가올 기회에 대비하는 나 그리고 나의 공간.

1.

한주를 마무리하는 금요일.
SJ선배님과 노트북을 정리했고,
JS대리님의 wave 조사를 scripting했다.

저작자 표시
신고
블로그 이미지

카펠

1차 목표를 이룬, 이제는 다가올 기회에 대비하는 나 그리고 나의 공간.

1.

Game 프로젝트 보완
내가 어제 작성해 놓은 QNR들을 하나하나 차근차근 살펴보았다.
역시, 중간중간 빼놓은 부분, 틀린부분들이 눈에 띄었다.
고친다고 다 고쳤는데,
내일 다시 보면 미처 보지 못한 부분이 또 나오지 않을까?
아무튼 수정 완료.


2.

3DGridValidation 계속

저작자 표시
신고
블로그 이미지

카펠

1차 목표를 이룬, 이제는 다가올 기회에 대비하는 나 그리고 나의 공간.

1.

Check3DVal 함수의 업그레이드.
다른 문제가 아니다. 효율적인 알고리즘을 구현하는 것 이상으로
내 function에 필요한 것은 호출의 편의성.

그렇지만 이번 과제는 확실히 어렵다.
3DGrid가 자신이 소유하고 있는 Single/Multi/Open 의 이름을 알고 있어야 한다.
(물론 알고 있기는 할 것이다.)
문제는 그걸 어떤 변수에 담아놓고 있느냐인데,
Confirmit의 Object라는 대단한 존재가 일개 초보 사용자에 불과한 나에게
순순히 자신의 X-ray 를 제공해 줄 것 같지가 않다.
그래서 scripting manual과 authoring manual을 찾아봤다.
앞으로 시간이 얼마 없는데.. 쉽게 해결할 수 있을 것 같지는 않다.


2.

game 조사 scripting 참여
밤 11시까지. QNR 작성.

저작자 표시
신고
블로그 이미지

카펠

1차 목표를 이룬, 이제는 다가올 기회에 대비하는 나 그리고 나의 공간.

1.

편안한 분위기의 하루. 편안했던 이유는 높으신 분들의 부재?
그렇다고 아무것도 안한것은 아니다. 후후..

저작자 표시
신고
블로그 이미지

카펠

1차 목표를 이룬, 이제는 다가올 기회에 대비하는 나 그리고 나의 공간.

1.

2월 11일. 어제 만들었던 3DGridVal 함수를 완성.
그렇지만 찜찜한게 있다.
for문을 3번이나 돌아야 한다는 것.
알고리즘 상 더 빠른 방법이 있지 않을까? 라는 고민.


2.

RIS
드디어 들어가는 RIS

사용자 삽입 이미지사용자 삽입 이미지사용자 삽입 이미지
<보면서 감탄사가 나온 멋진 flash animation>
사용자 삽입 이미지

TNS만의 Survey Solution

VISIT
Video Solutions
Article Select
Highlighter
SuperSort
SAM

VISIT (Virtual In-Store Interactive Testing)
 : 마치 store에 들어온 것 처럼 시각화해서 제품을 보여주는 solution
Video Solution
 : 비디오 서베이를 위한 최신 solution
Article Select
 : 마치 잡지를 넘기듯 한장 한장 확대 축소해 볼 수 있는 solution
Highlighter
 : 인상적인 문구, 문제있는 문구를 고르는데 있어서 하이라이팅(강조)할 수 있는 solution
SuperSort
 : respondent들이 정렬도 하고 grouping할 수도 있는 solution.
SAM (Survey Assistant Module)
 : 말그대로 survey를 도와주는 assistant입니다. animation으로 만들어진 아름다운(?) 여성분이 나와서 설명을 해줍니다. 

저작자 표시
신고
블로그 이미지

카펠

1차 목표를 이룬, 이제는 다가올 기회에 대비하는 나 그리고 나의 공간.

예정대로 오늘은 3DGrid Validation에 대해!
각 순위에 똑같은 응답을 했을 경우, ErrorMessage를 출력해주는 validation code를 만들 생각이다.
사실 TNS KR WI Library의 <dg>를 사용하면 이 사태를 예방할 수 있다.
그렇지만 IE를 제외한 오픈브라우져에서 CAWI Checker등의 프로그램을 사용해서 체크할 경우 막을 수 없어서
또다른 script를 필요로하게 된다.

그래서 간단히 만들어보았다.

사용자 삽입 이미지

사실 이런형태는 오히려 쉽다.
내가 기존에 썼던 방법.
하나의 값을 저장해 두고, 다음 값과의 차이를 비교하는 방식으로도 충분히 걸러낼 수 있는 형태였다.

사용자 삽입 이미지

오히려 어려운 쪽은 이쪽이다
function을 이렇게 정의하고

function Check3DVal(qSet)
{
   var allQIDArr = qSet.members();
   ShowAlert(allQIDArr)
}

그리고 validation 탭에

var qSet = set('suc_1st','suc_2nd','suc_3rd')
Check3DVal(qSet)

이렇게 넣으면
ShowAlert가 순서대로 값을 돌려주어야 하는데,
이상하게도...

사용자 삽입 이미지

이렇게 3, 1, 2의 순서대로 들어간다.
이쯤에서 궁금증이 생겼다.
그래서 6개로 늘려보기로 했다.

사용자 삽입 이미지

4,6,3,1,2,5의 순서로 들어간다.
이건..뭐..무작위군.
결국 이렇게 무작위로 저장되게 되면 바로 앞 항목과의 차이만 비교하는 첫번째 방법으로는 잡아내지 못하고
그대로 통과시켜버리는 불상사가 발생하게 된다.

그래서 고민하다가 두번째 방법을 생각해냈다.
배열을 하나 만들고,
그 배열안에 3DGrid안쪽 각각의 질문들의 answer precode를 저장한다.
그리고 검색 알고리즘 (말이 알고리즘이지, 가장 단순한 search) 을 통해
중복된 대답을 찾고 에러메시지를 반환.

그렇게해서 잘 동작하는 스크립트를 만들었다.
codes are below

function Check3DVal(qSet)
{
   var allQIDArr = qSet.members();
   var previousValue = 0;
   var currentValue;
   var currentValues = new Array();

   for(var i=0;i<allQIDArr.length;i++)
   {
        currentValue = f(allQIDArr[i]) // 우선 하나씩 precode값을 currentvalue에 넣는다.
        currentValue = parseInt(currentValue, 10)
        currentValues[i] = currentValue // 그리고 그걸 배열에 차례대로 넣는다.
            
   }

   for (var j=0;j<currentValues.length;j++) // 그 배열의 길이동안
    {
        for (var k=(j+1);k<currentValues.length;k++)
        {
               if (currentValues[j] == currentValues[k])
               {
                    RaiseError();
                    SetErrorMessage(LangIDs.ko,ErrorTemplate("각 순위에는 다른 값을 선택해 주세요."));
               }    
        }
   }
}


적용법은

사용자 삽입 이미지

3DGrid의 경우, 통상적으로 validation은 맨 마지막 문항에 넣어준다.
이 경우 suc_6th에 넣어주면 되겠다.

var qSet = set('suc_1st','suc_2nd','suc_3rd','suc_4th','suc_5th','suc_6th' )
Check3DVal(qSet)

나는 qSet이라는 set을 만들어서 그 안에 해당하는 문항들을 넣었다.
그리고 그 qSet을 parameter로 함수에 전달하기만하면 된다.
결과.

사용자 삽입 이미지


저작자 표시
신고
블로그 이미지

카펠

1차 목표를 이룬, 이제는 다가올 기회에 대비하는 나 그리고 나의 공간.

드디어 마지막 파트.

1.

CheckBetweenOpenAndMulti(qOpen, qMulti)

오픈문항과 멀티문항의 내용 유무를 validation하는 함수.

사용자 삽입 이미지

이렇게 오픈문항과 멀티문항을 놓고

CheckBetweenOpenAndMulti(q288, q286)

함수를 q286(Don't Know = DK)의 val.에 놓고
아무것도 입력하지 않은채 넘어가게 되면,

사용자 삽입 이미지

이렇게 미리 지정해둔 에러메시지가 출력. (Hey! 는 내가 넣은 것. 자유롭게 편집 가능)
그리고 이번엔, 양쪽에 모두 내용을 입력하고 넘어가게 되면,

사용자 삽입 이미지

이런 결과를 보여준다.
현재 매우 많이 쓰이지만 굳이 함수로 만들어서 정의해 놓을 필요는 없다.
그만큼 간단하니까.


2.

CheckColumnSumAtLeast(minNum)

멀티오픈 문항에서 모든 문항의 합이 주어진 minNum보다 작은지를 validation해줍니다.
합이 minNum보다 작아지면 ErrorMessage 출력.

사용자 삽입 이미지



3.

CheckColumnSumAtMost(maxNum)

2번의 함수와 정반대의 기능을 수행.
오픈문항의 수치들의 합이 maxNum보다 클경우 에러메시지를 출력한다.


4.

CheckColumnSumEqualTo(equalNum)

여전히 sum시리즈의 연속.
합이 equalNum과 같아야 함.

사용자 삽입 이미지



5.

CheckEmail(qEmail)

이메일을 isEMail함수에 의해 이메일인지 아닌지 판단하고, 동작.

사용자 삽입 이미지



6.

CheckRankOptional(uptoNum)

여러 오픈멀티 문항들의 ranking을 구하는 함수.
아래와 같이 각 문항들의 '순위'를 구하는데 쓰인다.
10문항이니까 1~10의 값이 나와야 하는데,
아래는 11이 들어가 있으므로 error가 출력되는 것이다.

사용자 삽입 이미지



7.

CheckTwoExclusive(qid, code1, code2)

멀티오픈 문항에서 아래의 경우와 같이 두 항목에 동시에 응답해선 안 되는 경우가 있다.
그럴때 쓰이면 편할 것 같다.
그렇지만 말 그대로 멀티오픈에만 가능하기에.. 활용도가 미미하다.

사용자 삽입 이미지



8.

RequireBetweenMultis(qMultiSet)

7번 함수와 거의 같지만 멀티오픈이 아닌 일반 멀티를 대상으로 한다는 것이다.


9.

RequireMulti()

멀티 문항에는 반드시 입력값이 있어야 한다. 입력 여부를 확인하는 초간단 validation.
그렇지만 Confirmit 자체만으로도 간단하게 설정 가능하기 때문에 이 함수의 활용도는 낮은 편이다.


10.

RequireMultiAtMost(maxSize)

항목의 최소 선택 개수를 지정해주는 함수
그렇지만 10번과 마찬가지로 Confirmit 자체만으로도 간단하게 설정 가능하기 때문에 이 함수의 활용도는 낮은 편이다.


11.

RequireMultiBetweenLimits(minSize, maxSize)

이번에는 상한과 하한을 정해주는 함수이다. 물론 이 함수도 Confirmit 만으로 대체 사용이 가능하다.
그렇지만 위의 두가지보다는 좀 더 쓸모가 있다 하겠다.

RequireMultiBetweenLimits(2, 4)

이렇게 넣고, 실행시킨 후 6가지를 고르게 되면,

사용자 삽입 이미지

이렇게 에러메시지가 발생하게 된다.


12.

RequireMultiOpen()

open문항에 응답이 되었는지 안되었는지만 체크하는 함수. 역시 초간단.


13.

RequireSeqInput()

멀티오픈 문항을 여러개 입력함에 있어 위에서부터 순서대로 채울 것을 확인하는 함수.
그런데 이게 의문이다. 우리가 체크할 수 있는건 순서대로가 아니라
빈칸의 유무일 것이다.

사용자 삽입 이미지



오늘부로 인트라넷의 JScript Library를 모두 살펴봤다.
아직 많이 안다고는 할 수 없지만, 뭔가 뿌듯함을 느낀다.
중간중간 불성실(?)하게 확인해 본 부분도 있었지만,
이것으로 조금은 자신감 상승!?

내일부터는 JH대리님이 말씀하신 3DGrid validation 개발(!)에 돌입해보자!

저작자 표시
신고
블로그 이미지

카펠

1차 목표를 이룬, 이제는 다가올 기회에 대비하는 나 그리고 나의 공간.