melreams.com

Nerrrrd

Stubbornness > intelligence

Unrelated image from pexels.com to make this post look nicer in social media shares.
Unrelated image from pexels.com to make this post look nicer in social media shares.

As part of my ongoing effort to demystify development, let’s talk about what personality traits actually matter even a little bit for developers.

There are tons of stereotypes out there about how you have to be super smart or great at math or have started programming when you were six to be a really good programmer. That’s all total bullshit.

I believe there is a single personality trait that’s extremely important to becoming a programmer, but it has nothing to do with how smart you are.

Intelligence, in as much as you can even measure something so poorly defined, simply does not matter. In my experience being clever has nothing to do with whether your code is readable or maintainable. I would much rather work with someone who knows they aren’t a genius and codes to avoid common mistakes than someone who is in love with how smart they think they are.

Being great at math can be helpful, but it’s by no means necessary. Math is really good practice at thinking through a problem one step at a time, particularly stuff like proofs, but if you’re not working on games or graphics programming you may never use any math more complicated than basic arithmetic in your day to day job.

Having started programming when you were very young can also be helpful because that gives you more years of experience, but it’s not as if there aren’t plenty of great programmers who never touched a computer until high school or even college.

So if none of those things really matter, what does? Stubbornness. I firmly believe the one personality trait you really need to be a programmer is stubbornness.

Programming, particularly when you’re just starting out, can be immensely frustrating. Teeny tiny little details like where exactly you put that semi-colon will ruin your day. The sheer amount of stuff you need to learn will seem totally overwhelming. You will feel stupid and think about quitting over and over and over.

Learning to code these days with friendly modern languages like python is certainly easier than learning assembler back in the day, but you need to be pretty stubborn to learn enough programming to be able to build something interesting.

But don’t think it’s all smooth sailing once you learn to code. Just the other day I spent a couple of hours debugging what I thought was an issue in my server code, but was actually me passing in the wrong parameter names through a javascript api like a dope. The more time you spend programming, the more horrible bugs you will run into, the more tough design problems you will have to solve, the more times you’ll have to figure out how to refactor existing code to get something new working, the more times you will kick yourself when the thing that seemed like a great idea six months ago turns out to be a terrible idea after all, and so on and so on.

As much as I love programming, I still think that you have to be a little bit weird to put up with this level of frustration. If programmers had the sense to do something that was less of a pain in the ass, they wouldn’t be programmers :)

What should you ask in an interview?

In a few of my how does it work? posts I’ve mentioned that asking about a particular data structure or algorithm is a boring interview question that doesn’t tell you much of anything about whether your candidate can code.

First of all, the reason I think asking someone to implement a data structure or an algorithm is boring is because all you learn by doing that is whether or not your candidate looked it up beforehand. Not even that, necessarily. Interviews are pretty stressful and plenty of people’s minds go blank when they’re stressed. I once choked on a question about the servlet lifecycle and it’s not like I don’t know how servlets work. If a question might tell you one thing and might tell you nothing, I don’t think it’s a good use of the limited amount of time you have in an interview.

Unrelated image from pexels.com to make this post look nicer in social media shares.
Unrelated image from pexels.com to make this post look nicer in social media shares.

I hate ridiculous brainteasers for the same reason – they’re just so binary.  Either your candidate gets the right answer or they don’t, which may or may not tell you anything because a stressful situation where you’re really scared of looking stupid is basically the worst possible environment to solve puzzles in.

Given all that, it seems fair to ask “Well what on earth should I ask in an interview?”

My take on it is that we’re overcomplicating the question. Which is kind of an occupational hazard, so don’t feel too bad about it :) Basically, if you want to know if someone can program, ask them about programming! Just straight up ask them how they would solve a problem.

One of my many pet peeves are wildly improbable scenarios questions like how many piano tuners are there in New York? Google, that’s how many. If you want to know how someone approaches a problem, just give them a programming problem. I really think it’s just weird to dance around the subject you really want to know about. You are allowed to straight up ask people about programming! It’s not as if programming problems are thin on the ground either (hey, what do you do all day again?), although it does take some work to find a problem that doesn’t require twenty minutes of backstory to explain why the problem is a problem. And if you’re asking improbable scenario questions because you want to see how a person thinks about a problem without them jumping directly into code, I think you’re depriving yourself of useful information. If somebody jumps directly into coding without thinking the problem through, I want to know that!

The kind of questions I think are interesting are realistic-ish (obviously you need something relatively simple if you want to ask more than two questions before you run out of time) scenarios like “given a system like x, how would you add feature y?” and “how does your solution change when you discover that the system is actually more like q than like x?” or “what would you do if production went down or was painfully slow?” or “given this description of a weird bug, what would you do to track it down and solve it?”

