As part of my work with Science Olympiad, I worked on making CodeBusters become a national event for the 2018/2019 season.  While one part of the process was to define the rules, the real challenge was making it easy for all of the individual states event supervisors to be able to run the event easily.  

In the previous two years of being the event supervisor for North Carolina, I wrote almost two dozen tests by hand using Microsoft Word.  In the process we analyzed the testing results and formats as well as elicited feedback from event supervisors who administered the tests.  Based on the feedback, I tweaked the test format to make it easier to grade by putting boxes around answer spots using tables as well as standardized the format for presenting the questions so that students could clearly recognize how to approach the problems.  However the process was still manual and generating the answer key was a tedious effort to ensure that everything was in sync, especially when the test question order was randomized, and yes I did make a couple of mistakes that we caught at the last minute.  Additionally, while there was somewhat of a template to follow, the process was tedious such that it could take several hours to prepare a test with only eight questions, ensuring that everything was correct.

From this experience, it became obvious that automation was required.  In order to make it accessible, I needed to build a web application. 

Laying out the basic requirements:

  1. Truly WYSIWYG web pages so that as the user updates the data, the test question is dynamically updated.
  2. Responsive so that the test could be accessible from a desktop, tablet or mobile phone that students use.
  3. Ability to generate questions using various cipher types (Aristocrat, Vigenère, Hill, Caesar, etc.).
  4. Customizing question text and score values for each cipher type.
  5. Organizing questions into tests.
  6. Ability to customize test, reorder questions.
  7. Ability to print the test, answer keys and solutions.
  8. Secure so that there was no chance of test being leaked or accessed by a student.
  9. Ability to run the entire site offline for people who had limited internet access (or wanted to create tests while traveling).

Technology Choices

In looking at the technology available, I had to make choices in four areas

Frontend Framework

I probably spent the most time here going back and forth on the various options.  While there are literally dozens of CSS frameworks to choose from, the obvious front runners are BootstrapFoundation, and Semantic UI.  You can find plenty of articles comparing them (such as the codeburst.io article and stackshare.io summary chart) and I would encourage you to do your own research before making a decision.  In my case it came down to mobile support and I found that while Bootstrap certainly has the market share by farFoundation felt like it had started from a more modern base while Bootstrap was catching up to the modern browsers.  Additionally, I found that sites built using Bootstrap all tended to look the same while Foundation seemed to have a more flexible user interface.  Given that what I was building didn't look like any of the other sites I have seen, ultimately Foundation seemed to offer the flexibility I needed. When I started, Foundation was working on the version 6 release and I had to deal with a few of the bleeding edge bugs which they ultimately fixed. 

 

Controller Framework

This is where the project really diverged.  As part of my work at Escape Velocity, we build our application using Angular and I was initially tempted to continue along those lines.  I'm a big fan of Typescript and liked how the Angular framework worked.  Of course you can't ignore the fact that React is the big powerhouse in terms of usage (there's a good article at TechMagic showing trends), but both of them seemed to not quite match where I was going.  I looked at several implementations of Undo/Redo (for example the React Tic Tac Toe Tutorial) and didn't feel that it gave me the flexibility that was going to be needed for the encoders.  Ultimately I ended up rolling my own controller framework and I'm happy with how it worked out.  Each encoder has its own web page with infrastructure to do dynamic page updates and the Undo/Redo code ended up also working with the Save/Load and even URI parameter parsing.

Backend Framework

It is very important to be able to download the entire tool as a bundle.  For this reason the web pages had to be plain HTML which could be launched by any browser locally.  Additionally, because many of the users who download the tool were not technically savvy, there should be no local install of other software required.  I.e. they should be able to put a directory on their machine and double click on the index.html file to be able to do the work with the tool.  This immediately eliminated many of the Backend frameworks (Django and  Flask need Python, Ruby on Rails needs Ruby and so on).  For this reason, any backend framework needed to be compiled down to simple HTML pages.

Storage Framework

Here is where there can be a lot of fun.  The test has a LOT of diverse but small data associated with it.  A typical test may have twenty questions.  The most obvious way to store the data is to use a REST interface with a server which stores it into a database.  Along with this comes a host (pardon the pun) of challenges - security, user ids, passwords, SQL injection problems.  In this case, the size of the data is actually quite small — a typical test is only 14K — which presented a very nice opportunity: Simply store all of the data locally on the user's machine.  In this way, nothing is ever sent to a server and all of the other security concerns generally go away.  For this, a solution of using LocalStorage when available and Cookies when not available turns out to meet all of the application needs.

Architecture of the Application

The entire application is at https://github.com/toebes/ciphers for anyone to see.  The application is built on top of several well known open source components.

WebPack

When building a web application, it is important to have a reliable way of consistently constructing the application.  You could start with Make or even Grunt/Gulp but ultimately when creating something for the web it is important to optimize out the pieces which aren't needed and shrink down the code to the minimum size.  For this you will need a transpiler such as Typescript and Babel.  There is a good article on the various options at SurviveJS.  Currently the best choice which combines everything into a single package is WebPack.  However, you should be warned that creating a configuration file for Webpack seems quite a bit like black magic.  If you look around at various projects which use WebPack and compare their configuration files you will find that they greatly vary (to put it mildly).  Once you figure out that the configuration file is really a javascript file to invoke packages and provide configuration for which transformation to run on which type of file, it becomes a bit easier to understand.  In the case of the CodeBusters tool, the configuration file needs to: (Note you can click on the description to jump the specific spot in the webpack file).

Foundation