Projects

Reddit Insight Logo

Reddit Insight: My Hack Reactor group project was featured on TechCrunch

About three weeks ago, we started our group project sprint at Hack Reactor. The class broke up into teams of 4-5 students to work on a large project of our choosing, that would showcase our full-stack development skills. I was part of a team consisting of Patrick, Elle, Alex, and Bill, and we formed an idea to create an analytics suite for Reddit.com.

Our project is called Reddit Insight, and we launched our first version of the site 5 days ago. In that time, quite a lot has happened, and 100,000+ people (and counting!) have visited the site. The highlight of this experience so far is having TechCrunch pick up on the story and invite us to their offices to do an interview about our work.

Check out Elle and Alex on TechCrunch TV!

When we set out to create Reddit Insight, our goal was to create an app that would be interesting to the Reddit community, and would hopefully gain some traction. We also wanted to build an interesting app that would be exciting to talk about with future employers during job interviews.

Our first course of action with this project was to silo responsibilities, and then start working on the app framework. I decided to tackle the front-end MVC structure with Patrick, because that required extending skills I already had surrounding Backbone routers and controllers. We decided on a single-page structure, with dynamic views that would be shown/hidden based on the user navigation.

To help keep everything organized, we created a controller, which is typically not found in a Backbone application. We also created a global object with name-spacing, so that modules could be re-used throughout all areas of the application. We called this global object Redd, and we extended all of the Backbone events to this object, so that we could listen to all events from everywhere in the app. Some example app structure code:

//global Redd object
var Redd = _.extend({
  Views: {},
  Models: {},
  Collections: {},
  Templates: {},
  Controller: {},
  Router: {},
  d3: {},
  initialize: function() {
    Backbone.history.start();
    //more code here...
  }
}, Backbone.Events);

//part of the controller file
Redd.Controller = Backbone.Controller.extend({
  initialize: function() {
    this.navbar    = new Redd.Views.Navbar();
    this.header    = new Redd.Views.Header();
    //more instantiations here...
  }
});

While Patrick and I were building the client-side framework, Alex and Bill were busy using Reddit’s API to download over 240,000 posts and over 200,000 SubReddits worth of data. Once we had that data in our Mongo database, they starting using Python machine-learning scripts to analyze specific segments of the data to find interesting facts that Elle could model using a d3 graphing library.

After two weeks of working on this project, we had a working prototype to show to our classmates and instructors on presentation day. We made our index page an animated info-graphic, which worked well for large-screen presentations. We had also implemented real-time performance graphing of a specific post on Reddit, thanks to Elle’s work with dynamic d3 charts.

Last Saturday, we officially launched an unfinished version of the site on the r/JavaScript SubReddit to get some early feedback. The results were not good. Most users did not like our animated info-graphic, and the site completely broke for mobile users. Users on Reddit also complained of a bad navigation experience, and pointed out a few bugs in different areas of the site. This was exactly the feedback we were looking for.

All along, our instructors had been telling us to cut all features, and to get our app to market as quickly as possible. Having an unfinished website go live to a small set of users is way more valuable than waiting to launch until you think everything has been perfected. It is better to fail fast, then refactor, than to spend a lot of time building features that the public may not even like or use.

I took the user feedback we received to heart, and I completely refactored the homepage and navigation on Sunday. I made the site mobile friendly using a responsive grid, and I created much clearer calls to action and feature lists on the homepage. The site was now ready for the spotlight.

On Monday morning we posted a link to Reddit Insight on the SubReddit r/Technology, which was the section of Reddit we had identified as having a higher positive feedback rate than any other SubReddit. The user feedback was immense and immediate. As our post climbed higher and higher on Reddit, the number of users on Reddit Insight kept growing. Eventually, we got all the way up to the #4 post on Reddit Technology:

Reddit Insight on Reddit Technology

This is about when things started to get crazy. Gregg Finn, who writes for a marketing website called Marketing Land, saw our post on Reddit and wrote a blog post about us. He then sent it out to their 40k+ followers. This post was quickly picked up by Google Analytics, who sent it out to their 270,000 followers:

Google Analytics Reddit Insight

From that tweet, Reddit Insight exploded within the marketing community. We were re-tweeted and blogged about all over the world. Our traffic load started to strain our Heroku server, so we had to add 2 additional worker dynos to help with all of the traffic.

Our app really struck a chord with the professional marketing community. There seems to be a great need for a brand awareness and analytics tool for the black box that is Reddit. If we were to move forward with this project, I believe we could focus on the marketing community, and make a tool for them that could be monetized.

Reddit Insight concurrent users

