オンラむンマヌケティング調査甚の゚ンゞンのニュアンスずプログラミングアルゎリズム

芪愛なるハブラフ人、こんにちは。 長い間、私はそのようなマニュアルを曞きたいず思っおいたので、私は座っおそれを曞くこずを匷制するこずに決めたした-マヌケティングの分野でのプログラミング研究䞭に受け取った経隓ず、耇数のプロゞェクトが実装された゚ンゞンに眮かれたいく぀かのアルゎリズムに぀いお共有するために。



30〜40の質問に察する些现なWordのアンケヌト圢匏のTKの方が簡単なように思われたす。顧客はプログラムされた圢匏でブラりザりィンドりに衚瀺し、さらに4日間すべおを提䟛したすか 私の友人がか぀お蚀ったように、圌が私ず働き始めるたで



-はい、4時間ありたす 圌は午前䞭に座っお、倕方たでにすべおが準備され、テストされたした。 なぜあなたが叩いおいるのか分かりたせん...



しかし、残念なこずに、圌が提瀺したように、すべおは単玔なものではなく、緊急時に最初のアンケヌトを2日間プログラムしその埌2から3日以内にめちゃくちゃになりたす、電話やメヌルで絶えず倚くのコメントを受け取りたした。 そしお、ここでのポむントは、圌らの胜力や職業䞊の倱敗を再評䟡するこずではなくそしお、サむトビルダヌの豊富な経隓を持぀友人でなければなりたせん、フィヌルド自䜓は非垞に具䜓的で、萜ずし穎ず埮劙なポむントがありたす。 これらの萜ずし穎ず埮劙な点のいく぀かに぀いお、およびそれらを回避する方法に぀いお、私は䌝えたいず思いたす。



「赀が欲しいが青」たたはコヌドの倉曎可胜性



なぜ発生したのかはわかりたせんが、䜕らかの理由で、顧客が1日に数回プロファむル芁件を倉曎したいのはマヌケティングです。 どうやら、これは内郚組織によるもので、巊手は右手が䜕をしおいるのかを垞に把握しおいるわけではなく、時には完党に異なるものを望んでいたす。 しかし、これは本質ではありたせんが、ポむントはすべおプログラマヌの頭痛に぀ながるこずですずころで、ごく最近たで、CATIのアンケヌトの最終バヌゞョンが「V.13.3_final_final」ずしおリストされおいた堎合があり、これは「最終「TK」。



䜜業を容易にし、開発時間を短瞮し、起こりうる゚ラヌに察するヒュヌマンファクタヌの圱響を最小限に抑える゚ンゞンを䜜成するずいうアむデアは、4回目のアンケヌトの埌に出おきたした。 玠朎なアむデアは、このプログラミング自䜓の知識ず既存のプロゞェクトを倉曎する単玔さのない「プログラミング」アンケヌトの可胜性の基瀎ずしお採甚されたした。



アむデアは本質的にそれほど悪くはありたせんでしたが、重芁な圹割は、実装のためのリ゜ヌスの䞍足工数ず間違ったアプロヌチによっお行われたしたアンケヌトは、特定のコマンドを担圓する列がExcelファむルであるず想定されたしたデザむナヌモゞュヌルの堎合



解決枈み-完了。 しかし、最初のパンケヌキは、い぀ものように、ゎツゎツしおいたす...



故障理論



゚ンゞンは小芏暡なプロゞェクトで実行されたしたが、6回目たたは7回目以降、機胜の倧幅な拡匵により、遞択された開発パスがデッドロックされおいるこずが明らかになりたした。 私のパヌトナヌず私開発者自身が、どの機胜が芏定されおいるかに぀いおすでに混乱し始めおいるずいう点に達したした。 理由



他にも二次的な理由がありたした。



解決策はりィザヌドを䜜成するこずでした。このりィザヌドは、「アンケヌト回答」の圢匏で将来のアンケヌト甚のテンプレヌトを圢成し、組み蟌みの゚ディタヌでさらに頭に浮かびたす。 しかし、これはすべお新しい工数、無限のコヌド修正、絶え間ない曎新であり、結果ずしお、䞀皮のフランケンシュタむンの怪物です。 そのため、このアプロヌチを攟棄するこずが決定されたした。



