Programming at its core the process of solving problems; I think the best way to learn how to do this is to find problems, solve them and repeat the process. With this in mind, I have organised this website in a format that will slowly introduce you to ideas, concepts and principals as and when you need them, and then directly applying them to solve problems. To get the most from this format, I recommend that when presented with a question or problem, you should attempt to answer or solve it first by yourself.
The Problem Solving Process
When I present a problem or project, I will first give you a high-level brief to establish what we will be attempting to produce/solve. From there, we will work through the following process to think about and build a solution.
Problem Extraction
We will begin by taking the high-level brief and extracting the core components of the problem or project. This is a useful first step in the process of problem-solving as often the high-level brief contains information and ideas that make the core problems more difficult to understand. By extracting only the key components of the problem, we can discuss possible solutions much more clearly.
For example, imagine you are given the following brief:
You are to produce a system that automatically corrects spelling and typing errors
This brief is both vague and has a broad scope; two common and disastrous traits of briefs you will be given over your career. The brief could describe anything from a simple program that corrects errors in a single word to the complex autocorrection systems found on most phones. At the core of these possible end products is a shared problem; given a word from some text, can the program correct any errors in that word. This core problem is much easier to tackle than having to think about the rest of a potential system at the same time. Of course, the other information is vital to be able to present the finished product to your client or the user, but it does not make solving the core problem any simpler.
Breaking down problems
Once you have extracted the core problems from a brief, the next step is to explore if the problem can be broken down further. Being able to break down a problem into smaller and smaller chunks allows us to think about each of them in isolation.
Using the previous example of a text correction system, we can take the extracted problem and break it down further.
Given a word from some text, can the program correct any errors in that word
There are many avenues of thoughts for what you might consider correct. You might wish to find the closest match based on letters in the word, or you might want to find the word that requires the least amount of "correction". Additionally, you might want to take into account the distance between keys on a keyboard to determine if something was a typo or miss-spelling.
These are now smaller problems that you can address in an isolated fashion, allowing you to think more clearly about possible solutions while also allowing for easier testing.
Testing
Testing is almost the most important step of this entire process; without it, there's no way to know if your program works as intended. There are many different ways you can test your program, and each has its own merits.
The easiest way to test your program is to run it, give it inputs and see what it does. This is a very fast and sometimes entertaining way to test your programs as sometimes your mistakes can lead to funny consequences. This method of testing though, does suffer greatly in some areas though. Repeated testing quickly becomes tiresome and boring, which can and will lead to it not being done properly, which leads us onto our next testing method.
Unit testing is, by far, one of the best ways to test your programs. It allows you to isolate individual units of the code and test them using inputs and comparing the outputs to what is considered correct. For example, if you were building a calculator program, this might be as simple as expect(add(1, 1)).toEqual(2)
. While these types of tests might seem trivial and tedious to set up they pay off greatly the more you use them, as in this example you know now that if anything that uses the add
function breaks that it wasn't the add
function. This type of testing also has the major advantage of being able to be automated easily both in your development environment and in [continuous integration](/reference/continuous-integration)
systems. This automation also allows you to easily check that any changes you have made will not introduce a bug without having to test hundreds of components by hand.
We will slowly introduce testing into our projects as they become larger, and finding bugs will become harder.
Setting up your development environment
Being able to use a search engine to solve problems is a very important skill to have. As such I will give advice on what tools and languages I think you should use, but I will not walk you through how to set them up by hand as there are many other fantastic websites and videos that can help you what that process.
Choosing a programming language
Most of the time, when I provide code samples, I will give them both in a psudeo code language and Java (I may use other languages if it better illustrates a point I am making). By all means, do not think that this is the only language you can or should use; I am not aiming to make a Java tutorial. With that in mind, I think it is worth discussing why I chose Java over other languages and what you should be looking for when choosing other languages to use.
Syntax
While most programming languages can trace their origin back to C-like languages, many popular languages have grown away from certain conventions. For example, in many C-like languages, whitespace (spaces and tabs) do not affect program execution; however, this is not true of Python and some other languages. While these languages have much to offer, I find that the reliance on whitespace can often be confusing for newer programmers especially when you accidentally mix spaces and tabs (this throws an error in some of these languages).
Taking that into consideration I chose Java as it has many similarities with many other C-like languages which provides the ability for the code to be easily translatable between languages; an ability that I think is key for code examples that are not provided in many different languages (something that is sadly not suitable for this website).
Type Safety
Programming languages often sit on the spectrum that stretches from Statically Typed to Dynamically Typed (this is obviously a simplification, and if you want to learn more there are many resources available). This, in essence, describes how strict the compiler is about how you use data types; take this code snippet for example:
x = 1
x = 'hello world'
In a statically typed language, the compiler will throw an error telling you that you cannot replace a variable that held a number with a string (collection of characters). Whereas in dynamically typed languages, this is common practice.
There are many arguments to be made from all sides about which approach is best, and there is a time to use each. I have opted to use Java as it is statically typed. I think static typing is important when learning to program as it forces you to be aware of what data types you're using, making it very clear when you have made a mistake. This allows you to catch potential bugs early and will cause data types to become second nature to you for when you do use less strict languages.
Tools
It is important also to consider what tools you can use with each language. This includes compiler support, availability of packages/modules and text editors. When selecting a text editor or Integrated Development Environment (IDE), you should find one that helps you with tools like autocompletion but does not slow you down by presenting too many options. This is a very personal thing and relies a lot upon your personal programming style; I would recommend trying any that appeal to you before settling.
Recommendations
With these traits in mind, I would recommend using any of the following environments:
- Java
- Javascript (NodeJS)
- Python
They are widely supported on all operating system and have a wide collection of tools for you to use. This is certainly not an exclusive list, and I have probably overlooked a language that you may consider a good starting language.