Adventures Into Code

3 months at The Flatiron School, NYC

Durham to NYC to SF

Flatiron wrapped up late April and the past couple of weeks have been a crazy mix of coffee shop meetings, working on side projects, interviewing, and spending too much time in email. Since graduating, I’ve been looking at two different options for my next step: 1. Find a junior ruby dev position to solidify what I’ve learned and keep building out my dev chops. 2. Find a co-founding role with a team looking for a utility player…and keep building out my dev chops.

To cut right to it, I’ll be joining Scott and Steve Klein to co-found statuspage.io.

You may be able to guess what the company does by it’s name, but think status pages as a service. Every top tech company (Amazon/Twitter/Facebook/Github…etc) has a status page for the developers building ontop of their platforms to keep up to date with the status of their servers, errors, uptime, and other metrics. Here’s a great example from Github. Following after these tech giants, many smaller software companies are building their own status pages for their own developers as well as customers/users.The goal is to take over this emerging market and become the go-to tool for companies’ status pages.

Backstory

Just getting into the Durham startup scene about two years ago, I would regularly schedule coffee with entrepreneuers and other people working for startups, including Scott. He had recently sold his first company to ReverbNation and we took the time to pass ideas back and forth as well as chat about the company he was currently working on. I remember leaving that meeting thinking, “This is a smart guy. We should stay in touch.”

Fast forward a couple years and we reconnected just as StatusPage was interviewing for Y Combinator.

After being accepted to YC, a badge of honor in itself, we decided to have a few more serious conversations and Scott pulled in his co-founder and brother, Steve.

When deciding to bring on another co-founder or join as a co-founder yourself, there is a bit of a dance that takes place. Each side needs to figure out what the other side can bring to the table. Each side also needs to figure out if they personally like the other side. It turned out that Scott and Steve were looking for a generalist co-founder. Someone who could build a sales process, crank out content marketing, ship code, and whatever else needs to get done when you start a company. Thankfully, that’s exactly what I was looking for in a co-founding role.

Why I’m Joining

A while back I wrote a post on how to choose the right startup as an early employee. While there are some additional questions to consider when potentially joining as a co-founder, I tried to ask myself and Scott/Steve most of these questions.

Team

The most important part. Scott and Steve are awesome guys, incredibly smart, and top notch developers.

Problem/Market

The intersection of backend technology, support, and marketing is an emerging market and in my opinion, there will be big winners. Companies that are transparent and open with their user bases will edge out those that are not.

Also, we’re not inventing this concept. Companies are already building out status pages. I see a big opportunity if we can build a product that a) saves them the hassle of building their own from scratch, b) integrates out of the box with other systems such as New Relic and Pingdom, c) displays custom metrics as a support, marketing, or sales tool.

Solution

I signed up for a free trial and the product was easy to use and coherent. I received a series of emails from their free trial drip campaign, a sign that these guys have thought through the process of what it takes to get someone from a free trial to a paying customer.

In addition, 17 customers are already paying for the product such as Shopify, Zendesk, Travis CI, and Spreedly.

My Role

Over the past 3 months I’ve come to love building things with code. I told Scott that if he was just looking for someone to take over sales, then I’m not the right guy. Instead, I received this note in an email: “Most importantly: tell us what you need and when you need it and we’ll do our best to make sure everyone is having a blast. When we stop having fun the company will die, so don’t feel like you are forced into working only on sales because that’s what you know. I want you to become the best developer you’ve ever known, and if it means you banging your head against the wall for 12 weeks, then let’s do that.”

Do I expect to be coding the entire time during YC? Most likely not. I’m looking forward to doing a mix of everything from bringing new customers on board, figuring out the right products to build, and cap deploying. But, the decision to join was an easy one after reading that note.

What’s next?

I’m moving to the bay area late May to attend YC with the company and couldn’t be more excited for the whirlwind that is the next 3 months.

A couple last words

