diff --git a/analysis/analyse.js b/analysis/analyse.js index 08f8ca3..b0a2704 100644 --- a/analysis/analyse.js +++ b/analysis/analyse.js @@ -1,3 +1,40 @@ +// http://codereview.stackexchange.com/questions/37028/grouping-elements-in-array-by-multiple-properties +function groupBy(array, f) +{ + var groups = {}; + array.forEach(function(o) { + var group = JSON.stringify(f(o)); + groups[group] = groups[group] || []; + groups[group].push(o); + }); + + return Object.keys(groups).map(function(group) { + return groups[group]; + }) +} + +function compareRecommendationStyle(style1, style2) { + + if (style1.recommendation_style[4] === 'B' && style2.recommendation_style[4] !== 'B') { + return -1; + } + + if (style2.recommendation_style[4] === 'B' && style1.recommendation_style[4] !== 'B') { + return 1; + } + + if (style1.recommendation_style[4] === 'V' && style2.recommendation_style[4] === 'A') { + return -1; + } + + if (style2.recommendation_style[4] === 'V' && style1.recommendation_style[4] === 'A') { + return 1; + } + + return 0; + +} + function main(path) { var db = JSON.parse(require('fs').readFileSync(path, 'utf8')); @@ -8,45 +45,152 @@ function main(path) { var meanTimeArrow = 0; var meanTimeViewport = 0; - console.log(); + var groups = makeGroups(db); - for (var i = 0; i < db.experiments.length; i++) { + groups.forEach(function(elt) { + var ok = true; - var exp = db.experiments[i]; - var events = exp.elements.events; - - if (events.length === 0 || exp.user.worker_id === null) { - - continue; - - } - - var coins = []; - for (var j = 0; j < exp.elements.events.length; j++) { - - if (exp.elements.events[j].type === 'coin') { - - if (coins.find(function(elt) { return elt.id === exp.elements.events[j].id; }) === undefined) { - - coins.push(exp.elements.events[j]); - - } + // console.log(elt); + elt.sort(compareRecommendationStyle); + // console.log(elt); + elt.forEach(function(subElt) { + if (subElt.coin_combination_id !== elt[0].coin_combination_id) { + ok = false; } + }); + if (!ok) { + process.stderr.write('Error : assertion failed'); + process.exit(-1); + } + + console.log(elt.length + ' -> ' + elt[0].coin_combination_id); + }); + + console.log('-----------------'); + + var value = minDifferences(groups); + console.log(value); + + // for (var i = 0; i < db.experiments.length; i++) { + + // var exp = db.experiments[i]; + // var events = exp.elements.events; + + // if (events.length === 0 || exp.user.worker_id === null) { + + // continue; + + // } + + // var coins = []; + // for (var j = 0; j < exp.elements.events.length; j++) { + + // if (exp.elements.events[j].type === 'coin') { + + // if (coins.find(function(elt) { return elt.id === exp.elements.events[j].id; }) === undefined) { + + // coins.push(exp.elements.events[j]); + + // } + + // } + + // } + // console.log(`${exp.id} -> ${coins.length} (on ${exp.coinCombination.scene_id} )`); + // } + + // console.log(); + + // for (var i = 0; i < db.users.length; i++) { + + // var user = db.users[i]; + // console.log(`${user.worker_id} has done ${user.experiments.length} experiments with rating ${user.rating}`); + + // } + +} + +function minDifference(exps) { + + var dict = {}; + + exps.forEach(function(subElt) { + dict[subElt.recommendation_style[4]] = subElt.duration; + }); + + if (dict.B !== undefined) { + + if (dict.A !== undefined && dict.V !== undefined) { + return ( + Math.min(dict.A - dict.B, dict.V - dict.B) + ); + } + + if (dict.A !== undefined) { + return dict.A - dict.B; + } + + if (dict.V !== undefined) { + return dict.V - dict.B; } - console.log(`${exp.id} -> ${coins.length} (on ${exp.coinCombination.scene_id} )`); } - console.log(); +} - for (var i = 0; i < db.users.length; i++) { +function minDifferences(groups) { - var user = db.users[i]; - console.log(`${user.worker_id} has done ${user.experiments.length} experiments with rating ${user.rating}`); + var differences = []; + groups.forEach(function(elt) { + + var timesMean = 0; + + elt.forEach(function(elt) { + var duration = experimentDuration(elt); + timesMean += experimentDuration(elt); + }); + + timesMean /= elt.length; + + var normalizedElt = []; + + elt.forEach(function(subElt) { + normalizedElt.push({ + recommendation_style : subElt.recommendation_style, + duration : experimentDuration(subElt) / timesMean + }); + }); + + var diff = minDifference(normalizedElt); + + if (diff !== undefined) + differences.push(diff); + }); + + var sum = 0; + + differences.forEach(function(elt) { + sum += elt; + }); + + return sum / differences.length; + +} + +function experimentDuration(exp) { + var lastCoin = null; + + for (var i = exp.elements.events.length - 1; i >= 0; i--) { + if (exp.elements.events[i].type === 'coin') { + lastCoin = exp.elements.events[i]; + break; + } } + return timeDifference(exp.elements.events[0].time, lastCoin.time); + } function timeDifference(time1, time2) { @@ -63,6 +207,26 @@ function timeToString(_time) { } +function makeGroups(db) { + + var elements = []; + + for (var i = 0; i < db.experiments.length; i++) { + + if (db.experiments[i].coinCombination.scene_id !== 1 && db.experiments[i].elements.events.length !== 0) { + + elements.push(db.experiments[i]); + + } + + } + + return groupBy(elements, function(item) { + return item.coin_combination_id;//, item.user.rating]; + }); + +} + if (process.argv.length !== 3) { process.stderr.write('Error : please give me a JSON file to work on\n'); process.exit(-1); diff --git a/controllers/intro/views/index.jade b/controllers/intro/views/index.jade index e8d45a2..d54928f 100644 --- a/controllers/intro/views/index.jade +++ b/controllers/intro/views/index.jade @@ -12,7 +12,8 @@ block content block extrajs script. - if ($.browser.chrome || $.browser.mozilla) { + var isOpera = window.navigator.userAgent.indexOf("OPR") > -1 || window.navigator.userAgent.indexOf("Opera") > -1; + if (($.browser.chrome || $.browser.mozilla) && !isOpera) { $('#start').html('You can now start when you are ready'); } else { $('#start').html('Sorry, your browser is not compatible... please try again with Firefox or Chrome'); diff --git a/controllers/prototype/views/prototype.jade b/controllers/prototype/views/prototype.jade index 305182f..35b9618 100644 --- a/controllers/prototype/views/prototype.jade +++ b/controllers/prototype/views/prototype.jade @@ -37,8 +37,8 @@ block content //-input#fullarrow(type="checkbox", style={'margin-right': '10px', 'margin-bottom': '10px'}) //-label(for="fullarrow" style={'margin-right':'10px'}) Full arrow - input#lock(type="checkbox", style={'margin-right': '10px', 'margin-bottom': '10px'}, checked) - label(for="lock" style={'margin-right':'10px'}) Pointer lock + input#lock(type="checkbox", style={'zoom':'1.7'}, checked) + label(for="lock" style={'margin-right':'10px', 'zoom': '1.7'}) Pointer lock input#showarrows(type="checkbox", style={'margin-right': '10px', 'margin-bottom': '10px', 'display':'none'}, checked) label(for="showarrows" style={'margin-right':'10px', 'display': 'none'}) Show arrows diff --git a/js/l3d/apps/prototype/tutorial/TutorialSteps.js b/js/l3d/apps/prototype/tutorial/TutorialSteps.js index d4cc4f6..3668a96 100644 --- a/js/l3d/apps/prototype/tutorial/TutorialSteps.js +++ b/js/l3d/apps/prototype/tutorial/TutorialSteps.js @@ -258,7 +258,7 @@ TutorialSteps.prototype.alert = function(myString, justclicked) { TutorialSteps.prototype.notify = function(myString, justclick) { $('#alert-placeholder').html( - '