536 active users on Reddit Insight at one time!

Our press coverage reached it peak when we were invited to the TechCrunch offices to do a video interview about Reddit Insight! We couldn’t believe it. They would only let 2 of us on camera, so we used the JavaScript random number generator to decide who would get the opportunity. Alex and Elle got lucky at the right time, and they ended up doing the interview with Colleen Taylor of TechCrunch TV. The TechCrunch team was great, and they really took the time to learn everything about our project and Hack Reactor.

reddit_insight_tech_crunch_tv_01

On set at TechCrunch TV

reddit_insight_tech_crunch_tv_02

L to R: Patrick, myself, Elle, our mentor Larry, Alex, Bill

The TechCrunch article came out yesterday afternoon, and we experienced another traffic spike while we were at the top of their homepage. The spike was not as large as on Monday, when we were at the top of r/Technology on Reddit, but the traffic from TechCrunch stayed on our site almost 4 times longer and was much more engaged with the content.

All of this has been an incredible experience in full-stack app development, marketing and launch promotion, and dealing with scaling issues. It is incredibly satisfying to have something you build be accepted and praised by the community you built it for. Reddit Insight has been used by over 100k people in 156 countries around the world in only 5 days! That right there is what is so incredible about being able to build things for the web. There simply is no other medium in which you can reach that many people, in such diverse areas of the planet, so quickly.

A few of the websites that covered Reddit Insight:
Tech Crunch
Marketing Land
Digital Trends
SocialTimes
The Slanted
DailyJS
PRWeb
Reddit – r/Technology Comments

We have a few more media interviews scheduled, so look for this list to be updated soon.

reddit-insight-team-hack-reactor

Check out RedditInsight.com or view the open-source code on GitHub.

Read more

Link ThreeSix – A Logic Game, Written in JavaScript

I have been working on a game called Link ThreeSix for a few weeks now. This is a personal project I built in my free time during lunch and after class at Hack Reactor ends for the day. It’s a challenging, strategy game to play against another person, and I have yet to figure out the optimal way to play it. There are distinct strategies for playing offensive or defensive, and I have mixed results with both.

This project originally started in the classroom at Hack Reactor, when our instructors gave us two days for a “make-up sprint”. These two days were set aside to let us catch up on any topics we felt like we needed more time with. I decided to jump into Backbone.js again to see if building some simple apps would help me learn this JavaScript library a little better. I originally set out to make a simple tic-tac-toe game, and I had a working prototype built in the first 6 hours. I had learned more about Backbone, but now I wanted to take the project further.

Once I had the tic-tac-toe scaffolding built, I began to think of ways to expand this project into a game that I would actually want to play. I started by increasing the board size to 6 x 6 squares. With a board this size, the typical tic-tac-toe rules do not work well, as it is trivial to block your opponent from scoring.

We had recently finished the N-Queens algorithm sprint, and I was interested in exploring this problem further. It made sense to apply similar scoring to my 6×6 board, and so Link ThreeSix was born.

Link ThreeSix

In this game, each player takes turns placing their mark on a single board square, until the board is filled. Your objective is to make links of 3 in a row, or more. Links can be made horizontally, vertically, or diagonally. The game is scored in real time, after every move, and the Game Score board highlights the current game leader.

Scoring is as follows:
3 in a row: 1 point
4 in a row: 3 points
5 in a row: 10 points
6 in a row: 20 points

After each game, the Total Wins board updates to reflect the winner of the current game, and keeps track of the entire match. The first player to win 3 single games, wins the match!

Once I had built out my application architecture using Backbone’s MVP, the biggest challenge of this project was to correctly score each player’s points, as they create connections of 3 or more in any direction. I began by creating two-dimensional arrays for each player, with numerical values representing the position of their marks on the board. These two-dimensional arrays make it easier to keep track of diagonal scores, which are the hardest to solve with an algorithm.

I used Backbone’s built in event listeners to detect when a player makes a move, and then I ran the scoring algorithm for that particular player. This scoring function checks every corresponding row, column, and diagonal for that player, after every move. The hard part was first checking for connections of six, then five, then four, then three in each possible scenario, for each direction, and then breaking out of that function for that particular line and direction once a match was found. However, all of the other lines and directions still have to be checked at that point, because many moves score points in multiple directions.

This scoring function proved to be much more complicated that I originally thought it would be, which is what kept me hacking away at this project in my free time. I would spend a few hours one day making significant progress, then get stuck on an issue. I would usually think of the solution at a random time a day or two later, and I would come back to the code to make more progress.