While every interviewing method has flaws, I like the idea of giving someone a take home project that either takes under two hours or that you pay them for, then talking about the choices they made in the interview. If you want to know if someone can code, just ask them to write some code! But for the love of god don’t ask them to do it on a whiteboard, that’s ridiculous. Coding on a whiteboard in no way resembles what a programmer does all day, even if your candidate is good at it it’s simply irrelevant to the job you’re trying to fill.

The downsides to take home projects are that they’re very biased in favour of people who have the free time outside of work to do them and that like everything else, it’s very very easy to do them badly. I’m willing to spend an hour or two on a take home project, but any more than that and I expect to get paid for my time.  That’s coming from someone who has no children, no pets, no elderly or sick relatives to look after, and practically no chores to do, too. For people who do have responsibilities, asking them to spend n hours of their scant free time on you is a big deal and you need to keep that in mind when you design your take home project.

Which is the other potential problem with take home projects: they need to actually take the amount of time you say they will. Yes, that means you need to have someone at the level you’re trying to hire for solve it first. I would say solve it yourself, but if you’ve been programming for ten years and you’re trying to fill a junior position, you need an actual junior to make sure what you’re asking for is reasonable.

That said, even the worst take home project is much more realistic than the ridiculous idea of asking people to take a short contract with you to see how they actually work with everyone in the office. There is basically zero chance anyone with any responsibilities is going to think “Sure, I’ll definitely quit my stable full-time permanent job to take a two week contract with some yahoo who might hire me if they decide they like me. What could go wrong?” That said, if you’re looking for people you can exploit, by all means keep hiring that way.

On a more cheerful note, a really good idea that came from a discussion on slack is having the candidate read some code and explain what it does. Most professional programming involves way more reading code and making sure you understand it, so much so that it seems like a really good idea to test people on that directly.

In general, ask stuff that directly relates to the job you’re asking someone to do. If you really do want them doing algorithm design then fine, ask them about algorithms. If you’re doing web apps, ask them about the frameworks you use or about general web concepts like concurrency, multi-threading, sessions, basic security, etc. If you do consulting, lean a little harder on scenarios where the candidate needs to ask questions to figure out what the client really needs, which is usually not what they asked for.

What do you think, readers? Do you have any favourite interview questions?

Programming is actually a creative field

There’s this stereotype that programming isn’t a creative field, that programmers do nothing but mechanically assemble code all day. I find that really sad, I think if we did a better job of explaining how creative programming actually is many more people would be willing to give it a shot.

If you’ve only ever had a total beginner intro to programming, it might be really hard to see where the creativity comes in. Honestly, variables are pretty boring and conditionals aren’t much better. Programming gets a lot more interesting once you’ve mastered the basics, I swear :)

Programming is a bit like building things with lego blocks, except that you have to make all the blocks yourself. Building the blocks – that is, writing an if statement or creating a variable – isn’t that interesting, I’ll be honest. But once you get good at creating those blocks, that’s when you get to be creative. Just like you can build a castle or a siege engine or an entire lego Westeros out of simple little blocks, you can build amazing things out of variables and loops and conditionals if you’re patient.

It’s also a bit like pottery or wood working. Just because you’re constrained to making a usable cup or chair doesn’t mean you can’t be incredibly creative within those constraints. Even in visual art or writing you need sentences that make sense and a combination of shapes and colours that work. Jokes about modern art aside, you can’t just throw paint in the direction of the canvas and expect anyone to care what you’ve done.

There are always constraints on anything you make, programming just has particularly rigid ones. An imperfect sentence is still intelligible, but a missing semicolon will keep your code from compiling at all. For some people that’s more frustration than they care to deal with, for others it’s an interesting challenge.

Building your own project that does anything you want it to is pretty obviously creative, but what about programming at work where you’re given assignments?

Even the least interesting internal application still requires creative problem solving to add new features or fix bugs. There have been times when I’ve had to be very creative to change an application in a way that meets the new requirements without breaking anything that used to work and without making a horrifying mess of the code. There are often quick and dirty ways to make a change that just leave you with more trouble in the long run, and sometimes (in an emergency, for example) they’re the least bad option, but usually you think about not just how you can make the change that’s necessary right now but how you can set things up so that you can make more changes in the future without tearing your hair out.

