Introduction

19 min read

What is Programming?

Programming is the process of writing a precise set of instructions that a computer executes to perform a specific task or solve a problem. Because computers do not naturally understand human speech, these instructions must be written in specialized computer languages, such as C++, Python, or JavaScript.

At its core, programming is about automation and problem-solving. It involves breaking down a complex problem into minor, logical steps, configuring how data is processed, and controlling the flow of execution based on various conditions. By writing and organizing this code, programmers build everything from simple scripts that automate repetitive tasks to massive software systems, including video games, web applications, and artificial intelligence models.

The Binary Language

The Central Processing Unit (CPU), is the primary component of a computer that acts as its brain. It is responsible for executing the instructions that make up computer programs, interpreting inputs from hardware and software, and managing the flow of data throughout the entire system. Without a CPU, a computer would be unable to perform calculations, run applications, or process any form of digital information.

The CPU accepts low-level instructions known collectively as machine code, which consists entirely of binary digits, or sequences of zeros and ones. These binary instructions correspond directly to the specific operations the hardware is physically designed to perform. Because raw binary is incredibly difficult for humans to read and write, these commands are often represented in software development using assembly language, where short text-based mnemonics map directly to individual machine instructions.

; ========================================================================================
; CPU ARCHITECTURE: x86-64 (Intel Core i7/i9, AMD Ryzen)
; OPERATION: Function that takes two integers, adds them together, and returns the result.
; ========================================================================================

; ASSEMBLY LANGUAGE (AT&T Syntax)   HEXADECIMAL            BINARY CODE
; -------------------------------   ------------           ------------------------------

movl %edi, %eax                     0x89f8                 10001001 11111000
  ; Copies the 1st argument (from EDI register) into the return register (EAX).

addl %esi, %eax                     0x01f0                 00000001 11110000
  ; Adds the 2nd argument (from ESI register) to the value in EAX.

ret                                 0xc3                   11000011
  ; Returns control to the calling program. The answer is now waiting in EAX.
Info

Hexadecimal is used to represent binary numbers in a more compact and readable format. It is a base-16 number system that uses the digits 0-9 and the letters A-F to represent the values 10-15. Each hexadecimal digit represents 4 binary digits, so two hexadecimal digits can represent a full byte (8 binary digits).

Registers are small, high-speed storage locations within the CPU that hold the data it needs. They are the fastest type of memory in a computer.

Memory is where the data is stored. It is much slower than registers but can hold much more data. There are different types of memory, such as RAM and SSD.

  • RAM (Random Access Memory) is volatile memory that is used to store the data that is currently being processed by the CPU. It is much faster than SSD but loses its data when the computer is turned off. Here, the running program is loaded from the SSD and executed. Data that the program needs in the current moment is stored in the RAM.
  • SSD (Solid State Drive) is non-volatile memory that is used to store data that is not frequently accessed. It is slower than RAM but retains its data when the computer is turned off. Here, all your programs, files, music, videos, etc. are stored.

Modern Programming Languages

Programs are generally not written directly in assembly language today, as it is incredibly tedious, time-consuming, and prone to human error. Instead, developers write software using high-level programming languages like C++, C#, or Python, which feature human-readable syntax and abstract away the complex, low-level management of hardware components. A specialized piece of software called a compiler or interpreter then automatically translates this high-level source code into the machine instructions that the processor can actually execute.

Writing an entire modern application in assembly is impractical because the language is completely tied to a specific hardware architecture. Code written for one processor type will not run on another without a complete rewrite, making software non-portable.
Furthermore, simple high-level concepts require dozens of individual assembly lines to manage low-level details like memory addresses and CPU registers, dramatically slowing down development speed and complicating code maintenance.

Take a look at the Python equivalent of the assembly code above:

def add_two_numbers(edi, esi):
    """
    Takes two integers and returns their sum.
    """
    eax = edi       # movl %edi, %eax (Copy 1st value to return variable)
    eax += esi      # addl %esi, %eax (Add 2nd value to it)
    return eax      # ret             (Return the result)

# Example usage:
result = add_two_numbers(5, 7)
print(result)  # Outputs: 12

The Python interpreter will translate the high-level code above into low-level machine instructions that the CPU can execute.

Compiler vs. Interpreter

  • A compiler translates the entire source code into machine code at once, creating an executable file that can be run later.
  • An interpreter translates and executes the code line by line, on the fly, which makes it easier to debug but generally slower.

Interpreted code is platform-independent, which makes it highly portable. Write a Python script and run it anywhere where Python is installed. Compiled code, on the other hand, is platform-dependent. Write C++ code for Windows and you won’t be able to run it on Linux. You will need to recompile it for each platform you want to run it on.

Compiled code is generally faster than interpreted code because it is translated into machine code at once, which allows the compiler to optimize the code better than what an interpreter can do on the fly. Interpreters add overhead because they have to translate each line of code into machine code before executing it.

Examples of compiled languages include C, C++, C#, and Java.
Examples of interpreted languages include Python, Ruby, and JavaScript.

Info

An Integrated Development Environment (IDE) is a software application that consolidates the essential tools required for programming into a single graphical user interface. Instead of forcing developers to use separate programs for different tasks, it combines these utilities to streamline the software creation process.

At its core, an IDE integrates a specialized text editor with features like syntax highlighting and code completion, automation tools that compile or build the code into an executable program, and a debugger to locate and fix errors.

Examples of IDEs: Visual Studio Code, PyCharm, Eclipse, Visual Studio, Xcode.

Pseudocode and Algorithms

With the advent of AI, it has become easier to write code. Nowdays, you can just describe what you want the code to do in natural language and the AI will write it for you in a specific programming language.

