Hey, I was interviewed!

What was it like to ramp up at that first job? Did you find you had some blind spots that your job filled in? Were certain things more or less important than you anticipated?
It was tough. I didn't get a lot of support from the other engineers, so I had to learn a lot on my own. If I ever ran into issues, usually they would just take the ticket themselves instead of helping me learn. At one point, I had almost no work, so I started taking online classes and working through programming books. I had never realized how important it was to have a team that supports you, which is definitely something I've looked for in every job since. Even as I move along in my career, I still want to be able to talk to my coworkers about issues that I am having without feeling like I'm wasting their time. However, I still feel like it wasn't a waste. It still enabled me to list myself as a software developer, have some actual production code that I could show, and really get my foot in the door. It's great to have a great job, but sometimes, especially if it's your first in a field, any job will do if you have limited choices.

Plotting Data From A CSV with Matplotlib

After I got all that data from the logs, my boss wanted it in a nice graph. First of the active user numbers, then the top 15 users. I knew that, despite having never used Matplotlib, it will still take me less time to learn it than any of my other options. I was able to get my script running and plotting correctly in less than two hours, so I felt pretty good about that. However, I had a few nested for loops and I wasn't a big fan. Enter the crowd-sourced code review! My friend Jenny was able to come up with a cool alternative to my solution that I ended up using. She utilized plot_date to sort the dates/data, which really helped (I was doing all sorts of crazy fun things).

So here's an example of what active_users.csv looked like:


he biggest problem was determining how to store the data in the program in a way that could be easily plotted. End solution? A dictionary of arrays. Or more precisely, a dictionary of a dictionary of arrays. With each line, we appended each data point to the matching array, which meant that a given date had the same index as it's data. And boom! It works!

import matplotlib.pyplot as plt
import csv
from datetime import datetime