This game currently only supports 2 player mode, with both players on the same computer. I want to eventually incorporate the Facebook OAuth login with a Node server, to allow players to compete on separate computers from different locations.

I also plan on developing a computer opponent AI to enable single player mode. This will definitely be the next branch of this project, and I plan on learning all about game AI in the process. It would be great to develop the optimal strategy for this game, explore the computer decision tree, and to set up multiple difficulty levels. However, with all of the other projects I am working on, along with my upcoming job search, this will probably have to wait a while.

Let me know what you think about Link ThreeSix! It is open source on GitHub, so feel free to post any issues you find, or fork it on your local machine. I would also be interested in talking with anyone that has experience with programming game logic, or anyone that wants to help with coming up with an optimal strategy to play this game.

Read more

A One-Day Sprint with Backbone.js – Backbone Solitaire

Today we took a break from the regularly scheduled sprints. The idea was to focus on a topic you wanted to spend more time with, and to come up with an app idea you could implement quickly. This was a good exercise in project management, along with testing how much of a skill you could put into an app on your own.

I decided to build a simple solitaire game using the Backbone.js MVC framework I talk about in my Hack Reactor Week 3 blog post, along with CoffeeScript. I already had working deck-shuffling code that I could use from the blackjack game we built, so I figured it wouldn’t take too long to translate that into a new card game. I was definitely mistaken about this.

I started the project with a whiteboard session to draw up the game layout and initial deal of all the cards. This would help break up the app into smaller chunks that could be translated in the different models and views. I then sketched out all of the individual modules and organized them into their Backbone components. I ended up creating the following models and collections: Card, Deck, Column, GameBoard, and Game. I also created corresponding views for each of these modules.

Backbone-Solitaire

Rough styling of my solitaire views. Only the column and deck models have live data at this time.

 

Building a Backbone app from scratch was the biggest challenge of my day today. Laying out all of these models, collections, and views, and then making sure they can all talk to each other took much longer than I anticipated. Backbone takes a pretty big commitment of code before you can start to see your data rendered to the screen. I also spend lots of time in the Chrome JavaScript console to make sure all of my model data was in the correct place for each object.

After spending too much time diving into the details of Backbone, CJ came over to my workstation to see how things were coming along. I didn’t have much on the screen at this point, so he advised me to focus on the most simple task I could and completely get that model and view completed as my first deliverable. I decided to focus on the initial deal of the 28 cards in the main game board. This required focusing further on each individual column, and building a column model to grab the corresponding cards from the deck collection. I made some good progress once I was focused on this particular module.

Before I knew it, everyone was leaving for dinner break and I had just moved on to building the view for the 24 remaining cards in the deck after the initial board setup. This is when I realized that the project was going to take me quite a bit more time to complete, and I had been too ambitious in my project planning from the start. I should have chosen a much simpler concept, rather than a card game with complicated logic and drag-and-drop functionality. I will definitely remember this lesson when it comes to planning future projects.

My main takeaways from today:

  • Focus on the most simple version of a project.
  • A first build of an app is best accomplished by removing all features
  • Focus on small deliverables so you always have working code to commit every few hours or every day

Today was the first time we had been released on our own, to create a project from scratch. I was pleased with what I learned about Backbone.js, but I need to be less ambitious with my one-day goals at this point in my career. Hopefully I can find some time to work on this project more in the future!

I pushed my initial code to GitHub if you want to check it out, but it is most definitely a work in progress.

Read more

N-Queens, Algorithms, REST, and Ajax – Hack Reactor Week 2

inside Hack Reactor

Inside Hack Reactor

 

Week 2 at Hack Reactor has come to a close, but the frantic pace of learning continues. We kicked off week 2 by finishing up our Sub-Class and OOP sprint that involved making individual nodes “dance” on the page with any random behaviors we decided to give them. What we ended up with were fancy screen savers with objects that could interact with each other (and explode!). This led us to a discussion of particle systems, which sounds like something I want to devote some time to once this course is over.

We had another guest lecture at the beginning of the week regarding algorithms, complexity analysis, and ways to approach solving interview problems. Solving complex problems like this while under pressure is a skill I need to work on, but luckily there are a few great online resources to help build your skills. Some of my favorites that I’ve used so far are:
Project Euler
Coderbyte
TopCoder Algorithm Tutorials

Our discussion of algorithms led us into our next project, and my favorite project of the week, called N-Queens. This goal of this project is to find how many ways n queen chess pieces can fit on an nxn chessboard without being able to attack each other. So, if you have a 4×4 chessboard, how many different ways can you fit 4 queen chess pieces on the board so that all 4 queens are safe from being attacked by the other queens? The answer for the 4×4 board is 2 different arrangements of queens. For a more in-depth explanation, check out the wikipedia entryfor the 8 queens solution.