There’s never just one way to do that, either. When you’re working through a beginner tutorial it will probably look like there’s one right way to build any application and you can’t be creative at all once you’ve decided what you’re going to build and what the user interface should look like. That’s totally untrue. Once you’re working on anything larger than a simple assignment to write a for loop, you enter the world of trade-offs. There’s never only one way to solve a problem and each solution has its own pros and cons.

For example, optimizing code so it runs faster involves a lot of decisions about trade-offs and a lot of creative problem solving. Optimizing code usually makes it harder to read, which makes it harder to update if you need a new feature or find a bug. This matters a whole lot when you’re running a business because programmer time is so expensive. On the other hand, if your program runs so slowly that no one wants to use it (and pay for it!), it doesn’t matter how nice the code is to work with. Sometimes you absolutely need your code to run as fast as possible and unclear code is worth it to get your game to run at a decent frame rate. Other times performance isn’t your highest priority and what you really need is to be able to read and change your code quickly because you get requests for new features all the time.

In short, I build things all day. How is that not creative?

Failure

Everybody screws up sometimes and I wish we talked about it more. One of many things that I think scares off new programmers is the belief that if you ever fuck up then you’re just not cut out to be a programmer. That’s totally not true, even experienced professional programmers make mistakes. All making a mistake means is that you tried to do something that’s actually difficult, it’s not the end of the world.

a relaxing view of rolling hills dotted with trees and a field with a flock of sheep and a shepherd
Look at some relaxing sheep from pexels.com while we talk about making mistakes.

In the spirit of helping other people not freak out about their own mistakes, let’s talk about some of mine.

Early in my career I came up with a truly terrible design for a portlet (remember portlets? No? Okay, I feel old now). If I remember correctly it was supposed to provide a friendly UI for people to create their own report queries, so there were all sorts of rules about which kinds of values applied to each field and how fields could be combined to keep track of. This was back before I really understood that requirements never ever stay the same, and after a couple rounds of changes my design was a real mess. If nothing had ever changed my house of cards might have been okay, but since things did it started to crack and warp under the strain.

What did I learn from that one? That requirements always change and your design needs to handle that, and that it’s always a good idea to have someone else review your design before you start building, especially if you don’t have a lot of experience. Designing software to handle requirement changes is something I’m still working on and something that could fill a whole book, let alone a blog post, so I’ll just say that asking yourself what happens if you need to add more rules or take some away is a good start.

Another thing I messed up I already mentioned in my post If it’s hard to explain, it’s probably a bad idea. To recap really quickly, we (the backend team on the project) came up with a scheme to sort players into rooms that was basically impossible to explain to non-programmers. Actually, I’m not sure it ever even made sense to the devs on the client team either. I bring that one up again to drive home the point that design is hard and you’re going to screw it up a lot before you get good at it.

What I learned from that mistake was that designing in isolation can really trip you up. That design seemed like a good idea to us backend devs in isolation, but if we had run it past the rest of the team first we could have figured out it was confusing and a bad experience for the users before we wasted weeks building something that ended up being confusing and frustrating for the people who actually used it.

I’ve also really fouled things up with databases. I once took down production by making a data model change that had run fine in test. Turns out things run differently when a) there’s actual load on the database, and b) there are orders of magnitude more rows in prod than in test. Now I know not to try to make data model changes in mysql cluster without taking the app down for maintenance.

Sadly, that’s not the only time a difference between prod and test has tripped me up. The amount of data in your database can change the way mysql optimizes its queries, which can lead to some really interesting results when you assume the database is using an index that it’s actually blissfully ignoring. And by interesting I mean unusably slow response times. Wheee.

What that one really drove home for me is that you can’t trust the test database unless there’s a full production dump in there and you’re simulating realistic load. Outside of a perfect clone of production, load included, you need to lean on explain plans. Explain plans are great because they tell you how things are going to run into production without actually migrating your whole application to prod and breaking everything. Next time, I’m running explain plans first in production instead of assuming things will be fine because it worked in a test database with a few hundred rows.

Another really entertaining screw up I’ve had was when we were preparing to turn off an online game that wasn’t performing well and was a maintenance nightmare on top of that. We thought that it would be a nice gesture to make the virtual game cards (kind of like a virtual scratch ticket) in the game free so they could play as much as they wanted until we turned the game off entirely. The design of the game didn’t allow us to make the cards entirely free, but it did allow us to make everything cost only one token. Normally higher level game cards cost hundreds of tokens, so we figured players were still getting a pretty good deal.

Unfortunately, I didn’t think through the consequences of players being able to buy hundreds more game cards than usual. On each card you could win credits (thankfully you couldn’t buy more cards with those credits or we really would have been in trouble) that you could use to buy prizes in the store. Normally the number of credits you could possibly win at one time was limited by how many cards you could afford, with the higher level ones that gave out lots of credits being so expensive that you could only buy a few at a time.