Meet people. You never know when a 45 minute coffee shop meeting from way back when can lead to your next opportunity.

Stealing this one from Avi, but for upcoming Flatiron students, blog blog blog. Every important conversation I’ve had with companies over the past couple of weeks has included a conversation about problems I’ve had fun solving and code that I’m proud of. It’s been incredibly helpful to follow up and point to a blog post you have written.

That’s all for now!

Building API Wrappers for Your Application

First, the boiler plate for Starboard, one of my Flatiron School projects:

What is it?

A modern-take on an old fashioned gold star board.

Why does it matter?

The Flatiron School is hard. Throughout the semester students are learning new material, working on github projects, writing blog posts, completing online coding tutorials, and much more. Without having much time to realize how much has been accomplished, Starboard becomes the hub to track all of their achievements. From completing Codeschool courses, to committing to an open source project, to giving someone else a star for help with a bug fix, Starboard is an app to collectively celebrate learning to code.

One of my favorite problems to solve when building the application was how to normalize data (creating user achievements) for actions taken on other websites such as completing a Codeschool course or making a commit to an opensource project. The complete gist is below.

Each service we used would return a uniquely formatted set of data. Treehouse and Codeschool also have 0 documentation for their APIs. Figuring out how to manipulate these different data sets was the engine driving our application. Here are the steps I suggest you take when building API wrappers:

Explore the API in your browser

Without writing a line of code, read the documentation (if there is any) and ask for json objects back. For Codeschool, all that was required was a json get request for a user profile’s information: http://www.codeschool.com/users/dolinsky.json

Play with the data in console

Using the json and open-uri gems, test manipulating the data in console. How is the json structured? What keys do you need to chain together in order to get to the values you are looking for? In our case, we were looking for the ‘title’ of the ‘completed’ ‘courses’.

Decide on your output structure

Once you have a solid understanding of what you can get back from each API, begin to think through how you can normalize the data to use in your own application and save to your database. For instance, would a hash work best with sets of key/value pairs or a simpler array? We decided that an array would be best for us. At this point, all we knew was that each wrapper (Codeschool, Treehouse, Github, Blog) would need to return an array of strings. As an example, Codeschool could return [“Rails for Zombies”, “Ruby Bits”], while Github could return [“Committed to an open source project”, “Had a repo forked”]. The individual wrappers will contain their own methods for getting us to the final array, but in the end, an array will be needed.

Normalize methods

Before an array is returned from a wrapper, a method needs to be called to ask for data from an API. As you can see in the gist below, each of our wrappers has the ‘get_data’ method. So, we could call things like Treehouse.get_data(username) or Blog.get_data(blog_url). Test the method by itself. Write additional methods needed within the wrapper’s class to help you manipulate the data for your application. For example, Codeschool.get_data creates a hash from the json returned and then calls the get_completed_courses method to iterate through the hash and return an array of completed courses.

Here’s our get_data method for Codeschool:

1
2
3
4
5
6
7
8
9
10
11
12
13
def get_data(username)
    cs_json = self.class.get("http://codeschool.com/users/#{username}.json")
    case cs_json.code
      when 200
        self.get_completed_courses(cs_json)
      when 404
        p "Codeschool username not found - #{username}"
        return nil
      when 500..600
        p "ERROR Pulling from Codeschool #{response.code}"
        return nil
    end
end

Create services hash

After creation of a user, we call user.get_external_data in ther user model. This method contains a hash of service => identifier

1
2
3
4
5
6
7
8
9
 def get_external_data
    external_services =
    {
      'Treehouse' => self.treehouse_username,
      'Codeschool' => self.codeschool_username,
      'Github' => self.github_username,
      'Blog' => self.id
    }
 end

Call individual wrappers