Currently, the largest board that all solutions have been found for is a 26×26 board. At this time, 27×27 is too large of a solution to be handled by today’s computer processors with the current algorithms. However, some students in the senior Hack Reactor class are tackling this problem with an app called supercomputer.js that leverages many networked computers, each solving a small portion of the entire algorithm (similar to the Playstation 3 Folding@Home project out of Stanford).

We spent much of the first day building a JavaScript algorithm for finding single solutions to this problem, and testing it on small chess boards (less than 8×8). We ran through a series of tests written in Jasmine to ultimately come to an algorithm that would successfully find every solution for a given n. However, our first attempt was a brute-force solutions that used 2-dimensional arrays to build every possible configuration of n queens on the board. We then tested every one of these board layouts to determine if it was a valid arrangement where the queens couldn’t attack one another. The boards that passed our test were put into a results array, and then counted. This solutions was very inefficient and took a tremendous amount of computer processing power to complete. This first attempt could not find a solution to any n over 7, because the browser would time out before the JavaScript was done running.

Now that our algorithm was finding all of the correct solutions, it was time to optimize it so that we could find solutions to chess boards above 8×8. Our first optimization involved making our tests for evaluating correct boards more efficient. With these improvements, we were able to find all 92 solutions to n=8 in just over 20 seconds on a Mac mini. From there, we decided to trim down the number of chess boards our algorithm generated.

Instead of creating a large tree data structure of all possible solutions, we started checking early on in the board building process if the piece we just placed was in conflict. So, once we placed a queen on the first row, we knew no other queens could be placed on that row, thus moving on to second row right away. We also knew that the first queen placed on the second row cannot be placed in the same column as the piece on the first row, thus “pruning” our data tree of all possible iterations below that conflicting node. We also checked for diagonal conflicts before placing each piece. The result of this “pruning” was allowing our algorithm to find all solutions on an 8×8 board in about 2.5 seconds!

We were pretty excited about our 10x improvement in speed, but we decided to see if we could make it even faster. Up until this point we represented our solutions using 2-dimensional arrays, which take a lot of iterations to traverse all of the elements. We decided to represent our boards using a simple 1-dimensional array instead. For example, a 3×3 array normally looks like [[1,0,0],[0,1,0],[0,0,1], with the 1 representing a queen (not an actual solution obviously). Instead, we can represent this same array with [0,1,2] , with each index of the array representing a row, and the value of that index representing where in that row the queen is located. Once we implemented this new storage mechanism, our time for finding the n=8 solution was reduced to 49 milliseconds! It was very satisfying to see such huge speed gains from each improvement we made in our code. Here is our final JavaScript solution:

window.countNQueensSolutions = function(n){
  var startTime = new Date();
  if (n===0){return 1;} //0 queens fit on a 0x0 board 1 time
  var solutionCount = 0;
  var rNQueens = function(tempBoard){
    if(tempBoard.length === n){
      checkQueenSolution(tempBoard) && solutionCount++;
      return;
    }
    for(var i = 0; i < n; i++){
      var boardCheck = tempBoard.concat(i);
      if (checkQueenSolution(boardCheck)){
        rNQueens(boardCheck);
      } else {
        continue;
      }
    }
  };
  rNQueens([]);
  var endTime = new Date();
  console.log('Number of solutions for ' + n + ' queens:', solutionCount, 'in', endTime - startTime, 'milliseconds');
  return solutionCount;
};

window.checkRookSolution = function(matrix) {
  return _.uniq(matrix).length !== matrix.length ? false : true;
};

window.checkQueenSolution = function(matrix) {
  if(!checkRookSolution(matrix)){
    return false;
  }
  for(var i = 0; i < matrix.length; i++){
    for(var j = i+1; j < matrix.length; j++){
      if(i - j === matrix[i] - matrix[j] || i - j === -matrix[i] + matrix[j]){
        return false;
      }
    }
  }
  return true;
};

The remainder of week 2 was spent learning about HTTP requests, REST, and how to use Ajax with the service from Parse. We lumped this all together to create a real-time chat room client that all of the Hack Reactor students could use. Once everyone was up and running with the chat client, we implemented features like preventing script attack hacks, creating friends lists, and allowing the user to create and join new chat rooms.

This week was intense, but the instructors are warning us about the start of week 3, which involves us diving into Backbone.js. I’m running through some Codeschool tutorials on Backbone right now to get prepared for next week!

Read more