I'm convinced that at least the majority of people is able to learn to write simple computer programs. If you don't belive me, that's probably because some broken "education" system told you so.
When teaching Python in my spare time, I prefer to not bore people with formal basics that are way to abstract in the beginning. I usually show small working code snippets to people, explain what they are doing, encourage them to explain with and hope that they will make the connection and build their mental model. This works very well in some cases and not at all in others.
I wondered several times what makes the difference. Recently I got at least an idea: The difference is how much (or perhaps which) patterns people can recognize in the programm code, even if they do not yet know the exact rules and meaning of those patterns.
As an experiment I'll explain some of those patterns, hoping that it will help people identifying structure in program code, which in turn should help learning to code. Your feedback whether this makes sense to you and / or was helpful would be highly appreciated.
Before we start I would like to make very explicit, that the following explanations orient themselves around Python code, but only aim at helping you seeing structure in code. There will be oversimplifications and after your first steps you have to check the Python docs for details that I had to ignore.
Lets start with the most simple expression you already know:
42
It is so simple that there is nothing to be computed. An expression has a
value. In this case it is literally 42. That's why such expressions are also
called literal experesions or for short: literals. Expressions can be combined
using so called operators. You know some of them from school:
20 + 22
And of course we have parantheses too:
2 * (10 + (15 - 4))
Even if you don't like math you will probably be able to follow this expresion
and how it would be evaluated: 15 - 4 is a sub-expression that is evaluated
into 11. This results in 2 * (10 + 11). The next sub-expression is 10 +
11 which becomes 21 and finally we get 2 * 21 which will be evaluated as
42. There is a good reaons that I did not yet used the word "equal" or
"equals to" and did not used a =. We come back to this in a moment. For now
remember how you evaluate an expression like the above.
Expressions alone are not very useful. Let's say you have a price of 120 and want to know
how much a discount of 7% would be. The expression to calculate that would be
120 * 0.07
But what if you want to refer to the value of this expression later? For example to substract it from the original price? You have to give the result a name:
discount = 120 * 0.07
discount now refers to the result of 120 * 0.07. discount is usually
called a variable. Now for something important that is very confusing for
beginners: The equal sign = is NOT used for comparison of values. It asigns
the value of the expression on the right to the name on the left. To compare to
values in the sense of checking whether the left and the right side are equal,
you have to use ==. We come back to it in a moment.
We started with expressions composed out of numbers and well known mathematical operators. But there is more and you already encountered another option in the last paragraph: Variables.
It would make little sense to give something the name discount if we could
not use that name afterwards. So the following is a valid expression too:
120 - discount
Of course we would like to remember the discounted price, so let's make the expression the right side of an asignment again:
new_discount = 120 - discount
I hope you start to see a pattern:
Expressions can be either simple literal expressions like numbers or they can be composed out of sub-expression and operators.
Usually we are interested in the calculated value of an expression. To be able to refer to it later, we have to give it a name. Programmes usuall say: We store it in a variable.
An asignment usually has a very simple left side: The name aka variable that we will use to refer to the value on the right. The right side can be arbitrary compley and nested, but it will always be just one single expression.
There is a whole bunch of other "things" that are also expressions. I'll give you a list of the most common examples, but will not go into details, as those are out of scope of this article.
Functions are called using parantheses, so if you have a function called
calculate_discount you would call it like this:
calculated_discount(120)
We cannot tell from this snippet what calculate_discount is doing, but it
will calculate something and this result is the value of the expression. The 120 does not need to be a literal.
Any expression will do, so we could also do:
calculated_discount(100 + 20)
# or
calculated_discount(price_item_a + price_item_b * 3)
# or
price - calculated_discount(price) + some_fee
# or ...
As before we probably want to remember the result, so all above examples would quite likely become the right side of an asignment:
final_price = price - calculated_discount(price) + some_fee
So far "values" were always numbers, but computers work with all kinds of data. A function might not return just a single number, but a list of them. Or you might have an "employee object" that has properties like a name and a department. Those more complex data types are sometimes called containers, because they package multiple related values into a bigger one.
In expressions you quite often want to refer to specific values in such a container, like the 5th element of a list or the salary of an employee. Again we are only focussing on how that looks like in code:
If prices refers to a list of values you can pick one of those values by
using square brackets: prices[3]. Counting starts with zero, so this would
give you the 4th price from the list. As you might have already guessed:
prices[3] is an expression too.
If mr_smith refers to an employee, you might get his birthday using
mr_smith.birthday. Such objects can have their own function, which are
called by using mr_smith.update_salary(123).