From 19d95cfb8587170487d360ab1a5ca77fb4307c9d Mon Sep 17 00:00:00 2001 From: Matt Lott Date: Wed, 24 Dec 2014 16:56:57 -0800 Subject: [PATCH] Average code problem count for level rates script --- .../analytics/mongodb/queries/levelRates.js | 85 +++++++++++++++---- 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/scripts/analytics/mongodb/queries/levelRates.js b/scripts/analytics/mongodb/queries/levelRates.js index 9885f20dd..d0a7c844c 100644 --- a/scripts/analytics/mongodb/queries/levelRates.js +++ b/scripts/analytics/mongodb/queries/levelRates.js @@ -6,13 +6,14 @@ // Bucketize start/finish events into days, then bucketize into levels // Average playtime: level sessions created in timeframe, state.complete = true, then average 'playtime' +// TODO: Should this be total code problems / levels finished, or total / level session count instead? +// Average code problems: total code problems / levels staretd + // TODO: Why do a small number of 'Started level' not have properties.levelID set? // TODO: spot check the data: NaN, only some 0.0 dates, etc. // TODO: exclude levels with no interesting data? -// TODO: User code problem rate: average count. - var today = new Date(); today = today.toISOString().substr(0, 10); print("Today is " + today); @@ -72,6 +73,13 @@ function getCompletionRates() { if (!levelData[level][created]) levelData[level][created] = {}; if (event === 'Started Level') levelData[level][created]['started'] = doc.count; else levelData[level][created]['finished'] = doc.count; + + // Ensure we have entries for today + if (!levelData[level][today]) { + levelData[level][today] = {}; + levelData[level][today]['started'] = 0; + levelData[level][today]['finished'] = 0; + } } longestLevelName += 2; @@ -135,11 +143,9 @@ function addPlaytimeAverages(levelRates) { var doc = cursor.next(); var created = doc._id.created; var level = doc._id.level; - if (!levelPlaytimeData[level]) levelPlaytimeData[level] = {}; levelPlaytimeData[level][created] = doc.average; } - // printjson(levelPlaytimeData); for (levelIndex in levelRates) { for (dateIndex in levelRates[levelIndex]) { @@ -152,33 +158,75 @@ function addPlaytimeAverages(levelRates) { } } +function addUserCodeProblemCounts(levelRates) { + print("Getting user code problem counts..."); + var match = {"$match" : {"created": { $gte: ISODate(startDate)}}}; + + var proj0 = {"$project": { + "_id" : 0, + "levelID" : 1, + "created": { "$concat": [{"$substr" : ["$created", 0, 4]}, "-", {"$substr" : ["$created", 5, 2]}, "-", {"$substr" : ["$created", 8, 2]}]} + }}; + + var group = {"$group" : { + "_id" : { + "created" : "$created", + "level": "$levelID" + }, + "count" : { + "$sum" : 1 + } + }}; + + var cursor = db['level.sessions'].aggregate(match, proj0, group); + + var levelPlaytimeData = {}; + while (cursor.hasNext()) { + var doc = cursor.next(); + var created = doc._id.created; + var level = doc._id.level; + if (!levelPlaytimeData[level]) levelPlaytimeData[level] = {}; + levelPlaytimeData[level][created] = doc.count; + } + + for (levelIndex in levelRates) { + for (dateIndex in levelRates[levelIndex]) { + var level = levelRates[levelIndex][dateIndex].level; + var created = levelRates[levelIndex][dateIndex].created; + if (levelPlaytimeData[level] && levelPlaytimeData[level][created]) { + levelRates[levelIndex][dateIndex].codeProblems = levelPlaytimeData[level][created]; + } + } + } +} + var longestLevelName = -1; var dates = []; var levelRates = getCompletionRates(); -// print("Before addPlaytimeAverages"); -// printjson(levelRates); addPlaytimeAverages(levelRates); -// print("After addPlaytimeAverages"); -// printjson(levelRates); +addUserCodeProblemCounts(levelRates); // Print out all data -print("Columns: level, day, started, finished, completion rate, average finish playtime"); +print("Columns: level, day, started, finished, completion rate, average finish playtime, average code problem count"); for (levelKey in levelRates) { for (dateKey in levelRates[levelKey]) { var created = levelRates[levelKey][dateKey].created; var level = levelRates[levelKey][dateKey].level; var started = levelRates[levelKey][dateKey].started; var finished = levelRates[levelKey][dateKey].finished; - var completionRate = finished / started; + var completionRate = started > 0 ? finished / started : 0; var averagePlaytime = levelRates[levelKey][dateKey].averagePlaytime; + averagePlaytime = averagePlaytime ? Math.round(averagePlaytime) : 0; + var averageCodeProblems = levelRates[levelKey][dateKey].codeProblems; + averageCodeProblems = averageCodeProblems ? (averageCodeProblems / started).toFixed(2) : 0.0; var levelSpacer = new Array(longestLevelName - level.length).join(' '); - print(level + levelSpacer + created + "\t" + started + "\t" + finished + "\t" + (finished / started * 100).toFixed(2) + "% " + (averagePlaytime ? Math.round(averagePlaytime) : -1) + "s"); + print(level + levelSpacer + created + "\t" + started + "\t" + finished + "\t" + (completionRate * 100).toFixed(2) + "% " + averagePlaytime + "s " + averageCodeProblems); } } // Print out a nice grid of levels with 7 days of data -print("Columns: level, completion rate, average playtime, completion rate, average playtime, etc..."); +print("Columns: level, completion rate/average playtime/average code problems, completion rate/average playtime/average code problems ..."); print(new Array(longestLevelName).join(' ') + dates.join('\t\t')); for (levelKey in levelRates) { var hasStarted = false; @@ -190,7 +238,7 @@ for (levelKey in levelRates) { } if (!hasStarted) continue; - if (levelRates[levelKey].length < 7) continue; + if (levelRates[levelKey].length < 6) continue; var level = levelRates[levelKey][0].level; var levelSpacer = new Array(longestLevelName - level.length).join(' '); @@ -201,10 +249,11 @@ for (levelKey in levelRates) { var started = levelRates[levelKey][dateKey].started; var finished = levelRates[levelKey][dateKey].finished; var averagePlaytime = levelRates[levelKey][dateKey].averagePlaytime; - var rate = finished / started; - msg += (finished / started * 100).toFixed(2) + "\t" + (averagePlaytime ? Math.round(averagePlaytime) : -1) + "\t"; - // print(level + levelSpacer + started + "\t" + finished + "\t" + (finished / started * 100).toFixed(2) + "%"); - // print(levelRates[key].level + "\t" + started + "\t" + finished + "\t" + (levelRates[key].rate * 100).toFixed(2) + "%"); + averagePlaytime = averagePlaytime ? Math.round(averagePlaytime) : 0; + var averageCodeProblems = levelRates[levelKey][dateKey].codeProblems; + averageCodeProblems = averageCodeProblems ? averageCodeProblems / started : 0.0; + var completionRate = started > 0 ? finished / started : 0; + msg += (completionRate * 100).toFixed(2) + "/" + averagePlaytime + "/" + averageCodeProblems.toFixed(2) + "\t"; } print(msg); -} +} \ No newline at end of file