Three years ago, my boss asked me to head up the then non-existent data journalism unit at the Times. I'd not written a line of code in my life.

As a print journalist, I'd always thought programming was a task undertaken done by awkward guys in loose-fitting T-shirts who rarely saw the sun. (I wasn't altogether wrong about that.)

With a little reluctance, I said yes.

In the time since, I've learnt a lot about programming. I'm not a great programmer, I'm almost certainly not even a good programmer, but I'm better than I was, and I hope, too, that I'm in some kind of position to advise people thinking about starting to learn to code.

This post is not a coding tutorial. There's thousands of those. Nor is it a 'which programming language should I learn?' post. If you're wondering whether you might want to explore the world of code, I'd say there are more important questions to ask first up, namely: what is programming? What does programming look like on the inside? Are programming and me going to 'get on'?

In that spirit, here are some things I've come to learn about programming which I hope may be useful to people thinking about giving programming a try.

#1 The 'Logic, not maths' principle

One of the greatest misconceptions about programming - certainly at beginner levels - is that it is full of maths. If, like some people, you have an idea that programming will dredge up all manner of faded school-day memories of trigonometry, algebra and the like, you're wrong. The maths learnings of my distant past, at least to date, haven't figured strongly in my programming experience.

If I had to give two examples of 'vaguely maths-y' things that have sprung up though, I'd say: the order of operations (ie. the use of brackets to help 'order' the way tasks are performed), and the idea of a co-ordinate space (ie. defining x and y coordinates to represent where things will be in a two-dimensional space.) Neither are enormously complicated.

Logic, on the other hand, abounds. The ability to think things through, understand the order in which they will take place, and have a sense of how to control that flow, pervades every aspect of programming. If you have an aptitude for logic, you're going to be in a good position to start wrestling with the task of programming.

#2 The 'Catch a shooting star' principle

One way to think about programming is as a series of 'processes' that you set running - a bit like you're getting the computer to 'do a job for you' - and whose interactions you manage. In programming, a process often produces an outcome. This outcome might be a file, but it might be something much simpler than a file, like a 'string' (a collection of characters), or a number.

The problem with processes is that, unless you do something with their outcomes, they just disappear into thin air. They literally 'slip into oblivion', never to be recovered, much like a shooting streaks across the sky and is gone. In other words, you need to 'catch them'.

One of my earliest exposures to programming was via 'Hackety Hack', a follow-along Ruby tutorial written by a guy called _why. (Weird name, I know.) _why referred to a principle he called 'catch the shooting star', and it's always stuck with me.

If you're creating something with a process, you need to grab hold of it, or you're going to lose it That's where variables come in - as a way of 'holding onto' the outcomes of processes. This principle has underpinned a lot of my understanding of how programming works, and if you can grasp it early, you'll find it really handy.

#3 The 'Dictionary' principle

In programming, there are many 'types'. Think of 'types' as being a bit like the building blocks of a programming language. One type is a 'string', or a collection of things inside a quote mark. 'Apple' and 'orange' are both strings. (I could join them together to make 'Appleorange', for instance.) Numbers are another type. Numbers can be added together, subtracted, or multiplied (among other things). Then there are 'arrays' - sets of things in order. ["This", "comes", "before", "that"], for instance, is an array in which the first item is the string "This", and the last item is the string "that".

But probably the most powerful type, and the one which it took me a long time to get my head around, is the 'hash', or 'key value pair'. The hash goes by many names. In Ruby it is a hash. JavaScript refers to it as an 'object'. Probably the best name for it, though, is the name Python gives it: 'dictionary'. If you think about it, a dictionary is a bit like a set of 'keys' (words) all pointing to their own 'values' (meanings).

Why does all this matter, you might ask? Well, it turns out there will be many, many instances in which you need a structure like this to store data. Take a person (me) for instance. Here is a way of packaging up some information about me:

{"first_name" => "Jonathan",

"last_name" => "Richards",

"nationality" => "British"

}

There are the 'keys' - 'first_name', 'last_name' etc. - they're like 'properties', or attributes, of me. (I could equally add: 'hair_colour', 'age', or 'gender'.) And each of these keys has a value (hence: 'key value pair').

A lot of programming is concerned with working out what would be the best format in which to structure data, and 'key value' pairs will become a vital weapon in your armoury, so it's good to get an understanding early on of how they work.

#4 The 'Russian dolls' principles

Programming is stuffed full instances of things within things within things. Often, in programming, you find yourself trying to structure things (data, for instance), and often these structures in turn have nested structures within themselves.

To use my previous example, imagine I added a new "siblings" property to this person object. The person object might then look something like this:

{"first_name" => "Jonathan",

"last_name" => "Richards",

"nationality" => "British",

"siblings" => {

"brothers" => [Matthew, Pete, Simon],

"sisters" => ["Fiona", "Mary"]

}

}

This kind of principle you find all through programming. In HTML, for instance, elements can nest other elements:

<div id="outer_div">

<div id="internal_div">

<div id="yet_another_internal_div></div>

</div>

</div>



In CSS (Cascading Style Sheets), too, there is a sense of hierarchy. Similarly when you're writing scripts, you frequently have to perform one thing inside another, inside another. Getting comfortable with doing things within things is going to be a big part of your programming learning curve, so, again, it helps to get to grips with it early.

