# Computational Thinking: The Data-Science of Algorithmic Thinking.

**Programming is a very close relative of common sense** and so virtually everybody has the capacity to learn to program. There is no harm in trying and failing when we put our efforts toward earning a skill. Failures and setbacks are just the price to be paid to acquire a skill. Failure is our true teacher which guarantees to teach us in various ways on different occasions. In order to become knowledgeable in programming, one need only follow this simple rule: **fail fast to learn fast**. To learn a new subject quickly, we need to experiment in many different ways according to a plan and this demands interest. Without genuine interest, it is almost impossible to be consistent with any kind of learning. It is my observation that for most absolute beginners this unique approach of juggling with numbers based on mathematical fundamentals in order to practice the skill of programming is simply **boredom on steroids**. Developing **a fertile ground for the visualization of programming logic **should be an absolute beginner’s prime focus. Unfortunately, this perspective is alien to many beginners and even teachers. Many novice programmers and many frustrated programmers ask similar questions which are as follows.

“How to learn to program?”

“How to develop logic-building skills?”

“How to learn to code?”

“How to improve programming logic?”

Programming is an applied field. If a programmer who is weak in programming logic is not a programmer even. We know that complaining is the easiest job and if someone is expert in that haven’t actually achieved anything big. Whenever there is a problem, we just need to think “**what could be the easiest possible way out**?”

**The Right Approach**

First and foremost,** **beginning programmers should focus on developing their **logic-building skills**. Basic command of programming logic will give new programmers the confidence to deal with heavier topics and learn the features of a programming language in depth. If instead, the beginner focuses mainly on learning the syntax and features of a particular programming language, progress will be slow and frustrating. In order to become confident in any programming language, the first step should be to gain some level of proficiency to self-hack programming logic. **I strongly recommend that novice learners initially pay more attention to developing their programming logic skills than to the features of a given programming language. **This book is dedicated to installing the skills of programming logic in the mind of the learner. Additionally, if you are among those who have limited time to learn programming, this guide can serve you well too. It often happens that a beginner may know almost all the concepts of a programming language but still feel that something is missing. The missing element is sufficient logic-building capability. Without it, the beginner spends a lot of time being stuck and confused. This can lead many learners to lose interest. For example, we wouldn’t expect a person who is weak in basic math to take a strong interest in secondary school math or higher studies in mathematics. Weakness in the basics of a subject kills confidence sooner or later.

Participation in sports helps a person gain stamina, patience, discipline and resilience. Programming is similar. By practicing programming logic, a person builds their brain muscle, learns to focus, develops patience and definitely learns to adopt the attitude of “**let’s bounce back**” when faced with a setback. Programming is a self-disciplined, self-motivating activity that truly encourages a person to fight and sustain themselves against long odds. Programming encourages a person to become a “**Problem-Solver**”. Indirectly, it makes a person more sportive. Therefore, programming is not just for those who want to build a career: anyone can take up programming as a hobby. Thus it is an easy guess why **Steve Jobs **said,

“

Everybody in this country should learn how to program a computer, because it teaches you how to think.”

You can’t manage what you can’t measure.

- Peter Drucker

The most important aspect of calculation or measurement is that it gives clarity. We will try to tap this “**clarity**” factor to get the hidden programming logic right using computational thinking. Following are the basic steps of computational thinking that can help beginner programmers to learn the fundamentals of algorithmic thinking;

**Pattern-Based Exercise:** To learn logic-building skills or fundamentals of algorithmic thinking, pattern-recognition-based exercises are a fun way to learn it. It just pulls-off all the pressure of learning, since it required minimal technical baggage. I find this is, the most efficient way to learn for beginners or teach coding to a beginner of any age-group.

**Data Representation:** Expressing a problem in terms of data or just associating relevant data helps to understand the problem and its needs. Basically, it gives some clarity.

**Decomposition:** Breaking down an actual problem into parts.

**Pattern Recognition:** Observing trends in data. Spotting the pattern behavior, their differences, and similarities.

**Abstraction:** Observing trends in data. Spotting the pattern behavior, their differences, and similarities. Replacing trends in data using logical expressions made up of variables, because variables represent a range of data.

**Execute Algorithm:** After discovering required logical expressions it is to set steps and rules for the algorithm. Implementing the program based on the algorithm and verifying the result by executing it.

Let’s try to understand these steps of computational thinking by applying them to the following pattern-based example.

Suppose our programming job is to print this logic-based pattern on a part of the computer screen.** We will assume our approach that the computer screen is a combination of rows and columns virtually dividing it into smaller boxes. **The smallest box treated as a resident of just a single character only. The address in each smallest box on the display screen will logically become a unique **(row, column)** numeric combination. With this assumption computer screen will simply uniquely combine (row, column) numeric value paired boxes which are uniformly spread all across the screen.

**Data Representation**