Does anyone see where this is going? Yes, overflows! We let players win so many credits that the fields in the database couldn’t hold their winnings. Once we fixed the database we discovered that parts of the game server code couldn’t handle those numbers either. It was a rough few days trying to get that game back into action.

There are two main things I learned from that experience, one specific to the problems we had and one less so.

One – do not make sweeping changes to a game’s economy! Just don’t do it, it’s a bad idea and will make you unhappy. The next time we sunsetted a game (the industry’s polite euphemism for killing it) we most certainly did not destroy the economy on the way out.

Two – the consequences of an action aren’t always obvious, you’ve got to put some work into figuring out what’s going to happen when you change things. If I had that particular change to do over again, I would look at how many daily tokens our top players were getting and calculate how many game cards they could buy with those tokens and how many credits they could win off of those game cards. Then I would try manually giving myself that many credits and tokens in test and see what happens. After watching everything blow up, I would go back to the product manager and say “1 credit game cards break the game, how about we just give players 50% off?”

Let’s mix things up a little. I have one more failure to talk about, but this time it’s not one of mine. Here’s the notification I got about a sad little troll trying to comment on my Shitty hackathon! post:

New comment on your post “Shitty hackathon!”
Date: 10 February, 2016 11:43
Author: Nancy Grace (IP: 72.39.146.43, d72-39-146-43.home1.cgocable.net)
Email: toolofoppression@gmail.com
URL:
Comment: I must say, that I am impressed. Keep it up, and one day you just might earn your official script kiddie participation award. In the meantime, don’t quit your night prostitution job just yet ;)

Now, it’s pretty clear that this shitheap is unable to learn (if he was, he would be good enough at his job not to be frightened of a woman talking about code), but other readers can learn something from this. First of all, it’s pretty clear that he’s terrified of women developers. That in turn makes it obvious he sucks at his job, because with the shortage of developers you have to be a serious fuckup to be afraid a girl will come and steal your job. It’s also pretty sad that he had to go digging three pages back from my front page. Poor bastard had to go past two of my posts about SOLID design principles and my post about Java synchronization and my post about different languages being good for different things before he found something that he thought he could smear his poop on like the shitty little baby he is.

If you’re going to try to shit on me for not being a perfect programmer, get it right! I’m embarrassed for you and I don’t even like you, fuckstick.

However, fuckstick does accidentally bring up something in the vague (astronomically vague) vicinity of a point: if you talk openly about your failures, it’s possible someone will give you shit for having the unbelievable gall to be a human instead of a robot. You should ignore those people because they’re stupid :) No seriously, you do not want to work with or for anyone who is so willfully ignorant of what software development actually is that they think it’s possible to do this without ever making mistakes. If god forbid your boss shows you that they know that little about development, they’ve given you the gift of complete certainty that you need to run. Everybody in Victoria is hiring right now and developers are in demand all over, there’s no reason to put up with a boss who doesn’t understand their industry.

Another reason to talk openly about your failures, especially on your blog, is that when the classic interview question comes up, you’ll have something to say already lined up. You could even share a link to your blog post if you’re less of a potty mouth than I am :)

How about you, readers? What have you screwed up and what did you learn?

Development is maintenance

Professional programming and the kind of programming you learn in college/university/bootcamp/etc are actually very different things. Despite what you learned in school, development is really maintenance. In other words, I’m here to crush your dreams :)

So, you know how in school you started new projects from the ground up all the time? Yeah, you’ll hardly ever do that at work.

Now, sometimes you will need to research new technologies and/or frameworks and starting a new prototype project is usually a part of that, and sometimes even the largest and slowest moving organization needs to start something completely new, but that’s generally a very small part of the job.

What you’ll actually spend most of your time doing as a professional developer is adding features and fixing bugs in an existing product. That’s such a large part of the job that I wish we’d done more (or any) of it in school. For anyone reading this who is learning to code, I strongly recommend taking sample projects or open source projects or whatever you can get your hands on and adding new features or fixing bugs. Learning to read other people’s code is hugely important and you may only barely touch on it in your studies.

To be fair, just learning to code takes a lot of time and you can only cram so much into any one program without keeping students there for years and years, but I wish we put a little more emphasis on what software developers actually do at work most of the time. I also wish we’d spent more time on why design is such a big deal.

