From 9bb9152df0ae57edfa6d8abc0628f68875ee7d39 Mon Sep 17 00:00:00 2001
From: Evan Welsh <2943271+ewlsh@users.noreply.github.com>
Date: Sat, 3 Oct 2020 13:38:14 -0500
Subject: [PATCH 01/16] Switch primary branch to main.
---
.github/workflows/cd.yml | 2 +-
README.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml
index 6797cbf39..e191afa52 100644
--- a/.github/workflows/cd.yml
+++ b/.github/workflows/cd.yml
@@ -2,7 +2,7 @@ name: CD
on:
push:
branches:
- - master
+ - main
jobs:
deploy:
diff --git a/README.md b/README.md
index 80900c3ee..74beb50d3 100644
--- a/README.md
+++ b/README.md
@@ -72,5 +72,5 @@ _Screenshots showing major parts of app_
We are a team within **Cornell Design & Tech Initiative**. For more information, see our [website](https://cornelldti.org/).
-
+
From f43cef0f25883ce64b59340a13b8e936c15eb067 Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Sat, 9 Nov 2024 21:53:21 -0500
Subject: [PATCH 02/16] added month and day fields
---
src/scripts/wrapped-fa24.js | 370 ++++++++++++++++++++++++++++++++++++
src/scripts/wrapped-fa24.ts | 279 +++++++++++++++++++++------
2 files changed, 593 insertions(+), 56 deletions(-)
create mode 100644 src/scripts/wrapped-fa24.js
diff --git a/src/scripts/wrapped-fa24.js b/src/scripts/wrapped-fa24.js
new file mode 100644
index 000000000..d67453c88
--- /dev/null
+++ b/src/scripts/wrapped-fa24.js
@@ -0,0 +1,370 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (_) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+exports.__esModule = true;
+var firebase_admin_1 = require("firebase-admin");
+firebase_admin_1["default"].initializeApp({
+ credential: firebase_admin_1["default"].credential.applicationDefault(),
+ databaseURL: 'https://qmi-test.firebaseio.com'
+});
+// eslint-disable-next-line no-console
+console.log('Firebase admin initialized!');
+// Initialize Firestore
+var db = firebase_admin_1["default"].firestore();
+var errorUsers = [];
+// Firestore Timestamps for the query range
+var startDate = firebase_admin_1["default"].firestore.Timestamp.fromDate(new Date('2024-01-22'));
+var endDate = firebase_admin_1["default"].firestore.Timestamp.fromDate(new Date('2024-11-22'));
+var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function () {
+ var questionsRef, sessionsRef, wrappedRef, usersRef, questionsSnapshot, userStats, getWrappedUserDocs, taCounts, officeHourSessions, TAsessions, updateWrappedDocs, initializeUser, _loop_1, _i, _a, doc, _loop_2, _b, _c, _d, userId, stats;
+ var _e, _f, _g, _h, _j, _k, _l, _m, _o;
+ return __generator(this, function (_p) {
+ switch (_p.label) {
+ case 0:
+ questionsRef = db.collection('questions-test');
+ sessionsRef = db.collection('sessions-test');
+ wrappedRef = db.collection('wrapped-fa24');
+ usersRef = db.collection('users-test');
+ return [4 /*yield*/, questionsRef
+ .where('timeEntered', '>=', startDate)
+ .where('timeEntered', '<=', endDate)
+ .get()];
+ case 1:
+ questionsSnapshot = _p.sent();
+ userStats = {};
+ getWrappedUserDocs = function () { return __awaiter(void 0, void 0, void 0, function () {
+ var docs;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ docs = {};
+ return [4 /*yield*/, Promise.all(Object.keys(userStats).map(function (id) { return __awaiter(void 0, void 0, void 0, function () {
+ var _a, _b;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ if (!id) return [3 /*break*/, 2];
+ _a = docs;
+ _b = id;
+ return [4 /*yield*/, usersRef.doc(id).get()];
+ case 1:
+ _a[_b] = _c.sent();
+ _c.label = 2;
+ case 2: return [2 /*return*/];
+ }
+ });
+ }); }))];
+ case 1:
+ _a.sent();
+ return [2 /*return*/, docs];
+ }
+ });
+ }); };
+ taCounts = {};
+ officeHourSessions = {};
+ TAsessions = {};
+ updateWrappedDocs = function () { return __awaiter(void 0, void 0, void 0, function () {
+ var batch, userDocuments, _i, _a, _b, userId, stats, hasVisits, isUserActive, hasFavoriteTa, wrappedDocRef, userDoc;
+ var _c;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ batch = db.batch();
+ return [4 /*yield*/, getWrappedUserDocs()];
+ case 1:
+ userDocuments = _d.sent();
+ for (_i = 0, _a = Object.entries(userStats); _i < _a.length; _i++) {
+ _b = _a[_i], userId = _b[0], stats = _b[1];
+ // Only want to make wrapped changes for a user if they have an ID and are active
+ if (userId) {
+ hasVisits = stats.numVisits > 0;
+ isUserActive = stats.timeHelpingStudents === undefined || (((_c = TAsessions[userId]) === null || _c === void 0 ? void 0 : _c.length) > 0);
+ hasFavoriteTa = stats.favTaId !== "";
+ if (hasVisits && isUserActive && hasFavoriteTa) {
+ wrappedDocRef = wrappedRef.doc(userId);
+ batch.set(wrappedDocRef, stats);
+ userDoc = userDocuments[userId];
+ if (userDoc.exists) {
+ usersRef.doc(userId).update({
+ wrapped: true
+ });
+ }
+ else {
+ // Handle the case where the document does not exist
+ errorUsers.push({ user: userId, error: "No document found for this user, skipping update." });
+ }
+ }
+ else {
+ errorUsers.push({ user: userId, error: "User is not an active student/TA" });
+ }
+ }
+ else {
+ errorUsers.push({ user: userId, error: "User ID is undefined, skipping update." });
+ }
+ }
+ return [4 /*yield*/, batch.commit()];
+ case 2:
+ _d.sent();
+ return [2 /*return*/];
+ }
+ });
+ }); };
+ initializeUser = function (answererId, askerId) {
+ var _a;
+ // if an instance doesn't exist yet for the user, creating one
+ if (!userStats[askerId]) {
+ userStats[askerId] = {
+ numVisits: 0,
+ favClass: '',
+ favTaId: '',
+ totalMinutes: 0,
+ personalityType: ''
+ };
+ taCounts[askerId] = new Map();
+ officeHourSessions[askerId] = [];
+ }
+ if (!userStats[answererId]) {
+ userStats[answererId] = {
+ numVisits: 0,
+ favClass: '',
+ favTaId: '',
+ totalMinutes: 0,
+ personalityType: '',
+ timeHelpingStudents: 0
+ };
+ taCounts[answererId] = new Map();
+ officeHourSessions[answererId] = [];
+ TAsessions[answererId] = [];
+ // Checking if ta already showed up as student and now as an answerer
+ }
+ else if (userStats[answererId] && ((_a = userStats[answererId]) === null || _a === void 0 ? void 0 : _a.timeHelpingStudents) === undefined) {
+ userStats[answererId] = {
+ numVisits: userStats[answererId].numVisits,
+ favClass: userStats[answererId].favClass,
+ favTaId: userStats[answererId].favTaId,
+ totalMinutes: userStats[answererId].totalMinutes,
+ personalityType: userStats[answererId].personalityType,
+ timeHelpingStudents: 0
+ };
+ taCounts[answererId] = new Map();
+ officeHourSessions[answererId] = [];
+ TAsessions[answererId] = [];
+ }
+ };
+ _loop_1 = function (doc) {
+ var question, answererId, askerId, sessionId, timeEntered, timeAddressed, sessionDoc, timeHelping, taAmt, minutesSpent;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ question = doc.data();
+ answererId = question.answererId, askerId = question.askerId, sessionId = question.sessionId, timeEntered = question.timeEntered, timeAddressed = question.timeAddressed;
+ initializeUser(answererId, askerId);
+ return [4 /*yield*/, sessionsRef.doc(sessionId).get()];
+ case 1:
+ sessionDoc = _a.sent();
+ if (TAsessions[answererId].find(function (TAsession) { return TAsession.session === sessionId; }) === undefined) {
+ /* Since TA was active during this session and this is the first
+ time encountering the session, we add it to their timeHelped */
+ if (sessionDoc.exists && userStats[answererId].timeHelpingStudents !== undefined) {
+ timeHelping = (sessionDoc.get('endTime').toDate().getTime()
+ - sessionDoc.get('startTime').toDate().getTime()) / 60000;
+ // this should never be less than 0 (or 0, really)
+ if (timeHelping >= 0) {
+ userStats[answererId].timeHelpingStudents =
+ ((_e = userStats[answererId].timeHelpingStudents) !== null && _e !== void 0 ? _e : 0) + timeHelping;
+ }
+ }
+ }
+ officeHourSessions[askerId] = officeHourSessions[askerId] || [];
+ if (!officeHourSessions[askerId].includes(sessionId)) {
+ officeHourSessions[askerId].push(sessionId);
+ }
+ if (answererId !== undefined && answererId !== "") {
+ // eslint-disable-next-line no-console
+ console.log(sessionDoc.get('startTime').toDate());
+ // eslint-disable-next-line no-console
+ console.log(sessionDoc.get('startTime').toDate().getDay());
+ // eslint-disable-next-line no-console
+ console.log(sessionDoc.get('startTime').toDate().getMonth());
+ // eslint-disable-next-line no-console
+ console.log("-------");
+ (_f = TAsessions[answererId]) === null || _f === void 0 ? void 0 : _f.push({
+ session: sessionId,
+ asker: askerId,
+ courseId: sessionDoc.get('courseId'),
+ day: sessionDoc.get('startTime').toDate().getDay()
+ });
+ if (!((_g = taCounts[askerId]) === null || _g === void 0 ? void 0 : _g.has(answererId))) {
+ (_h = taCounts[askerId]) === null || _h === void 0 ? void 0 : _h.set(answererId, 1);
+ }
+ else if (answererId !== undefined && ((_j = taCounts[askerId]) === null || _j === void 0 ? void 0 : _j.has(answererId))) {
+ taAmt = (_k = taCounts[askerId]) === null || _k === void 0 ? void 0 : _k.get(answererId);
+ taAmt && ((_l = taCounts[askerId]) === null || _l === void 0 ? void 0 : _l.set(answererId, taAmt + 1));
+ }
+ }
+ // Minutes spent at office hours
+ if (timeEntered) {
+ if (timeAddressed) {
+ minutesSpent = (timeAddressed.toDate().getTime() -
+ timeEntered.toDate().getTime()) / 60000;
+ if (minutesSpent >= 0) {
+ userStats[askerId].totalMinutes += minutesSpent;
+ }
+ }
+ else {
+ userStats[askerId].totalMinutes += 60; // assume 60 minutes if not addressed
+ }
+ }
+ return [2 /*return*/];
+ }
+ });
+ };
+ _i = 0, _a = questionsSnapshot.docs;
+ _p.label = 2;
+ case 2:
+ if (!(_i < _a.length)) return [3 /*break*/, 5];
+ doc = _a[_i];
+ return [5 /*yield**/, _loop_1(doc)];
+ case 3:
+ _p.sent();
+ _p.label = 4;
+ case 4:
+ _i++;
+ return [3 /*break*/, 2];
+ case 5:
+ _loop_2 = function (userId, stats) {
+ var weeksInRange, averageSessionsPerWeek, resSession, sessionsDoc, sessionFrequency_1, modeSessionId, sessionsDoc;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ stats.numVisits = (_m = officeHourSessions[userId]) === null || _m === void 0 ? void 0 : _m.length;
+ stats.totalMinutes = Math.ceil(stats.totalMinutes);
+ if (stats.timeHelpingStudents !== undefined) {
+ stats.timeHelpingStudents = Math.ceil(stats.timeHelpingStudents);
+ }
+ weeksInRange = (endDate.toDate().getTime() - startDate.toDate().getTime())
+ / (1000 * 60 * 60 * 24 * 7);
+ averageSessionsPerWeek = stats.numVisits / weeksInRange;
+ if (averageSessionsPerWeek >= 2) {
+ stats.personalityType = 'Consistent';
+ }
+ else if (averageSessionsPerWeek >= 0.5) {
+ stats.personalityType = 'Resourceful';
+ }
+ else {
+ stats.personalityType = 'Independent';
+ }
+ // Get the ids in the map that have the highest counts
+ if (taCounts[userId].size !== 0) {
+ stats.favTaId = Array.from(taCounts[userId].entries()).reduce(function (a, b) { return a[1] < b[1] ? b : a; })[0];
+ }
+ if (!(stats.favTaId && stats.favTaId !== "")) return [3 /*break*/, 4];
+ resSession = (_o = TAsessions[stats.favTaId]) === null || _o === void 0 ? void 0 : _o.filter(function (TAsession) {
+ return officeHourSessions[userId].includes(TAsession.session);
+ });
+ if (!((resSession === null || resSession === void 0 ? void 0 : resSession.length) === 1)) return [3 /*break*/, 2];
+ return [4 /*yield*/, sessionsRef.doc(resSession[0].session).get()];
+ case 1:
+ sessionsDoc = _a.sent();
+ stats.favClass = sessionsDoc.get("courseId");
+ return [3 /*break*/, 4];
+ case 2:
+ if (!((resSession === null || resSession === void 0 ? void 0 : resSession.length) > 1)) return [3 /*break*/, 4];
+ sessionFrequency_1 = {};
+ resSession.filter(function (elem) { return elem.asker === userId; }).forEach(function (elem) {
+ if (!sessionFrequency_1[elem.session]) {
+ sessionFrequency_1[elem.session] = 1;
+ }
+ else {
+ sessionFrequency_1[elem.session] += 1;
+ }
+ });
+ modeSessionId = Object.keys(sessionFrequency_1).reduce(function (a, b) {
+ return sessionFrequency_1[a] > sessionFrequency_1[b] ? a : b;
+ });
+ return [4 /*yield*/, sessionsRef.doc(modeSessionId).get()];
+ case 3:
+ sessionsDoc = _a.sent();
+ stats.favClass = sessionsDoc.get("courseId");
+ _a.label = 4;
+ case 4: return [2 /*return*/];
+ }
+ });
+ };
+ _b = 0, _c = Object.entries(userStats);
+ _p.label = 6;
+ case 6:
+ if (!(_b < _c.length)) return [3 /*break*/, 9];
+ _d = _c[_b], userId = _d[0], stats = _d[1];
+ return [5 /*yield**/, _loop_2(userId, stats)];
+ case 7:
+ _p.sent();
+ _p.label = 8;
+ case 8:
+ _b++;
+ return [3 /*break*/, 6];
+ case 9: return [4 /*yield*/, updateWrappedDocs()];
+ case 10:
+ _p.sent();
+ // debugging console log
+ // eslint-disable-next-line no-console
+ errorUsers.forEach(function (errUser) { return console.log(errUser.user + ": " + errUser.error); });
+ return [2 /*return*/];
+ }
+ });
+}); };
+(function () { return __awaiter(void 0, void 0, void 0, function () {
+ var error_1;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ _a.trys.push([0, 2, , 3]);
+ return [4 /*yield*/, getWrapped()];
+ case 1:
+ _a.sent();
+ // eslint-disable-next-line no-console
+ console.log("Processing complete.");
+ return [3 /*break*/, 3];
+ case 2:
+ error_1 = _a.sent();
+ // eslint-disable-next-line no-console
+ console.error("Failed to update stats:", error_1);
+ return [3 /*break*/, 3];
+ case 3: return [2 /*return*/];
+ }
+ });
+}); })();
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index f628c3543..78ca1e401 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -9,94 +9,248 @@ admin.initializeApp({
// eslint-disable-next-line no-console
console.log('Firebase admin initialized!');
+
+
// Initialize Firestore
const db = admin.firestore();
+const errorUsers: {
+ user: string,
+ error: string
+}[] = [];
// Firestore Timestamps for the query range
-const startDate = admin.firestore.Timestamp.fromDate(new Date('2023-08-20'));
-const endDate = admin.firestore.Timestamp.fromDate(new Date('2024-05-19'));
+
+const startDate = admin.firestore.Timestamp.fromDate(new Date('2024-01-22'));
+const endDate = admin.firestore.Timestamp.fromDate(new Date('2024-11-22'));
const getWrapped = async () => {
// Refs
- const questionsRef = db.collection('questions');
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- const sessionsRef = db.collection('sessions');
- const wrappedRef = db.collection('wrapped');
- const usersRef = db.collection('users');
+ const questionsRef = db.collection('questions-test');
+ const sessionsRef = db.collection('sessions-test');
+ const wrappedRef = db.collection('wrapped-fa24');
+ const usersRef = db.collection('users-test');
// Query all questions asked between FA23 and SP24
const questionsSnapshot = await questionsRef
- .where('timeEntered', '>=', startDate)
+ .where('timeEntered', '>=', startDate)
.where('timeEntered', '<=', endDate)
.get();
const userStats: { [userId: string]: {
- officeHourVisits: string[];
+ numVisits: number;
+ favClass: string;
+ favTaId: string;
+ favMonth: number;
+ favDay: number;
totalMinutes: number;
personalityType: string;
timeHelpingStudents?: number;
}} = {};
- const TAsessions: { [userId: string]: string[]} = {};
+ const getWrappedUserDocs = async () => {
+ const docs: {[userId:string]: FirebaseFirestore.DocumentSnapshot} = {};
+ await Promise.all(Object.keys(userStats).map(async (id) => {
+ if (id){
+ docs[id] = await usersRef.doc(id).get();
+ }
+ }
+ ));
+ return docs;
+ }
- for (const doc of questionsSnapshot.docs) {
- const question = doc.data() as {
- answererId: string;
- askerId: string;
- sessionId: string;
- timeEntered: admin.firestore.Timestamp;
- timeAddressed: admin.firestore.Timestamp | undefined;
- };
- const { answererId, askerId, sessionId, timeEntered, timeAddressed } = question;
+ const taCounts: {[userId: string] : Map} = {};
+ const officeHourSessions: { [userId: string]: string[]} = {};
+ // Every taID has an array of objects, where the objects store a sessionId and askerId
+ const TAsessions: {[taID:string]: {
+ session: string;
+ asker: string;
+ courseId: string;
+ day: number;
+ month: number;
+
+ }[]} = {};
+ // Helper functions
+ const updateWrappedDocs = async () => {
+ // Update the wrapped collection
+ const batch = db.batch();
+ const userDocuments = await getWrappedUserDocs();
+ for (const [userId, stats] of Object.entries(userStats)) {
+ // Only want to make wrapped changes for a user if they have an ID and are active
+ if (userId) {
+ /* Defition of active:
+ If a user is only a student, they need to have at least one OH visit.
+ If a user is a TA, they need to have at least one TA session AND at least one OH visit as a student.
+ */
+
+ const hasVisits = stats.numVisits > 0;
+ // This is true if the user is either a student, or a TA who has more than one session
+ const isUserActive = stats.timeHelpingStudents === undefined || (TAsessions[userId]?.length > 0);
+ const hasFavoriteTa = stats.favTaId !== "";
+ if (hasVisits && isUserActive && hasFavoriteTa) {
+ const wrappedDocRef = wrappedRef.doc(userId);
+ batch.set(wrappedDocRef, stats);
+
+ // eslint-disable-next-line no-await-in-loop
+ // const userDoc = await usersRef.doc(userId).get();
+ const userDoc = userDocuments[userId];
+ if (userDoc.exists) {
+ usersRef.doc(userId).update({
+ wrapped: true,
+ });
+ } else {
+ // Handle the case where the document does not exist
+ errorUsers.push({user: userId, error: "No document found for this user, skipping update."});
+ }
+ } else {
+ errorUsers.push({user: userId, error: "User is not an active student/TA"});
+ }
+
+ } else {
+ errorUsers.push({user: userId, error: "User ID is undefined, skipping update."});
+ }
+ }
+
+ await batch.commit();
+ }
+
+ const initializeUser = (answererId:string, askerId:string) => {
+ // if an instance doesn't exist yet for the user, creating one
if (!userStats[askerId]) {
userStats[askerId] = {
- officeHourVisits: [],
+ numVisits: 0,
+ favClass: '',
+ favTaId: '',
+ favMonth: 0,
+ favDay: 0,
totalMinutes: 0,
personalityType: '',
};
- }
+
+ taCounts[askerId] = new Map();
+ officeHourSessions[askerId] = [];
+ }
if (!userStats[answererId]) {
userStats[answererId] = {
- officeHourVisits: [],
+ numVisits: 0,
+ favClass: '',
+ favTaId: '',
+ favMonth: 0,
+ favDay: 0,
totalMinutes: 0,
personalityType: '',
timeHelpingStudents: 0,
};
+
+ taCounts[answererId] = new Map();
+ officeHourSessions[answererId] = [];
+ TAsessions[answererId] = [];
+ // Checking if ta already showed up as student and now as an answerer
+ } else if (userStats[answererId] && userStats[answererId]?.timeHelpingStudents === undefined) {
+ userStats[answererId] = {
+ numVisits: userStats[answererId].numVisits,
+ favClass: userStats[answererId].favClass,
+ favTaId: userStats[answererId].favTaId,
+ favMonth: userStats[answererId].favMonth,
+ favDay: userStats[answererId].favMonth,
+ totalMinutes: userStats[answererId].totalMinutes,
+ personalityType: userStats[answererId].personalityType,
+ timeHelpingStudents: 0,
+ };
+
+ taCounts[answererId] = new Map();
+ officeHourSessions[answererId] = [];
+ TAsessions[answererId] = [];
}
+ }
+
+ // do all sorting for preprocessing here
+
+ for (const doc of questionsSnapshot.docs) {
+ const question = doc.data() as {
+ answererId: string;
+ askerId: string;
+ sessionId: string;
+ timeEntered: admin.firestore.Timestamp;
+ timeAddressed: admin.firestore.Timestamp | undefined;
+ };
+
+ const { answererId, askerId, sessionId, timeEntered, timeAddressed } = question;
+
+ initializeUser(answererId, askerId);
+
// Office hour visits
- if (!userStats[askerId].officeHourVisits?.includes(sessionId)) {
- userStats[askerId].officeHourVisits?.push(sessionId);
+ // TRYING TO FIX BELOW LINE
+ // eslint-disable-next-line no-await-in-loop
+ const sessionDoc = await sessionsRef.doc(sessionId).get();
+ if (TAsessions[answererId].find((TAsession) => TAsession.session === sessionId) === undefined) {
+ /* Since TA was active during this session and this is the first
+ time encountering the session, we add it to their timeHelped */
+
+ if (sessionDoc.exists && userStats[answererId].timeHelpingStudents !== undefined ) {
+ /* Add a total session time to the min TA helped */
+ const timeHelping = (sessionDoc.get('endTime').toDate().getTime()
+ - sessionDoc.get('startTime').toDate().getTime())/ 60000;
+ // this should never be less than 0 (or 0, really)
+ if (timeHelping >= 0) {
+ userStats[answererId].timeHelpingStudents =
+ (userStats[answererId].timeHelpingStudents ?? 0) + timeHelping;
+ }
+ }
+ }
+
+ officeHourSessions[askerId] = officeHourSessions[askerId] || [];
+ if (!officeHourSessions[askerId].includes(sessionId)) {
+ officeHourSessions[askerId].push(sessionId); }
+
+ if (answererId !== undefined && answererId !== "") {
+ TAsessions[answererId]?.push({
+ session: sessionId,
+ asker: askerId,
+ courseId: sessionDoc.get('courseId'),
+ day: sessionDoc.get('startTime').toDate().getDay(),
+ month: sessionDoc.get('startTime').toDate().getMonth()
+ });
+
+ if(!taCounts[askerId]?.has(answererId)) {
+ taCounts[askerId]?.set(answererId, 1);
+ } else if (answererId !== undefined && taCounts[askerId]?.has(answererId)){
+ const taAmt = taCounts[askerId]?.get(answererId);
+ taAmt && taCounts[askerId]?.set(answererId, taAmt + 1 );
+ }
}
// Minutes spent at office hours
if (timeEntered) {
if (timeAddressed) {
const minutesSpent = (timeAddressed.toDate().getTime() -
- timeEntered.toDate().getTime()) / 60000; // convert ms to minutes
- userStats[askerId].totalMinutes += minutesSpent;
+ timeEntered.toDate().getTime()) / 60000; // convert ms to minutes
+ if (minutesSpent >= 0) {
+ userStats[askerId].totalMinutes += minutesSpent;
+ }
} else {
userStats[askerId].totalMinutes += 60; // assume 60 minutes if not addressed
}
}
-
- if (!TAsessions[answererId]?.includes(sessionId)) {
- TAsessions[answererId]?.push(sessionId);
- }
}
// Personality type will be calculated after processing all documents
// Process personality type
- for (const [, stats] of Object.entries(userStats)) {
- const sessionCount = stats.officeHourVisits.length;
+ for (const [userId, stats] of Object.entries(userStats)) {
+ stats.numVisits = officeHourSessions[userId]?.length;
+ stats.totalMinutes = Math.ceil(stats.totalMinutes);
+ if (stats.timeHelpingStudents !== undefined) {
+ stats.timeHelpingStudents = Math.ceil(stats.timeHelpingStudents);
+ }
+
const weeksInRange = (endDate.toDate().getTime() - startDate.toDate().getTime())
/ (1000 * 60 * 60 * 24 * 7); // convert ms to weeks
- const averageSessionsPerWeek = sessionCount / weeksInRange;
+ const averageSessionsPerWeek = stats.numVisits / weeksInRange;
if (averageSessionsPerWeek >= 2) {
stats.personalityType = 'Consistent';
@@ -105,34 +259,47 @@ const getWrapped = async () => {
} else {
stats.personalityType = 'Independent';
}
- }
-
- // Update the wrapped collection
- const batch = db.batch();
+
+ // Get the ids in the map that have the highest counts
+ if (taCounts[userId].size !== 0) {
+ stats.favTaId = Array.from(taCounts[userId].entries()).reduce((a, b) => a[1] < b[1] ? b : a)[0];
+ }
- Object.entries(userStats).forEach(async ([userId, stats]) => {
- if (userId) {
- const wrappedDocRef = wrappedRef.doc(userId);
- batch.set(wrappedDocRef, stats);
+ if (stats.favTaId && stats.favTaId !== "") {
+ const resSession = TAsessions[stats.favTaId]?.filter( (TAsession) =>
+ officeHourSessions[userId].includes(TAsession.session));
+ if (resSession?.length === 1) {
+ // eslint-disable-next-line no-await-in-loop
+ const sessionsDoc = await sessionsRef.doc(resSession[0].session).get()
+ stats.favClass = sessionsDoc.get("courseId");
- const userDoc = await usersRef.doc(userId).get();
- if (userDoc.exists) {
- usersRef.doc(userId).update({
- wrapped: true,
+ } else if (resSession?.length > 1) {
+ // finding session that occurs the most
+ const sessionFrequency: { [courseId: string]: number } = {};
+
+ resSession.filter((elem) => elem.asker === userId).forEach((elem) => {
+ if (!sessionFrequency[elem.session]) {
+ sessionFrequency[elem.session] = 1;
+ } else {
+ sessionFrequency[elem.session] += 1;
+ }
});
- } else {
- // Handle the case where the document does not exist
- // eslint-disable-next-line no-console
- console.log(`No document found for user ID ${userId}, skipping update.`);
+
+ const modeSessionId = Object.keys(sessionFrequency).reduce((a, b) =>
+ sessionFrequency[a] > sessionFrequency[b] ? a : b);
+ // eslint-disable-next-line no-await-in-loop
+ const sessionsDoc = await sessionsRef.doc(modeSessionId).get()
+ stats.favClass = sessionsDoc.get("courseId");
}
- } else {
- // eslint-disable-next-line no-console
- console.log("User ID is undefined, skipping update.")
}
-
- });
+ }
+
+ await updateWrappedDocs();
+ // debugging console log
+ // eslint-disable-next-line no-console
+ errorUsers.forEach((errUser) => console.log(errUser.user + ": " + errUser.error));
- await batch.commit();
+
}
(async () => {
@@ -144,4 +311,4 @@ const getWrapped = async () => {
// eslint-disable-next-line no-console
console.error("Failed to update stats:", error);
}
-})();
+})();
\ No newline at end of file
From abe758bfc63eeeb494e88d6ba8c093f941542f83 Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Sun, 10 Nov 2024 14:50:38 -0500
Subject: [PATCH 03/16] added most time spent in a month logic - added some
extra checks and made some anon functions have more clear names
---
src/scripts/wrapped-fa24.js | 89 ++++++++++++++++++++++---------------
src/scripts/wrapped-fa24.ts | 70 ++++++++++++++++++-----------
2 files changed, 97 insertions(+), 62 deletions(-)
diff --git a/src/scripts/wrapped-fa24.js b/src/scripts/wrapped-fa24.js
index d67453c88..8ccd9b5ae 100644
--- a/src/scripts/wrapped-fa24.js
+++ b/src/scripts/wrapped-fa24.js
@@ -50,10 +50,10 @@ var errorUsers = [];
var startDate = firebase_admin_1["default"].firestore.Timestamp.fromDate(new Date('2024-01-22'));
var endDate = firebase_admin_1["default"].firestore.Timestamp.fromDate(new Date('2024-11-22'));
var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function () {
- var questionsRef, sessionsRef, wrappedRef, usersRef, questionsSnapshot, userStats, getWrappedUserDocs, taCounts, officeHourSessions, TAsessions, updateWrappedDocs, initializeUser, _loop_1, _i, _a, doc, _loop_2, _b, _c, _d, userId, stats;
- var _e, _f, _g, _h, _j, _k, _l, _m, _o;
- return __generator(this, function (_p) {
- switch (_p.label) {
+ var questionsRef, sessionsRef, wrappedRef, usersRef, questionsSnapshot, userStats, getWrappedUserDocs, taCounts, monthTimeCounts, officeHourSessions, TAsessions, updateWrappedDocs, initializeUser, _loop_1, _i, _a, doc, _loop_2, _b, _c, _d, userId, stats;
+ var _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
+ return __generator(this, function (_q) {
+ switch (_q.label) {
case 0:
questionsRef = db.collection('questions-test');
sessionsRef = db.collection('sessions-test');
@@ -64,7 +64,7 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
.where('timeEntered', '<=', endDate)
.get()];
case 1:
- questionsSnapshot = _p.sent();
+ questionsSnapshot = _q.sent();
userStats = {};
getWrappedUserDocs = function () { return __awaiter(void 0, void 0, void 0, function () {
var docs;
@@ -95,6 +95,7 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
});
}); };
taCounts = {};
+ monthTimeCounts = {};
officeHourSessions = {};
TAsessions = {};
updateWrappedDocs = function () { return __awaiter(void 0, void 0, void 0, function () {
@@ -115,17 +116,22 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
isUserActive = stats.timeHelpingStudents === undefined || (((_c = TAsessions[userId]) === null || _c === void 0 ? void 0 : _c.length) > 0);
hasFavoriteTa = stats.favTaId !== "";
if (hasVisits && isUserActive && hasFavoriteTa) {
- wrappedDocRef = wrappedRef.doc(userId);
- batch.set(wrappedDocRef, stats);
- userDoc = userDocuments[userId];
- if (userDoc.exists) {
- usersRef.doc(userId).update({
- wrapped: true
- });
+ if (stats.favClass && stats.favDay && stats.favMonth) {
+ errorUsers.push({ user: userId, error: "User is active and has favorite TA, but is missing either most common class, day, or month." });
}
else {
- // Handle the case where the document does not exist
- errorUsers.push({ user: userId, error: "No document found for this user, skipping update." });
+ wrappedDocRef = wrappedRef.doc(userId);
+ batch.set(wrappedDocRef, stats);
+ userDoc = userDocuments[userId];
+ if (userDoc.exists) {
+ usersRef.doc(userId).update({
+ wrapped: true
+ });
+ }
+ else {
+ // Handle the case where the document does not exist
+ errorUsers.push({ user: userId, error: "No document found for this user, skipping update." });
+ }
}
}
else {
@@ -151,17 +157,22 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
numVisits: 0,
favClass: '',
favTaId: '',
+ favMonth: 0,
+ favDay: 0,
totalMinutes: 0,
personalityType: ''
};
taCounts[askerId] = new Map();
officeHourSessions[askerId] = [];
+ monthTimeCounts[askerId] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
}
if (!userStats[answererId]) {
userStats[answererId] = {
numVisits: 0,
favClass: '',
favTaId: '',
+ favMonth: 0,
+ favDay: 0,
totalMinutes: 0,
personalityType: '',
timeHelpingStudents: 0
@@ -169,6 +180,7 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
taCounts[answererId] = new Map();
officeHourSessions[answererId] = [];
TAsessions[answererId] = [];
+ monthTimeCounts[answererId] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
// Checking if ta already showed up as student and now as an answerer
}
else if (userStats[answererId] && ((_a = userStats[answererId]) === null || _a === void 0 ? void 0 : _a.timeHelpingStudents) === undefined) {
@@ -176,13 +188,16 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
numVisits: userStats[answererId].numVisits,
favClass: userStats[answererId].favClass,
favTaId: userStats[answererId].favTaId,
+ favMonth: userStats[answererId].favMonth,
+ favDay: userStats[answererId].favMonth,
totalMinutes: userStats[answererId].totalMinutes,
personalityType: userStats[answererId].personalityType,
timeHelpingStudents: 0
};
- taCounts[answererId] = new Map();
- officeHourSessions[answererId] = [];
+ // taCounts[answererId] = new Map();
+ // officeHourSessions[answererId] = [];
TAsessions[answererId] = [];
+ // monthTimeCounts[answererId] = [0,0,0,0,0,0,0,0,0,0,0,0];
}
};
_loop_1 = function (doc) {
@@ -213,25 +228,18 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
if (!officeHourSessions[askerId].includes(sessionId)) {
officeHourSessions[askerId].push(sessionId);
}
- if (answererId !== undefined && answererId !== "") {
- // eslint-disable-next-line no-console
- console.log(sessionDoc.get('startTime').toDate());
- // eslint-disable-next-line no-console
- console.log(sessionDoc.get('startTime').toDate().getDay());
- // eslint-disable-next-line no-console
- console.log(sessionDoc.get('startTime').toDate().getMonth());
- // eslint-disable-next-line no-console
- console.log("-------");
+ if (answererId && timeAddressed) {
(_f = TAsessions[answererId]) === null || _f === void 0 ? void 0 : _f.push({
session: sessionId,
asker: askerId,
courseId: sessionDoc.get('courseId'),
- day: sessionDoc.get('startTime').toDate().getDay()
+ day: timeAddressed.toDate().getDay(),
+ month: sessionDoc.get('startTime').toDate().getMonth()
});
if (!((_g = taCounts[askerId]) === null || _g === void 0 ? void 0 : _g.has(answererId))) {
(_h = taCounts[askerId]) === null || _h === void 0 ? void 0 : _h.set(answererId, 1);
}
- else if (answererId !== undefined && ((_j = taCounts[askerId]) === null || _j === void 0 ? void 0 : _j.has(answererId))) {
+ else if (answererId && ((_j = taCounts[askerId]) === null || _j === void 0 ? void 0 : _j.has(answererId))) {
taAmt = (_k = taCounts[askerId]) === null || _k === void 0 ? void 0 : _k.get(answererId);
taAmt && ((_l = taCounts[askerId]) === null || _l === void 0 ? void 0 : _l.set(answererId, taAmt + 1));
}
@@ -244,30 +252,34 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
if (minutesSpent >= 0) {
userStats[askerId].totalMinutes += minutesSpent;
}
+ monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += minutesSpent;
}
else {
userStats[askerId].totalMinutes += 60; // assume 60 minutes if not addressed
+ monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += 60;
}
+ // eslint-disable-next-line no-console
+ console.log(monthTimeCounts[askerId]);
}
return [2 /*return*/];
}
});
};
_i = 0, _a = questionsSnapshot.docs;
- _p.label = 2;
+ _q.label = 2;
case 2:
if (!(_i < _a.length)) return [3 /*break*/, 5];
doc = _a[_i];
return [5 /*yield**/, _loop_1(doc)];
case 3:
- _p.sent();
- _p.label = 4;
+ _q.sent();
+ _q.label = 4;
case 4:
_i++;
return [3 /*break*/, 2];
case 5:
_loop_2 = function (userId, stats) {
- var weeksInRange, averageSessionsPerWeek, resSession, sessionsDoc, sessionFrequency_1, modeSessionId, sessionsDoc;
+ var weeksInRange, averageSessionsPerWeek, modeElement, resSession, sessionsDoc, sessionFrequency_1, modeSessionId, sessionsDoc;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
@@ -288,12 +300,15 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
else {
stats.personalityType = 'Independent';
}
+ // Month user spent the most time in
+ stats.favMonth = (_o = monthTimeCounts[userId]) === null || _o === void 0 ? void 0 : _o.indexOf(Math.max.apply(Math, monthTimeCounts[userId]));
// Get the ids in the map that have the highest counts
if (taCounts[userId].size !== 0) {
- stats.favTaId = Array.from(taCounts[userId].entries()).reduce(function (a, b) { return a[1] < b[1] ? b : a; })[0];
+ stats.favTaId = Array.from(taCounts[userId].entries()).reduce(function (prev, next) { return prev[1] < next[1] ? next : prev; })[0];
}
+ modeElement = 0;
if (!(stats.favTaId && stats.favTaId !== "")) return [3 /*break*/, 4];
- resSession = (_o = TAsessions[stats.favTaId]) === null || _o === void 0 ? void 0 : _o.filter(function (TAsession) {
+ resSession = (_p = TAsessions[stats.favTaId]) === null || _p === void 0 ? void 0 : _p.filter(function (TAsession) {
return officeHourSessions[userId].includes(TAsession.session);
});
if (!((resSession === null || resSession === void 0 ? void 0 : resSession.length) === 1)) return [3 /*break*/, 2];
@@ -326,20 +341,20 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
});
};
_b = 0, _c = Object.entries(userStats);
- _p.label = 6;
+ _q.label = 6;
case 6:
if (!(_b < _c.length)) return [3 /*break*/, 9];
_d = _c[_b], userId = _d[0], stats = _d[1];
return [5 /*yield**/, _loop_2(userId, stats)];
case 7:
- _p.sent();
- _p.label = 8;
+ _q.sent();
+ _q.label = 8;
case 8:
_b++;
return [3 /*break*/, 6];
case 9: return [4 /*yield*/, updateWrappedDocs()];
case 10:
- _p.sent();
+ _q.sent();
// debugging console log
// eslint-disable-next-line no-console
errorUsers.forEach(function (errUser) { return console.log(errUser.user + ": " + errUser.error); });
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index 78ca1e401..91e6b57db 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -60,6 +60,7 @@ const getWrapped = async () => {
const taCounts: {[userId: string] : Map} = {};
+ const monthTimeCounts: {[userId: string]: number[]} = {};
const officeHourSessions: { [userId: string]: string[]} = {};
// Every taID has an array of objects, where the objects store a sessionId and askerId
const TAsessions: {[taID:string]: {
@@ -89,24 +90,27 @@ const getWrapped = async () => {
const isUserActive = stats.timeHelpingStudents === undefined || (TAsessions[userId]?.length > 0);
const hasFavoriteTa = stats.favTaId !== "";
if (hasVisits && isUserActive && hasFavoriteTa) {
- const wrappedDocRef = wrappedRef.doc(userId);
- batch.set(wrappedDocRef, stats);
-
- // eslint-disable-next-line no-await-in-loop
- // const userDoc = await usersRef.doc(userId).get();
- const userDoc = userDocuments[userId];
- if (userDoc.exists) {
- usersRef.doc(userId).update({
- wrapped: true,
- });
+ if (stats.favClass && stats.favDay && stats.favMonth) {
+ errorUsers.push({user: userId, error: "User is active and has favorite TA, but is missing either most common class, day, or month."});
} else {
- // Handle the case where the document does not exist
- errorUsers.push({user: userId, error: "No document found for this user, skipping update."});
+ const wrappedDocRef = wrappedRef.doc(userId);
+ batch.set(wrappedDocRef, stats);
+
+ // eslint-disable-next-line no-await-in-loop
+ // const userDoc = await usersRef.doc(userId).get();
+ const userDoc = userDocuments[userId];
+ if (userDoc.exists) {
+ usersRef.doc(userId).update({
+ wrapped: true,
+ });
+ } else {
+ // Handle the case where the document does not exist
+ errorUsers.push({user: userId, error: "No document found for this user, skipping update."});
+ }
}
} else {
- errorUsers.push({user: userId, error: "User is not an active student/TA"});
+ errorUsers.push({user: userId, error: "User is not an active student/TA or doesn't have favorite TA."});
}
-
} else {
errorUsers.push({user: userId, error: "User ID is undefined, skipping update."});
}
@@ -130,6 +134,7 @@ const getWrapped = async () => {
taCounts[askerId] = new Map();
officeHourSessions[askerId] = [];
+ monthTimeCounts[askerId] = [0,0,0,0,0,0,0,0,0,0,0,0];
}
if (!userStats[answererId]) {
@@ -147,6 +152,7 @@ const getWrapped = async () => {
taCounts[answererId] = new Map();
officeHourSessions[answererId] = [];
TAsessions[answererId] = [];
+ monthTimeCounts[answererId] = [0,0,0,0,0,0,0,0,0,0,0,0];
// Checking if ta already showed up as student and now as an answerer
} else if (userStats[answererId] && userStats[answererId]?.timeHelpingStudents === undefined) {
userStats[answererId] = {
@@ -160,9 +166,10 @@ const getWrapped = async () => {
timeHelpingStudents: 0,
};
- taCounts[answererId] = new Map();
- officeHourSessions[answererId] = [];
+ // taCounts[answererId] = new Map();
+ // officeHourSessions[answererId] = [];
TAsessions[answererId] = [];
+ // monthTimeCounts[answererId] = [0,0,0,0,0,0,0,0,0,0,0,0];
}
}
@@ -206,18 +213,18 @@ const getWrapped = async () => {
if (!officeHourSessions[askerId].includes(sessionId)) {
officeHourSessions[askerId].push(sessionId); }
- if (answererId !== undefined && answererId !== "") {
+ if (answererId && timeAddressed) {
TAsessions[answererId]?.push({
session: sessionId,
asker: askerId,
courseId: sessionDoc.get('courseId'),
- day: sessionDoc.get('startTime').toDate().getDay(),
+ day: timeAddressed.toDate().getDay(),
month: sessionDoc.get('startTime').toDate().getMonth()
});
if(!taCounts[askerId]?.has(answererId)) {
taCounts[askerId]?.set(answererId, 1);
- } else if (answererId !== undefined && taCounts[askerId]?.has(answererId)){
+ } else if (answererId && taCounts[askerId]?.has(answererId)){
const taAmt = taCounts[askerId]?.get(answererId);
taAmt && taCounts[askerId]?.set(answererId, taAmt + 1 );
}
@@ -230,24 +237,28 @@ const getWrapped = async () => {
timeEntered.toDate().getTime()) / 60000; // convert ms to minutes
if (minutesSpent >= 0) {
userStats[askerId].totalMinutes += minutesSpent;
- }
+ }
+ monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += minutesSpent;
} else {
userStats[askerId].totalMinutes += 60; // assume 60 minutes if not addressed
+ monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += 60;
}
+ // eslint-disable-next-line no-console
+ console.log(monthTimeCounts[askerId]);
}
}
// Personality type will be calculated after processing all documents
- // Process personality type
+ // Process stats
for (const [userId, stats] of Object.entries(userStats)) {
stats.numVisits = officeHourSessions[userId]?.length;
stats.totalMinutes = Math.ceil(stats.totalMinutes);
if (stats.timeHelpingStudents !== undefined) {
stats.timeHelpingStudents = Math.ceil(stats.timeHelpingStudents);
}
-
+ // Personality type
const weeksInRange = (endDate.toDate().getTime() - startDate.toDate().getTime())
/ (1000 * 60 * 60 * 24 * 7); // convert ms to weeks
const averageSessionsPerWeek = stats.numVisits / weeksInRange;
@@ -259,13 +270,18 @@ const getWrapped = async () => {
} else {
stats.personalityType = 'Independent';
}
-
+
+ // Month user spent the most time in
+ stats.favMonth = monthTimeCounts[userId]?.indexOf(Math.max(...monthTimeCounts[userId]));
// Get the ids in the map that have the highest counts
if (taCounts[userId].size !== 0) {
- stats.favTaId = Array.from(taCounts[userId].entries()).reduce((a, b) => a[1] < b[1] ? b : a)[0];
+ stats.favTaId = Array.from(taCounts[userId].entries()).reduce((prev, next) => prev[1] < next[1] ? next : prev)[0];
}
+ const modeElement = 0;
+
if (stats.favTaId && stats.favTaId !== "") {
+ // only looking at the sessions from the favorite TA that match with sessions the user went to
const resSession = TAsessions[stats.favTaId]?.filter( (TAsession) =>
officeHourSessions[userId].includes(TAsession.session));
if (resSession?.length === 1) {
@@ -274,7 +290,11 @@ const getWrapped = async () => {
stats.favClass = sessionsDoc.get("courseId");
} else if (resSession?.length > 1) {
- // finding session that occurs the most
+ /* filtering from general to specific:
+ - find mode class
+ - out of all the sessions for that class, find favorite day to go
+ */
+
const sessionFrequency: { [courseId: string]: number } = {};
resSession.filter((elem) => elem.asker === userId).forEach((elem) => {
From ff9a3d6d016df2806ab15ad5949a2885ae340832 Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Tue, 12 Nov 2024 19:10:01 -0500
Subject: [PATCH 04/16] stats seems to work, need to do further testing
---
src/scripts/wrapped-fa24.js | 219 ++++++++++++++++++++++--------------
src/scripts/wrapped-fa24.ts | 143 ++++++++++++++++-------
2 files changed, 239 insertions(+), 123 deletions(-)
diff --git a/src/scripts/wrapped-fa24.js b/src/scripts/wrapped-fa24.js
index 8ccd9b5ae..18c075cfc 100644
--- a/src/scripts/wrapped-fa24.js
+++ b/src/scripts/wrapped-fa24.js
@@ -99,7 +99,7 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
officeHourSessions = {};
TAsessions = {};
updateWrappedDocs = function () { return __awaiter(void 0, void 0, void 0, function () {
- var batch, userDocuments, _i, _a, _b, userId, stats, hasVisits, isUserActive, hasFavoriteTa, wrappedDocRef, userDoc;
+ var batch, userDocuments, _i, _a, _b, userId, stats, hasVisits, isUserActive, hasFavoriteTa, taStatsMismatched, wrappedDocRef, userDoc;
var _c;
return __generator(this, function (_d) {
switch (_d.label) {
@@ -115,9 +115,14 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
hasVisits = stats.numVisits > 0;
isUserActive = stats.timeHelpingStudents === undefined || (((_c = TAsessions[userId]) === null || _c === void 0 ? void 0 : _c.length) > 0);
hasFavoriteTa = stats.favTaId !== "";
+ taStatsMismatched = (stats.timeHelpingStudents !== undefined && stats.numStudentsHelped === undefined)
+ || (stats.timeHelpingStudents === undefined && stats.numStudentsHelped !== undefined);
if (hasVisits && isUserActive && hasFavoriteTa) {
- if (stats.favClass && stats.favDay && stats.favMonth) {
- errorUsers.push({ user: userId, error: "User is active and has favorite TA, but is missing either most common class, day, or month." });
+ if (!(stats.favClass && stats.favDay !== -1 && stats.favMonth !== -1)) {
+ errorUsers.push({ user: userId, error: "User is active and has favorite TA but missing one of the following:\n favClass: " + stats.favClass + ", favDay: " + stats.favDay + ", favMonth: " + stats.favMonth });
+ }
+ else if (taStatsMismatched) {
+ errorUsers.push({ user: userId, error: "Mismatch in updating ta specfic values." });
}
else {
wrappedDocRef = wrappedRef.doc(userId);
@@ -135,7 +140,7 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
}
}
else {
- errorUsers.push({ user: userId, error: "User is not an active student/TA" });
+ errorUsers.push({ user: userId, error: "User is not an active student/TA or doesn't have favorite TA." });
}
}
else {
@@ -157,8 +162,8 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
numVisits: 0,
favClass: '',
favTaId: '',
- favMonth: 0,
- favDay: 0,
+ favMonth: -1,
+ favDay: -1,
totalMinutes: 0,
personalityType: ''
};
@@ -171,11 +176,12 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
numVisits: 0,
favClass: '',
favTaId: '',
- favMonth: 0,
- favDay: 0,
+ favMonth: -1,
+ favDay: -1,
totalMinutes: 0,
personalityType: '',
- timeHelpingStudents: 0
+ timeHelpingStudents: 0,
+ numStudentsHelped: 0
};
taCounts[answererId] = new Map();
officeHourSessions[answererId] = [];
@@ -189,15 +195,13 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
favClass: userStats[answererId].favClass,
favTaId: userStats[answererId].favTaId,
favMonth: userStats[answererId].favMonth,
- favDay: userStats[answererId].favMonth,
+ favDay: userStats[answererId].favDay,
totalMinutes: userStats[answererId].totalMinutes,
personalityType: userStats[answererId].personalityType,
- timeHelpingStudents: 0
+ timeHelpingStudents: 0,
+ numStudentsHelped: 0
};
- // taCounts[answererId] = new Map();
- // officeHourSessions[answererId] = [];
TAsessions[answererId] = [];
- // monthTimeCounts[answererId] = [0,0,0,0,0,0,0,0,0,0,0,0];
}
};
_loop_1 = function (doc) {
@@ -233,8 +237,7 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
session: sessionId,
asker: askerId,
courseId: sessionDoc.get('courseId'),
- day: timeAddressed.toDate().getDay(),
- month: sessionDoc.get('startTime').toDate().getMonth()
+ day: timeAddressed.toDate().getDay()
});
if (!((_g = taCounts[askerId]) === null || _g === void 0 ? void 0 : _g.has(answererId))) {
(_h = taCounts[askerId]) === null || _h === void 0 ? void 0 : _h.set(answererId, 1);
@@ -259,7 +262,7 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += 60;
}
// eslint-disable-next-line no-console
- console.log(monthTimeCounts[askerId]);
+ console.log("month counts: [" + monthTimeCounts[askerId] + "]");
}
return [2 /*return*/];
}
@@ -279,81 +282,131 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
return [3 /*break*/, 2];
case 5:
_loop_2 = function (userId, stats) {
- var weeksInRange, averageSessionsPerWeek, modeElement, resSession, sessionsDoc, sessionFrequency_1, modeSessionId, sessionsDoc;
- return __generator(this, function (_a) {
- switch (_a.label) {
- case 0:
- stats.numVisits = (_m = officeHourSessions[userId]) === null || _m === void 0 ? void 0 : _m.length;
- stats.totalMinutes = Math.ceil(stats.totalMinutes);
- if (stats.timeHelpingStudents !== undefined) {
- stats.timeHelpingStudents = Math.ceil(stats.timeHelpingStudents);
- }
- weeksInRange = (endDate.toDate().getTime() - startDate.toDate().getTime())
- / (1000 * 60 * 60 * 24 * 7);
- averageSessionsPerWeek = stats.numVisits / weeksInRange;
- if (averageSessionsPerWeek >= 2) {
- stats.personalityType = 'Consistent';
- }
- else if (averageSessionsPerWeek >= 0.5) {
- stats.personalityType = 'Resourceful';
+ // eslint-disable-next-line no-console
+ console.log("name is " + userId);
+ stats.numVisits = (_m = officeHourSessions[userId]) === null || _m === void 0 ? void 0 : _m.length;
+ stats.totalMinutes = Math.ceil(stats.totalMinutes);
+ if (stats.timeHelpingStudents !== undefined) {
+ stats.timeHelpingStudents = Math.ceil(stats.timeHelpingStudents);
+ if (stats.numStudentsHelped !== undefined) {
+ stats.numStudentsHelped = TAsessions[userId].length;
+ }
+ }
+ // Personality type
+ var weeksInRange = (endDate.toDate().getTime() - startDate.toDate().getTime())
+ / (1000 * 60 * 60 * 24 * 7); // convert ms to weeks
+ var averageSessionsPerWeek = stats.numVisits / weeksInRange;
+ if (averageSessionsPerWeek >= 2) {
+ stats.personalityType = 'Consistent';
+ }
+ else if (averageSessionsPerWeek >= 0.5) {
+ stats.personalityType = 'Resourceful';
+ }
+ else {
+ stats.personalityType = 'Independent';
+ }
+ // Month user spent the most time in
+ stats.favMonth = (_o = monthTimeCounts[userId]) === null || _o === void 0 ? void 0 : _o.indexOf(Math.max.apply(Math, monthTimeCounts[userId]));
+ // Get the ids in the map that have the highest counts
+ if (taCounts[userId].size !== 0) {
+ stats.favTaId = Array.from(taCounts[userId].entries()).reduce(function (prev, next) { return prev[1] < next[1] ? next : prev; })[0];
+ }
+ // eslint-disable-next-line no-console
+ console.log(userId + "'s fav ta is " + stats.favTaId + ", taCounts length is " + taCounts[userId].size);
+ if (stats.favTaId) {
+ // eslint-disable-next-line no-console
+ console.log("here");
+ // only looking at the sessions from the favorite TA that match with sessions the user went to
+ var resSession = (_p = TAsessions[stats.favTaId]) === null || _p === void 0 ? void 0 : _p.filter(function (TAsession) {
+ return officeHourSessions[userId].includes(TAsession.session) && TAsession.asker === userId;
+ });
+ if ((resSession === null || resSession === void 0 ? void 0 : resSession.length) === 1) {
+ stats.favClass = resSession[0].courseId;
+ stats.favDay = resSession[0].day;
+ // eslint-disable-next-line no-console
+ console.log("finding " + userId + "'s mode stats");
+ // eslint-disable-next-line no-console
+ console.log(stats.favTaId + "'s total sessions");
+ // eslint-disable-next-line no-console
+ console.log(TAsessions[stats.favTaId]);
+ // eslint-disable-next-line no-console
+ console.log(stats.favTaId + ("'s total sessions with " + userId));
+ // eslint-disable-next-line no-console
+ resSession.map(function (x) { return console.log(x); });
+ }
+ else if ((resSession === null || resSession === void 0 ? void 0 : resSession.length) > 1) {
+ /* filtering from general to specific:
+ - find mode class
+ - out of all the sessions for that class, find mode day
+ */
+ // eslint-disable-next-line no-console
+ console.log("finding " + userId + "'s mode stats");
+ // eslint-disable-next-line no-console
+ console.log(stats.favTaId + "'s total sessions");
+ // eslint-disable-next-line no-console
+ console.log(TAsessions[stats.favTaId]);
+ // eslint-disable-next-line no-console
+ console.log(stats.favTaId + ("'s total sessions with " + userId));
+ // eslint-disable-next-line no-console
+ resSession.map(function (x) { return console.log(x); });
+ var classFrequency_1 = {};
+ var dayFrequency_1 = {};
+ /*
+ You need to find modeDay AFTER filtering all of modeCourse
+ because of the case where if you filter by looking at what
+ sessions have modeCourse AND modeDay, the modeDay might be a
+ number that doesn't exist with modeCourse.
+ */
+ resSession.forEach(function (TAsession) {
+ if (!classFrequency_1[TAsession.courseId]) {
+ classFrequency_1[TAsession.courseId] = 1;
}
else {
- stats.personalityType = 'Independent';
+ classFrequency_1[TAsession.courseId] += 1;
}
- // Month user spent the most time in
- stats.favMonth = (_o = monthTimeCounts[userId]) === null || _o === void 0 ? void 0 : _o.indexOf(Math.max.apply(Math, monthTimeCounts[userId]));
- // Get the ids in the map that have the highest counts
- if (taCounts[userId].size !== 0) {
- stats.favTaId = Array.from(taCounts[userId].entries()).reduce(function (prev, next) { return prev[1] < next[1] ? next : prev; })[0];
- }
- modeElement = 0;
- if (!(stats.favTaId && stats.favTaId !== "")) return [3 /*break*/, 4];
- resSession = (_p = TAsessions[stats.favTaId]) === null || _p === void 0 ? void 0 : _p.filter(function (TAsession) {
- return officeHourSessions[userId].includes(TAsession.session);
- });
- if (!((resSession === null || resSession === void 0 ? void 0 : resSession.length) === 1)) return [3 /*break*/, 2];
- return [4 /*yield*/, sessionsRef.doc(resSession[0].session).get()];
- case 1:
- sessionsDoc = _a.sent();
- stats.favClass = sessionsDoc.get("courseId");
- return [3 /*break*/, 4];
- case 2:
- if (!((resSession === null || resSession === void 0 ? void 0 : resSession.length) > 1)) return [3 /*break*/, 4];
- sessionFrequency_1 = {};
- resSession.filter(function (elem) { return elem.asker === userId; }).forEach(function (elem) {
- if (!sessionFrequency_1[elem.session]) {
- sessionFrequency_1[elem.session] = 1;
+ });
+ var modeCourseId_1 = Object.keys(classFrequency_1).reduce(function (a, b) {
+ return classFrequency_1[a] > classFrequency_1[b] ? a : b;
+ });
+ resSession.forEach(function (TAsession) {
+ if (TAsession.courseId === modeCourseId_1) {
+ if (!dayFrequency_1[TAsession.day]) {
+ dayFrequency_1[TAsession.day] = 1;
}
else {
- sessionFrequency_1[elem.session] += 1;
+ dayFrequency_1[TAsession.day] += 1;
}
- });
- modeSessionId = Object.keys(sessionFrequency_1).reduce(function (a, b) {
- return sessionFrequency_1[a] > sessionFrequency_1[b] ? a : b;
- });
- return [4 /*yield*/, sessionsRef.doc(modeSessionId).get()];
- case 3:
- sessionsDoc = _a.sent();
- stats.favClass = sessionsDoc.get("courseId");
- _a.label = 4;
- case 4: return [2 /*return*/];
+ }
+ });
+ var modeDay_1 = Object.keys(dayFrequency_1).reduce(function (day1, day2) {
+ return dayFrequency_1[parseInt(day1, 10)] > dayFrequency_1[parseInt(day2, 10)] ? day1 : day2;
+ });
+ // eslint-disable-next-line no-console
+ console.log("modeCourse: " + modeCourseId_1 + " and modeDay: " + modeDay_1);
+ var modeSessions = resSession.filter(function (TAsession) { return TAsession.courseId === modeCourseId_1
+ && TAsession.day === parseInt(modeDay_1, 10); });
+ // eslint-disable-next-line no-console
+ console.log("final filtering for modeSessions");
+ // eslint-disable-next-line no-console
+ console.log(modeSessions);
+ // there could be multiple ties, so just picking the first one
+ stats.favClass = modeSessions[0].courseId;
+ stats.favDay = modeSessions[0].day;
+ // eslint-disable-next-line no-console
+ console.log("favClass: " + stats.favClass + ", favDay: " + stats.favDay);
+ // eslint-disable-next-line no-console
+ console.log("------------");
}
- });
+ }
};
- _b = 0, _c = Object.entries(userStats);
- _q.label = 6;
+ // Personality type will be calculated after processing all documents
+ // Process stats
+ for (_b = 0, _c = Object.entries(userStats); _b < _c.length; _b++) {
+ _d = _c[_b], userId = _d[0], stats = _d[1];
+ _loop_2(userId, stats);
+ }
+ return [4 /*yield*/, updateWrappedDocs()];
case 6:
- if (!(_b < _c.length)) return [3 /*break*/, 9];
- _d = _c[_b], userId = _d[0], stats = _d[1];
- return [5 /*yield**/, _loop_2(userId, stats)];
- case 7:
- _q.sent();
- _q.label = 8;
- case 8:
- _b++;
- return [3 /*break*/, 6];
- case 9: return [4 /*yield*/, updateWrappedDocs()];
- case 10:
_q.sent();
// debugging console log
// eslint-disable-next-line no-console
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index 91e6b57db..cfceab655 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -45,6 +45,7 @@ const getWrapped = async () => {
totalMinutes: number;
personalityType: string;
timeHelpingStudents?: number;
+ numStudentsHelped?: number;
}} = {};
const getWrappedUserDocs = async () => {
@@ -68,8 +69,6 @@ const getWrapped = async () => {
asker: string;
courseId: string;
day: number;
- month: number;
-
}[]} = {};
// Helper functions
@@ -89,15 +88,19 @@ const getWrapped = async () => {
// This is true if the user is either a student, or a TA who has more than one session
const isUserActive = stats.timeHelpingStudents === undefined || (TAsessions[userId]?.length > 0);
const hasFavoriteTa = stats.favTaId !== "";
+ const taStatsMismatched = (stats.timeHelpingStudents !== undefined && stats.numStudentsHelped === undefined)
+ || (stats.timeHelpingStudents === undefined && stats.numStudentsHelped !== undefined);
if (hasVisits && isUserActive && hasFavoriteTa) {
- if (stats.favClass && stats.favDay && stats.favMonth) {
- errorUsers.push({user: userId, error: "User is active and has favorite TA, but is missing either most common class, day, or month."});
+ if (!(stats.favClass && stats.favDay !== -1 && stats.favMonth !== -1)) {
+ errorUsers.push({user: userId,
+ error: `User is active and has favorite TA but missing one of the following:
+ favClass: ${stats.favClass}, favDay: ${stats.favDay}, favMonth: ${stats.favMonth}`});
+ } else if (taStatsMismatched) {
+ errorUsers.push({user: userId, error: "Mismatch in updating ta specfic values."})
} else {
const wrappedDocRef = wrappedRef.doc(userId);
batch.set(wrappedDocRef, stats);
- // eslint-disable-next-line no-await-in-loop
- // const userDoc = await usersRef.doc(userId).get();
const userDoc = userDocuments[userId];
if (userDoc.exists) {
usersRef.doc(userId).update({
@@ -126,8 +129,8 @@ const getWrapped = async () => {
numVisits: 0,
favClass: '',
favTaId: '',
- favMonth: 0,
- favDay: 0,
+ favMonth: -1,
+ favDay: -1,
totalMinutes: 0,
personalityType: '',
};
@@ -142,11 +145,12 @@ const getWrapped = async () => {
numVisits: 0,
favClass: '',
favTaId: '',
- favMonth: 0,
- favDay: 0,
+ favMonth: -1,
+ favDay: -1,
totalMinutes: 0,
personalityType: '',
timeHelpingStudents: 0,
+ numStudentsHelped: 0
};
taCounts[answererId] = new Map();
@@ -160,16 +164,13 @@ const getWrapped = async () => {
favClass: userStats[answererId].favClass,
favTaId: userStats[answererId].favTaId,
favMonth: userStats[answererId].favMonth,
- favDay: userStats[answererId].favMonth,
+ favDay: userStats[answererId].favDay,
totalMinutes: userStats[answererId].totalMinutes,
personalityType: userStats[answererId].personalityType,
timeHelpingStudents: 0,
+ numStudentsHelped: 0
};
-
- // taCounts[answererId] = new Map();
- // officeHourSessions[answererId] = [];
TAsessions[answererId] = [];
- // monthTimeCounts[answererId] = [0,0,0,0,0,0,0,0,0,0,0,0];
}
}
@@ -218,8 +219,7 @@ const getWrapped = async () => {
session: sessionId,
asker: askerId,
courseId: sessionDoc.get('courseId'),
- day: timeAddressed.toDate().getDay(),
- month: sessionDoc.get('startTime').toDate().getMonth()
+ day: timeAddressed.toDate().getDay()
});
if(!taCounts[askerId]?.has(answererId)) {
@@ -244,7 +244,7 @@ const getWrapped = async () => {
monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += 60;
}
// eslint-disable-next-line no-console
- console.log(monthTimeCounts[askerId]);
+ console.log("month counts: [" + monthTimeCounts[askerId] + "]");
}
}
@@ -253,10 +253,15 @@ const getWrapped = async () => {
// Process stats
for (const [userId, stats] of Object.entries(userStats)) {
+ // eslint-disable-next-line no-console
+ console.log(`name is ${userId}`);
stats.numVisits = officeHourSessions[userId]?.length;
stats.totalMinutes = Math.ceil(stats.totalMinutes);
if (stats.timeHelpingStudents !== undefined) {
stats.timeHelpingStudents = Math.ceil(stats.timeHelpingStudents);
+ if (stats.numStudentsHelped !== undefined) {
+ stats.numStudentsHelped = TAsessions[userId].length;
+ }
}
// Personality type
const weeksInRange = (endDate.toDate().getTime() - startDate.toDate().getTime())
@@ -275,41 +280,99 @@ const getWrapped = async () => {
stats.favMonth = monthTimeCounts[userId]?.indexOf(Math.max(...monthTimeCounts[userId]));
// Get the ids in the map that have the highest counts
if (taCounts[userId].size !== 0) {
- stats.favTaId = Array.from(taCounts[userId].entries()).reduce((prev, next) => prev[1] < next[1] ? next : prev)[0];
+ stats.favTaId = Array.from(taCounts[userId].entries()).reduce(
+ (prev, next) => prev[1] < next[1] ? next : prev)[0];
}
-
- const modeElement = 0;
-
- if (stats.favTaId && stats.favTaId !== "") {
+ // eslint-disable-next-line no-console
+ console.log(`${userId}'s fav ta is ${stats.favTaId}, taCounts length is ${taCounts[userId].size}`);
+ if (stats.favTaId) {
+ // eslint-disable-next-line no-console
+ console.log(`here`);
// only looking at the sessions from the favorite TA that match with sessions the user went to
const resSession = TAsessions[stats.favTaId]?.filter( (TAsession) =>
- officeHourSessions[userId].includes(TAsession.session));
+ officeHourSessions[userId].includes(TAsession.session) && TAsession.asker === userId);
if (resSession?.length === 1) {
- // eslint-disable-next-line no-await-in-loop
- const sessionsDoc = await sessionsRef.doc(resSession[0].session).get()
- stats.favClass = sessionsDoc.get("courseId");
-
+ stats.favClass = resSession[0].courseId;
+ stats.favDay = resSession[0].day;
+ // eslint-disable-next-line no-console
+ console.log(`finding ${userId}'s mode stats`);
+ // eslint-disable-next-line no-console
+ console.log(stats.favTaId + "'s total sessions");
+ // eslint-disable-next-line no-console
+ console.log(TAsessions[stats.favTaId]);
+ // eslint-disable-next-line no-console
+ console.log(stats.favTaId + `'s total sessions with ${userId}`);
+ // eslint-disable-next-line no-console
+ resSession.map((x) => console.log(x));
} else if (resSession?.length > 1) {
/* filtering from general to specific:
- find mode class
- - out of all the sessions for that class, find favorite day to go
+ - out of all the sessions for that class, find mode day
*/
- const sessionFrequency: { [courseId: string]: number } = {};
-
- resSession.filter((elem) => elem.asker === userId).forEach((elem) => {
- if (!sessionFrequency[elem.session]) {
- sessionFrequency[elem.session] = 1;
+ // eslint-disable-next-line no-console
+ console.log(`finding ${userId}'s mode stats`);
+ // eslint-disable-next-line no-console
+ console.log(stats.favTaId + "'s total sessions");
+ // eslint-disable-next-line no-console
+ console.log(TAsessions[stats.favTaId]);
+ // eslint-disable-next-line no-console
+ console.log(stats.favTaId + `'s total sessions with ${userId}`);
+ // eslint-disable-next-line no-console
+ resSession.map((x) => console.log(x));
+
+
+ const classFrequency: { [courseId: string]: number } = {};
+ const dayFrequency: { [day: number]: number } = {};
+
+ /*
+ You need to find modeDay AFTER filtering all of modeCourse
+ because of the case where if you filter by looking at what
+ sessions have modeCourse AND modeDay, the modeDay might be a
+ number that doesn't exist with modeCourse.
+ */
+
+ resSession.forEach((TAsession) => {
+ if (!classFrequency[TAsession.courseId]) {
+ classFrequency[TAsession.courseId] = 1;
} else {
- sessionFrequency[elem.session] += 1;
+ classFrequency[TAsession.courseId] += 1;
}
});
- const modeSessionId = Object.keys(sessionFrequency).reduce((a, b) =>
- sessionFrequency[a] > sessionFrequency[b] ? a : b);
- // eslint-disable-next-line no-await-in-loop
- const sessionsDoc = await sessionsRef.doc(modeSessionId).get()
- stats.favClass = sessionsDoc.get("courseId");
+
+ const modeCourseId = Object.keys(classFrequency).reduce((a, b) =>
+ classFrequency[a] > classFrequency[b] ? a : b);
+ resSession.forEach((TAsession) => {
+ if (TAsession.courseId === modeCourseId) {
+ if (!dayFrequency[TAsession.day]) {
+ dayFrequency[TAsession.day] = 1;
+ } else {
+ dayFrequency[TAsession.day] += 1;
+ }
+ }
+ });
+ const modeDay = Object.keys(dayFrequency).reduce((day1, day2) =>
+ dayFrequency[parseInt(day1, 10)] > dayFrequency[parseInt(day2,10)] ? day1 : day2);
+ // eslint-disable-next-line no-console
+ console.log(`modeCourse: ${modeCourseId} and modeDay: ${modeDay}`);
+ const modeSessions = resSession.filter((TAsession) => TAsession.courseId === modeCourseId
+ && TAsession.day === parseInt(modeDay,10));
+
+ // eslint-disable-next-line no-console
+ console.log("final filtering for modeSessions");
+ // eslint-disable-next-line no-console
+ console.log(modeSessions);
+ // there could be multiple ties, so just picking the first one
+ stats.favClass = modeSessions[0].courseId;
+ stats.favDay = modeSessions[0].day;
+ // eslint-disable-next-line no-console
+ console.log(`favClass: ${stats.favClass}, favDay: ${stats.favDay}`);
+
+ // eslint-disable-next-line no-console
+ console.log("------------");
+
+
}
}
}
From b5bc1747b49846ad0182755b3fb3a43b9f5b902d Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Thu, 14 Nov 2024 17:39:25 -0500
Subject: [PATCH 05/16] refactored one more function and added progress
statements for big loops
---
src/scripts/wrapped-fa24.js | 414 +++++++++++++++++++-----------------
src/scripts/wrapped-fa24.ts | 296 +++++++++++++-------------
2 files changed, 366 insertions(+), 344 deletions(-)
diff --git a/src/scripts/wrapped-fa24.js b/src/scripts/wrapped-fa24.js
index 18c075cfc..bcc55c514 100644
--- a/src/scripts/wrapped-fa24.js
+++ b/src/scripts/wrapped-fa24.js
@@ -50,21 +50,21 @@ var errorUsers = [];
var startDate = firebase_admin_1["default"].firestore.Timestamp.fromDate(new Date('2024-01-22'));
var endDate = firebase_admin_1["default"].firestore.Timestamp.fromDate(new Date('2024-11-22'));
var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function () {
- var questionsRef, sessionsRef, wrappedRef, usersRef, questionsSnapshot, userStats, getWrappedUserDocs, taCounts, monthTimeCounts, officeHourSessions, TAsessions, updateWrappedDocs, initializeUser, _loop_1, _i, _a, doc, _loop_2, _b, _c, _d, userId, stats;
- var _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
- return __generator(this, function (_q) {
- switch (_q.label) {
+ var questionsRef, sessionsRef, wrappedRef, usersRef, questionsSnapshot, userStats, getWrappedUserDocs, getWrappedSessionDocs, taCounts, monthTimeCounts, officeHourSessions, TAsessions, updateWrappedDocs, initializeUser, processStats, sessionDocs, count, _loop_1, _i, _a, doc;
+ var _b, _c, _d, _e, _f, _g, _h;
+ return __generator(this, function (_j) {
+ switch (_j.label) {
case 0:
- questionsRef = db.collection('questions-test');
- sessionsRef = db.collection('sessions-test');
+ questionsRef = db.collection('questions');
+ sessionsRef = db.collection('sessions');
wrappedRef = db.collection('wrapped-fa24');
- usersRef = db.collection('users-test');
+ usersRef = db.collection('users');
return [4 /*yield*/, questionsRef
.where('timeEntered', '>=', startDate)
.where('timeEntered', '<=', endDate)
.get()];
case 1:
- questionsSnapshot = _q.sent();
+ questionsSnapshot = _j.sent();
userStats = {};
getWrappedUserDocs = function () { return __awaiter(void 0, void 0, void 0, function () {
var docs;
@@ -94,6 +94,41 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
}
});
}); };
+ getWrappedSessionDocs = function () { return __awaiter(void 0, void 0, void 0, function () {
+ var docs, sessionIds;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ docs = {};
+ sessionIds = [];
+ questionsSnapshot.docs.map(function (doc) { return sessionIds.push(doc.get('sessionId')); });
+ sessionIds.sort();
+ // eslint-disable-next-line no-console
+ // console.log(sessionIds);
+ return [4 /*yield*/, Promise.all(sessionIds.map(function (id) { return __awaiter(void 0, void 0, void 0, function () {
+ var _a, _b;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ if (!id) return [3 /*break*/, 2];
+ _a = docs;
+ _b = id;
+ return [4 /*yield*/, sessionsRef.doc(id).get()];
+ case 1:
+ _a[_b] = _c.sent();
+ _c.label = 2;
+ case 2: return [2 /*return*/];
+ }
+ });
+ }); }))];
+ case 1:
+ // eslint-disable-next-line no-console
+ // console.log(sessionIds);
+ _a.sent();
+ return [2 /*return*/, docs];
+ }
+ });
+ }); };
taCounts = {};
monthTimeCounts = {};
officeHourSessions = {};
@@ -135,12 +170,14 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
}
else {
// Handle the case where the document does not exist
- errorUsers.push({ user: userId, error: "No document found for this user, skipping update." });
+ errorUsers.push({ user: userId,
+ error: "No document found for this user, skipping update." });
}
}
}
else {
- errorUsers.push({ user: userId, error: "User is not an active student/TA or doesn't have favorite TA." });
+ errorUsers.push({ user: userId,
+ error: "User is not an active student/TA or doesn't have favorite TA." });
}
}
else {
@@ -202,213 +239,194 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
numStudentsHelped: 0
};
TAsessions[answererId] = [];
+ // eslint-disable-next-line no-console
+ console.log(answererId + " was a student but now theyre a TA");
}
};
- _loop_1 = function (doc) {
- var question, answererId, askerId, sessionId, timeEntered, timeAddressed, sessionDoc, timeHelping, taAmt, minutesSpent;
- return __generator(this, function (_a) {
- switch (_a.label) {
- case 0:
- question = doc.data();
- answererId = question.answererId, askerId = question.askerId, sessionId = question.sessionId, timeEntered = question.timeEntered, timeAddressed = question.timeAddressed;
- initializeUser(answererId, askerId);
- return [4 /*yield*/, sessionsRef.doc(sessionId).get()];
- case 1:
- sessionDoc = _a.sent();
- if (TAsessions[answererId].find(function (TAsession) { return TAsession.session === sessionId; }) === undefined) {
- /* Since TA was active during this session and this is the first
- time encountering the session, we add it to their timeHelped */
- if (sessionDoc.exists && userStats[answererId].timeHelpingStudents !== undefined) {
- timeHelping = (sessionDoc.get('endTime').toDate().getTime()
- - sessionDoc.get('startTime').toDate().getTime()) / 60000;
- // this should never be less than 0 (or 0, really)
- if (timeHelping >= 0) {
- userStats[answererId].timeHelpingStudents =
- ((_e = userStats[answererId].timeHelpingStudents) !== null && _e !== void 0 ? _e : 0) + timeHelping;
- }
- }
- }
- officeHourSessions[askerId] = officeHourSessions[askerId] || [];
- if (!officeHourSessions[askerId].includes(sessionId)) {
- officeHourSessions[askerId].push(sessionId);
- }
- if (answererId && timeAddressed) {
- (_f = TAsessions[answererId]) === null || _f === void 0 ? void 0 : _f.push({
- session: sessionId,
- asker: askerId,
- courseId: sessionDoc.get('courseId'),
- day: timeAddressed.toDate().getDay()
- });
- if (!((_g = taCounts[askerId]) === null || _g === void 0 ? void 0 : _g.has(answererId))) {
- (_h = taCounts[askerId]) === null || _h === void 0 ? void 0 : _h.set(answererId, 1);
+ processStats = function () {
+ var _a, _b;
+ count = 0;
+ var _loop_2 = function (userId, stats) {
+ if (count > 0 && count % 100 === 0) {
+ // eslint-disable-next-line no-console
+ console.log(count + "/" + Object.entries(userStats).length + " users processed.");
+ }
+ stats.numVisits = officeHourSessions[userId].length;
+ stats.totalMinutes = Math.ceil(stats.totalMinutes);
+ if (stats.timeHelpingStudents !== undefined) {
+ stats.timeHelpingStudents = Math.ceil(stats.timeHelpingStudents);
+ if (stats.numStudentsHelped !== undefined) {
+ stats.numStudentsHelped = TAsessions[userId].length;
+ }
+ }
+ // Personality type
+ var weeksInRange = (endDate.toDate().getTime() - startDate.toDate().getTime())
+ / (1000 * 60 * 60 * 24 * 7); // convert ms to weeks
+ var averageSessionsPerWeek = stats.numVisits / weeksInRange;
+ if (averageSessionsPerWeek >= 2) {
+ stats.personalityType = 'Consistent';
+ }
+ else if (averageSessionsPerWeek >= 0.5) {
+ stats.personalityType = 'Resourceful';
+ }
+ else {
+ stats.personalityType = 'Independent';
+ }
+ // Month user spent the most time in
+ stats.favMonth = (_a = monthTimeCounts[userId]) === null || _a === void 0 ? void 0 : _a.indexOf(Math.max.apply(Math, monthTimeCounts[userId]));
+ // Get the ids in the map that have the highest counts
+ if (taCounts[userId].size !== 0) {
+ stats.favTaId = Array.from(taCounts[userId].entries()).reduce(function (prevEntry, nextEntry) { return prevEntry[1] < nextEntry[1] ? nextEntry : prevEntry; })[0];
+ }
+ // eslint-disable-next-line no-console
+ // console.log(`${userId}'s fav ta is ${stats.favTaId}, taCounts length is ${taCounts[userId].size}`);
+ if (stats.favTaId) {
+ // only looking at the sessions from the favorite TA that match with sessions the user went to
+ var resSession = (_b = TAsessions[stats.favTaId]) === null || _b === void 0 ? void 0 : _b.filter(function (TAsession) {
+ return officeHourSessions[userId].includes(TAsession.session) && TAsession.asker === userId;
+ });
+ if ((resSession === null || resSession === void 0 ? void 0 : resSession.length) === 1) {
+ stats.favClass = resSession[0].courseId;
+ stats.favDay = resSession[0].day;
+ }
+ else if ((resSession === null || resSession === void 0 ? void 0 : resSession.length) > 1) {
+ /* filtering from general to specific:
+ - find mode class
+ - out of all the sessions for that class, find mode day
+ */
+ // eslint-disable-next-line no-console
+ // console.log(`finding ${userId}'s mode stats`);
+ // // eslint-disable-next-line no-console
+ // console.log(stats.favTaId + "'s total sessions");
+ // // eslint-disable-next-line no-console
+ // console.log(TAsessions[stats.favTaId]);
+ // // eslint-disable-next-line no-console
+ // console.log(stats.favTaId + `'s total sessions with ${userId}`);
+ // // eslint-disable-next-line no-console
+ // resSession.map((x) => console.log(x));
+ var classFrequency_1 = {};
+ var dayFrequency_1 = {};
+ resSession.forEach(function (TAsession) {
+ if (!classFrequency_1[TAsession.courseId]) {
+ classFrequency_1[TAsession.courseId] = 1;
}
- else if (answererId && ((_j = taCounts[askerId]) === null || _j === void 0 ? void 0 : _j.has(answererId))) {
- taAmt = (_k = taCounts[askerId]) === null || _k === void 0 ? void 0 : _k.get(answererId);
- taAmt && ((_l = taCounts[askerId]) === null || _l === void 0 ? void 0 : _l.set(answererId, taAmt + 1));
+ else {
+ classFrequency_1[TAsession.courseId] += 1;
}
- }
- // Minutes spent at office hours
- if (timeEntered) {
- if (timeAddressed) {
- minutesSpent = (timeAddressed.toDate().getTime() -
- timeEntered.toDate().getTime()) / 60000;
- if (minutesSpent >= 0) {
- userStats[askerId].totalMinutes += minutesSpent;
+ });
+ var modeCourseId_1 = Object.keys(classFrequency_1).reduce(function (courseId1, courseId2) {
+ return classFrequency_1[courseId1] > classFrequency_1[courseId2] ? courseId1 : courseId2;
+ });
+ resSession.forEach(function (TAsession) {
+ if (TAsession.courseId === modeCourseId_1) {
+ if (!dayFrequency_1[TAsession.day]) {
+ dayFrequency_1[TAsession.day] = 1;
+ }
+ else {
+ dayFrequency_1[TAsession.day] += 1;
}
- monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += minutesSpent;
- }
- else {
- userStats[askerId].totalMinutes += 60; // assume 60 minutes if not addressed
- monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += 60;
}
- // eslint-disable-next-line no-console
- console.log("month counts: [" + monthTimeCounts[askerId] + "]");
- }
- return [2 /*return*/];
+ });
+ var modeDay_1 = Object.keys(dayFrequency_1).reduce(function (day1, day2) {
+ return dayFrequency_1[parseInt(day1, 10)] > dayFrequency_1[parseInt(day2, 10)] ? day1 : day2;
+ });
+ // eslint-disable-next-line no-console
+ // console.log(`modeCourse: ${modeCourseId} and modeDay: ${modeDay}`);
+ var modeSessions = resSession.filter(function (TAsession) { return TAsession.courseId === modeCourseId_1
+ && TAsession.day === parseInt(modeDay_1, 10); });
+ // eslint-disable-next-line no-console
+ // console.log("final filtering for modeSessions");
+ // eslint-disable-next-line no-console
+ // console.log(modeSessions);
+ // There could be multiple ties, so just picking the first one
+ stats.favClass = modeSessions[0].courseId;
+ stats.favDay = modeSessions[0].day;
+ // eslint-disable-next-line no-console
+ // console.log(`favClass: ${stats.favClass}, favDay: ${stats.favDay}`);
+ // eslint-disable-next-line no-console
+ // console.log("------------");
+ }
}
- });
+ count++;
+ };
+ for (var _i = 0, _c = Object.entries(userStats); _i < _c.length; _i++) {
+ var _d = _c[_i], userId = _d[0], stats = _d[1];
+ _loop_2(userId, stats);
+ }
};
- _i = 0, _a = questionsSnapshot.docs;
- _q.label = 2;
+ return [4 /*yield*/, getWrappedSessionDocs()];
case 2:
- if (!(_i < _a.length)) return [3 /*break*/, 5];
- doc = _a[_i];
- return [5 /*yield**/, _loop_1(doc)];
- case 3:
- _q.sent();
- _q.label = 4;
- case 4:
- _i++;
- return [3 /*break*/, 2];
- case 5:
- _loop_2 = function (userId, stats) {
- // eslint-disable-next-line no-console
- console.log("name is " + userId);
- stats.numVisits = (_m = officeHourSessions[userId]) === null || _m === void 0 ? void 0 : _m.length;
- stats.totalMinutes = Math.ceil(stats.totalMinutes);
- if (stats.timeHelpingStudents !== undefined) {
- stats.timeHelpingStudents = Math.ceil(stats.timeHelpingStudents);
- if (stats.numStudentsHelped !== undefined) {
- stats.numStudentsHelped = TAsessions[userId].length;
- }
- }
- // Personality type
- var weeksInRange = (endDate.toDate().getTime() - startDate.toDate().getTime())
- / (1000 * 60 * 60 * 24 * 7); // convert ms to weeks
- var averageSessionsPerWeek = stats.numVisits / weeksInRange;
- if (averageSessionsPerWeek >= 2) {
- stats.personalityType = 'Consistent';
- }
- else if (averageSessionsPerWeek >= 0.5) {
- stats.personalityType = 'Resourceful';
+ sessionDocs = _j.sent();
+ count = 0;
+ _loop_1 = function (doc) {
+ // Console statement for debugging
+ if (count > 0 && count % 100 === 0) {
+ // eslint-disable-next-line no-console
+ console.log(count + "/" + questionsSnapshot.docs.length + " questions processed.");
}
- else {
- stats.personalityType = 'Independent';
+ var question = doc.data();
+ var answererId = question.answererId, askerId = question.askerId, sessionId = question.sessionId, timeEntered = question.timeEntered, timeAddressed = question.timeAddressed;
+ initializeUser(answererId, askerId);
+ // Office hour visits
+ var sessionDoc = sessionDocs[sessionId];
+ if (TAsessions[answererId].find(function (TAsession) { return TAsession.session === sessionId; }) === undefined) {
+ /* Since TA was active during this session and this is the first
+ time encountering the session, we add it to their timeHelped */
+ if (sessionDoc.exists && userStats[answererId].timeHelpingStudents !== undefined) {
+ /* Add a total session time to the min TA helped */
+ var timeHelping = (sessionDoc.get('endTime').toDate().getTime()
+ - sessionDoc.get('startTime').toDate().getTime()) / 60000;
+ // this should never be less than 0 (or 0, really)
+ if (timeHelping >= 0) {
+ userStats[answererId].timeHelpingStudents =
+ ((_b = userStats[answererId].timeHelpingStudents) !== null && _b !== void 0 ? _b : 0) + timeHelping;
+ }
+ }
}
- // Month user spent the most time in
- stats.favMonth = (_o = monthTimeCounts[userId]) === null || _o === void 0 ? void 0 : _o.indexOf(Math.max.apply(Math, monthTimeCounts[userId]));
- // Get the ids in the map that have the highest counts
- if (taCounts[userId].size !== 0) {
- stats.favTaId = Array.from(taCounts[userId].entries()).reduce(function (prev, next) { return prev[1] < next[1] ? next : prev; })[0];
+ officeHourSessions[askerId] = officeHourSessions[askerId] || [];
+ if (!officeHourSessions[askerId].includes(sessionId)) {
+ officeHourSessions[askerId].push(sessionId);
}
- // eslint-disable-next-line no-console
- console.log(userId + "'s fav ta is " + stats.favTaId + ", taCounts length is " + taCounts[userId].size);
- if (stats.favTaId) {
- // eslint-disable-next-line no-console
- console.log("here");
- // only looking at the sessions from the favorite TA that match with sessions the user went to
- var resSession = (_p = TAsessions[stats.favTaId]) === null || _p === void 0 ? void 0 : _p.filter(function (TAsession) {
- return officeHourSessions[userId].includes(TAsession.session) && TAsession.asker === userId;
+ if (answererId && timeAddressed) {
+ (_c = TAsessions[answererId]) === null || _c === void 0 ? void 0 : _c.push({
+ session: sessionId,
+ asker: askerId,
+ courseId: sessionDoc.get('courseId'),
+ day: timeAddressed.toDate().getDay()
});
- if ((resSession === null || resSession === void 0 ? void 0 : resSession.length) === 1) {
- stats.favClass = resSession[0].courseId;
- stats.favDay = resSession[0].day;
- // eslint-disable-next-line no-console
- console.log("finding " + userId + "'s mode stats");
- // eslint-disable-next-line no-console
- console.log(stats.favTaId + "'s total sessions");
- // eslint-disable-next-line no-console
- console.log(TAsessions[stats.favTaId]);
- // eslint-disable-next-line no-console
- console.log(stats.favTaId + ("'s total sessions with " + userId));
- // eslint-disable-next-line no-console
- resSession.map(function (x) { return console.log(x); });
+ if (!((_d = taCounts[askerId]) === null || _d === void 0 ? void 0 : _d.has(answererId))) {
+ (_e = taCounts[askerId]) === null || _e === void 0 ? void 0 : _e.set(answererId, 1);
}
- else if ((resSession === null || resSession === void 0 ? void 0 : resSession.length) > 1) {
- /* filtering from general to specific:
- - find mode class
- - out of all the sessions for that class, find mode day
- */
- // eslint-disable-next-line no-console
- console.log("finding " + userId + "'s mode stats");
- // eslint-disable-next-line no-console
- console.log(stats.favTaId + "'s total sessions");
- // eslint-disable-next-line no-console
- console.log(TAsessions[stats.favTaId]);
- // eslint-disable-next-line no-console
- console.log(stats.favTaId + ("'s total sessions with " + userId));
- // eslint-disable-next-line no-console
- resSession.map(function (x) { return console.log(x); });
- var classFrequency_1 = {};
- var dayFrequency_1 = {};
- /*
- You need to find modeDay AFTER filtering all of modeCourse
- because of the case where if you filter by looking at what
- sessions have modeCourse AND modeDay, the modeDay might be a
- number that doesn't exist with modeCourse.
- */
- resSession.forEach(function (TAsession) {
- if (!classFrequency_1[TAsession.courseId]) {
- classFrequency_1[TAsession.courseId] = 1;
- }
- else {
- classFrequency_1[TAsession.courseId] += 1;
- }
- });
- var modeCourseId_1 = Object.keys(classFrequency_1).reduce(function (a, b) {
- return classFrequency_1[a] > classFrequency_1[b] ? a : b;
- });
- resSession.forEach(function (TAsession) {
- if (TAsession.courseId === modeCourseId_1) {
- if (!dayFrequency_1[TAsession.day]) {
- dayFrequency_1[TAsession.day] = 1;
- }
- else {
- dayFrequency_1[TAsession.day] += 1;
- }
- }
- });
- var modeDay_1 = Object.keys(dayFrequency_1).reduce(function (day1, day2) {
- return dayFrequency_1[parseInt(day1, 10)] > dayFrequency_1[parseInt(day2, 10)] ? day1 : day2;
- });
- // eslint-disable-next-line no-console
- console.log("modeCourse: " + modeCourseId_1 + " and modeDay: " + modeDay_1);
- var modeSessions = resSession.filter(function (TAsession) { return TAsession.courseId === modeCourseId_1
- && TAsession.day === parseInt(modeDay_1, 10); });
- // eslint-disable-next-line no-console
- console.log("final filtering for modeSessions");
- // eslint-disable-next-line no-console
- console.log(modeSessions);
- // there could be multiple ties, so just picking the first one
- stats.favClass = modeSessions[0].courseId;
- stats.favDay = modeSessions[0].day;
- // eslint-disable-next-line no-console
- console.log("favClass: " + stats.favClass + ", favDay: " + stats.favDay);
- // eslint-disable-next-line no-console
- console.log("------------");
+ else if (answererId && ((_f = taCounts[askerId]) === null || _f === void 0 ? void 0 : _f.has(answererId))) {
+ var taAmt = (_g = taCounts[askerId]) === null || _g === void 0 ? void 0 : _g.get(answererId);
+ taAmt && ((_h = taCounts[askerId]) === null || _h === void 0 ? void 0 : _h.set(answererId, taAmt + 1));
}
}
+ // Minutes spent at office hours
+ if (timeEntered) {
+ if (timeAddressed) {
+ var minutesSpent = (timeAddressed.toDate().getTime() -
+ timeEntered.toDate().getTime()) / 60000; // convert ms to minutes
+ if (minutesSpent >= 0) {
+ userStats[askerId].totalMinutes += minutesSpent;
+ }
+ monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += minutesSpent;
+ }
+ else {
+ userStats[askerId].totalMinutes += 60; // assume 60 minutes if not addressed
+ monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += 60;
+ }
+ }
+ count++;
};
- // Personality type will be calculated after processing all documents
- // Process stats
- for (_b = 0, _c = Object.entries(userStats); _b < _c.length; _b++) {
- _d = _c[_b], userId = _d[0], stats = _d[1];
- _loop_2(userId, stats);
+ for (_i = 0, _a = questionsSnapshot.docs; _i < _a.length; _i++) {
+ doc = _a[_i];
+ _loop_1(doc);
}
+ processStats();
return [4 /*yield*/, updateWrappedDocs()];
- case 6:
- _q.sent();
- // debugging console log
+ case 3:
+ _j.sent();
// eslint-disable-next-line no-console
errorUsers.forEach(function (errUser) { return console.log(errUser.user + ": " + errUser.error); });
return [2 /*return*/];
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index cfceab655..c67275723 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -25,10 +25,10 @@ const endDate = admin.firestore.Timestamp.fromDate(new Date('2024-11-22'));
const getWrapped = async () => {
// Refs
- const questionsRef = db.collection('questions-test');
- const sessionsRef = db.collection('sessions-test');
+ const questionsRef = db.collection('questions');
+ const sessionsRef = db.collection('sessions');
const wrappedRef = db.collection('wrapped-fa24');
- const usersRef = db.collection('users-test');
+ const usersRef = db.collection('users');
// Query all questions asked between FA23 and SP24
const questionsSnapshot = await questionsRef
@@ -59,6 +59,22 @@ const getWrapped = async () => {
return docs;
}
+ const getWrappedSessionDocs = async () => {
+ const docs: {[userId:string]: FirebaseFirestore.DocumentSnapshot} = {};
+ const sessionIds: string[] = [];
+ questionsSnapshot.docs.map((doc) => sessionIds.push(doc.get('sessionId')));
+ sessionIds.sort();
+ // eslint-disable-next-line no-console
+ // console.log(sessionIds);
+ await Promise.all(sessionIds.map(async (id) => {
+ if (id) {
+ docs[id] = await sessionsRef.doc(id).get();
+ }
+ }
+ ));
+ return docs;
+ }
+
const taCounts: {[userId: string] : Map} = {};
const monthTimeCounts: {[userId: string]: number[]} = {};
@@ -83,12 +99,12 @@ const getWrapped = async () => {
If a user is only a student, they need to have at least one OH visit.
If a user is a TA, they need to have at least one TA session AND at least one OH visit as a student.
*/
-
const hasVisits = stats.numVisits > 0;
// This is true if the user is either a student, or a TA who has more than one session
const isUserActive = stats.timeHelpingStudents === undefined || (TAsessions[userId]?.length > 0);
const hasFavoriteTa = stats.favTaId !== "";
- const taStatsMismatched = (stats.timeHelpingStudents !== undefined && stats.numStudentsHelped === undefined)
+ const taStatsMismatched =
+ (stats.timeHelpingStudents !== undefined && stats.numStudentsHelped === undefined)
|| (stats.timeHelpingStudents === undefined && stats.numStudentsHelped !== undefined);
if (hasVisits && isUserActive && hasFavoriteTa) {
if (!(stats.favClass && stats.favDay !== -1 && stats.favMonth !== -1)) {
@@ -108,11 +124,13 @@ const getWrapped = async () => {
});
} else {
// Handle the case where the document does not exist
- errorUsers.push({user: userId, error: "No document found for this user, skipping update."});
+ errorUsers.push({user: userId,
+ error: "No document found for this user, skipping update."});
}
}
} else {
- errorUsers.push({user: userId, error: "User is not an active student/TA or doesn't have favorite TA."});
+ errorUsers.push({user: userId,
+ error: "User is not an active student/TA or doesn't have favorite TA."});
}
} else {
errorUsers.push({user: userId, error: "User ID is undefined, skipping update."});
@@ -171,13 +189,133 @@ const getWrapped = async () => {
numStudentsHelped: 0
};
TAsessions[answererId] = [];
+ // eslint-disable-next-line no-console
+ console.log(`${answererId} was a student but now theyre a TA`)
}
}
- // do all sorting for preprocessing here
+
+ const processStats = () => {
+ count = 0;
+ for (const [userId, stats] of Object.entries(userStats)) {
+ if (count > 0 && count % 100 === 0) {
+ // eslint-disable-next-line no-console
+ console.log(`${count}/${Object.entries(userStats).length} users processed.`);
+ }
+ stats.numVisits = officeHourSessions[userId].length;
+ stats.totalMinutes = Math.ceil(stats.totalMinutes);
+ if (stats.timeHelpingStudents !== undefined) {
+ stats.timeHelpingStudents = Math.ceil(stats.timeHelpingStudents);
+ if (stats.numStudentsHelped !== undefined) {
+ stats.numStudentsHelped = TAsessions[userId].length;
+ }
+ }
+ // Personality type
+ const weeksInRange = (endDate.toDate().getTime() - startDate.toDate().getTime())
+ / (1000 * 60 * 60 * 24 * 7); // convert ms to weeks
+ const averageSessionsPerWeek = stats.numVisits / weeksInRange;
+
+ if (averageSessionsPerWeek >= 2) {
+ stats.personalityType = 'Consistent';
+ } else if (averageSessionsPerWeek >= 0.5) {
+ stats.personalityType = 'Resourceful';
+ } else {
+ stats.personalityType = 'Independent';
+ }
+ // Month user spent the most time in
+ stats.favMonth = monthTimeCounts[userId]?.indexOf(Math.max(...monthTimeCounts[userId]));
+ // Get the ids in the map that have the highest counts
+ if (taCounts[userId].size !== 0) {
+ stats.favTaId = Array.from(taCounts[userId].entries()).reduce(
+ (prevEntry, nextEntry) => prevEntry[1] < nextEntry[1] ? nextEntry : prevEntry)[0];
+ }
+ // eslint-disable-next-line no-console
+ // console.log(`${userId}'s fav ta is ${stats.favTaId}, taCounts length is ${taCounts[userId].size}`);
+ if (stats.favTaId) {
+ // only looking at the sessions from the favorite TA that match with sessions the user went to
+ const resSession = TAsessions[stats.favTaId]?.filter( (TAsession) =>
+ officeHourSessions[userId].includes(TAsession.session) && TAsession.asker === userId);
+ if (resSession?.length === 1) {
+ stats.favClass = resSession[0].courseId;
+ stats.favDay = resSession[0].day;
+ } else if (resSession?.length > 1) {
+ /* filtering from general to specific:
+ - find mode class
+ - out of all the sessions for that class, find mode day
+ */
+
+ // eslint-disable-next-line no-console
+ // console.log(`finding ${userId}'s mode stats`);
+ // // eslint-disable-next-line no-console
+ // console.log(stats.favTaId + "'s total sessions");
+ // // eslint-disable-next-line no-console
+ // console.log(TAsessions[stats.favTaId]);
+ // // eslint-disable-next-line no-console
+ // console.log(stats.favTaId + `'s total sessions with ${userId}`);
+ // // eslint-disable-next-line no-console
+ // resSession.map((x) => console.log(x));
+
+ const classFrequency: { [courseId: string]: number } = {};
+ const dayFrequency: { [day: number]: number } = {};
+
+ resSession.forEach((TAsession) => {
+ if (!classFrequency[TAsession.courseId]) {
+ classFrequency[TAsession.courseId] = 1;
+ } else {
+ classFrequency[TAsession.courseId] += 1;
+ }
+ });
+
+ const modeCourseId = Object.keys(classFrequency).reduce((courseId1, courseId2) =>
+ classFrequency[courseId1] > classFrequency[courseId2] ? courseId1 : courseId2);
+ resSession.forEach((TAsession) => {
+ if (TAsession.courseId === modeCourseId) {
+ if (!dayFrequency[TAsession.day]) {
+ dayFrequency[TAsession.day] = 1;
+ } else {
+ dayFrequency[TAsession.day] += 1;
+ }
+ }
+ });
+ const modeDay = Object.keys(dayFrequency).reduce((day1, day2) =>
+ dayFrequency[parseInt(day1, 10)] > dayFrequency[parseInt(day2,10)] ? day1 : day2);
+ // eslint-disable-next-line no-console
+ // console.log(`modeCourse: ${modeCourseId} and modeDay: ${modeDay}`);
+ const modeSessions = resSession.filter((TAsession) => TAsession.courseId === modeCourseId
+ && TAsession.day === parseInt(modeDay,10));
+
+ // eslint-disable-next-line no-console
+ // console.log("final filtering for modeSessions");
+ // eslint-disable-next-line no-console
+ // console.log(modeSessions);
+
+ // There could be multiple ties, so just picking the first one
+ stats.favClass = modeSessions[0].courseId;
+ stats.favDay = modeSessions[0].day;
+ // eslint-disable-next-line no-console
+ // console.log(`favClass: ${stats.favClass}, favDay: ${stats.favDay}`);
+
+ // eslint-disable-next-line no-console
+ // console.log("------------");
+ }
+ }
+ count++;
+ }
+ }
+
+ // ----- end of helper functions --------
+
+
+ const sessionDocs = await getWrappedSessionDocs();
+ let count = 0;
for (const doc of questionsSnapshot.docs) {
+ // Console statement for debugging
+ if (count > 0 && count % 100 === 0) {
+ // eslint-disable-next-line no-console
+ console.log(`${count}/${questionsSnapshot.docs.length} questions processed.`)
+ }
const question = doc.data() as {
answererId: string;
askerId: string;
@@ -189,15 +327,11 @@ const getWrapped = async () => {
const { answererId, askerId, sessionId, timeEntered, timeAddressed } = question;
initializeUser(answererId, askerId);
-
// Office hour visits
- // TRYING TO FIX BELOW LINE
- // eslint-disable-next-line no-await-in-loop
- const sessionDoc = await sessionsRef.doc(sessionId).get();
+ const sessionDoc = sessionDocs[sessionId];
if (TAsessions[answererId].find((TAsession) => TAsession.session === sessionId) === undefined) {
/* Since TA was active during this session and this is the first
time encountering the session, we add it to their timeHelped */
-
if (sessionDoc.exists && userStats[answererId].timeHelpingStudents !== undefined ) {
/* Add a total session time to the min TA helped */
const timeHelping = (sessionDoc.get('endTime').toDate().getTime()
@@ -243,146 +377,16 @@ const getWrapped = async () => {
userStats[askerId].totalMinutes += 60; // assume 60 minutes if not addressed
monthTimeCounts[askerId][timeEntered.toDate().getMonth()] += 60;
}
- // eslint-disable-next-line no-console
- console.log("month counts: [" + monthTimeCounts[askerId] + "]");
}
+ count++;
}
- // Personality type will be calculated after processing all documents
-
-
- // Process stats
- for (const [userId, stats] of Object.entries(userStats)) {
- // eslint-disable-next-line no-console
- console.log(`name is ${userId}`);
- stats.numVisits = officeHourSessions[userId]?.length;
- stats.totalMinutes = Math.ceil(stats.totalMinutes);
- if (stats.timeHelpingStudents !== undefined) {
- stats.timeHelpingStudents = Math.ceil(stats.timeHelpingStudents);
- if (stats.numStudentsHelped !== undefined) {
- stats.numStudentsHelped = TAsessions[userId].length;
- }
- }
- // Personality type
- const weeksInRange = (endDate.toDate().getTime() - startDate.toDate().getTime())
- / (1000 * 60 * 60 * 24 * 7); // convert ms to weeks
- const averageSessionsPerWeek = stats.numVisits / weeksInRange;
-
- if (averageSessionsPerWeek >= 2) {
- stats.personalityType = 'Consistent';
- } else if (averageSessionsPerWeek >= 0.5) {
- stats.personalityType = 'Resourceful';
- } else {
- stats.personalityType = 'Independent';
- }
-
- // Month user spent the most time in
- stats.favMonth = monthTimeCounts[userId]?.indexOf(Math.max(...monthTimeCounts[userId]));
- // Get the ids in the map that have the highest counts
- if (taCounts[userId].size !== 0) {
- stats.favTaId = Array.from(taCounts[userId].entries()).reduce(
- (prev, next) => prev[1] < next[1] ? next : prev)[0];
- }
- // eslint-disable-next-line no-console
- console.log(`${userId}'s fav ta is ${stats.favTaId}, taCounts length is ${taCounts[userId].size}`);
- if (stats.favTaId) {
- // eslint-disable-next-line no-console
- console.log(`here`);
- // only looking at the sessions from the favorite TA that match with sessions the user went to
- const resSession = TAsessions[stats.favTaId]?.filter( (TAsession) =>
- officeHourSessions[userId].includes(TAsession.session) && TAsession.asker === userId);
- if (resSession?.length === 1) {
- stats.favClass = resSession[0].courseId;
- stats.favDay = resSession[0].day;
- // eslint-disable-next-line no-console
- console.log(`finding ${userId}'s mode stats`);
- // eslint-disable-next-line no-console
- console.log(stats.favTaId + "'s total sessions");
- // eslint-disable-next-line no-console
- console.log(TAsessions[stats.favTaId]);
- // eslint-disable-next-line no-console
- console.log(stats.favTaId + `'s total sessions with ${userId}`);
- // eslint-disable-next-line no-console
- resSession.map((x) => console.log(x));
- } else if (resSession?.length > 1) {
- /* filtering from general to specific:
- - find mode class
- - out of all the sessions for that class, find mode day
- */
-
- // eslint-disable-next-line no-console
- console.log(`finding ${userId}'s mode stats`);
- // eslint-disable-next-line no-console
- console.log(stats.favTaId + "'s total sessions");
- // eslint-disable-next-line no-console
- console.log(TAsessions[stats.favTaId]);
- // eslint-disable-next-line no-console
- console.log(stats.favTaId + `'s total sessions with ${userId}`);
- // eslint-disable-next-line no-console
- resSession.map((x) => console.log(x));
-
-
- const classFrequency: { [courseId: string]: number } = {};
- const dayFrequency: { [day: number]: number } = {};
-
- /*
- You need to find modeDay AFTER filtering all of modeCourse
- because of the case where if you filter by looking at what
- sessions have modeCourse AND modeDay, the modeDay might be a
- number that doesn't exist with modeCourse.
- */
-
- resSession.forEach((TAsession) => {
- if (!classFrequency[TAsession.courseId]) {
- classFrequency[TAsession.courseId] = 1;
- } else {
- classFrequency[TAsession.courseId] += 1;
- }
- });
-
-
- const modeCourseId = Object.keys(classFrequency).reduce((a, b) =>
- classFrequency[a] > classFrequency[b] ? a : b);
- resSession.forEach((TAsession) => {
- if (TAsession.courseId === modeCourseId) {
- if (!dayFrequency[TAsession.day]) {
- dayFrequency[TAsession.day] = 1;
- } else {
- dayFrequency[TAsession.day] += 1;
- }
- }
- });
- const modeDay = Object.keys(dayFrequency).reduce((day1, day2) =>
- dayFrequency[parseInt(day1, 10)] > dayFrequency[parseInt(day2,10)] ? day1 : day2);
- // eslint-disable-next-line no-console
- console.log(`modeCourse: ${modeCourseId} and modeDay: ${modeDay}`);
- const modeSessions = resSession.filter((TAsession) => TAsession.courseId === modeCourseId
- && TAsession.day === parseInt(modeDay,10));
-
- // eslint-disable-next-line no-console
- console.log("final filtering for modeSessions");
- // eslint-disable-next-line no-console
- console.log(modeSessions);
- // there could be multiple ties, so just picking the first one
- stats.favClass = modeSessions[0].courseId;
- stats.favDay = modeSessions[0].day;
- // eslint-disable-next-line no-console
- console.log(`favClass: ${stats.favClass}, favDay: ${stats.favDay}`);
-
- // eslint-disable-next-line no-console
- console.log("------------");
-
-
- }
- }
- }
+ processStats();
await updateWrappedDocs();
- // debugging console log
+
// eslint-disable-next-line no-console
errorUsers.forEach((errUser) => console.log(errUser.user + ": " + errUser.error));
-
-
}
(async () => {
From bcd841effa04e9276fea0662b9335aae070a7089 Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Thu, 14 Nov 2024 22:44:01 -0500
Subject: [PATCH 06/16] added extra check for tas so no 0 amounts show up
---
src/scripts/wrapped-fa24.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index c67275723..d58d46780 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -102,11 +102,14 @@ const getWrapped = async () => {
const hasVisits = stats.numVisits > 0;
// This is true if the user is either a student, or a TA who has more than one session
const isUserActive = stats.timeHelpingStudents === undefined || (TAsessions[userId]?.length > 0);
+ // True if user is either a student, or TA who helped more than 0 students for more than 0 minutes
+ const taHelped = stats.timeHelpingStudents === undefined ||
+ (stats.numStudentsHelped && stats.timeHelpingStudents > 0 && stats.numStudentsHelped > 0);
const hasFavoriteTa = stats.favTaId !== "";
const taStatsMismatched =
(stats.timeHelpingStudents !== undefined && stats.numStudentsHelped === undefined)
|| (stats.timeHelpingStudents === undefined && stats.numStudentsHelped !== undefined);
- if (hasVisits && isUserActive && hasFavoriteTa) {
+ if (hasVisits && isUserActive && hasFavoriteTa && taHelped) {
if (!(stats.favClass && stats.favDay !== -1 && stats.favMonth !== -1)) {
errorUsers.push({user: userId,
error: `User is active and has favorite TA but missing one of the following:
From 6070b5bd5b47d31ca8ff4ecb06cc63ed8bf451a6 Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Fri, 15 Nov 2024 11:37:05 -0500
Subject: [PATCH 07/16] pushing edited js file
---
src/scripts/wrapped-fa24.js | 6 ++++--
src/scripts/wrapped-fa24.ts | 2 +-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/scripts/wrapped-fa24.js b/src/scripts/wrapped-fa24.js
index bcc55c514..fb46bc88e 100644
--- a/src/scripts/wrapped-fa24.js
+++ b/src/scripts/wrapped-fa24.js
@@ -134,7 +134,7 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
officeHourSessions = {};
TAsessions = {};
updateWrappedDocs = function () { return __awaiter(void 0, void 0, void 0, function () {
- var batch, userDocuments, _i, _a, _b, userId, stats, hasVisits, isUserActive, hasFavoriteTa, taStatsMismatched, wrappedDocRef, userDoc;
+ var batch, userDocuments, _i, _a, _b, userId, stats, hasVisits, isUserActive, taHelped, hasFavoriteTa, taStatsMismatched, wrappedDocRef, userDoc;
var _c;
return __generator(this, function (_d) {
switch (_d.label) {
@@ -149,10 +149,12 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
if (userId) {
hasVisits = stats.numVisits > 0;
isUserActive = stats.timeHelpingStudents === undefined || (((_c = TAsessions[userId]) === null || _c === void 0 ? void 0 : _c.length) > 0);
+ taHelped = stats.timeHelpingStudents === undefined ||
+ (stats.numStudentsHelped && stats.timeHelpingStudents > 0 && stats.numStudentsHelped > 0);
hasFavoriteTa = stats.favTaId !== "";
taStatsMismatched = (stats.timeHelpingStudents !== undefined && stats.numStudentsHelped === undefined)
|| (stats.timeHelpingStudents === undefined && stats.numStudentsHelped !== undefined);
- if (hasVisits && isUserActive && hasFavoriteTa) {
+ if (hasVisits && isUserActive && hasFavoriteTa && taHelped) {
if (!(stats.favClass && stats.favDay !== -1 && stats.favMonth !== -1)) {
errorUsers.push({ user: userId, error: "User is active and has favorite TA but missing one of the following:\n favClass: " + stats.favClass + ", favDay: " + stats.favDay + ", favMonth: " + stats.favMonth });
}
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index d58d46780..31ea88506 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -60,7 +60,7 @@ const getWrapped = async () => {
}
const getWrappedSessionDocs = async () => {
- const docs: {[userId:string]: FirebaseFirestore.DocumentSnapshot} = {};
+ const docs: {[sessionId:string]: FirebaseFirestore.DocumentSnapshot} = {};
const sessionIds: string[] = [];
questionsSnapshot.docs.map((doc) => sessionIds.push(doc.get('sessionId')));
sessionIds.sort();
From ba06555edc0136c48ae4de5b9a5f9c4e77da9c48 Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Mon, 18 Nov 2024 10:33:43 -0500
Subject: [PATCH 08/16] undoing main changes and deleting console logs
---
.github/workflows/cd.yml | 2 +-
README.md | 2 +-
src/scripts/wrapped-fa24.ts | 33 +++------------------------------
3 files changed, 5 insertions(+), 32 deletions(-)
diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml
index ed53373c3..a3f6ed013 100644
--- a/.github/workflows/cd.yml
+++ b/.github/workflows/cd.yml
@@ -2,7 +2,7 @@ name: CD
on:
push:
branches:
- - main
+ - master
jobs:
deploy:
diff --git a/README.md b/README.md
index 17589ee8a..da546060e 100644
--- a/README.md
+++ b/README.md
@@ -117,5 +117,5 @@ _Screenshots showing major parts of app_
We are a team within **Cornell Design & Tech Initiative**. For more information, see our [website](https://cornelldti.org/).
-
+
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index 31ea88506..d69c7107b 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -9,8 +9,6 @@ admin.initializeApp({
// eslint-disable-next-line no-console
console.log('Firebase admin initialized!');
-
-
// Initialize Firestore
const db = admin.firestore();
const errorUsers: {
@@ -75,7 +73,6 @@ const getWrapped = async () => {
return docs;
}
-
const taCounts: {[userId: string] : Map} = {};
const monthTimeCounts: {[userId: string]: number[]} = {};
const officeHourSessions: { [userId: string]: string[]} = {};
@@ -192,8 +189,6 @@ const getWrapped = async () => {
numStudentsHelped: 0
};
TAsessions[answererId] = [];
- // eslint-disable-next-line no-console
- console.log(`${answererId} was a student but now theyre a TA`)
}
}
@@ -234,8 +229,7 @@ const getWrapped = async () => {
stats.favTaId = Array.from(taCounts[userId].entries()).reduce(
(prevEntry, nextEntry) => prevEntry[1] < nextEntry[1] ? nextEntry : prevEntry)[0];
}
- // eslint-disable-next-line no-console
- // console.log(`${userId}'s fav ta is ${stats.favTaId}, taCounts length is ${taCounts[userId].size}`);
+
if (stats.favTaId) {
// only looking at the sessions from the favorite TA that match with sessions the user went to
const resSession = TAsessions[stats.favTaId]?.filter( (TAsession) =>
@@ -249,17 +243,6 @@ const getWrapped = async () => {
- out of all the sessions for that class, find mode day
*/
- // eslint-disable-next-line no-console
- // console.log(`finding ${userId}'s mode stats`);
- // // eslint-disable-next-line no-console
- // console.log(stats.favTaId + "'s total sessions");
- // // eslint-disable-next-line no-console
- // console.log(TAsessions[stats.favTaId]);
- // // eslint-disable-next-line no-console
- // console.log(stats.favTaId + `'s total sessions with ${userId}`);
- // // eslint-disable-next-line no-console
- // resSession.map((x) => console.log(x));
-
const classFrequency: { [courseId: string]: number } = {};
const dayFrequency: { [day: number]: number } = {};
@@ -284,24 +267,14 @@ const getWrapped = async () => {
});
const modeDay = Object.keys(dayFrequency).reduce((day1, day2) =>
dayFrequency[parseInt(day1, 10)] > dayFrequency[parseInt(day2,10)] ? day1 : day2);
- // eslint-disable-next-line no-console
- // console.log(`modeCourse: ${modeCourseId} and modeDay: ${modeDay}`);
+
const modeSessions = resSession.filter((TAsession) => TAsession.courseId === modeCourseId
&& TAsession.day === parseInt(modeDay,10));
-
- // eslint-disable-next-line no-console
- // console.log("final filtering for modeSessions");
- // eslint-disable-next-line no-console
- // console.log(modeSessions);
// There could be multiple ties, so just picking the first one
stats.favClass = modeSessions[0].courseId;
stats.favDay = modeSessions[0].day;
- // eslint-disable-next-line no-console
- // console.log(`favClass: ${stats.favClass}, favDay: ${stats.favDay}`);
-
- // eslint-disable-next-line no-console
- // console.log("------------");
+
}
}
count++;
From 1a7d672858cf7492697aa017ab0fc0db6675a75e Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Tue, 19 Nov 2024 22:28:45 -0500
Subject: [PATCH 09/16] took out fav stats constraints
---
src/scripts/wrapped-fa24.js | 33 +--------------------------------
src/scripts/wrapped-fa24.ts | 8 +-------
2 files changed, 2 insertions(+), 39 deletions(-)
diff --git a/src/scripts/wrapped-fa24.js b/src/scripts/wrapped-fa24.js
index fb46bc88e..0346af2cd 100644
--- a/src/scripts/wrapped-fa24.js
+++ b/src/scripts/wrapped-fa24.js
@@ -103,8 +103,6 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
sessionIds = [];
questionsSnapshot.docs.map(function (doc) { return sessionIds.push(doc.get('sessionId')); });
sessionIds.sort();
- // eslint-disable-next-line no-console
- // console.log(sessionIds);
return [4 /*yield*/, Promise.all(sessionIds.map(function (id) { return __awaiter(void 0, void 0, void 0, function () {
var _a, _b;
return __generator(this, function (_c) {
@@ -122,8 +120,6 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
});
}); }))];
case 1:
- // eslint-disable-next-line no-console
- // console.log(sessionIds);
_a.sent();
return [2 /*return*/, docs];
}
@@ -155,10 +151,7 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
taStatsMismatched = (stats.timeHelpingStudents !== undefined && stats.numStudentsHelped === undefined)
|| (stats.timeHelpingStudents === undefined && stats.numStudentsHelped !== undefined);
if (hasVisits && isUserActive && hasFavoriteTa && taHelped) {
- if (!(stats.favClass && stats.favDay !== -1 && stats.favMonth !== -1)) {
- errorUsers.push({ user: userId, error: "User is active and has favorite TA but missing one of the following:\n favClass: " + stats.favClass + ", favDay: " + stats.favDay + ", favMonth: " + stats.favMonth });
- }
- else if (taStatsMismatched) {
+ if (taStatsMismatched) {
errorUsers.push({ user: userId, error: "Mismatch in updating ta specfic values." });
}
else {
@@ -241,8 +234,6 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
numStudentsHelped: 0
};
TAsessions[answererId] = [];
- // eslint-disable-next-line no-console
- console.log(answererId + " was a student but now theyre a TA");
}
};
processStats = function () {
@@ -280,8 +271,6 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
if (taCounts[userId].size !== 0) {
stats.favTaId = Array.from(taCounts[userId].entries()).reduce(function (prevEntry, nextEntry) { return prevEntry[1] < nextEntry[1] ? nextEntry : prevEntry; })[0];
}
- // eslint-disable-next-line no-console
- // console.log(`${userId}'s fav ta is ${stats.favTaId}, taCounts length is ${taCounts[userId].size}`);
if (stats.favTaId) {
// only looking at the sessions from the favorite TA that match with sessions the user went to
var resSession = (_b = TAsessions[stats.favTaId]) === null || _b === void 0 ? void 0 : _b.filter(function (TAsession) {
@@ -296,16 +285,6 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
- find mode class
- out of all the sessions for that class, find mode day
*/
- // eslint-disable-next-line no-console
- // console.log(`finding ${userId}'s mode stats`);
- // // eslint-disable-next-line no-console
- // console.log(stats.favTaId + "'s total sessions");
- // // eslint-disable-next-line no-console
- // console.log(TAsessions[stats.favTaId]);
- // // eslint-disable-next-line no-console
- // console.log(stats.favTaId + `'s total sessions with ${userId}`);
- // // eslint-disable-next-line no-console
- // resSession.map((x) => console.log(x));
var classFrequency_1 = {};
var dayFrequency_1 = {};
resSession.forEach(function (TAsession) {
@@ -332,21 +311,11 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
var modeDay_1 = Object.keys(dayFrequency_1).reduce(function (day1, day2) {
return dayFrequency_1[parseInt(day1, 10)] > dayFrequency_1[parseInt(day2, 10)] ? day1 : day2;
});
- // eslint-disable-next-line no-console
- // console.log(`modeCourse: ${modeCourseId} and modeDay: ${modeDay}`);
var modeSessions = resSession.filter(function (TAsession) { return TAsession.courseId === modeCourseId_1
&& TAsession.day === parseInt(modeDay_1, 10); });
- // eslint-disable-next-line no-console
- // console.log("final filtering for modeSessions");
- // eslint-disable-next-line no-console
- // console.log(modeSessions);
// There could be multiple ties, so just picking the first one
stats.favClass = modeSessions[0].courseId;
stats.favDay = modeSessions[0].day;
- // eslint-disable-next-line no-console
- // console.log(`favClass: ${stats.favClass}, favDay: ${stats.favDay}`);
- // eslint-disable-next-line no-console
- // console.log("------------");
}
}
count++;
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index d69c7107b..7aaf8997b 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -62,8 +62,6 @@ const getWrapped = async () => {
const sessionIds: string[] = [];
questionsSnapshot.docs.map((doc) => sessionIds.push(doc.get('sessionId')));
sessionIds.sort();
- // eslint-disable-next-line no-console
- // console.log(sessionIds);
await Promise.all(sessionIds.map(async (id) => {
if (id) {
docs[id] = await sessionsRef.doc(id).get();
@@ -107,11 +105,7 @@ const getWrapped = async () => {
(stats.timeHelpingStudents !== undefined && stats.numStudentsHelped === undefined)
|| (stats.timeHelpingStudents === undefined && stats.numStudentsHelped !== undefined);
if (hasVisits && isUserActive && hasFavoriteTa && taHelped) {
- if (!(stats.favClass && stats.favDay !== -1 && stats.favMonth !== -1)) {
- errorUsers.push({user: userId,
- error: `User is active and has favorite TA but missing one of the following:
- favClass: ${stats.favClass}, favDay: ${stats.favDay}, favMonth: ${stats.favMonth}`});
- } else if (taStatsMismatched) {
+ if (taStatsMismatched) {
errorUsers.push({user: userId, error: "Mismatch in updating ta specfic values."})
} else {
const wrappedDocRef = wrappedRef.doc(userId);
From 997af906c5ddb72ae1850b15ed8cac84bd88b5f8 Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Tue, 19 Nov 2024 22:31:47 -0500
Subject: [PATCH 10/16] added initial values to reduce and extra check for
undefined course
---
src/scripts/wrapped-fa24.ts | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index 7aaf8997b..6014feb60 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -248,8 +248,8 @@ const getWrapped = async () => {
}
});
- const modeCourseId = Object.keys(classFrequency).reduce((courseId1, courseId2) =>
- classFrequency[courseId1] > classFrequency[courseId2] ? courseId1 : courseId2);
+ const modeCourseId = Object.keys(classFrequency).reduce(((courseId1:string, courseId2:string) =>
+ classFrequency[courseId1] > classFrequency[courseId2] ? courseId1 : courseId2), "");
resSession.forEach((TAsession) => {
if (TAsession.courseId === modeCourseId) {
if (!dayFrequency[TAsession.day]) {
@@ -259,8 +259,8 @@ const getWrapped = async () => {
}
}
});
- const modeDay = Object.keys(dayFrequency).reduce((day1, day2) =>
- dayFrequency[parseInt(day1, 10)] > dayFrequency[parseInt(day2,10)] ? day1 : day2);
+ const modeDay = Object.keys(dayFrequency).reduce(((day1, day2) =>
+ dayFrequency[parseInt(day1, 10)] > dayFrequency[parseInt(day2,10)] ? day1 : day2), "");
const modeSessions = resSession.filter((TAsession) => TAsession.courseId === modeCourseId
&& TAsession.day === parseInt(modeDay,10));
@@ -317,12 +317,13 @@ const getWrapped = async () => {
officeHourSessions[askerId] = officeHourSessions[askerId] || [];
if (!officeHourSessions[askerId].includes(sessionId)) {
officeHourSessions[askerId].push(sessionId); }
-
- if (answererId && timeAddressed) {
+
+ const course = sessionDoc.get('courseId');
+ if (answererId && timeAddressed && course) {
TAsessions[answererId]?.push({
session: sessionId,
asker: askerId,
- courseId: sessionDoc.get('courseId'),
+ courseId: course,
day: timeAddressed.toDate().getDay()
});
From d6623b8123903c646e0c363e08d9e2c930f6c7a9 Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Wed, 20 Nov 2024 00:13:03 -0500
Subject: [PATCH 11/16] pushing js file
---
src/scripts/wrapped-fa24.js | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/scripts/wrapped-fa24.js b/src/scripts/wrapped-fa24.js
index 0346af2cd..642cc8357 100644
--- a/src/scripts/wrapped-fa24.js
+++ b/src/scripts/wrapped-fa24.js
@@ -295,9 +295,9 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
classFrequency_1[TAsession.courseId] += 1;
}
});
- var modeCourseId_1 = Object.keys(classFrequency_1).reduce(function (courseId1, courseId2) {
+ var modeCourseId_1 = Object.keys(classFrequency_1).reduce((function (courseId1, courseId2) {
return classFrequency_1[courseId1] > classFrequency_1[courseId2] ? courseId1 : courseId2;
- });
+ }), "");
resSession.forEach(function (TAsession) {
if (TAsession.courseId === modeCourseId_1) {
if (!dayFrequency_1[TAsession.day]) {
@@ -308,9 +308,9 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
}
}
});
- var modeDay_1 = Object.keys(dayFrequency_1).reduce(function (day1, day2) {
+ var modeDay_1 = Object.keys(dayFrequency_1).reduce((function (day1, day2) {
return dayFrequency_1[parseInt(day1, 10)] > dayFrequency_1[parseInt(day2, 10)] ? day1 : day2;
- });
+ }), "");
var modeSessions = resSession.filter(function (TAsession) { return TAsession.courseId === modeCourseId_1
&& TAsession.day === parseInt(modeDay_1, 10); });
// There could be multiple ties, so just picking the first one
@@ -358,11 +358,12 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
if (!officeHourSessions[askerId].includes(sessionId)) {
officeHourSessions[askerId].push(sessionId);
}
- if (answererId && timeAddressed) {
+ var course = sessionDoc.get('courseId');
+ if (answererId && timeAddressed && course) {
(_c = TAsessions[answererId]) === null || _c === void 0 ? void 0 : _c.push({
session: sessionId,
asker: askerId,
- courseId: sessionDoc.get('courseId'),
+ courseId: course,
day: timeAddressed.toDate().getDay()
});
if (!((_d = taCounts[askerId]) === null || _d === void 0 ? void 0 : _d.has(answererId))) {
From c014d383907a08ea55916de51b8fcf5bc7ce9288 Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Wed, 20 Nov 2024 13:17:36 -0500
Subject: [PATCH 12/16] readding check for month and removing hasFavTa
---
src/scripts/wrapped-fa24.js | 6 +++---
src/scripts/wrapped-fa24.ts | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/scripts/wrapped-fa24.js b/src/scripts/wrapped-fa24.js
index 642cc8357..0b9033e47 100644
--- a/src/scripts/wrapped-fa24.js
+++ b/src/scripts/wrapped-fa24.js
@@ -130,7 +130,7 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
officeHourSessions = {};
TAsessions = {};
updateWrappedDocs = function () { return __awaiter(void 0, void 0, void 0, function () {
- var batch, userDocuments, _i, _a, _b, userId, stats, hasVisits, isUserActive, taHelped, hasFavoriteTa, taStatsMismatched, wrappedDocRef, userDoc;
+ var batch, userDocuments, _i, _a, _b, userId, stats, hasVisits, isUserActive, taHelped, hasMinutes, taStatsMismatched, wrappedDocRef, userDoc;
var _c;
return __generator(this, function (_d) {
switch (_d.label) {
@@ -147,10 +147,10 @@ var getWrapped = function () { return __awaiter(void 0, void 0, void 0, function
isUserActive = stats.timeHelpingStudents === undefined || (((_c = TAsessions[userId]) === null || _c === void 0 ? void 0 : _c.length) > 0);
taHelped = stats.timeHelpingStudents === undefined ||
(stats.numStudentsHelped && stats.timeHelpingStudents > 0 && stats.numStudentsHelped > 0);
- hasFavoriteTa = stats.favTaId !== "";
+ hasMinutes = stats.favMonth !== -1 && stats.totalMinutes > 0;
taStatsMismatched = (stats.timeHelpingStudents !== undefined && stats.numStudentsHelped === undefined)
|| (stats.timeHelpingStudents === undefined && stats.numStudentsHelped !== undefined);
- if (hasVisits && isUserActive && hasFavoriteTa && taHelped) {
+ if (hasVisits && isUserActive && hasMinutes && taHelped) {
if (taStatsMismatched) {
errorUsers.push({ user: userId, error: "Mismatch in updating ta specfic values." });
}
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index 6014feb60..e9ff82771 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -100,11 +100,11 @@ const getWrapped = async () => {
// True if user is either a student, or TA who helped more than 0 students for more than 0 minutes
const taHelped = stats.timeHelpingStudents === undefined ||
(stats.numStudentsHelped && stats.timeHelpingStudents > 0 && stats.numStudentsHelped > 0);
- const hasFavoriteTa = stats.favTaId !== "";
+ const hasMinutes = stats.favMonth !== -1 && stats.totalMinutes > 0;
const taStatsMismatched =
(stats.timeHelpingStudents !== undefined && stats.numStudentsHelped === undefined)
|| (stats.timeHelpingStudents === undefined && stats.numStudentsHelped !== undefined);
- if (hasVisits && isUserActive && hasFavoriteTa && taHelped) {
+ if (hasVisits && isUserActive && hasMinutes && taHelped) {
if (taStatsMismatched) {
errorUsers.push({user: userId, error: "Mismatch in updating ta specfic values."})
} else {
From 01ffc3a5d802482fe07f9b28051c0cdf8b212db2 Mon Sep 17 00:00:00 2001
From: rgu0114
Date: Thu, 21 Nov 2024 15:33:10 -0500
Subject: [PATCH 13/16] deploy run changes
---
src/scripts/wrapped-fa24.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/scripts/wrapped-fa24.ts b/src/scripts/wrapped-fa24.ts
index e9ff82771..5fd7c220c 100644
--- a/src/scripts/wrapped-fa24.ts
+++ b/src/scripts/wrapped-fa24.ts
@@ -2,7 +2,7 @@ import admin from "firebase-admin";
admin.initializeApp({
credential: admin.credential.applicationDefault(),
- databaseURL: 'https://qmi-test.firebaseio.com'
+ databaseURL: 'https://queue-me-in-prod.firebaseio.com'
});
@@ -25,7 +25,7 @@ const getWrapped = async () => {
// Refs
const questionsRef = db.collection('questions');
const sessionsRef = db.collection('sessions');
- const wrappedRef = db.collection('wrapped-fa24');
+ const wrappedRef = db.collection('wrapped');
const usersRef = db.collection('users');
// Query all questions asked between FA23 and SP24
From fed45dc520b0fd55e8cd4fa75746cd2aa51f3ab9 Mon Sep 17 00:00:00 2001
From: rgu0114
Date: Thu, 21 Nov 2024 15:33:28 -0500
Subject: [PATCH 14/16] wrapped validation script
---
src/scripts/query-wrapped.ts | 58 ++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
create mode 100644 src/scripts/query-wrapped.ts
diff --git a/src/scripts/query-wrapped.ts b/src/scripts/query-wrapped.ts
new file mode 100644
index 000000000..013a1f61e
--- /dev/null
+++ b/src/scripts/query-wrapped.ts
@@ -0,0 +1,58 @@
+import admin from 'firebase-admin';
+
+// Initialize Firebase Admin with credentials and database URL
+admin.initializeApp({
+ credential: admin.credential.applicationDefault(),
+ databaseURL: 'https://queue-me-in-prod.firebaseio.com'
+});
+
+// Initialize Firestore database
+const db = admin.firestore();
+
+async function validateDocuments() {
+ // Reference to the 'wrapped' collection
+ const wrappedRef = db.collection('wrapped');
+
+ try {
+ // Get all documents in the collection
+ const snapshot = await wrappedRef.get();
+
+ // Print the total number of documents
+ // eslint-disable-next-line no-console
+ console.log(`Total number of documents in 'wrapped-fa24': ${snapshot.size}`);
+
+ // Iterate over each document
+ snapshot.forEach(doc => {
+ const data = doc.data();
+ const errors = [];
+
+ // Check if numVisits is a positive number
+ if (data.numVisits <= 0) {
+ errors.push('numVisits is not positive');
+ }
+
+ // Check if personalityType is not an empty string
+ if (!data.personalityType || data.personalityType.trim() === '') {
+ errors.push('personalityType is empty');
+ }
+
+ // Check if totalMinutes is a positive number
+ if (data.totalMinutes <= 0) {
+ errors.push('totalMinutes is not positive');
+ }
+
+ // If there are errors, log them with the user ID
+ if (errors.length > 0) {
+ // eslint-disable-next-line no-console
+ console.log(`Document ID: ${doc.id} has the following issues: ${errors.join(', ')}`);
+ }
+ });
+ } catch (error) {
+ // Log any errors that occur during the fetch
+ // eslint-disable-next-line no-console
+ console.error('Error retrieving documents:', error);
+ }
+}
+
+// Call the function to execute it
+validateDocuments();
From 0aa0aa79ad44965ac8f33005be571d30f3dbc43f Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Fri, 22 Nov 2024 00:24:25 -0500
Subject: [PATCH 15/16] extra check that all students have a taId
---
src/scripts/query-wrapped.js | 102 +++++++++++++++++++++++++++++++++++
src/scripts/query-wrapped.ts | 5 ++
2 files changed, 107 insertions(+)
create mode 100644 src/scripts/query-wrapped.js
diff --git a/src/scripts/query-wrapped.js b/src/scripts/query-wrapped.js
new file mode 100644
index 000000000..7672c9f15
--- /dev/null
+++ b/src/scripts/query-wrapped.js
@@ -0,0 +1,102 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (_) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+exports.__esModule = true;
+var firebase_admin_1 = require("firebase-admin");
+// Initialize Firebase Admin with credentials and database URL
+firebase_admin_1["default"].initializeApp({
+ credential: firebase_admin_1["default"].credential.applicationDefault(),
+ databaseURL: 'https://queue-me-in-prod.firebaseio.com'
+});
+// Initialize Firestore database
+var db = firebase_admin_1["default"].firestore();
+function validateDocuments() {
+ return __awaiter(this, void 0, void 0, function () {
+ var wrappedRef, snapshot, error_1;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ wrappedRef = db.collection('wrapped');
+ _a.label = 1;
+ case 1:
+ _a.trys.push([1, 3, , 4]);
+ return [4 /*yield*/, wrappedRef.get()];
+ case 2:
+ snapshot = _a.sent();
+ // Print the total number of documents
+ // eslint-disable-next-line no-console
+ console.log("Total number of documents in 'wrapped-fa24': " + snapshot.size);
+ // Iterate over each document
+ snapshot.forEach(function (doc) {
+ var data = doc.data();
+ var errors = [];
+ // Check if numVisits is a positive number
+ if (data.numVisits <= 0) {
+ errors.push('numVisits is not positive');
+ }
+ // Check if personalityType is not an empty string
+ if (!data.personalityType || data.personalityType.trim() === '') {
+ errors.push('personalityType is empty');
+ }
+ // Check if totalMinutes is a positive number
+ if (data.totalMinutes <= 0) {
+ errors.push('totalMinutes is not positive');
+ }
+ // Check if favTa exists for students
+ if (!data.timeHelpingStudents && data.numStudentsHelped === 0 && data.favTaId) {
+ errors.push('favTaId is missing');
+ }
+ // If there are errors, log them with the user ID
+ if (errors.length > 0) {
+ // eslint-disable-next-line no-console
+ console.log("Document ID: " + doc.id + " has the following issues: " + errors.join(', '));
+ }
+ });
+ return [3 /*break*/, 4];
+ case 3:
+ error_1 = _a.sent();
+ // Log any errors that occur during the fetch
+ // eslint-disable-next-line no-console
+ console.error('Error retrieving documents:', error_1);
+ return [3 /*break*/, 4];
+ case 4: return [2 /*return*/];
+ }
+ });
+ });
+}
+// Call the function to execute it
+validateDocuments();
diff --git a/src/scripts/query-wrapped.ts b/src/scripts/query-wrapped.ts
index 013a1f61e..d1e856ee9 100644
--- a/src/scripts/query-wrapped.ts
+++ b/src/scripts/query-wrapped.ts
@@ -41,6 +41,11 @@ async function validateDocuments() {
errors.push('totalMinutes is not positive');
}
+ // Check if favTa exists for students
+ if (!data.timeHelpingStudents && data.numStudentsHelped === 0 && data.favTaId) {
+ errors.push('favTaId is missing');
+ }
+
// If there are errors, log them with the user ID
if (errors.length > 0) {
// eslint-disable-next-line no-console
From dfa3807403ed59355922fc338bb209067d8fe6c8 Mon Sep 17 00:00:00 2001
From: NIDHI2023
Date: Thu, 5 Dec 2024 00:09:13 -0500
Subject: [PATCH 16/16] added extra checks for fields in verification script
---
src/scripts/query-wrapped.js | 19 ++++++++++++++++++-
src/scripts/query-wrapped.ts | 23 ++++++++++++++++++++++-
2 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/src/scripts/query-wrapped.js b/src/scripts/query-wrapped.js
index 7672c9f15..7d219e48d 100644
--- a/src/scripts/query-wrapped.js
+++ b/src/scripts/query-wrapped.js
@@ -77,9 +77,26 @@ function validateDocuments() {
errors.push('totalMinutes is not positive');
}
// Check if favTa exists for students
- if (!data.timeHelpingStudents && data.numStudentsHelped === 0 && data.favTaId) {
+ if (!data.timeHelpingStudents && !data.numStudentsHelped && !data.favTaId) {
errors.push('favTaId is missing');
}
+ // Check if one of the TA stats exists but the other doesn't
+ if ((data.timeHelpingStudents && !data.numStudentsHelped)
+ || (!data.timeHelpingStudents && data.numStudentsHelped)) {
+ errors.push('One of the TA stats is mismatched');
+ }
+ // Check if favClass is not an empty string
+ if (!data.favClass || data.favClass.trim() === '') {
+ errors.push('favClass is empty');
+ }
+ // Check if favDay is not a default value
+ if (data.favDay === -1) {
+ errors.push('favDay is not valid');
+ }
+ // Check if favMonth is not a default value
+ if (data.favMonth === -1) {
+ errors.push('favMonth is not valid');
+ }
// If there are errors, log them with the user ID
if (errors.length > 0) {
// eslint-disable-next-line no-console
diff --git a/src/scripts/query-wrapped.ts b/src/scripts/query-wrapped.ts
index d1e856ee9..5da693877 100644
--- a/src/scripts/query-wrapped.ts
+++ b/src/scripts/query-wrapped.ts
@@ -42,10 +42,31 @@ async function validateDocuments() {
}
// Check if favTa exists for students
- if (!data.timeHelpingStudents && data.numStudentsHelped === 0 && data.favTaId) {
+ if (!data.timeHelpingStudents && !data.numStudentsHelped && !data.favTaId) {
errors.push('favTaId is missing');
}
+ // Check if one of the TA stats exists but the other doesn't
+ if ((data.timeHelpingStudents && !data.numStudentsHelped)
+ || (!data.timeHelpingStudents && data.numStudentsHelped)) {
+ errors.push('One of the TA stats is mismatched')
+ }
+
+ // Check if favClass is not an empty string
+ if (!data.favClass || data.favClass.trim() === '') {
+ errors.push('favClass is empty');
+ }
+
+ // Check if favDay is not a default value
+ if (data.favDay === -1) {
+ errors.push('favDay is not valid');
+ }
+
+ // Check if favMonth is not a default value
+ if (data.favMonth === -1) {
+ errors.push('favMonth is not valid');
+ }
+
// If there are errors, log them with the user ID
if (errors.length > 0) {
// eslint-disable-next-line no-console