Pseudocode is a plain-language description of the steps in an algorithm or computer program, written using a combination of natural language and simplified programming structures. It is completely independent of any specific programming language syntax and is designed to be easily read and understood by humans.

Because there are no rigid syntax rules or formatting standards for pseudocode, it allows developers to focus entirely on solving the underlying problem without getting distracted by the technical nuances of a specific language. It typically uses universal programming concepts like conditional logic, loops, and variable assignments expressed in clear english.

An algorithm is a finite, step-by-step sequence of well-defined instructions designed to solve a specific problem. It acts as a logical blueprint that takes a set of inputs, processes them through a series of instructions, and produces a deterministic output. In computer science, algorithms form the foundational logic behind software, dictating exactly how data is manipulated and how tasks are executed by a machine.

An algorithm can be specified in pseudocode, in high-level or low-level programming languages, or in other forms like flowcharts.

For example, this is the Python code from the example above written in pseudocode (I like to use a variation of pseudocode that resembles Python, but you can use any format you like):

function add_two_numbers(edi, esi):
    eax = edi
    eax += esi
    return eax

Here is another way of writing the same pseudocode:

function add_two_numbers(edi, esi)
    eax = edi
    eax = eax + esi
    return eax
end function

What this course is about

This course will focus on teaching you how to break down a complex problem into smaller, manageable parts, and then solve each part in a step-by-step manner. You will learn how to think like a programmer and how to write code that is efficient and easy to understand.

You won’t be learning any programming language. Instead, you’ll be learning how to develop algorithms in pseudocode, which you can then implement in any programming language you want.

I recommend you to convert the pseudocode into Python and then test it here: https://www.online-python.com/.
Ask any AI chatbot to help you with the conversion.

If you don’t want Python, then I recommend to take a look at the online IDE https://www.onlinegdb.com/ which supports multiple languages.

Review

### What is the primary role of the CPU in a computer system? > Think of the component that acts as the hardware's "brain" to process instructions. 1. [x] It acts as the brain, executing program instructions and managing data flow. 1. [ ] It serves as volatile high-speed memory for running applications. 1. [ ] It provides permanent storage for files and media when powered off. 1. [ ] It translates high-level code directly into human-readable text. ### Which programming language represents low-level machine instructions using short text-based mnemonics? > This language maps text commands directly to individual processor instructions. 1. [ ] Python 1. [ ] C++ 1. [x] Assembly language 1. [ ] JavaScript ### How does hexadecimal notation simplify the representation of binary code? > Consider the mathematical relationship between the number of binary bits and a single character in base-16. 1. [ ] It converts binary lines into human-readable pseudocode. 1. [ ] It eliminates the need for a compiler or interpreter. 1. [x] Each hexadecimal digit compactly represents exactly 4 binary digits. 1. [ ] It directly replaces the CPU registers for faster storage. ### What is a key difference between RAM and an SSD? > Focus on what happens to the data in each storage type when the power is turned off. 1. [ ] RAM is non-volatile, whereas an SSD loses its data when powered off. 1. [x] RAM is volatile and faster, while an SSD is non-volatile and slower. 1. [ ] RAM stores all unaccessed programs, while an SSD only handles data currently in use. 1. [ ] RAM is directly tied to hardware architectures, making SSDs the only portable memory. ### Why is writing modern, large-scale applications entirely in assembly language considered impractical? > Think about how tied the code is to specific hardware, and the development effort required for simple logic. 1. [ ] Assembly language does not allow functions to add or manipulate data. 1. [ ] Assembly language can only be executed by older generations of CPUs. 1. [x] It is highly tedious, error-prone, and non-portable across different hardware architectures. 1. [ ] Modern compilers are unable to translate assembly language into machine code. ### What distinguishes a compiler from an interpreter? > Look at how each tool handles the translation of the source code—either all at once or line by line. 1. [ ] A compiler executes code line by line, while an interpreter creates an executable file. 1. [ ] A compiler makes code platform-independent, while an interpreter makes it platform-dependent. 1. [x] A compiler translates the entire source code at once, while an interpreter translates and executes it line by line. 1. [ ] A compiler adds more runtime overhead than an interpreter during execution. ### Which of the following is an example of an interpreted language? > Think of a language where the source code is translated on the fly and is highly portable across systems. 1. [ ] C++ 1. [x] Python 1. [ ] C# 1. [ ] Java ### What is the primary purpose of an Integrated Development Environment (IDE)? > Consider how it simplifies a developer's workflow by combining multiple tools into a single interface. 1. [ ] It acts as a physical hardware register inside the CPU to accelerate execution. 1. [ ] It forces programmers to use separate utilities for editing, building, and debugging. 1. [x] It consolidates a text editor, automation tools, and a debugger into a single graphical user interface. 1. [ ] It automatically converts raw binary machine code directly into pseudocode. ### Which statement best describes pseudocode? > Remember that it ignores rigid syntax rules and uses informal language to map out code structure. 1. [ ] It is a low-level programming language that maps directly to CPU registers. 1. [x] It is a plain-language description of an algorithm independent of any specific language syntax. 1. [ ] It is a compiled file format that executes directly on Windows or Linux operating systems. 1. [ ] It is a standardized artificial intelligence model used to write computer programs. ### What is an algorithm? > Think of a logical blueprint or a finite, step-by-step sequence designed to achieve a deterministic outcome. 1. [ ] A hardware storage location that holds volatile data currently being processed. 1. [ ] A specialized text editor feature that provides automatic syntax highlighting. 1. [ ] A piece of software that translates high-level code into executable files for specific platforms. 1. [x] A finite, step-by-step sequence of well-defined instructions designed to solve a specific problem.