One of the consequences of hardly ever starting completely new projects at work is that the few projects that do get started are extremely long lived. Instead of a tiny throw-away project that you spend maybe a week building and then never touch again, you’ll work with applications that live for years or even decades. This can be really weird to adjust to since the lifespan of those projects means every tiny decision you made in five minutes can come back to haunt you for years to come :)

On the other hand, long lived projects have a much greater impact than tiny little throw-aways. If you do a good job, the code you write can make people’s lives a little bit easier for years and years. You can also build much larger things, whether they’re applications, games, frameworks, or something else entirely, when you have years to work on something. Corporate software development isn’t all bad, you get to work on things that you could never build on your own.

Another way professional development is different from school projects is that requirements always, always change. Even if every feature you add is perfect and bug free (ha!), your users are going to ask for new things and/or discover that the feature they asked for isn’t actually what they needed and the business might expand into new areas and the laws that your business has to follow might change. Sometimes technical requirements even drive changes: if a new version of your database or framework or a library you depend on comes out, eventually you’re going to want to switch to that.

The requirements changes can be infuriating, I’m not going to sugar-coat that. But at least you get to work on something that people care enough about to ask for changes, even if sometimes it seems like they have no idea what they actually want. If you never had to change a piece of software, all that would mean was that absolutely nobody was using it. I  don’t know about you but I think it’s pretty cool that people actually use the stuff I build.

Real world software development is very, very different from what you do in school, so don’t be surprised if it takes you a little while to find your feet. As much as it can be frustrating sometimes, there are some really cool upsides too.

If it’s hard to explain, it’s probably a bad idea

One of the things I struggled with when I was new to programming was how to tell whether a given piece of code is good or not. When everything is new and confusing, how do you tell bad confusing from normal confusing?

One thing that will give you a very helpful hint is if you code is hard to explain. Like this Python style guide puts it:

If the implementation is hard to explain, it’s a bad idea. This is a general software engineering principle — but applies very well to Python code. Most Python functions and objects can have an easy-to-explain implementation. If it’s hard to explain, it’s probably a bad idea. Usually you can make a hard-to-explain function easier-to-explain via “divide and conquer” — split it into several functions.

Basically, if something you’re working on is hard to explain, that’s a sign that it needs to be re-thought. Some problems are just unavoidably complex, but it should still be possible to explain what you’re doing at a high level.

That applies to higher level application logic just as much as to individual functions. At a previous job I worked on a multiplayer game project that involved putting groups of players into rooms together for each round, then closing down that room when the round was over and creating a new one. Our first implementation seemed like a good idea at the time, but when we got the game to a point where the team could play together, we had a terrible time explaining how players were sorted into rooms the to the artists and project manager.

The non-programmers on the team were by no means stupid people and had been working on the game for quite a while by that point. The fact that we couldn’t explain our room selection scheme to them was a very strong sign that what we were doing just didn’t make sense. As we kept playing our in-progress game, it also turned out that it was extremely difficult to get the whole team into the same room. There were less than a dozen of us working on that game, so there was really no good reason for it to be that hard to play together.

In the end, we admitted our room selection logic wasn’t working and rewrote it to be much simpler. Players sometimes had to wait a bit longer for a round to start, but they could play with their friends more easily and stay in the same room with the people they played with last round. The simpler logic that was easier to explain was also a better experience for the players.

I’m not going to pretend you’ll never run into anyone who is invested in not understanding what you’re trying to explain to them, but if you give someone an overview of what you’re up to and they don’t follow it, think about whether you’re doing something overly complicated before you assume the person you’re trying to explain it to is just dumb. Complicated code is harder to test, harder to debug, and harder to change when you get a new feature request. It’s worth paying attention to seemingly unimportant signs like having a hard time explaining your code to someone else because it can save you so much time in the long run.

Productivity is overrated

A little while ago I posted a productivity tip and immediately started worrying that I sounded like one of those awful productivity gurus who preach maximum productivity all day every day what do you mean leisure has value?

I want to be very clear here: my worth as a human being is not measured by how much stuff I get done and neither is yours. My sole interest in productivity is breaking the shame spiral.

The shame spiral I’m talking about is the horrible feedback loop where you procrastinate, feel ashamed of not getting enough done, procrastinate more because you associate the work with shame, feeling more ashamed because you’re still not getting anything done and on and on. I don’t want you to be the perfect [insert work here]-producing machine, I want you to be happy and to feel good about what you’ve done at the end of the day. In fact, I actively want you to not be a perfect work-producing machine because that’s no way to live. If you don’t enjoy your life and have time for friends and family (chosen or assigned) and hobbies it doesn’t matter how much you get done.

