document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. //*************************************************************************************//
  2. //*************************************************************************************//
  3. //                                                                                     //
  4. //                  RESPONDER FOR THE PBS SEXISM QUIZ                                  //
  5. //                  ----------------------------------------                           //
  6. //                                                                                     //
  7. //  instructions for use:                                                              //
  8. //                                                                                     //
  9. //  1. create a robot respondent to answer the quiz on your behalf.                    //
  10. //      - var r1 = new respondent(name, gender, age, american, education, salary);     //
  11. //                                                                                     //
  12. //  2. set the respondent off doing the quiz, passing in the respondent object.        //
  13. //      - do_quiz(r1);                                                                 //
  14. //                                                                                     //
  15. //*************************************************************************************//
  16. //*************************************************************************************//
  17.  
  18.  
  19. // each time a quiz is submitted or restarted, the browser reloads and the script is read.
  20. // memento is called at the bottom of the script, and it reads a note left by the last function
  21. // called before reload, if there was one. memento then calls the next appropriate function,
  22. // according to the status indicated by the note.
  23. function memento() {
  24.  
  25.     var fname;
  26.     var status;
  27.     var read_me;
  28.     var respondent = {};
  29.     var note_to_self = {};
  30.  
  31.     // see if there is a \'read me\' note in session storage, which will tell us who we are and what we
  32.     // are supposed to be doing. if there is no note, then it means that we have just started the quiz.
  33.     if (sessionStorage.read_me !== null) {
  34.  
  35.         read_me         =   sessionStorage.getItem(\'read_me\');
  36.         note_to_self    =   JSON.parse(read_me);
  37.         fname           =   note_to_self.fname;
  38.         status          =   note_to_self.status;
  39.  
  40.     } else {
  41.  
  42.         status = \'ready to start\';
  43.     }
  44.  
  45.     // if the \'read me\' note gives us a \'ready to start\' status, then we are just starting the quiz. output
  46.     // instructions to the user on how to make a respondent and start them off doing the quiz.
  47.     if (status == \'ready to start\') {
  48.  
  49.         console.log(\'ready: \');
  50.         console.log(\'create a respondent, like this: r1 = new respondent(fname, gender, age, american, education, salary);\');
  51.         console.log(\'then set them off doing the quiz, like this: do_quiz(r1);\');
  52.         console.log(\'you can harvest the results once they are done.\');
  53.  
  54.         // if status is \'ready for next pass\', then we have just done one pass of the quiz and are ready for the next.
  55.         // wake the respondent up and set them going on the next pass. the respondent will do 6 x 12 = 72 passes of the
  56.         // quiz in total (12 questions, 6 options for each).
  57.     } else if (status == \'ready for next pass\') {
  58.  
  59.         respondent = cryogenic_suspension(fname, \'wake\');
  60.         do_quiz(respondent);
  61.  
  62.         // if the status in the note is \'ready to process results\', then we have done a pass of the quiz and submitted it, and
  63.         // now we are looking at the results. wke up our respondet and get them to write down the results and put them in their
  64.         // jacket pocket.
  65.     } else if (status == \'ready to process results\') {
  66.  
  67.         respondent = cryogenic_suspension(fname, \'wake\');
  68.         process_results(respondent);
  69.  
  70.         // if the status in the note reads \'ready to output results\', then we have done all 72 passes of the quiz and we want
  71.         // to output them to the console in a rough and ready kind of csv format. wake our respondent up and get the results
  72.         //out of his or her jacket pocket.
  73.     } else if (status == \'ready to output results\') {
  74.  
  75.         respondent = cryogenic_suspension(fname, \'wake\');
  76.         do_debrief(respondent);
  77.  
  78.         // if the status in the note reads \'done\', then there is nothing else for our respondent to do. He or she is asleep now, and
  79.         // we won\'t wake them. They deserve the rest. put their name in a list of respondents currently in sessionStorage so we can
  80.         // get in touch with them if we need to, remove the \'read me\' note so we\'re ready to start afresh with a new respondent, and
  81.         // call memento again to display the welcome message.
  82.     } else if (status == \'done\') {
  83.  
  84.         sessionStorage.setItem(\'retired_respondents\', fname);
  85.         sessionStorage.removeItem(\'read_me\');
  86.         memento();
  87.     }
  88. }
  89.  
  90. // constructor for respondent objects. respondent objects hold the personal details
  91. // of the \'respondent\' answering the quiz, and also the results of their questionnaire
  92. // responses. each respondent will give all possible answers to each (non personal)
  93. // question on the quiz, while holding all the other answers at a constant middle value.
  94. // each respondent will therefore recieve 6 x 12 = 72 result sets.
  95. function respondent(fname, gender, age, american, education, salary) {
  96.  
  97.     this.fname                          =       fname;
  98.     this.gender                         =       gender;
  99.     this.age                            =       age;
  100.     this.american                       =       american;
  101.     this.education                      =       education;
  102.     this.salary                         =       salary;
  103.     this.current_pass                   =       1;
  104.     this.current_focus_question         =       1;
  105.     this.response_variation_value       =       0;
  106.     this.codebook                       =       get_codebook();
  107.     this.quiz_info                      =       {\'status\': false};
  108.     this.result_set                     =       [];
  109. }
  110.  
  111. // make a codebook of the quiz questions and response levels.
  112. function get_codebook() {
  113.  
  114.     var codebook = {};      // codebook of questions and response levels.
  115.     var lev     = [];       // array of levels for each question.
  116.     var q_key;              // serves as the question in the codebook and provedes the key for the arrays of response levels.
  117.  
  118.     //there are 17 questions
  119.     for (var q = 1; q <= 17; q++) {
  120.  
  121.         // q_key serves as a record of the question, and the key for the question arrays which are inside
  122.         // it in the codebook object
  123.         q_key = jQuery(\'#q\' + q + \'>.question_text\').text();
  124.  
  125.         //get the number of options for the question in... um... question.
  126.         q_children = jQuery(\'#q\' + q + \'>ul\').children(\'li\').length;
  127.  
  128.         //put the answers into the array lev
  129.         for (var a = 0; a < q_children; a++) {
  130.  
  131.             lev[a] = jQuery(\'label[for="a\' + q + \'_\' + a + \'"]\').text();
  132.         }
  133.  
  134.         codebook[q_key] = lev.slice();
  135.         lev = [];
  136.     }
  137.  
  138.     return codebook;
  139. }
  140.  
  141. // make the quiz responses. pass in the respondent and add the results for each pass of the
  142. // quiz to the respondent object variables.
  143. function do_quiz(respondent) {
  144.  
  145.     // get the current focus question and response variation value for the respondent.
  146.     var current_focus_question   = respondent.current_focus_question;
  147.     var response_variation_value = respondent.response_variation_value;
  148.  
  149.     // answer each of the sexism questions. answer \'2\' (slightly agree) for each question (this is as
  150.     // close to a neutral response we can get), except the current focus question, which will be answered
  151.     // according to what pass we are currently on.
  152.     for (var question = 1; question <= 12; question++) {
  153.  
  154.         var response = (question == current_focus_question) ? response_variation_value : 2;
  155.  
  156.         jQuery(\'input[name=a\' + question + \'][value=\' + response + \']\').prop("checked",true);
  157.     }
  158.  
  159.     // answer the questions about our respondent\'s personal details.
  160.     jQuery(\'input[name=a13][value="\'    + respondent.gender     +\'"]\').prop("checked",true);
  161.     jQuery(\'input[name=a14][value="\'    + respondent.age        +\'"]\').prop("checked",true);
  162.     jQuery(\'input[name=a15][value="\'    + respondent.american   +\'"]\').prop("checked",true);
  163.     jQuery(\'input[name=a16][value="\'    + respondent.education  +\'"]\').prop("checked",true);
  164.     jQuery(\'input[name=a17][value="\'    + respondent.salary     +\'"]\').prop("checked",true);
  165.  
  166.     //submit the quiz to get the results.
  167.     do_submission(respondent);
  168. }
  169.  
  170. // submit the form after writing a note-to-self to remind us what we are doing when we wake up
  171. // from the page load.
  172. function do_submission(respondent) {
  173.  
  174.     // write a little note-to-self so that we know who we are and what we\'re supposed to be doing when
  175.     // we wake up after browser reload. Then submit.
  176.     var fname = respondent.fname;
  177.  
  178.     write_note_to_self(fname, \'ready to process results\');
  179.  
  180.     // store the respondent away so he/she doesn\'t get vaporized when the the results page gets
  181.     //loaded.
  182.     r = cryogenic_suspension(respondent, \'sleep\');
  183.  
  184.     // submit once the responcence is safely in their chamber, or let us know if something goes wrong.
  185.     if (r === true) jQuery("#submit-quiz").submit(); else console.log("Cryo-pod malfunction.");
  186. }
  187.  
  188. // once the quiz has been submitted, the results need to be processed. process_results() scrapes the scores
  189. // from the screen and puts them in the responents jacket pocket (the inner one) for safe keeping until all the
  190. // passes are done, when they can be output to the console.
  191. function process_results(respondent) {
  192.  
  193.     var hos     =   jQuery(\'#highcharts-0 svg g g:first-child text tspan\').html();  // the location of the result for hostile sexism in the html.
  194.     var ben     =   jQuery(\'#highcharts-2 svg g g:first-child text tspan\').html();  // the location of the result for benevolent sexism in the html.
  195.     var foc     =   respondent.current_focus_question;                              // the question the respondent is currently recursing over with all the possible permutations.
  196.     var val     =   respondent.response_variation_value;                            // the current option permutation we are getting results for.
  197.     var pass    =   respondent.current_pass;                                        // current pass of the quiz. 72 passes will be made in total.
  198.  
  199.     //load up an array of the results
  200.     var result = {
  201.         \'pass\': pass,
  202.         \'foc\': foc,
  203.         \'val\': val,
  204.         \'hos\': hos,
  205.         \'ben\': ben
  206.     };
  207.    
  208.     // put this result with the others in the respondent\'s jacket pocket.
  209.     if (respondent.result_set === undefined) respondent.result_set = [result]; else respondent.result_set.push(result);
  210.  
  211.     // if we don\'t already have it, get the results definitions and average scores for the populace (i think), and put them in our
  212.     // respondent\'s jacket pocket.
  213.     if (respondent.quiz_info.status === false) respondent.quiz_info = quiz_info(respondent);
  214.  
  215.     // along with the results, our respondent is also keeping a note of which question and option they have to do next. level
  216.     //it up. level_up() also calls write_note_to_self() in order to update the status.
  217.     respondent = level_up(respondent);
  218.  
  219.     // put the respondent into a deep, deep, frozen sleep.
  220.     r = cryogenic_suspension(respondent, \'sleep\');
  221.  
  222.     // reset the quiz if the cryogenic suspension goes ok, or let us know if there\'s a problem. then reset the quiz so our respondent
  223.     // can do another pass, or output the results if he or she has done all 72 passes.
  224.     if (r === true) reset_quiz(); else console.log(\'Uhm... there was a bit of an issue with cryogenisis...\');
  225. }
  226.  
  227. function quiz_info(respondent) {
  228.  
  229.     //info from results page
  230.     var hos_def         = jQuery(\'.results-description:eq(0) > p\').text();  // definition of hostile sexismm
  231.     var ben_def         = jQuery(\'.results-description:eq(1) > p\').text();  // defiinition of benevolent sexism
  232.  
  233.     var hos_male            = jQuery(\'#highcharts-0 > svg > g.highcharts-data-labels > g:nth-child(2) > text > tspan\').text();  // average scores (for populace, i guess)
  234.     var hos_fem             = jQuery(\'#highcharts-0 > svg > g.highcharts-data-labels > g:nth-child(3) > text > tspan\').text();  // average scores (for populace, i guess)
  235.     var ben_male            = jQuery(\'#highcharts-2 > svg > g.highcharts-data-labels > g:nth-child(2) > text > tspan\').text();  // average scores (for populace, i guess)
  236.     var ben_fem             = jQuery(\'#highcharts-2 > svg > g.highcharts-data-labels > g:nth-child(3) > text > tspan\').text();  // average scores (for populace, i guess)
  237.  
  238.     var quiz_info = {\'status\': true, \'hos_def\': hos_def, \'ben_def\': ben_def, \'hos_male\': hos_male, \'hos_fem\': hos_fem, \'ben_male\': ben_male, \'ben_fem\': ben_fem};
  239.  
  240.     return quiz_info;
  241. }
  242.  
  243. // do another pass of the quiz. resets the form and goes back to the beginning.
  244. function reset_quiz() {
  245.  
  246.     window.location.assign(\'http://www.pbs.org/newshour/data/quiz/ambivalent-sexism?clear=true\');
  247. }
  248.  
  249. function do_debrief(respondent) {
  250.  
  251.     var fname = respondent.fname;
  252.  
  253.     //output the result set.
  254.     output_result_set(respondent);
  255.  
  256.     // output the codebook;
  257.     output_codebook(respondent);
  258.  
  259.     //output the definitions of terms and population averages from the results page.
  260.     output_quiz_info(respondent);
  261.  
  262.     // write our little \'read me\' note to update the respondent\'s status to indicate a job well done.
  263.     write_note_to_self(fname, \'done\');
  264.  
  265.     //retire our respondent
  266.     r = cryogenic_suspension(fname, \'sleep\');
  267.  
  268.     console.log(\'mission accomplished!\');
  269. }
  270.  
  271. // ok! all passes of the quiz have been completed and it\'s time to harvest the results. print to
  272. // the console in a ramshackle kind of csv format that can be tidied up fairly easily, afterwards.
  273. function output_result_set(respondent) {
  274.  
  275.     var fname       =   respondent.fname;
  276.     var gen         =   respondent.gender;
  277.     var age         =   respondent.age;
  278.     var american    =   respondent.american;
  279.     var edu         =   respondent.education;
  280.     var sal         =   respondent.salary;
  281.     var res         =   respondent.result_set;
  282.  
  283.     /// csv header
  284.     var w = window.open();
  285.  
  286.     w.document.writeln(\'<h2>Result Set</h2><br>\');
  287.     w.document.writeln(\'name,gender,age,american,education,salary,pass,question,value,hostile,benevolent\');
  288.     w.document.writeln(\'<br>\');
  289.  
  290.     for (var i = 0; i < res.length; i++) {
  291.  
  292.         // csv values. go through all the result slips in the respondent\'s tweed jacket pocket. The
  293.         // tweed is either being worn ironically or not, depending on the personal details provided
  294.         // for our respondent.
  295.         w.document.writeln(fname + \',\' + gen + \',\' + age + \',\' + american + \',\' + edu + \',\' + \'"\' + sal + \'"\'+ \',\' + respondent.result_set[i].pass + \',\' + respondent.result_set[i].foc + \',\' + respondent.result_set[i].val + \',\' + respondent.result_set[i].hos + \',\' + respondent.result_set[i].ben);
  296.         w.document.writeln(\'<br>\');
  297.     }
  298. }
  299.  
  300. // output the codebook as a list of questions and response levels, in a separate browser window.
  301. // this can be copied and pasted from the browser window and saved as a text file.
  302. function output_codebook(respondent) {
  303.  
  304.     var sorted_keys = Object.keys(respondent.codebook).sort();
  305.  
  306.     var w = window.open();
  307.  
  308.     w.document.writeln(\'<h2>Codebook</h2><br>\');
  309.  
  310.     for (var q = 0; q < 17; q++) {
  311.  
  312.         var lev = respondent.codebook[Object.keys(respondent.codebook)[q]].length;
  313.  
  314.         w.document.writeln(\'<ul style="list-style:none;"><li>\' + Object.keys(respondent.codebook)[q] + \'<ul style="list-style:none;">\');
  315.  
  316.         for (var a = 0; a < lev; a++) {
  317.  
  318.             w.document.writeln(\'<li> &nbsp; &nbsp; [\' + a + \'] \' + respondent.codebook[Object.keys(respondent.codebook)[q]][a] + \'</li>\');
  319.         }
  320.  
  321.         w.document.writeln(\'</ul></li><br>\');
  322.  
  323.         w.document.writeln(\'</ul>\');
  324.     }
  325. }
  326.  
  327. // output the quiz info in a separate browser window. this can be copied and pasted from the browser window and saved as a text file.
  328. function output_quiz_info(respondent) {
  329.  
  330.     var hos_def = respondent.quiz_info.hos_def;
  331.     var ben_def = respondent.quiz_info.ben_def;
  332.     var hos_male = respondent.quiz_info.hos_male;
  333.     var hos_fem = respondent.quiz_info.hos_fem;
  334.     var ben_male = respondent.quiz_info.ben_male;
  335.     var ben_fem = respondent.quiz_info.ben_fem;
  336.  
  337.     var w = window.open();
  338.  
  339.     w.document.writeln(\'<h2>Quiz Info</h2><br>\');
  340.  
  341.     w.document.writeln(\'<p><b>Definitions</b></p>\');
  342.     w.document.writeln(\'<p>\' + hos_def + \'</p>\');
  343.     w.document.writeln(\'<p>\' + ben_def + \'</p>\');
  344.  
  345.     w.document.writeln(\'<p><b>Population averages</b></p>\');
  346.     w.document.writeln(\'<p>Hostile sexism average - male: \' + hos_male + \'</p>\');
  347.     w.document.writeln(\'<p>Hostile sexism average - female: \' + hos_fem + \'</p>\');
  348.     w.document.writeln(\'<p>Benevolent sexism average - male: \' + ben_male + \'</p>\');
  349.     w.document.writeln(\'<p>Benevolent sexism average - female: \' + ben_fem + \'</p>\');
  350. }
  351.  
  352. // we\'ve finished a pass of the quiz, so lets write an entry in our journal to remind us where we\'re at -
  353. // we\'ll have been to sleep by the next time we need to know!
  354. function level_up(respondent) {
  355.  
  356.     var current_focus_question      =   respondent.current_focus_question;
  357.     var response_variation_value    =   respondent.response_variation_value;
  358.     var pass                        =   respondent.current_pass;
  359.  
  360.     //if we haven\'t iterated though all the possible responses to the current question...
  361.     if (response_variation_value < 5) {
  362.  
  363.         // set our reminder to the next response.
  364.         response_variation_value++;
  365.         pass++;
  366.         write_note_to_self(respondent.fname, \'ready for next pass\');
  367.  
  368.         // if we have made all possible responses to the current question but we haven\'t gone through all the questions, yet...
  369.     } else if (current_focus_question < 12) {
  370.  
  371.         //set our reminder to start the next question.
  372.         response_variation_value = 0;
  373.         current_focus_question++;
  374.         pass++;
  375.         write_note_to_self(respondent.fname, \'ready for next pass\');
  376.  
  377.         // if we\'ve done all responses to all questions...
  378.     } else {
  379.  
  380.         // set our reminder to indicate such state of affairs.
  381.         write_note_to_self(respondent.fname, \'ready to output results\');
  382.     }
  383.  
  384.     // put the reminder in our respondent\'s inside jacket pocket. next to their heart.
  385.     respondent.current_focus_question   = current_focus_question;
  386.     respondent.response_variation_value = response_variation_value;
  387.     respondent.current_pass             = pass;
  388.  
  389.     return respondent;
  390. }
  391.  
  392. // write a little note-to-self to remind us who we are and what we\'re supposed to be doing
  393. // when we wake up... am i right, guys? eh? am i right?
  394. function write_note_to_self(respondent_fname, status) {
  395.  
  396.     // pack an array with the name of the respondent (by which they are awoken from thier slumber)
  397.     // and their status along the production line of this quiz.
  398.  
  399.     var note_to_self = {
  400.         \'fname\': respondent_fname,
  401.         \'status\': status
  402.     };
  403.  
  404.     //sessionStorage only accepts strings, so turn the array into a json string.
  405.     var read_me = JSON.stringify(note_to_self);
  406.  
  407.     // put the note somewhere our respondent will see it.
  408.     sessionStorage.setItem(\'read_me\', read_me);
  409.  
  410.     return true;
  411. }
  412.  
  413. //cryogenically suspend our respondent so that he doesn\'t get vaporized by the page-load
  414. //pay-load.
  415. function cryogenic_suspension(respondent, mode) {
  416.  
  417.     // if we\'re in sleep mode, put the respondent in a frozen sleep to evade the memory apocolypse that
  418.     // is a browser reload.
  419.     if (mode == \'sleep\') {
  420.  
  421.         suspended_respondent = JSON.stringify(respondent);
  422.  
  423.         sessionStorage.setItem(respondent.fname, suspended_respondent);
  424.  
  425.         return true;
  426.  
  427.         // if we are in wake mode, then the angel of death has passed over and we can thaw out our
  428.         //respondent and set them about their task once more.
  429.     } else if (mode == \'wake\') {
  430.  
  431.         fetched_respondent = sessionStorage.getItem(respondent);
  432.         awoken_respondent  = JSON.parse(fetched_respondent);
  433.  
  434.         return awoken_respondent;
  435.     }
  436. }
  437.  
  438. function stereotyped_respondent(description) {
  439.  
  440.     var r;
  441.  
  442.     if (description == \'male student\') r = new respondent(\'stuart\', \'male\', \'18-34\', \'no response\', \'high school or less\', \'< $30,000\');
  443.     if (description == \'female student\') r = new respondent(\'sally\', \'female\', \'18-34\', \'no response\', \'high school or less\', \'< $30,000\');
  444.     if (description == \'male professional\') r = new respondent(\'patrick\', \'male\', \'35-50\', \'no response\', \'bachelors degree or more\', \'$30,000 - $74,999\');
  445.     if (description == \'male professional\') r = new respondent(\'polly\', \'female\', \'35-50\', \'no response\', \'bachelors degree or more\', \'$30,000 - $74,999\');
  446.     if (description == \'Hugh Hefner\') r = new respondent(\'Hugh\', \'male\', \'88+\', \'no response\', \'bachelors degree or more\', \'> $75,000\');
  447.     if (description == \'Queen Elizabeth\') r = new respondent(\'Lizzy\', \'female\', \'88+\', \'no response\', \'high school or less\', \'> $75,000\');
  448.  
  449.     return r;
  450. }
  451.  
  452. function context_page() {
  453.  
  454.     // open the context page on pbs website.
  455.     var w = window.open(\'http://www.pbs.org/newshour/rundown/are-you-sexist-take-this-quiz/\');
  456. }
  457.  
  458. // clip out variable definitions, average scores, and other information from the quiz, to give us some background
  459. // information. put this in our respondent\'s jacket pocket.
  460.  
  461.  
  462. //  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
  463. //  v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v
  464. // -------------------> start the ball rolling <----------------------------- <--
  465. //                                                                          |
  466. //-->   -------------- read me ---------------------------------------------- <--
  467. memento();
  468. //-->   ---------------------------- // memento boots the whole thing up      <--
  469. //                                  //each time a new page is loaded
  470. //                                                                      |     <--
  471. ///////////////////////////////------------------------------------------
  472. // ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^
  473. // |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
');