内郚スクリプト蚀語の蚘述、C ++でのデヌモンのプログラミングより広範な機胜のため、Word文曞のパヌサヌ特定の圢匏で蚘述、および他の倚くのアむデアが怜蚎されたした。 しかし、それらのすべおは、圌らの䞍条理たたは実装の面倒さのためにマヌクされたした。 シンプルでありながら柔軟な゜リュヌションを芋぀ける必芁がありたした...



問題の説明ず解決策



問題の有胜な声明は、保蚌ではないにしおも、アむデアの成功した実装ぞの道の良い助けです。



オンラむン調査のプログラミングですでに十分な経隓があり、この問題で倚くの萜ずし穎ずニュアンスに盎面しおいたため、システムが満たすべきいく぀かの䞻芁な私の意芋ではポむントを抂説したした。



たた、起こりうる問題を最小限に抑えるために、いく぀かの簡単なルヌルに埓うこずが決定されたした。



結果ずしお、出力はモノリシック゚ンゞンではなく、ナヌザヌに質問を衚瀺するモゞュヌルの耇合䜓であり、関数のjsラむブラリずphpラむブラリも含たれおいたした。



ここで、さらに詳しく説明したいく぀かのポむントをペむントしたす。



さたざたなデザむンを接続し、それらを「オンザフラむ」で倉曎する機胜



顧客は、サヌドパヌティの䌚瀟で調査を泚文した堎合でも、マヌケティング調査で独自のデザむンを䜿甚する必芁があるこずがよくありたす。 これは特に、ブランドや、アンケヌトぞのリンクがクラむアントのりェブサむトに投皿されおいる堎合に圓おはたりたすナヌザヌがサむトを離れおいないずいう印象を䞎えるため。



なぜなら 圧倒的倚数の投祚には共通点が1぀ありたす-情報が1぀の領域でのみ倉化するため、解決策は2぀のphp関数を䜿甚するこずでした。 次のようになりたす。

 <?php session_start(); include('./php/funcs.php'); //    if (!$_SESSION['user_ID']){ //         $user_id = md5(date('ymd H:i:s').rand()); $_SESSION['user_ID'] = $user_id; $_SESSION['user_position'] = setUserPosition($user_id); //      ,            ( "start") } else { $_SESSION['user_position'] = setUserPosition($_SESSION['user_ID']); //   ,        ,        } ?> ... // html- <div id="workDiv" class="workDiv" > <?php showQuest($_SESSION['user_position']); // ,      div' ?> </div> ... // html-    ("", "", "") <input type="button" style="width: 75px;" id="backBtn" onclick="request('back');" value=""> <input type="submit" style="width: 75px;" id="submitBtn" onclick="request('forvard');" value=""> <input type="submit" style="width: 75px; display: none;" id="endBtn" onclick="endOfSurvey();" value=""> 
      





<?php session_start(); include('./php/funcs.php'); // if (!$_SESSION['user_ID']){ // $user_id = md5(date('ymd H:i:s').rand()); $_SESSION['user_ID'] = $user_id; $_SESSION['user_position'] = setUserPosition($user_id); // , ( "start") } else { $_SESSION['user_position'] = setUserPosition($_SESSION['user_ID']); // , , } ?> ... // html- <div id="workDiv" class="workDiv" > <?php showQuest($_SESSION['user_position']); // , div' ?> </div> ... // html- ("", "", "") <input type="button" style="width: 75px;" id="backBtn" onclick="request('back');" value=""> <input type="submit" style="width: 75px;" id="submitBtn" onclick="request('forvard');" value=""> <input type="submit" style="width: 75px; display: none;" id="endBtn" onclick="endOfSurvey();" value="">







これは、投祚のすべおの可胜なバリ゚ヌションの3/4の芁件を満たすのに十分です。 残りの1/4に぀いおは、いく぀かのタグ/関数の远加を劚げるものはありたせん。



蚭蚈倉曎の問題は解決されたした。



プログラミングプロセスの最倧加速



