Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

...

Now, not only is there feedback that the email has been sent successfully, but the system also tracks when was the last time a student was emailed. This is the reason why we added the user accounts mentioned above.

Implementation

Groupings -> JS class that represents ANDs and ORs in code.  Will automatically flatten to the smallest component.

Terminator -> Takes in a valid output from Parser and converts it to Groupings

Parser -> Takes in any string and gives back a list of possible options (for and/or and parenthesis) where ambiguity might occur

objectFilter -> Takes in a grouping and list of JS objects and will filter those objects based off the grouping

Set.js -> Modified implementation of a Set class in JS

File: Data.js -> Loads the data from the backend, including courses and skills

State -> A global variable that maintains application state.  Used to update "Start New Search" button and track other things

Front end code logic:

1) When you enter a term into courses/skills, it will attempt to autocomplete based off the loaded file from data.js

2) When clicking "add," it takes your entry and sends it to parser.  It then truncates that list to 16 "best" items.

3) This list is fed back to the UI code.  If there's only one item, it runs with it.  Otherwise, it shows the "We're confused" dialog.

4) After resolving any confusion, it adds this new grouping as an AND block the the global Course or Skills search item.

5) Since this should change search results, it calls Grouping.toString() and sends this new query to the backend, attempting to filter data.

6) Clicking a student will add them to the Selected state property.  Hiding a student will add them to the Hidden state property.

7) Adjusting a filter updates the State property and triggers a new search again.

8) Current page is a state property.

9) Entered subject/message for e-mail are state properties.

Frontend Implementation

The front end is a combination of HTML, CSS, and JavaScript. (Data is loaded via JSON; more on that later.)

We use a variety of libraries for many reasons:

  • jQuery (JS) - We used jQuery to make our life easier.  Its selectors, event handling, and AJAX support helps simplify the amount of code necessary to implement features.  It also helped greatly with cross-browser implementations.
  • jQuery UI (JS, CSS) - We used jQuery UI primarily for its autocomplete feature.  It was robust enough to offer us the inline tweaking support we wanted for the tagging system.
  • Underscore.js (JS) - Underscore.js is a collections manipulation library.  We used this to simplify what we needed to write since JS's built in collections support is fairly weak and inconsistent cross-browser at times.
  • Bootstrap (CSS) - We used Bootstrap all over the place.  The CSS component was used to generate styles for our website, helping us produce a professional and clean layout.  This layout also has responsive features, provided by Bootstrap.
  • Bootstrap (JS) - Bootstrap's JS library was also used.  Its primary usage was the alerts (notifications shown at the top of the page when you hide a student/send an email), tabs (seen in the Full Student Profile page), tooltips (in the Full Student Profile page when hovering over class numbers), popovers (used for the e-mail timestamp), and the dropdown (used for the options menu.)  If we did this again, Modals would also be reimplemented with Bootstrap.

Backend Implementation

The backend was implemented both in the browser (pagination, hidden students, filters) with JavaScript and also in the server (filtering, loading the data, tracking emailed students) with Python.  The Parser that converts generic input into potential AND/OR groupings is written in JavaScript.  The Terminator which converts a Parser output into a Grouping (the boolean representation of the query) was originally written in JavaScript for GR4 but was also ported to Python for GR5. (Both are used in the final implementation.)  The Grouping class is also both JavaScript and Python.  ObjectFilter, which was originally JavaScript (GR4), was converted to Python for GR5.  It takings a Grouping and filters out the students.

The backend server was implemented using Flask.  We chose Flask because of Sarah and Chris's familiarity with it.  Python was the language chosen because the whole team was familiar with it.

The login system is implemented entirely in the backend.  We store only three pieces of information: e-mails (usernames), sha256 hashes of passwords, and a list of all emailed students for that user.  Password hashing is done via Python's hashlib.

Compiling the Templates File

We wrote a custom build scripts (bin/compile.py) that would take our templates (.html files), dump them as a JSON object (so, just a string), and then write this JSON object to a file.  This let us access our templates in JS.  It was only necessary to recompile after editing the templates.

Content

The images that we used for the student cards are images that we took off of Google. The data that we used for the students was a combination of fake data and modified real data. We sent out a survey to students at MIT to gather data, reasoning that it would be the simplest way to gather a good variety of classes and skills. The data we received in return was manually organized and formatted into a database of students, skills, and classes. Though the data is added to the database with a Python script, they are stored as JSON objects and are later accessed by javascript functions.

When collecting the data, we wrote a collection form in PHP.  This form wrote to a SQL database.  Then, our dumper.php script read the database and translated it to a form that our Python backend would read.  We then manually transferred this data and corrected any inconsistencies and typos.

Collection form: http://sz-ex.com/chris/813/

Data dumper: http://sz-ex.com/chris/813/dumper.php

Challenges

By far the most difficult thing to implement was the handling of the user boolean input for Courses and Skills. We had to rework the parser and grouping code several times before we reached a balance of utility and learnability. One feature we had to entirely remove from grouping was the ability to nest "AND clauses" within "OR clauses" (e.g. (6.831 OR (6.813 AND 6.005)) AND 6.01). This quickly became very confusing, and exponentially increased the number of options that would be shown to the user in the "We're Confused" dialogue used to clarify ambiguous groupings. We decided that this was an unnecessary implementation given the other capabilities of our interface, and chose to drop it in favor of maintaining simple learnability and usability. Not sure what else Tanya wants.

Evaluation

Our target user population is professors, administrators and project leads who need to fill positions with qualified and fitting MIT students. We tried to select our users to have different backgrounds. User 1 is an administrator who looks for a variety of students, from all different majors depending on the temporary position she’s looking to fill. User 2 is a MIT professor who works with Media Lab and the Department of Urban Studies and Planning and generally looks for Course 6 students. User 3 is a project lead who works to search for engineering students to fit the program she oversees, generally Course 2 and 6.

...

Solution: Consider either using “Classes” or “Subjects” or both.

Reflection

The iterative design process was definitely a learning process for our group. It was interesting to see the feedback that we would get after each stage, and useful to incorporate the feedback into the next iteration of our interface.

Design stage

One of the best things that we did during the design stage was to come together with many different ideas for an interface. Something we could have done better, however, was to keep the many initial designs of the individual group members in mind. After picking the initial elements from each design that we liked, we, as a whole, forgot about the rest of the ideas. There was a point in the final stage of developing the final prototype where all of us were not satisfied with a particular portion of our interface. In a fit of inspiration, however, we decided on an element we had turned down in the very beginnings of design, tabbed organization. Had we kept all of the ideas we had during the initial design stage, it is possible that we would have been able to solve our issues much earlier than we had.

Prototyping and user testing

The different stages of prototyping were very helpful in providing us with feedback. The initial paper prototype helped us fix issues with layout and confusing wording before coding even began. We were able to simply scrap parts of the paper prototype and quickly fix glaring issues between testers, if absolutely necessary. 

The computer prototyping enabled us to actually witness our features in real time, and made it much easier for us to see the reactions of users to a particular functionality. This was most helpful in demonstrating what parts of the prototype made no sense logically. Thus, we were able to focus a lot of our time in making the "AND" and "OR" logic fully understandable and easily learnable to users, rather than continuing with what we thought made sense.

One of the most interesting things that our team learned was the drastic difference in the way users and developers thought. Logic and actions that made sense to us often completely baffled the user in ways that we had never guessed. There were many times where testers pointed out things that, after brought to our attention, seemed painfully obvious. At the time of development, however, we had been convinced that our method had no issues.