Once you have your hash, iterate through it, calling your predefined get_data methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
  def get_external_data
    external_services =
    {
      'Treehouse' => self.treehouse_username,
      'Codeschool' => self.codeschool_username,
      'Github' => self.github_username,
      'Blog' => self.id
    }

    external_services.each do |service, identifier|
      array = service.classify.constantize.get_data(identifier)
    end
 end

Save your data

Now comes the fun part. We have the data needed stored in arrays for each service and we can begin storing the data how we see fit in our application. In our case, we created a method called check_achievement_by_array.

1
2
3
4
5
6
7
8
def get_external_data
  ...

  external_services.each do |service, identifier|
    array = service.classify.constantize.get_data(identifier)
    check_achievements_by_array(array)
  end
end

You’ll see that the code looks slightly different in the gist below, but don’t worry about that. We are using Sidekiq to offload these API calls to a background service (another blog post to come). You can make these API calls work without Sidekiq.

For each element in the returned array, we then call check_achievement_by_string. We are essentially checking to see if we have the given star in our database already, if that user already has that star, and if not, create the ‘achievement’ for that user.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def check_achievement_by_string(string, source_string)
  source = Source.where(:name => source_string).first
  star = Star.where(:name => string, :source_id => source.id).first_or_create
  if source.name == 'Blog'
    self.achievements.create(:star_id => star.id)
  else
    unless self.star_ids.include? star.id
      self.achievements.create(:star_id => star.id)
    end
  end
end

def check_achievements_by_array(array, source_string)
  if array
    array.each do |item|
      self.check_achievement_by_string(item, source_string)
    end
  end
end

Check your database

Does your data look the way you want it to look? Is it there? It may not be. We fixed many bugs along the way to actually getting our wrappers to work. Whether it’s the data itself, the way you are manipulating it, or an error from the API, you will need to work through these bugs to eventually store the data you need. But, it’s worth it.

I hope this helps as an example for those who are depending on mulitiple API’s to drive their own application. Feel free to comment below with other suggestions!

Code and the Learning Curve

1 to 50. One of the simplest, but most addicting apps out there. A couple students told me about the game a few weeks back and ever since it has become my go-to for killing time on the subway. The concept is simple: find and click the numbers on the grid in order from 1 to 50 as fast as possible.

My first few results were quite bad. 50 seconds. 48 seconds. 47 seconds. However, without consciously trying, my brain quickly adapted to the task at hand. It began looking for patterns, seeking the fastest way to complete the puzzle based on my prior experience. My eyes began to scan the complete grid instead of looking and pecking for individual numbers. Groups of numbers started appearing and within 10 tries I had cut my time average time down to 34 seconds. Unfortunately, I’ve now had the app for two weeks and can’t seem to beat my high score from a week ago of 26 seconds.

What happened? Why can’t I keep learning at the same pace? Turns out, 1 to 50 follows Hermann Ebbinghaus’ learning curve.

1 to 50 is a simple a simple skill. I learned most of what I could learn in a short period of time and have asymptoted out.

How does this apply at all to code?

At first, I came to the conclusion that code follows a similiar learning curve. A beginner coder is a sponge ready to absorb and retain all information thrown his or her way. Wrong. Coding follows the S-Curve.

In this situation, learning starts off slowly and once a foundation is built, begins to increase rapidly. I’d guess that this is the exact reason why Flatiron assigns 100 hours of pre-work before the program starts. It takes time to prep your brain for learning how to code. However, once you make your way out of the weeds, the pieces begin to fall into place. As with 1 to 50, your brain subconsciously looks for, detects, and provides meaning to patterns based on past experiences.

Steve Klabnik alluded to this concept when he came in to speak to the class. While I don’t remember the exact quote, it went something like, “The difference between beginner coders and advanced coders is their ability to spot patterns.”

This idea rang true for me over the weekend. I’ve been building an online coding activity tracker with my group over the past few weeks. The app let’s you track your own progress as well as compare yourself to students in your class. Building the intial database schema along with the ability for users to create/join classes took a couple days. It was our first real foray into rails. Here’s a shot three weeks in. Props to Tyler Davis for the awesome design.

