11  Conditionals and Iterations

Conditionals are a fundamental programming entities used to make decisions during the execution of a program. They allow a program to choose different paths of execution based on certain conditions. Conditionals are used to implement decision-making processes in software, such as:

Iterations, also known as loops, are another core programming entity that allows a piece of code to be executed repeatedly. They’re essential for tasks that require repetition, such as processing elements in a collection, performing calculations multiple times, and automating repetitive tasks.

Iterations are crucial for:

You will be making extensive use of conditionals and iterations to implement: (1) flow control as the ability to control how and when code is executed and (2) flow repetition as the ability to run code repeatedly, refer to the following figure.

Conditionals and Iterations
A Note of Caution

Conditionals and Iterations should be used only when strictly required as they tend to degrade the performance of the running code. In my professional experience, the majority of use cases involving complex data transformations can be addressed with existing Pandas methods which are optimized to perform in large data scenarios.

11.1 Conditionals

Conditional statements enables us to check conditions and change the behavior of the program accordingly, for instance

  • if the weather is nice, then I will:

    • Mow the lawn
    • Weed the garden
    • Take the dog for a walk
  • If the weather is not nice, then don’t do anything

Conditional Statements

11.1.1 If Statements.

if statements in Python allow you to execute certain blocks of code based on whether a condition is true or false.

if <expr>:
    <statement>
    <statement>
    <statement>

where <expr> is an expression evaluated in a Boolean context, as discussed in the section on Logical Operators in the Operators and Expressions in XXXX,<statement> is a valid Python statement, which must be indented. If <expr> is true (evaluates to a value that is “1”), then all <statement> are executed. If <expr> is false, then all <statement> are skipped over and not executed.

The following example illustrates an if statement that compares two numbers and executes the print() method as the first number is larger than the second.

firstNumber=5
secondNumber=3
if firstNumber > secondNumber:
    print("The condition returned True, the first number is larger than the second number")
The condition returned True, the first number is larger than the second number

In the following example, however, given that the first number is not larger than the second one the print method is not executed.

firstNumber=1
secondNumber=3
if firstNumber > secondNumber:
    print("The condition returned True, that is because the first Number is larger than the second number")

Indeed if statements can be defined with other boolean expressions, for instance:

customer='Robert'
if customer== 'Robert':
    print("Welcome: "+customer)
Welcome: Robert

Or even other more complex ones, for instance:

if 'foo' in ['bar', 'baz', 'qux','foo']:
    print('Expression was true')
    print('I found foo in the list')
    
    
print('Bye Bye')
Expression was true
I found foo in the list
Bye Bye

11.1.2 If-Else Statements.

Sometimes, you want to evaluate a condition and take one path if it is true but specify an alternative path if it is not. The alternatives are called branches, because they are branches in the flow of execution. In Python this is accomplished with an else clause:

if <expr>:
    <statement>
    <statement>
    <statement>
else:
    <statement>
    <statement>

The following example illustrates an if-else statement that compares two numbers and: (1) executes the first print() method if the comparison operation returns True (this means that the first number is larger than the second), (2) executes the second print() method if the comparison operations returns False (the first number IS NOT larger than the second)

firstNumber=1
secondNumber=3
if firstNumber > secondNumber:
    print("The condition returned True, the first number is larger than the second number")
else:
    print("The condition returned False, the first number is NOT larger than the second one")
The condition returned False, the first number is NOT larger than the second one

11.1.3 If-else-if Statements.

Sometimes there are more than two possibilities and we need more than two branches for this you can use chained conditionals. In Python this is accomplished with an if-elif clause:

if <expr>:
    <statement>
    <statement>
    <statement>
elif <expr>:
    <statement>
    <statement>

elif <expr>:
    <statement>
    <statement>

elif is an abbreviation of “else if”. Exactly one branch will run. There is no limit on the number of elif statements. If there is an else clause, it has to be at the end, but there doesn’t have to be one.

if choice == 'a':
    draw_a()
elif choice == 'b':
    draw_b()
elif choice == 'c':
    draw_c()

Each condition is checked in order. If the first is false, the next is checked, and so on. If one of them is true, the corresponding branch runs and the statement ends. Even if more than one condition is true, only the first true branch runs.

The following example illustrates the use of elif statements to define branches in the execution of a program.

firstNumber=1
secondNumber=3
if firstNumber > secondNumber:
    print("The first number is larger than the second number")

elif firstNumber == secondNumber:
    print("The second number is equal to the second one")

elif firstNumber < secondNumber:
    print("The first number is smaller than the second one")
The first number is smaller than the second one

The following example adds an else clause at the end to define a branch of ‘last resort’ that is executed only if the previous branches have failed (in the sense of having returned False).

age = 18
if age < 13:
    print("You're a kid")
elif 13 <= age < 18:
    print("You're a teenager")
else:
    print("You're an adult")
