Monthly Archives

June 2015

PhoneGap and Rails – Love at Second Site ;-)

By | Tech Blog | No Comments

The Request and Requirements

A few days ago, a friend of mine asked me to create a simple CRUDing app. He had two requirements: it had to work completely off-line and be compatible with an Android tablet. Now this posed a few problems, the main one being: I am not an Android developer.

As I think more about this request, I know I can make the app entirely using javascript and then PhoneGap to make it compatible with Android. However, there is one big problem when starting a javascript app from scratch: organization. As I continue thinking about this app, I list a few other thoughts, requirements, questions, and desires of my own:

  1. Structure benefits javascript code and Backbone.js could provide this.
  2. I have had enough of those darn curly braces – I could write this in CoffeeScript.
  3. All the data has to be stored on the client’s side – I think localStorage would work.
  4. Compiling all assets into one css and js file would be awesome.
  5. A nice touch of Bootstrap would make it look professional.
  6. Is there anyway I could use bourbon or sass to make my life easier?
  7. Testing is always important especially if the feature requests grow.

All these thoughts make me realize I have one robust solution: Rails!

Rails? Really? You may ask. Why? Isn’t that a large solution for such a small app? Especially, for a client-side application?! You may be right, but please, let’s give Rails a second look.

The Gems

Over that past few years, the rails community has embraced js frameworks such as Backbone.js, AngularJS, and Ember.js. The rails asset pipeline makes integrating these frameworks quite easy. With the backbone-on-rails gem, js code can be organized nicely into Collections, Models, Views, and Route directories. With a localStorage adapter for Backbone.js, Backbone.localStorage, Rails no longer needs a server. I can write in coffeescript with the coffee-rails gem – included by default when you build a new Rails app. I am able to write clean js code for free.

As for css, things couldn’t be any simpler. I am tired of writing in css without sass, and by including sass-rails as a default, rails programmers can say ‘goodbye’ to redundant css. While I am at it, I decide to take advantage of Bootstrap 3. I mean, this app needs to be on a tablet right? And it can look professional too. I include anjlab-bootstrap-rails in my gem file, and one rake command later – rake assets:precompile – I get two precompiled files: application.css and application.js.


I am not sure how apps can exists anymore without testing, but don’t ask the government. No matter how small, I always seem to avoid problems or find ones problems with my code when testing. Rails testing frameworks are robust but simple to set up. I decide that if I am going to test the javascript, I need to automate the browser.

In other projects I have found Selenium to be a great solution. With the rspec-rails, capybara, database_cleaner, launchy, selenium-webdriver, and shoulda-matchers gems, I get it all. I get matchers, a FireFox test driver, and even a way to inspect a page with one of my favorite gems: launchy. Below is an example test:

require 'spec_helper'
describe "CRUD ToDos", :js => true do
  describe 'Index' do
    it 'user can view a table of all todos' do
      visit '/'
      should_see_in "h1", "ToDos"
      with_scope ".btn-toolbar" do
        page.should have_link "New ToDo", :href => "#todos/new"
      with_scope "table#todos" do
        should_see "Title"

I also want faster test execution and to reduce the boot up time of my server, console or any other execution so I include the zeus or spork gems. It is a major time saver.

Minor Changes to Rails

Once I have my rails-backbone app up and running, I need to make a few adjustments in order to have my code work with PhoneGap.

Updating your application.html.erb file

This is what a Rails application.html file looks like upon creation:


I remove the ruby code and made sure my link and script tags point to the correct place:

I add a div with an id ‘main’ and use this for all the backbone pages.

Creating a Rake Task for PhoneGap

My last step is to create a rake task that creates all the files necessary for PhoneGap. Viola, I have file for easy code uploading.

require 'fileutils'
require 'zip/zip'
namespace :phonegap do
  task :build => [:environment, "assets:precompile"] do
    remove_dir("phonegap", true) if'phonegap')
    cp("./app/views/layouts/application.html.erb", 'phonegap')
    File.rename('phonegap/application.html.erb', 'phonegap/index.html' )
    cp("./public/assets/application.js", "phonegap/assets")
    cp("./public/assets/application.css", "phonegap/assets")
    cp("./public/assets/twitter/glyphicons-halflings-regular.eot", "phonegap/assets/twitter")
    cp("./public/assets/twitter/glyphicons-halflings-regular.svg", "phonegap/assets/twitter")
    cp("./public/assets/twitter/glyphicons-halflings-regular.ttf", "phonegap/assets/twitter")
    cp("./public/assets/twitter/glyphicons-halflings-regular.woff", "phonegap/assets/twitter")
    remove_file "" if File.exist?("")
    Dir["phonegap"].each do |file|
        `zip -r "#{file}.zip" "#{file}"`

Thank you so much for your time. Comments are appreciated.

Why Asynchronous != Concurrent: An Introduction to the Event Loop

By | Tech Blog | No Comments

The megahertz race in desktop CPUs petered out sometime in the middle of the 2000’s as Intel and AMD found it more difficult to keep increasing the clock speeds of their processors as they had done consistently for the fifteen years before. The competition shifted from who could pack the most MHz into their chips into one where the overall performance of a set of increasing processing cores became the competition.

In a multicore world, writing snappy code ceased being just about being picking the best algorithm with the smallest Big-O and began to rely on concurrent programming techniques that allowed programs to delegate their work to separate cores to process simultaneously. If I had two independent tasks that each took N seconds to complete, the program would run in 2N time in a single-core world, but only inN time in a dual core world. A process that could split its work into independent units could now run as quickly as the slowest component – not the overall sum of all of them. If programmed correctly.

For several years, mobile devices were content to run on single-core processors, but as chipsets caught up, multiple cores proliferated in handheld devices and we find ourselves reviewing specification sheets with phrases like “2.3 GHz quad-core Krait 400” (Nexus 5) and“1.4 GHZ ARMv8A dual-core CPU” (iPhone 5S). Core-mania has infected our pockets now as well.

The key to making the most of the processors on our mobile devices requires that we understand how our mobile apps run and what opportunities are available to offload work to other processors to ensure a snappy and responsive user experience. The key construct we must understand is called the event loop.

Event loops are basically structured in the following manner:

    // App initialization goes here
    dont_quit = true;
    while (dont_quit) // this is the event loop
        event = wait_for_event();
    // App cleanup and wrapup goes here

The program basically enters an endless loop where it waits for a stream of events to process. These events can be user interface interactions (a user clicked a button or typed text) or system-generated events like updating the state a progress indicator.

When we’re programming user interfaces, a term that pops up frequently is the main thread or the UI thread. A thread is a unit of execution that typically runs on a single processor. The UI thread is important in development because most GUI toolkits are not thread-safe, meaning that they are not designed to be used concurrently, so tasks like updating the label on a button must be executed on the main thread.

