Not long ago I read this blog post Why Learning to Code is So Damn Hard, which makes a really interesting point about the “desert of despair” between beginning to learn to code and having the skills to build a complete project on your own. The desert of despair, according to the post (which I agree with) is a combination of lack of resources for learners who are between beginner and expert, and having learned enough to know how much you still have to learn. Many aspiring coders get lost in the desert of despair and never find their way out.
I also read Amy Hoy’s post 5 Things I Wish Somebody Told Me Before I Founded My SaaS. One of the points I found the most interesting was that there’s always another inflection point. By inflection point, she means “those knife-edges you tip toe along, when things could go either way, when you are, say… trying to grow your team but lack the time/revenue to do it, but growing your team would help increase the time/revenue to the point where you could grow your team. Ouch. To me, that’s the prototypical inflection point.”
Where this ties back to the other post is where Amy says “Over the last 8 years running this biz, I have said so many times: “We just have to get through this $INFLECTIONPOINT and then things will get easier.”” Doesn’t that remind you of programming?
If I can just learn enough to get my code to compile then things will be easier.
If I can just learn enough to add a feature to an existing project then things will be easier.
If I can just learn enough to start a project on my own, then things will be easier.
If I can just learn enough to break my code down into good methods, then things will be easier.
If I can just learn enough to break my code down into good classes, then things will be easier.
If I can just learn enough to break my code down into good layers, then things will be easier.
If I can just learn enough design patterns, then things will be easier.
If I can just learn this new framework, then things will be easier.
If I can just learn this new style of programming, then things will be easier.
If I can just build enough different projects, then things will be easier.
If I can just learn enough…
There’s always going to be something else to learn, it’s never going to become easy and stay that way. Things do get easier once you find your way out of the desert of despair, but initially learning to code just leads to worrying about whether your code is good leads to worrying about design and architecture and scalability and reliability and security and those are seriously hard problems.
Despite how it may sound, I’m actually not trying to say that coding will suck forever and you should just give up. I’m saying that it’s normal to feel like you still suck at this even after years of working as a programmer. You don’t actually suck, it’s just normal to feel that way. What’s really happening is you’ve levelled up. When you do that you see the problems that used to give you trouble as too simple to count and focus on the stuff you aren’t good at yet, which can easily make you think you suck.
The thing I struggle with is design. I’ve been at this for ten years now and I’m still never sure if I’ll regret the design I’ve come up with the next time we add a feature to the system. Plenty of times I’ve come up with something that seemed like a good idea at the time, only to find out that it had serious flaws when I came back and changed it later.
It’s tough sometimes but on the upside, you will never ever run out of things to learn as a programmer :)
Much like development is maintenance and a creative field, development is also communication. One of the hardest problems I’ve run into with programming isn’t the programming itself, it’s making sure I’m actually building the right thing and fully understand the requirements.
Just because it’s obvious to you that a feature should work a certain way doesn’t mean it isn’t equally obvious to someone else that it should work a different way. Not that I’ve ever gotten burned by that or anything ;) As overly simple as it sounds, it can be really helpful to talk your plan for building a feature over with the person who came up with the requirements and your team lead. Something as simple as having a quick chat about how you’re going to build a feature can uncover assumptions you’ve made that aren’t right or things you missed or even existing code you didn’t know about that could really help.
If you’re working directly with other developers on the same project, it’s possibly even more important to communicate with them. At the very least you need to figure out who does which piece and how your code will work together. If you can divide a project into nicely separated pieces with an interface or API between them that definitely makes things easier, but you still need to keep in touch. Interfaces can change as you build and discover what you actually need, parts of the project can be delayed, there are all kinds of things other people on your project might want to know about.
Even if you’re not on the same project, it’s still useful to communicate with your team. If nothing else, your team lead needs to know how your task is going so they can get ready to assign you more work or re-assign a task they were going to give you if you hit a snag.
Stubbornness is more important than intelligence or talent when you’re learning to code, but that doesn’t mean it’s useful all the time. Listening to other people’s ideas is just as important as refusing to give up. It’s tempting to stubbornly insist on doing things your way, but that’s only going to hurt your project and piss off your team. An idea being yours doesn’t mean it’s the best way to do it. Of course, another dev, even a more senior one, having an idea doesn’t magically make that one perfect either, that’s why it’s so important to talk things out. It’s nice when you get to implement your own ideas, but it’s best for your project if you implement the best ideas you have available, whether those came from you or from someone else on your team.
Whether or not you actually take their suggestions, it’s really important to listen to your team. Despite what you may have heard, software development involves surprisingly little coding in a basement far away from all human contact. Professional software development is fundamentally a team sport, very little of it is so small that a single person can build and maintain an application by themselves. Working with a team means you need to get along with them and listening to them is a big part of that. If you bother asking for anyone else’s opinion, you need to give it a fair shot and seriously consider implementing it. If your mind is already made up, do the polite thing and don’t waste people’s time by asking for opinions you’re not actually going to listen to.
The preceding rant is brought to you by the many horror stories I’ve read online about people who label their listening problems someone else’s communication problem. Listening is communication. Without it, no information gets shared.
Communication skills are at least as important as hard development skills if you want to make a living as a developer. If I had to choose just one, I’d say communication is more important. Someone who will listen to me and explain what they’re doing can learn to code or code better. There’s nothing you can do with someone who can’t communicate. That doesn’t mean you have to be perfect at it – I’m certainly not – just that you’ve got to try.
So last Monday I talked about how frustrating programming can be and how important sheer bloody-mindedness is if you want to be a programmer. If that made you wonder why on earth someone would choose to do this, I couldn’t blame you :)
I love programming because I love building things. It’s just fun to make stuff – who doesn’t love LEGO? But even better than LEGO, if you mess up when you’re programming you can just revert to an earlier version, and if you want to experiment with an idea that might not work out you can create a separate branch for it.
While programming can be frustrating, there’s no physical material I know of that’s anywhere near as easy to work with. Buildings, machines, and even sculptures need to obey the laws of physics where the biggest restriction on programmers is our own ability to design a system. There are certainly things that are likely to get you into trouble, but with code as with writing, you can break all sorts of rules if you’re good enough to get away with it.
Programming is also a lot like solving a puzzle, something else I’ve loved since I was a kid. One of my favourites was the IQ block – I had a plastic one that came in a little case and it was so satisfying to get all the pieces to fit back inside it. I get the exact same satisfaction out of fixing a bug or getting a new feature working, but even more so because programs have so many moving parts. If you enjoy puzzles, code is about as complicated of a puzzle as you can find.
I get bored pretty quickly if I feel like I’m doing the same thing over and over, so the constant learning when you’re programming is great for me. There’s always something new to learn whether it’s another language, a design technique, a new tool, a new technology, or just a new way to do something. If you go into programming, you may get frustrated but you’ll never get bored :)
While professional programming is a generally a team sport, it’s amazing how much one programmer can get done on their own. It takes a factory to build a car and a team to build a house, but one programmer can knock out app after app if they want to. It’s just cool to look at something that’s actually useful to other people and be able to say “I built that.”
And yes, if you’ve read The Mythical Man-Month, my post was indeed inspired by Fred Brooks’ explanation of the joys of the craft.
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.
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 :)
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.
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?
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?
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.
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: 22.214.171.124, d72-39-146-43.home1.cgocable.net)
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 SOLIDdesign 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?
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.
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.
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.