Beginning a simple stats gathering app in Django

I just pushed a commit to my worksheet generator website containing a new app: something I’m calling “tobystats.” (Guess what my first name is.) The idea is simple: to try and collect the kind of stats that I’d like to have as I think about intentionally growing the site to be useful to more than just myself. (I mentioned the idea already.)

What stats would I like to collect?

In all honesty, this is probably a poorly-conceived project. I mean, I don’t know what I want to know. I do know that I’d like to start working on my landing page and create something of a conversion funnel to attract new users.

To that end, I’d like to know how many people who visit my site either 1) log in (they’re returning users and wouldn’t have clicked through, anway) or 2) click through to a “learn more” or “try it free” page.

Eventually, the same app should also be used for something akin to event logging. I’d like to know how many total worksheets the site has made. (It would be fun to celebrate a thousand worksheets made, or whatever) as well as counting other events. This is not something I’ve added, yet, but will.

How am I doing this?

The goal is to be able to add a single line to the views of pages that I’d like to track. Right now, that line is:

from tobystats import tobystats

tsid = tobystats.process_request(request, 'LandingPage')

And then the tsid string that’s returned is passed through to the template. (tsid stands for “tobystats id”), where it’s appended in the query string in links, like this:

<a href="example.com/link/blah.html?tsid={{ tsid }}">Example link!</a>

So, the idea is simple: when the process_request() function is called, it checks if there’s a tsid already associated with the URL. If there isn’t, we assume this is the first page that’s been loaded and create a new SiteVisit object (SiteVisit is the model I’m using to store the basics of a single visitor–eventually I’ll use some kind of IP geo-lookup to get the city and country of origin and store it there as well) and a PageView is created for that specific page, storing only the name of the page visited (this seemed to make more sense to me thatn URLs) and the date and time. Lastly, the tsid (a random five-character string) is generated and associated with the SiteVisit and returned to the view that called it.

If there’s already a tsid in the query string, it’s even simpler: look up the SiteVisit with the corresponding tsid and create a new PageView object associated with it. Job done!

I still have to make a dashboard

So far, all of the stats reporting available to me is the number of site visits and the number of those which were successful logins (the idea is that we’re going to only worry about what happens to visitors who don’t login–they’re the ones at whom the messaging is directed).

There’s a lot more to look at: how many visitors are identified by django-user-agents as bots (turns out that, within moments of uploading my stats, I was seeing referer spam), how many of the non-bots clicked through to the “learn more” page. If each step in the signup/initiation process is logged, it would be interesting to see how any people get fatigued by it and at what point. (Also, with geo-lookup, I could skip a step in the signup process).

It’s just a start

I’m sure there is more I can do–see the comment above about using geo-lookup for IP addresses. However, it was important to me to push something to the production site as soon as possible to just get a baseline for current usage. After all, if I don’t measure now, how will I know how many more visits are coming?

Also–and this may be the point of the whole thing–it’s nice to have a coding project to tinker with as I have time.

Some Coding Goals

Setting my own goals

It was not a super-productive summer for me, coding-wise. However, as I get away from ‘vacation-mode’ and back to ‘real life,’ in addition to improving as a teacher (more on that in another post), I want to improve as a coder.

Here’s the thing: There are a million ways to improve as a coder. And, I’m sticking to the ‘hobby coder’ label, so I don’t feel compelled to even try an know everything about coding, or even a specialization under the ‘coding’ header.

My task: is to be able to do the things I want to do, nothing more, but also nothing less. (To be honest, it will always be something less — I have an active imagination for what’s possible.) Now though, what I’d like to do is to make the things I make seem more like a ‘web application.’

What’s a web application?

The short answer is: it doesn’t matter. As a language teacher, I’m a big fan of the idea that words only mean what you and the person you’re speaking to understand. And, when I say web application, I mean it in contrast to a ‘web page.’

To me, a web page is static: Some guy (me) writes a bunch of stuff, takes a bunch of photos, makes a video, maybe, and puts it online. The web page is your chance to interact with what I’ve made, on my terms.

A web application, on the other hand, is magic. Sure, some guy (me) made it, but it’s a tool that I get to pick up and use how it best fits in my life. A web application is my chance to take something algorithmic I’ve made, and let you run with it.

Don’t you already do that?

To be fair, yes, I think that Dynamic EFL already qualifies as a web application. But, it doesn’t feel like it yet. It feels like a series of web pages that the user moves through, ending with a PDF, the most static document format of all time.

It’ll always end with a PDF, because the whole idea is that it’s supposed to be hidden. The learner isn’t supposed to know you used a ‘tool.’ The learner might hear the word ‘tool’ and think ‘shortcut.’ The whole idea is that the learner thinks “wow, the teacher invested time in me. I’m getting my money’s worth.”

So, maintaining the PDF format at the end, the way I see to make it feel more like an application is to make better use of transitions between pages and modals (the ‘foreground’ pages that open ‘over’ the rest of the page — logins are often done in modals).

The best web applications — gmail, Google calendar — don’t feel like pages at all. It feels like you enter an address into your browser, and then you interact with an application. That’s what I’d like to do.

A good argument for it

First, I rationalize it would help make what I do clear in comparison to what teachers are already paying for — static resources presented on web pages.

Second, it’s a sales point. Done smartly, the transitions and ‘web app experience’ simply feels more ‘modern.’ It helps to explain why I’m taking money.

A roadmap

I don’t have a roadmap in the traditional sense. That’s where this little goal-setting exercise breaks down. I’ve started experimenting and I’m finding it pretty hard. I have used JavaScript to dynamically change content on a web page, but I haven’t made the animation part of that work, and I haven’t been able to load a new django view into one <div> of a page.

So, I guess I have my work cut out for me.

The plan, now, is to leave Dynamic EFL how it is as I begin attracting beta testers. Instead, I have a new project idea that I want to start from scratch as a web application (using Google APIs, no less!) (more information on the actual project in a future post). Then, when that’s working, I’ll be able to apply lessons learned to Dynamic EFL.

Wish me luck.