Skip to content

Commit 1945f6d

Browse files
dawangkgithub-actions[bot]
authored andcommitted
Auto-formatted the code using Prettier
1 parent 82d46fb commit 1945f6d

File tree

1 file changed

+90
-86
lines changed

1 file changed

+90
-86
lines changed

course-matrix/backend/src/controllers/generatorController.ts

Lines changed: 90 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import exp from 'constants';
2-
import {Request, Response} from 'express';
1+
import exp from "constants";
2+
import { Request, Response } from "express";
33

4-
import {supabase} from '../db/setupDb'; // Supabase instance for database interactions
5-
import asyncHandler from '../middleware/asyncHandler'; // Middleware to handle async route handlers
4+
import { supabase } from "../db/setupDb"; // Supabase instance for database interactions
5+
import asyncHandler from "../middleware/asyncHandler"; // Middleware to handle async route handlers
66

77
// Interface to define the structure of an Offering
88
export interface Offering {
@@ -28,29 +28,29 @@ export function createOffering(overrides: Partial<Offering> = {}): Offering {
2828
return {
2929
id: overrides.id ?? -1,
3030
course_id: overrides.course_id ?? -1,
31-
meeting_section: overrides.meeting_section ?? 'No Section',
32-
offering: overrides.offering ?? 'No Offering',
33-
day: overrides.day ?? 'N/A',
34-
start: overrides.start ?? '00:00:00',
35-
end: overrides.end ?? '00:00:00',
36-
location: overrides.location ?? 'No Room',
31+
meeting_section: overrides.meeting_section ?? "No Section",
32+
offering: overrides.offering ?? "No Offering",
33+
day: overrides.day ?? "N/A",
34+
start: overrides.start ?? "00:00:00",
35+
end: overrides.end ?? "00:00:00",
36+
location: overrides.location ?? "No Room",
3737
current: overrides.current ?? -1,
3838
max: overrides.max ?? -1,
3939
is_waitlisted: overrides.is_waitlisted ?? false,
40-
delivery_mode: overrides.delivery_mode ?? 'N/A',
41-
instructor: overrides.instructor ?? 'N/A',
42-
notes: overrides.notes ?? 'N/A',
43-
code: overrides.code ?? 'N/A',
40+
delivery_mode: overrides.delivery_mode ?? "N/A",
41+
instructor: overrides.instructor ?? "N/A",
42+
notes: overrides.notes ?? "N/A",
43+
code: overrides.code ?? "N/A",
4444
};
4545
}
4646

4747
// Enum to define different types of restrictions for offerings
4848
export enum RestrictionType {
49-
RestrictBefore = 'Restrict Before',
50-
RestrictAfter = 'Restrict After',
51-
RestrictBetween = 'Restrict Between',
52-
RestrictDay = 'Restrict Day',
53-
RestrictDaysOff = 'Days Off',
49+
RestrictBefore = "Restrict Before",
50+
RestrictAfter = "Restrict After",
51+
RestrictBetween = "Restrict Between",
52+
RestrictDay = "Restrict Day",
53+
RestrictDaysOff = "Days Off",
5454
}
5555

5656
// Interface for the restriction object
@@ -79,17 +79,17 @@ export interface OfferingList {
7979
// course (LEC, TUT, PRA)
8080
export interface CategorizedOfferingList {
8181
course_id: number;
82-
category: 'LEC'|'TUT'|'PRA';
82+
category: "LEC" | "TUT" | "PRA";
8383
offerings: Record<string, Offering[]>;
8484
}
8585

8686
// Function to fetch offerings from the database for a given course and semester
8787
export async function getOfferings(course_id: number, semester: string) {
88-
let {data: offeringData, error: offeringError} =
89-
await supabase.schema('course')
90-
.from('offerings')
91-
.select(
92-
`
88+
let { data: offeringData, error: offeringError } = await supabase
89+
.schema("course")
90+
.from("offerings")
91+
.select(
92+
`
9393
id,
9494
course_id,
9595
meeting_section,
@@ -106,9 +106,9 @@ export async function getOfferings(course_id: number, semester: string) {
106106
notes,
107107
code
108108
`,
109-
)
110-
.eq('course_id', course_id)
111-
.eq('offering', semester);
109+
)
110+
.eq("course_id", course_id)
111+
.eq("offering", semester);
112112

113113
return offeringData;
114114
}
@@ -138,18 +138,16 @@ export async function getMaxDays(restrictions: Restriction[]) {
138138
for (const restriction of restrictions) {
139139
if (restriction.disabled) continue;
140140
if (restriction.type == RestrictionType.RestrictDaysOff) {
141-
return 5 -
142-
restriction
143-
.numDays; // Subtract the restricted days from the total days
141+
return 5 - restriction.numDays; // Subtract the restricted days from the total days
144142
}
145143
}
146-
return 5; // Default to 5 days if no restrictions
144+
return 5; // Default to 5 days if no restrictions
147145
}
148146

149147
// Function to check if an offering satisfies the restrictions
150148
export function isValidOffering(
151-
offering: Offering,
152-
restrictions: Restriction[],
149+
offering: Offering,
150+
restrictions: Restriction[],
153151
) {
154152
for (const restriction of restrictions) {
155153
if (restriction.disabled) continue;
@@ -161,15 +159,17 @@ export function isValidOffering(
161159
break;
162160

163161
case RestrictionType.RestrictAfter:
164-
console.log('====');
162+
console.log("====");
165163
console.log(offering.end);
166164
console.log(restriction.endTime);
167165
if (offering.end > restriction.startTime) return false;
168166
break;
169167

170168
case RestrictionType.RestrictBetween:
171-
if (offering.start < restriction.endTime &&
172-
restriction.startTime < offering.end) {
169+
if (
170+
offering.start < restriction.endTime &&
171+
restriction.startTime < offering.end
172+
) {
173173
return false;
174174
}
175175
break;
@@ -188,16 +188,16 @@ export function isValidOffering(
188188

189189
// Function to get valid offerings by filtering them based on the restrictions
190190
export async function getValidOfferings(
191-
groups: Record<string, Offering[]>,
192-
restrictions: Restriction[],
191+
groups: Record<string, Offering[]>,
192+
restrictions: Restriction[],
193193
) {
194194
const validGroups: Record<string, Offering[]> = {};
195195

196196
// Loop through each group in the groups object
197197
for (const [groupKey, offerings] of Object.entries(groups)) {
198198
// Check if all offerings in the group are valid
199-
const allValid = offerings.every(
200-
(offering) => isValidOffering(offering, restrictions),
199+
const allValid = offerings.every((offering) =>
200+
isValidOffering(offering, restrictions),
201201
);
202202

203203
// Only add the group to validGroups if all offerings are valid
@@ -212,33 +212,33 @@ export async function getValidOfferings(
212212

213213
// Function to categorize offerings into lectures, tutorials, and practicals
214214
export async function categorizeValidOfferings(
215-
offerings: GroupedOfferingList[],
215+
offerings: GroupedOfferingList[],
216216
) {
217217
const lst: CategorizedOfferingList[] = [];
218218

219219
for (const offering of offerings) {
220220
const lectures: CategorizedOfferingList = {
221221
course_id: offering.course_id,
222-
category: 'LEC',
222+
category: "LEC",
223223
offerings: {},
224224
};
225225
const tutorials: CategorizedOfferingList = {
226226
course_id: offering.course_id,
227-
category: 'TUT',
227+
category: "TUT",
228228
offerings: {},
229229
};
230230
const practicals: CategorizedOfferingList = {
231231
course_id: offering.course_id,
232-
category: 'PRA',
232+
category: "PRA",
233233
offerings: {},
234234
};
235235

236236
for (const [meeting_section, offerings] of Object.entries(
237-
offering.groups,
238-
)) {
239-
if (meeting_section && meeting_section.startsWith('PRA')) {
237+
offering.groups,
238+
)) {
239+
if (meeting_section && meeting_section.startsWith("PRA")) {
240240
practicals.offerings[meeting_section] = offerings;
241-
} else if (meeting_section && meeting_section.startsWith('TUT')) {
241+
} else if (meeting_section && meeting_section.startsWith("TUT")) {
242242
tutorials.offerings[meeting_section] = offerings;
243243
} else {
244244
lectures.offerings[meeting_section] = offerings;
@@ -260,19 +260,19 @@ export async function canInsert(toInsert: Offering, curList: Offering[]) {
260260
for (const offering of curList) {
261261
if (offering.day == toInsert.day) {
262262
if (offering.start < toInsert.end && toInsert.start < offering.end) {
263-
return false; // Check if the time overlaps
263+
return false; // Check if the time overlaps
264264
}
265265
}
266266
}
267267

268-
return true; // No conflict found
268+
return true; // No conflict found
269269
}
270270

271271
// Function to check if an ever offerings in toInstList can be inserted into
272272
// the current list of offerings without conflicts
273273
export async function canInsertList(
274-
toInsertList: Offering[],
275-
curList: Offering[],
274+
toInsertList: Offering[],
275+
curList: Offering[],
276276
) {
277277
console.log(toInsertList);
278278
return toInsertList.every((x) => canInsert(x, curList));
@@ -292,12 +292,12 @@ export function getFrequencyTable(arr: Offering[]): Map<string, number> {
292292
// Function to generate all valid schedules based on offerings and restrictions
293293

294294
export async function getValidSchedules(
295-
validSchedules: Offering[][],
296-
courseOfferingsList: CategorizedOfferingList[],
297-
curList: Offering[],
298-
cur: number,
299-
len: number,
300-
maxdays: number,
295+
validSchedules: Offering[][],
296+
courseOfferingsList: CategorizedOfferingList[],
297+
curList: Offering[],
298+
cur: number,
299+
len: number,
300+
maxdays: number,
301301
) {
302302
// Base case: if all courses have been considered
303303
if (cur == len) {
@@ -306,7 +306,7 @@ export async function getValidSchedules(
306306
// If the number of unique days is within the allowed limit, add the current
307307
// schedule to the list
308308
if (freq.size <= maxdays) {
309-
validSchedules.push([...curList]); // Push a copy of the current list
309+
validSchedules.push([...curList]); // Push a copy of the current list
310310
}
311311
return;
312312
}
@@ -315,20 +315,20 @@ export async function getValidSchedules(
315315

316316
// Recursively attempt to add offerings for the current course
317317
for (const [groupKey, offerings] of Object.entries(
318-
offeringsForCourse.offerings,
319-
)) {
318+
offeringsForCourse.offerings,
319+
)) {
320320
if (await canInsertList(offerings, curList)) {
321321
const count = offerings.length;
322-
curList.push(...offerings); // Add offering to the current list
322+
curList.push(...offerings); // Add offering to the current list
323323

324324
// Recursively generate schedules for the next course
325325
await getValidSchedules(
326-
validSchedules,
327-
courseOfferingsList,
328-
curList,
329-
cur + 1,
330-
len,
331-
maxdays,
326+
validSchedules,
327+
courseOfferingsList,
328+
curList,
329+
cur + 1,
330+
len,
331+
maxdays,
332332
);
333333

334334
// Backtrack: remove the last offering if no valid schedule was found
@@ -345,7 +345,7 @@ export function trim(schedules: Offering[][]) {
345345

346346
const uniqueNumbers = new Set<number>();
347347
while (uniqueNumbers.size < 10) {
348-
uniqueNumbers.add(Math.floor(Math.random() * (num)));
348+
uniqueNumbers.add(Math.floor(Math.random() * num));
349349
}
350350
// console.log(uniqueNumbers);
351351
const trim_schedule: Offering[][] = [];
@@ -359,62 +359,66 @@ export default {
359359
generateTimetable: asyncHandler(async (req: Request, res: Response) => {
360360
try {
361361
// Extract event details and course information from the request
362-
const {name, date, semester, search, courses, restrictions} = req.body;
362+
const { name, date, semester, search, courses, restrictions } = req.body;
363363
const courseOfferingsList: OfferingList[] = [];
364364
const validCourseOfferingsList: GroupedOfferingList[] = [];
365365
const maxdays = await getMaxDays(restrictions);
366366
const validSchedules: Offering[][] = [];
367367
// Fetch offerings for each course
368368
for (const course of courses) {
369-
const {id} = course;
369+
const { id } = course;
370370
courseOfferingsList.push({
371371
course_id: id,
372372
offerings: (await getOfferings(id, semester)) ?? [],
373373
});
374374
}
375375

376376
const groupedOfferingsList: GroupedOfferingList[] =
377-
await groupOfferings(courseOfferingsList);
377+
await groupOfferings(courseOfferingsList);
378378

379379
// console.log(JSON.stringify(groupedOfferingsList, null, 2));
380380

381381
// Filter out invalid offerings based on the restrictions
382-
for (const {course_id, groups} of groupedOfferingsList) {
382+
for (const { course_id, groups } of groupedOfferingsList) {
383383
validCourseOfferingsList.push({
384384
course_id: course_id,
385385
groups: await getValidOfferings(groups, restrictions),
386386
});
387387
}
388388

389389
const categorizedOfferings = await categorizeValidOfferings(
390-
validCourseOfferingsList,
390+
validCourseOfferingsList,
391391
);
392392

393393
// console.log(typeof categorizedOfferings);
394394
// console.log(JSON.stringify(categorizedOfferings, null, 2));
395395

396396
// Generate valid schedules for the given courses and restrictions
397397
await getValidSchedules(
398-
validSchedules,
399-
categorizedOfferings,
400-
[],
401-
0,
402-
categorizedOfferings.length,
403-
maxdays,
398+
validSchedules,
399+
categorizedOfferings,
400+
[],
401+
0,
402+
categorizedOfferings.length,
403+
maxdays,
404404
);
405405

406406
// Return error if no valid schedules are found
407407
if (validSchedules.length === 0) {
408-
return res.status(404).json({error: 'No valid schedules found.'});
408+
return res.status(404).json({ error: "No valid schedules found." });
409409
}
410410
// Return the valid schedules
411-
return res.status(200).json(
412-
{amount: validSchedules.length, schedules: trim(validSchedules)});
411+
return res
412+
.status(200)
413+
.json({
414+
amount: validSchedules.length,
415+
schedules: trim(validSchedules),
416+
});
413417
} catch (error) {
414418
// Catch any error and return the error message
415419
const errorMessage =
416-
error instanceof Error ? error.message : 'An unknown error occurred';
417-
return res.status(500).send({error: errorMessage});
420+
error instanceof Error ? error.message : "An unknown error occurred";
421+
return res.status(500).send({ error: errorMessage });
418422
}
419423
}),
420424
};

0 commit comments

Comments
 (0)