You're an adult

11.2 Iterations

Iterations, also known as loops, are another core programming concept that allows a piece of code to be executed repeatedly. They’re essential for tasks that require repetition, such as processing elements in a collection, performing calculations multiple times, and automating repetitive tasks.

Iterations are crucial for:

  • Reading and writing data in batches (e.g., processing external records from a database).
  • Performing repetitive calculations (e.g., computing factorials, training ML systems).
  • Iterating over data structures (e.g., lists, DataFrames).

Iterations enables us to repeatedly execute blocks of code based on conditions, refer to the following figure, for instance:

  • while the light is green, keep:

    • the engine turned on
    • driving forward
    • paying attention to incoming traffic

Indefinite iterations

11.2.1 Indefinite Iterations

Indefinite iterations in Python refer to loops that keep executing as long as a certain condition remains true. The most common way to achieve this is using the while loop.

A while loops allow us to execute code repeatedly while a condition remains True.

while <expr>:
    <statement>
    <statement>
    <statement>

Where <expr> is an expression evaluated in a Boolean context, as discussed in the section on Logical Operators in the Operators and Expressions in XXXX,<statement> is a valid Python statement, which must be indented. All <statement> are executed for as long as <expr> remains true. If <expr> is false, then all <statement> are skipped over and not executed.

The following example illustrates an while statement that checks if count is larger than zero and, given that is the case, executes a print() method.

count = 10
while count > 0:
    print("Counting down:", count)
    count -= 1  # Decrement the counter
print("Liftoff!")
Counting down: 10
Counting down: 9
Counting down: 8
Counting down: 7
Counting down: 6
Counting down: 5
Counting down: 4
Counting down: 3
Counting down: 2
Counting down: 1
Liftoff!
Beware of neverending loops

In the previous example the variable count is decreased every time we iterate over the loop, this is required to avoid an infinite loop

We can add an else statement to a loop to run a block of code once when the condition no longer is true:

counter = 0
while counter < 5:
    print("Counter is at:", counter)
    
    counter += 1
else:
    print("Counter has reached 5, exiting the loop.")

print("I am outside the loop, Bye.")
Counter is at: 0
Counter is at: 1
Counter is at: 2
Counter is at: 3
Counter is at: 4
Counter has reached 5, exiting the loop.
I am outside the loop, Bye.

11.2.2 Definite iterations

Definite iterations refer to loops that iterate a specific number of times, usually over a predefined collection of elements, like a list, string, or a DataFrame. This is in contrast to indefinite iterations, where the loop continues until a certain condition is met.

Definite iterations are extremely useful in data science and ML, they allow us to implement complex data manipulation and processing.

The most common way to perform definite iterations in Python is by using a for loop.

A for loop allow us to execute code as long as there are elements left in collection (e.g. a list).

for <collection>:
    <statement>
    <statement>
    <statement>

The following example processes a list of elements.

fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
    print( "I have found a:", fruit)
I have found a: apple
I have found a: banana
I have found a: cherry

The following example processes a string

CustomerAddress = 'Oxford Street'
for character in CustomerAddress:
    internalVariable=character.upper()
    print( internalVariable)
O
X
F
O
R
D
 
S
T
R
E
E
T

Anything that can be iterated on can be processed by a for loop. The following example illustrates the use of the range() method in combination with a for loop.

numberlist=range(0,5)
for number in numberlist:
  print(number)
0
1
2
3
4

We can even process Pandas DataFrames columns.

import pandas as pd

data = {
    'Product': ['Cycle', 'Car', 'House'],
    'Price': [100, 150, 500],
    'Quantity': [30, 45, 10]
}
df = pd.DataFrame(data)

for item in df['Product']:
  print("I have found the following Product:", item)
I have found the following Product: Cycle
I have found the following Product: Car
I have found the following Product: House
Iterating over Pandas DataFrames

Future chapters of the book will illustrate how to iterate over a Pandas DataFrame

11.3 Iterations in Practice

11.3.1 First Example

The following Jupyter Notebook provides examples of conditionals and iterations. Feel free to execute and change the code to understand how conditionals and iterations work in practice.

11.3.2 Second Example

The following Jupyter Notebook provides examples of conditionals and iterations in a healthcare context. Please execute the code making sure that you understand how it works and the logic behind the analysis.

11.4 Conclusion

Conditionals and Iterations are important entities that would allow you to perform complex manipulations of Pandas DataFrames. You will be using if statements in combination with DataFrame.apply() and lambda functions to control for unexpected situations when processing DataFrame rows (e.g. non-existing values, wrong format,etc). Remember that real datasets are expected to be messy.

You will be using for loops in combination with DataFrame.groupby() to enable fine-grained processing of DataFrames. Next chapters will illustrate how to do this in practice.

11.5 Further Readings

For those interested in additional examples and references on conditionals and iterations feel free to check the following: