Mel Reams

Nerrrrd

Be a better programmer while still having a life: part 3

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

More stuff you can do to be a better programmer while still having a life!

The core of programming is really problem solving, but we’re kind of expected to pick it up as we go while we’re learning specific skills like programming in java. I have a strong suspicion that’s why so many new developers feel totally lost when they try to build something on their own: we’ve collectively done a bad job of teaching them how to break down problems and solve them.

Problem solving is a gigantic topic so I’m not pretending this blog post is going to be comprehensive, I’m just aiming to share a few tips to get you started.

First of all, don’t just start coding. It really helps to have some sort of plan for what you’re going to do. If you dive in and just start coding without any sort of plan you’ll often end up lost in the weeds because figuring out how to solve a problem and how to code that solution at the same time is so much harder than doing those things one at a time.

Ironically, it’s also hard not to do those things at the same time. It’s really common to feel like you’re wasting time planning and making lists when you should be writing code, or that planning is boring and no plan is ever perfect so why bother? It’s also not at all unusual for programmers to start coding without a plan because they’re worried about whether they can solve the problem, so they just start writing code and hope the complete solution will come to them.

Having a plan actually speeds things up because it cuts down on the feeling your way around in the dark that you end up doing when you don’t know where you’re going or how to get there. If you really can’t stand the planning part, programming may just not be for you – solving problems is the real job, code is just the tool we use to solve them. Making a plan may force you to admit that you just don’t know how to solve a certain problem which sucks, I’m not going to lie, but isn’t it better to figure that out right away instead of potentially spending days or weeks coding only to find out that your partial solution is never going to work? Trust me, that sucks way more.

So that’s all great, but how exactly do you break down a problem and make a plan to solve it?

One example is laid out in 5 Steps to Solving Programming Problems by Adrian Prieto. The step I want to concentrate on is “2. Solve the problem manually.” Seriously, write it down exactly the way you would do it if you had to do it manually. If part of the problem involves looking things up in the database, just pretend you have a gigantic binder or that you can call another department for the data you need. The imaginary manual procedure might sound really awful and tedious but that’s fine, computers are great at boring and tedious.

Example time! A common programming challenge question is to write a palindrome checker – you give it a string, it tells you whether or not it’s the same backwards and forwards. It’s really easy to look at a short palindrome like racecar and see that it’s obviously the same backwards and forwards, so let’s imagine we have a much longer string. Now how do we tell whether or not it’s a palindrome? One way is to look at the first character and see if it’s the same as the last character, then the second character and the second last one, and keep doing that until we get to the middle of the string (let’s assume for now that we don’t have to worry about spaces or punctuation). If we make it to the middle of the string it must be a palindrome, so we can return true. If any of the pairs of characters don’t match then it’s definitely not a palindrome, so we can stop checking right there and return false.

Now that we have a manual process, we can start adapting it for a computer to run. The thing you have to remember is that computers are really dumb. If you tell a person “stop when you get to the middle of the string” they’ll know what you mean and what to do if the string has an odd number of characters so there’s only one in the middle. Computers, on the other hand, don’t know what a “middle” is unless you tell them and don’t know what to do with a string with an odd number of characters either. For that matter, they don’t know how to tell they’ve gotten to the middle of the string.

In the interests of not making this post 5000 words long I’ll skip the specifics of telling a computer how to find the middle of a string, the important thing to know is that once you have an overall process you can dive into subproblems like “how can the computer tell when it has checked enough characters?” without losing sight of why that problem even matters and how it fits into the rest of your solution.

It really doesn’t matter how bad your first try at a process is. Writing down how you would do it manually is always good enough for a first try, and once you have a basic process you can start improving it or even trying totally different algorithms. The great thing about a simple set of point form instructions or even pseudocode is that it’s much quicker and easier to change than actual code, so you can mess with it to your heart’s content.

That works great for straightforward problems, but what do you do with an overwhelmingly large problem where it’s not obvious where to start? Let’s say you want to build a todo list app. Should you start by designing the UI? Or by figuring out what your data model should look like? How do you decide which features your app should have?

The question about what features you should have is one of the simpler ones: build the tiniest thing that could possibly work. You can always add more features later. In the case of a todo list app, I would start with being able to add new todos and being able to cross off existing ones. Don’t worry about subtasks, don’t worry about due dates or recurring tasks or anything else, just start with the simplest thing that could possibly be considered a todo list.

