It is often difficult to define the term “computer science” (“computer science”). Perhaps the reason for this is the unfortunate use of the word “computer” in the title. As you may know, computer science is not just about studying computers. Although they play an important supporting role in this discipline, they still remain just tools.

Computer science deals with the study of problems, the process of solving them and the results obtained. For each task, the computer scientist must develop an **algorithm** – step-by-step instructions for obtaining a solution to any of its special cases that may arise. An algorithm is considered complete if following it leads to a solution to the problem. The algorithm is this solution.

Computer science can be thought of as the science of algorithms. However, we should be careful, given the fact that some tasks may not have a solution. Although the proof of this proposition is beyond the scope of this book, the fact that an answer cannot be found for all problems is very important for those who decide to study computer science. We can fully formulate the concept of “informatics” only by including both types of tasks in it and assuming that this science is studying both solvable problems and those that have no solutions.

Also, when describing problems and their solutions, the word **“computable”** is often used . We say that a problem is computable if there is an algorithm to solve it. Thus, it is possible to formulate an alternative definition of informatics, as a science dealing with the study of computable and non-computable problems, existing and non-existing algorithms. In any case, you can easily notice that the word “computer” is not used anywhere. The solution is considered independently of the machine.

Computer science, related to the process of solving various problems, is also engaged in the study of abstractions. Abstraction allows us to consider the problem and its solution, separating the so-called logical and physical angles. The essence of this idea is familiar to us from a widespread example.

Consider a car that may take you to school or work every day. As a driver (user of a car), you interact with a car in a certain way in order to use it for its intended purpose. You sit down, insert the ignition key, start the car, shift gears, brake, press the gas and turn the steering wheel while driving. From an abstract point of view, we can say that you are considering the car from a logical perspective. You use a set of functions provided to you by the car designers to move yourself from point A to point B. These functions are also sometimes called the **interface** .

On the other hand, the mechanic who has to fix your car has a completely different view of it. He not only needs to know how to operate the car, but also to be aware of all the details of those functions that we take for granted. For example, how the engine and gearbox work, temperature is controlled and the like. This approach is known as the “physical view” – the details under the hood.

The same is true when working with a computer. Most people use a computer to write documents, send and receive mail, surf the Internet, play music, store pictures, and play games, without having the slightest idea of the details of all these applications. They look at the computer from a logical (or user) point of view. Computer scientists, programmers, technical support personnel, and system administrators have a completely different * and * computer denier. They must know the details of how the operating system works, set up network protocols, write scripts to perform certain tasks. They should be prepared to manage all the low-level details that are meant to users by themselves.

What these two examples have in common is that the user of the abstraction (sometimes called the “client”) does not need to know the details as long as the interface works fine. This interface is the way we as users communicate with the underlying complexity of implementation. As another example of abstraction, you can consider `math`the Python language module . Once importing a module, we can perform calculations of the form:

**>>> ****import** **math**

**>>> **math.sqrt(16)

4.0

>>>

This is an example of **procedural abstraction** . We don’t need to know how the square root will be calculated – just enough information about which function to call and how to use it. If we made the correct call, then we can safely assume that we will get the correct result. We know that someone has implemented the calculation of the square root, but all we really need is to know how to use this function. This approach is sometimes called the “black box”. We just describe the interface: the name of the function, its parameters, and the result