So, if we need to manipulate our user interfaces on the main thread, why worry about concurrent programming at all? The primary reason is that in the code above, one process(event) must complete before the next process(event) and HCI studies have experimentally shown that humans can start to perceive delays if something is taking more than 100 to 200 milliseconds. So, if one operation to update the user interface exceeds that 200ms threshold, the user will start to feel like your app is not responsive and a bit laggy.

So, once your app exceeds some basic level of functionality, you’re more likely to run into work that your app needs to do off of the main thread so that the responsiveness of your app isn’t compromised. A common pattern emerges within the code that processes the event:

    r = block()
        results = time_intensive_task();
        results += network_intensive_task();
        results += io_intensive_task();
        s = block()

Overall, this code is structured to keep the UI updates on the main thread, but offload as soon as possible any tasks that could take a significant amount of time to another thread that can run concurrently on another core. While these time intensive tasks are running, the main event loop is free to process other events. Once the time intensive tasks complete, the independent thread constructs a set of operations updating the user interface that are run on the main thread. The outcome of do_ui_updates(results) becomes just another event posted to the event loop.

So, what are some tasks that might be time intensive? In my own work, I’ve run across the following examples in the last week alone:

  • Processing and saving content to any kind of persistent storage.
  • Resizing images to optimize limited memory use.
  • Retrieving content from the network.
  • Non-trivial database queries.
  • Time-intensive mathematical operations (e.g. fast Fourier transform).

So, given the event loop, how do we write apps in a reasonable way to make the most of processing resources available?

An iOS example for loading and resizing images from the network:

- (void) loadImageFromUrl:(NSURL *) url size:(CGSize) size block:(void (^)(UIImage *)) block
    AFHTTPRequestOperationManager * manager = [AFHTTPRequestOperationManager manager];
    dispatch_async(dispatch_get_main_queue(), ^{
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    [manager GET:[url description] 
         success:^(AFHTTPRequestOperation *operation, id responseObject)
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        dispatch_queue_t backgroundQueue = dispatch_queue_create("fetch_image", 0);
        dispatch_async(backgroundQueue, ^{
            NSData * responseData = operation.responseData;
            UIImage * responseImage = [UIImage imageWithData:responseData];
            dispatch_queue_t backgroundQueue = dispatch_queue_create("resize_image", 0);
            dispatch_async(backgroundQueue, ^{
                UIImage * scaledImage = expensive_resizing_function(responseImage);
                [UIImagePNGRepresentation(scaledImage) writeToFile:path atomically:YES];
                UIImage * image = [UIImage imageWithContentsOfFile:path];
                dispatch_async(dispatch_get_main_queue(), ^{
    failure:^(AFHTTPRequestOperation *operation, NSError *error)
        NSLog(@"Error: %@", error);
        NSLog(@"RESPONSE: %@", operation.responseString);

In this example, the loadImageFromUrl:size:block: selector is typically called from the main UI thread. Blocks (code between ^{ and} symbols) look like

dispatch_async(dispatch_get_main_queue(), ^{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

instruct the app to post a UI event to the main UI thread. When called from the main thread, this dispatch_async doesn’t do anything useful. However, when it’s called from other threads, it makes sure that the UI updates are sent to the proper thread.

Next, we call the AFNetworking library to fetch the image data and we pass it a success and failure block that defines the operations to carry out after the fetch attempt is complete. These blocks are posted to the main UI thread, so we take advantage of that to update the UI, then we create a background thread (queue in iOS jargon) to process the image:

dispatch_queue_t backgroundQueue = dispatch_queue_create("resize_image", 0);

And then we run the operation:

dispatch_async(backgroundQueue, ^{
    UIImage * scaledImage = [FCDatabase resizedImage:responseImage ofSize:size];
    [UIImagePNGRepresentation(scaledImage) writeToFile:path atomically:YES];
    UIImage * image = [UIImage imageWithContentsOfFile:path];

When the resized image is ready to go, we update the main UI thread:

dispatch_async(dispatch_get_main_queue(), ^{

the block usually defined something like:

^(UIImage * image)
    imageView.image = image;

The functions dispatch_queue_create, dispatch_async, and supporting types are all provided by a relatively recent iOS/Mac framework called Grand Central Dispatch. Previous versions of iOS and Mac OS X could achieve the same results using the NSThread class that dates back to the early NextStep days. Since GCD is the preferred way of implementing concurrent processing on Apple platforms, I’ll skip the NSThread equivalent and leave it as an exercise to the reader.

Android exposes a similar mechanism called Handlers that manage the creation of event loops (provided by the Looper class) on different threads. This is roughly equivalent to the Grand Central Dispatch functionality provided by Apple and is generally useful if you want to post events with delays.

However, Android also provides low-level threads that are more flexible and work in other Java contexts. Purple Robot uses threads extensively. For example, when the user wants to delete archived files (an operation that can take quite some time if enough files have accumulated), the HttpUploadPlugin.deleteArchiveFiles method is called:

public void deleteArchiveFiles(final Activity activity)
    final HttpUploadPlugin me = this;
    Runnable r = new Runnable()
        public void run()
            File pendingFolder = me.getArchiveFolder();
            activity.runOnUiThread(new Runnable()
                public void run()
                    Toast.makeText(activity, activity.getString(R.string.message_clearing_archive), Toast.LENGTH_LONG).show();
    Thread t = new Thread(r);

In this case, we’re passing in the Activity object from which the method is called. The first thing we do is set up a new Runnable (r, analogous to a GCD block) and create a thread to run it. Within r, we update the main user interface via activity.runOnUiThread to show a toast notification and then we delete the folder. Once the deletion is complete, the parent method completes and the thread is destroyed.

The disadvantage in using threads in this manner (as opposed to the Handler or GCD queues) is that it opens up the possibility of flooding the system with threads if the software is poorly written. Keep in mind that (active) threads are useful only as long as you don’t exceed the processor core count. If you have more threads than cores, you’re only creating additional work for the local device since it needs to manage the thread bookkeeping along with everything else. Any non-trivial app will exceed the core count when its threads are added to those of the OS and any concurrent apps, so don’t worry it too much – just don’t go overboard. (The specific issues are beyond the scope of this post.)

So to get back to the title of this post, how do these threading models compare with single-threaded event-driven systems like Twisted orNode.JS/V8? These frameworks work off of the same basic event loop model. When you do an operation such as fetching a network resource or loading an image (in a browser context), the underlying runtime handles that work for you in a thread (from a managed internal pool) that it creates and it fires events back to your main event loop that your code can handle via the provided callbacks.

In these contexts, any code that you write is still executing in the main thread. If you’re working on an application where your code isn’t CPU-intensive, this model works well because all the work can be done well below the limit of human lag perception.

However, if you’re doing something non-trivial (such as running a pure-JS Fourier transform on a non-trivial amount of data), the system will begin to exhibit lag and it’s likely that your users’ operations will pile up as they wait for them to be processed by the main event loop. This is the point where treating asynchronous operations as functionally equivalent to concurrent processing breaks down. On the single-core machines from the past, this distinction was largely academic (indeed, events were better in this case due to lower bookkeeping overhead). However, as the Megahertz Race peters out in the mobile realm and we repeat the experiences of the past by stuffing more cores into our mobile devices, our ability to implement more computationally-intensive tasks will depend upon making the most of all of our local processors instead of relying on an individual cores to become faster on their own.

Introducing Puppet and Vagrant

By | News, Tech, Tech Blog | No Comments

Vagrant And Puppet

The ability to easily start new virtual machines has brought us multiple challenges, some of which are :

  • The ability to maintain our infrastructure over time, ensuring we have the right configuration in the right place.
  • The ability to version and record the history of our configuration.
  • The ability to re-use pieces of automated configuration in order to minimize work.

This blog post will introduce Vagrant, a tool which makes it dead-simple to start and stop virtual environments which run on your local workstation, and Puppet, a tool which allows us to express our configuration as code. By using Vagrant and Puppet together, we can easily and iteratively create complex configurations, and re-use our efforts across local, remote virtual, and cloud environments.


Vagrant is a command line program and a tiny DSL for creating virtual machines hosted on a local workstation. Vagrant depends on a provider, meaning a platform or hypervisor to host the virtual machines. The default Vagrant provider is Oracle VM VirtualBox. As of this writing, both Vagrant and VirtualBox are free and open-source to one degree or another. Vagrant works with the concept of “base boxes”, which are virtual machine templates which Vagrant then clones and customizes as specified using the Vagrant DSL. As described on the Vagrant website, getting started with Vagrant requires only three commands.

$ vagrant box add base
$ vagrant init
$ vagrant up

The commands up add a template called base to the local vagrant repository from an http:// URI, initialize a default configuration file, and start the machine specified in the initial configuration file. Your base box and starting configuration files would likely vary, but the above is a good way to get started. There are lots of Vagrant boxes available from a variety of sources. Eventually you will create your own to fit your own needs.

Configuration Management

We will now use Vagrant to create an initial virtual machine and use Puppet to provision this machine. Our high-level requirement is toenable multicast DNS, so that our host laptop can reach the virtual machine without having to explicitly set entries in /etc/hosts or manage a DNS resolver.


First, add a Vagrant base box. In the example below, we’re going to use a template available from which includes an appropriate version of Puppet for our needs.

vagrant box add centos64

The base box is now available to Vagrant under the name centos64.


By default, a Vagrant virtual machine will start with a single network interface, eth_0. This is a NAT interface, meaning all network operations performed by the virtual machine will be done through a virtual Network Address Translation interface provided by the host. Vagrant will also set port-forwarding options for VirtualBox so that the virtual machine’s internal port 22 is available on the host as port 2222 or above. The result of this is that ssh commands to localhost:2222 will be directed at the guest’s ssh server.

vagrant commmands

Most vagrant commands for operating on virtual machines are usually to be executed from within the same ‘top level’ directory as the Vagrantfile. The vagrant command vagrant ssh will automatically connect to the virtual machine, making use of existing ssh public-key authentication. Please note that most vagrant base boxes are not suitable for production use, as the default Vagrant ssh keypairs they often employ are known and widely published.

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| = "centos64"
  config.vm.hostname = "db2" "private_network", ip: ""
  config.vm.provision "puppet" do |puppet|
    puppet.manifest_file  = "site.pp"

The following actions are taken when executing vagrant up using the above Vagrantfile:

  • The base box “centos64” is copied and started as a new virtual machine.
  • The hostname “db2” is assigned to the new virtual machine.
  • A second network interface is created and assigned to the virtual machine. This network interface is a private_network in Vagrant configuration files, also known as a host-only network. This means that only the host machine (your workstation) will be able to communicate with this one virtual machine.
  • The “puppet” block tells vagrant to execute the puppet apply command with the file site.pp as an argument. The location of this file must be in the same directory as our Vagrantfile.

The output from vagrant up should look something like:

Bringing machine 'default' up with 'virtualbox' provider...
[default] Importing base box 'centos64'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] Setting hostname...
[default] Configuring and enabling network interfaces...
[default] Mounting shared folders...
[default] -- /vagrant

The contents of our site.pp

$vagrant_packages = ['nss-mdns', 'avahi']
  package { $vagrant_packages: ensure => installed }
  service { 'messagebus':
    ensure  => running,
    require => Package[$vagrant_packages],
    service { 'avahi-daemon':
    ensure   => running,
    require  => Service['messagebus'],

.pp files are known in Puppet as manifests, and the above manifest does three things.

  • Lines 1-3: define two packages and install them.
  • Lines 5-8: start the service messagebus, but only after the nss-mds and avahi packages are installed.
  • Lines 10-13: start the service avahi-daemon, but only after nss-mds is started.

Now, assuming everything went to plan (and iptables is disabled or similarly turned off), the machine should be available on the host-only under its hostname and the .local DNS suffix.

ping db2.local
PING db2.local ( 56 data bytes
64 bytes from icmp_seq=0 ttl=64 time=0.389 ms


The above snippets show us how we can use Vagrant and Puppet in order to create machine configurations as if they were source code. Much like source code, these Puppet code behind these environments can and should be re-used whether across production servers or on local development workstations. In a future post, we will explore features of the puppet tool and language share an evolutionary approach to creating re-useable puppet configurations.

Mobile Apps for Depression: A Brief Overview

By | Tech Blog, Uncategorized | No Comments

The mobile app landscape is constantly changing. There are literally hundreds of mobile apps for depression and anxiety treatment and prevention with new ones published all the time. Of course I’ve seen and used many of these apps before, but I wanted to get an overview of what is currently out there, common features and limitations, and how app developers are weaving tutorials into the user experience.


Searching both the App Store and the Google Play store for the word “depression” and ignoring results that were obviously unrelated (a mobile study guide about the Great Depression, for example), I found 158 relevant apps on Apple’s App Store and 157 on the Google Play store. And that’s only apps for depression that include the word depression in the title, description, or keywords. Searching for “anxiety” or “happiness” adds in a load more, though with much overlap.

The apps I found could be sorted into a few basic categories:

  • depression tests – provides the user with tools such as the PHQ-9 and the Hamilton Rating Scale for Depression to “self-diagnose” depression
  • “mood boosting” apps – inspirational quotes, gratitude journals, etc.
  • informational apps – text-heavy apps that offer information and suggestions for dealing with depression
  • meditation apps – audio files with guided meditations or relaxing music
  • mood trackers – apps that allow users to track their mood changes over time, sometimes alongside potential triggers such as sleep deficit

This last category interests us most since it’s most related to what we do. I was particularly curious to learn how many apps took advantage of Android and iPhone’s context sensing technology the way Purple Robot does. I expected to find a lot but I actually only found one, and that app used the data very differently than we do.

There are a few features that are common to many of the mood tracking apps I reviewed:

  • mostly manual input – as I said, only one app that I found used context sensing to gather information the user hasn’t expressly entered herself
  • timeline-based graphs – pretty much all of the apps offered graphs to view the user’s mood (and sometimes other inputs) over time
  • simple sliders – most apps offered simple sliders and other quick and easy ways for users to enter data
  • emoticons for mood selection – rather than words, many apps relied on colorful emoticons for labeling mood
  • text notes – most apps allowed users to enter text notes for any given entry
  • trigger tracking – many of the apps allowed the user to track other potential factors aside from mood: sleep, medication adherence, menstrual cycle, etc.

We were specifically interested in learning how other mood intervention apps educate users on how the app works, how to use specific features, and on a more conceptual scale, why the user might want to use the app in the first place and what she can hope to get out of it. Almost all of the apps I reviewed had some sort of tutorial built in, though some were more sophisticated than others.

There were five main types of tutorials I saw:

  • text-based welcome – The first time the user opens the app or accesses a certain screen, a page or pages of plain text instructions are displayed.
  • semi-transparent overlay – The first time the user opens the app or accesses a certain screen, a semi-transparent overlay with arrows and text bubbles explains how it works. Often screens like this will display right away but sometimes another screen with more advanced tips will show up later after the user has used the app for awhile.
  • video – The first time the user opens the app or accesses a certain screen, or when the user requests it, a short instructional video plays. Sometimes these videos are animated, others are just a static view of a talking head. Videos usually require sound to be fully understood and if they’re too long or not interesting enough, the user may not watch all the way through.
  • slideshow – The first time the user opens the app or accesses a certain screen, she’s led through a short series of illustrated, low-text-density slides that describe that app or feature.
  • help icons – These apps don’t use tutorials at all. Instead, the design is intuitive, making use of familiar standards and offering unobtrusive help icons for when the user is stuck. More detailed instructions may be accessible through a menu if the user seeks them out.

Test Case: CommunicationBridge — Rails Admin as CMS

By | Tech Blog | No Comments

Building custom, simple, and user-friendly content management systems is perhaps the greatest challenge in developing web applications for clinical research. Standard, widely available platforms like WordPress are not designed out of the box to satisfy the specific needs of individual research projects that require robust data models and complex views controlled by a wide array of logical parameters. From a development standpoint, many of these features are not difficult to design so long as the custom content is completely administered by the developer. However, the requirements of many studies demand the creation of an application that can both balance the complex and specific logical functions of the application and the ability for a non-programmer researcher to administer custom content within the application.

With this dual demand in mind, I have been developing CommunicationBridge — an application that coaches people with aphasia — in a RoR framework and testing the limits of the popular Rails Admin gem as a CMS. My aim in this process is to determine if Rails Admin can meet three requirements:

  1. It can create individualized content for each user of the application and control the content that individual users will be shown and can interact with..
  2. It can be customized to mask or automate model associations in the creation process without compromising the data relationships
  3. It can be administered by a non-programmer researcher without excessive support

Rails Admin does an admirable job of understanding model relationships and translating them into a well-ordered and attractive CRUD interface. For object generation, Rails Admin is simple and effective. It also has built-in data exporting that makes it very easy for an administrator to extract data. However, it does require that the user have a relatively strong understanding of the data models that the interface is exposing. A CMS like WordPress has abstracted this model layer away so that the administrator can interact with the application in a more user-friendly way. My challenge has been to push Rails Admin to its limit to try to modify it to act more like a popular CMS without compromising the integrity of the application logic.

My open-ended verdict of Rails Admin as a CMS is that it can be used effectively for a variety of use cases. However, it has two notable weaknesses.

First, Rails Admin can quickly get overburdened with nested forms. If one wishes to restrict content generation within a single form, nesting will run as deep as the models are nested. To compensate for this, I have had to create some awkward model relationships or callbacks to mitigate this complexity.

Second, while Rails Admin form fields are customizable via partials and scoping, the DSL is awkward and the documentation is almost non-existent. For standard model relationships, achieving desired form modifications is easily attainable once the DSL is better understood, but I had great difficulty in trying to massage the interface to accommodate polymorphic relationships.

Overall, Rails Admin has been a useful tool for content generation and offers fine-grained control over complex UI logic. However, if the model relationships are not well-thought-out in advance, I can easily find myself jumping through hoops attempting to fit my application within the constraints of my CMS, rather than the opposite. This, however, is likely a problem for any application that demands a high degree of customization from an administrator.

JSON Wars: The Empire SAX Back

By | Tech Blog | No Comments

Two of the most persistent issues that I have to constantly address with Purple Robot are its performance and resource footprint. After over a year, I’ve continued to refine and modify the code to squeeze out more responsiveness and battery life. In the current Purple Robot code, I just committed some code that increased battery life 176%, decreased average CPU load by 65%, at the cost of increasing the average memory footprint from 31.7MB to 36.4MB (as measured on a Samsung Galaxy Nexus running Android 4.3).

How did I do it?

I’ve known for some time that Purple Robot’s major performance bottleneck has been the original implementation of the code that handles sensor data, from its original collection to transmission to the server. Basically, this process unfolds as follows:

  1. A sensor generates a reading and broadcasts the reading (and other data) to the rest of the system using an Android broadcast.
  2. The HttpUploadPlugin receives the broadcast and generates a JSON object that it holds in memory. When a sufficient number of sensor broadcasts are collected, Purple Robot bundles them up into a single JSON object and writes the aggregate to disk.
  3. On another thread, Purple Robot periodically wakes up and determines if there is new data to transmit. (One or more files will be in a predetermined location.)
  4. If there’s new data to upload, Purple Robot reads the JSON files and extracts a sufficient number of JSON objects to construct a “payload”. The size of the ideal payload is either determined adaptively (from data collected from prior transmissions) or set in the app preferences.
  5. Purple Robot transmits the payload to the server and repeats the process. If no more data is available for upload, Purple Robot allows the current thread to complete and restarts the process at some time in the future (either determined adaptively or set in the preferences).

This has been a useful approach that minimizes the opportunity for data loss and attempts to scale the uploader activity with the user’s available connection quality.

However, when I profiled Purple Robot to try and determine what various performance bottlenecks were, I found that the bulk of the samples that I collected were string manipulations related to JSON serialization and deserialization. With that in mind, I simplified the data collection and upload pipeline:

  1. A sensor generates a reading and broadcasts the reading (and other data) to the rest of the system using an Android broadcast.
  2. The new upload plugin receives the broadcast and converts the bundle to JSON. This JSON is added to an array already being created. If the expanded array exceeds a set size (256kB in this case), it’s written to disk as a JSON string.
  3. On another thread, Purple Robot periodically wakes up and determines if there is new data to transmit. (One or more files will be in a predetermined location.) If there’s new data to upload, Purple Robot reads the JSON payload directly from disk and uploads it to the server.
  4. Purple Robot transmits the payload to the server and repeats the process. If no more data is available for upload, Purple Robot allows the current thread to complete and restarts the process at some time in the future (either determined adaptively or set in the preferences).

This process is similar to the original one. However, it differs in that the sensor data is translated into a JSON string only once. That string is included verbatim in the upload document that’s posted to the server. Data that once went through three JSON conversions now only goes through one. The other major change is that the JSON is processed using a streaming method rather than the popular in-memory tree method.

The tree-based method (using the org.json classes) reads a full JSON document in memory and operations such as reads and updates are done in-memory. When the manipulations are complete, the full in-memory structure is written out to disk. The streaming method uses an alternative set of classes that construct a JSON document on-disk through a series of events. At no time is the JSON full tree in memory. This is directly analogous to the differences between DOM and SAX parsers for XML.

Android introduced streaming JSON classes in Honeycomb. These allowed me to create a new streaming JSON uploader for newer devices. A third-party Java library called Jackson also provides very similar API that allows the streaming approach to be used on pre-3.0 devices. As of today, Purple Robot includes uploaders that use both classes for the purpose of a comparison.

So, how do these uploaders compare to each other?

Uploader Battery Drain
(seconds per %)
Avg. CPU Load Avg. Memory Usage
HttpUploadPlugin 211s 0.74 31.6MB
StreamingJSONUploadPlugin 345s 0.64 38.7MB
StreamingJacksonUploadPlugin 584s 0.25 36.4MB

These measures were collected on a Samsung Galaxy Nexus running Android 4.3. The accelerometer, magnetic field, and gyroscope probes were set to their highest frequencies (> 100Hz), and the quantities above were collected over a 30 minute period.

I was surprised to see that the original approach remained the most memory efficient (31.6MB vs. 38.7MB & 36.4MB). This may be explained by my (and Jackson’s) use of buffered output classes that keep content in memory longer in order to facilitate more efficient writes (write a a large amount at once instead of many small writes). On the battery front, the streaming approaches dramatically decreased the battery usage. Using the tree-based approach, we could expect a runtime around 5.86 hours using this configuration. Using the Honeycomb classes, runtime grows to 9.58 hours, and the Jackson classes boost the runtime up to 16.22 hours. We see an expected decrease in CPU load, with the use of the Jackson classes providing the largest gains. (Note that these figures will vary based on other applications running on the device. A marathon session of Angry Birds will still drain your battery just as quickly.)

Since the Jackson-based uploader not only provides the largest performance gains, but also provides backward compatibility to pre-3.0 devices, this will become the new upload approach after some more testing. The results I measured were in line with other tests of JSON read/write performance.

I’m quite pleased with these results and look forward to deploying these enhancements in an upcoming version of Purple Robot.

Ontologies at CBITS

By | Tech Blog | No Comments



The world of CBITS is two intersecting domains – Behavioral Intervention theory and web technology. Ontologies are one strategy to manage the multi-faceted body of knowledge, models, designs, data and code that researchers at CBITS encounter every day.

What Are Ontologies?

An ontology is a “domain model,” or a model of some particular area of knowledge such as anatomy, robotics, or farming. The goal of an ontology is to capture how humans understand the parts of a domain (such as bones, muscles, and organs) and the relationships between them (“muscles move bones,” “organs regulate the system.”) If sufficiently well-described, an AI system could, in theory, generate its own relationships from the model. For human users, ontologies can serve as knowledge management systems.

To promote integration with software, ontologies have a well-defined data model that ensures syntactic coherence. If a human enters knowledge that is coherent but untrue, it will still be sensible to a machine from a grammatical perspective, allowing it to compile. This data model, generally hidden from the users of graphical tools like Protégé, facilitates “expert knowledge capture.” A doctor with an excellent command of anatomy does not need to understand computer science to create an anatomical ontology.

The Protégé set of tools ( is used to create, edit, and visualize domain models. Protégé is expressive enough to support any domain. At CBITS, we have begun to explore the role of ontology in aiding the link between two seemingly disparate domains: preventative behavioral medicine and software technology.

Emphasis on Standards

The desire to create standards fuels the ontological approach. Although it is often enjoyable to debate the precise meaning and construction of higher-level concepts, these debates are time-consuming and often unresolved. In areas of medicine, where one hopes to eventually provide benefits to patients; or technology, where a software tool must eventually be built, there can be an advantage to minimizing the length and re-occurrence of such debates. Ontologies capture discussion in digital form while allowing revision. This helps to create consensus needed to move from abstract discussion to practical implementation.

This becomes even more relevant in intra-domain discussion, where the same word can have drastically different meanings. By clearly describing the meaning and relationships of terms within a specific domain, researchers who work in two different areas – such as psychological behavior and technology – can use ontologies as a guide to ensure that domain concepts are not confused during project planning and discussion.

At CBITS, the word “intent” can mean a general intention of a patient to perform a behavior, a way to tell an Android application what to do next, a specific intention of a person working in CBITS, or be used in a colloquial phrase such as “for all intents and purposes” without much particular meaning attached to it. In situations like these, even the natural ability of humans to manage ambiguity begins to break down. A computer might be more confused.

By helping to capturing broad concepts and anchoring them in domain-specific interpretations, ontologies can save time, save cost, and even resolve confusion among practitioners from different domains who work together. The logical structure of an ontology is extremely general – the next section will show some concrete examples of the power of this logical generality.

A Frames Ontology for Intellicare

“Intellicare” is a set of Behavioral Intervention Tools (BITs) currently in development by CBITS. Their clinical aim is to target anxiety and depression by addressing different behaviors that can improve or impede progress in these areas. The research goal of the Intellicare project is to create a “recommendation engine” that will suggest mini-apps to users based on their response to other apps. To create Intellicare, clinical researchers and technologists collaborated to reconcile models of clinical behavior with technology resources. The results of these collaborations were stored in an Excel spreadsheet.

To create a more flexible domain knowledge store, and to aid future design and evaluation of a recommendation engine, I used this Excel documentation to create an ontology of Intellicare.

This following example demonstrates that to capture expert knowledge in ontologies, not only do experts not necessarily have to understand details about technology, but they don’t necessarily have to understand ontologies. With sufficient semi-structured documentation, an ontologist can create a preliminary ontology that faithfully represents expert ideas – further collaboration can then refine the ontology, and in time the ontology can itself grow.


The classes in the Intellicare ontology can be seen in the left panel – these describe all the general features of Intellicare, including tech, behavior and clinical aspects.



Frames is an Object-Oriented model. Classes have instances which are annotated using “slots.” Slots, or attributes/properties/fields, are defined with respect to the class. Above, we describe a technology interaction called “record audio.”



“Slumber Time” is an instance of “Mini_App,” and above it is described in relation to clinical goals.

Companion Ontologies

To keep ontologies compact within large domain spaces, I create a variety of ontologies for a domain rather then attempt to link all concepts in one file. This facilitates more user-friendly knowledge browsing.

Creating organizationally internal Frames-based ontologies also allows ontologists to represent similar concepts from different perspectives. This is helpful when “reverse-engineering” software tools that have an undocumented, but implicit domain model. To demonstrate, I reverse-engineered an ontology for “Slumber Time” by browsing the application on an Android tablet and documenting each observed part.




Above, a set of instances of checklist items.

Designing with Ontology: Cows are Ruminants

While creating an app called “Cows are Ruminants,” a tool for addressing rumination, I re-used significant amounts of software code from “Slumber Time.” While the content of Ruminants and Slumber Time differ, from a technology perspective they share many attributes, such as slideshows, a method to create SQLite database, and questionnaires for users. The “Cows are Ruminants” ontology can be compared to the Slumber Time ontology, to retroactively begin to make generalizations that may speed up the development of future Intellicare apps.

In its unfinished state, the ontology provides an easy way to collaborate with the clinical lead. The ontology is structured enough to guide discussion, demonstrates clearly where there are gaps in understanding, and allows for precise and rapid specification of tool aspects such as the database structure or the relationship between two different surveys in the tool.



Above, a clinician-defined database schema that I translated into an Android content provider. The ontology permits structured discussion and serves as documentation.

Frames vs OWL

What is the difference between Frames ontologies and those based on OWL, and what guides the choice of one over another? For the preceding examples, the Frames model was used. I explain this choice in the following section. * Intellicare: Closed World, Frames, Specific within Domain*

Frames ontologies follow the “closed world” assumption, which means that nothing is true in the domain unless it is specified by the ontology to be true. This closed-world assumption is limiting from the perspective of spontaneous knowledge generation by machines. The closed-world assumption is extremely helpful when porting ontologies into other technology domains, such as databases or software tools. This porting is best achieved when ambiguity is limited. The sacrifice of expression is made up for by the savings in time, and the possibilities of expanding model implementations into richly developed open-source ecosystems. An example of how this can work will be presented in a later section on the Django python framework.

The domain of Intellicare can be understood to be quite limited. It is a specific project, conceptualized by specific people, which will produce a specific suite of software tools. This specificity means that the Frames model does not do too much to hamper human expression, and the closed-world assumption allows an opt-in approach to defining concepts, which drastically reduces the amount of time required to model the domain. As an example, the Intellicare ontology above was translated from a spreadsheet in three hours of work. The two app ontologies took about an hour each. Comparatively, some OWL ontologies take years to build. * Behavior: Open World, OWL, Universal within Domain*

OWL ontologies use the “open-world” assumption, which means that anything in the domain that can be inferred from the ontology can be assumed to be true. This is useful when an ontology is intended to capture a very general domain – such as the domain of human emotion, or anatomy, or robotic decision making. The “open-world” assumption demands much more precision and time in ontological definition. Since anything that can be inferred from the ontology can be considered to be true, if machines are going to use the ontology, it is best to make sure that the ontology is as well specified as possible.

A computer has no problem conflating a logical truth with an empirical truth – this is, for example, how might decide that you are very interested in wireless keyboards and recommend hundreds of models to you a year after you’ve purchased the single one that you needed. Logically, you were at one point interested in keyboards, evidenced by your search for one on the site, but the system does not have sufficient capacity to understand that your interest has been sated. To avoid these issues, ontologists using OWL ontologies use precise detail when creating their ontologies. The advantage is that when done well, an OWL ontology of, say, human emotion can be considered relatively universal, and integrated across many other domains. The cost comes in time, with some OWL ontologies requiring teams of collaborators and years to complete.

Although our current work at CBITS focuses on Frames ontologies to capture concepts internal to CBITS, ontological work done in OWL will be invaluable in helping to integrate broader domain concepts (especially behavioral ones) into our specific tools. They will also aid our group when collaborating with other teams that use ontologies, or might like to, or are simply interested in reading ours. The exact reconciliation of these two methods remains to be developed. The open-source ethos of ontologies helps promote sharing and collaboration. This ethos has always been integral to productive research.

Next Steps for an Ontology of Intellicare * Intra-Ontology Integration*

One way to reduce “double-work” when developing ontologies is to integrate different ontologies as much as possible. Ontologies are easily composed and decomposed into larger or smaller domain models, and this can save a great deal of time, as concepts do not need to be continually re-worked.



The “Prompt” plugin is used to create new ontologies from old ones through composition and decomposition. Above, behavioral theory concepts are being added to the “Cows are Ruminants” app ontology.

Tool Development, Design and Reconciliation through Ontologies

As the suite of CBITs ontologies grows, they can be integrated into software tool development at earlier and earlier stages. Ontologies can be used to define the structure and clinical aims of a tool, refine the model, compare the tool to other tools already created to identify reusable code and components, and inform the integration of a tool into the overall Intellicare model. In time, as other software tools are pulled in, a general “BIT Framework” can be developed.

app_comparison (1)


Above, shared structural components between two Intellicare apps – “Slumber Time” and “Cows are Ruminants.”

Once CBITS clinicians, researchers and technologists alike become comfortable with the use of ontologies, these models can help facilitate collaboration and create universal, reusable and persistent documentation of the many discussions that precede tool development. Ontologies can help identify redundancies, allowing teams to be more productive and do more work that focuses on new problems rather than rehashing old solutions.

Expert Knowledge Capture

Ontologies aid “expert knowledge” capture. The Intellicare ontology, translated from an Excel document, provides one example. An ontology which acts as a data-dictionary for the Purple Robot database is another. Using a plugin provided by Protégé, I imported the entire database schema for the Purple Robot sensor database into a Frames ontology. I sat down with one of the database experts and question him on the ontology, documenting choices made in the creation of the database.



The result is a data dictionary for the current Purple Robot database that did not exist before and took approximately four man-hours to complete. Anyone who has inherited a data set to work with that has no data dictionary attached can appreciate our effort here.

Use Queries to Identify Gaps

Protégé has a query language that allows users to sift through the model based on attributes.



The query, defined on the left, reveals the result, on the right, that one Intellicare app has the proximal goal of “Identify and Change thoughts.”


When a query returns no results, or unwanted one, this illustrates a “gap” in the model, or perhaps in the reality of current tools which, now identified, can be addressed. ** Future Work in Ontology** * Documentation / “Frames Style Guide”*

For ontologies to be productive at CBITS, more documentation is required. A style guide will be needed to guide ontology development. The flexibility of the tools promotes creativity, but guidelines will ensure that different ontologies can interact easily together.

Internal Tool that Serves Collaborative Frames Ontologies

A way to store ontologies for collective browsing or collaboration can also be developed – currently, our ontologies live on local machines and change tracking is not available.

A precedent for this exists as ( This client may serve our needs “out of the box,” but must be evaluated from an efficacy and a security standpoint. Fortunately, as an open-source project, we have the capacity to modify the tool if necessary – but due to resource constraints this may or may not be a good idea. * Translations between OWL instances and Frames Instances*

Translating between OWL and Frames remains one of the trickier problems that we are considering. It is desirable as a way to integrate the work of researchers around the world at the high-level into our more specific domains of individual software tools. Below, useful work has been captured in an ontology of emotion, and stored in OWL format:

grief grief2


The full ontology can be found at .

*Port Domain Models onto Web Technologies *

One exciting possibility of ontologies results from their highly-structured data model. Since ontologies are “object-oriented,” the models can be ported into other kinds of object-oriented systems. In the below example, a Java script reads a Frames ontology and generates a set of Django models. These models then may be passed through the Django ORM and compiled into a relational database.












Above on the left, the Protege data model. On the right, the appropriate translation into a python-based Django model element. A script written in Java uses regex to comb through a Protégé class file and generate the Django model.

Any object-oriented framework can be given the same treatment, creating increased coupling between expert knowledge capture and software tools. With capabilities like these, experts in domains outside technology can define tools, and technologists have to do less work to translate these definitions into the tools themselves, and can create more accurate translations.

  • Integration with Code Repositories*

One day ontologies could be directly connected to code repositories. CBITS ontologies could be delivered to collaborators who may then define ontologies of their own BITs by copying, composing, and decomposing our domain models. These models, if connected to scripts that connect the ontologies to other software Frameworks, can generate the base code for software tools. These models can also be connected directly to code repositories to import entire modules of code.

The intervention of technologists will still be needed to glue parts together, but through iteration, this intervention will become easier and easier. The net result is less work, less cost, and more patient benefits as BITs can be generated from semi-generic concepts into extremely specific, but functional tools. Additionally, research resources will be freed to continue innovating on the BIT model and incorporating new technologies as they appear.

The literal nature of computers can come in handy – the computer does not care if it is generating a database of patient information for an HIV study, or a study of depression, as long as the data model looks the same. Fortunately for us, the data model often does.

Using Android Helper Apps to Put Purple Robot on a Diet

By | Tech Blog | No Comments

Since Purple Robot’s inception in the fall of 2012, it’s become the largest Android application I’ve ever written with over 50 different sensors, a built-in web server, and two complete embedded scripting environments. Lately, I’ve had to temper my ambitions a bit given that the app has begun to hit fundamental system limitations that are causing major issues moving forward.

The first limit that I hit was on older phones related to how Android installs APK files. The high-level summary is that a limitation on a fixed-size buffer on pre-3.0 Android devices doesn’t allow an Android app to install because the installer exhausts an internal fixed-size buffer and fails with a cryptic error message to the user. If you have had issues installing recent Purple Robot on 2.x devices, this is the culprit. This issue was addressed in Android Honeycomb by expanding the hardcoded limit, and then expanded further in the Android 4.x series. For a fuller description of the issue, Facebook has a great blog post on the topic. While I am not planning on using a native JNI extension to solve this issue, Facebook’s description was extremely valuable in helping me make sense of a cryptic error.

A similar issue that I’m currently experiencing on newer Android devices is also related to how Android parses Dalvik bytecode. When I compile Purple Robot against newer versions of the Google Play library, this happens:

[2014-05-09 14:51:53 - Dex Loader] Unable to execute dex: method ID not in [0, 0xffff]: 65536
[2014-05-09 14:51:53 - Purple Robot] Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536

This occurs because only 2^16 (65536) methods can be present in an application APK. Purple Robot isn’t that large on its own, but once I link against the Facebook SDK, Google Play services, Rhino JavaScript library, Apache Commons Math library, and more, the app grows and exceeds that built-in limitation.

Contributing to the problem is the growth of the Google Play services bundle, which continues to expand its own method count with each new release. 2,500 more methods were added between the 4.2 and 4.3 releases and those new methods count against Purple Robot’s method budget. (Recent investigations revealed that linking against the Play Services library will automatically add 14,000 methods in total.) A lot of this functionality are things that I don’t need, such as game center integration and mobile ad serving. However, I don’t expect Google to split these off into separate modules, so I’m stuck with the current situation for the foreseeable future.

One solution proposed is to split the application into separate APKs and load classes dynamically. Given that I’m trying to deliver as close to a checkout-and-compile experience as possible, I’ve ruled out this approach as it makes the build process non-trivial and introduces more potential for things to break at a basic level. I’ve come up with an alternative solution that I’ll be implementing moving forward.

Late in March, I was working on getting Purple Robot to communicate with the open-source Shion home automation platform that I’d built a couple of years ago. The Shion home-to-client protocol uses XMPP as a messaging layer and pulling house device events (lights on, temperature changes sensed by the thermostat, motion sensors, and more) into Purple Robot really only needed an XMPP client that spoke Shion’s XMPP dialect. In the past, I’ve used the Smack XMPP library on Java and that was my plan for this integration. However, I’d already encountered the methods limit described above, so I worked around it by creating a helper app that would have its own process and memory space and it would communicate with Shion on Purple Robot’s behalf. This was a pretty simple app to write and consisted of an activity to let the user enter their Shion authentication credentials and a persistent service that managed the XMPP communication. When the service received a new event from my smarthome, it would package the information into an Android bundle and use the built-in broadcasting features to send the information to Purple Robot. On the Purple Robot side, I constructed a very minimal probe that would intercept the broadcast and transmit the bundled data to the data pipeline. From there, the data could be processed by triggers (“alert me when someone turns on my desk lamp”), transmitted to the analysis server, or any of the other nifty things that Purple Robot does with probe data.

Since the initial Shion integration, I’ve successfully replicated this process by integrating with some (currently) closed-source research platforms with Purple Robot. Moving forward, I’m evaluating the current collection of Purple Robot probes and looking for opportunities to “slim down” the core offering by pulling out collections of plugins and offering them as add-ons. A couple of potential add-ons:

  • Social presence: Probes that capture your social activity on platforms like Facebook, Twitter, and Instagram.
  • Fitness: Probes that can communicate with the growing population of fitness trackers: FitBit, Jawbone, Shine, etc.
  • External devices: Shion devices, Nest appliances, Chromecast devices, etc.
  • Location data: Information from Google Places, Foursquare, etc.
  • Research: Integration with research platforms like Open mHealth and Cornell’s SAINT system.
  • Automotive: Integration with automotive data buses and smart consoles: Ford/Microsoft Sync, CarPlay

I could go on, but the path forward should be clear. Now that we have a proven mechanism for expanding Purple Robot’s sensing features without hitting the limitations described earlier, this allows me the latitude to push Purple Robot beyond the personal sensing space into a much more interconnected world.

Keep an eye open for these changes in the Purple Robot 1.6 release cycle.

Programming Principles Week 1: Single Responsibility Principle

By | Tech Blog | No Comments

PRIM is a white-labeled, participant registration intervention management system. Important aspects of PRIM include:

  • an appealing home page, meant to grab interest of potential participants
  • a process for administrators to personalize the content and facade of the intervention site
  • content that details the intent and purpose of an intervention
  • content that details the eligibility of the intervention
  • content that details the funding for the intervention
  • contact information for the administrators of the intervention
  • resource information for the intervention
  • a process for participant registration and screening

The PRIM system currently exists as a RoR application, designed to act as a hub for a variety of intervention sites. As participant registration occurs on the PRIM front end, the participant data is persisted into PAPI, a central and secure repository. The justification for a central data repository is the requirement to track participants across multiple interventions, aiding in decisions to allow or deny participant access.

The CBITs web developers have decided to focus on a new programming principle, heuristic or pattern each week. Our hope is that by doing so, we will start to develop a more intuitive understanding of the tradeoffs involved when applying these principles.

For our first week, we have chosen the Single Responsibility Principle. The tl;dr version is: each unit of code should have a closely related set of features that serve a unified goal. Below we will get into specific examples that illustrate this.


This first example comes from a Cordova application called MedLink, built with JavaScript on top of the Backbone library. It involves a model "class" that has outgrown its original responsibility of storage and retrieval of application configuration settings. It is now being used to access the API of a native Android application called Purple Robot. As configuration settings are updated within the host application, remote methods are invoked on Purple Robot.

function Settings() {
  this.setMedicationTime = function(time) {
    localStorage[KEYS.MEDICATION_TIME] = time;
  this._updateMedPromptTriggers = function() {
    // add a nightly trigger to run about midnight and reset the tray notification and adherence value

This code is ripe for refactoring. It no longer has a single reason to change, but at least two: 1. when there are updates to configuration options and 2. when the desired behavior of Purple Robot changes. One possibility is that event listeners could be added so that when a relevant setting changes, a unit of code that contains all Purple Robot programming logic would be notified and perform the necessary API calls. For example:

function Settings() {
  this.setMedicationTime = function(time) {
    localStorage[KEYS.MEDICATION_TIME] = time;
    this.trigger("medicationTimeChange", time);
function PurpleRobotRules() {
  function updateMedPromptTriggers(time) {
  this.initialize = function(settings) {
    settings.on("medicationTimeChange", updateMedPromptTriggers);


This example was an exercise in getting to know localStorage. Using HTML5 and JavaScript, we've created a simple CRUD document that generates a random array of integers. The user can then store the array into the browser's storage and also display the stored array. Once it has been stored, the user can choose to delete an integer using the drop down or delete the entire array and start fresh.

var array, arrayPosition, storedArray;
var arrayMax = 8;
var dropdown = document.getElementById('arraySelector');
function generateNumbers() {
    array = [];
    while (array.length < arrayMax) {
        var randomInteger = Math.ceil(Math.random()*10);
function storeNumbers() {
    localStorage.setItem('numbers', JSON.stringify(array));
    storedArray = JSON.parse(localStorage.numbers);
function showNumbers() {
    var div = document.getElementById('numberDisplay');
    div.innerHTML = localStorage.getItem('numbers');
function deleteSingleNumber() {
    arrayPosition = dropdown.options[dropdown.selectedIndex].value;
    storeNumbers(); //update localStorage with shortened array
    showNumbers(); //automatically refresh the displayed array
function deleteNumbers() {

The functions are then called using HTML buttons on the document body. You can see a rendered preview here:


Rails sometimes makes it difficult to adhere to the SRP. ActiveRecord models inherently violate the Single Responsibility Principle. Business logic that may involve the interaction of more than one model is often moved into concerns: modules that aid in the splitting up of complicated model interactions. These concerns attempt to bridge the gap between non-SRP Rails conventions and classes that handle a single conceptual piece of domain logic.

One fairly common feature CBITs applications must often accommodate deals with the determination of a patient's adherence status to the BIT. Here is an example of one particular implementation of this that attempts to maintain the SRP while at the same time not cluttering up the Participant model class with a logically distinct set of functions.

# Handles Participant overall status logic
# Module is included in the Participant model
module Status
  extend ActiveSupport::Concern
  def current_study_status
    if start_date
      if current_lesson && previous_lesson
      elsif current_lesson
  def current_lesson
    Lesson.where("day_in_treatment <= ?", study_day)
          .where(locale: locale)
          .order(day_in_treatment: :desc).second
  def previous_lesson
    Lesson.where("day_in_treatment <= ?", study_day)
          .where(locale: locale)
          .order(day_in_treatment: :desc).offset(2).first
  def current_lesson_complete?
    if current_lesson
      current_lesson.content_access_events.where(participant_id: id).any?
  def previous_lesson_complete?
    if previous_lesson
      previous_lesson.content_access_events.where(participant_id: id).any?
  def two_lessons_passed
    if  !current_lesson_complete? &&
    elsif !current_lesson_complete? ||
  def one_lesson_passed
    if current_lesson_complete?

PRIM: Participant Registration Intervention Management

By | Tech Blog | No Comments

PRIM is a white-labeled, participant registration intervention management system. Important aspects of PRIM include:

  • an appealing home page, meant to grab interest of potential participants
  • a process for administrators to personalize the content and facade of the intervention site
  • content that details the intent and purpose of an intervention
  • content that details the eligibility of the intervention
  • content that details the funding for the intervention
  • contact information for the administrators of the intervention
  • resource information for the intervention
  • a process for participant registration and screening

The PRIM system currently exists as a RoR application, designed to act as a hub for a variety of intervention sites. As participant registration occurs on the PRIM front end, the participant data is persisted into PAPI, a central and secure repository. The justification for a central data repository is the requirement to track participants across multiple interventions, aiding in decisions to allow or deny participant access.

Although the participant registration is the central focus of PRIM, ease of administration is an essential non-functional requirement. An administrator must be able to easily update intervention registration content and be able to change the look and feel. The initial implementation allows for real time updating of the content for administrators and content managers. Currently, Rails Admin is used to manage participant registration data and to choose the facade or template of the intervention site. The overall structure of the PRIM front end is shown below:

The flexibility of this structure allows for simplicity of the applications. The PRIM front end has only a few major functions and features: an attractive interface, a way for participants to register and be screened, and a quick and easy view for administrators. The PRIM API can be interfaced to create alternative applications with additional features. For instance, an aggregate reporting application could be created to hook into the PAPI for real time data updates.