すべおが関数のセットずしお実装され、サヌバヌずデヌタを亀換する䞻なタスクずその解釈が解決され、゚ンゞン䞊にあるずいう事実により、アンケヌト自䜓のプログラミングは、どのチェックに察応するjsスクリプトに登録するロゞック付きのファむルを曞くこずになりたす次の圢匏の質問テンプレヌトの半自動䜜成

 <form name="form" method="post"> <b>  :</b> <br /><br /> <input type="radio" name="Z0" id="Z0" value="1" /> <div class="textAssociationDiv" >  </div> <br /> <input type="radio" name="Z0" id="Z0" value="2" /> <div class="textAssociationDiv" >  </div> <br /> </form> 
      





<form name="form" method="post"> <b> :</b> <br /><br /> <input type="radio" name="Z0" id="Z0" value="1" /> <div class="textAssociationDiv" > </div> <br /> <input type="radio" name="Z0" id="Z0" value="2" /> <div class="textAssociationDiv" > </div> <br /> </form>









コヌドには、クラス「textAssociationDiv」を持぀耇数のdivが含たれおいたす-これは、特定のチェックボックスやラゞオボタンなど、テキストのクリックを関連付けるために䜿甚されたす。 誰かが興味を持っおいる堎合、これを行うjs関数のコヌドは次のずおりです。

 function associateTextToElement(){ $(".textAssociationDiv").click(function(){document.forms['form'].elements[$(".textAssociationDiv").index($(this)[0])].click();}); } 
      





function associateTextToElement(){ $(".textAssociationDiv").click(function(){document.forms['form'].elements[$(".textAssociationDiv").index($(this)[0])].click();}); }







たた、コヌドで同じIDが䜿甚されたす。 これにより、耇数の質問が衚瀺されおいる堎合にペヌゞ芁玠の分析が簡単になりたす。 耇数セット耇数遞択などの質問を掚枬する必芁がある堎合、名前ずIDは次の圢匏を取りたすS9.1、S9.2、S9.3、S9.4、S9.5、S9.97、ここでポむントの埌の数字-応答コヌド。



ナヌザヌが[次ぞ]たたは[戻る]ボタンをクリックするず、javascriptは入力されたすべおのデヌタを収集し、Ajaxはそれを次の圢匏でphpスクリプトに送信したすvariable_code = value。 倉数コヌドは芁玠のidから取埗されたす。単䞀の質問では同じですが、小さなセットでは異なるため、非垞に䟿利です。 スクリプトは、POSTメ゜ッドを䜿甚しおそれらを受信したすナヌザヌからそのような情報を非衚瀺にするこずが重芁です。$ _SESSION ['user_ID']に保存された名前でログファむルに曞き蟌みたす。



ファむルシステムを䜿甚しおデヌタを保存する



デヌタベヌスの䜿甚を攟棄する理由はいく぀かありたしたが、その䞻な理由は、調査䞭に倉数をすばやく远加/削陀する必芁があったこずです。 たた、このアプロヌチは、MySQLを䜿甚する際のナヌザヌ応答テヌブルのフィヌルド数の問題を解決したした䞀郚の研究では異なる倉数の総数が1.5から2000に達するこずがありたした。



ファむルシステムを䜿甚するず、すべおの困難がなくなりたした。 サヌバヌに送信されたデヌタはすべお、察応するログファむルに蚘録されたした。 そしお、いく぀かの新しい回答を远加するには、必芁な入力を含む2、3行を察応する質問ファむルに远加するだけで十分です。...すべお-すべおのデヌタが保存され、これに費やされた時間はほんの数秒でした。 ログの解釈をコンピュヌタヌず人の䞡方で簡単にするために、ログの圢匏は次のずおりです。



userID = 1cb3761177ec8846fe8ae35392017e36

userIP = 192.168.1.34

startTime = 04/19/10 12:50:21

S4 = 33

S5 = 3

S9_8 = 8 //これは耇数セットの蚘述方法ですS9.8、S9.10など



別のファむルにロゞックを入れる



ロゞックの蚘録に関する問題は、プログラマヌがアンケヌトをプログラミングしおいるず刀断され、マネヌゞャヌがTKのみを䞎えたずきに、それ自䜓で解決されたした。 ビゞュアル゚ディタ/りィザヌドを䜿甚しお誰かの生掻を「単玔化」する必芁はありたせんプログラマにずっお生掻が困難になりたすが、jsずphpを理解しおいる人ぱンゞンずラむブラリを䜿甚したす。 車茪を再発明する必芁さえありたせんでした-実装された倚数のプロゞェクトを分析するずき、「盎接」ロゞックはクラむアントのすべおのニヌズを満たし、わずか数個の関数、2぀の倉数、ifステヌトメントで十分なブランチを実装できるこずがわかりたした







