Making myBYUclasses.com

All-In-One Course Scheduling Solution for BYU Students

Posted on February 23, 2016 in education, webdev

What is it?

myBYUclasses.com alleviates the pains of planning and registering for BYU classes.

This project has taken around 3 months to complete. I have been spending my free time and early mornings working on this, often shirking my calculus homework. I'm happy with the results. While there is still a lot to be done, I believe there is enough functionality for this site to be useful for other students.

Table of Contents

The Pain
How to Ease the Pain
Solution
Getting All the Data
Storing the Data
Auto-Scheduling
Design
Evolution of Ideas
Lessons Learned
Prospects

The Pain

Right now, BYU's service for class registration isn't exactly user-friendly. In order to learn about and sign up for a specific course, you have to click around a lot, and you have to visit multiple sites. Available course sections are listed in huge tables, making it tedious to find the section you want.

Even once you find a section that is available, you need to open up two or more windows: one for learning about the course, another for seeing their current schedule, another for learning about your teacher, and so forth.

Most students want to make sure they get a good teacher. So they go to RateMyProfessors.com and search for the teacher of the section they are considering. That adds another browser window to the process.

Sometimes when I'm planning my schedule, my screen looks like this:

Most BYU students that I know plan to spend 4 hours or more on this whole process. After all, they are deciding how they will spend every single day of their semester. Your schedule has a big impact on your education.

I was tired of going through this process every semester. I knew there had to be a better way.

How to Ease the Pain

Here are the things I wanted a website to do for me:

  1. Gather all the info I need to make an educated decision about:
    • the courses I should take
    • the teachers I should choose
  2. Show me my schedule in a calendar view and show me my schedule as I am adding a course to it so I can see immediately whether it works.
  3. Let me read and create student reviews for my courses.
  4. After I set some parameters, give me a schedule that meets those parameters.
    • Example: "Give me the best teachers" and "I don't want any classes before 9am."

Solution

I went through a lot of different layouts. I tried to identify the general flow of a student's planning session to make the best design. I asked all my friends to show me how they register for classes. I asked them to describe the ideal scheduling tool. Then I showed them what I came up with and asked for feedback.

After a lot of experimenting, I resolved to keep it as basic as I could.

There are two different ways to arrive at the optimal schedule:

One way (The "Auto-Scheduler" flow):

  1. Choose your classes as the site guides you through your program's requirements
  2. Then choose more classes by browsing subject areas, teachers, or by searching for them
  3. Pick your parameters, apply filters, and click "Find my schedule"

Another way (The "Let me do it" flow):

  1. Browse for courses and view their sections in the interactive schedule
  2. Click on them to add them to your schedule

So, when you log in you can choose to be guided through your program's requirements or you can start searching for courses. (Shown below)

The "Guided" Flow

If you click "Choose Based on Requirements", you'll be prompted to choose from a list of the school programs and degrees.

Once you choose a program, you see more info about it, along with a list of courses to choose from. You can see my attempt to consolidate data in this screen.

Then you'll see more general university requirements:

Finally, you'll see a review of the courses you have chosen, and you can set some parameters for the auto-scheduler:

If you still want to add more courses, you can. Just search for them using the search bar at the top of the page. Once you find the one you want, you just have to click the plus next to its name.

Once you have decided on all the courses that you want, then click the button and let it load for awhile. You'll then see your schedule.

In this case, I got an error:

It is spring semester, so there are less sections available. It's impossible for me to take all these classes at the same time. In future versions, I am going to allow the user to specify "backup classes" in case they can't get their first choices. I will also show multiple possible schedules, instead of just one.

The "Let me do it myself" Flow

If you don't want your schedule created automatically, you can add course sections manually. Just start browsing subject areas, teachers, or searching for courses. When you find a course you want, you'll see this layout of the course's sections and details...

Course View

You just click on the section you want and click 'Save' to put it on your schedule. You can hover over sections to see more info about them, including the teacher's rating.

If you want to see more info about the course, reviews from other students, or the current teachers, you can click the tabs under the course name.

Follow this process for all of the courses you want to take, and then click "My Schedule" in the navigation bar to see all of them in the same place!

Getting All the Data

Since BYU didn't have an student-accessible API from which I could fetch course data, I resolved to use curl and the PHP Simple DOM Parser to get all the data I wanted. This was perhaps the most laborious task of the whole project.

First, I tried to pull in some basic public data about BYU's course offerings. I opened up Chrome's dev tools to see what requests my browser made to get the data I wanted. Then I emulated the request using curl. I was pretty excited; it was easy to get any data from any webpage! Or so I thought...

I didn't have any experience with curl or web scraping, so I had to do a lot of digging to come up with a solution for this next part. The course registrar, which holds all important information about a course's sections, times, teachers, location, and more, requires you to log in.

I won't go into too much detail about how I did this, but I banged my head against the keyboard until I found out that I could use cookies to take my browser session and give it curl. Curl has a "cookie jar" option (awesome name) that lets you import, read, write, and export cookies. So, to access the registrar data, I exported my cookie from my browser, referenced the file in my curl request, and it worked! I was able to pull down any info I wanted with the DOM Parser and curl.

Storing the Data

BYU

Now that I could pull in data about departments, subject areas, teachers, courses, sections, and more, I had to figure out how to store it efficiently to use in my application.

Thankfully, Laravel's Eloquent makes reasoning about data persistence easy. You can use simple phrases like $subjectArea->hasMany('Course') and $course->belongsTo('SubjectArea') to establish relationships. All you need to do to save a course to a subject area, for example, is $newSubjectArea->courses()->save($newCourse). This saved me SO much time.