Fast forward to this past weekend when myself and two other students decided to start on a hackathon organizer and listings app called Codewithus. Although the tables are named differently, the basic functionality of being able to create a hackathon, invite people to the hackathon, and join other hackathons is the same. Instead of a day to discuss and build the database schema, it took us 45 minutes. Instead of a day to build out the initial views and the basic functionality, it took us 2 hours (excuse my minimal design skills). Stepping back from the project, I’ve realized just how much myself and the rest of the class has learned in a short time period.

While there’s a never ending amount amount of articles to read, languages to learn, and features to implement, it feels good to know we’re climbing up the curve.

Making a Simple Rake Task

Last week, we began our group projects at the school. From here on out we’ll be building everyday, allday. My group is working on Starboard, an online coding activity tracker. At its core, you earn achievements for different activities such as writing blog posts, commiting to open source projects on Github, and earning badges on Codeschool/Treehouse. To picture the concept, think of the charts when you were a kid at school and your teachers gave you those gold star stickers for doing good things. You were able to not only see your stars, but also how you compared to your fellow students. Similiarly, future Flatiron students will be able to track their coding activities and see how they stack up to the rest of the class.

Why is a rake task needed?

The main data engine driving Starboard is the wrapper we’ve built to extract information from our sources (currently Github, Treehouse, Codeschool, your blog). Stay tuned for another blog post on how we did this. When you first sign-up, you’ll be prompted to enter in your usernames/urls, so that we can go out and populate your profile with current achievements. We’ll be vastly improving the interface, but here’s our V1 for the profile page to give you a better idea:

After we populate your profile, we’ll also have to check for new achievements at scheduled intervals. To do this, we first need to implement a rake task. This rake task will be called by a cron job eventually, but for now we can call it manually to update all users’ achievements.

Here’s the code for our rake task, found at app/lib/tasks/achievements.rake:

1
2
3
4
5
6
7
8
namespace :achievements do
  desc "Check for new user achievements"
  task :update => :environment do
    User.all.each do |user|
      user.save
    end
  end
end

‘namespace’ and ‘task’ let us define the name of our task. In this case, we would run rake achievements:update in our console to run the task. The meat of this task is querying our database for all of our users and then calling rails’ save method for each user. To update each user’s data, we have a couple callbacks in the User model that are run before the user is actually saved.

1
2
3
4
5
6
7
class User < ActiveRecord::Base
  before_save :check_blog,
              :get_external_data

...

end

For a quick example, here are the number of stars I had before writing this post (we give one star for writing one blog post).

The rake task.

And finally, my updated stars.

Just like that we can update all of our users’ data with one command. Pretty cool.

Understanding Nested Attributes

Let’s talk about rails’ accepts_nested_attributes_for method.

What is it?

According to Rails API, the method allows you to ‘save attributes on associated records through the parent.”

What does that mean and why should you use it?

Using an example from class, let’s pretend you’re creating an app built around horse races. In your app, you have a race model and a horse model. A race has a name and a horse has a name, number, and starting position.

You also have a view to create a new race. When you create a new race you want to populate the race with horses. For simplicity sake, we’ll only populate the race with one horse for now.

You soon realize that you can’t figure out a way to create a new horse within a race using the form_for @race helper.

Enter accepts_nested_attributes_for.

Essentially, the method allows you to create a new instance of a horse with it’s respective attributes at the exact same time of creating the ‘parent’ race.

Enter the following into your race model (I am assuming you have already setup the respective database associations):

Enter the following into your new race view:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%= form_for @race do |f| %>

  
  <p>Name <%= f.text_field :name %></p>
  <p>Description <%= f.text_field :description %></p>


   <%= f.fields_for :horses do |h| %>
    <p>Horse Name <%= h.text_field :name %></p>
    <p>Horse Number <%= h.number_field :number %></p>
    <p>Horse Position <%= h.number_field :position %></p>
  
  <% end %>

  <%= f.submit %>

