teacher-tools/api/source/sample_data.d

128 lines
4.3 KiB
D

module sample_data;
import db;
import data_utils;
import d2sqlite3;
import std.random;
import std.algorithm;
import std.array;
import std.datetime;
private const STUDENT_NAMES = [
"Andrew",
"Richard",
"Klaus",
"John",
"Wilson",
"Grace",
"Sarah",
"Rebecca",
"Lily",
"Thomas",
"Michael",
"Jennifer",
"Robert",
"Christopher",
"Margaret",
"Mordecai",
"Rigby",
"Walter",
"Roy",
"Cindy"
];
void insertSampleData(ref Database db) {
db.begin();
ulong adminUserId = addUser(db, "test", "test", false, true);
ulong normalUserId = addUser(db, "test2", "test", false, false);
Random rand = Random(0);
const SysTime now = Clock.currTime();
const Date today = Date(now.year, now.month, now.day);
for (ushort i = 1; i <= 6; i++) {
ulong classId = addClass(db, "2024-2025", i, adminUserId);
bool classHasAssignedDesks = uniform01(rand) < 0.5;
size_t count = uniform(10, STUDENT_NAMES.length, rand);
auto studentsToAdd = randomSample(STUDENT_NAMES, count, rand);
ushort deskNumber = 1;
foreach (name; studentsToAdd) {
bool removed = uniform01(rand) < 0.1;
ushort assignedDeskNumber = 0;
if (classHasAssignedDesks) {
assignedDeskNumber = deskNumber++;
}
ulong studentId = addStudent(db, name, classId, assignedDeskNumber, removed);
// Add entries for the last N days
for (int n = 0; n < 30; n++) {
Date entryDate = today - days(n);
bool missingEntry = uniform01(rand) < 0.05;
if (missingEntry) continue;
bool absent = uniform01(rand) < 0.05;
bool phoneCompliant = uniform01(rand) < 0.85;
ubyte behaviorRating = 3;
string behaviorComment = null;
if (uniform01(rand) < 0.25) {
behaviorRating = 2;
behaviorComment = "They did not participate enough.";
if (uniform01(rand) < 0.5) {
behaviorRating = 3;
behaviorComment = "They are a horrible student.";
}
}
addEntry(db, classId, studentId, entryDate, absent, phoneCompliant, behaviorRating, behaviorComment);
}
}
}
db.commit();
}
ulong addUser(ref Database db, string username, string password, bool locked, bool admin) {
const query = "INSERT INTO user (username, password_hash, created_at, is_locked, is_admin) VALUES (?, ?, ?, ?, ?)";
import std.digest.sha;
import std.stdio;
string passwordHash = cast(string) sha256Of(password).toHexString().idup;
db.execute(query, username, passwordHash, getUnixTimestampMillis(), locked, admin);
return db.lastInsertRowid();
}
ulong addClass(ref Database db, string schoolYear, ushort number, ulong userId) {
const query = "INSERT INTO classroom_compliance_class (number, school_year, user_id) VALUES (?, ?, ?)";
db.execute(query, number, schoolYear, userId);
return db.lastInsertRowid();
}
ulong addStudent(ref Database db, string name, ulong classId, ushort deskNumber, bool removed) {
const query = "INSERT INTO classroom_compliance_student (name, class_id, desk_number, removed) VALUES (?, ?, ?, ?)";
db.execute(query, name, classId, deskNumber, removed);
return db.lastInsertRowid();
}
void addEntry(
ref Database db,
ulong classId,
ulong studentId,
Date date,
bool absent,
bool phoneCompliant,
ubyte behaviorRating,
string behaviorComment
) {
const entryQuery = "
INSERT INTO classroom_compliance_entry
(class_id, student_id, date, created_at, absent)
VALUES (?, ?, ?, ?, ?)";
db.execute(entryQuery, classId, studentId, date.toISOExtString(), getUnixTimestampMillis(), absent);
if (absent) return;
ulong entryId = db.lastInsertRowid();
const phoneQuery = "INSERT INTO classroom_compliance_entry_phone (entry_id, compliant) VALUES (?, ?)";
db.execute(phoneQuery, entryId, phoneCompliant);
const behaviorQuery = "
INSERT INTO classroom_compliance_entry_behavior
(entry_id, rating, comment)
VALUES (?, ?, ?)";
db.execute(behaviorQuery, entryId, behaviorRating, behaviorComment);
}