Although it is logical, we can almost locate the position of each printable character on the display screen by knowing its uniquely identifiable **(row, column)** numeric paired-values.

Computer dominantly works on very precise calculations. One of the interesting ways to practice programming is to try converting manual steps of writing a pattern into programming instructions. We can use paper or a spreadsheet. We can mark row numbers and column numbers to logically identify position-indicators to analyze a pattern correctly.

**Decomposition And Pattern Recognition:**

We can decompose our repetitive actions of printing pattern into the following categories

**Repetitive Actions**

**a) Row Level: **Repetitively moving down, marking the next row number in sequence-wise.

**b) Column Level: **Repetitively writing * characters at the column level.

The pattern is a 2-dimensional simple picture we can express such that it in terms of rows and columns**. **Our next step will be to transform these manual, repetitive actions into a working program. We will use * characters in our program to print it on the computer screen.

**COLUMN LEVEL** **REPETITIVE ACTION: **The table decomposes the pattern into the relationship of **one-to-many** between row and column values.

For uniquely identifying each printing character of a pattern let’s consider variables **row **and** col**. Choosing variables** row **and** col** to precisely mark printing character’s row and column number position respectively in a pattern. Every value of the **variable: row** can be mapped to a set of **variable: col** values at the column level. The **variable: col** values maintain a common difference of value 1 if we move from *starting value* to the* ending value*. Wait for a second, doesn’t it very much sound like another case of ** for-loop** construction.

By considering **variable: row **and** variable: col **we can further refine the logic trace table intending to build ** for-loop** against each value of row number. The

**will be basically a nested-loop for each row’s value**

*for-loop***.**Based on the updated logic trace table we can write the program’s logic given as follows.

**Abstraction:**

The next step in generalization will be to convert many nested-loops into one nested-loop. Such conversion to a single nested-loop suggests that the number of rows inputted to the program should not affect our version of the solution. We will see all these in action while applying the principles of the logic trace table. Primarily, our goal will be to get consistent numeric or logical expressions in the columns of the logic trace table. We will use these consistent numeric or logical expressions to design the logic of our program and that is, the most essential learning. Derived expressions considered correct only when it gives correct output, otherwise, we need to re-work on the logic trace table to find out our own mistakes. This is the “**computational thinking**” way to learn the design of the program’s logic as compared to the trial-error method.

The column **start** contains the data **col = 1 **which is the same for every row. Hence, column **start** is already being in generalized state and hence we got the consistent logical expression in order to **start** the column level for-loop. The **column level** **for-loop **must require a singular *starting value* and a singular *end value*.

Clearly, the column **end** with singular value* *is not our case. The other remained possibility is to derive a logical expression that should be consistent with this column. We can observe numeric pattern variations of the **variable: col** and the **variable: row.** The column **end** matches exactly with numeric pattern variations of the **variable: row**, shown in the above logic trace table.

It means column level for-loop with **variable: col **starts at value 1 and ends at the most recent value taken by the **variable: row**. Hence, we got the consistent logical expression **(col = row) **for the column **end.**

So, during the execution of the program row-level for-loop with **variable: row **takes the value 1 to 5. Then column level for-loop with **variable: col **will** **take values between 1 and the current value of the **variable: row**.

Mathematically, it can be given as

**1 <= col <= row**

Where **row = 1 to 5**

The row-level for-loop will get started at the value 1 and a changing value of a **variable: row** during the execution of the program will stop and control it. At each row’s value how column level ** for-loop** should stop looping and controlled by the logical expression

**(col <= row).**The consistent logical expression

**( col <= row )**will be the reason to produce dynamic output at the column level for different values of

**variable: row**. Extracting the consistent logical expression is a way to generalize and to get a customized solution. When we can establish a relationship between variables, then we can automate computing. We can now clearly define the action of column-level

**.**

*for-loop*The following logic trace table is basically **for-loop** in action at row level. The only action expected from **row-level for-loop **in our case is to shift the program’s control to the next row. We should do it dynamically based on the **total number of rows** inputted by the **variable: totalRows**. Our target is to get singular numeric/logical expressions for the **start** and **end** of a **row-level for-loop**.

After doing numeric pattern matching and applying replacement using **variable: totalRows**, the logic trace table looks like the following.

The following logic tracing table suggests that maximum repetition of **row-level** **the value stored in the variable: totalRows can control for-loop and moving program’s control to the next row**. Now, the stored value of **totalRows** will act as the maximum boundary value for the **row-level for-loop** repetitions. This is the way it plans a flexible solution to resize the length of the pattern based on the given input value of the **variable: totalRows**.

**Algorithm:**

Applied knowledge is wisdom. To understand the importance of computational thinking, please try to solve the following given problems and improve something about logic-building skills.

To develop or improve logic-building skills, interested ones can refer to the following resources.

**Java**

**Python**

**JavaScript**

**C++**

C