# Programming Concepts for Beginners

## Summary


Computers operate at a low level of bits and bytes that are difficult for humans to understand. To program a computer, we use higher level languages that are closer to how humans think and reason. These programming languages make it easier to us to instruct what a computer should do.

While there are dozens of programming languages, all of them share a number of basic constructs. All languages must have constructs to do basic things such as initializing data, adding numbers, storing data, checking for certain conditions, repeating some tasks, and so on. This article introduces these basic concepts to someone new to programming.

The actual syntax of each language may be different. There are also different programming paradigms. These are not covered in this article.

## Discussion

### What's the difference between hardware and software?

Hardware refers to a physical device. For example, a computer and its peripherals such as monitor, keyboard, and mouse are all part of the hardware. Software is a set of instructions that are executed step by step to perform a specific task. Software is otherwise called *code* or *program*. 

Although we think of desktops and laptops as computing hardware, any device that executes a program can be considered a computing device. Thus, digital cameras and smartphones contain both hardware and software. Some devices such as Wi-Fi routers and firewalls are called networking devices because of their specialized functions, but these too contain both hardware and software.

We may say that hardware is tangible and software is not. Some say that hardware is about *atoms* and software is about *bits*. This is because software is made of ones and zeros, which are the values that a bit can take. 

Computing hardware without software does nothing and is therefore useless. Software needs hardware to do its job. Thus, both are needed for delivering a useful application.


### Why do we need programming languages?

Computers have been designed to work with ones and zeroes. They can't understand human languages. However, writing a program with ones and zeros is extremely hard for human programmers. Programming languages have therefore been invented for this reason. 

Programs are written in **high-level languages** such as C, Java or Python. Such languages are independent of the hardware architecture on which they are meant to execute. This has the added advantage that the same program can execute on different hardware. There are tools called *compilers* or *interpreters* that translate high-level code into lower level instructions. 

It's possible to write programs using hardware-specific instructions called **assembly-level languages**. In fact, compilers output assembly code. *Assemblers* translate them into machine code of ones and zeroes. Hand-crafted assembly code may be more optimized code (in terms of memory or speed). The trade-off is that such code can't be reused across different hardware architectures.


### What are the basic constructs of a programming language?

Here are some basic constructs of any language: 

    + **Variables**: These are names for easy storage and access of data. A program is essentially about manipulating and storing data.
    + **Expressions**: Data needs to be manipulated and expressions involving mathematical operations are used to achieve this.
    + **Assignments**: The output of an expression, if needs to be stored into a variable, is saved using an assignment.
    + **Conditionals**: Program execution sometimes involves branching based on conditions. If some condition is true, do one thing; if not true, do something else.
    + **Loops**: When something has to be repeated a number of times, loops are useful. Loops typically have well-defined exit conditions.For example, `balance` is a variable to refer to a person's bank account balance. The expression `newbalance = balance - withdrawal` calculates new balance from two variables and assigns the result to another variable. The condition `if (balance > 0)` checks if the balance is positive. To calculate the sum of all withdrawals, stored in `all_withdrawals`, we would use a loop such as `for i in all_withdrawals: total_withdrawals += i`, assuming that `total_withdrawals` is initialized to zero.


### How is data stored and manipulated during program execution?

Content stored in memory is of two types: **instructions** that are executed by the computer; and **data** that are accessed and manipulated by instructions. Using memory addresses, instructions point to relevant data that need to be processed. Variables are simply names that translate to memory addresses where their values are stored. 

Consider the statement, `a = a + b`, where "a" and "b" are two variables. In algebra, this equation implies that "b" must be zero. In computing, this is not an equation but an assignment statement. The right side is evaluated and the result is assigned to the left side. For example, if "a" and "b" start with values 3 and 4, after this execution, "a" will contain the value 7 while "b" will remain unchanged. In this example, we're are not concerned with preserving the original value of "a" and hence we overwrite it with the recent result. To preserve the original value, we can introduce another variable (memory location), `c = a + b`.


### What are the common types of data?

Numeric data is mostly either an **integer** or a **decimal**. Programmers can specify how much memory they wish to allocate to number variables using type names such as short, long, float, or double. More memory implies a bigger range of values.

Among the non-numeric types is the **character** type. A sequence of characters form a **string**. Thus, "Hello World" is a string of characters, enclosed in quotes. To store the result of conditionals, we have **boolean** types that have only two valid values: true or false. 

It's common to deal with a sequence of data values. For example, we wish to store the names of all students in a single variable. We can do this by creating a **list** or **array** data type. Each item of the list can be accessed using an index. In computing, indices often (but not always) start with zero. 

Since arrays accept only integer indices, we can create an **associative array** (also called **map** or **dictionary**) that accept strings as indices. This is useful when storing key-value pairs. 


### What are conditional expressions?

Any expression that yields a boolean result of either true or false can be considered a conditional expression. For example, `balance > 0` is a numerical comparison that has a boolean result; `lastname == 'Smith'` is a string comparison that has a boolean result.

The purpose of such expressions is to do branching in code. For example, if account balance is positive, allow withdrawal; else, show customer an error message.