active_users = {
  'jira': {
    'dates': [],
    'au1': [],
    'au30': []
  'confluence': {
    'dates': [],
    'au1': [],
    'au30': []

with open('active_users.csv') as csvfile:
  active_users_csv = csv.reader(csvfile)
  for system, au1, au30, date in active_users_csv:
    active_users[system]['dates'].append(datetime.strptime(date, '%Y-%m-%d'))

plt.plot_date(active_users['jira']['dates'], active_users['jira']['au1'], label='jira au1', color='orange', fmt='-')
plt.plot_date(active_users['jira']['dates'], active_users['jira']['au30'], label='jira au30', color='red', fmt='-')
plt.plot_date(active_users['confluence']['dates'], active_users['confluence']['au1'], label='confluence au1', color='green', fmt='-')
plt.plot_date(active_users['confluence']['dates'], active_users['confluence']['au30'], label='confluence au30', color='blue', fmt='-')
plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
           ncol=4, borderaxespad=0.)
Resulting graph of AU1 and AU30 numbers

Resulting graph of AU1 and AU30 numbers

Ok, so now that graph #1 is done, I had to graph the top 15 users over the past week and their usage patterns. First off, here's an example of the data I was working with:

User,Date,Request Count

Obviously, with our actual prod data, there were thousands of users... so a few more lines to loop through. The first problem was to put the data into a format I could use. Since even a top user might not use the system at all one day (say a Sunday), I couldn't use a simple dictionary; this time I had to utilize defaultdict. Defaultdict enabled me to create a dictionary of users where the value was (by default) an array of 7 zeros (representing usage for the past 7 days). After that, I was able to loop through the file for each day. To get the file names, I had to start with yesterday's date and go backwards. The date still gets appended to the 'dates' array, but the big change is in users: instead of appending the data to an array, I insert it into the index that matches that day.

So now that I have a dictionary of dates and users, I have all that I need to determine the top 15 users of the week. I create another dictionary that has the users as keys and sums up their total requests from the array and sets that as the value. Once I do that, I sort it, end up with a tuple, reverse it, then slice off the top 15. At that point, I just need to loop through my weekly_active_users list and then plot each user's data! Though I did have one, final (much smaller) problem: I had to find 15 matplotlib colors that I could use and distinguish. I created my array of colors and added a counter to each loop so I could add a unique color to each user. Success!

import matplotlib.pyplot as plt
import csv
from datetime import datetime, timedelta, date
from collections import defaultdict
import operator
from itertools import islice
import re

active_users = {
  'jira': {
    'dates': [],
    'users': defaultdict(lambda: [0] * 7)
  'confluence': {
    'dates': [],
    'users': defaultdict(lambda: [0] * 7)

active_users_weekly = {
  'jira': {},
  'confluence': {}
current_date = date.today()
day = timedelta(days=1)

for i in range(0,7):
  current_date = current_date - day
  current_date_txt = current_date.strftime('%Y-%m-%d')
  for system in ['jira', 'confluence']:
    with open("active_users_{0}_{1}.csv".format(system,current_date_txt)) as csvfile:
      users = csv.reader(csvfile)
      for user, log_date, request_count in users:
        active_users[system]['users'][user][i] = int(request_count)

sorted_active = {'jira': {}, 'confluence': {}}
for system in ['jira', 'confluence']:
  for user, request_list in active_users[system]['users'].items():
    active_users_weekly[system][user] = sum(request_list)
  sorted_active[system] = sorted(active_users_weekly[system].items(), key=operator.itemgetter(1))
  sorted_active[system] = list(islice(sorted_active[system],15))

fig = plt.figure()
jira = fig.add_subplot(211)
conf = fig.add_subplot(212)
colors = ['red', 'gold', 'darkorange', 'green', 'turquoise', 'dodgerblue', 'navy', 'darkviolet', 'violet', 'pink', 'darkslategrey', 'silver', 'blue', 'lime', 'orange']

i = 0
for user, request_num in sorted_active['jira']:
  jira.plot_date(active_users['jira']['dates'], active_users['jira']['users'][user], label=user, fmt='-', color=colors[i])
  i += 1

i = 0
for user, request_num in sorted_active['confluence']:
  conf.plot_date(active_users['confluence']['dates'], active_users['confluence']['users'][user], label=user, fmt='-', color=colors[i])
  i += 1

jira.legend(bbox_to_anchor=(0., 1.1, 1., .102), loc='lower center',
           ncol=8, borderaxespad=0.)
conf.legend(loc='upper center', bbox_to_anchor=(0.5,-0.1), ncol=8)
Oooh pretty colors! Also, fake data makes for a bad graph.

Oooh pretty colors! Also, fake data makes for a bad graph.

Parsing Logs With Ruby

I used to write log parsing scripts all the time with Python. That's basically how I got started programming. In the past few years, I've been working almost entirely on application development. Recently my boss wanted to get the unique number of active users in a day and the unique number of active users within the past 30 days, in addition to an actual list of each of those users with the number of requests that they made to the system.

There were a few issues. I had to keep in mind that there were sometimes anonymous requests, which I didn't want to add to my list since it didn't serve my purpose. I also noticed that there were some lines that didn't seem to contain a request at all, so I also had to account for that. Let's all hop on the regex party train!

Thanks to the magic of regex, I can very quickly tell whether or not a line is a request from an anonymous user and skip that line. I can also skip a line if there is no IP address at the beginning, which occurs when there are usually requests that cover multiple lines. I also have a regex to match the date format that our logs are using. If there's a date, then I grab it; if not, then I can skip that line too.

Now I'm left with only valid lines. SWEET! But what do I do with them? Since I need to keep track of both users by day (along with number of requests) and the numbers of unique users across the day and past 30 days, a hash will definitely be my best friend. All of the information in this case will go into a hash called all_days. Here is the basic format:

all_days = { date => { user_name => num_requests } }

Now that we have valid lines, we can start populating this hash. If the current date exists as a key, then we increase the given user's request count. If it doesn't, then we instantiate the user/request_count hash with a default value of zero. That's actually the bulk of the work. After that it's just a matter of counting and generating a list of users for the past 30 days, then uniquing that list.

If anyone has any comments on how I could make this better, I would welcome the feedback!

Complete script:

require 'date'
require 'fileutils'
au1 = 0
au30 = 0
IP_AT_START = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/
DATE = /(3[01]|[12][0-9]|0[1-9])\/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\/[0-9]{4}/
month_users = []
all_days = {}
Dir.glob("/path/to/logs/access.log*") do |filename|
  File.foreach(filename) do |line|
    next if line.match(EMPTYLINE)
    next unless line.match(IP_AT_START)
    date_match = line.match(DATE)
    next unless date_match
    user_name = line.split(" ")[2]
    date = Date.parse date_match[0]
    if all_days[date]
      all_days[date][user_name] += 1
      all_days[date] = Hash.new(0)
      all_days[date][user_name] = 1
au1 = all_days[Date.today].count
all_days.each do |date, day_users|
  month_users += day_users.keys if date >= Date.today - 30
au30 = month_users.uniq.count

Getting Your First Job As A Software Developer


This post is aimed primarily at people who are transitioning to another industry, not new grads. New grads will probably get something from this post, but they are not the primary audience. With that said, this post will discuss primarily getting a job as a web developer since, not only is that what I have experience with, web dev jobs are usually the ones that junior developers can get.

Getting the Interview

In some ways, this can be the most daunting part. I'm going to break this up and hopefully help you to see that you (yes YOU!) have what it takes to apply.

Getting Your Resume Ready

One thing I always tell people is to make their existing jobs as technical as possible. For example, when I was applying to my first software developer job, I made my job at Home Depot (which was a PM job) sound like I did way more development. I did all the things that I put on my resume, but I emphasized the more relevant tasks and did not mention that my day to day was mostly working in Excel. Did you optimize a process at work? That shows how you can problem solve! Did you write a script to help you analyze data? Definitely add that. Also, writing actual code is not the only skill needed by developer. Chris Doyle, CTO of Pretty Quick, does a good job of summing this up (slightly paraphrasing from tweets):

There are many valuable dev skills besides code, many of which you probably possess! Start there.[1] Also, your dev skills may be relatively small, but it doesn't mean they aren't already useful.[2] A junior developer sent me a cover letter identifying a potential UX improvement in my site, saying "This is something I could help you with."[3] That was such a concrete demonstration of initiative! They were an immediate favorite who was ultimately hired.[4]

For new developers, I expect to invest in their training, so it's really about "are they going to multiply or waste effort".[5] I do consider their current ability and have a low minimum bar, but gaining confidence in trajectory is much more important.[6]

What are these other valuable dev skills? Chris has created a whole list of developer competences. Don't worry if you look at that list and feel like you are missing a few. However, this list should help you decide what to include on your resume. For example, if you are currently in a customer support role, you are probably very good at suggesting possible causes for bugs! For more of my thoughts on resumes, see my post on the topic.

Creating Your Portfolio

This part of applying to jobs because less critical as you have more relevant experience. For example, a visit to my github or gitlab pages would make one think that I never coded! False... all my code is just proprietary and I invest my time in PyLadies vs OSS. Works for me because I have former employers and coworkers who will back up the quality of my code. If you are starting out, you need to show it. As Carlos Alonso said, as a junior developer, "your public code is the most important part of your CV." Dustin King recommends "writing a small game or other fun demo and putting it up online with code." Your project doesn't have to be huge, but you should have a friend QA it and make sure that there aren't glaring bugs. My project ended up being a choose your own adventure game that was part of going through Zed Shaw's Learn Python The Hard Way. However, I would recommend going a step further and building your own web app prior to applying. See the end of my "Getting Started As A Developer" post for more suggestions on how to get started with that.

Finding Jobs To Apply To

How do you even find jobs that are available? There are many great job boards out there, my favorite being Stack Overflow Jobs. But don't stick with just one. Search any job board that you can find and, as Christian Steinert says "try not to only consider common tech companies. Others (like financial services) might offer interesting stuff." At this point, most companies have at least a few software developers on staff. If there's a company you love, look at their job board. If it looks like they have a few technical jobs, reach out! Being passionate about a company's mission/product can often get you pretty far. As an example, if I lived in San Francisco, I would be hounding Betabrand until they hired me. If you have extensive experience in a field, look at companies with that focus so that your past experience can be even more beneficial. For example, if you are a biologist by training and looking to switch to development, you might find a place like AddGene to be a good fit. I, personally, have also enjoyed working with recruiters, like Talener in Boston. At bare minimum, they will get you in front of a ton of companies and get you in for interviews. Even if none of those pan out, it will be good practice and you will be better prepared when you find a job you are really excited about. Also, don't forget to milk your own personal connections! Do you know anyone who works at a company that's hiring devs? Contact them, see if they can meet you for coffee (buy them a coffee), and talk to them about what it's like to work at their company and their hiring process.

Now that you have a long list of job postings, you maybe are starting to notice that they all seem to say that you need experience with all these different languages, maybe one of which you have used... how can you ever be ready? GOOD NEWS! Most job postings are wish lists. Yes, even the parts that say "Required" are often negotiable. If a job sounds interesting, you should apply. Let whoever is reviewing your resume determine whether you are qualified. The only phrase that should give you pause is "Senior". If a job posting is looking for a "Senior Application Developer" or something like that, the hiring manager is unlikely to hire a junior person instead. Even so, if it's a company that you are really passionate about, reaching out will not hurt.

Acing the Interview


One way to prepare is to work through a list of common interview questions and maybe a few exercism problems. Almost every interview I've had has also asked questions about SQL. Given that every job I have had has required me to use SQL in one form or another, I would recommend learning a bit before applying to any job. If you aren't up to speed yet, work through exercise 12 of Learn SQL The Hard Way. It looks like most of the lessons probably aren't too time consuming and it will be well worth your time!


I wrote my own "Job Search Retrospective" last September which talks about some of the things that I did in my most recent round of interviews that made me feel a lot more confident. As a junior, the most important thing to remember is that it's ok to say "I don't know" or "I don't know, but I was reading about this recently and I think it is [x]". An employer who you actually want will not be expecting you to be super knowledgable about development at this point. Stay calm on just make sure all your awesome qualities are on display. Most importantly, don't forget to ask questions!


If you aren't sure that you did very well during the interview, don't despair! You still have time to make a good impression. Going back to Chris Doyle, he had a person who sent in a refactored version of a coding exercise they did during an interview. This is such a great demonstration of initiative and also that you continue to consider and think about your solution even after you have "solved" the problem. It is good to send an email to the interviewer and thank them. That's a perfect place to add in "and I've been thinking about that problem that we did and I think the solution could be improved by [x]".

Starting the Job

Getting the Offer

The only advice that Mr. Sam Phippen through out really struck a cord with me:

Charge. More. People entering the industry consistently underestimate their reasonable salary band by about 20%.

This hit me because, as of recently, I was underpaid by about 25%. To get an idea of what other places are paying, look at sites like Indeed and the recent Stack Overflow Developer Survey. If you find out after the fact that you have undervalued yourself, you can fix it, but it takes a while. I speak from experience.

Doing the Work

Never feel bad about asking questions. Take advantage of the senior devs that you work with and learn as much as you can from them. If your company supports pairing, pair program as often as you can. You will learn so much more so much faster that way. Also, take charge of a project or a feature. That doesn't mean you have to do all the work, just that you are taking responsibility for making sure it gets past the finish line. Along those lines, @codepaintsleep says:

Don't get stuck with grunt work just because you're junior. Push your knowledge when there's more experienced people to help! Also, don't write off grunt work as grunt work. Learn from everything!

To give an example of how you can learn from everything, I am covering for a coworker and working support this week. I am not doing any actual coding. However, the amount that I have learned about how our system works and what our users want in just a week is incredible. Learn. From. EVERYTHING.


I hope you got something out of this. If you think I missed something, feel free to comment on the post or contact me.

Why You Should Go To Conferences

Maybe I'm the wrong person to write this. After all, I only go to one or two conferences a year because I can't quite afford to travel as much as some people do. I check out some local conferences and that's about it. However, I'm inspired to write this because I just got back from RailsCamp East Coast and it was AMAZING. It reminded me of the same reason I love Burlington Ruby Conference and my first PyCon. Conferences (or in the case of RailsCamp, a retreat) set aside a few days to learn some new things and also to spend some time with other developers, building relationships. In a way, it's the best networking you will ever do. Going to loads of meetups and making a passing acquaintance with a lot of people might do you some good. Really getting to know a few people over a few days will do you a lot of good.

OMG RAINBOW (waterfalls near the Ashokan Center in Olivebridge, NY)

OMG RAINBOW (waterfalls near the Ashokan Center in Olivebridge, NY)

I don't mean to dissuade anyone from going to meetups... I have made so many wonderful friends through PyLadies Boston that I would absolutely vouch for and that I've helped get jobs. However, those relationships have formed over the course of years and sometimes you don't have that much time. If you are a junior developer who is trying to get a job, one of the best things you could do is go to a conference and do some heavy-duty bonding. If you can do a talk, that's even better. Anything to show how interested you are in whatever language/field you want to work in. Going to conferences won't guarantee a job, but it will likely increase the number of people who are willing to recommend you to other employers and increase your chances of getting a better job.

If you are like me and a more experienced developer who is not looking for a job, conferences are still beneficial. I love my job, but I'm not going to be there for the rest of my career. When I am looking for a job, now I know even more awesome people who I would love to work with who also know me. This increases my chances of finding a job I actually enjoy since I have spent a significant amount of time with all of these people and have a better sense of who they are and what they value.

TL;DR - Go to conferences (and RailsCamp). They are fun and valuable.

Getting Started As A Developer

Through my work with PyLadies Boston, I have been asked quite a few times on how to get started with development. I'm going to try to write it all down here.

So you want to become a software developer?

Awesome! It's a pretty fun (albeit sometimes frustrating) gig and the pay is pretty decent too. Just be patient... it's not super easy and sometimes it'll get difficult. It's worth it though, so stick with it.

Step 1: Pick a language

Don't spend too long on this step! I would recommend either Python or Ruby as good beginner languages. The syntax is relatively similar to English, so it's not too hard to read code from early on. Also, these are two languages that are widely used at actual companies! Ruby is a fan favorite of startups and Python has a huge following in the scientific/academic communities. If you want to further progress into web development, I would recommend Ruby because, in my opinion, I think the documentation and tutorials available for Rails are much better (and in some cases easier to understand) than the docs/tutorials for Django.

Either way: don't think too hard about it. You just need to pick one. Once you learn one, you can always, much more easily, learn another.

Step 2: Pick a method

There are a load of resources out there. One I recommend is Zed Shaw's Learn Code the Hard Way (for Ruby, Python, SQL, and C). There's also How To Think Like A Computer Scientist (for Python), along with plenty of others. If you prefer a book, I can recommend both Dietel's How To Program (Java) and Pine's Learn To Program (Ruby, also a web tutorial!). The world of programming books/tutorials is  your oyster! Just pick a learning style that you like and stick with it. If videos are your thing, Codeschool has excellent video tutorials.

What I do not recommend: while Codecademy can be good for trying to decide what language to use, I do not recommend it for learning. Codecademy is software (what you will be building) and software has bugs. What you don't want to be spending time on is trying to figure out if the bug is yours or Codecademy's. If you think that sounds crazy, I have had Python code that I've run locally with no errors that gets a random error on Codecademy. Plus, one of the most difficult parts is installation and setup. You miss that with Codecademy. If this is your tool of choice, you have been warned.

Step 3: Give it some time

Try to dedicate some amount of time every day. 10 minutes when you first get in to work? 30 minutes when you get home? Doesn't matter. The more time you can dedicate, the faster you will progress, but the important thing is to make it a habit so you stick with it. Most of these resources have forums that you can utilize if you run into problems. If they don't, then you can also use StackOverflow. If you google for your error message, you will probably get a result on StackOverflow. Check it out and see if you can fix your bug. Once you get past the basics, give yourself a challenge by trying some exercism.io problems. They have problems for almost all languages and your submissions will actually get code reviewed!

Step 4: Level up!

You have a solid foundation! Time to take it to next level! And by that I mean web development. Is that the only route you can go? Nope! But I'm a web developer, so that's what I actually have experience on. Also, I have the most experience in Python and Ruby, so those are the languages that I'll have the most links for. If anyone has some next level topics for non-web developers, put it in the comments! Or link to your own post. Depending on what you started with, here are some resources:


  • Michael Hartl's Rails Tutorial - This is the best Rails tutorial out there. I'd almost argue that it's the best web dev tutorial out of any language.
  • CodeSchool's Rails For Zombies - If you prefer videos, Rails For Zombies is corny, but pretty great. And the first course is free!
  • Sinatra - a microframework for Ruby. If you really want to dig in and try to learn how things work, using a microframework that doesn't enable all the bells and whistles by default is awesome. 


  • Tracy Osborn's Hello Web App - Awesome book series made to teach non-programmers web development through Django
  • Getting Started With Django - Short video series. Starts you after the official Django tutorial
  • Django Book - The official Django tutorial. I'm hoping it's been updated since I tried to go through it because it was a bit buggy then.
  • Flask - a microframework for Python. Also see this tutorial
  • Lynn Root's NewCoder.io - Not web dev, but definitely a level up. Lynn has written tutorials on APIs, web scraping, data visualization, GUIs, and networks. These are great if one of these topics is of interest to you.
  • Daniel and Audrey Roy Greenfield's Two Scoops of Django - this is not really a beginner book. More an "after your first app" book. But this is one of the best programming books I have ever read, so I absolutely had to add it to this list.


  • Play Framework - As far as I can tell, this is the most popular web framework for Java. Their own documentation contains a solid amount of good tutorials to get you up and running fast.

Step 5: Build something!

This is absolutely the hardest step. Why? Because it requires you to actually be a little imaginative and think of something that you want to create. To start, you can create a website (either a personal site or a landing page for your project) on Github Pages. It's free and super easy to get started! As far as picking a project, there are shortcuts if your brain is a bit fried and you can't think of anything. There are lists of coding projects that you can pick from. You can also contribute to open source. Whatever you choose, the important thing is to keep working at it. Even senior developers are still constantly improving their skills, so you will constantly be learning at all stages of your career.

A Quick Post About Resumes

PyLadies Boston recently had a mock interview night and with that I offered to review resumes. I got a few takers, did some reviews, and now I have some thoughts.

  1. If you are randomly switching fonts, please have a good reason for it. It is distracting (in a bad way) if you go from a serif to a sans serif for seemingly no reason.
  2. If you are writing your job duties as a bullet-point list, please make sure each point is connected to itself. I can't seem to think of a great way to say that, but let me give an example. If one of your points is: Improved test coverage by 10%, organized tech talks, and implemented a code quality standard - then those should really be elaborated upon if possibly and definitely split into three separate points.
  3. Make sure your resume reflects the skills of the job you are looking for. That doesn't mean that, if you have been a research scientist that now wants to be a full-time programmer, you have to ignore your past history. However, you do have to highlight different things. For example, how did you analyze a set of data? Did you use Python? What libraries did you use?
  4. Along the same lines: If you are applying for your first programming job and don't have any related experience, you really need a projects section that lists the programming projects you have worked on and any open source you have done, along with descriptions. You know you can do the job, but if you don't put proof that you can code, the internal recruiter/HR person is going to throw your resume out.
  5. For skills section: if you are including it, please make sure they are relevant! If you are applying for programming jobs, you do not need to include photoshop. Also, definitely do not include the Office Suite... familiarity with Office or similar software is assumed if you know how to use a computer (which is also assumed if you are applying for programming jobs).
  6. White space is your friend! Definitely don't jam everything together. Separating out sections, careful use of bold fonts and color, and horizontal lines can really help draw the reader's attention to wherever you want it to go.

Sorry some of those were a bit of a ramble, but these are all things I have seen recently on resumes. A resume is often the first look that many people have into your professional life, so you want it to represent you in the best way possible. If you have any questions, feel free to comment!

Calculating Age... in Java 8

I'm doing a bit more Java now that I'm taking a Java class. With that is coming a lot of "oh that should be easy... wait, there's not a really simple way to accomplish this???". First example of this: determining someone's age.

import java.time.LocalDate;

public class Age {
  private int birthYear, birthMonth, birthDay, age;

  public Age(int birthYear, int birthMonth, int birthDay){
    this.birthYear = birthYear;
    this.birthMonth = birthMonth;
    this.birthDay = birthDay;
    this.age = getAge(birthYear, birthMonth, birthDay);

  public int getAge(int birthYear, int birthMonth, int birthDay){
    LocalDate fullBirthday = LocalDate.of(birthYear, birthMonth, birthDay);
    LocalDate now = LocalDate.now();
    long daysSinceBirth = now.toEpochDay() - fullBirthday.toEpochDay();
    return (int) (daysSinceBirth/365);

LocalDate is new to Java 8. Previously it was part of the Joda-Time API, but the Java folks seem to have added the bulk of the functionality directly into Java. Sweet! What does this allow us to do? LocalDate creates an object that represents a date and has quite a verbose API. Since we're calculating someone's age, we are going to need an object that represents their birthday and an object that represents today (in this case fullBirthday and now). If we convert these both to Epoch Days, which is generally just the number of days from 1970-01-01, we can just compare the number of days and divide by 365 to get the age. Not too hard... but did take a second to come up with it... I was a bit surprised that it seemed like I couldn't actually subtract dates. Ruby has spoiled me...

Polymorphic Routes

I just started classes (working toward the CS certificate at BU Met) and my new big project at work is porting over a ton of code from Rails 2 to Rails 4, so I’m sure I’m about to have tons to write about. For today, here’s something I somehow just found out about: polymorphic routes in Rails.

What are polymorphic routes? Let’s say you want to have a partial that is used for quite a few different models. Every model you have has a show page for individual instances of that model and each show page has an edit link. So instead of creating a new page for each, the view you have reads in a generic @object and then you can use polymorphic routes to generate the path for the edit link! In this example, I’ll have the @object represent an instance of the Article class. Like so:


results in:


I’m pretty surprised I haven’t seen this yet, but now I’m glad that I have! This is pretty cool :D

Oh My Zsh!

The terminal is fun. And it should also look fun (and be functional). I’ve been using Robby Russell’s Oh My Zsh for years now, but it still surprises me when people haven’t heard of it.

I’m not going to go into a ton of detail as to why you should use it. Here are a few great posts that already do that.

Nope, I’m mostly going to talk about how I have been adding a series of increasingly ridiculous emojis to my prompt. Why? Because if I am having a bad day, dammit if a 💩 doesn’t make me smile a bit. Right now I have a rainbow if I have a clean git repo, but I’m going to add a unicorn as soon as I can update my work computer.

There are so many awesome, fun themes to use depending on your workflow. I was using a slightly modified bullet-train:

But then today, I decided it was taking up too much space and went back to an old standby: crunch. I modified it just a bit to change the icons (💩) and also to just display the current folder instead of the whole path. Though I’m sure the whole path can be useful to most people, my directory paths can sometimes get long and ridiculous, so generally a folder name does in a pinch. If I need to confirm, there’s always pwd.

Try zsh. It has some other sweet features that are all useful, but my favorite thing is the themes and how much easier they make my day to day.


My friend Pamela had some thoughts on code schools that she shared on Twitter today and I just have to echo them in every venue that I have. Code schools have long made me feel uncomfortable. It really started when a local code school started amping up representation at RailsBridge (free & community driven), obviously with an aim to drive RailsBridge grads to their boot camp. Considering the other TAs were there from companies that were interested in hiring, I thought it really sleazy that they were just using it to try to recruit more students. Add this in to women generally needing more validation before they feel comfortable calling themselves developers and that makes me feel even more uncomfortable.

I try to do my part by running PyLadies Boston and Pamela runs Rails Girls Atlanta. Both of these groups exist to provide a community for women to learn to code, with no charge. I’ve actually had multiple women from my group start applying to jobs as developers and I know the same goes with Rails Girls. Community can make a big different and we need to let women know that you don’t have to shell out $$$ to become a developer. The community will help!

PS - I have met so many wonderful and smart grads of code schools. This is not a knock on you! It’s a knock on this f’ed up industry.

A Bash Script For When You Need To Duplicate Host Keys Across Servers

Why would you need to do this? Let’s say you have three production nodes: server1.test.com, server2.test.com, server3.test.com. In general, your production application (at prod.test.com) point to server1.test.com. But OH NO you totally messed something up on that node and you need to easily failover to server2.test.com. Easiest way? If they all have matching server host keys, you can just point prod.test.com to server2’s ip and you won’t get any errors. Otherwise, you’ll get loads. I also added a noop (no operation) mode to this script so it could be run as ./move_keys.sh -n and only print out the lines that it would run.

This script is written to be run on the server you want to copy the keys from as your user, which means you have to have ssh access into each server. For each server in the list that is not the host, it backs up the /etc/ssh directory, rsyncs the keys over, restarts ssh, then removes the relevant lines for that server in the known_hosts file.

# use noop mode by passing -n
# parse the options
while getopts 'n' opt ; do
  case $opt in
    n) NOOP=true ;;

HOST=`hostname -f`

# Params: $1, host to log into and copy ssh dir into backup dir
copyit() {
  if [ $NOOP = true ]
    echo "$SSHC -A $1 'sudo cp -r /etc/ssh /etc/ssh_bak_$(date +%Y%m%d%H%M)'"
    $SSHC -A "$1" "sudo cp -r /etc/ssh /etc/ssh_bak_$(date +%Y%m%d%H%M)"

# Params: $1: src path, $2: dest path
moveit () {
  if [ $NOOP = true ]
    echo "sudo -E rsync -avz -e 'ssh -o StrictHostKeyChecking=no' --rsync-path='sudo rsync' $1 $2"
    sudo -E rsync -avz -e 'ssh -o StrictHostKeyChecking=no' --rsync-path='sudo rsync' $1 $2

# Params: $1, host to log into
restartit() {
  if [ $NOOP = true ]
    echo "$SSHC -A $1 'sudo service ssh restart'"
    $SSHC -A "$1" "sudo service ssh restart"

# Parmas: $1: host to deploy keys to
removeknown() {
  if [ $NOOP = true ]
    echo "sudo ssh-keygen -f '/root/.ssh/known_hosts' -R $1"
    echo ""
    sudo ssh-keygen -f "/root/.ssh/known_hosts" -R $1

# Params: $1: host to deploy keys to
movekeys () {
  copyit "$1"
  moveit "/etc/ssh/ssh_host_key" "$USER@$1:/etc/ssh/"
  moveit "/etc/ssh/ssh_host_key.pub" "$USER@$1:/etc/ssh/"
  restartit  "$USER@$1"
  removeknown "$1"

set -e

declare -a Servers

Servers_minus_host=( ${Servers[@]/$HOST*/} )

for server in "${Servers_minus_host[@]}"
  movekeys $server

Some Thoughts On Soylent


I’ve gotten a variety of reactions when I’ve told people that I drink Soylent. Usually it’s gentle mocking or ‘BUT WHAT DOES IT TASTE LIKE???’. Both of these reactions make sense… on some level, I think I’m a bit crazy for drinking it. On the other hand, it saves me so much time. I currently drink Soylent for only about 8-10 meals per week, generally breakfast and lunch during the work week. Pre-Soylent, I spent hours on Sunday prepping my meals for the week or was constantly eating leftovers; either way, I was eating the same thing almost every day. Or even worse, I went out to lunch, spent $10, and ended up getting something that wasn’t very healthy for me. Soylent costs about $1.92/500kcal meal - plus one point for cheap! It’s also pretty well balanced nutritionally, so I know I’m getting a decent amount of nutrients per meal. The other benefit is it’s bland taste… it’s hard to describe, but I just don’t even think about it. Since I don’t think about it, I don’t get sick of it. Overall, I like it and I’ll probably keep ordering it for the foreseeable future.

Relevant to all of you programmers out there considering switching to the nerd smoothie.

Sanitize Text in Perl

One of the projects I’m working on is in Perl. Having never touched Perl before, this is a bit of a new adventure! Today I had to sanitize a field being passed by a url. This took me a few google searches before I found the right answer, so I’m going to write down the solution really quick here so I don’t forget it.

Here’s the code:

# assuming $message is your user-inputed data
use HTML::Entities;
my $encoded_message = HTML::Entities::encode($message);


Then you can print your $encoded_message out in html and you will not be vulnerable to XSS attacks.

I literally just looked at Perl for the first time today, so any tips are welcome!

When Bad Things Happen to Good Jobs

No job is perfect. This post is going to cover some types of those imperfections (from personal experience) and what you can do to fix it (or at least make your job a bit better). One piece of advice applicable across the board: if something seems off, document it. Get a weird IM? Save it. Even if something is good now, you’ve got to protect yourself in case the situation gets worse.

1. Retaliation

How to spot it

Retaliation is not acceptable at most companies. However, most people are aware of that, so the way they retaliate can be more nefarious and more difficult to prove. This is one situation in which it is definitely critical to document everything. The two things to look out for are: 1) did a triggering event happen? Example: did someone get fired and could you be blamed in any way? 2) has one of your coworkers’ behavior towards you changed dramatically? Example: did you formerly have a good relationship and now they are criticizing you and complaining about you?

How to fix it

If this person is not your boss, I would first talk to your boss. Unless you have direct proof, it doesn’t serve you to be acussatory, but you can at least clear your name. You can possibly say that you think the retaliator seems to have an issue with you and ask for advice on how to handle it, or ask if you should change teams or departments.

If this person is your boss, go directly to HR. Again, unless you have direct proof, I would stay away from harsh accusations. Say something like “I’m not sure what happened, but ever since [triggering event], Joe has treated me differently and I’m not sure it’s healthy for me to continue working under him.” Ask for advice, see if you can transfer to a different manager, and possibly start updating your resume. Do not be afraid to talk to HR because that is not a fireable offense. However, if it doesn’t go very well, it’s probably not the type of company you want to work for.

2. Boss Is Not a Good Manager

How to spot it

There are so many versions of this. My favorite is the super micro-manager. Or the “never there and you don’t know what to do” manager. Or the “for some reason wants to make sure you don’t grow professionally” manager. All are bad, just on different levels. Depending on how you work, the micro-manager or never-there manager might not be too bad. Or not.

How to fix it

When you have issues like this with your boss, I would go to HR directly, especially for the second two. If you aren’t getting support (because they are never there or are denying you the opportunity for advancement), that has a huge impact on your career and your productivity at the company. Most HR professionals will listen and try to find a solution. This happened to me and I was moved to a different boss within a few weeks. For the micro-manager, I would actually first try to talk to your boss directly, if they are approachable. If you frame it as you wanting the opportunity for more independence and “larger” projects, the conversation could go quite well. No one likes to be told that they are doing something wrong, so make sure it is about what you can do, not what they are doing wrong.

3. Boss Dislikes You

How to spot it

This one can be sorta hard to tell. I think that you can know, but it’s definitely hard to prove and your boss would probably never admit it. If they admit it, then I would go to HR. Otherwise…

How to fix it

If your work environment is good otherwise, I would stay and keep doing good work. Your boss may not be a good reference, but if you keep submitting excellent work, your coworkers will be. I had an experience like this (and my suspicions were confirmed after I left). I still had great work experience to add to my resume, great coworkers to add to my network, and just a man who I know I don’t want to work for again.

If your boss’ dislike of you is really affecting your work environment, I would polish up that resume and leave as soon as possible. If you have proof, take it to HR.

4. Coworkers Are Inaccessible/No Help

How to spot it

This can be a fairly common problem when you are a junior developer or a new employee. It can be especially common if a lot of people work from home and turn their IM off. This can be especially hard if you need to get a particular piece of information and the person everyone points you to is in their “dev cave”.

How to fix it

If you are in an office full of people like this, get out now. Teamwork is an important part of growing as an engineer and obviously you are in an environment that doesn’t value it. Gross.

However, this is unlikely. Most of the time it will be a small handful of people. Search out the people who are available and willing to help you and reach out to them. If you have a decent boss, request a one-on-one and discuss the situation with them. Most bosses want their team to communicate and will not be pleased if they find that quite a few of their engineers are radio silent most days.

5. Total Disrespect

How to spot it

This is luckily an uncommon problem and also can be really easy to spot. However, in my experience, it was the problem that I felt most like I could fix and yet was totally unfixable. If you are constantly getting second-guessed, but nothing you have said has been false or even inaccurate, that is a form of disrespect. If your superiors are saying negative things about you to other employees of the company, that is a form of disrespect.

Those are a bit more outright, but disrespect can also be less blatent and take the form of microagressions. For example, if your coworkers, especially your higher ups, are smiling and nodding at you, then completely ignoring your suggestions and doing the opposite of what they said they’d do (what you recommended), that can be a microagression and a form of disrespect. This can be hard to spot because it usually doesn’t happen all at once, but if you are stripped of the ability to do your job effectively, that is also a form of disrespect.

How to fix it

You probably can’t. Definitely document everything. In a situation like this, you can’t be sure what will happen. Save all your emails, save all your IMs, and, if possible (and with permission of the people in the meeting), record conversations. If this is actually happening with a company large enough to have HR, definitely go to HR. However, that is fairly unlikely. You can try to have conversations with the people or person who are/is being disrespectful, but you definitely have to be ready to quit. I’ve had one job on this level. I kept bringing things up and even coming up with solutions in meetings that were agreed upon, would think things would improve, and they never did. In the end, that was the only job I walked out on. As a human being, you should not be treated like that, but, if you are a programmer, the job market is good enough right now that you absolutely do not have to be treated like that.

Job Search Retrospective

Wow what a month. I’ve been interviewing for a little over a month now. Two weeks ago, I quit my job (post on that mess coming up in a a few more months) and somehow got a job offer the same day. This has definitely been my shortest job search (time when I submitted my first application to first offer), so I wanted to share what I think has been different.

Finding Potential Employers - Recruiters & Networking

So first things first… I may run a fairly large meetup group, but I’m actually pretty bad at networking. If you are a networker and can go to a ton of meetups and talk to people, that’s the best way, hands down. First interview I got was because I went up to someone who I knew was hiring at a conference and talked to them.

If you aren’t much of a networker (like myself), working with recruiters is the way to go. If you are in one of the areas they serve, I have had really good luck with Talener, their Boston office in particular. They have put me in front of some great companies and I’ve had a ton of in person interviews as a result. 

Many people say that you don’t get anywhere from submitting your resume just from the company’s website. NOT THE CASE! I got my last job like that and, during this search, I got a great interview by doing that.

Now that the interviews are lined up…


The biggest change is obviously experience. Time definitely makes each round of interviews a bit easier! There were a few other things that made it a bit easier though. 

The first was inspired by Julie Pagano’s own job search retrospective. I’ve never been very good at asking a bunch of questions, but I looked at the questions she and Julia Evans asked and took a bunch of my favorites. I had a notebook and wrote out all the questions and all the answers. This helped immensely because, not only did I find out more about the companies and how they worked, but it also helped turn the tables a bit to have me interviewing them. 

The second was that I finally actually thought of a good answer for ‘Tell us about an interesting/challenging problem that you have solved and how you did it’. I was asked variations of that question at almost every interview and this is the first year I felt I had something to talk about. I was just talking to a junior dev about this question and, really, anyone who has solved any problem with code should have an answer to this question. If you have a project, you must have created it to solve a problem. If you had a bug in your project and fixed it, there’s your problem. Sure, it’s not the most interesting, but you will get better and better answers as you gain more experience, and employers recognize that.

And the one thing you cannot forget in tech interviews, WHITEBOARDING. Three years into this and whiteboarding is still nerve-wracking and I still feel like I’m awful at it. One thing I have learned: how the interviewers interact with you while whiteboarding tells you a lot how they would interact with you when actually problem solving on that job. If someone is making you feel stupid while whiteboarding, then you probably don’t want to work with that person. On the flip side, If you are having a bit of trouble and the person interviewing you is actually helpful, then that is the type of person that you want to work with.


Interviewing is tough. No matter what level you’re at, you’ll get people who will tell you don’t have enough experience for the job. Don’t sweat it. It just means it’s not a good fit… you’ll find a good fit somewhere else :D

Chosen & Multiselect

I’ve been doing a bit of work jazzing up our multiple select boxes. These plugins are going to be familiar to most people, but if you haven’t looked into both of these, you should. I had previously been using jQuery multiselect in my current app but have recently switched to Chosen to make use of it’s search functionality. Here are the two that I’m going to highlight:

1) Chosen

Chosen gives you the ability to do a type-ahead search. Instead of scrolling down through a long list, I can start typing and see what options match. Particularly helpful in dealing with food… if I don’t like almonds, it’s nice to see that almonds, almond milk, and almond flour could all potentially be ingredients.

2) jQuery multiselect

jQuery multiselect does require the scroll down list. You can use a separate plugin for search capabilities, but, by default, it doesn’t include it. However, if you have a shorter list, this is a very nice way to let the user select and deselect items.