Learn With Jeff

I learn by teaching

Your First Hex Package

Let’s talk about publishing a hex package.

(This post assumes that you have Erlang, Elixir and hex installed. If you don’t check out Elixir’s getting started guide.)

For the last few weeks I’ve been doing a deep dive into Elixir/Erlang’s success types (I will be posting more about that soon). During that time I ran into some issues where I was confused about the type signatures I was seeing. As a Rubyist, I found myself reaching for something like this:

"foo".class #=> String

However, because of Elixir’s pattern matching, this isn’t something you should actually be doing in your code. Instead we have guard clauses.

def foo(bar) when is_atom(bar) do
  IO.puts(bar)
end

In order to do a quick inspection of the types being passed into a given fuction, I need something that looks like this:

def foo(bar) do
  Type.check(bar)
    |> IO.puts
end

I built a little module to accomplish this functionality. I thought it would make a good example for this blog post.

My goals for this package are as follows:

  • Simple API
  • Well tested
  • Well documented

For the API, let’s take the above example. I want it to look something like this:

iex> Type.check(:foo)
'Atom'
iex> Type.check(%{hello: 'world'})
'Map'

I will start by creating the package:

$mix new type
$cd type
$mix test

Let’s take a look at the files that mix has generated for us.

First we have the config/config.exs. We won’t be utilitizing this file in this exercise. This is the file you can use to add your own configurations to a package. There is further documentation here if you are interested.

Next we have the lib folder. This is where all of the code for our package will go. Since we don’t have too much functionaility in this library, we will probably only need to use the provided lib/type.ex which has already defined a module for us.

defmodule Type do
end

Then, under test/, we have two files: test/test_helper.exs and test/type_test.exs.

Finally, we have the README and the mix.exs file. The mix file is where we will list our dependencies and other package metadata.

Writing your first tests

We have a pretty good idea what we want our code to do, so let’s start by writing some basic tests.

In test/type_test.exs we can start with the most basic types:

defmodule TypeTest do
  use ExUnit.Case
  doctest Type

  test "a number" do
    assert Type.check(1) == 'Integer'
  end

  test "a boolean" do
    assert Type.check(true) == 'Boolean'
  end

  test "a float" do
    assert Type.check(1.0) == 'Float'
  end

  test "a atom" do
    assert Type.check(:hi) == 'Atom'
  end

  test "a map" do
    assert Type.check(%{:hi => 1}) == 'Map'
  end

  test "a list" do
    assert Type.check([1,2,3])  == 'List'
  end

  test "a binary" do
    assert Type.check("abc") == 'Binary'
  end

  test "a bitstring" do
    assert Type.check(<< 1 :: size(1)>>) == 'Bitstring'
  end
end

These are the ones I know off the top of my head. Looking at the available guard clauses, we have a few not covered by these tests:

is_nil(arg)
is_function(arg)
is_number(arg)
is_pid(arg)
is_port(arg)
is_reference(arg)
is_tuple(arg)

Out of these, I am least sure what is_number does. From the Elixir docs:

isnumber(term) Returns true if term is either an integer or a floating point number; otherwise returns false

It looks like we don’t need to define this as it is a super type of floats and integers. There is no situation where I would want the Type.check/1 function to return ‘Number’ instead of a ‘Float’ or ‘Integer’. I want the most specific type it can regcognize.

Let’s implement tests for the rest of them:

  test "function" do
    assert Type.check(&(&1+1)) == 'Function'
  end

  test "nil" do
    assert Type.check(nil) == 'Nil'
  end

  test "is pid" do
    pid = Process.spawn(Type, :check, ["hi"],[])
    assert Type.check(pid) == 'Pid'
  end

  test "is port" do
    port = Port.open({:spawn,'test'},[])
    assert Type.check(port) == 'Port'
  end

  test "a reference" do
    pid = Process.spawn(Type, :check, ["hi"],[])
    ref  = Process.monitor(pid)
    assert Type.check(ref) == 'Reference'
  end

  test "a tuple" do
    assert Type.check({:ok, "200"}) == 'Tuple'
  end

That should cover the rest of the types we want our function to handle.

Making the tests pass

I will start out with a function that takes any argument, and returns a character list representation of the type of the argument.

To simplify the API, I will create a single function as an entry point to the module that calls a private function. I use the typespec notation to show that this function takes any type and always returns a character list.

@spec check(any()) :: char_list
def check(arg), do: _check(arg)

