-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcoins_calculator_html.js
More file actions
129 lines (109 loc) · 3.88 KB
/
Copy pathcoins_calculator_html.js
File metadata and controls
129 lines (109 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
const xlsx = require("xlsx");
const fs = require("fs");
const readline = require("readline");
const { parse, format, addDays, differenceInDays } = require("date-fns");
// === PROMPT USER WITH DEFAULT SUPPORT ===
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function promptDefault(query, defaultValue) {
return new Promise(resolve =>
rl.question(`${query} (default: ${defaultValue}): `, input =>
resolve(input.trim() === "" ? defaultValue : input.trim())
)
);
}
async function main() {
// === PROMPT WITH DEFAULTS ===
const defaultFile = "Time_and_Topic.xlsx";
const defaultStart = "2025-07-11";
const defaultEnd = "2025-08-04";
const filePath = await promptDefault("Enter the Excel filename", defaultFile);
const startDateStr = await promptDefault("Enter the start date (YYYY-MM-DD)", defaultStart);
const endDateStr = await promptDefault("Enter the end date (YYYY-MM-DD)", defaultEnd);
rl.close();
const MIN_MINUTES = 31;
const MIN_TOPICS = 1;
const startDate = parse(startDateStr, "yyyy-MM-dd", new Date());
const endDate = parse(endDateStr, "yyyy-MM-dd", new Date());
const totalDaysInPeriod = differenceInDays(endDate, startDate) + 1;
// === LOAD WORKBOOK ===
const wb = xlsx.readFile(filePath);
const sheet = wb.Sheets[wb.SheetNames[0]];
const data = xlsx.utils.sheet_to_json(sheet, { range: 3 });
// === DETECT MAX DAY INDEX FROM ALL ROWS ===
let maxDay = 0;
data.forEach((row) => {
Object.keys(row).forEach((key) => {
const match = key.match(/^h:mm_(\d+)$/);
if (match) {
const dayNum = parseInt(match[1]);
if (dayNum > maxDay) maxDay = dayNum;
}
});
});
// === DETECT TIME/TOPIC COLUMNS DYNAMICALLY ===
const pairs = [];
for (let i = 1; i <= maxDay; i++) {
pairs.push([`h:mm_${i}`, `added to pie_${i}`]);
}
// === UTILITY ===
function timeToMinutes(time) {
if (!time || typeof time !== "string") return 0;
const parts = time.split(":");
return parseInt(parts[0]) * 60 + parseInt(parts[1]);
}
// === PROCESS STUDENTS ===
const results = data.map((row) => {
const name = row[Object.keys(row)[0]];
const studentId = row[Object.keys(row)[2]];
const email = row[Object.keys(row)[3]];
let coins = 0;
const dailyLog = [];
pairs.forEach(([timeCol, topicCol], index) => {
const date = format(addDays(startDate, index), "yyyy-MM-dd");
const minutes = timeToMinutes(row[timeCol]);
const topics = parseFloat(row[topicCol]) || 0;
const minMsg = minutes >= MIN_MINUTES ? null : `${minutes} mins (needs ${MIN_MINUTES} mins)`;
const topicMsg = topics >= MIN_TOPICS ? null : `${topics} topics (needs ${MIN_TOPICS} topic${MIN_TOPICS > 1 ? 's' : ''})`;
const qualified = !minMsg && !topicMsg;
if (qualified) coins++;
let reason = "";
if (qualified) {
reason = `✅ Met requirement: ${minutes} mins + ${topics} topics`;
} else {
const parts = [];
if (minMsg) parts.push(minMsg);
if (topicMsg) parts.push(topicMsg);
reason = `❌ Not enough: ` + parts.join(" and ");
}
dailyLog.push({
day: index + 1,
date,
qualified,
minutes,
topics,
reason
});
});
const percentComplete = ((coins / maxDay) * 100).toFixed(1);
return { studentId, name, email, coins, maxDay, totalDaysInPeriod, percentComplete, dailyLog };
});
// === JSON OUTPUT ===
const jsonMap = {};
results.forEach(s => {
jsonMap[s.studentId] = {
name: s.name,
email: s.email,
coins: s.coins,
totalDays: s.maxDay,
periodDays: s.totalDaysInPeriod,
percentComplete: parseFloat(s.percentComplete),
dailyLog: s.dailyLog
};
});
fs.writeFileSync("students.json", JSON.stringify(jsonMap, null, 2));
console.log("✅ JSON file written to students.json");
}
main();