Yet Another Covid Statistics Web App
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
Brady McDonough ccb9c63791
Updated upstream
10 months ago
backend Updated upstream 10 months ago
frontend New Brunswick was being rendered on 2 lines instead of 1 10 months ago
nginx Build now fully works 10 months ago
.env.default Wrong defaults 10 months ago
.gitignore Autoconf/Make nearing completion 10 months ago
.gitmodules Brought requirements in as submodules, changed to libgit from the git binary 3 years ago
Makefile.in Rewrote backend to use Guile's module system rather than primitive loads 10 months ago
README.md More Ramble 10 months ago
configure.in Wrong defaults 10 months ago

README.md

Yet Another Covid Statistics Web App

During the Covid-19 pandemic it seems like everyone and their dog made a web app to display statistics, and I was part of everyone. I was working in a grocery store at the time and that means I saw a lot of people. Originally I reasoned about my risk using a spreadsheet, manually pulling in fresh statistics for my area every week or so; being a programmer I knew I could do better and I made this. The backend is written in Guile Scheme while the frontend is written in Elm, both languages were chosen due to my interest at the time.

If you want to run this all yourself the project depends on:

It uses autoconf and make and can be deployed locally by running:

./configure; make; make install; make up

Don't forget to restart nginx after invoking the up or down target!

Notes

There's a lot that could be said of how I chose to calculate risk and unfortunately that's part of the project that was never completed. First of all the idea of calculating risk of exposure is at least somewhat novel but there are major hurdles that keep such calculations from being accurate and it should be noted that exposure isn't the same as infection. Based on this data I was almost certainly exposed to Covid-19 seeing hundreds of people a day at the height of the pandemic, perhaps I was also infected at some time but I never ended up with symptoms.

There are reasons to think that this data both overestimates and underestimates the real risk of exposure. For starters, the reporting mechanism was inconsistent, relying on a mix of reporters, some of whom never work weekends and who would variably attribute data reported on Saturday and Sunday as being either on the day it was recorded or lumped into Monday's numbers. This fact forced me to rely on looking at 7-day increments and rely on that averaging to smooth out the spike of catch-up reports appearing on Mondays. To varying degrees there were also constant reports of both under and over reporting. There is no way for the data to capture or account for cases in a pre-symptomatic stage nor false testing outcomes. Behavior of an infected individual would also likely be greatly modified, by all accounts Covid quite reliably put you out of commission and it's unlikely someone with an active case would be out and about beyond a certain point.

With all these challenges that I don't have the means to account for I decided to make it anyways and rely on the fact that the mix of both positive and negative biases would average out to an estimate which was good enough for at least my purposes.

The backend

Scheme in general has a number of features as a language that make it quite good at processing structured data. Parsers are quite easy to build in Lisp-like languages and there are entire languages (Racket) devoted to that fact. S-expressions are the primary building block of all Scheme languages, both syntax and data are just a series of S-expressions and when parsing structured data it all gets converted into a tree of S-expressions, commonly called sxml. There exist very strong means of manipulating these sxml trees, namely pre-post-order which can walk through a tree and dynamically change between depth-first and breadth-first walk orders depending on the node. In this program, data is read using a modified csv parser and output as sxml, processed using pre-post-order to remove data from the tree we aren't interested in and label each group of data with hr before the tree is evalutated as though it's code. The hr symbol is a syntax-rule and so when the evaluation is run each Health Region's data is re-written to code associating that data with a variable by the Guile interpreter. The same basic process is used on a list associating postal codes with health regions.

After all that parsing and data wrangling all that's left is to serve the data using Guile's own web server Artanis which looks more or less like every other web server out there. It's very straightforward to deine routes, handle get requests and define things like return types.

The frontend

Elm is a very interesting language, it's a Haskell that compiles to Javascript. It was created as a thesis project back in 2012 as a proof of concept for something the author called functional reactive programming. The "reactive" part of that recipe is everywhere in modern web programming and common terminology like "reactive props" were coined by Elm. In it's current form Elm's reactive roots are handled under the hood, its html module is clever enough to spot dependant variables and make minimal modifications to the DOM as an app's state updates. Elm is very aggressively an MVC language, the Model and Controller types are referenced everywhere and both pass through the View and Update functions. I decided to cut up the Controller type mid-way through the project according to why something was happening and it was quite easy. Thanks to the strict type system and detailed error messages any change I missed was caught by the compiler and portioning out the update function into active and passive concerns really cleaned things up.