I will implement the rest of the module. We can use the built in guard clauses.

 defp _check(arg) when is_map(arg), do: 'Map'
 defp _check(arg) when is_list(arg), do: 'List'
 defp _check(arg) when is_atom(arg), do: 'Atom'
 defp _check(arg) when is_binary(arg), do: 'Binary'
 defp _check(arg) when is_bitstring(arg), do: 'Bitstring'
 defp _check(arg) when is_boolean(arg), do: 'Boolean'
 defp _check(arg) when is_float(arg), do: 'Float'
 defp _check(arg) when is_function(arg), do: 'Function'
 defp _check(arg) when is_integer(arg), do: 'Integer'
 defp _check(arg) when is_number(arg), do: 'Number'
 defp _check(arg) when is_pid(arg), do: 'Pid'
 defp _check(arg) when is_port(arg), do: 'Port'
 defp _check(arg) when is_reference(arg), do: 'Reference'
 defp _check(arg) when is_tuple(arg), do: 'Tuple'
 defp _check(arg) when is_nil(arg), do: 'Nil'

Let’s run the tests.

$mix test

We see two failing tests:

  1) test a boolean (TypeTest)
 test/type_test.exs:9
 Assertion with == failed
 code: Type.check(true) == 'Boolean'
 lhs:  'Atom'
 rhs:  'Boolean'
 stacktrace:
   test/type_test.exs:10

  2) test nil (TypeTest)
 test/type_test.exs:41
 Assertion with == failed
 code: Type.check(nil) == 'Nil'
 lhs:  'Atom'
 rhs:  'Nil'
 stacktrace:
   test/type_test.exs:42

It looks like booleans and nil must be implemented under the hood as atoms. Because Elixir will match in the order the functions are defined, and because defp _check(arg) when is_atom(arg), do: 'Atom' is defined third, it is being called before the checks for booleans and nil are reached. A quick check of the documentation confirms my suspicion: “The booleans true and false are, in fact, atoms.”

So, we move the defp _check(arg) when is_atom(arg), do: 'Atom' to the bottom and rerun the tests. They all pass.