Conditional expressions can be combined using **logical operators**. The most common of these are the "and" and "or" operators. For example, `firstname == 'John' and lastname == 'Smith'` can be true only for John Smith. Another example is `balance <= 0 or accountDisabled` where `accountDisabled` is of boolean type. If either condition is true, we disallow account withdrawal. A value can be inverted using "not" operator. 

When combining multiple boolean expressions, **Boolean logic** is used to determine the final result. 


### What are the different ways of implementing loops?

There are three main looping constructs: 

    + **do-while**: One or more statements are executed, then a condition is checked. If condition remains true, the next iteration of the loop is entered. If condition is false, loop is exited.
    + **while**: Similar to do-while, but the condition if checked first. This implies that statements within the loop may not be executed even once if the condition starts as false. This is unlike do-while where the statements execute at least once.
    + **for**: This starts with an initialization, such as initializing a loop counter. Then the condition if checked, and if true, loop statements are executed. Next, the loop counter is incremented before attempting the next iteration.Statements within the loop can be any valid programming construct. They can contain their own loops, resulting in *nested loops*. They can contain conditions, which if false, can help us exit the loop completely or skip following statements and move to the next iteration. These are usually called `break` and `continue` loop statements respectively. 


### What are comments in the context of programming?

A programmer may write excellent code but he or she is most likely not the only person reading that code. Other members of the development team and managers will read the code. Code will be maintained and possibly improved by others. To make it easier for others to understand the code, it's good practice to write comments. The purpose of comments is to explain what the code does, particularly those parts that may not be obvious. 

Comments are meant for humans and are ignored by compilers and interpreters. In other words, comments don't affect program execution. However, some tools process comments with the goal of automatically generating software documentation. This documentation is again useful for only humans. Some tools use comments to give hints and warnings to programmers while they write code. This enables programmers to catch problems early. 


### What's the purpose of functions, classes and methods?

Modern applications are often complex, running into thousands or even millions of lines of code. The solution is to break up a large program into small manageable units, each of which connects with other units via well-defined interfaces.

A **function**, also called a *subroutine* or a *procedure*, is a block of code that encapsulates a specific functionality. It takes in input parameters, executes and returns an output. Thus, functions can be called from other parts of code with different inputs. They promote code reuse. For example, `float add(float a, float b)` is a function that takes two decimal numbers, adds them up and return the result as a decimal number. Calling `add(2.3, 1.2)` should return 3.5 as result.

A **class** encapsulates not only code but also data and expose well-defined interfaces. Functions encapsulated within classes are called **methods**. Consider `Rectangle` as a class with two data attributes `length` and `breadth`. One of its methods could be `float area()` that returns the rectangle's area as a decimal number.


### What tools does a programmer need to program a computer?

To write code, the programmer needs at least a text editor. A better approach is to use an **Integrated Development Environment (IDE)**. IDEs provide a useful set of features out of the box. These include language syntax highlighting, flagging programming errors, powerful code search, code formatting, and many more. 

Code must be compiled or interpreted into their lower level instructions. Thus, programmers need to install **compilers** or **interpreters**. For example, C and C++ are compiled whereas JavaScript and Python are interpreted.

What if the program doesn't work as expected during execution? Where could be the problem? This is where a **debugger** becomes a useful. A debugger can help us inspect the value of a variable step by step during program execution. We can also ask the program to break at a specific line of code. 

Code undergoes changes. To keep track of who has changed what, a **Version Control System (VCS)** such as Git is essential. In coding projects, it's common to use many other tools for planning, scheduling, tracking progress, or recording issues.

## Milestones

1843

Ada Lovelace translates a French article written by Luigi Menabrea on the *Analytical Engine* invented by Charles Babbage. She adds extensive notes to the translation detailing how the Engine might be instructed by a sequence of operations to solve problems. She is often regarded as the "world's first programmer". 

1847

George Boole publishes *The Mathematical Analysis of Logic*. This shows the rules for manipulating expressions containing True and False values. This later influences the design of digital circuits and programming with boolean data types. 

1943

At the Moore School of Electrical Engineering of the University of Pennsylvania, work begins on *ENIAC*. Unlike earlier electromechanical computers, ENIAC is electronic (no moving parts) and therefore more than thousand times faster. Possibly inspired by telephone switchboards, it's programmed using panel wiring and switches. It uses 18,000 vacuum tubes and weighs 30 tons. 

1947

Herman H. Goldstine and John von Neumann invent a graphical method to represent the execution flow of a program. This is called a **flow diagram**, later named as *flowchart*. 

1952

Mathematician Grace Hopper completes **A-0 compiler** that allows the use of English-like words instead of numbers to program a computer. This marks the beginning of the move towards high-level programming languages and compilers. 

1968

Edgser Dijkstra publishes an article titled *Go To Statement Considered Harmful*. Goto is a programming construct that allows execution to jump to another part of the code. Dijkstra recognizes that excessive use of goto can result in confusing code. The alternative is to adopt **structured or procedural programming**. In modern programming languages, goto is not quite as bad since jumps are restricted. 

1985

Bjarne Stroustrup publishes *The C++ Programming Language*. This makes C++ the dominant **object-oriented language** to tackle complex applications. 

1990

This decade sees the invention of a number of high-level languages: Python (1991), Java (1994), and JavaScript (1995). Python and JavaScript are interpreted languages. Java is compiled to bytecode, which is then executed by the Java Virtual Machine.