RateMyProfesors.com

Pulling data from RateMyProfessors.com just took one query. I used my other scraping scripts as a template for this process. And since I had all my Eloquent models set up, all I had to do to store the ratings was add them as an attribute to the Teacher model. ($newTeacher->rating = $value)

Perhaps the most fun part of this project was combining various data sources to create a whole with more value than the sum of its parts. In particular, I got excited about seeing RateMyProfessors ratings together with all the other data I had collected. Normally, students have to make separate searches to find teacher ratings. The way it is set up now lets students see teacher reviews right of the bat. Wherever you see a teacher's name, you see their rating too.

Auto-Scheduling

I lied earlier when I said that scraping the course data was the hardest part of this project. The scheduling algorithm was definitely the hardest part. It's still not great, but it works.

The goal is to give the student the best teachers possible for each course that he/she is taking. So this is how I prioritize by best teacher. The $teachers collection is sorted from best rating to worst rating in the first line.

$teachers = $currentCourse->teachers()->get('desc', 'rating') ;

foreach ( $teachers as $teacher )
{
    foreach ( $teacher->courseSections as $section)
    {
        if ( meetsCriteria($section) && fitsInSchedule($section) )
        {
            $addToSchedule($section);
        }
    }
}

If the sections of the teacher being considered don't fit on the students schedule, then it moves on to the next teacher. Even though they didn't get the best teacher possible, we still want to find a way to get the course onto their schedule.

As you can guess, going through the list of desired courses once doesn't always work. There are almost always an overlap between the first sections that the program finds.

Let's say that I just went through a list of these three courses in the order that they appear:

  1. Music Theory
  2. History
  3. Calculus

Music Theory has 3 available sections, History has 2 and Calculus has just 1.

So if I add them in the order they appear, the program will add the first section available for Music Theory and move on. It starts to look at the available History sections. The first one overlaps with Music Theory so it adds the second one. Now it considers Calculus, which only has one section. Unfortunately, that section overlaps with Music Theory, so it is not added.

If a human were to look at this, he would add the Calculus section first because there is only one section available. But the program doesn't know that. If the program were to add the courses in the order 3,2,1 then it would have added all three courses to the schedule.

So how do we tell it to do that?

I used a function that, given an array of numbers, returns a collection of all the possible orderings of those numbers. For example, if I pass it [ 1, 2, 3 ] it will return [ 1, 2, 3 ] [ 1, 3, 2 ] [ 2, 1, 3 ] [ 2, 3, 1 ] [ 3, 2, 1 ] [ 3, 1, 2 ]

Those numbers correspond to courses. I pass that that array into the "schedule analyzer" and it tries add the courses in every order it is given until it succeeds in adding all of the courses. If it can't add all the courses with any of the combinations, then it gives you a schedule with the least number of courses missing.

This puts a lot of stress on the server, especially when there are more than 6 courses to consider. I am also struggling to find the best way to run this analysis without the server timing out. This is the biggest hindrance I have right now. I have limited the auto-scheduler to 4 courses until I can find a better solution.

I know there has to be a better way to do this, but this is what I've decided to do for now. Email me if you have a better solution!

Design

I learned the hard way that you should let your ideas grow for awhile before you start thinking about how the site will look. I think I shut off my brain's idea generator when I started to style my site (way before it was finished). While it did give me some motivation (I thought it looked pretty good), I ended up changing almost everything I started with. I started with a bare bones bootstrap layout, then later I decided to convert everything into semantic ui.

Evolution of Ideas

My favorite part of any project is watching it evolve on its own. Initially, I thought this site would be solely for reading and creating course reviews. Then, as I shared the idea with other people, they gave me new ideas. Each of those ideas had something great about them.

One of my coworkers told me that I could give users profiles, let them interact, and send them updates about course information and reviews. I had never thought of that. He then helped me realize that I could automatically schedule classes for users if I wanted to. I hadn't even thought of making an auto-scheduler.

After the fact, all of these ideas seem like they'd be obvious inclusions, but they just weren't obvious to me. I didn't realize the full potential of this site until I started building it and letting the ideas grow and interact with each other. Getting your hands dirty is the best way to start coming up with ideas.

Lessons Learned

  • Write about your project along the way, not just at the very end.
  • Take snapshots often, so you can see the evolution of your ideas.
  • Take more time planning the foundation. (like the database relationships and backend flow)
  • Even though your best ideas won't come until later, take time to imagine how big your project can get. Try to think of all the cool things it could do one day. Then build your foundation to support that dream.

Prospects

I'm positive that if this works as expected, many students will enjoy it and save time planning their semester. This would be very useful for other colleges. If I could, I would spend every day working on this, making it even better.

Over the next few months and into the summer, I plan on adding these features:

  • Let the user store backup courses
  • Let the user see multiple possible schedules
  • Let the user establish priority between their courses
  • Make the scheduling algorithm quicker and less "brute"
  • Let users see which classes their friends are taking (using Facebook)
  • Make the site useful for professors, helping them find potential teaching assistants
  • Let students register themselves as "tutors" and engage in useful discussion surrounding courses

There is so much that needs to be changed about how we are taught in school. Until I know more so that I can do more to change education, the least I can do is make it a little more bearable.

Eventually, I hope that this site (or another like it) will not only make scheduling easier, but bring students together to collaborate, to help each other with their struggles, and to make their education better.


comments powered by Disqus