Next, we can add documentation and a doctest:

 @doc """
  Returns  a string representation of the type of a passed argument

  ## Example
  iex> Type.check(:hello_world)
  'Atom'
  """
  @spec check(any()) :: char_list
  def check(arg), do: _check(arg

In the test file we see the line:

 doctest Type

This runs our doctests for the Type module with the rest of our test suite. Let’s run the tests again to make sure the doctest passes.

$mix test

It does. Let’s publish our package.

Your next step will be to register as a hex user. Here is the example from the hex documentation:

$ mix hex.user register
Username: johndoe
Email: john.doe@example.com
Password:
Password (confirm):
Registering...
Generating API key...
You are required to confirm your email to access your account, a confirmation email has been sent to john.doe@example.com

Then, we need to add metadata to the mix.exs file. Mine looks like:

defmodule Type.Mixfile do
  use Mix.Project

  def project do
    [app: :type,
     version: "0.0.1",
     elixir: "~> 1.2",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     description: "A module for checking the type of an argument",
     package: package,
     deps: deps]
  end

  def package do
    [
      maintainers: ["Jeffrey Baird"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/jeffreybaird/type"}
    ]
  end

  # Configuration for the OTP application
  #
  # Type "mix help compile.app" for more information
  def application do
    [applications: [:logger]]
  end

  defp deps do
    []
  end
end

After that is set up, we can build and publish our app.

$mix hex.build
$mix hex.publish

We then get the message “Don't forget to upload your documentation with mix hex.docs

So we run that:

$mix hex.docs
Compiled lib/type.ex
Generated type app
** (Mix) The task "docs" could not be found. Did you mean "do"?

This isn’t a very helpful error. A quick Google search tells me that in order to generate docs I need Exdoc. So, let’s add that as a dependency.

In mix.exs we can add these:

 defp deps do
    [{:earmark, ">= 0.0.0", only: :dev},
    {:ex_doc, "~> 0.10", only: :dev}]
  end

Then we run:

$mix deps.get

And then generate the docs with:

$mix docs

And publish them:

$mix hex.docs

Conclusion

That is it. You have published your first hex package! Hopefully you enjoyed the post. If you find any errors, please let me know.

Building a JSON API With Phoenix

I’ve been following Elixir for the last 18 months and finally, this week I was able to make it to ElixirConf. I’m glad I did. I had, up until this point, been very skeptical about phoenix. I really enjoyed writing in Elixir but I wasn’t convinced that the language needed a Rails. However, the ease in which you can create apis is just too cool. I thought that I would share just how easy it is.

Dependencies

Install Elixir

This will help you install Erlang, Mix, Elixir and other Elixir specific tools

Install Phoenix

This has the instructions for installing hex, phoenix and configuring your database. Phoenix, by default, uses postgres. I use the Postgres.app but you can use the install you prefer.

Let’s Get Started

$mix phoenix.new testapi
$cd testapi
$mix ecto.create
$mix phoenix.gen.json User users fullname:string email:string

This will create a bunch of files that do a bunch of different stuff. But, the point of this post isn’t to explain how phoenix works to you. Instead it is to show you how fast you can get an api built.

Open you web/router.ex file and look for the following block:

#Other scopes may use custom stacks.
  #scope "/api", Testapi do
     #pipe_through :api
  #end

Un-comment this block and paste this line (It should show up in your terminal):

resources "/users", UserController, except: [:new, :edit]

under “pipe_through” :api

It should look like:

#Other scopes may use custom stacks.
  scope "/api", Testapi do
     pipe_through :api
     resources "/users", UserController, except: [:new, :edit]
  end

Then, back in your terminal run:

$mix ecto.migrate

This migrates your database.

$iex -S mix phoenix.server

This starts up your phoenix server and opens an interactive terminal.

That is it! You have a JSON api. Let’s test it out.

In another terminal window:

$curl -H "Content-Type: application/json" -X POST -d '{"user": {"fullname": "Jeff Baird", "email": "jeff@example.com"}}'   http://localhost:4000/api/users

Back in your phoenix server terminal you should see something like:

[info] POST /api/users
[debug] Processing by Testapi.UserController.create/2
  Parameters: %{"user" => %{"email" => "jeff@example.com", "fullname" => "Jeff"}}
  Pipelines: [:api]
[debug] BEGIN [] OK query=142.8ms queue=4.2ms
[debug] INSERT INTO "users" ("email", "fullname", "inserted_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" ["jeff@example.com", "Jeff Baird", \{\{2015, 10, 3\}, \{17, 32, 48, 0\}\}, \{\{2015, 10, 3\}, \{17, 32, 48, 0\}\}] OK query=2.2ms

Cool!

Let’s see if we can get data out of our api:

$curl -H "Content-Type: application/json" http://localhost:4000/api/users

You should see something like:

'{"data":[{"id":1,"fullname":"Jeff Baird","email":"jeff@example.com"}]}

It works!

This post is super basic and only meant to show you how fast you can get started developing apis with phoenix. I highly encourage you to go dive into phoenix some more. The documentation is great and the community is even better. Enjoy!

Can You Learn to Code?

I get this email three or four times a month:

I’ve recently had a thought that I should learn how to code. I have a full time job. Can I learn to code? How long will it take me?

I often hesitate to respond since it often results in a series of exchanges that leaves me frustrated and the original author unsatisfied. So I hope to clarify or extend my almost two year old post How to get a Job as a Developer in Less Than Six Months with this one.

Can You Learn to Code?

Short answer:

I have no idea.

Slightly longer answer:

Yes. I emphatically stand behind the idea that almost anyone has the mental facilities needed to comprehend programming.

However, when reading my post my circumstances are easy to forget. I had no job. I had just graduated from college. I had three months of money saved up. I was living at home with my parents.

Not everyone has those privileges.

I was able to devote all of my available time to learn to code.

There is a reason that the Flatiron School and schools like them encourage students to not be employed during while they are attending.

learning to code is hard work.

Even now, when I am learning something new I find that I need to block off at least two hours at a time in order to be productive.

So ask yourself some questions:

  • Can you reduce the amount of hours you work?
  • How many (consecutive) hours can you devote each day to learning how to code?
  • How long can you sustain that pace?

Your answers to those questions still won’t help me answer your original question because this will be different for every person reading this post.

The resources are out there, the community is out there. I am happy to pair with anyone on almost any project. I will review your code. I will recommend code schools – Flatiron School – but at the end of the day I cannot decide if you are capable of learning how to code.

Only you can.

Free Consulting

I’ve struggled for a while to figure out where I fit into the activist community. I have learned lately that I (another cis white hetero male programmer) don’t have much, in the way of experiences, to add to the greater conversation.

But I recently helped a writer/activist with some programming tasks, and I realized there might be a lot of activists for whom the Web is complicated territory. So, if you’re an independent activist who works to fight injustice, and you need help on anything Web-related, I’m happy to provide it, free of charge.

email me at anytime: jeff (at) jeffreyleebaird.com

I have no idea how many requests I’ll get so if it becomes too much to handle I’ll have to put some sort of limit on it, but for now let’s just see where this goes.

Easy Broiled Rib-eye

Sometimes, after a long day of work, the last thing Clare and I want to do is spend an hour crafting the perfect Paleo dinner. This steak and salad combination is a great way to have dinner ready in less than 20 minutes and have it feel like a gourmet meal.

Broiled Rib-Eye

Tools

  1. A 12-inch, well-seasoned cast-iron pan. I use this one from Lodge.

  2. A meat thermometer

  3. Pepper Grinder/Mortar & Pestle

Ingredients

  • 2 Rib-Eye Steaks
  • ½ tablespoon fresh ground pepper
  • ½ tablespoon sea salt
  • Olive Oil

Prep

  1. I like to leave the steak on the counter for about 30 minutes prior to cooking. It seems that this allows the steak to cook more evenly

Cooking

  • Turn on the Broiler. When it is warm put the skillet on the top rack and let it heat up for about 5 – 7 minutes. It may start to smoke, open a window and turn on a fan.

  • While the skillet is heating up salt and pepper the steak, gently pressing it into the meat. Then, drizzle the steaks with olive oil. Flip the steaks over and repeat.

  • Pull the skillet out of the broiler (it will be extraordinarily hot; use a thick pot holder) and put the steaks on it.
  • Return the skillet to the top rack of the broiler and set the timer for 4-5 mins.
  • Check the steak. If it is at 125 degrees it is ready (rare, the only way it should be eaten).
  • Let the steak sit for about 3 to 4 minutes before cutting it.
  • Eat!

Clare prepared a spinach salad ahead of time so maybe I’ll be able to get her on here to write about that. Enjoy!

The Easiest Stew

I think we have all realized by now that I am a pretty awful blogger.

I haven’t reliably posted, ever.

But, I am going to give it another go.

So let’s start with cooking, at least that is something I can write about. Let’s start with my stew.

Jeff’s Paleo Stew

Ingredients

  • 1.5 lbs of stew meat (Trader Joe’s sells pre-packaged pre cut stew meat)
  • 1 large or 2 medium sized onions (Any Kind will do, I like Vidalia but I used Red Onions here)
  • 8oz of whole White Mushroom
  • 1 lb of carrots (I use baby carrots here but usually prefer rainbow carrots)
  • 2 – 3 sweet potatoes or regular potatoes
  • 1 quart Beef Broth
  • 5-6 cloves of garlic
  • 2 Bay leaves
  • 2 tsp freshly ground pepper
  • 2 tsp salt
  • 1 tsp rosemary
  • 1 tsp thyme

Steps

Collect your ingredients:

Stew Meat:

Beef! It's whats for dinner

Onions:

Onions, try not to cry :'(

Mushrooms:

Mushrooms, wash them well, they grow in shit

Carrots:

Carrots, Wish I had rainbows

Potatoes

Potatoes, I like em sweet

Garlic

Keep away the vampires

Beef Broth:

dead animal juice

Spices:

Not the drug

Prep your ingredients:

Cut the ends off of the onion

step 1 prep

Cut the onion into eight wedges

step 2 prep

step 3 prep

Wash the mushrooms very well then slice them in half

step 4 prep

Scrub the potatos and cut the into (approximately) 1 inch chunks

step 5 prep

Cut carrots (if not using baby carrots) into 1 inch chunks

Put it in the cooker:

Start with a layer of about ½ of your onions

step 6

Add about ½ of your carrots

step 7

Add about ½ of your potatoes

step 8

Add about ½ of your mushrooms

step 9

Put in the two bay leaves

step 10

Put in all of your meat

step 11

Put in your garlic

Put in the rest of your vegetables

step 13

Sprinkle on all of the spices

Pour the entire quart of broth into the slow cooker (try to cover as many veggies as possible)

Give everything a quick mix

Set the slow cooker to ‘Low’ for at least 10 hours. I have set it for as long as 16 hours, the longer it cooks the more tender the meat is.

step 17

EAT YOUR CREATION:

step 18

Moving to Portland

Moving to Portland

It feels like yesterday that I was writing about new adventures. Here I am, planning another crazy but exciting move.

The last 18 months have involved an insane amount of change for me. I changed careers, moved to New York, then switched jobs again. Now we are starting a new chapter in Portland, Oregon!

Clare, my fiancee, was recently offered a feature writing position at The Oregonian newspaper! I am excited for the adventure, the prospect of a new job and a new city, but I will miss my friends, Brooklyn and the Flatiron School immensely.

In the last few months I have watched and helped train 32 of the most amazing people I have met. I have no doubt that over the next few years we will see amazing products coming from these students.

This move is a little bittersweet. In a few short months the team and Flatiron School has become like a family. I’ve learned so much from my bosses and coworkers, and I’m incredibly grateful to them.

My time at Flatiron School has changed me as a person and as a programmer.

This is goodbye, but hopefully not forever. New York, I’ll miss you.

Moving Beyond ‘Advanced Beginner’

Last year Erik Dietrich wrote a great piece called How Developers Stop Learning: Rise of the Expert Beginner.

Just in case, here’s a quick summary.

Dietrich’s main point is that some beginners reach a point of complacency with their expertise long before they ever reach the “expert” level on the Dryfus Model of Skill Aquisition. This results in many over-confident programmers writing production applications and often leaving the team before they have to suffer for their mistakes.

He has a great little graphic to explain what he means:

"Expert Beginners"

I think Dietrich has an excellent point, yet it isn’t really a problem I see in my role as a TA at the Flatiron school. I think, instead the bigger question raised is “What is an Advanced beginner to do?”

I have been working as a rails developer for about a year now. I have a fair grasp of the basics; I feel I can be productive on most rails projects without too much of a ramp-up; I can pick up new languages with relative ease; I’m slowly developing my personal style as a programmer.

I still have a long way to go.

One of the most prominent traits of an expert beginner is extensive breadth and a lack of depth. As a guy who loves “shiny” things, I am faced with a problem. I tend to pick up new technologies before I have truely mastered the ones I get paid to know.

I’ve posed the following question to myself: how do I level up from here?

The options seem endless. A year ago, I only wanted to build web apps, now I want to try writing a VM, a compiler, or a language.

That is only the tip of the iceberg. The more I learn, the more I realize I don’t know. I feel overwhelmed because I want to do everything.

So what is an advanced beginner to do?

I’ve decided to set a series of high level learning objectives, followed by goals that will give some amount of concrete accountability to them. The Web is where I am least comfortable and will likely have the biggest impact on my career going forward, so that is where I’ve decided to focus.

Objectives

  1. Gain a deep understanding of TCP/IP
  2. Learn how to effectively use WebSockets
  3. Become comfortable with the DOM apis
  4. Understand Event Handling

I almost put a line about learning Functional Reactive Programming in the list above, but I think it is a good example of me trying to ‘pre-maturly optimize’ my knowledge for problems I don’t have yet. That being said, FRP is really freaking cool.

Below I’ve sketched out some projects to help me reach these goals.

Projects

  1. Build a web application using at least one major JavaScript framework, currently leaning towards Ember.js.
  2. Write a simple webserver in Ruby from scratch.
  3. Read TCP/IP Network Administration.
  4. Read The Definitive Guide to HTML5 WebSocket.
  5. Build an interactive browser game using JavaScript.

Readers, what do you think? Is there something I should add, subtract or expand on? Let me know on twitter!

A New Challenge

Man, it has been a long time since I’ve written a blog post. The last time you heard from me I had just started working for Medivo. My experience at Medivo has been amazing. I learned from some amazing developers, worked on a product I care deeply about and made some great friends.

But all good things come to an end, and as of this Monday I started as a Teacher’s Assistant at The Flatiron School. Look at the title of this blog — teaching has long been a passion of mine. I am pumped to take on this new challenge in my life.

In other news, I’ve been playing a lot with Go. You should go over there and check it out. I will be writing on it soon :–)

How to Get a Job as a Developer in Less Than Six Months - Learn With Jeff

So the month of June came and went, and so did July. A lot has happened, but I wasn’t able to complete my goals

I did, however, make huge strides in my programming skills – so huge, in fact, that I was hired as a junior developer at Medivo!

This post is about how I got hired for my dream job with less then six months of programming experience.

Learning to Program

Work your ass off:

This isn’t how to fake your way into a position. It is how I got real results in a short amount of time.

I was, however, in a unique position. I didn’t have a job, I was only taking one class and I had fallen in love with programming.

So, in order to make the kind of strides I made, expect to spend at least 10 hours a day, six days a week dedicated to programming activities.

Read a shit ton:

The Pragmatic Programmers is now your best friend. If you are learning Ruby, get the Ruby 1.9 manual, Learn to Program, and get their Pragmatic studios learning ruby course (It is $200 but worth every cent). Start with the Pragmatic studios video course, and after about five lessons, start step two of my process while continuing to work on the videos.

Join your local ruby group:

This is a must. If you ignore everything else I say, still join your local meetup group.

This is imperative for three main reasons: First, the people you meet may become your employers, or they might introduce you to your future employers. Second, you will be around the people that have the jobs you want. Listen to them, jot down notes about the things they say, and if you don’t understand, then go research it. Last, if you show passion, you will likely find enthusiastic mentors from this group of people. I would not have made it as far as I have without Gavin Stark, Aubrey Goodman and the rest of the Tampa ruby brigade.

Write a ton of code:

Learn git and get a GitHub account. Push code to github EVERYDAY. There is no exception to this rule.

There are no shortcuts, you must write code, and a lot of it. It doesn’t have to be good code, but you must write it. If you look at it and think, “boy, this is shitty,” document the code and explain what you were thinking.

Make everything public:

This is an important aspect of writing a ton of code. If you keep it to yourself, it can be as shitty as you want. I find that if its public, every line of code has to be defendable, even if your reasoning is flawed. It is easier to adjust how you do things if you know why you did it in the first place.

Get a GitHub account, learn git like a boss, make every repo public.

Blog about your challenges:

You will face challenges just like everyone else. Blog about them incessantly. You can’t get any better unless you are asking for help. Also, having a record of your progress will come into handy later when you are trying to get that job.

Make sure you also blog about your successes. When you get something right, especially early on, it feels like the most epic of wins. Tell everyone about how awesome it feels and how you did it.

Getting The Job

So now you know a little programming. Don’t wait to get to a point where you feel skilled enough to get a job, because you will be waiting a long time. There is a desperate need for developers, and you are doing a great disservice to yourself and to the community. By learning on the job, you will give yourself a much more focused learning environment. However, here are a few things that will make the search go a little smoother.

Learn to speak like a programmer:

You’ll get a little of this from your reading and from your meetup groups, but there is more you can do. First, listen to related podcasts, I recommend every episode of Ruby Rogues, next subscribe to Rails Casts and Destroy all Software two great programming screen casts.

Some of what is discussed will go right over your head. That is okay. The point of this is to learn how developers speak. When you interview this will be an important skill.

Cast a wide net:

I got my job by sending out this email to the NYC Ruby community:

Hey NYC.rb!

I am a (relatively new) self-taught programmer moving to NYC from Tampa, FL at the end of July. Tampa’s awesome Ruby community inspired me to learn Ruby as my first language, and I’m excited to get involved with the New York City Ruby community.

I am graduating in a few weeks with a degree in business and entrepreneurship from the University of South Florida but found my passion, programming, while I was hiring a developer for one of my businesses.

I am looking for an internship/apprenticeship/junior programming position open in the area. If anyone has or knows of such a position, I would love to meet in June when I am in town for GoRuCo.

I am getting fairly proficient with Ruby, know the basics of JavaScript, HTML and CSS and am currently working with Rails. I learn quickly and work hard.

You can see where I am with my skills on GitHub, and I blog about my learning at learnwithjeff.com. Any feedback or advice is greatly appreciated!

I look forward to meeting some of you and getting involved with the New York City Ruby Community.

Sincerely, Jeff

I got 40+ responses in 18 hours. I also found every NYC ruby shop I could and read about them.

Next, I made a list of my top 10 companies and I worked my ass off to get interviews with all of them. I also stayed open to a few more pending discussions with the people on the team.

Don’t underestimate your value:

When I started this search I thought I would be scrubbing toilets in exchange for nightly code reviews. While that determination was probably a good thing, the market is currently in favor of devs looking for work. You may be a n00b, but don’t underestimate your value.

So to sum up:

Work hard, write a lot of code, be transparent and be enthusiastic.

In February 2012 I had never written a line of code. But, as of July 11, 2012 I am employed as a full-time Ruby Developer. You can do it too :).