Ad-hoc Dating App (Using Heroku Django Stack)
In which I try to recreate a cool piece of software from my web administrator years in college that provided simple, user-anonymous, peer-to-peer dating/connection service for seniors during the brief interim between exams and graduation.
A Bit of Background
During college, I was on the administrative board for a student volunteer-run organization called Williams Students Online (WSO). Among other things, one of the tasks that fell to me as I became more experienced within the organization was to maintain certain portions of the website. One of those pieces of software was called EphCatch, which was a simple Rails/MySQL application that provided a dating service for seniors during the two weeks between exams and graduation.
This application was about as simple as the original designers could make it when they wrote the code in 2006. Largely due to the simplicity of debugging a two-file Rails application on an already-running Linux/Apache stack, EphCatch survived in its original form until it was rewritten in 2014-15.
Perhaps "dating service" is an incorrect term, since the tool was so simple. At its most basic level, EphCatch as I knew it was composed of two database tables: People and Picks. 'People' was a database of users with attributes lifted directly from the WSO facebook database including, among other fields,
pick fields. The main (and only) page view for users was a list of the full names of the 550 or so students in the class accompanied by a facebook headshot image and a checkbox, and at the bottom, a Submit button.
The process to recreate such a simple tool was therefore only made difficult by the fact that I had to develop a part of the platform it would be hosted on as well as the application itself, or so I thought. Because I did not have my own dedicated hardware for a public application that may be required to handle mid-100s of requests per minute, I opted for Heroku, a Salesforce product that provides a versatile and easy-to-use hosting framework to developers for free. (Scaling an app to use more processing power and RAM is pay-per, which is how the basic developer hosting is kept free). To me, the most impressive parts of Heroku are 1) how easily it scales and 2) how quickly it spins up Git data into a fully-functional web application. I'm sure it's even more impressive working with Rails sites, since that was Heroku's first supported framework (and that's what Heroku itself is built on), but in my experience it's been pretty good with Python/Django too.
Heroku is extremely well-documented, so I will not get into any setup specifics. All I'll say is this: I had worked mostly with Rails in college, and only worked with Django peripherally. So this was my first experience really diving into writing anything larger than troubleshooting a page in Django. Working with Heroku could not have been more helpful and satisfying as I learned a new framework. I was expecting bedlam, stress, tearing out my hair, and worse. Hell, that's why I started writing this application two years before reunion even started. But there is nothing bad to say about it. I even upgraded ReunionCatch to Heroku's paid tier because I liked working with it so much. That, and the fact that I wanted to be able to have visitors click on a link to the site and not have to wait for the ~10 second spin-up time of the dyno. Besides, when I think of all of the things Williams gave me, heck yeah I'm going to pay 7 dollars a month to keep this site up.
Moving right along...
The mission statement of this effort is simple: "Connect classmates." The more specific goal of this project was to recreate EphCatch for reuniongoers.
My whole motivation in doing this is to connect people. In person. Forget web chat. The opportunity is this: a whole bunch of classmates are converging on one site at one time. It's a bit like Senior Week. After exams finish, everyone comes out of the woodwork and actually hangs out with each other. No longer valid is the excuse to do work with Facebook chat open in one browser tab. Having worked at the event for five years in a row before and during college, Williams Reunion is a time to gather and celebrate the college and each other, like Senior Week, that (eventually) starts to try and work the family angle too. This is your chance to come and talk to people! They've missed you!
That is the space in which EphCatch—and by proxy ReunionCatch—is designed to operate: connecting people and then stepping back to let them talk to each other.
I am not a matchmaker, and I don't really have much interest in becoming one. But Reunion, especially 5-year Reunion, is a brilliant matchmaking opportunity, made possible by several things.
- Williams people! All in one place at once! How we've missed each other!
- People at 5-year reunions are still in their twenties; all marriage statistics and partying habits implied therein.
- It's a relatively safe environment. Lots of friends are around, Security is out and about, and you're in Williamstown. Do not take this the wrong way, one should always be careful. But this isn't your average bar in New York.
- The "all my friends are getting married" hype train has begun to depart the station.
- There's usually an event called Reunion Fridays in Goodrich. This shouldn't need an explanation.
ReunionCatch seeks to remind people that they should be excited about seeing their classmates in person. So once the matches are made, it's really up to the users to connect with each other. If this app is to be successful, it must rely on the opportunities presented by Reunion, and not force anything. First and foremost to support that idea is that people will be together in one place, so after the initial match, ReunionCatch will do as EphCatch did: let them find each other on their own. The point of having a Reunion is to forget about work: talk to your friends, make new friends, and have a good time. ReunionCatch should exist, but be as separate as possible from Reunion. Reunion's intended face time should not be stolen by ReunionCatch screen time. The way I tried to write it, ReunionCatch should be no more than picking and the subsequent notification service.
Having said that, of course, I do think that the statistics of all of this will be really cool. So, at risk of providing something antithetical to the previous statement, I opted to have a time-based statistics page, and a built-in stats collection function that runs every x minutes. Yes, I know...I'm undermining the face time/screen time argument. My only defense is this: I figure if ReunionCatch is popular enough, the statistics give nerds like myself, who may find themselves struggling to find a topic, something to talk about. Hey, it's my app!
And that, as they say, is what it's all about.
Development: The Negatives
I have heard it said (in quite different words, mind you) that a good Django site designed to essentially be a free-standing entity with a conglomeration of different tools all contributing something extra to that entity. Each additional tool that's separate from the main Django stack is intended to do one thing well (maybe two), and if you think a third thing needs to be done by that tool, it's probably best to just create a new tool to handle that other thing. Thus, the concept of "apps" in your main Django folder.
Unfortunately, I misunderstood that when I started mapping out the work it would take to make this project successful. So while it wasn't exactly bedlam, my writing process did run into some bloating issues in the main ReunionCatch app's files. Nothing too bad, just a lot of functions that, if I were to rewrite them now, would end up in separate conglomerate apps in a more 'horizontal' structure. You'll notice if you end up looking through the GitHub project that the
apps/pycupid folder is pretty crowded. Whoops. My excuse is that as this was my first ground-up application, and I didn't know any better.
Seriously though, upon beginning the development process I thought the 'one thing' ReunionCatch did was complete the mission of the project: "Connect classmates." Instead of being multiple services, it is one, with different functions inside the main app to achieve different parts of the mission. That's the goal, right? Well, kinda. Turns out I misunderstood the philosophy slightly. It wasn't until I stumbled upon a very well-written StackOverflow answer talking about the way Django software was intended to be written that I really got it. The project's goal should be the mission. The app's goal inside the project is to do one or two very specific things related to that mission. For example: "Verify user email validity, and assign username and password" would be two features in one app called
verify. User profiles would be handled by the
profile app, statistics would be handled by the
statistics app, and so on. They'd all refer back to the main app. Understanding this would've made a lot of things easier for me, but I acknowledge that the learning experience was valuable as well.
One other thing I would have changed were I to write it again would be to get rid of the
apps/ folder containing other apps. I know some people like to do it this way, and I respect that. I was all about the idea at first, since it meshes nicely with my organizational style. However, having tried it, I find that having to fool around with Django settings simply to be able to call another app in the folder is cumbersome and introduces a much larger potential for weird errors and quirks to bother. By the time I figured this out, though, I was too far into the development process to change without introducing a whole new level of stress and error. Like I said: I'm sure it works for some, but I haven't found a way that it works for me yet.
Development: The Positives
I've loved Python since the very first time I first touched it in college. I didn't learn it in a classroom. My introduction to Python was slightly unorthodox; I was a guy who learned Python because it was featured so prominently in ArcGIS workflows. After finding that it was just as easy, useful, and good looking as the Ruby I had learned for WSO, I began to use it more and more to make my GIS data processing more powerful and customized. I had heard that Python was the language of choice for scientists, and as someone who wasn't a CS major by nature, I liked it for its readability and consistency of formatting. All of these are reasons that, several years later, I opted for Django over something I already knew a decent amount about about like Rails. (Although I will add my voice to the throng in saying that Ruby-on-Rails is a very aesthetically pleasing language-environment pairing.)
Given that this was my first big Django project with a fair amount of moving parts, I'm pleased that there even were positives. There were many.
- I have made a working, standalone clone of EphCatch in well under two years. (yay, me!)
- ReunionCatch is orders of magnitude faster than EphCatch was.
- I learned to really like how Django treats models, which I didn't 100% understand the first time I encountered them.
- Working with the Django User model is awesome and I didn't expect it to be.
- Passing (multiple, potentially large) sets of data from Models through Views to Templates is simple, fast, and intuitive. Side note: dictionaries are great.
And I think I'll add a coule more because I can't overstate how significant a part of my development and debugging processes they were...
I had originally intended to write a longer post describing the process behind ReunionCatch. I still intend to do that, eventually. However given that at the moment my life is a whirlwind of work and grad school application prep work, I will summarize first and return to expand on the post later (at which point, I will be relying largely on code review and comment lines I've left for myself, so...yikes).
ReunionCatch was a huge project for me, and one that I poured most of my free time into during development. There were a lot of dead ends initially as I felt my way around Django and reacquainted myself with Python. It was painful and yet the satisfaction at creating successes and realizing potential was immense. It was everything that one expects learning a challenging new skill to be. And in learning it, I created something useful, so the satisfaction at having built something worthwhile was likewise incredible. I have to thank Django Girls and Stack Overflow. They were absolutely incredible resources, and I highly recommend them.