As you are learning programming in this course, and you continue to learn and explore the world of software, you will hear many people refer to programming as many things. We often call it Computer Science, which refers to the study of computation and algorithms, which don't necessarily require a computer to exist. You may also hear somebody talk about "Software Engineering" as a career or even job title.
These are both great concepts to understand, and encompass more than just being a "programmer." We aren't just coding and writing programs, and in many cases, your exact code is not the product you are selling, or the project you are trying to bring to life. Code is just a tool to bring your ideas to life, or to solve a problem that deals in information.
I was in a great lecture about systems, and while many of the systems we were talking about involve different layers of computer systems, the principles apply to many systems in the real world, like the train system, a restaurant etc. The lecturer said that as software engineers, we study the science of computers as a tool to execute the art of abstraction. In any situation, our job is to use our fundamental building block concepts to build a more abstract idea.
The internet is a great example of code abstraction to such a point that the creation of the internet cannot be attributed to one single person or company. The internet is built on many different layers of code, using different standardized protocols to operate. One such layer you may be familiar with is an IP address, which every online device has. This is a simple identifier that is agreed upon by us collectively, and using it stops us from having to re-invent the entire concept of the internet, when all we want to do is create a simple web app.
Let's look at a simple example of the power of abstraction. Say you are a software engineer working at a large company building a new online banking platform for some bank. You are tasked with creating a script that sends an email near the end of the month to everybody who has a negative balance and owes the bank money, reminding them to get their balance above 0. Many of your co-workers at the same time are working on all kinds of other code for the website. Your idea is to use a loop to look at each user in the database, check if their balance is a negative number, and if so add their email address to the email list.
Maybe you ran into a couple issues with the database and had to make a few extra lines of code that might not make sense outside the context of the project. You add a short comment explaining this within your code, but you know your co-workers don't care about this lower level loop code very much. Because of this, you decide to wrap the code in a function called createBalanceEmailList(userData) which takes in the user database, and returns the email list. Now you realize even further, that your co-workers do not need to be concerned with the creation of the email list, as you are going to use the list to write another script which takes the email list and sends the emails. At this stage of the game, you aren't very concerned with efficiency, and just want code that will run and work. You create a new function sendBalanceEmails(emailList) which takes the email list created by the previous function, and sends all of the emails.
You have already abstracted your code two layers, and have all of the email code in one simple file. Your co-workers need to know nothing about the code, besides that if they call that file, it will send all of the appropriate emails to the correct customers. Now, two weeks later, as the banking app is being tested, your project manager comes to you, and says that they have updated the database system, and now there is a problem with the email script where in some cases, emails would be sent to customers with a positive balance . Because you neatly abstracted your code, you can easily go back to your createBalanceEmailList function, and quickly fix it, and clean up the code you wrote before. Because you used two functions instead of one, you don't even have to touch the sendBalanceEmails function, because it still expects the same input. If it was all one function, you may have had to rewrite most of the code you had already written.
This kind of abstraction is carried up in layers where pieces of code are wrapped and simplified, until you have the entire banking app that was intended. As programmers, we are often so concerned with the underlying mechanics of our software, that we sometimes forget that most of it will never be seen, and we lose site of the bigger picture, which is the abstracted idea we are creating in the first place. This art of abstraction is truly our greatest skill as programmers, software engineers, or computer scientists, and no matter how long someone has been in the game, they are always learning how to better abstract their code in a way that is pleasing to the users, and others working on it.