You will never ever hear productivity tips from me about shit like how much work you can get done if you start waking up at 5 am or how you should listen to professional development audiobooks on your commute. You are allowed to listen to music and relax on your way to work. You do not have to cram something useful into every minute of every day.

A question I hardly ever see anyone ask in articles or blog posts about productivity is why you want to be more productive. Everyone just assumes that getting more done must automatically be a good thing. Getting stuff done is a great feeling if it’s something important to you and you’re not pushing yourself into burnout, but you know what else is great? Downtime. Playing a boardgame with your friends or trying out a new restaurant or going for a walk or reading a novel.

Personally, I do feel unfulfilled if I do nothing but play computer games when I come home from work for too many days in a row. I like the sense of accomplishment that comes from making progress on personal projects. But just like computer games can’t be my whole life, neither can work. That’s just not healthy and that lack of perspective leads to shitty work anyway.

Before you look at a productivity tip, ask yourself why you want to get more done. If you have a project that you want to finish, great! But if you feel guilty if you’re not doing something useful every minute of every day or you don’t want your parents to be disappointed in you or you feel like you’ll be left behind if you don’t spend every minute working, you officially have my permission to say “Fuck it, I’m going to go play videogames.” Don’t be productive for the sake of being productive, do stuff that’s either personally meaningful to you or fun.

 

Degrees aren’t everything

A common worry I see in self-taught developers is that not having a degree means that you’re not a good programmer and no one will hire you. I’m not going to lie, having a degree does make it easier to get an interview, but it in no way guarantees that everyone with a degree is a better programmer than everyone without.

Here’s a fun fact about hiring developers: having a degree tells interviewers so little about whether you can code that people came up with the idea of asking candidates to code a very, very simple math “game” called fizzbuzz to figure out if you can write a for loop all by yourself. I’m completely serious, in the mid-late 2000’s fizzbuzz was all over the programmer blogosphere. If you poke around online you will likely find a bunch of criticism about how fizzbuzz is too simple to tell you anything interesting about a junior programmer candidate, which I think is true but is not the point of this post.

Three women of colour having a meeting in a boardroom
Photo provided by WOCInTechChat under a CC Attribution-ShareAlike License

Back at my point, it sounds completely ridiculous that you would need to ask a new college/university grad to prove they can write a for loop and a couple of conditionals. How could someone graduate and not be able to code? That question really deserves its own blog post, but part of it is that memorizing facts for a test is a very different skill than writing code on the spot to solve a problem.

Ridiculous or not, people started asking developers to code fizzbuzz for a reason and it’s not because hiring without it worked so well. Fizzbuzz exists as a programming concept because interviewers needed a quick way to weed out people who simply couldn’t program at all.

If you don’t have a degree, don’t feel bad. If you can program at all, then you’re already ahead of the game. You’re probably just as good a coder as anyone who does have one. In a lot of ways being self-taught is more impressive because once you make the decision to go to college/university you’re essentially locked in. Aside from feeling like you have to get your money’s worth once you’ve started paying for a degree, there’s a massive amount of social pressure not to drop out and feel like you’ve disappointed your family and friends.

If you study something on your own time, on the other hand, then it’s much easier to just stop when you’re bored or it’s hard or you’d rather go have a pint with some friends. When nobody will know or necessarily care that you stopped, it’s a lot harder to keep going.

To be fair, having a degree/diploma/certificate from a bootcamp/etc does open doors, and you can end up with really frustrating gaps in your knowledge if you’re self-taught. My husband is a sysadmin but he grudgingly does a little bit of programming when he has to (he’s weird and thinks setting up servers is more fun than writing code). Not so long ago I had to tell him about maps/associative arrays/dictionaries because the last programming class he took was in high school and the language they used didn’t have maps. Turns out there was a point to all the time my teachers spent hammering datatypes into our heads in college after all :)

A degree or a diploma doesn’t mean anyone is special or a better programmer than you are. It really just means they had the good luck and inclination to pick up a degree and some ability to follow through, at least when a large amount of money and the prospect of their parents being disappointed is on the line. Who knows, maybe you’ll be the one asking new grads to code fizzbuzz one day.

Different languages are good for different things

As you learn to code and learn new programming languages you’ll often hear that different languages are good for different things. Technically you can do just about anything in any language, so for a long time that never meant much to me. Once you get past basic conditionals and loops, there actually are pretty major differences in how easy it is to do different things in different languages.

