Bojangles was a class timetabler I made in 2014 while studying at UNSW. I maintained bojangles until mid 2018, however it is now retired as I have graduated and the uni substantially changed class scheduling when it moved to Trimesters in 2019. If you’re looking for a timetabler Crossangles is an up-to-date replacement.
This was the #1 question I was asked by other students. UNSW has had a number of unofficial timetablers over time, first starting with rectangles and then octangles. I should mention there was also a satirical timetabler called circles which was a fork of octangles with the only change being it used circles instead of rectangles to represent classes. I wanted to keep to the general -angles theme and a friend in highschool used to say bojangles a lot and so bojangles was born. I’m glad that the next in line (Crossangles) has kept to this theme.
The earlier timetablers worked by generating a sorted list of example timetables which you could look through but could not interact with. The downside of this approach is that you cannot easily explore changing classes around and if there were many options for class times you would only see a small subset of the thousands of possibilities. This frustrated me and was the main reason I decided to make a new timetabler.
With that in mind the main features I aimed for were:
In the end Bojangles drag and drop capabilities worked so that you could click on a class and all the possible locations it could be moved to would be highlighted. Then you could drag the class around and drop it into new places which let you iterate on new timetables quickly.
For bojangles I opted to generate timetables on the client while the earlier timetablers had gone for server side generation. This was chosen so that hosting would only be static files that would cache well and very low server CPU load to keep things cheap. These days it could easily be hosted from free providers like github pages and netlify.
To generate the actual timetables I used a recursive backtracking algorithm but originally this was just planned to be a quick proof of concept. I had ultimately intended to use a genetic algorithm, however in practice the recursive backtracker was relatively fast so I decided to stick with it. At UNSW you are allowed to have classes overlap up to a certain number of hours, so the algorithm would backtrack when the overlap hours were exceeded. To get the backtracker to perform well I did some research on how the JS JIT compiler in chrome worked and how to optimise for it, this resulted in some ugly code with a lot of nested, fixed sized lists of ints but it did perform well even on mobile platforms. The minimum spec platform I aimed for was an iPad 2 and on this platform the backtracking algorithm could generate about 1K timetables per second.
Bojangles had a slightly more flexible timetable generation system than the earlier timetablers. Like earlier timetablers you could choose to optimise for:
However you could also rank your preferences in this list, for example ‘least days at uni’ and ‘later wakeup time’ would first rank timetables by least days at uni, then rank by latest wakeup time within this.
One area where bojangles didn’t do so well was that it didn’t separate academic weeks which could (but rarely did) have different class times. Instead bojangles opted to flatten the weeks together for easier timetable generation and a simpler UI. This was a good assumption at the time, however it is the main area where bojangles fell down with the switch to trimesters as courses were frequently scheduled quite differently in alternating weeks, leading to many overlapping classes.
Bojangles used fabric.js to provide interactivity using a HTML5 canvas. When Bojangles was released fabric.js did not have good support for high DPI displays. At the time I had just upgraded to a new Retina Macbook Pro so was keen to make sure rendering was pretty. In the end I had to tweak the library to get it working well but this ended up being well worth the time as the high DPI trend took off.
Class data was mostly scraped from classutil using a python script. Unfortunately at the end of the year classutil was slow to roll over to the new academic year, so a scraper using timetable.unsw.edu.au had to be maintained too. This was inconvenient as timetable.unsw.edu.au only updates once a day and has a different page per subject, compared to classutil updating 4 times a day and having one page per faculty. Writing the timetable.unsw.edu.au did succeed in stopping a lot of complaint emails though.
Overall this was an interesting project to work on and it got a lot of positive feedback over the years from other students. Looking back I’m surprised it worked as well as it did for a few years it was up, but I’m glad I don’t have to worry about receiving bug reports anymore.