diff --git a/analysis/analyse.js b/analysis/analyse.js index b0a2704..e1e153c 100644 --- a/analysis/analyse.js +++ b/analysis/analyse.js @@ -1,43 +1,9 @@ -// 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; - -} +var lib = require('./lib.js'); function main(path) { - var db = JSON.parse(require('fs').readFileSync(path, 'utf8')); + var db = lib.loadFromFile(path); + var groups = lib.makeGroups(db); console.log(`There were ${db.users.length} users for ${db.experiments.length} experiments`); @@ -45,7 +11,6 @@ function main(path) { var meanTimeArrow = 0; var meanTimeViewport = 0; - var groups = makeGroups(db); groups.forEach(function(elt) { var ok = true; @@ -73,43 +38,6 @@ function main(path) { 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) { @@ -179,54 +107,6 @@ function minDifferences(groups) { } -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) { - - return new Date(time2).getTime() - new Date(time1).getTime(); - -} - -function timeToString(_time) { - - var time = _time / 1000; - - return Math.floor(time / 3600) + 'h' + Math.floor((time % 3600) / 60) + 'm' + Math.floor(time % 60); - -} - -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/analysis/lib.js b/analysis/lib.js new file mode 100644 index 0000000..3f9221a --- /dev/null +++ b/analysis/lib.js @@ -0,0 +1,182 @@ +var Lib = module.exports; + +// http://codereview.stackexchange.com/questions/37028/grouping-elements-in-array-by-multiple-properties +Lib.groupBy = function(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 letterToInt(letter) { + switch (letter) { + case 'B': return 0; + case 'V': return 1; + case 'A': return 2; + default: return null; + } +} + +Lib.compareRecommendationStyle = function(style1, style2) { + + return letterToInt(style1.recommendation_style[4]) - letterToInt(style2.recommendation_style[4]); + +}; + +Lib.experimentDuration = function(exp) { + + if (exp === undefined) { + + return; + + } + + 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 Lib.timeDifference(exp.elements.events[0].time, lastCoin.time); + +}; + +Lib.max = function(elt1, elt2) { + + if (elt1 === undefined) + return elt2; + + if (elt2 === undefined) + return elt1; + + return Math.max(elt1,elt2); + +}; + +Lib.min = function(elt1, elt2) { + + if (elt1 === undefined) + return elt2; + + if (elt2 === undefined) + return elt1; + + return Math.min(elt1,elt2); + +}; + +Lib.timeDifference = function(time1, time2) { + + return new Date(time2).getTime() - new Date(time1).getTime(); + +}; + +Lib.timeToString = function(_time) { + + var time = _time / 1000; + + return Math.floor(time / 3600) + 'h' + Math.floor((time % 3600) / 60) + 'm' + Math.floor(time % 60); + +}; + +Lib.makeGroups = function(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 Lib.groupBy(elements, function(item) { + return item.coin_combination_id;//, item.user.rating]; + }); + +}; + +Lib.loadFromFile = function(path) { + + return JSON.parse(require('fs').readFileSync(path, 'utf8')); + +}; + +Lib.toMatlabArray = function(name, array) { + + var str = name + ' = [ '; + + array.forEach(function(elt) { str += ' ' + elt + ' '; }); + + str += '];\n'; + + return str; + +}; + +// http://stackoverflow.com/questions/3895478/ +Lib.range = function(start, stop, step, computation) { + + if (typeof step === 'function') { + + computation = step; + step = 1; + + } + + if (computation === undefined) { + + computation = function(i) { return i; }; + + } + + if (step === undefined) { + + step = 1; + + } + + var a = []; + while (start < stop) { + a.push(computation(start)); + start += step; + } + return a; +}; + +// Simplified version +Lib.numberOfInteraction = function(exp) { + + if (exp === undefined) { + + return; + + } + + + 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 i; + +}; diff --git a/analysis/matlab/script.m b/analysis/matlab/script.m new file mode 100644 index 0000000..b59012f --- /dev/null +++ b/analysis/matlab/script.m @@ -0,0 +1,7 @@ +var; +plot(X,Y1); +hold on; +plot(X, Y2, 'red'); +hold on; +plot(X, Y3, 'green'); +legend('Without recommendation', 'Worst with recommendation', 'Best with recommendation'); diff --git a/analysis/numberOfInteractionCurve.js b/analysis/numberOfInteractionCurve.js new file mode 100644 index 0000000..ecc2129 --- /dev/null +++ b/analysis/numberOfInteractionCurve.js @@ -0,0 +1,45 @@ +// Shows with and without : time to last coin = f(CoinCombination) + +var lib = require('./lib.js'); + + +function main(path) { + + var db = lib.loadFromFile(path); + var groups = lib.makeGroups(db); + + // Erase groups that are not usable + groups = groups.filter(function(elt) { + + // An elt is valid if it contains at least 2 exp, BaseRecommendation included + return elt.length > 1 && elt.find(function(e) { return e.recommendation_style[4] === 'B'; }) !== undefined; + + }); + + groups.forEach(function(elt) { + elt.sort(lib.compareRecommendationStyle); + }); + + console.log(lib.toMatlabArray('X', lib.range(0, groups.length))); + + console.log(lib.toMatlabArray('Y1', lib.range(0, groups.length, function(i) { + return lib.numberOfInteraction(groups[i][0]); + }))); + + console.log(lib.toMatlabArray('Y2', lib.range(0, groups.length, function(i) { + return lib.max(lib.numberOfInteraction(groups[i][1]), lib.numberOfInteraction(groups[i][2])); + }))); + + console.log(lib.toMatlabArray('Y3', lib.range(0, groups.length, function(i) { + return lib.min(lib.numberOfInteraction(groups[i][1]), lib.numberOfInteraction(groups[i][2])); + }))); + +} + +if (process.argv.length !== 3) { + process.stderr.write('Error : please give me a JSON file to work on\n'); + process.exit(-1); +} + +main(process.argv[2]); + diff --git a/analysis/timeCurve.js b/analysis/timeCurve.js new file mode 100644 index 0000000..5ef627c --- /dev/null +++ b/analysis/timeCurve.js @@ -0,0 +1,45 @@ +// Shows with and without : time to last coin = f(CoinCombination) + +var lib = require('./lib.js'); + + +function main(path) { + + var db = lib.loadFromFile(path); + var groups = lib.makeGroups(db); + + // Erase groups that are not usable + groups = groups.filter(function(elt) { + + // An elt is valid if it contains at least 2 exp, BaseRecommendation included + return elt.length > 1 && elt.find(function(e) { return e.recommendation_style[4] === 'B'; }) !== undefined; + + }); + + groups.forEach(function(elt) { + elt.sort(lib.compareRecommendationStyle); + }); + + console.log(lib.toMatlabArray('X', lib.range(0, groups.length))); + + console.log(lib.toMatlabArray('Y1', lib.range(0, groups.length, function(i) { + return lib.experimentDuration(groups[i][0]); + }))); + + console.log(lib.toMatlabArray('Y2', lib.range(0, groups.length, function(i) { + return lib.max(lib.experimentDuration(groups[i][1]), lib.experimentDuration(groups[i][2])); + }))); + + console.log(lib.toMatlabArray('Y3', lib.range(0, groups.length, function(i) { + return lib.min(lib.experimentDuration(groups[i][1]), lib.experimentDuration(groups[i][2])); + }))); + +} + +if (process.argv.length !== 3) { + process.stderr.write('Error : please give me a JSON file to work on\n'); + process.exit(-1); +} + +main(process.argv[2]); +