As for where to start, if I knew the right way to approach every problem I’d be a millionaire :) I personally like to start with the UI so that once I get down to the data model I already have a list of all the visible information that I definitely need to store. On the other hand, if you’re especially comfortable with data modelling it can be easier to start there. That can also save you from building a database that’s perfect for one screen and kind of terrible for everything else. It really doesn’t matter where you start as long as you remember to look at your overall design from different angles and see if it still makes sense.

At the “boxes and lines” diagram stage just like the point form description of a manual process stage you lose hardly any time at all if you sketch out a solution, figure out it doesn’t handle something well, then throw it out and start over. The important thing is to learn more about the problem, not to come up with a perfect design on the first try.

Like communication, practising problem solving doesn’t have to take up a single hour of your time outside of work. You can get all the practice you need on work problems while you’re at work and still have a life outside of work :)

Be a better programmer while still having a life: part 2

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

In my last post about becoming a better programmer while still having a life, I talked about communication. Specifically, making sure you understand why you’re doing a task and what the eventual user of that feature wants to accomplish. That’s far from the only thing communication is good for, though. It’s not just about clarifying tasks, it’s also important to communicate status. Strictly speaking, this may not make you a better programmer in terms of getting things done. It does, however, make you easier to work with and that’s a big part of being a professional. And in the interests of full disclosure, I’m not always great at this, especially when I’m busy, but I try.

If you use slack, a good solution for my team and maybe yours is to post little updates about what you’re working on and how it’s going in your dev channel. When you share what you’re working on, people will have something useful to tell you surprisingly often. I’ve had coworkers tell me about existing code I hadn’t seen before that applies to my problem, ways they had already tried to do something and failed (super helpful because it narrows down what I have to try), or bring up potential issues I hadn’t thought of.

Team leads also really seem to like having a running list of what you’ve been doing and if you’ve hit any snags lately. In my office it’s common for people to work from home, which means my team lead can’t always rely on chatting with people in the lunchroom or on the way to get coffee to figure out whether our tasks are going well or not. My last set of updates were a series of complaints about how badly I was getting along with play 2.5’s requirejs plugin, don’t feel like you have to have positive or even particularly well thought out updates.

Nobody particularly likes to post a bunch of updates about how badly things are going, but that’s actually really useful for your team lead and the rest of your team to know. They can’t make plans about next week if they have no idea how much stuff is going to get done this week. Your team lead doesn’t just know what you’re doing or if you need help, you’ve got to tell them directly. If your updates are always about how badly things are going that’s a useful sign that something is wrong. It could be that you and/or your team lead need to find another solution because the current one isn’t working, it could be that your assignment isn’t at the right level for you and you need some help, it could just be that it’s an especially hard task and you’re not going to be available to do anything else for a while.

If something is going poorly, it’s always better to talk about that sooner rather than later. Seriously, waiting too long to raise the alarm kills projects. Now, it is true that in dysfunctional workplaces you may be blamed or punished for bringing up perfectly reasonable concerns. I’m not going to pretend that every boss you’ll ever have will be the perfect manager, but if you bring up a concern and get ignored or punished for “being negative” I want to reassure you that you are not the problem and didn’t do anything wrong.

If things are going well, you should talk about that too. Just like your team lead needs to know if they can’t give you another task, they need to know if they do need to get another feature specced out and ready for you to work on next.

Whether or not you ever show anyone else your list of things you got done (and it’s not a bad idea to have that handy for when annual review time comes around), just looking back at your list can help motivate you. When I feel like I haven’t been accomplishing anything, it can be really helpful to scroll back through the updates I’ve given and remember that while I maybe didn’t end up with a lot to show for my fight with requirejs, I did learn a lot about play 2.5 plugins and build processes and that will definitely be useful later.

If ongoing updates throughout the day are too much information you can do daily or weekly updates, the only essential part is giving updates on a regular basis. Definitely don’t feel like you need to write a novel for every update, status updates are meant to let people know what you’re up to, not to eat up time you could be using for your actual work.

Giving status updates regularly probably sounds like a really small thing, but it’s been incredibly useful for me.

Be a better programmer while still having a life: part 1

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

In my last post I said that being a better programmer wasn’t worth sacrificing your entire life outside of work, but that doesn’t mean being a better programmer isn’t worth some work. Also, sacrificing all of your free time is simply not necessary. There are lots of things you can do to be better that don’t involve never seeing your friends again and/or being a bad partner. Lots of them!

Here’s tip #1 for being a better dev without killing yourself over it:

Communication!

Specifically, when you get a task, ask some questions to make sure you understand it. Some of the most important questions are the ones you’re scared to ask because you don’t want to look stupid. Like “What is feature x for?” Just because the JIRA ticket says to build an x doesn’t mean the business really needs an x. They might actually need outcome y and think that building an x is the way to get it.

Once you understand why the business needs an x you might be able to suggest a simpler solution – sometimes you don’t need a week of dev time, sometimes all you need is a cron job. Sometimes there’s a library that can do what you need quickly and easily. Sometimes there’s a product or service that does what you need for less than the cost of the dev time, plus if it breaks you may be able to make it their customer support’s problem instead of yours :)

Even if you don’t have a better solution, it’s really helpful to understand why you’re doing something and what you’re really supposed to accomplish. No spec is ever perfect, you’re practically always going to have to make some decisions on your own – knowing the reason behind what you’re doing lets you make way better decisions than if you’re just trying to guess what might make sense. That’s how things nobody wants get built (well, one of many ways they get built, let’s not pretend there’s only one cause) – somebody gets a vague spec, takes their best guess, maybe runs into some problems and has to cut part of it, maybe some of the parts that get cut are actually really important but the dev didn’t know that and now we’ve got a feature nobody wants.

Another good reason to ask questions is to clarify the spec. If you run into anything that needs more details or contradicts some other part of the spec, it’s better to know that before you start building. Nobody likes having to go to their boss after days of development and tell them that they just realised that to build the feature properly they need to build z too and that means they have to throw out the code they already wrote that only supports x and y. Nobody likes hearing that either, so think of the time you spend asking questions as an investment in not disappointing your boss/missing your deadline later.

You might find a whole extra set of problems that need to be figured out before you can build the thing you were originally supposed to. On a large project at work I found out partway through that I hadn’t put nearly enough thought into how new settings for an extension of an existing feature were going to work with the original settings. I could have saved myself a lot of time building and rebuilding handling for that if I had asked more questions in the beginning (and done a better job of planning everything out before I started building it, but that’s a separate blog post).

Not only are complications like that really useful to know about for the sake of building something only once, but the feature might get scoped down or cut entirely if it’s too much of a hassle to do it properly. That might sound disappointing but how much more would it suck to waste days or weeks of time on something that’s never going to work correctly?

And the bet part? Asking questions about work while you’re at work doesn’t touch your free time at all!

Link of the day

We talk all the time about how often code is read vs written and how important it is to be good at reading code, but I’ve hardly ever seen anyone talk about how to get good at reading code. This excellent slide deck by Josh Matthews called How to Read Unfamiliar Code is one of the only times I’ve ever seen anyone even address learning how to read unfamiliar code, and it has a great case study with a really clear step by step method for understanding a feature in an unfamiliar codebase. I recommend checking it out!

Talk of the day

I really enjoyed this recording of the Pycon 2015 keynote and I think you will too. My favourite part was the bit about we are all statistically unlikely to be terrible – it’s called a normal distribution for a reason, most of us are, drumroll please…. normal! Sure, you’re not super likely to be extraordinary (if everyone was then it really wouldn’t be extraordinary), but you’re not super likely to be terrible either. I personally find that comforting to remind myself of when I’m struggling with something and feel totally useless.

Why not start with an IDE?

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.

In college our first Java classes used a text editor (TextPad), not a full featured IDE like Eclipse, and compiled and ran our programs from the command line. When we finally started using Eclipse, I was kind of pissed off that we’d spent so much time slowly and painfully debugging our code when Eclipse could’ve just told us exactly where the problem was. Knowing what I know now, I totally understand why our teachers did it that way, but I don’t remember anyone doing a particularly good job of explaining it at the time.

For anyone out there wondering why on earth they have to do things the hard way when they could just use a tool that makes things so much easier, the answer is that the tool doesn’t actually make things easier.

It sure seems like it does once you’ve got the basics of coding down, but until then it’s just another complication that you really don’t need when you’re already trying to learn something extremely complicated. Take this question I found on reddit for example: you can have perfectly good code but be unable to run it because your IDE isn’t configured correctly. IDEs are powerful tools, and any powerful tool can hurt as much as it helps. If you already know how to write code, compile it, keep track of your files and build path and everything, then IDEs are great. If you try to learn all those things plus how to use an IDE, how to set it up, and how to recognize and fix problems with your configuration if you mess something up all at the same time, you’re going to have a bad time.

