Chapter 47: Thinking abstractly
Abstraction is the act of removing unnecessary detail in a problem.
A famous example of this is the Könisberg Bridge Problem, which you can see below.
The aim of this problem is to cross all bridges (highlighted in pink) only once, without crossing a bridge twice. The famous mathmatician Euler pointed out that much of this picture is irrelevant, and that the problem can be simplified to what we now call a graph:

This removal of unnecessary detail is known as Abstraction
Chapter 48: Thinking ahead
Any computational problem is made up of 3 stages:
- Input - Information relevant to the problem
- Computational Problem - Some task that needs to be solved
- Output - The answer to the problem
As well as this, preconditions are additional rules that must be followed when solving the problem.
Preconditions are useful as they allow the user to clearly see what needs to be checked before solving. It also allows for creating reusable code.
Reusable code segments are necessary as it saves time when coding larger projects.
Caching is an automatic process done by the operating system, in which some data or instructions are stored in cache memory for a speedy retrieval of recently used code. This is obviously incredibly useful for cutting down on runtimes of larger programs.
Chapter 49: Thinking procedurally
Procedural Abstraction is the act of using a procedure to abstract away useless detail. An example of this is having a function
drawTriangle(colour, base, height)
A programmer using this function does not need to know how it is actually coded, they just need to know how to use it.
Problem decomposition is breaking down a large problem into many smaller, more managable ones. A further subset of this is Top-down design, which breaks these problems down even further into many small tasks.