This article will not tell you how to use what functions to solve that problem, but will take a look at the process a person should go through in order to write simple, yet elegant code. In a world where we are met with colorful examples of things not to do, there is a great need for people who know what they are doing.
Think of it this way. With the advent of cheap but powerful computers, every two bit wannabe director is making a movie with amazing special effects, but crappy actors and terrible lines. Movies are never about the special effects, but about the story that they tell. Likewise with video games: people living in their parents basements are churning out games with amazing graphics, sounds, and other special effects, yet playing one of these games is about as pleasant as bashing your head into a wall. Great games aren't determined about how amazing the world looks, but how deep the player can immerse himself while playing the game. All the special effects do is add to what is already there. But if there is no solid game play present, if there is no foundation, all they end up doing is subtracting from the experience.
Similarly, using any piece of software is never about how pleasant or fancy it looks, but how simple it is to use, and how efficiently it gets the job done. Programs are a tool for getting a job done, whether it be to immerse yourself in the story of a game, or to do your taxes. And like any tool, it is merely an extension of the user. The problem is, today's tools are a pain to use.
We need better toolmakers.
Out of everything I’ve learned from my Computer Science classes and my experience from programming, nothing has proved as useful as learning how to think like a programmer. It is a mindset that allows me to solve problems practically and efficiently.
Below is a summary of the process I go through when writing a program. I hope that it will prove to be as useful for others as it has for me.
0) What you do, and don't have.
When you first start coding a program, you will have a list of required features. These will either come from your boss, your teacher, or you, i.e., what you want the program to do. If you are writing the program for yourself, then you need to take the time to decide everything you want your program to do. This is crucial to avoid needless complications later on.
For the time being, ignore all asthetics or any mention of how pretty, shiny, or colorful the program should look. We'll get to that later on. The first step is researching what you do and do not have; what code you can use and what you'll have to make. This last part is especially important for anyone working for a company. Many times you will find the perfect piece of code that will do just what you need, but it will be owned by someone else, and you won't be allowed to use it. Instead, you will have to find your own way of jumping that hoop without landing on the ground of a lawsuit.
Normally as a student you can get away with this. So long as you only use it to further your education and don't make any money off of it, no one will pitch a fit. This of course precludes that your teacher didn't tell you to do everything on your own and not use anyone else’s code.
So, once you've found all the code that you need and made sure that you're completely within your rights to use it, you'll need to start planning out all the code you will need to make. The most important part of writing these functions is that you never program first thing; you always take the time to sit down and think things through.
- The first thing you'll want to do is to plan the function out; what you need it to do, and, if you feel like you'll need it, what it doesn't do or doesn't need to do. Often we can get confused, thinking that we need to do something here, when we've already done if somewhere else, or when it will merely complicate things. Occam's Razor my friends: the simplest solution is usually the best.
I often find that people underestimate how useful this is, to just write down the code's purpose. The purpose is what we need to focus on when programming, because how can we fulfill it if we aren't mindful of it?
- Write out the steps the code will have to take in your normal, everyday language. Don't bother with including examples of the code unless you're really worried you will forget what it is. But if you do include examples, they should be just that, examples. They do not replace you taking the time to write out the full step.
- Now we get to the fun part. Go back through the steps, and look for anything that looks really complicated, or that you have a hard time imagining, and draw a diagram, or a picture, or do something that will allow you to visualize what's happening in that step.
- Another thing that people underestimate: save all your notes. All the information you've had to write out, your research, and all your pictures and diagrams, take them and put them in a folder or a binder. Keep them organized: put a note with them, with the date and what project you were working on. Details like that matter, especially when it comes to code you’ve had write yourself. If you came up with it, then either you or your company owns the copyright to it, which means that you could then license that code out and make money off of it.
On the other hand, maybe someone is accusing you of copyright infringement. Your notes would be your defense, showing that you did in fact figure this out for yourself. Or maybe someone you know has a similar problem. Not only could you give them the answer, but you would be able to show them all the information you learned in order to figure it out. What if that person is your boss?
Keep your notes.
1) The Bare Necessities
Now it's time to actually start programming. As I said earlier, don't worry about how the program looks. That's the very last thing we'll do. Here we are going to get all of our functions working one at a time. I would recommend just using a Console application for this stage. All you're going to do is write the code, make sure it works, make sure it can handle errors, and then move on. You don't need anything fancy looking at this stage.
- The first thing you'll want to do is to get all the code working that's already written: everything that fell under the 'what you've already got' category from step one. There are a couple of reasons for this:
- There's a good chance you'll need it for one of the functions or pieces of code that you'll have to write yourself, so it would be nice to have it already written without so that you won't worry about having another piece of code, when you already have it.
- It allows you to begin organizing your code. Keeping your code organized is a sign of a professional programmer. It makes it easier for you to find things, makes it way easier for others to find stuff, and gives you an edge over lazy and sloppy programmers (and there are a lot of them).
- Writing your own code can be a challenging experience. In the course of having to write a program, you can feel just about every emotion humans possess; anger, disappointment, sorrow, joy, just to name a few. If you'll notice, three out of those four are not ones most people typically enjoy feeling. After hours of having to put up with what can seem like meaningless B.S. you would then have to finish up by writing more programs. Easier ones yes, but at this point you probably won't care. So, first things first, get all the easy stuff out of the way, then move on to the hard stuff.
- Now it’s time for the challenging stuff. The key to good code is simplicity: don't needlessly overcomplicate it. It slows the program down, takes up more memory than you need, and makes you look like an idiot. Here are a couple of things to remember when programming.
- Unlike addition, subtraction, and multiplication, division is a complicated procedure. So rather than dividing a number by 2, multiply it by 0.5 instead. Or say that you have an algorithm that divides by a constant. Instead of dividing by that constant every time, divide it once by 1 to find it's reciprocal, and then multiply the reciprocal rather than divide.
- Square roots are a lot of fun, and are used very often in games, military applications, and various other programs. But like division, the square root algorithm takes a long time when compared to the multiplication, addition... But something that people rarely notice is that squares and square roots tend to keep their relationship whenever you manipulate them. For example, say you need to find the product of the square root of A and the square root of B. Rather than taking the two square roots of each and then multiplying, all you need to do is multiply A times B and then take the square root, allowing you to find the answer while saving time by not using an unnecessary operation.
- Object and classes are a wonderful way of organizing information, and making use of your code. That being said, they are overused. I’ve seen people use objects in their programs when they could have used structs or something else, and waste twenty or thirty megabytes of ram. In our world, this is an inexcusable mark of laziness. Even with the large amounts of RAM and powerful processors available to us, we cannot let ourselves become sloppy programmers.
- When you’re writing a new piece of code, the first thing you should do is write the only part that does what you need it do to. By this I mean, don’t worry about error handling, or what would happen if the user put this instead of that. It makes you anxious and therefore more likely to screw up. Assume for now that you will always be given perfect input. It might help to make a constant that will be your example, and work with that. And if it appears to work, then you can alter the constant to make sure it really does. Remember, you know what’s going on behind the scenes; you know what works and what doesn’t work. Use this to your advantage, and get it to do just what you need to it do. If your program can’t do what that, it’s useless. “Do or do not, there is no try.”
Now that you’ve got the bare components working, go back and add the error handling. Generally it’s best to handle it in a separate function, but depending on how complicated or simple your program will be, you might be able to fit it in the original function. However when you’re first writing it, you should put it in a separate function. It’s easy to get lost and confused adding to code that already exists, so keep them separate at first, and then see whether or not they’ll fit together afterwards.
- Possibly the most important step when writing a program: Comments. Always, always, always add comments to your code. Odds are your notes from before will be perfectly acceptable to use, but you should always make sure that your comments describe what you actually have, rather than what you planned on having. So as you’re going along, add comments for each function. If you organize your code in a particular way, leave a comment why. If you had a particular problem that took you a long time to solve, put the explanation for the solution in a comment.
Comments make it much easier for us to find our way in our code, and to remember what we were doing and why we did it. Ever have this happen to you: you’re really in the moment, fully focused on what you’re working on, and then it comes time to stop. Maybe it’s time to leave work, or school, or you have a meeting, etc. And the next day, or whenever it is you come back and sit down, you can’t remember what you were doing. It happens to everyone, and comments are what allow us to get back in that moment, and finish the program without having to mess around for a while trying to remember what we were doing, and potentially screw up what we already had done.
2) Organized and Easy to Use
By this point, your program should have all the functions it needs. You should be able to run a Console application that demonstrates all the functions your program will use. It won’t look like much, but what you have is the foundation for your finished product. Without this foundation in place, your software will crumble and fall apart.
So now it’s time to make your program easy to use. This will involve making a GUI for your program, which will allow you to organize the different functions your code will need to perform. This should be done by both drawing diagrams, and building sample applications.
As with the steps before, you should not be concerned with how fancy or how colorful the program is. All you’re doing here is getting all the menus, textboxes, buttons, scrolls, and such in place. When you’re done, your software should work just like it perfectly, but look like a Windows 2000 application.
The important thing to remember here is to arrange everything in an organized, yet simple manner. Use the menus, drop boxes, tabs and such to keep everything organized in such a way that it makes it easy to take advantage of all your programs features, without making it hard to navigate and find each feature.
3) Pretty, Oh So Pretty
Now we reach the final stage; making your software look like it should. The reason we save this stage for last is that colors don’t make a program. It doesn’t matter how pretty or fancy it looks; if it can’t do what it needs to, it’s useless.
While prettying up your software, you should be mindful of a few things.
- By adding all the graphics, colors, and effects to your program, it will naturally be slowed down by having to run so many extra features. However the graphics should never compromise the speed or size of the software, meaning that they don’t take up more space than they absolutely have to, and that your program doesn’t have to continuously load and process and display your graphics to the point where your program is unusable.
- Numerous studies have been done on the first impression people get, both from each other, as well as when they use items. The results from all these studies pretty much say the same thing. Within the first 5 seconds, people form a judgment based on what they perceive, and from that decide on whether or not to stay where they are, or move on.
What this means for programmers is that within the first 5 seconds of when a person uses your software, or logs onto your website, what they see will and hear will decide on whether or not they stay on your website, or go to a different one.
So when you are designing the appearance of your program, make sure that all the graphics and colors and whatever other features you add on accent your program. But above all, make sure that they never make your program look more complicated than it actually is; and they certainly should never actually make your program more complicated or harder to use. Nothing turns a person away faster than having to sort through the color-fest of an annoying and flashing program in order to get what they need done.
Things to Remember
- Excess does not justify waste.
Just because the modern computer has several gigabytes of RAM and a two gigahertz processor does not mean that a programmer does not have the duty to their customer for a good product. Always minimize the amount of RAM you’ll need, and the amount of cycles your program will have to run. Simplify, simplify, simplify. Use Occam’s Razor to cut away all the excess from a program.
- Pretty doesn’t make perfect.
Just because a program is pretty doesn’t mean it will work like it should, or does it easily. In fact in today’s market, the prettier piece of software is, the more it is usually trying to make up for. The ‘prettiness’ of a program should never exceed how simple it is to use. Or if you want to keep things really simple, leave the program as a Barebones GUI, and don’t try to polish up its appearance. Some of the most widely used programs are nothing more than a Classic Windows Form application. However in cases like that, the rule should remain the same, keep it simple, and keep it organized.
- 18th October, 2010: Initial post