Here’s a handy example: the other day I wanted to figure out how much I spend on average each month so I could figure out how much I can reliably throw into my RRSP. Okay, use mint, you say. Not so fast there! I only wanted to know about my expenses NOT including RRSP and TFSA contributions, and I wanted to leave out the month I got married because it’s a huge outlier and screws up my average :) If you can get mint to do that, I’d love to hear how.

What I ended up doing was downloading my transaction history as a csv from my bank and manually removing the stuff I didn’t want to include. Then I needed to create monthly totals (so I could see if those looked reasonable) and an overall average somehow. I was hoping I could do that with a simple formula in a spreadsheet, but after fiddling with it for a bit I decided I’d rather poke myself in the eye than stick with that idea.

Python to the rescue! Not so long ago I was a mentor at a Ladies Learning Code workshop about data processing with Python. At the end of that workshop we ended up with a little script that read in a csv, did some processing, and output the results, which is exactly what I needed. I started with that script and ended up with this:

# Import the csv library
import csv
import datetime

# Open the statement file
statement_file = open('./statement.csv')

# Convert it to a csv_data structure
statement_data = csv.DictReader(statement_file)
current_month = -1
current_year = -1
months = 0
grand_total = 0.0
running_total = 0
# Loop through each of the rows
for transaction in statement_data:
    # deposits have a blank in the withdrawal field, we only want withdrawals
    if transaction['withdrawal'] is not '':
        #convert the string date to a date object so we can get the month
        date = datetime.datetime.strptime(transaction["date"], '%d-%b-%Y')
        #every time we hit a row where the month doesn't match the month from
        #the last row we know it's a new month and we need to update current
        # month & year and increment the month count
        if date.month != current_month:
            if current_month > -1:
                months += 1
                #print current_month instead of date.month because date.month
                #is the new month
                print(str(current_month) + "-" + str(current_year)
                      + " monthly total: " + str(running_total))
            current_month = date.month
            current_year = date.year
            running_total = 0
        running_total += float(transaction["withdrawal"])
        grand_total += float(transaction["withdrawal"])

# one more print statement for the last month in the file
print(str(current_month) + "-" + str(current_year) + " monthly total: "
      + str(running_total))

average = grand_total / months
print("avg: " + str(average) + " over " + str(months) + " months")

Then I started thinking, that was weirdly easy considering that since college I’ve touched Python twice – once while preparing for that Ladies Learning Code workshop and once while actually mentoring at the workshop. That made me wonder how Java, the language I’ve used just about every day at work for the last nine years, would compare. So I ported my Python script to Java and this is what I ended up with:

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;

public class Calc {
    public static void main(String[] args) {
        try {
            int monthCount = 0;
            int currentMonth = -1;
            int currentYear = -1;
            float grandTotal = 0;
            float runningTotal = 0;
            // open the statement csv
            Reader in = new FileReader("statement.csv");
            // parse it into CSVRecords so we can get values out more easily
            // unlike python this CSV library doesn't seem to automagically
            // figure out what a header row is so I had to add the headers
            // manually
            Iterable<CSVRecord> records = CSVFormat.DEFAULT.withHeader(
                    "account", "date", "desc", "num", "withdrawal", "deposit",
                    "balance").parse(in);
            // loop through each of the rows
            for (CSVRecord record : records) {
                String dateStr = record.get("date");
                String withdrawalStr = record.get("withdrawal");
                // deposits have a blank in the withdrawal field, we only want
                // withdrawals
                if (withdrawalStr != null && !withdrawalStr.equals("")) {
                    // java requires a lot of boilerplate around parsing a
                    // string into a date that we can get a month out of
                    DateFormat df = new SimpleDateFormat("d-MMM-yyyy");
                    Date transactionDate = df.parse(dateStr);
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(transactionDate);
                    // every time we hit a row where the month doesn't match 
                    // the month from the last row we know it's a new month 
                    // and we need to update the current month and increment 
                    // the month count. technically we can get the month 
                    // using transactionDate.getMonth() but that method is 
                    // deprecated and I'm trying to set a good example
                    if (cal.get(Calendar.MONTH) != currentMonth) {
                        monthCount++;
                        if (currentMonth > -1) {
                            // in java months start from 0, add 1 so we get
                            // nicer looking output
                            System.out.println((currentMonth + 1) + "-"
                                    + currentYear + " monthly total: "
                                    + runningTotal);
                        }
                        currentMonth = cal.get(Calendar.MONTH);
                        currentYear = cal.get(Calendar.YEAR);
                        runningTotal = 0;
                    }

                    float withdrawal = Float.parseFloat(withdrawalStr);
                    grandTotal += withdrawal;
                    runningTotal += withdrawal;
                }
            }
            // one more print statement for the last month in the file
            System.out.println((currentMonth + 1) + "-" + currentYear
                    + " monthly total: " + runningTotal);
            float average = grandTotal / monthCount;
            // the one convenient thing java does here is 'autoboxing' - it
            // automatically converts non-strings into strings when you try to
            // add them to a string
            System.out.println("avg: " + average + " over " + monthCount
                    + " months");
        } catch (IOException | ParseException e) {
            e.printStackTrace();
        }
    }
}