<% end %>

Let’s inspect one of the attribute fields for the horse.

If we click on ‘Create Race’ and raise params before the race is saved, we will get the following:

As you can see, the paramaters being passed through to the controller for a horse come in the form of race[horses_attributes][0][{attribute}]. horses_attributes is a hash nested within params[:race]

Make sure your create action in your race controller looks something like this:

1
2
3
4
5
6
7
8
9
  def create
      @race = Race.new(params[:race])

      if @race.save
        redirect_to @race, notice: 'Race was successfully created.'
      else
        render action: "new"
      end
  end

Just like that you’ll be able to create horses within your races thanks to mass-assignment. Now let’s look at what the method is actually doing.

1st level of abstraction down:

Instead of using ‘accepts_nested_attributes_for’, we can substitute a writer method in your race model.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Race < ActiveRecord::Base
  attr_accessible :description, :name

  has_many :horse_races
  has_many :horses, :through => :horse_races

  def horses_attributes=(hash)
    hash.each do |horse_index, horse_attributes|
      horse = self.horses.new
      horse_attributes.each do |horse_attribute, attribute_value|
        horse.send("#{horse_attribute}=", attribute_value)
      end
    end
  end

end

During mass-assignment from your race controller, the horses_attributes= method will be called and a new horse will be created from this iteration.

2nd level of abstraction down:

If you’re like me when you first tried to figure out what’s going on beneath the hood, you may have written the code in your race controller to handle the task. I initially iterated through the params for both race and horse attributes, assigning the attributes one by one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class RacesController < ApplicationController

  def create
    @race = Race.new()
    @race.name = params[:race][:name]
    @race.description = params[:race][:description]


    params[:race][:horses_attributes].each do |horse_index, horse_data|
      @horse = Horse.new
      @horse.name = horse_data[:name]
      @horse.number = horse_data[:number]
      @horse.position = horse_data[:position]

      @race.horses << @horse
    end

    if @race.save
      redirect_to @race, notice: 'Race was successfully created.'
    else
      render action: "new"
    end
  end

end

This way works to get the job done, but it’s best to take the code out of your controller and create a writer method as shown above in your race model. Or better yet, just use the ‘accepts_nested_attributes_for’ method and don’t worry about creating the writer method at all.

I hope this helps for anyone looking to better understand nested attributes. Feel free to comment below if there are any questions!

Understanding Rails’ Routes

We began our foray into Rails last week. As expected, a ton of questions immediately came to mind once diving into a few tutorials. This post will address the routes that Rails automatically builds upon generation of resources and scaffolds.

As a Ruby framework, Rails essentially creates your application’s skeleton so that the programmer can get right to building the muscle of the app (not sure if that analogy makes sense, but sounded good at the time).

In creating the skeleton, Rails abstracts out many parts of your application into files that it has already created. For a Ruby newb, this is both incredible and confusing. It’s an awesome feeling to be able to startup the rails server, edit the controller, create a view or two with some forms, and automagically see your code in action. But, the hidden logic which lies within a new Rails’ application begs the question, “How does all of this actually work?”

While there are a ton of books to learn about the ins and outs of Rails, let’s take a look at one small, but extremely important piece: routes.

Let’s pretend you have created a new rails app for RSVPing to an event. To kick things off, you run the following in terminal to generate a User resource:

1
$ rails generate scaffold User

Along with creating a controller, model, migration, and other files, Rails also creates routes for you. Take a look within your config directory and you’ll see a ‘routes.rb’ file. Within the first few lines, you should see something like this:

1
2
3
RsvpApp::Application.routes.draw do

  resources :users

This one line of code blew my mind. All of a sudden (if you created the respective views and controller actions), you could navigate to paths such as http://localhost:4000/users, http://localhost:4000/users/new, or even fill out a form and have your data be stored to a database.