#5 The 'sausage' principle

"In computing, things are generally either a program or a file - there isn't really much else," an early mentor told me. I nodded, not particularly knowingly, at the time, but I've realised since that it's an extremely helpful principle to hold on to.

In programming you hear a lot of references to 'in' and 'out' - input, and output etc. The reason for this is that often in programming the task is to take an input (often data), do something to it (a process), and in turn produce something different (output). The 'doing' or active bits are the processes, which are governed by the code you will write. The passive bits are the data (often in the form of a file) that you will work with. It is all a bit like turning mince into sausages.

#6 The dog, cat and fish (or, causation) principle

Imagine I have a room. In this room are a cat, and some fish in a bowl. The fish are acting normally. At a precise moment, two things happen: a dog enters the room, and the cat leaves the room. At the same time, the fish start to sing. The question is: what is it that caused the fish to sing?

There are many possibilities to consider. You might say it was the dog entering. You might say it was the cat leaving. You might say it was the combination of the two. You might say it was neither, but was in fact because that precise moment - 6:17pm - is the fish witching hour. All fish sing then. Some or all of these things might be true.

What's important about this from a programming point of view is that, hopefully, what starts to instill itself is the ability to isolate the cause of a change.

You'll come across similar situations to this one all the time when you're coding. In this case, we might want to ask ourselves: can we simulate a dog entering the room without a cat leaving (because that might teach us something); can we simulate a cat leaving without a dog entering (because likewise); can we recreate that environmental factor (i.e. it being 6:17pm), to see whether that causes the fish to sing irrespective of dogs and cats. And on it goes.

The important thing is that you start to learn to apply a methodology in order to establish causation in the event that something changes. The ability to do that will help you out time and time again when you're coding.

#7 The abstraction, or 'pizza', principle

I've purposely left this one until last, because it's one of the trickier ones and I'm still getting to grips with it myself.

Imagine a pizzeria. Each day the pizza-maker makes pizzas with different types of toppings. Each pizza is made by following a specific set of instructions in order: first you prepare the dough, then you rest the dough, then you mould it into the base, then you add tomato sauce, then the toppings, then the cheese, then you bake.

But of course, the pizza maker doesn't make each one from scratch as it's ordered. That would take ages. Instead he prepares ahead of time such that when the order comes for a Napoletana, all he needs to do is take the base (which is already moulded), add tomato sauce, anchovy and cheese to it, and pop it in the oven.

The key thing to grasp here is that, even though making pizza is, in its entirety, quite an involved process, at the time of ordering, all the pizza-maker needs to know is the ingredients that are to go on this particular pizza. In every other respect, it is just like any other pizza.

Programming is a little bit similar, and uses a process called 'abstraction' to keep slightly the more general things (the programming equivalent of making the pizza base) separate from the slightly more specific things (which toppings we want in a particular instance).

Let's imagine we were turning this pizza-making process into code. I'll start with the wrong way of doing it.

We might have a method (don't worry too much about what this is at the moment - it's the principle we want to focus on) called

make_a_napoletana_pizza

It in turn might have a few steps that it goes through:

make_the_base

add_the_tomato_sauce

add_anchovy

add_cheese

bake



Fine. But what if I want to make a salami pizza? I'm going to have to write a whole new method called make_a_salami_pizza, which is going to have a lot in common with the make_a_napoletana_pizza method, only at the key point, it's going to add salami, not anchovy. This seems a bit wasteful.

Programming's approach to this, much like the pizza maker's, is to say: hang on, let's remove or 'abstract' out all the bits that the two pizza methods have in common, and work out a way of taking into account the bits that are different - ie. their specific ingredients - when we need to. It does this via something called an 'argument', that is 'passed in' to the method.

Here's what I mean. Let's imagine, instead, that our method is going to be called: make_a_pizza, and it's going to depend on an argument called 'toppings'. The method will now look a bit like this:

make_a_pizza(toppings)

and it will work as follows:

make_the_base

add_the_tomato_sauce

add_toppings(toppings)

add_cheese

bake



In this third line, I'm going to take the toppings that I specified at the start and add them to the pizza.

'Now hang on a sec', I hear you saying. 'What are you talking about? You haven't got any specific toppings here - you've just got this word: 'toppings'. How do the actual toppings get on it?' Well here's the magical bit. Now that I've defined my general pizza-making method, I can just 'call' it, and at the time I'm calling it, I specify the toppings I want. Everything else happens automatically.

In other words, I call: make_pizza("salami"), and when the method runs, "salami", because it's an argument, will be the topping that gets added when the make_pizza method gets to line 3. But having called make_pizza("salami"), straight after that I could call make_pizza("chicken"), and the same code would add "chicken" when it gets to line 3.

In making that one change - the topping that is passed into the method as an argument - I get two totally different pizzas.

It's the very same economy that means a waitress can write "1 x salami, 1 x vegetarian" on her order form, and the pizza-maker knows everything he has to know. In programming, this is referred to as 'abstraction'.

So there you have it: seven principles which have instilled themselves in me in my first three years of programming, and which, I think, have done a lot to aid my understanding of the craft of writing code. If you're thinking of setting out on this journey, I hope that they may be helpful to you too.