In a word, ugh. File processing scripts are not even slightly what Java is good at. Everything I needed for the Python script was part of the Python language. For the Java version, I had to go hunt down a library and add it to my project, which required knowing that there probably was a library, knowing how to add it to my build path, and figuring out how to use it.

Even the least terrible csv library I was able to find for Java inside of five minutes of googling (Apache Commons CSV, if you’re curious) was much harder to use as Python’s builtin csv handling. Java’s date parsing also requires way more steps than Python’s does. And to run this in Java you have to know about main methods and all the boilerplate around them. Even if you just let your IDE generate that for you, you still need to know it exists and what it’s for.

Basically you have to fight Java to do something like my average monthly spending script. You can still do it, but it’s much more work than it has to be. Java is great for big enterprisey systems with APIs and multiple programmers working on different pieces, but it’s kind of painful for little scripts to parse a csv and do some processing. Python, on the other hand, rocks at stuff like that. I hope this helps you understand what people actually mean when they say different languages are good for different things.

I Google things professionally

It’s pretty common to hear developers joke about how they get paid to Google things. Fun fact: we’re only kind of kidding. An enormous part of my job is Googling stuff.

Tech changes so quickly it’s just not possible to know everything. It’s definitely not possible to keep up with everything, and it’s especially not possible to know the entire tech stack a new job uses. No two company’s tech stacks are the same (we use AWS, play, Java, Ember, javascript, and bootstrap, just to name a few of the languages and frameworks in our app. At my last job we used spring, jetty/tomcat depending on the app, an internal front end framework, Facebook’s hideous sdk, and Flash (AS3) and Unity on the front end), and even if you did magically know all of those technologies before you started, given a few months it wouldn’t matter. No matter what you use right now, things are going to change. You’ll try out a new front-end framework, integrate with a new system, be asked to build a feature that requires a new library, something will happen that means you’ll need to learn something new.

two women of colour working together at an Apple laptop
Photo provided by WOCInTechChat under a CC Attribution-ShareAlike License

This is why developers spend so much time Googling. We have to learn new stuff constantly. Don’t feel bad about not knowing everything, no one else does either.

Even if your tech stack didn’t change, you would still get asked to build new stuff all the time and honestly, your problem is probably not unique. Even if you already have a plan, it’s not going to hurt to do a quick search and see if someone else has a better way to solve your problem. If you don’t already know how to solve it, Google is here for you. Why reinvent the wheel? You could call that laziness but honestly it’s inefficient to fight with a problem for hours when you could just ask Google for a hint. Work is not an exam, you’re getting graded on how much you produce and how solid it is, not the intellectual purity of your solution. Plus, next time you have to solve a similar problem you’ll remember what you did last time.

Now, you do need to make sure you actually understand the code you found (and that you’re not violating any licences or anything), but if you’re a professional you’re doing that anyway, right? If you don’t understand your code you’re just going to end up wasting time chasing down weird bugs. Don’t forget that software is at least 90% maintenance, you will touch that code again and you need to understand it when you do.

Of course, I’m being a little bit flippant when I say I Google things professionally. A big part of being a professional is knowing how to search, what to search for, and how to tell useful results from dead ends. Learning how to look stuff up is a real skill and it’s one that takes practice. You also need a bit of a knowledge base to tell good results from bad ones. That is, the more you know about, say, Java, the easier it is to tell a good solution from a bad one. A combination of having a feel for the way Java does things and knowing what good Java looks like makes it much easier for me to tell whether that Stack Overflow result is actually a clever solution or whether it’s a filthy hack. Sometimes you do need to use the filthy hack but you should at least know that’s what you’re doing and add a comment about it.

Software development is at least as much about knowing how to learn as it is about knowing stuff in the first place. If you can learn how to search effectively and are willing to brute force (seriously, a huge amount of my college education was banging my head against java until it started to make sense) the conceptual framework that lets you make sense of the results you’ll get when you search, you can be a programmer. It’s not all Google but honestly if you’re good at Googling and are weird enough to actually enjoy programming, you can do it professionally. We like to pretend we’re wizards but it’s mostly Google :)