Let’s take a closer look at what happens. Run the following within your app’s directory in terminal:

1
$ rake routes

You should get output similar to this:

1
2
3
4
5
6
7
8
9
    users GET    /users(.:format)          users#index
          POST   /users(.:format)          users#create
 new_user GET    /users/new(.:format)      users#new
edit_user GET    /users/:id/edit(.:format) users#edit
     user GET    /users/:id(.:format)      users#show
          PUT    /users/:id(.:format)      users#update
          DELETE /users/:id(.:format)      users#destroy
     rsvp GET    /rsvp(.:format)           users#new
     root        /                         users#home

Rails has created all of these routes for you with just that one line of code.

Now, do the following:

1. Comment out ‘resources :users’ in routes.rb.

2. Insert this code into routes.rb:

1
2
3
4
5
6
7
8
  get '/users' => 'users#index'
  post '/users' => 'users#create'
  get '/users/new' => 'users#new', :as => :new_user
  get '/users/:id/edit' => 'users#edit', :as => :edit_user
  get '/users/:id' => 'users#show', :as => :user

  put '/users/:id' => 'users#update'
  delete '/users/:id' => 'users#destroy'

3. Run ‘rake routes’ again within terminal. Your output should be the same as before.

4. Think about what Rails just did. Anytime you generate a new scaffold/resource, the above routes are automatically created so you don’t have to go through the trouble of writing them yourself. Thanks Rails!

If anyone has other helpful tidbits on rails routes, please link to them in the comments section below.

Creating My Songkick-to-Calendar App

Last week, myself and two other Flatiron students were assigned with building and presenting our own ruby command line interface (CLI) applications. The task at hand was to combine a data source with a messaging service in order to make something useful. Here’s the process I went through to create my first useful ruby app.

1. Idea.

Concert listing scraper that asks for user input and automatically adds events of your favorite artists to your calendar.

The final product:

Songkick found two Beyonce shows on August 3rd and 4th at the Barclays Center in Brooklyn, NY. Both files were created in the current directory. Below I’ve opened the files with iCal.

2. Oh shit.

I actually have to build this thing and don’t know where to start. It’s Monday and the app needs to ready to roll by Thursday.

3. Break it down.

My initial excitement to build a concert parser had quickly turned into a wall of stress and doubt. Avi could tell that I started to quit on the project and told me that I needed to both figuratively break down the wall and literally break down the problem. He was right. As a beginner dev, it’s easy to be consumed by the idea of the final product without realizing that the overarching big problem is really just a set of interweaving easier problems.

4. Pseudocode.

Pseudocode essentially solved this problem for me. Unfortunately, I must have written over my initial code, but it went something like this:

1
2
3
4
5
6
7
8
9
10
11
# get artist from user

# get location from user

# use location to lookup the location id using Songkick API

# use songkickr gem with artist name and location id to fetch data for each show

# create hash to store event name and date from songkickr gem results

# create ical files from hash

5. Build the parts individually.

The two core pieces of functionality needed for my app to work hinged on creating ical files and fetching data from Songkick’s API. While there would eventually have to be code that ties these two pieces together, it made the most sense to me to write them separately (again, breaking the problem down to smaller parts). Here’s the inital code I wrote to create an ical file. Most of it comes directly from the Icalendar gem.

1
2
3
4
5
6
7
8
9
cal = Calendar.new
event = Event.new
event.start = Time.now
event.summary = "This is the event's summary"
cal.add_event(event)