You know how your teacher always said to add one a thing at a time when you’re writing code so that you know what caused it if something breaks? That counts for tools, too. If you’re not already good at tracking down what’s wrong with your code, you’ll have a terrible time figuring out whether your code is actually wrong or whether your IDE isn’t configured right.

IDEs can also hide stuff from you that you actually will want to learn, even if it’s a pain while you’re learning it. With java in particular, an IDE can make it seem like you just write code and it runs by magic. That’s not helpful once you start working on projects that need to be run outside of the IDE. You will need to know how to compile your code, what settings you need to get the right output, where that output ends up, and how to use/deploy the compiled code, none of which you’ll learn by hitting the run button in Eclipse.

I can even see the point, as infuriating as it was at the time, of making students manually find issues like missing semicolons without the help of an IDE. The level of attention to detail you learn by finding your own missing semicolons is absolutely necessary to track down the kind of subtle logic errors an IDE can’t help you with. I don’t believe there’s any way to learn that without spending a lot of time being very very frustrated, but it’s an extremely useful skill and one that every programmer will need sooner or later.

If there’s a better (and less frustrating) way to learn to program I’d love to hear it, but I’d be very surprised if there’s a non-frustrating way to learn a fundamentally frustrating skill.

Not all problems need to be solved with code

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.

If you’re a programmer and someone asks you to solve a problem, that means the problem needs to be solved by writing code, doesn’t it? That’s what programmers do, right? Not necessarily!

Knowing how to write good code is a huge part of being a good developer, but so is knowing when not to write more code. Take this question from reddit for example. If the problem is that you need an online store, writing one from scratch is the last thing you should consider. Needing to be able to sell stuff online is not a unique problem. It’s not even a slightly unusual problem. The more common the problem you’re trying to solve, the better chance somebody out there has already solved it and will sell you the solution for a reasonable price. In the case of an online store, that’s probably WordPress and one of about a zillion ecommerce plugins, or one of many (so many) ecommerce platforms.

To keep beating on the online store example, let’s talk about why it’s such a bad idea to write one from scratch. First of all, writing a whole store from nothing would take ages. If your goal is to sell things, spending weeks if not months building your store and getting everything working just right would be a huge waste of time. And don’t think you’re done just because the store works – if nothing else, you’re going to need to apply security updates to whatever it runs on, and let’s be honest, there will be bugs and you will need to fix them :) Sadly, the more lines of code you have the more potential bugs you have. The more code you write, the more code you have to maintain.

Another reason you shouldn’t write a store from scratch is if you’re taking people’s money, you have to be absolutely sure that you keep their payment details and personal information safe. Protip: security is hard and if at all possible, you should make it someone else’s problem. If you use a reputable plugin or platform, you can be reasonably sure all the security stuff has been done correctly. Aside from security, there’s also uptime to worry about. If your store goes down, you don’t make any money and you get to freak out about what brought it down and how to bring it back up. Again, if what you want to do is sell things, trying to figure out why your store went down is a terrible use of your time. Also, if you use existing software that thousands of other people have already beaten on, you’re a lot less likely to have surprise downtime.

And don’t forget requests for new features! If you build your own store, it’s going to be pretty basic at first. Sooner or later, you’re going to want fancy stuff like sales, limited time offers, discount codes, etc, etc. Yay, more stuff to worry about finding bugs in! Those aren’t even the really scary examples, either. If you decide you want to internationalize your store with descriptions in the local language and prices in the local currency, you may need to rewrite huge parts of it. And then worry about finding bugs in those parts, because there are so many fiddly little details you can get wrong with internationalization.

Developing your own [fill in the blank] can enormously expensive, too. Sometimes it is worth it to develop exactly the thing you need in-house, but sometimes it’s really not. The great thing about commercial off-the-shelf software is that the vendor can sell it for a tiny fraction of what it cost to build it because they can sell it over and over. Even the very newest junior dev’s time still has a value – is a week of their time still cheaper than buying the solution? Is having precisely the feature you want going to make more money than having that junior dev work on something more directly related to your business?

As developers, our first instinct is to start writing code when we want to get something done. That’s totally normal and you shouldn’t feel bad about it. It took me ages to learn to ask whether we actually need more code to solve a problem or whether there’s a simpler workaround. What I wish more developers were taught in school is that our job is to solve problems, not to write code. Yes, sometimes writing custom code is the best solution to the problem, but sometimes a simple wordpress plugin or a cron job is all you need :)

