Introducing cuScheduling
cuScheduling allows students to build their schedule for the next term in seconds not hours.
Hello! (this is my first ever blog post!11!)
My cuScheduling is extremely inspired by the original and now defunct cuScheduling by Tobias Schlagenhaufer. Tobias is a Carleton alum who so kindly gave me permission to use his original project’s name!
A few months ago I’d been working on a fun little side-project called cuScheduling that I’ve now finally got around to shipping. Essentially, it’s a tool that lets you query courses offered over various terms and automatically build a schedule based on which courses you select.
The Original Problem
Currently, to build schedules, Carleton students have to use Carleton Central (CC) which is notorious for it’s awful UI and UX. The main problem with using CC to schedule your courses is the pain of dealing with course conflicts. Every Carleton student has had an experience similar to this before:
-
Pick the courses you want to take.
-
Find out that registration is closed.
-
Replace that with another course.
-
Find out that your courses overlap on your schedule.
-
Replace one of the conflicting courses.
-
Go back to either steps 2 or 4 until you get lucky.
-
Register!
This is pretty awful and frustrating for students who just want to pick their courses. Instead of being able to focus on the fun part, actually choosing what you want to study this term, you have to focus a lot more on whether courses are open or if they conflict. This sucks! Especially knowing that Carleton Central has enough data to take care of this problem for you.
cuScheduling’s Solution
This is the experience you’ll find in cuScheduling:
-
Pick the courses you want to take
-
Register!
Ah, much better! cuScheduling takes care of the annoying conflicts and closed registration problems for you. All you have to worry about as a user is if a course sounds interesting to you.
How it was made
Backend
I made the backend for cuScheduling (cuapi) using Django, Celery and PostgreSQL. The implementation is super simple and only acts as a database so that any client can query for courses at Carleton University.
We store only 3 essential tables.
-
CourseDetails
-
Stores information for a given class such as:
-
Instructor
-
Name
-
Registration Status
-
Time
-
-
Example: “COMP 1405 A2”
-
-
CourseSection
-
Represents all the CourseDetails for given section
-
Example: COMP 1405 A
-
-
Offering
-
Represents all the CourseSections for a given Course
-
Example: COMP 1405
-
This arrangement allows us to query for offerings and then build schedules from each of the sections and timetables from each of the classes in each section.
Other than querying for courses, there isn’t any other logic going on in the backend. No auth, no way to upload data. Just a simple endpoint to query courses.
Automated Scraping
I used celery, requests and bs4 to scrape the courses from Carleton University’s website. Every 6 hours a large scraping job is triggered to first get the available terms then subjects and finally the CRNs of all the courses offered.
By using chaining and grouping in celery this can be done effectively by parallelizing the scraping workload as much as possible.
UI
The UI is a really simple React app with a not-so-fancy Calendar component that displays the current timetable you have selected. However, the real fun in the UI comes from the Genetic Algorithm that powers the scheduling system.
Genetic Algorithm
There are many different algorithms that can be used to build schedules, one of which is a Genetic Algorithms. Genetic Algorithms are great for problems like scheduling because:
-
We can easily quantify the fitness of a schedule (How good a schedule is)
-
There is a large problem spaces (i.e. lots of possible schedules)
Schedule Fitness
For deeming the fitness of a schedule, we calculate two traits.
-
Number of conflicting classes
-
Total minutes spent in-between classes The final fitness function ends up looking something like this (pseudocode)
function fitness(schedule):
int score = 0
score -= 10000 * calculate_number_of_conflicts(schedule)
score -= minutes_spent_in_between_classes(schedule)
This allows us to heavily penalize schedules that have any conflicts and quickly remove them from the population. We also slightly penalize schedules that have a lot of time spent in between classes which will cause the GA to explore schedules that are more compact and better for the user (i.e. less time spent at school!)
The most fun part about a fitness function is the freedom it gives us when deciding what makes a schedule “good.” We can add to the fitness function however we’d like! For example:
score += -1000 * count_classes_on_monday(schedule)
We can severely penalize schedules that have Monday classes and this will be reflected in our genetic algorithm, leaving us with the “best” schedules (that have as few classes on monday as possible).
What’s next for cuScheduling…
I’ve had a lot of fun building cuScheduling and there’s some stuff I’d like to add to it someday…
-
Fully automated scheduling
- Users can input their previous credits, their grade and the degree they’re working on and we build them a full plan on how to meet their degree requirements at various paces
-
Schedule sharing
-
This wouldn’t be hard to implement and its a nice feature to have for ‘virality.’
-
Let people share either a link or a pretty screenshot of the schedule they made in cuScheduling.
-
-
Interesting data
-
The scraper gives us all the data we need!
-
Wouldn’t it be cool to know how many classes are happening on campus at a given time?
-
or how many courses Pat Morin is currently teaching?
-
or…
-
-
It would be cool to have a page full of these.
-
-
A full platform for course reviews (akin to Rate My Professor)
-
This would be a bit overkill for my little scheduling app, but some folks at Laurier did it and it seems pretty awesome
-
This would also give us some extra criteria to build schedules on (i.e. prof ratings)
-
-
You
- You might be a bored first year looking for something to do. If so, give contributing to cuScheduling a go! It’s all open source. Take a look at it, fork it, and try adding something!
cu later
Building cuScheduling has been fun and rewarding for me. It solves a real problem for Carleton students, making the course selection process much easier and more enjoyable. I’m excited to continue improving it and adding new features based on user feedback and my own ideas.
Thank you for taking the time to read about cuScheduling. I’m super excited to finally share it with everyone and I hope it becomes a useful tool for Carleton students. If you have any feedback, suggestions, or want to contribute, don’t hesitate to reach out.
Happy scheduling!
Nathan Coulas
Email: me@nathancoulas.com