File.open('testing'.ics", 'w+') do |f|
      f << cal.to_ical
    end

Eventually I would have to fill in event.start, event.summary, and the filename with variables, but all I wanted to do at this point was make sure that the creation of files worked properly.

Similiarly, I hardcoded artist/location information into the songkickr gem to make sure it returned data for upcoming Beyonce shows in NYC. The gem is essentially a Songkick API wrapper that performs the API call and fetching of the concert data for you.

1
2
remote = Songkickr::Remote.new 'Your Songkick API Key'
remote.events(:artist_name => "Beyonce", :location => "sk:7644", :min_date => "2013-02-20", :max_date => "2013-10-31")

Sidenote: Unless I am mistaken, it turned out that the Songkickr gem cannot accept a location such as ‘NYC’ and instead must have an ‘sk:id’ that points to a location (i.e. sk:7644 above points to NYC). Because of this, I needed to call Songkick’s API myself in order to return a location id. That location id was then used in the songkickr gem. Here’s the code:

1
2
3
4
5
6
require 'open-uri'
require 'json'

doc = open("http://api.songkick.com/api/3.0/search/locations.json?query='#{interpolate user location}'&apikey='Your Songkick API Key').read
location_hash = JSON.parse(doc)
location_id = location_hash.flatten[1]["results"]["location"][0]["metroArea"]["id"]

6. Methodize.

After filling in my pseudocode with actual code, it became very clear that each piece of functionality needed to live within its own method. Also needed was a hash to store the event name and date. To accomplish this, I first created a ‘shows’ hash. Next, I iterated over the results from the Songkickr gem, creating key-value pairs of event name and date within the ‘shows’ hash. Finally, I created ical files by iterating over the hash, replacing previously hardcoded values with the new key value pairs of event name and date. See below for the complete gist.

1
2
3
4
5
 def create_event_hash
  @event_results.each do |event|
    @shows[event.display_name] = event.start
  end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
def create_files
  @shows.each do |display_name, date|
    cal = Calendar.new
    event = Event.new
    event.start = date
    event.summary = display_name
    cal.add_event(event)

      File.open("'#{display_name}'.ics", 'w+') do |f|
          f << cal.to_ical
        end
  end
end

7. Object-orient…ish.

Being only a few weeks into really learning code, I’m still wrapping my head around object orientation. I understand the theory, but it’s a challenge to implement a variety of classes that do the right things and play nicely with each other. So, for the sake of time, I decided to create one giant class called ‘Result.’ The Result class contains a method called ‘run’ which essentially fires off each method in order.

Moving forward, I plan to refactor the code into multiple classes and also integrate the app with Google Calendar.

8. Next Steps.

I couldn’t believe that by Thursday I had a tangible, presentable, functioning version of a product that was in my head three days previously. I’ve never been able to say that before and I think that’s pretty cool. Stay tuned for the presentation video.

If anyone has feedback on my code or suggestions for the type of classes to build, I’d be all ears.

…now back to work.

4 Reasons to Learn to Code

Everyone has their own reasons for learning how to code. Here are mine.

To create products.

I’ve been a musician since learning guitar at 12 and have always been driven by the creative process. The concept of creating something from nothing that makes my life and others’ lives better as well is pretty cool.

To execute on a vision.

We’ve all seen this one before: business guy comes up with an idea, stays up all night thinking about it, scribbles the business model down along with an outlined marketing/sales plan, and then realizes he’s stuck. How is he going to execute? How is he going to create a MVP to begin testing his hypotheses? The short answer - he’s not unless he gets a tech guy to join him. Most likely, he’ll search through his network contacting developers only to find that they are all working on ideas of their own. I’m tired of having to rely on someone else to bring my ideas to life.

To build a foundation (for learning code the rest of my life).

Twenty years from now, I don’t see there being nearly as much of a distinction in the startup world between business and tech guys/gals. Coding will become part of schools’ curriculums, similar to learning a new language. It will be expected for most CEO’s to have solid technical background. Without one, it will be harder to raise capital, build a team, and execute on a vision. This trend is already on the rise and I plan to get a head start, rather than fall behind.

To impact the world.

Yes, maybe it’s cheesy, but we all search for meaning in our lives and it’s hard for me to think of a better way to impact millions of people around the world.

That’s it for now. If you recently made the jump as well, what were your reasons?