Talk of the day: Be Awesome By Being Boring

Because I’m a Katrina Owen fan, I’ve watched a bunch of her talks. Recently I was watching her talk on Therapeutic Refactoring (it’s great and you should watch that one too), saw that it was from Cascadia Ruby Conf, and decided to see what other talks from that conference were recorded anywhere. One that grabbed my eye right away was called Be Awesome By Being Boring by John Hyland.

The gist of his talk is that “boring” (stable, commonly used, not shiny and new) technology is awesome because you can trust it, you can get help when you need it, and you can focus on building something useful instead of fighting with your tools.

Even if you’re a beginner programmer and nowhere near ready to worry about whether your production database is going to crash, it’s still good advice. Well known, commonly used tools are way easier to learn because they’ve been around long enough to have docs written for them and to have the majority of the bugs worked out of them, they’ve been used enough that somebody else has probably run into the same problem and asked about it on stackoverflow already, and because so many people use it, even if your exact question hasn’t been asked already somebody out there can answer it.

For example, take a look at the number of questions tagged Java on stackoverflow versus the number of Kotlin questions. When I wrote this post, Kotlin was closing in on 4k, where Java had 1.1 million. I’ve heard good things about Kotlin and I’m not saying it’s a bad language to learn, just that you’re going to find answers a lot more easily with the language that has over 200 times more presence on stackoverflow. Not that stackoverflow is the be all, end all of programming language popularity, but I think it’s a decent measure of how many people are using a language.

Be awesome by being boring, it’ll make your life easier!

Strategy pattern

Let’s talk about the strategy design pattern today. According to good old wikipedia, the strategy pattern “defines a family of algorithms, encapsulates each algorithm, and makes the algorithms interchangeable within that family.” In other words, if you have an object most of its behaviour stays the same but there’s one piece that changes, you want to be able to change that one piece without messing with the rest of the object.

A concrete example would probably help :) Let’s say you’re working on a videogame with monsters that attack the player and you want your monsters to be more aggressive at night and less aggressive during the day. The rest of the monster code like movement and tracking health points or inventory stays the same, it’s just one part of the behaviour that you want to be able to change on the fly. The strategy pattern would let you swap in different “should I attack the player?” algorithms any time and the monster code wouldn’t have to change, it would just call a method on the strategy object it was given.

So how would you implement the strategy pattern? Pretty much the same way you’d implement the bridge pattern, actually. The bridge pattern is about organizing your code and the strategy pattern is about how it behaves (thank you stackoverflow), but the way you arrange your interfaces and objects that inherit from them is largely the same. One difference is that your context class (the one that uses the strategy for something) doesn’t have to change – you could have only one of those and still want to use the strategy pattern. Comparing the class diagrams for the two patterns helps show how similar they are.

Here’s a class diagram for the strategy pattern:

Diagram taken from wikipedia, by Bocsika - wikimedia, CC0
Diagram taken from wikipedia, by Bocsika – wikimedia, CC0

and here’s one for the bridge pattern to compare it to:

By Trashtoy - My own work, written with text editor., Public Domain
By Trashtoy – My own work, written with text editor., Public Domain

If you imagine there’s another ConcreteImplementor, the bridge pattern looks a lot like the strategy pattern. On it’s own I don’t find the bridge pattern diagram super helpful, but in comparison with the strategy pattern diagram it does help illustrate that there are more things that vary in the bridge pattern than in the strategy pattern.

Given that the patterns are so similar, why do we need both of them? Earlier I mentioned that the bridge pattern is about organizing your code and the strategy pattern is about how it behaves. That might sound like a minor difference, but misunderstandings are a huge, huge problem when you’re developing software. It really does help to make it as clear as you can when you’re talking about how you want to arrange your code and when you’re talking about how you want it to behave.

Talk of the day

If you share my obsession with software design (and maybe even if you don’t) you’ll enjoy this talk by Katrina Owen called Overkill. The basic idea of the talk is the use of a simple toy problem as an excuse for focused practice. I really like the idea of going back to basics as a path to mastery, that’s actually why I’ve been on my own back to basics kick on this blog.

If you like that talk, Katrina Owen co-authored an object oriented design book with Sandi Metz (who is also fantastic) called 99 Bottles of OOP. I haven’t read all of it myself yet, but I have watched (well, listened to) a few of Katrina’s and Sandi’s talks and really enjoyed them.

WordPress Appliance - Powered by TurnKey Linux