An Introduction to the Art of Computer Programming Using Python in the Age of Generative AI

VII. Control Flow and Looping

Flat is better than nested.
Tim Peters, Zen of Python

Understanding how to control execution flow and implement looping constructs is fundamental to programming. Python provides a variety of control flow mechanisms, such as if, else, and elif statements, and looping constructs, such as for and while loops, that allow programmers to execute code conditionally and repetitively.

If-Else Statements

An if statement is used to test a condition and execute a block of code if the condition is true. If the condition is false, the block of code below the else statement is executed. Multiple conditions can be tested in sequence using elif (short for "else if") statements. Each if or elif statement can have its own condition, and the block with the first true condition is executed. If no conditions are true, the else block, if any, is executed.


x = 10
if x > 5:
    print("x is greater than 5")
elif x == 5:
    print("x is equal to 5")
else:
    print("x is less than 5")
        

For Loops

for loops are fundamental constructs in programming that allow us to execute a block of code repeatedly over a set of items or a range of values. This is particularly important because many tasks are repetitive by nature, and it is common to apply the same operation to numerous items. Here is a simple for loop example.


for i in range(5):
    print(i)
        

For a better understanding, here is a simple for loop that calculates the sum of the first five numbers:


sum = 0

for i in range(5):
    sum += i
    print(f'Sum: {sum}')
        

Sum: 0

Now for a more complex example where we combine for loops, if-else statements, and formatted strings:


fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
    if fruit[0] in ['a', 'o', 'u', 'e', 'i']:
        print(f'I eat an {fruit}.')
    else:
        print(f'I eat a {fruit}.')
        

While Loops

while loops are a type of iteration mechanism that repeatedly executes a block of code while a specified condition is true. They are used when you need to continue looping until a certain condition changes, which, unlike for loops, may not correspond to a fixed number of iterations.


x = 0
while x < 5:
    print(x)
    x += 1
        

Breaking and Continuing Loops

If we want a loop to stop when a certain condition is met, we can use a break statement. When a break statement occurs inside a loop, it causes the loop to exit immediately, and the execution flow continues with the first line of code outside the loop. This is useful in situations where it's necessary to exit the loop early, often because a certain condition has been met or a final result has been found.


for i in range(5):
    if i == 3:
        break
    print(i)
        

If we want to skip certain iterations that do not satisfy certain conditions, we can use the continue statement. Instead of executing the entire body of the loop, continue allows the loop to move on to the next iteration, effectively ignoring the remaining code for the current element. This is especially helpful when certain elements in the iteration don't require any action, or when you want to avoid certain conditions that would otherwise require complex nested conditional logic.


for i in range(5):
    if i == 3:
        continue
    print(i)
        

A Simple Numerical Algorithm

With the knowledge we have gained so far, we already have all the tools we need to perform all computations in the sense of Turing completeness. Let's say we want to find the square root of an integer. The square root of 3, for example, cannot be represented as a finite number in the decimal system, so we can only give an approximation. A well-known algorithm that can be used to find such an approximation is the bisection search. In this algorithm, we first define the precision with which we want to specify the square root. Since we are only looking for square roots of integers, we also know that the square root is greater than 0 (minimum) and less than or equal to the integer (maximum). Now we halve the midpoint between the maximum and minimum and compare the square of that value to the integer whose square root we want to find. We repeat these steps until we have found the square root with the accuracy we defined before.


integer_number = 25
accuracy = 0.01

if integer_number < 0:
    print("There is no true square root of a negative number.")

else:
    minimum = 0
    maximum = max(1, integer_number)
    number_of_iterations = 0
    midpoint = (maximum + minimum) / 2

    while abs(midpoint ** 2 - integer_number) >= accuracy:
        if midpoint**2 < integer_number:
            minimum = midpoint
        else:
            maximum = midpoint
        midpoint = (maximum + minimum) / 2
        number_of_iterations += 1

    print(f"After {number_of_iterations} iterations, the bisection search algorithm found {midpoint} to be close to the square root of {integer_number} with an accuracy of {accuracy}. ")
        

Prompting Generative AI for Efficient Control Flow and Looping Constructs

Leveraging Generative AI to implement control flow and looping constructs effectively requires crafting precise and application-oriented prompts. By providing clear objectives, context, and specific requirements, you can obtain AI-generated code that is both efficient and tailored to your programming needs. Below are some strategies to enhance your interactions with AI:

Example Prompt:
Create a Python program that uses a for loop to iterate through a list of numbers. The program should check whether each number is prime or not using if-else statements and store the results in a dictionary. Finally, display the dictionary with numbers as keys and their prime status as values.

Resulting AI-generated code:


# Prime Number Checker Program
numbers = [2, 3, 4, 5, 10, 13, 17, 19, 23, 24, 29]
prime_status = {}

for number in numbers:
    if number < 2:
        prime_status[number] = False
    elif number == 2:
        prime_status[number] = True
    else:
        is_prime = True
        for i in range(2, int(number ** 0.5) + 1):
            if number % i == 0:
                is_prime = False
                break
        prime_status[number] = is_prime

print("Prime Status of Numbers:")
for num, status in prime_status.items():
    print(f"{num}: {'Prime' if status else 'Not Prime'}")
        
Back to Home