オンラむンアンケヌトでは、調査ベクトルは垞に䞀方向に進み、コンピュヌタヌの芳点から可胜な分岐オプションは2぀のみであるずいう条件条件が満たされたかどうかを考慮するず、ロゞック党䜓が制限たで簡略化され、次の圢匏php 

 if ($_SESSION['user_position'] == 'S9' && checkAnswer('S9',1)){ //    S9     1-  $question_contents = file_get_contents('../qst/Z6.php'); echo iconv("cp1251", "UTF-8", $question_contents); //include_once('../qst/Z6.php'); //echo iconv("cp1251", "UTF-8", showQuest()); $_SESSION['user_position'] = 'Z6'; exit; } //   ,      php (,            ) if ($_SESSION['user_position'] == 'A1'){ //    A1 //$question_contents = file_get_contents('../qst/A3.php'); //echo iconv("cp1251", "UTF-8", $question_contents); include_once('../qst/A3.php'); echo iconv("cp1251", "UTF-8", showQuest()); $_SESSION['user_position'] = 'A3'; exit; } 
      





if ($_SESSION['user_position'] == 'S9' && checkAnswer('S9',1)){ // S9 1- $question_contents = file_get_contents('../qst/Z6.php'); echo iconv("cp1251", "UTF-8", $question_contents); //include_once('../qst/Z6.php'); //echo iconv("cp1251", "UTF-8", showQuest()); $_SESSION['user_position'] = 'Z6'; exit; } // , php (, ) if ($_SESSION['user_position'] == 'A1'){ // A1 //$question_contents = file_get_contents('../qst/A3.php'); //echo iconv("cp1251", "UTF-8", $question_contents); include_once('../qst/A3.php'); echo iconv("cp1251", "UTF-8", showQuest()); $_SESSION['user_position'] = 'A3'; exit; }







䞊蚘のコヌドからわかるように、䞡方のオプションはほが同じであり、他のすべおのチェックの条件は䌌おいたす。 これに基づいお、適切なスクリプトで質問のリストをそれらが埓う順序で単にロヌドし、出力で生成されたロゞックを取埗したす。これは手動でわずかに修正されるだけです条件内の察応するブロックのコメントを倖し、必芁に応じお远加の機胜を远加したす/たたは条件。 質問のブロック党䜓に条件を蚭定する必芁がある堎合、これもifによっお解決されたすたずえば、質問のためにA1を開き、A8を閉じたす。



このようなファむルがある堎合、jsからログに転送されたデヌタをログに曞き蟌む機胜を最初に远加するだけです。 ロゞックの準備が敎い、質問は1぀ず぀眮き換えられたす。 そしお、党䜓のポむントは、簡単にするために、jsからのリク゚ストがこのスクリプトに盎接送信され、デヌタを蚘録し、適切な条件を満たすたで実行され続けるだけであり、スクリプトは必芁なコンテンツをjsに送信しお䜜業を完了するこずです。 次に、jsはid = "workDiv"で前述のdivに受信デヌタを挿入し、ルヌプを繰り返したす。ナヌザヌが回答にマヌクを付け、jsがそれらを論理ファむルに送信し、phpがデヌタをログに曞き蟌み、次の質問の内容を返したす。jsは䜜業divの内容を受信デヌタに眮き換えたす。 。



サヌバヌからデヌタを受信し、䜜業䞭のdivの内容を眮き換えた埌、jsはもう1぀の機胜を実行したす。バむンド機胜を呌び出しお、質問に蚘入する有効性を確認したす。



Js-check蚘入質問



オンラむン調査で䜿甚される質問のほずんどは、いく぀かのタむプに分類できたす。



これに基づいお、察応するチェックを各入力芁玠に自動的にバむンドする関数のラむブラリが䜜成されたした。



質問衚に初めおアクセスするずき、および質問でブロックを曎新するずき、questsChecksjs関数が呌び出され、その本質は簡単に蚀えば次のようになりたす「次ぞ」ボタンをブロックしたす結局、これは新しい質問であり、デヌタはただ入力されおいたせん phpスクリプトから、$ _SESSION ['user_position']の倀぀たり、珟圚の質問、スむッチを実行したす。

 switch(quest){ case 'S2': disableNext(); radioMultCheck(); progressBar(0); break; case 'S4': disableNext(); checkAgeText(10, 99); progressBar(7); break; case 'S12': disableNext(); radioTextCheck(); progressBar(14); break; // ...    default: break; } 
      





switch(quest){ case 'S2': disableNext(); radioMultCheck(); progressBar(0); break; case 'S4': disableNext(); checkAgeText(10, 99); progressBar(7); break; case 'S12': disableNext(); radioTextCheck(); progressBar(14); break; // ... default: break; }









質問のコヌドに応じお、察応するラむブラリ関数を呌び出しお、チェックをハングさせたす。 以䞋は、そのうちの1぀耇数遞択+テキストずそれに関連付けられた2぀の䟋です。

 // ----------------------------------------------------------------------------- function checkboxText(check,text){ disableNext(); if (!check){ $("div[id='workDiv'] input[type='checkbox']").click(function(){checkboxText('true');}); $("div[id='workDiv'] input[type='text']").keyup(function(){checkboxText('true',this);}); } if (check){ if (!text && $("div[id='workDiv'] input[type='text'][value!='']").length > 0) enableNext(); if (!text && $("div[id='workDiv'] input[type='text'][value!='']").length == 0) checkCheckbox(); if (text && !checkCheckbox()){ checkText(text); } } } // ----------------------------------------------------------------------------- function checkCheckbox(uniqCodes){ if (!uniqCodes){ uniqText = getUniqTextObj(); if ($("div[id='workDiv'] input[type='checkbox'][name!='toggleOther']:checked").length > 0){ enableNext(); return true; } if ($("div[id='workDiv'] input[type='checkbox']:checked").length == 0 && !uniqText) disableNext(); if ($("div[id='workDiv'] input[type='checkbox']:checked").length == 0 && uniqText) checkText(uniqText); } if (uniqCodes){ for (var key in uniqCodes){ $(document.getElementById(getQuest()+'.'+uniqCodes[key])).attr("checked", ""); } checkCheckbox(); } } // ----------------------------------------------------------------------------- function checkText(text,uniqCodes){ if (!uniqCodes){ if (text.value) enableNext(); else disableNext(); } if (uniqCodes){ for (var key in uniqCodes){ $(document.getElementById(getQuest()+'.'+uniqCodes[key])).attr("checked", ""); } if (!checkCheckbox()) checkText(text); } } 
      





// ----------------------------------------------------------------------------- function checkboxText(check,text){ disableNext(); if (!check){ $("div[id='workDiv'] input[type='checkbox']").click(function(){checkboxText('true');}); $("div[id='workDiv'] input[type='text']").keyup(function(){checkboxText('true',this);}); } if (check){ if (!text && $("div[id='workDiv'] input[type='text'][value!='']").length > 0) enableNext(); if (!text && $("div[id='workDiv'] input[type='text'][value!='']").length == 0) checkCheckbox(); if (text && !checkCheckbox()){ checkText(text); } } } // ----------------------------------------------------------------------------- function checkCheckbox(uniqCodes){ if (!uniqCodes){ uniqText = getUniqTextObj(); if ($("div[id='workDiv'] input[type='checkbox'][name!='toggleOther']:checked").length > 0){ enableNext(); return true; } if ($("div[id='workDiv'] input[type='checkbox']:checked").length == 0 && !uniqText) disableNext(); if ($("div[id='workDiv'] input[type='checkbox']:checked").length == 0 && uniqText) checkText(uniqText); } if (uniqCodes){ for (var key in uniqCodes){ $(document.getElementById(getQuest()+'.'+uniqCodes[key])).attr("checked", ""); } checkCheckbox(); } } // ----------------------------------------------------------------------------- function checkText(text,uniqCodes){ if (!uniqCodes){ if (text.value) enableNext(); else disableNext(); } if (uniqCodes){ for (var key in uniqCodes){ $(document.getElementById(getQuest()+'.'+uniqCodes[key])).attr("checked", ""); } if (!checkCheckbox()) checkText(text); } }







各行に぀いおコメントしたせん。なぜなら これはあたりにも倚くのテキストに気付くでしょうが、私は簡単にアルゎリズムを説明したすクリックたたはキヌアップむベントによっお入力タむプの各芁玠に同じ関数の呌び出しをアタッチしたすが、「check」パラメヌタヌずオブゞェクトテキストフィヌルドを枡したす。 チェックが呌び出されるずクリックされるず、関数は定矩枈みのアルゎリズム䜜業の皮類に基づくに埓っお䜜業div内のすべおの芁玠を実行し、フィヌルドの倀を収集し、分析し、必芁に応じお、より専門的なテスト関数を呌び出したす。



この䟋では、テキストを䜿甚した耇数遞択チェック機胜は、単玔な耇数遞択チェック機胜の開始を開始できたす。 単玔な耇数遞択は、テキストを䜿甚した耇数遞択の簡易バヌゞョンであり、それに含たれおいたす。 プリミティブ型をチェックするためのすべおの機胜耇数遞択、単䞀遞択、自由回答圢匏の質問を含むは、プリミティブのフィヌルドタむプのみがチェックされるように蚭蚈されおいたす。 したがっお、耇雑なタむプの質問を単玔な質問に自動的に分類し、それらのチェックを実行するず、テストが成功したかどうかにかかわらず、目的の結果trueたたはfalseが埗られたす。 そしお、もしそうなら、次ぞボタンからロックを削陀し、そうでなければ䜕もしないか、それが利甚可胜であればそれをブロックしたす。



チェックが成功するず、送信、受信、蚘入、チェック、送信などの新しいサむクルが開始されたす。



構造プログラミングを䜿甚する



この堎合私の意芋では、クラスずオブゞェクトの代わりに裞の関数を䜿甚する方がパフォヌマンスの点でより望たしいです。 倧量のナヌザヌがいる堎合、1぀の特定のメ゜ッドを䜿甚するためだけに倚数のプロパティを持぀オブゞェクトを䜜成するこずは、少なくずも合理的ではありたせん。 5〜10個のオブゞェクトを䜿甚した操䜜は、機胜を䜿甚した同様のアクションよりもリ゜ヌスの点でコストが高くなりたす。



さらに、゚ンゞンアヌキテクチャがシンプルであるため、OOPのポむントがわかりたせん。



たずめるず





この゚ンゞンアヌキテクチャは、参加の招埅を受けたナヌザヌの数が玄12䞇から13䞇人であり、忠実なナヌザヌは顧客の顧客であり、郵送自䜓が顧客に代わっお行われた研究の1぀で成功したした-同時に、受信されたした玄22kの生産的なむンタビュヌ、および総蚪問数は玄45kでした。



少数の研究が倚数行われおいたす。



統蚈によるず、このアヌキテクチャは信頌性が高く高性胜です。 さらに、私の意芋では䟿利で非垞に柔軟です。



十分な空き時間がある堎合は、おそらくこの゚ンゞンのファむナラむズに戻り、再び、すべおの゜ヌスをパブリックドメむンに配眮し、機胜の詳现な説明ずあらゆる皮類の利点を远加したす。 しかし、これはすべお「可胜」なだけです...



か぀お私がこの分野に突入し始めたずき、そのトピックに関する情報の䞍足は壊滅的であり、すべおのタスクを詊行錯誀によっお解決する必芁がありたした。



このマニュアルずそれに反映した私の個人的な経隓が、䜕らかの圢であなたの助けになるこずを願っおいたす。



たた、この資料が、マヌケティング調査でのオンラむンプロファむルのプログラミングなどのトピックに関する情報の空癜を䜕らかの圢で満たすこずを願っおいたす。



ただし、残念ながら、クォヌタプログラミング、コンゞョむントたたはプログラミングのアンケヌト、および/たたはCATIの゚ンゞン実際には、CATIスタゞオ自䜓の技術ベヌスの組織などのトピックは察象倖です。 その他倚数...



しかし、これらはすべお個々のFAQずマニュアルのトピックです。



ご枅聎ありがずうございたした。



All Articles